diff --git a/[refs] b/[refs] index eeeed5622ee8..dfe9744149c3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 44f549217cd26daf7063984ae4ee6e46beca9c41 +refs/heads/master: e0ed5459030a8c9ddde44ef49bcb63aa6db425e1 diff --git a/trunk/CREDITS b/trunk/CREDITS index 66e82466dde8..cc3453a55fb9 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -1620,8 +1620,7 @@ D: fbdev hacking N: Jesper Juhl E: jesper.juhl@gmail.com -D: Various fixes, cleanups and minor features all over the tree. -D: Wrote initial version of the hdaps driver (since passed on to others). +D: Various fixes, cleanups and minor features. S: Lemnosvej 1, 3.tv S: 2300 Copenhagen S. S: Denmark @@ -2478,8 +2477,7 @@ S: Derbyshire DE4 3RL S: United Kingdom N: Ian S. Nelson -E: nelsonis@earthlink.net -P: 1024D/00D3D983 3EFD 7B86 B888 D7E2 29B6 9E97 576F 1B97 00D3 D983 +E: ian.nelson@echostar.com D: Minor mmap and ide hacks S: 1370 Atlantis Ave. S: Lafayette CO, 80026 diff --git a/trunk/Documentation/ABI/removed/devfs b/trunk/Documentation/ABI/obsolete/devfs similarity index 72% rename from trunk/Documentation/ABI/removed/devfs rename to trunk/Documentation/ABI/obsolete/devfs index 8195c4e0d0a1..b8b87399bc8f 100644 --- a/trunk/Documentation/ABI/removed/devfs +++ b/trunk/Documentation/ABI/obsolete/devfs @@ -1,12 +1,13 @@ What: devfs -Date: July 2005 (scheduled), finally removed in kernel v2.6.18 +Date: July 2005 Contact: Greg Kroah-Hartman Description: devfs has been unmaintained for a number of years, has unfixable races, contains a naming policy within the kernel that is against the LSB, and can be replaced by using udev. - The files fs/devfs/*, include/linux/devfs_fs*.h were removed, + The files fs/devfs/*, include/linux/devfs_fs*.h will be removed, along with the the assorted devfs function calls throughout the kernel tree. Users: + diff --git a/trunk/Documentation/ABI/testing/sysfs-power b/trunk/Documentation/ABI/testing/sysfs-power deleted file mode 100644 index d882f8093871..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-power +++ /dev/null @@ -1,88 +0,0 @@ -What: /sys/power/ -Date: August 2006 -Contact: Rafael J. Wysocki -Description: - The /sys/power directory will contain files that will - provide a unified interface to the power management - subsystem. - -What: /sys/power/state -Date: August 2006 -Contact: Rafael J. Wysocki -Description: - The /sys/power/state file controls the system power state. - Reading from this file returns what states are supported, - which is hard-coded to 'standby' (Power-On Suspend), 'mem' - (Suspend-to-RAM), and 'disk' (Suspend-to-Disk). - - Writing to this file one of these strings causes the system to - transition into that state. Please see the file - Documentation/power/states.txt for a description of each of - these states. - -What: /sys/power/disk -Date: August 2006 -Contact: Rafael J. Wysocki -Description: - The /sys/power/disk file controls the operating mode of the - suspend-to-disk mechanism. Reading from this file returns - the name of the method by which the system will be put to - sleep on the next suspend. There are four methods supported: - 'firmware' - means that the memory image will be saved to disk - by some firmware, in which case we also assume that the - firmware will handle the system suspend. - 'platform' - the memory image will be saved by the kernel and - the system will be put to sleep by the platform driver (e.g. - ACPI or other PM registers). - 'shutdown' - the memory image will be saved by the kernel and - the system will be powered off. - 'reboot' - the memory image will be saved by the kernel and - the system will be rebooted. - - The suspend-to-disk method may be chosen by writing to this - file one of the accepted strings: - - 'firmware' - 'platform' - 'shutdown' - 'reboot' - - It will only change to 'firmware' or 'platform' if the system - supports that. - -What: /sys/power/image_size -Date: August 2006 -Contact: Rafael J. Wysocki -Description: - The /sys/power/image_size file controls the size of the image - created by the suspend-to-disk mechanism. It can be written a - string representing a non-negative integer that will be used - as an upper limit of the image size, in bytes. The kernel's - suspend-to-disk code will do its best to ensure the image size - will not exceed this number. However, if it turns out to be - impossible, the kernel will try to suspend anyway using the - smallest image possible. In particular, if "0" is written to - this file, the suspend image will be as small as possible. - - Reading from this file will display the current image size - limit, which is set to 500 MB by default. - -What: /sys/power/pm_trace -Date: August 2006 -Contact: Rafael J. Wysocki -Description: - The /sys/power/pm_trace file controls the code which saves the - last PM event point in the RTC across reboots, so that you can - debug a machine that just hangs during suspend (or more - commonly, during resume). Namely, the RTC is only used to save - the last PM event point if this file contains '1'. Initially - it contains '0' which may be changed to '1' by writing a - string representing a nonzero integer into it. - - To use this debugging feature you should attempt to suspend - the machine, then reboot it and run - - dmesg -s 1000000 | grep 'hash matches' - - CAUTION: Using it will cause your machine's real-time (CMOS) - clock to be set to a random invalid time after a resume. diff --git a/trunk/Documentation/CodingStyle b/trunk/Documentation/CodingStyle index 29c18966b050..6d2412ec91ed 100644 --- a/trunk/Documentation/CodingStyle +++ b/trunk/Documentation/CodingStyle @@ -532,40 +532,6 @@ appears outweighs the potential value of the hint that tells gcc to do something it would have done anyway. - Chapter 16: Function return values and names - -Functions can return values of many different kinds, and one of the -most common is a value indicating whether the function succeeded or -failed. Such a value can be represented as an error-code integer -(-Exxx = failure, 0 = success) or a "succeeded" boolean (0 = failure, -non-zero = success). - -Mixing up these two sorts of representations is a fertile source of -difficult-to-find bugs. If the C language included a strong distinction -between integers and booleans then the compiler would find these mistakes -for us... but it doesn't. To help prevent such bugs, always follow this -convention: - - If the name of a function is an action or an imperative command, - the function should return an error-code integer. If the name - is a predicate, the function should return a "succeeded" boolean. - -For example, "add work" is a command, and the add_work() function returns 0 -for success or -EBUSY for failure. In the same way, "PCI device present" is -a predicate, and the pci_dev_present() function returns 1 if it succeeds in -finding a matching device or 0 if it doesn't. - -All EXPORTed functions must respect this convention, and so should all -public functions. Private (static) functions need not, but it is -recommended that they do. - -Functions whose return value is the actual result of a computation, rather -than an indication of whether the computation succeeded, are not subject to -this rule. Generally they indicate failure by returning some out-of-range -result. Typical examples would be functions that return pointers; they use -NULL or the ERR_PTR mechanism to report failure. - - Appendix I: References diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl index 6d4b1ef5b6f1..f8fe882e33dc 100644 --- a/trunk/Documentation/DocBook/kernel-api.tmpl +++ b/trunk/Documentation/DocBook/kernel-api.tmpl @@ -181,6 +181,27 @@ X!Ilib/string.c + + The proc filesystem + + sysctl interface +!Ekernel/sysctl.c + + + proc filesystem interface +!Ifs/proc/base.c + + + + + The debugfs filesystem + + debugfs interface +!Efs/debugfs/inode.c +!Efs/debugfs/file.c + + + The Linux VFS The Filesystem types @@ -213,50 +234,6 @@ X!Ilib/string.c - - The proc filesystem - - sysctl interface -!Ekernel/sysctl.c - - - proc filesystem interface -!Ifs/proc/base.c - - - - - The Filesystem for Exporting Kernel Objects -!Efs/sysfs/file.c -!Efs/sysfs/symlink.c -!Efs/sysfs/bin.c - - - - The debugfs filesystem - - debugfs interface -!Efs/debugfs/inode.c -!Efs/debugfs/file.c - - - - - relay interface support - - - Relay interface support - is designed to provide an efficient mechanism for tools and - facilities to relay large amounts of data from kernel space to - user space. - - - relay interface -!Ekernel/relay.c -!Ikernel/relay.c - - - Linux Networking Networking Base Types @@ -372,6 +349,13 @@ X!Earch/i386/kernel/mca.c + + The Filesystem for Exporting Kernel Objects +!Efs/sysfs/file.c +!Efs/sysfs/symlink.c +!Efs/sysfs/bin.c + + Security Framework !Esecurity/security.c @@ -402,7 +386,6 @@ X!Iinclude/linux/device.h --> !Edrivers/base/driver.c !Edrivers/base/core.c -!Edrivers/base/class.c !Edrivers/base/firmware_class.c !Edrivers/base/transport_class.c !Edrivers/base/dmapool.c @@ -454,11 +437,6 @@ X!Edrivers/pnp/system.c !Eblock/ll_rw_blk.c - - Char devices -!Efs/char_dev.c - - Miscellaneous Devices !Edrivers/char/misc.c diff --git a/trunk/Documentation/DocBook/usb.tmpl b/trunk/Documentation/DocBook/usb.tmpl index 3608472d7b74..320af25de3a2 100644 --- a/trunk/Documentation/DocBook/usb.tmpl +++ b/trunk/Documentation/DocBook/usb.tmpl @@ -43,52 +43,59 @@ A Universal Serial Bus (USB) is used to connect a host, such as a PC or workstation, to a number of peripheral - devices. USB uses a tree structure, with the host as the + devices. USB uses a tree structure, with the host at the root (the system's master), hubs as interior nodes, and - peripherals as leaves (and slaves). + peripheral devices as leaves (and slaves). Modern PCs support several such trees of USB devices, usually one USB 2.0 tree (480 Mbit/sec each) with a few USB 1.1 trees (12 Mbit/sec each) that are used when you connect a USB 1.1 device directly to the machine's "root hub". - That master/slave asymmetry was designed-in for a number of - reasons, one being ease of use. It is not physically possible to - assemble (legal) USB cables incorrectly: all upstream "to the host" - connectors are the rectangular type (matching the sockets on - root hubs), and all downstream connectors are the squarish type - (or they are built into the peripheral). - Also, the host software doesn't need to deal with distributed - auto-configuration since the pre-designated master node manages all that. - And finally, at the electrical level, bus protocol overhead is reduced by - eliminating arbitration and moving scheduling into the host software. + That master/slave asymmetry was designed in part for + ease of use. It is not physically possible to assemble + (legal) USB cables incorrectly: all upstream "to-the-host" + connectors are the rectangular type, matching the sockets on + root hubs, and the downstream type are the squarish type + (or they are built in to the peripheral). + Software doesn't need to deal with distributed autoconfiguration + since the pre-designated master node manages all that. + At the electrical level, bus protocol overhead is reduced by + eliminating arbitration and moving scheduling into host software. - USB 1.0 was announced in January 1996 and was revised + USB 1.0 was announced in January 1996, and was revised as USB 1.1 (with improvements in hub specification and support for interrupt-out transfers) in September 1998. - USB 2.0 was released in April 2000, adding high-speed - transfers and transaction-translating hubs (used for USB 1.1 + USB 2.0 was released in April 2000, including high speed + transfers and transaction translating hubs (used for USB 1.1 and 1.0 backward compatibility). - Kernel developers added USB support to Linux early in the 2.2 kernel - series, shortly before 2.3 development forked. Updates from 2.3 were - regularly folded back into 2.2 releases, which improved reliability and - brought /sbin/hotplug support as well more drivers. - Such improvements were continued in the 2.5 kernel series, where they added - USB 2.0 support, improved performance, and made the host controller drivers - (HCDs) more consistent. They also simplified the API (to make bugs less - likely) and added internal "kerneldoc" documentation. + USB support was added to Linux early in the 2.2 kernel series + shortly before the 2.3 development forked off. Updates + from 2.3 were regularly folded back into 2.2 releases, bringing + new features such as /sbin/hotplug support, + more drivers, and more robustness. + The 2.5 kernel series continued such improvements, and also + worked on USB 2.0 support, + higher performance, + better consistency between host controller drivers, + API simplification (to make bugs less likely), + and providing internal "kerneldoc" documentation. Linux can run inside USB devices as well as on the hosts that control the devices. - But USB device drivers running inside those peripherals + Because the Linux 2.x USB support evolved to support mass market + platforms such as Apple Macintosh or PC-compatible systems, + it didn't address design concerns for those types of USB systems. + So it can't be used inside mass-market PDAs, or other peripherals. + USB device drivers running inside those Linux peripherals don't do the same things as the ones running inside hosts, - so they've been given a different name: - gadget drivers. - This document does not cover gadget drivers. + and so they've been given a different name: + they're called gadget drivers. + This document does not present gadget drivers. @@ -96,14 +103,17 @@ USB Host-Side API Model - Host-side drivers for USB devices talk to the "usbcore" APIs. - There are two. One is intended for - general-purpose drivers (exposed through - driver frameworks), and the other is for drivers that are - part of the core. - Such core drivers include the hub driver - (which manages trees of USB devices) and several different kinds - of host controller drivers, + Within the kernel, + host-side drivers for USB devices talk to the "usbcore" APIs. + There are two types of public "usbcore" APIs, targetted at two different + layers of USB driver. Those are + general purpose drivers, exposed through + driver frameworks such as block, character, or network devices; + and drivers that are part of the core, + which are involved in managing a USB bus. + Such core drivers include the hub driver, + which manages trees of USB devices, and several different kinds + of host controller driver (HCD), which control individual busses. @@ -112,21 +122,21 @@ - USB supports four kinds of data transfers - (control, bulk, interrupt, and isochronous). Two of them (control - and bulk) use bandwidth as it's available, - while the other two (interrupt and isochronous) + USB supports four kinds of data transfer + (control, bulk, interrupt, and isochronous). Two transfer + types use bandwidth as it's available (control and bulk), + while the other two types of transfer (interrupt and isochronous) are scheduled to provide guaranteed bandwidth. The device description model includes one or more "configurations" per device, only one of which is active at a time. - Devices that are capable of high-speed operation must also support - full-speed configurations, along with a way to ask about the - "other speed" configurations which might be used. + Devices that are capable of high speed operation must also support + full speed configurations, along with a way to ask about the + "other speed" configurations that might be used. - Configurations have one or more "interfaces", each + Configurations have one or more "interface", each of which may have "alternate settings". Interfaces may be standardized by USB "Class" specifications, or may be specific to a vendor or device. @@ -152,7 +162,7 @@ The Linux USB API supports synchronous calls for - control and bulk messages. + control and bulk messaging. It also supports asynchnous calls for all kinds of data transfer, using request structures called "URBs" (USB Request Blocks). @@ -453,25 +463,14 @@ file in your Linux kernel sources. - This file, in combination with the poll() system call, can - also be used to detect when devices are added or removed: -int fd; -struct pollfd pfd; - -fd = open("/proc/bus/usb/devices", O_RDONLY); -pfd = { fd, POLLIN, 0 }; -for (;;) { - /* The first time through, this call will return immediately. */ - poll(&pfd, 1, -1); - - /* To see what's changed, compare the file's previous and current - contents or scan the filesystem. (Scanning is more precise.) */ -} - Note that this behavior is intended to be used for informational - and debug purposes. It would be more appropriate to use programs - such as udev or HAL to initialize a device or start a user-mode - helper program, for instance. + Otherwise the main use for this file from programs + is to poll() it to get notifications of usb devices + as they're plugged or unplugged. + To see what changed, you'd need to read the file and + compare "before" and "after" contents, scan the filesystem, + or see its hotplug event. + diff --git a/trunk/Documentation/HOWTO b/trunk/Documentation/HOWTO index d6f3dd1a3464..915ae8c986c6 100644 --- a/trunk/Documentation/HOWTO +++ b/trunk/Documentation/HOWTO @@ -358,8 +358,7 @@ Here is a list of some of the different kernel trees available: quilt trees: - USB, PCI, Driver Core, and I2C, Greg Kroah-Hartman kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/ - - x86-64, partly i386, Andi Kleen - ftp.firstfloor.org:/pub/ak/x86_64/quilt/ + Bug Reporting ------------- @@ -375,26 +374,6 @@ of information is needed by the kernel developers to help track down the problem. -Managing bug reports --------------------- - -One of the best ways to put into practice your hacking skills is by fixing -bugs reported by other people. Not only you will help to make the kernel -more stable, you'll learn to fix real world problems and you will improve -your skills, and other developers will be aware of your presence. Fixing -bugs is one of the best ways to earn merit amongst the developers, because -not many people like wasting time fixing other people's bugs. - -To work in the already reported bug reports, go to http://bugzilla.kernel.org. -If you want to be advised of the future bug reports, you can subscribe to the -bugme-new mailing list (only new bug reports are mailed here) or to the -bugme-janitor mailing list (every change in the bugzilla is mailed here) - - http://lists.osdl.org/mailman/listinfo/bugme-new - http://lists.osdl.org/mailman/listinfo/bugme-janitors - - - Mailing lists ------------- diff --git a/trunk/Documentation/IPMI.txt b/trunk/Documentation/IPMI.txt index 7756e09ea759..0256805b548f 100644 --- a/trunk/Documentation/IPMI.txt +++ b/trunk/Documentation/IPMI.txt @@ -326,12 +326,9 @@ for events, they will all receive all events that come in. For receiving commands, you have to individually register commands you want to receive. Call ipmi_register_for_cmd() and supply the netfn -and command name for each command you want to receive. You also -specify a bitmask of the channels you want to receive the command from -(or use IPMI_CHAN_ALL for all channels if you don't care). Only one -user may be registered for each netfn/cmd/channel, but different users -may register for different commands, or the same command if the -channel bitmasks do not overlap. +and command name for each command you want to receive. Only one user +may be registered for each netfn/cmd, but different users may register +for different commands. From userland, equivalent IOCTLs are provided to do these functions. diff --git a/trunk/Documentation/SubmitChecklist b/trunk/Documentation/SubmitChecklist index 7ac61f60037a..a10bfb6ecd9f 100644 --- a/trunk/Documentation/SubmitChecklist +++ b/trunk/Documentation/SubmitChecklist @@ -61,8 +61,3 @@ kernel patches. Documentation/kernel-parameters.txt. 18: All new module parameters are documented with MODULE_PARM_DESC() - -19: All new userspace interfaces are documented in Documentation/ABI/. - See Documentation/ABI/README for more information. - -20: Check that it all passes `make headers_check'. diff --git a/trunk/Documentation/SubmittingDrivers b/trunk/Documentation/SubmittingDrivers index 58bead05eabb..6bd30fdd0786 100644 --- a/trunk/Documentation/SubmittingDrivers +++ b/trunk/Documentation/SubmittingDrivers @@ -59,11 +59,11 @@ Copyright: The copyright owner must agree to use of GPL. are the same person/entity. If not, the name of the person/entity authorizing use of GPL should be listed in case it's necessary to verify the will of - the copyright owner. + the copright owner. Interfaces: If your driver uses existing interfaces and behaves like other drivers in the same class it will be much more likely - to be accepted than if it invents gratuitous new ones. + to be accepted than if it invents gratuitous new ones. If you need to implement a common API over Linux and NT drivers do it in userspace. @@ -88,7 +88,7 @@ Clarity: It helps if anyone can see how to fix the driver. It helps it will go in the bitbucket. Control: In general if there is active maintainance of a driver by - the author then patches will be redirected to them unless + the author then patches will be redirected to them unless they are totally obvious and without need of checking. If you want to be the contact and update point for the driver it is a good idea to state this in the comments, @@ -100,7 +100,7 @@ What Criteria Do Not Determine Acceptance Vendor: Being the hardware vendor and maintaining the driver is often a good thing. If there is a stable working driver from other people already in the tree don't expect 'we are the - vendor' to get your driver chosen. Ideally work with the + vendor' to get your driver chosen. Ideally work with the existing driver author to build a single perfect driver. Author: It doesn't matter if a large Linux company wrote the driver, @@ -116,13 +116,17 @@ Linux kernel master tree: ftp.??.kernel.org:/pub/linux/kernel/... ?? == your country code, such as "us", "uk", "fr", etc. -Linux kernel mailing list: +Linux kernel mailing list: linux-kernel@vger.kernel.org [mail majordomo@vger.kernel.org to subscribe] Linux Device Drivers, Third Edition (covers 2.6.10): http://lwn.net/Kernel/LDD3/ (free version) +Kernel traffic: + Weekly summary of kernel list activity (much easier to read) + http://www.kerneltraffic.org/kernel-traffic/ + LWN.net: Weekly summary of kernel development activity - http://lwn.net/ 2.6 API changes: @@ -141,8 +145,11 @@ KernelNewbies: Linux USB project: http://www.linux-usb.org/ -How to NOT write kernel driver by Arjan van de Ven: - http://www.fenrus.org/how-to-not-write-a-device-driver-paper.pdf +How to NOT write kernel driver by arjanv@redhat.com + http://people.redhat.com/arjanv/olspaper.pdf Kernel Janitor: http://janitor.kernelnewbies.org/ + +-- +Last updated on 17 Nov 2005. diff --git a/trunk/Documentation/SubmittingPatches b/trunk/Documentation/SubmittingPatches index 302d148c2e18..d42ab4c9e893 100644 --- a/trunk/Documentation/SubmittingPatches +++ b/trunk/Documentation/SubmittingPatches @@ -173,15 +173,15 @@ For small patches you may want to CC the Trivial Patch Monkey trivial@kernel.org managed by Adrian Bunk; which collects "trivial" patches. Trivial patches must qualify for one of the following rules: Spelling fixes in documentation - Spelling fixes which could break grep(1) + Spelling fixes which could break grep(1). Warning fixes (cluttering with useless warnings is bad) Compilation fixes (only if they are actually correct) Runtime fixes (only if they actually fix things) - Removing use of deprecated functions/macros (eg. check_region) + Removing use of deprecated functions/macros (eg. check_region). Contact detail and documentation fixes Non-portable code replaced by portable code (even in arch-specific, since people copy, as long as it's trivial) - Any fix by the author/maintainer of the file (ie. patch monkey + Any fix by the author/maintainer of the file. (ie. patch monkey in re-transmission mode) URL: @@ -209,19 +209,6 @@ Exception: If your mailer is mangling patches then someone may ask you to re-send them using MIME. -WARNING: Some mailers like Mozilla send your messages with ----- message header ---- -Content-Type: text/plain; charset=us-ascii; format=flowed ----- message header ---- -The problem is that "format=flowed" makes some of the mailers -on receiving side to replace TABs with spaces and do similar -changes. Thus the patches from you can look corrupted. - -To fix this just make your mozilla defaults/pref/mailnews.js file to look like: -pref("mailnews.send_plaintext_flowed", false); // RFC 2646======= -pref("mailnews.display.disable_format_flowed_support", true); - - 7) E-mail size. @@ -258,13 +245,13 @@ updated change. It is quite common for Linus to "drop" your patch without comment. That's the nature of the system. If he drops your patch, it could be due to -* Your patch did not apply cleanly to the latest kernel version. +* Your patch did not apply cleanly to the latest kernel version * Your patch was not sufficiently discussed on linux-kernel. -* A style issue (see section 2). -* An e-mail formatting issue (re-read this section). -* A technical problem with your change. -* He gets tons of e-mail, and yours got lost in the shuffle. -* You are being annoying. +* A style issue (see section 2), +* An e-mail formatting issue (re-read this section) +* A technical problem with your change +* He gets tons of e-mail, and yours got lost in the shuffle +* You are being annoying (See Figure 1) When in doubt, solicit comments on linux-kernel mailing list. @@ -489,10 +476,10 @@ SECTION 3 - REFERENCES Andrew Morton, "The perfect patch" (tpp). -Jeff Garzik, "Linux kernel patch submission format". +Jeff Garzik, "Linux kernel patch submission format." -Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer". +Greg Kroah-Hartman "How to piss off a kernel subsystem maintainer". @@ -501,9 +488,9 @@ Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer". NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people! -Kernel Documentation/CodingStyle: +Kernel Documentation/CodingStyle -Linus Torvalds's mail on the canonical patch format: +Linus Torvald's mail on the canonical patch format: -- diff --git a/trunk/Documentation/accounting/getdelays.c b/trunk/Documentation/accounting/getdelays.c index b11792abd6b6..795ca3911cc5 100644 --- a/trunk/Documentation/accounting/getdelays.c +++ b/trunk/Documentation/accounting/getdelays.c @@ -285,7 +285,7 @@ int main(int argc, char *argv[]) if (maskset) { rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, TASKSTATS_CMD_ATTR_REGISTER_CPUMASK, - &cpumask, strlen(cpumask) + 1); + &cpumask, sizeof(cpumask)); PRINTF("Sent register cpumask, retval %d\n", rc); if (rc < 0) { printf("error sending register cpumask\n"); @@ -315,8 +315,7 @@ int main(int argc, char *argv[]) } if (msg.n.nlmsg_type == NLMSG_ERROR || !NLMSG_OK((&msg.n), rep_len)) { - struct nlmsgerr *err = NLMSG_DATA(&msg); - printf("fatal reply error, errno %d\n", err->error); + printf("fatal reply error, errno %d\n", errno); goto done; } @@ -384,7 +383,7 @@ int main(int argc, char *argv[]) if (maskset) { rc = send_cmd(nl_sd, id, mypid, TASKSTATS_CMD_GET, TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK, - &cpumask, strlen(cpumask) + 1); + &cpumask, sizeof(cpumask)); printf("Sent deregister mask, retval %d\n", rc); if (rc < 0) err(rc, "error sending deregister cpumask\n"); diff --git a/trunk/Documentation/accounting/taskstats-struct.txt b/trunk/Documentation/accounting/taskstats-struct.txt deleted file mode 100644 index 661c797eaf79..000000000000 --- a/trunk/Documentation/accounting/taskstats-struct.txt +++ /dev/null @@ -1,161 +0,0 @@ -The struct taskstats --------------------- - -This document contains an explanation of the struct taskstats fields. - -There are three different groups of fields in the struct taskstats: - -1) Common and basic accounting fields - If CONFIG_TASKSTATS is set, the taskstats inteface is enabled and - the common fields and basic accounting fields are collected for - delivery at do_exit() of a task. -2) Delay accounting fields - These fields are placed between - /* Delay accounting fields start */ - and - /* Delay accounting fields end */ - Their values are collected if CONFIG_TASK_DELAY_ACCT is set. -3) Extended accounting fields - These fields are placed between - /* Extended accounting fields start */ - and - /* Extended accounting fields end */ - Their values are collected if CONFIG_TASK_XACCT is set. - -Future extension should add fields to the end of the taskstats struct, and -should not change the relative position of each field within the struct. - - -struct taskstats { - -1) Common and basic accounting fields: - /* The version number of this struct. This field is always set to - * TAKSTATS_VERSION, which is defined in . - * Each time the struct is changed, the value should be incremented. - */ - __u16 version; - - /* The exit code of a task. */ - __u32 ac_exitcode; /* Exit status */ - - /* The accounting flags of a task as defined in - * Defined values are AFORK, ASU, ACOMPAT, ACORE, and AXSIG. - */ - __u8 ac_flag; /* Record flags */ - - /* The value of task_nice() of a task. */ - __u8 ac_nice; /* task_nice */ - - /* The name of the command that started this task. */ - char ac_comm[TS_COMM_LEN]; /* Command name */ - - /* The scheduling discipline as set in task->policy field. */ - __u8 ac_sched; /* Scheduling discipline */ - - __u8 ac_pad[3]; - __u32 ac_uid; /* User ID */ - __u32 ac_gid; /* Group ID */ - __u32 ac_pid; /* Process ID */ - __u32 ac_ppid; /* Parent process ID */ - - /* The time when a task begins, in [secs] since 1970. */ - __u32 ac_btime; /* Begin time [sec since 1970] */ - - /* The elapsed time of a task, in [usec]. */ - __u64 ac_etime; /* Elapsed time [usec] */ - - /* The user CPU time of a task, in [usec]. */ - __u64 ac_utime; /* User CPU time [usec] */ - - /* The system CPU time of a task, in [usec]. */ - __u64 ac_stime; /* System CPU time [usec] */ - - /* The minor page fault count of a task, as set in task->min_flt. */ - __u64 ac_minflt; /* Minor Page Fault Count */ - - /* The major page fault count of a task, as set in task->maj_flt. */ - __u64 ac_majflt; /* Major Page Fault Count */ - - -2) Delay accounting fields: - /* Delay accounting fields start - * - * All values, until the comment "Delay accounting fields end" are - * available only if delay accounting is enabled, even though the last - * few fields are not delays - * - * xxx_count is the number of delay values recorded - * xxx_delay_total is the corresponding cumulative delay in nanoseconds - * - * xxx_delay_total wraps around to zero on overflow - * xxx_count incremented regardless of overflow - */ - - /* Delay waiting for cpu, while runnable - * count, delay_total NOT updated atomically - */ - __u64 cpu_count; - __u64 cpu_delay_total; - - /* Following four fields atomically updated using task->delays->lock */ - - /* Delay waiting for synchronous block I/O to complete - * does not account for delays in I/O submission - */ - __u64 blkio_count; - __u64 blkio_delay_total; - - /* Delay waiting for page fault I/O (swap in only) */ - __u64 swapin_count; - __u64 swapin_delay_total; - - /* cpu "wall-clock" running time - * On some architectures, value will adjust for cpu time stolen - * from the kernel in involuntary waits due to virtualization. - * Value is cumulative, in nanoseconds, without a corresponding count - * and wraps around to zero silently on overflow - */ - __u64 cpu_run_real_total; - - /* cpu "virtual" running time - * Uses time intervals seen by the kernel i.e. no adjustment - * for kernel's involuntary waits due to virtualization. - * Value is cumulative, in nanoseconds, without a corresponding count - * and wraps around to zero silently on overflow - */ - __u64 cpu_run_virtual_total; - /* Delay accounting fields end */ - /* version 1 ends here */ - - -3) Extended accounting fields - /* Extended accounting fields start */ - - /* Accumulated RSS usage in duration of a task, in MBytes-usecs. - * The current rss usage is added to this counter every time - * a tick is charged to a task's system time. So, at the end we - * will have memory usage multiplied by system time. Thus an - * average usage per system time unit can be calculated. - */ - __u64 coremem; /* accumulated RSS usage in MB-usec */ - - /* Accumulated virtual memory usage in duration of a task. - * Same as acct_rss_mem1 above except that we keep track of VM usage. - */ - __u64 virtmem; /* accumulated VM usage in MB-usec */ - - /* High watermark of RSS usage in duration of a task, in KBytes. */ - __u64 hiwater_rss; /* High-watermark of RSS usage */ - - /* High watermark of VM usage in duration of a task, in KBytes. */ - __u64 hiwater_vm; /* High-water virtual memory usage */ - - /* The following four fields are I/O statistics of a task. */ - __u64 read_char; /* bytes read */ - __u64 write_char; /* bytes written */ - __u64 read_syscalls; /* read syscalls */ - __u64 write_syscalls; /* write syscalls */ - - /* Extended accounting fields end */ - -} diff --git a/trunk/Documentation/cpusets.txt b/trunk/Documentation/cpusets.txt index 842f0d1ab216..76b44290c154 100644 --- a/trunk/Documentation/cpusets.txt +++ b/trunk/Documentation/cpusets.txt @@ -217,11 +217,11 @@ exclusive cpuset. Also, the use of a Linux virtual file system (vfs) to represent the cpuset hierarchy provides for a familiar permission and name space for cpusets, with a minimum of additional kernel code. -The cpus and mems files in the root (top_cpuset) cpuset are -read-only. The cpus file automatically tracks the value of -cpu_online_map using a CPU hotplug notifier, and the mems file -automatically tracks the value of node_online_map using the -cpuset_track_online_nodes() hook. +The cpus file in the root (top_cpuset) cpuset is read-only. +It automatically tracks the value of cpu_online_map, using a CPU +hotplug notifier. If and when memory nodes can be hotplugged, +we expect to make the mems file in the root cpuset read-only +as well, and have it track the value of node_online_map. 1.4 What are exclusive cpusets ? diff --git a/trunk/Documentation/devices.txt b/trunk/Documentation/devices.txt index addc67b1d770..66c725f530f3 100644 --- a/trunk/Documentation/devices.txt +++ b/trunk/Documentation/devices.txt @@ -2543,9 +2543,6 @@ Your cooperation is appreciated. 64 = /dev/usb/rio500 Diamond Rio 500 65 = /dev/usb/usblcd USBLCD Interface (info@usblcd.de) 66 = /dev/usb/cpad0 Synaptics cPad (mouse/LCD) - 67 = /dev/usb/adutux0 1st Ontrak ADU device - ... - 76 = /dev/usb/adutux10 10th Ontrak ADU device 96 = /dev/usb/hiddev0 1st USB HID device ... 111 = /dev/usb/hiddev15 16th USB HID device diff --git a/trunk/Documentation/fb/intelfb.txt b/trunk/Documentation/fb/intelfb.txt index aa0d322db171..c12d39a23c3d 100644 --- a/trunk/Documentation/fb/intelfb.txt +++ b/trunk/Documentation/fb/intelfb.txt @@ -1,19 +1,16 @@ -Intel 830M/845G/852GM/855GM/865G/915G/945G Framebuffer driver +Intel 830M/845G/852GM/855GM/865G/915G Framebuffer driver ================================================================ A. Introduction - This is a framebuffer driver for various Intel 8xx/9xx compatible + This is a framebuffer driver for various Intel 810/815 compatible graphics devices. These would include: Intel 830M - Intel 845G + Intel 810E845G Intel 852GM Intel 855GM Intel 865G Intel 915G - Intel 915GM - Intel 945G - Intel 945GM B. List of available options @@ -81,7 +78,7 @@ C. Kernel booting Separate each option/option-pair by commas (,) and the option from its value with an equals sign (=) as in the following: -video=intelfb:option1,option2=value2 +video=i810fb:option1,option2=value2 Sample Usage ------------ diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 9364f47c7116..552507fe9a7e 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -6,21 +6,6 @@ be removed from this file. --------------------------- -What: /sys/devices/.../power/state - dev->power.power_state - dpm_runtime_{suspend,resume)() -When: July 2007 -Why: Broken design for runtime control over driver power states, confusing - driver-internal runtime power management with: mechanisms to support - system-wide sleep state transitions; event codes that distinguish - different phases of swsusp "sleep" transitions; and userspace policy - inputs. This framework was never widely used, and most attempts to - use it were broken. Drivers should instead be exposing domain-specific - interfaces either to kernel or to userspace. -Who: Pavel Machek - ---------------------------- - What: RAW driver (CONFIG_RAW_DRIVER) When: December 2005 Why: declared obsolete since kernel 2.6.3 @@ -46,8 +31,17 @@ Who: Jody McIntyre --------------------------- +What: sbp2: module parameter "force_inquiry_hack" +When: July 2006 +Why: Superceded by parameter "workarounds". Both parameters are meant to be + used ad-hoc and for single devices only, i.e. not in modprobe.conf, + therefore the impact of this feature replacement should be low. +Who: Stefan Richter + +--------------------------- + What: Video4Linux API 1 ioctls and video_decoder.h from Video devices. -When: December 2006 +When: July 2006 Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6 series. The old API have lots of drawbacks and don't provide enough means to work with all video and audio standards. The newer API is @@ -61,18 +55,6 @@ Who: Mauro Carvalho Chehab --------------------------- -What: sys_sysctl -When: January 2007 -Why: The same information is available through /proc/sys and that is the - interface user space prefers to use. And there do not appear to be - any existing user in user space of sys_sysctl. The additional - maintenance overhead of keeping a set of binary names gets - in the way of doing a good job of maintaining this interface. - -Who: Eric Biederman - ---------------------------- - What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl]) When: November 2005 Files: drivers/pcmcia/: pcmcia_ioctl.c @@ -220,6 +202,14 @@ Who: Nick Piggin --------------------------- +What: Support for the MIPS EV96100 evaluation board +When: September 2006 +Why: Does no longer build since at least November 15, 2003, apparently + no userbase left. +Who: Ralf Baechle + +--------------------------- + What: Support for the Momentum / PMC-Sierra Jaguar ATX evaluation board When: September 2006 Why: Does no longer build since quite some time, and was never popular, @@ -304,24 +294,3 @@ Why: The frame diverter is included in most distribution kernels, but is It is not clear if anyone is still using it. Who: Stephen Hemminger ---------------------------- - - -What: PHYSDEVPATH, PHYSDEVBUS, PHYSDEVDRIVER in the uevent environment -When: Oktober 2008 -Why: The stacking of class devices makes these values misleading and - inconsistent. - Class devices should not carry any of these properties, and bus - devices have SUBSYTEM and DRIVER as a replacement. -Who: Kay Sievers - ---------------------------- - -What: i2c-isa -When: December 2006 -Why: i2c-isa is a non-sense and doesn't fit in the device driver - model. Drivers relying on it are better implemented as platform - drivers. -Who: Jean Delvare - ---------------------------- diff --git a/trunk/Documentation/filesystems/Locking b/trunk/Documentation/filesystems/Locking index eb1a6cad21e6..247d7f619aa2 100644 --- a/trunk/Documentation/filesystems/Locking +++ b/trunk/Documentation/filesystems/Locking @@ -356,9 +356,10 @@ The last two are called only from check_disk_change(). prototypes: loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); + ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); - ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); - ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); + ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, + loff_t); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt index 7240ee7515de..99902ae6804e 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -39,8 +39,6 @@ Table of Contents 2.9 Appletalk 2.10 IPX 2.11 /proc/sys/fs/mqueue - POSIX message queues filesystem - 2.12 /proc//oom_adj - Adjust the oom-killer score - 2.13 /proc//oom_score - Display current oom-killer score ------------------------------------------------------------------------------ Preface @@ -1126,15 +1124,11 @@ debugging information is displayed on console. NMI switch that most IA32 servers have fires unknown NMI up, for example. If a system hangs up, try pressing the NMI switch. -nmi_watchdog ------------- - -Enables/Disables the NMI watchdog on x86 systems. When the value is non-zero -the NMI watchdog is enabled and will continuously test all online cpus to -determine whether or not they are still functioning properly. - -Because the NMI watchdog shares registers with oprofile, by disabling the NMI -watchdog, oprofile may have more registers to utilize. +[NOTE] + This function and oprofile share a NMI callback. Therefore this function + cannot be enabled when oprofile is activated. + And NMI watchdog will be disabled when the value in this file is set to + non-zero. 2.4 /proc/sys/vm - The virtual memory subsystem @@ -1964,22 +1958,6 @@ a queue must be less or equal then msg_max. maximum message size value (it is every message queue's attribute set during its creation). -2.12 /proc//oom_adj - Adjust the oom-killer score ------------------------------------------------------- - -This file can be used to adjust the score used to select which processes -should be killed in an out-of-memory situation. Giving it a high score will -increase the likelihood of this process being killed by the oom-killer. Valid -values are in the range -16 to +15, plus the special value -17, which disables -oom-killing altogether for this process. - -2.13 /proc//oom_score - Display current oom-killer score -------------------------------------------------------------- - ------------------------------------------------------------------------------- -This file can be used to check the current score used by the oom-killer is for -any given . Use it together with /proc//oom_adj to tune which -process should be killed in an out-of-memory situation. ------------------------------------------------------------------------------ Summary diff --git a/trunk/Documentation/filesystems/vfs.txt b/trunk/Documentation/filesystems/vfs.txt index cd07c21b8400..1cb7e8be927a 100644 --- a/trunk/Documentation/filesystems/vfs.txt +++ b/trunk/Documentation/filesystems/vfs.txt @@ -699,9 +699,9 @@ This describes how the VFS can manipulate an open file. As of kernel struct file_operations { loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); + ssize_t (*aio_read) (struct kiocb *, char __user *, size_t, loff_t); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); - ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); - ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); + ssize_t (*aio_write) (struct kiocb *, const char __user *, size_t, loff_t); int (*readdir) (struct file *, void *, filldir_t); unsigned int (*poll) (struct file *, struct poll_table_struct *); int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); diff --git a/trunk/Documentation/hwmon/it87 b/trunk/Documentation/hwmon/it87 index e783fd62e308..9555be1ed999 100644 --- a/trunk/Documentation/hwmon/it87 +++ b/trunk/Documentation/hwmon/it87 @@ -13,25 +13,12 @@ Supported chips: from Super I/O config space (8 I/O ports) Datasheet: Publicly available at the ITE website http://www.ite.com.tw/ - * IT8716F - Prefix: 'it8716' - Addresses scanned: from Super I/O config space (8 I/O ports) - Datasheet: Publicly available at the ITE website - http://www.ite.com.tw/product_info/file/pc/IT8716F_V0.3.ZIP - * IT8718F - Prefix: 'it8718' - Addresses scanned: from Super I/O config space (8 I/O ports) - Datasheet: Publicly available at the ITE website - http://www.ite.com.tw/product_info/file/pc/IT8718F_V0.2.zip - http://www.ite.com.tw/product_info/file/pc/IT8718F_V0%203_(for%20C%20version).zip * SiS950 [clone of IT8705F] Prefix: 'it87' Addresses scanned: from Super I/O config space (8 I/O ports) Datasheet: No longer be available -Authors: - Christophe Gauthron - Jean Delvare +Author: Christophe Gauthron Module Parameters @@ -56,46 +43,26 @@ Module Parameters Description ----------- -This driver implements support for the IT8705F, IT8712F, IT8716F, -IT8718F and SiS950 chips. +This driver implements support for the IT8705F, IT8712F and SiS950 chips. + +This driver also supports IT8712F, which adds SMBus access, and a VID +input, used to report the Vcore voltage of the Pentium processor. +The IT8712F additionally features VID inputs. These chips are 'Super I/O chips', supporting floppy disks, infrared ports, joysticks and other miscellaneous stuff. For hardware monitoring, they include an 'environment controller' with 3 temperature sensors, 3 fan rotation speed sensors, 8 voltage sensors, and associated alarms. -The IT8712F and IT8716F additionally feature VID inputs, used to report -the Vcore voltage of the processor. The early IT8712F have 5 VID pins, -the IT8716F and late IT8712F have 6. They are shared with other functions -though, so the functionality may not be available on a given system. -The driver dumbly assume it is there. - -The IT8718F also features VID inputs (up to 8 pins) but the value is -stored in the Super-I/O configuration space. Due to technical limitations, -this value can currently only be read once at initialization time, so -the driver won't notice and report changes in the VID value. The two -upper VID bits share their pins with voltage inputs (in5 and in6) so you -can't have both on a given board. - -The IT8716F, IT8718F and later IT8712F revisions have support for -2 additional fans. They are not yet supported by the driver. - -The IT8716F and IT8718F, and late IT8712F and IT8705F also have optional -16-bit tachometer counters for fans 1 to 3. This is better (no more fan -clock divider mess) but not compatible with the older chips and -revisions. For now, the driver only uses the 16-bit mode on the -IT8716F and IT8718F. - Temperatures are measured in degrees Celsius. An alarm is triggered once when the Overtemperature Shutdown limit is crossed. Fan rotation speeds are reported in RPM (rotations per minute). An alarm is -triggered if the rotation speed has dropped below a programmable limit. When -16-bit tachometer counters aren't used, fan readings can be divided by -a programmable divider (1, 2, 4 or 8) to give the readings more range or -accuracy. With a divider of 2, the lowest representable value is around -2600 RPM. Not all RPM values can accurately be represented, so some rounding -is done. +triggered if the rotation speed has dropped below a programmable limit. Fan +readings can be divided by a programmable divider (1, 2, 4 or 8) to give the +readings more range or accuracy. Not all RPM values can accurately be +represented, so some rounding is done. With a divider of 2, the lowest +representable value is around 2600 RPM. Voltage sensors (also known as IN sensors) report their values in volts. An alarm is triggered if the voltage has crossed a programmable minimum or @@ -104,9 +71,9 @@ zero'; this is important for negative voltage measurements. All voltage inputs can measure voltages between 0 and 4.08 volts, with a resolution of 0.016 volt. The battery voltage in8 does not have limit registers. -The VID lines (IT8712F/IT8716F/IT8718F) encode the core voltage value: -the voltage level your processor should work with. This is hardcoded by -the mainboard and/or processor itself. It is a value in volts. +The VID lines (IT8712F only) encode the core voltage value: the voltage +level your processor should work with. This is hardcoded by the mainboard +and/or processor itself. It is a value in volts. If an alarm triggers, it will remain triggered until the hardware register is read at least once. This means that the cause for the alarm may already diff --git a/trunk/Documentation/hwmon/k8temp b/trunk/Documentation/hwmon/k8temp deleted file mode 100644 index bab445ab0f52..000000000000 --- a/trunk/Documentation/hwmon/k8temp +++ /dev/null @@ -1,52 +0,0 @@ -Kernel driver k8temp -==================== - -Supported chips: - * AMD K8 CPU - Prefix: 'k8temp' - Addresses scanned: PCI space - Datasheet: http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf - -Author: Rudolf Marek -Contact: Rudolf Marek - -Description ------------ - -This driver permits reading temperature sensor(s) embedded inside AMD K8 CPUs. -Official documentation says that it works from revision F of K8 core, but -in fact it seems to be implemented for all revisions of K8 except the first -two revisions (SH-B0 and SH-B3). - -There can be up to four temperature sensors inside single CPU. The driver -will auto-detect the sensors and will display only temperatures from -implemented sensors. - -Mapping of /sys files is as follows: - -temp1_input - temperature of Core 0 and "place" 0 -temp2_input - temperature of Core 0 and "place" 1 -temp3_input - temperature of Core 1 and "place" 0 -temp4_input - temperature of Core 1 and "place" 1 - -Temperatures are measured in degrees Celsius and measurement resolution is -1 degree C. It is expected that future CPU will have better resolution. The -temperature is updated once a second. Valid temperatures are from -49 to -206 degrees C. - -Temperature known as TCaseMax was specified for processors up to revision E. -This temperature is defined as temperature between heat-spreader and CPU -case, so the internal CPU temperature supplied by this driver can be higher. -There is no easy way how to measure the temperature which will correlate -with TCaseMax temperature. - -For newer revisions of CPU (rev F, socket AM2) there is a mathematically -computed temperature called TControl, which must be lower than TControlMax. - -The relationship is following: - -temp1_input - TjOffset*2 < TControlMax, - -TjOffset is not yet exported by the driver, TControlMax is usually -70 degrees C. The rule of the thumb -> CPU temperature should not cross -60 degrees C too much. diff --git a/trunk/Documentation/hwmon/vt1211 b/trunk/Documentation/hwmon/vt1211 deleted file mode 100644 index 77fa633b97a8..000000000000 --- a/trunk/Documentation/hwmon/vt1211 +++ /dev/null @@ -1,206 +0,0 @@ -Kernel driver vt1211 -==================== - -Supported chips: - * VIA VT1211 - Prefix: 'vt1211' - Addresses scanned: none, address read from Super-I/O config space - Datasheet: Provided by VIA upon request and under NDA - -Authors: Juerg Haefliger - -This driver is based on the driver for kernel 2.4 by Mark D. Studebaker and -its port to kernel 2.6 by Lars Ekman. - -Thanks to Joseph Chan and Fiona Gatt from VIA for providing documentation and -technical support. - - -Module Parameters ------------------ - -* uch_config: int Override the BIOS default universal channel (UCH) - configuration for channels 1-5. - Legal values are in the range of 0-31. Bit 0 maps to - UCH1, bit 1 maps to UCH2 and so on. Setting a bit to 1 - enables the thermal input of that particular UCH and - setting a bit to 0 enables the voltage input. - -* int_mode: int Override the BIOS default temperature interrupt mode. - The only possible value is 0 which forces interrupt - mode 0. In this mode, any pending interrupt is cleared - when the status register is read but is regenerated as - long as the temperature stays above the hysteresis - limit. - -Be aware that overriding BIOS defaults might cause some unwanted side effects! - - -Description ------------ - -The VIA VT1211 Super-I/O chip includes complete hardware monitoring -capabilities. It monitors 2 dedicated temperature sensor inputs (temp1 and -temp2), 1 dedicated voltage (in5) and 2 fans. Additionally, the chip -implements 5 universal input channels (UCH1-5) that can be individually -programmed to either monitor a voltage or a temperature. - -This chip also provides manual and automatic control of fan speeds (according -to the datasheet). The driver only supports automatic control since the manual -mode doesn't seem to work as advertised in the datasheet. In fact I couldn't -get manual mode to work at all! Be aware that automatic mode hasn't been -tested very well (due to the fact that my EPIA M10000 doesn't have the fans -connected to the PWM outputs of the VT1211 :-(). - -The following table shows the relationship between the vt1211 inputs and the -sysfs nodes. - -Sensor Voltage Mode Temp Mode Default Use (from the datasheet) ------- ------------ --------- -------------------------------- -Reading 1 temp1 Intel thermal diode -Reading 3 temp2 Internal thermal diode -UCH1/Reading2 in0 temp3 NTC type thermistor -UCH2 in1 temp4 +2.5V -UCH3 in2 temp5 VccP (processor core) -UCH4 in3 temp6 +5V -UCH5 in4 temp7 +12V -+3.3V in5 Internal VCC (+3.3V) - - -Voltage Monitoring ------------------- - -Voltages are sampled by an 8-bit ADC with a LSB of ~10mV. The supported input -range is thus from 0 to 2.60V. Voltage values outside of this range need -external scaling resistors. This external scaling needs to be compensated for -via compute lines in sensors.conf, like: - -compute inx @*(1+R1/R2), @/(1+R1/R2) - -The board level scaling resistors according to VIA's recommendation are as -follows. And this is of course totally dependent on the actual board -implementation :-) You will have to find documentation for your own -motherboard and edit sensors.conf accordingly. - - Expected -Voltage R1 R2 Divider Raw Value ------------------------------------------------ -+2.5V 2K 10K 1.2 2083 mV -VccP --- --- 1.0 1400 mV (1) -+5V 14K 10K 2.4 2083 mV -+12V 47K 10K 5.7 2105 mV -+3.3V (int) 2K 3.4K 1.588 3300 mV (2) -+3.3V (ext) 6.8K 10K 1.68 1964 mV - -(1) Depending on the CPU (1.4V is for a VIA C3 Nehemiah). -(2) R1 and R2 for 3.3V (int) are internal to the VT1211 chip and the driver - performs the scaling and returns the properly scaled voltage value. - -Each measured voltage has an associated low and high limit which triggers an -alarm when crossed. - - -Temperature Monitoring ----------------------- - -Temperatures are reported in millidegree Celsius. Each measured temperature -has a high limit which triggers an alarm if crossed. There is an associated -hysteresis value with each temperature below which the temperature has to drop -before the alarm is cleared (this is only true for interrupt mode 0). The -interrupt mode can be forced to 0 in case the BIOS doesn't do it -automatically. See the 'Module Parameters' section for details. - -All temperature channels except temp2 are external. Temp2 is the VT1211 -internal thermal diode and the driver does all the scaling for temp2 and -returns the temperature in millidegree Celsius. For the external channels -temp1 and temp3-temp7, scaling depends on the board implementation and needs -to be performed in userspace via sensors.conf. - -Temp1 is an Intel-type thermal diode which requires the following formula to -convert between sysfs readings and real temperatures: - -compute temp1 (@-Offset)/Gain, (@*Gain)+Offset - -According to the VIA VT1211 BIOS porting guide, the following gain and offset -values should be used: - -Diode Type Offset Gain ----------- ------ ---- -Intel CPU 88.638 0.9528 - 65.000 0.9686 *) -VIA C3 Ezra 83.869 0.9528 -VIA C3 Ezra-T 73.869 0.9528 - -*) This is the formula from the lm_sensors 2.10.0 sensors.conf file. I don't -know where it comes from or how it was derived, it's just listed here for -completeness. - -Temp3-temp7 support NTC thermistors. For these channels, the driver returns -the voltages as seen at the individual pins of UCH1-UCH5. The voltage at the -pin (Vpin) is formed by a voltage divider made of the thermistor (Rth) and a -scaling resistor (Rs): - -Vpin = 2200 * Rth / (Rs + Rth) (2200 is the ADC max limit of 2200 mV) - -The equation for the thermistor is as follows (google it if you want to know -more about it): - -Rth = Ro * exp(B * (1 / T - 1 / To)) (To is 298.15K (25C) and Ro is the - nominal resistance at 25C) - -Mingling the above two equations and assuming Rs = Ro and B = 3435 yields the -following formula for sensors.conf: - -compute tempx 1 / (1 / 298.15 - (` (2200 / @ - 1)) / 3435) - 273.15, - 2200 / (1 + (^ (3435 / 298.15 - 3435 / (273.15 + @)))) - - -Fan Speed Control ------------------ - -The VT1211 provides 2 programmable PWM outputs to control the speeds of 2 -fans. Writing a 2 to any of the two pwm[1-2]_enable sysfs nodes will put the -PWM controller in automatic mode. There is only a single controller that -controls both PWM outputs but each PWM output can be individually enabled and -disabled. - -Each PWM has 4 associated distinct output duty-cycles: full, high, low and -off. Full and off are internally hard-wired to 255 (100%) and 0 (0%), -respectively. High and low can be programmed via -pwm[1-2]_auto_point[2-3]_pwm. Each PWM output can be associated with a -different thermal input but - and here's the weird part - only one set of -thermal thresholds exist that controls both PWMs output duty-cycles. The -thermal thresholds are accessible via pwm[1-2]_auto_point[1-4]_temp. Note -that even though there are 2 sets of 4 auto points each, they map to the same -registers in the VT1211 and programming one set is sufficient (actually only -the first set pwm1_auto_point[1-4]_temp is writable, the second set is -read-only). - -PWM Auto Point PWM Output Duty-Cycle ------------------------------------------------- -pwm[1-2]_auto_point4_pwm full speed duty-cycle (hard-wired to 255) -pwm[1-2]_auto_point3_pwm high speed duty-cycle -pwm[1-2]_auto_point2_pwm low speed duty-cycle -pwm[1-2]_auto_point1_pwm off duty-cycle (hard-wired to 0) - -Temp Auto Point Thermal Threshold ---------------------------------------------- -pwm[1-2]_auto_point4_temp full speed temp -pwm[1-2]_auto_point3_temp high speed temp -pwm[1-2]_auto_point2_temp low speed temp -pwm[1-2]_auto_point1_temp off temp - -Long story short, the controller implements the following algorithm to set the -PWM output duty-cycle based on the input temperature: - -Thermal Threshold Output Duty-Cycle - (Rising Temp) (Falling Temp) ----------------------------------------------------------- - full speed duty-cycle full speed duty-cycle -full speed temp - high speed duty-cycle full speed duty-cycle -high speed temp - low speed duty-cycle high speed duty-cycle -low speed temp - off duty-cycle low speed duty-cycle -off temp diff --git a/trunk/Documentation/hwmon/w83627ehf b/trunk/Documentation/hwmon/w83627ehf deleted file mode 100644 index fae3b781d82d..000000000000 --- a/trunk/Documentation/hwmon/w83627ehf +++ /dev/null @@ -1,85 +0,0 @@ -Kernel driver w83627ehf -======================= - -Supported chips: - * Winbond W83627EHF/EHG (ISA access ONLY) - Prefix: 'w83627ehf' - Addresses scanned: ISA address retrieved from Super I/O registers - Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf - -Authors: - Jean Delvare - Yuan Mu (Winbond) - Rudolf Marek - -Description ------------ - -This driver implements support for the Winbond W83627EHF and W83627EHG -super I/O chips. We will refer to them collectively as Winbond chips. - -The chips implement three temperature sensors, five fan rotation -speed sensors, ten analog voltage sensors, alarms with beep warnings (control -unimplemented), and some automatic fan regulation strategies (plus manual -fan control mode). - -Temperatures are measured in degrees Celsius and measurement resolution is 1 -degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when -the temperature gets higher than high limit; it stays on until the temperature -falls below the Hysteresis value. - -Fan rotation speeds are reported in RPM (rotations per minute). An alarm is -triggered if the rotation speed has dropped below a programmable limit. Fan -readings can be divided by a programmable divider (1, 2, 4, 8, 16, 32, 64 or -128) to give the readings more range or accuracy. The driver sets the most -suitable fan divisor itself. Some fans might not be present because they -share pins with other functions. - -Voltage sensors (also known as IN sensors) report their values in millivolts. -An alarm is triggered if the voltage has crossed a programmable minimum -or maximum limit. - -The driver supports automatic fan control mode known as Thermal Cruise. -In this mode, the chip attempts to keep the measured temperature in a -predefined temperature range. If the temperature goes out of range, fan -is driven slower/faster to reach the predefined range again. - -The mode works for fan1-fan4. Mapping of temperatures to pwm outputs is as -follows: - -temp1 -> pwm1 -temp2 -> pwm2 -temp3 -> pwm3 -prog -> pwm4 (the programmable setting is not supported by the driver) - -/sys files ----------- - -pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range: - 0 (stop) to 255 (full) - -pwm[1-4]_enable - this file controls mode of fan/temperature control: - * 1 Manual Mode, write to pwm file any value 0-255 (full speed) - * 2 Thermal Cruise - -Thermal Cruise mode -------------------- - -If the temperature is in the range defined by: - -pwm[1-4]_target - set target temperature, unit millidegree Celcius - (range 0 - 127000) -pwm[1-4]_tolerance - tolerance, unit millidegree Celcius (range 0 - 15000) - -there are no changes to fan speed. Once the temperature leaves the interval, -fan speed increases (temp is higher) or decreases if lower than desired. -There are defined steps and times, but not exported by the driver yet. - -pwm[1-4]_min_output - minimum fan speed (range 1 - 255), when the temperature - is below defined range. -pwm[1-4]_stop_time - how many milliseconds [ms] must elapse to switch - corresponding fan off. (when the temperature was below - defined range). - -Note: last two functions are influenced by other control bits, not yet exported - by the driver, so a change might not have any effect. diff --git a/trunk/Documentation/hwmon/w83791d b/trunk/Documentation/hwmon/w83791d index 19b2ed739fa1..83a3836289c2 100644 --- a/trunk/Documentation/hwmon/w83791d +++ b/trunk/Documentation/hwmon/w83791d @@ -5,7 +5,7 @@ Supported chips: * Winbond W83791D Prefix: 'w83791d' Addresses scanned: I2C 0x2c - 0x2f - Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83791D_W83791Gb.pdf + Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83791Da.pdf Author: Charles Spirakis @@ -20,9 +20,6 @@ Credits: Chunhao Huang , Rudolf Marek -Additional contributors: - Sven Anders - Module Parameters ----------------- @@ -49,8 +46,7 @@ Module Parameters Description ----------- -This driver implements support for the Winbond W83791D chip. The W83791G -chip appears to be the same as the W83791D but is lead free. +This driver implements support for the Winbond W83791D chip. Detection of the chip can sometimes be foiled because it can be in an internal state that allows no clean access (Bank with ID register is not @@ -75,36 +71,34 @@ Voltage sensors (also known as IN sensors) report their values in millivolts. An alarm is triggered if the voltage has crossed a programmable minimum or maximum limit. -The bit ordering for the alarm "realtime status register" and the -"beep enable registers" are different. - -in0 (VCORE) : alarms: 0x000001 beep_enable: 0x000001 -in1 (VINR0) : alarms: 0x000002 beep_enable: 0x002000 <== mismatch -in2 (+3.3VIN): alarms: 0x000004 beep_enable: 0x000004 -in3 (5VDD) : alarms: 0x000008 beep_enable: 0x000008 -in4 (+12VIN) : alarms: 0x000100 beep_enable: 0x000100 -in5 (-12VIN) : alarms: 0x000200 beep_enable: 0x000200 -in6 (-5VIN) : alarms: 0x000400 beep_enable: 0x000400 -in7 (VSB) : alarms: 0x080000 beep_enable: 0x010000 <== mismatch -in8 (VBAT) : alarms: 0x100000 beep_enable: 0x020000 <== mismatch -in9 (VINR1) : alarms: 0x004000 beep_enable: 0x004000 -temp1 : alarms: 0x000010 beep_enable: 0x000010 -temp2 : alarms: 0x000020 beep_enable: 0x000020 -temp3 : alarms: 0x002000 beep_enable: 0x000002 <== mismatch -fan1 : alarms: 0x000040 beep_enable: 0x000040 -fan2 : alarms: 0x000080 beep_enable: 0x000080 -fan3 : alarms: 0x000800 beep_enable: 0x000800 -fan4 : alarms: 0x200000 beep_enable: 0x200000 -fan5 : alarms: 0x400000 beep_enable: 0x400000 -tart1 : alarms: 0x010000 beep_enable: 0x040000 <== mismatch -tart2 : alarms: 0x020000 beep_enable: 0x080000 <== mismatch -tart3 : alarms: 0x040000 beep_enable: 0x100000 <== mismatch -case_open : alarms: 0x001000 beep_enable: 0x001000 -user_enable : alarms: -------- beep_enable: 0x800000 - -*** NOTE: It is the responsibility of user-space code to handle the fact -that the beep enable and alarm bits are in different positions when using that -feature of the chip. +Alarms are provided as output from a "realtime status register". The +following bits are defined: + +bit - alarm on: +0 - Vcore +1 - VINR0 +2 - +3.3VIN +3 - 5VDD +4 - temp1 +5 - temp2 +6 - fan1 +7 - fan2 +8 - +12VIN +9 - -12VIN +10 - -5VIN +11 - fan3 +12 - chassis +13 - temp3 +14 - VINR1 +15 - reserved +16 - tart1 +17 - tart2 +18 - tart3 +19 - VSB +20 - VBAT +21 - fan4 +22 - fan5 +23 - reserved When an alarm goes off, you can be warned by a beeping signal through your computer speaker. It is possible to enable all beeping globally, or only @@ -115,6 +109,5 @@ often will do no harm, but will return 'old' values. W83791D TODO: --------------- -Provide a patch for per-file alarms and beep enables as defined in the hwmon - documentation (Documentation/hwmon/sysfs-interface) +Provide a patch for per-file alarms as discussed on the mailing list Provide a patch for smart-fan control (still need appropriate motherboard/fans) diff --git a/trunk/Documentation/i2c/busses/i2c-viapro b/trunk/Documentation/i2c/busses/i2c-viapro index 25680346e0ac..16775663b9f5 100644 --- a/trunk/Documentation/i2c/busses/i2c-viapro +++ b/trunk/Documentation/i2c/busses/i2c-viapro @@ -7,12 +7,9 @@ Supported adapters: * VIA Technologies, Inc. VT82C686A/B Datasheet: Sometimes available at the VIA website - * VIA Technologies, Inc. VT8231, VT8233, VT8233A + * VIA Technologies, Inc. VT8231, VT8233, VT8233A, VT8235, VT8237R Datasheet: available on request from VIA - * VIA Technologies, Inc. VT8235, VT8237R, VT8237A, VT8251 - Datasheet: available on request and under NDA from VIA - Authors: Kyösti Mälkki , Mark D. Studebaker , @@ -42,8 +39,6 @@ Your lspci -n listing must show one of these : device 1106:8235 (VT8231 function 4) device 1106:3177 (VT8235) device 1106:3227 (VT8237R) - device 1106:3337 (VT8237A) - device 1106:3287 (VT8251) If none of these show up, you should look in the BIOS for settings like enable ACPI / SMBus or even USB. diff --git a/trunk/Documentation/i2c/i2c-stub b/trunk/Documentation/i2c/i2c-stub index 9cc081e69764..d6dcb138abf5 100644 --- a/trunk/Documentation/i2c/i2c-stub +++ b/trunk/Documentation/i2c/i2c-stub @@ -6,12 +6,9 @@ This module is a very simple fake I2C/SMBus driver. It implements four types of SMBus commands: write quick, (r/w) byte, (r/w) byte data, and (r/w) word data. -You need to provide a chip address as a module parameter when loading -this driver, which will then only react to SMBus commands to this address. - No hardware is needed nor associated with this module. It will accept write -quick commands to one address; it will respond to the other commands (also -to one address) by reading from or writing to an array in memory. It will +quick commands to all addresses; it will respond to the other commands (also +to all addresses) by reading from or writing to an array in memory. It will also spam the kernel logs for every command it handles. A pointer register with auto-increment is implemented for all byte @@ -24,11 +21,6 @@ The typical use-case is like this: 3. load the target sensors chip driver module 4. observe its behavior in the kernel log -PARAMETERS: - -int chip_addr: - The SMBus address to emulate a chip at. - CAVEATS: There are independent arrays for byte/data and word/data commands. Depending @@ -41,9 +33,6 @@ If the hardware for your driver has banked registers (e.g. Winbond sensors chips) this module will not work well - although it could be extended to support that pretty easily. -Only one chip address is supported - although this module could be -extended to support more. - If you spam it hard enough, printk can be lossy. This module really wants something like relayfs. diff --git a/trunk/Documentation/input/ff.txt b/trunk/Documentation/input/ff.txt index c53b1c11aa40..c7e10eaff203 100644 --- a/trunk/Documentation/input/ff.txt +++ b/trunk/Documentation/input/ff.txt @@ -1,37 +1,67 @@ Force feedback for Linux. By Johann Deneux on 2001/04/22. -Updated by Anssi Hannula on 2006/04/09. You may redistribute this file. Please remember to include shape.fig and interactive.fig as well. ---------------------------------------------------------------------------- -1. Introduction +0. Introduction ~~~~~~~~~~~~~~~ This document describes how to use force feedback devices under Linux. The goal is not to support these devices as if they were simple input-only devices (as it is already the case), but to really enable the rendering of force effects. -This document only describes the force feedback part of the Linux input -interface. Please read joystick.txt and input.txt before reading further this -document. +At the moment, only I-Force devices are supported, and not officially. That +means I had to find out how the protocol works on my own. Of course, the +information I managed to grasp is far from being complete, and I can not +guarranty that this driver will work for you. +This document only describes the force feedback part of the driver for I-Force +devices. Please read joystick.txt before reading further this document. 2. Instructions to the user ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To enable force feedback, you have to: - -1. have your kernel configured with evdev and a driver that supports your - device. -2. make sure evdev module is loaded and /dev/input/event* device files are - created. +Here are instructions on how to compile and use the driver. In fact, this +driver is the normal iforce, input and evdev drivers written by Vojtech +Pavlik, plus additions to support force feedback. Before you start, let me WARN you that some devices shake violently during the initialisation phase. This happens for example with my "AVB Top Shot Pegasus". To stop this annoying behaviour, move you joystick to its limits. Anyway, you -should keep a hand on your device, in order to avoid it to break down if +should keep a hand on your device, in order to avoid it to brake down if something goes wrong. -If you have a serial iforce device, you need to start inputattach. See -joystick.txt for details. +At the kernel's compilation: + - Enable IForce/Serial + - Enable Event interface + +Compile the modules, install them. + +You also need inputattach. + +You then need to insert the modules into the following order: +% modprobe joydev +% modprobe serport # Only for serial +% modprobe iforce +% modprobe evdev +% ./inputattach -ifor $2 & # Only for serial +If you are using USB, you don't need the inputattach step. + +Please check that you have all the /dev/input entries needed: +cd /dev +rm js* +mkdir input +mknod input/js0 c 13 0 +mknod input/js1 c 13 1 +mknod input/js2 c 13 2 +mknod input/js3 c 13 3 +ln -s input/js0 js0 +ln -s input/js1 js1 +ln -s input/js2 js2 +ln -s input/js3 js3 + +mknod input/event0 c 13 64 +mknod input/event1 c 13 65 +mknod input/event2 c 13 66 +mknod input/event3 c 13 67 2.1 Does it work ? ~~~~~~~~~~~~~~~~~~ @@ -40,9 +70,9 @@ There is an utility called fftest that will allow you to test the driver. 3. Instructions to the developper ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -All interactions are done using the event API. That is, you can use ioctl() + All interactions are done using the event API. That is, you can use ioctl() and write() on /dev/input/eventXX. -This information is subject to change. + This information is subject to change. 3.1 Querying device capabilities ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -56,29 +86,18 @@ int ioctl(int file_descriptor, int request, unsigned long *features); Returns the features supported by the device. features is a bitfield with the following bits: +- FF_X has an X axis (usually joysticks) +- FF_Y has an Y axis (usually joysticks) +- FF_WHEEL has a wheel (usually sterring wheels) - FF_CONSTANT can render constant force effects -- FF_PERIODIC can render periodic effects with the following waveforms: - - FF_SQUARE square waveform - - FF_TRIANGLE triangle waveform - - FF_SINE sine waveform - - FF_SAW_UP sawtooth up waveform - - FF_SAW_DOWN sawtooth down waveform - - FF_CUSTOM custom waveform +- FF_PERIODIC can render periodic effects (sine, triangle, square...) - FF_RAMP can render ramp effects - FF_SPRING can simulate the presence of a spring -- FF_FRICTION can simulate friction +- FF_FRICTION can simulate friction - FF_DAMPER can simulate damper effects -- FF_RUMBLE rumble effects +- FF_RUMBLE rumble effects (normally the only effect supported by rumble + pads) - FF_INERTIA can simulate inertia -- FF_GAIN gain is adjustable -- FF_AUTOCENTER autocenter is adjustable - -Note: In most cases you should use FF_PERIODIC instead of FF_RUMBLE. All - devices that support FF_RUMBLE support FF_PERIODIC (square, triangle, - sine) and the other way around. - -Note: The exact syntax FF_CUSTOM is undefined for the time being as no driver - supports it yet. int ioctl(int fd, EVIOCGEFFECTS, int *n); @@ -89,7 +108,7 @@ Returns the number of effects the device can keep in its memory. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #include #include - + int ioctl(int file_descriptor, int request, struct ff_effect *effect); "request" must be EVIOCSFF. @@ -101,9 +120,6 @@ to the unique id assigned by the driver. This data is required for performing some operations (removing an effect, controlling the playback). This if field must be set to -1 by the user in order to tell the driver to allocate a new effect. - -Effects are file descriptor specific. - See for a description of the ff_effect struct. You should also find help in a few sketches, contained in files shape.fig and interactive.fig. You need xfig to visualize these files. @@ -112,8 +128,8 @@ You need xfig to visualize these files. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ int ioctl(int fd, EVIOCRMFF, effect.id); -This makes room for new effects in the device's memory. Note that this also -stops the effect if it was playing. +This makes room for new effects in the device's memory. Please note this won't +stop the effect if it was playing. 3.4 Controlling the playback of effects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -133,21 +149,22 @@ Control of playing is done with write(). Below is an example: play.type = EV_FF; play.code = effect.id; play.value = 3; - + write(fd, (const void*) &play, sizeof(play)); ... /* Stop an effect */ stop.type = EV_FF; stop.code = effect.id; stop.value = 0; - + write(fd, (const void*) &play, sizeof(stop)); 3.5 Setting the gain ~~~~~~~~~~~~~~~~~~~~ Not all devices have the same strength. Therefore, users should set a gain factor depending on how strong they want effects to be. This setting is -persistent across access to the driver. +persistent across access to the driver, so you should not care about it if +you are writing games, as another utility probably already set this for you. /* Set the gain of the device int gain; /* between 0 and 100 */ @@ -187,14 +204,11 @@ type of device, not all parameters can be dynamically updated. For example, the direction of an effect cannot be updated with iforce devices. In this case, the driver stops the effect, up-load it, and restart it. -Therefore it is recommended to dynamically change direction while the effect -is playing only when it is ok to restart the effect with a replay count of 1. 3.8 Information about the status of effects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Every time the status of an effect is changed, an event is sent. The values and meanings of the fields of the event are as follows: - struct input_event { /* When the status of the effect changed */ struct timeval time; @@ -211,9 +225,3 @@ struct input_event { FF_STATUS_STOPPED The effect stopped playing FF_STATUS_PLAYING The effect started to play - -NOTE: Status feedback is only supported by iforce driver. If you have - a really good reason to use this, please contact - linux-joystick@atrey.karlin.mff.cuni.cz or anssi.hannula@gmail.com - so that support for it can be added to the rest of the drivers. - diff --git a/trunk/Documentation/kbuild/makefiles.txt b/trunk/Documentation/kbuild/makefiles.txt index e2cbd59cf2d0..b7d6abb501a6 100644 --- a/trunk/Documentation/kbuild/makefiles.txt +++ b/trunk/Documentation/kbuild/makefiles.txt @@ -421,11 +421,6 @@ more details, with real examples. The second argument is optional, and if supplied will be used if first argument is not supported. - as-instr - as-instr checks if the assembler reports a specific instruction - and then outputs either option1 or option2 - C escapes are supported in the test instruction - cc-option cc-option is used to check if $(CC) supports a given option, and not supported to use an optional second option. diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 137e993f4329..766abdab94e7 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -110,13 +110,6 @@ be entered as an environment variable, whereas its absence indicates that it will appear as a kernel argument readable via /proc/cmdline by programs running once the system is up. -The number of kernel parameters is not limited, but the length of the -complete command line (parameters including spaces etc.) is limited to -a fixed number of characters. This limit depends on the architecture -and is between 256 and 4096 characters. It is defined in the file -./include/asm/setup.h as COMMAND_LINE_SIZE. - - 53c7xx= [HW,SCSI] Amiga SCSI controllers See header of drivers/scsi/53c7xx.c. See also Documentation/scsi/ncr53c7xx.txt. @@ -580,6 +573,8 @@ and is between 256 and 4096 characters. It is defined in the file gscd= [HW,CD] Format: + gt96100eth= [NET] MIPS GT96100 Advanced Communication Controller + gus= [HW,OSS] Format: ,,, @@ -1245,11 +1240,7 @@ and is between 256 and 4096 characters. It is defined in the file bootloader. This is currently used on IXP2000 systems where the bus has to be configured a certain way for adjunct CPUs. - noearly [X86] Don't do any early type 1 scanning. - This might help on some broken boards which - machine check when some devices' config space - is read. But various workarounds are disabled - and some IOMMU drivers will not work. + pcmv= [HW,PCMCIA] BadgePAD 4 pd. [PARIDE] @@ -1331,7 +1322,7 @@ and is between 256 and 4096 characters. It is defined in the file pt. [PARIDE] See Documentation/paride.txt. - quiet [KNL] Disable most log messages + quiet= [KNL] Disable log messages r128= [HW,DRM] @@ -1377,9 +1368,6 @@ and is between 256 and 4096 characters. It is defined in the file Reserves a hole at the top of the kernel virtual address space. - reset_devices [KNL] Force drivers to reset the underlying device - during initialization. - resume= [SWSUSP] Specify the partition device for software suspend diff --git a/trunk/Documentation/kprobes.txt b/trunk/Documentation/kprobes.txt index ba26201d5023..2c3b1eae4280 100644 --- a/trunk/Documentation/kprobes.txt +++ b/trunk/Documentation/kprobes.txt @@ -151,9 +151,9 @@ So that you can load and unload Kprobes-based instrumentation modules, make sure "Loadable module support" (CONFIG_MODULES) and "Module unloading" (CONFIG_MODULE_UNLOAD) are set to "y". -Also make sure that CONFIG_KALLSYMS and perhaps even CONFIG_KALLSYMS_ALL -are set to "y", since kallsyms_lookup_name() is used by the in-kernel -kprobe address resolution code. +You may also want to ensure that CONFIG_KALLSYMS and perhaps even +CONFIG_KALLSYMS_ALL are set to "y", since kallsyms_lookup_name() +is a handy, version-independent way to find a function's address. If you need to insert a probe in the middle of a function, you may find it useful to "Compile the kernel with debug info" (CONFIG_DEBUG_INFO), @@ -179,27 +179,6 @@ occurs during execution of kp->pre_handler or kp->post_handler, or during single-stepping of the probed instruction, Kprobes calls kp->fault_handler. Any or all handlers can be NULL. -NOTE: -1. With the introduction of the "symbol_name" field to struct kprobe, -the probepoint address resolution will now be taken care of by the kernel. -The following will now work: - - kp.symbol_name = "symbol_name"; - -(64-bit powerpc intricacies such as function descriptors are handled -transparently) - -2. Use the "offset" field of struct kprobe if the offset into the symbol -to install a probepoint is known. This field is used to calculate the -probepoint. - -3. Specify either the kprobe "symbol_name" OR the "addr". If both are -specified, kprobe registration will fail with -EINVAL. - -4. With CISC architectures (such as i386 and x86_64), the kprobes code -does not validate if the kprobe.addr is at an instruction boundary. -Use "offset" with caution. - register_kprobe() returns 0 on success, or a negative errno otherwise. User's pre-handler (kp->pre_handler): @@ -246,12 +225,6 @@ control to Kprobes.) If the probed function is declared asmlinkage, fastcall, or anything else that affects how args are passed, the handler's declaration must match. -NOTE: A macro JPROBE_ENTRY is provided to handle architecture-specific -aliasing of jp->entry. In the interest of portability, it is advised -to use: - - jp->entry = JPROBE_ENTRY(handler); - register_jprobe() returns 0 on success, or a negative errno otherwise. 4.3 register_kretprobe @@ -278,11 +251,6 @@ of interest: - ret_addr: the return address - rp: points to the corresponding kretprobe object - task: points to the corresponding task struct - -The regs_return_value(regs) macro provides a simple abstraction to -extract the return value from the appropriate register as defined by -the architecture's ABI. - The handler's return value is currently ignored. 4.4 unregister_*probe @@ -401,6 +369,7 @@ stack trace and selected i386 registers when do_fork() is called. #include #include #include +#include #include /*For each probe you need to allocate a kprobe structure*/ @@ -434,14 +403,18 @@ int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr) return 0; } -static int __init kprobe_init(void) +int init_module(void) { int ret; kp.pre_handler = handler_pre; kp.post_handler = handler_post; kp.fault_handler = handler_fault; - kp.symbol_name = "do_fork"; - + kp.addr = (kprobe_opcode_t*) kallsyms_lookup_name("do_fork"); + /* register the kprobe now */ + if (!kp.addr) { + printk("Couldn't find %s to plant kprobe\n", "do_fork"); + return -1; + } if ((ret = register_kprobe(&kp) < 0)) { printk("register_kprobe failed, returned %d\n", ret); return -1; @@ -450,14 +423,12 @@ static int __init kprobe_init(void) return 0; } -static void __exit kprobe_exit(void) +void cleanup_module(void) { unregister_kprobe(&kp); printk("kprobe unregistered\n"); } -module_init(kprobe_init) -module_exit(kprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -492,6 +463,7 @@ the arguments of do_fork(). #include #include #include +#include /* * Jumper probe for do_fork. @@ -513,13 +485,17 @@ long jdo_fork(unsigned long clone_flags, unsigned long stack_start, } static struct jprobe my_jprobe = { - .entry = JPROBE_ENTRY(jdo_fork) + .entry = (kprobe_opcode_t *) jdo_fork }; -static int __init jprobe_init(void) +int init_module(void) { int ret; - my_jprobe.kp.symbol_name = "do_fork"; + my_jprobe.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("do_fork"); + if (!my_jprobe.kp.addr) { + printk("Couldn't find %s to plant jprobe\n", "do_fork"); + return -1; + } if ((ret = register_jprobe(&my_jprobe)) <0) { printk("register_jprobe failed, returned %d\n", ret); @@ -530,14 +506,12 @@ static int __init jprobe_init(void) return 0; } -static void __exit jprobe_exit(void) +void cleanup_module(void) { unregister_jprobe(&my_jprobe); printk("jprobe unregistered\n"); } -module_init(jprobe_init) -module_exit(jprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -556,13 +530,16 @@ report failed calls to sys_open(). #include #include #include +#include static const char *probed_func = "sys_open"; /* Return-probe handler: If the probed function fails, log the return value. */ static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) { - int retval = regs_return_value(regs); + // Substitute the appropriate register name for your architecture -- + // e.g., regs->rax for x86_64, regs->gpr[3] for ppc64. + int retval = (int) regs->eax; if (retval < 0) { printk("%s returns %d\n", probed_func, retval); } @@ -575,11 +552,15 @@ static struct kretprobe my_kretprobe = { .maxactive = 20 }; -static int __init kretprobe_init(void) +int init_module(void) { int ret; - my_kretprobe.kp.symbol_name = (char *)probed_func; - + my_kretprobe.kp.addr = + (kprobe_opcode_t *) kallsyms_lookup_name(probed_func); + if (!my_kretprobe.kp.addr) { + printk("Couldn't find %s to plant return probe\n", probed_func); + return -1; + } if ((ret = register_kretprobe(&my_kretprobe)) < 0) { printk("register_kretprobe failed, returned %d\n", ret); return -1; @@ -588,7 +569,7 @@ static int __init kretprobe_init(void) return 0; } -static void __exit kretprobe_exit(void) +void cleanup_module(void) { unregister_kretprobe(&my_kretprobe); printk("kretprobe unregistered\n"); @@ -597,8 +578,6 @@ static void __exit kretprobe_exit(void) my_kretprobe.nmissed, probed_func); } -module_init(kretprobe_init) -module_exit(kretprobe_exit) MODULE_LICENSE("GPL"); ----- cut here ----- @@ -611,5 +590,3 @@ messages.) For additional information on Kprobes, refer to the following URLs: http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe http://www.redhat.com/magazine/005mar05/features/kprobes/ -http://www-users.cs.umn.edu/~boutcher/kprobes/ -http://www.linuxsymposium.org/2006/linuxsymposium_procv2.pdf (pages 101-115) diff --git a/trunk/Documentation/lockdep-design.txt b/trunk/Documentation/lockdep-design.txt index 55a7e4fa8cc2..00d93605bfd3 100644 --- a/trunk/Documentation/lockdep-design.txt +++ b/trunk/Documentation/lockdep-design.txt @@ -36,28 +36,6 @@ The validator tracks lock-class usage history into 5 separate state bits: - 'ever used' [ == !unused ] -When locking rules are violated, these 4 state bits are presented in the -locking error messages, inside curlies. A contrived example: - - modprobe/2287 is trying to acquire lock: - (&sio_locks[i].lock){--..}, at: [] mutex_lock+0x21/0x24 - - but task is already holding lock: - (&sio_locks[i].lock){--..}, at: [] mutex_lock+0x21/0x24 - - -The bit position indicates hardirq, softirq, hardirq-read, -softirq-read respectively, and the character displayed in each -indicates: - - '.' acquired while irqs enabled - '+' acquired in irq context - '-' acquired in process context with irqs disabled - '?' read-acquired both with irqs enabled and in irq context - -Unused mutexes cannot be part of the cause of an error. - - Single-lock state rules: ------------------------ diff --git a/trunk/Documentation/networking/pktgen.txt b/trunk/Documentation/networking/pktgen.txt index 18d385c068fc..44f2f769e865 100644 --- a/trunk/Documentation/networking/pktgen.txt +++ b/trunk/Documentation/networking/pktgen.txt @@ -100,7 +100,6 @@ Examples: are: IPSRC_RND #IP Source is random (between min/max), IPDST_RND, UDPSRC_RND, UDPDST_RND, MACSRC_RND, MACDST_RND - MPLS_RND, VID_RND, SVID_RND pgset "udp_src_min 9" set UDP source port min, If < udp_src_max, then cycle through the port range. @@ -126,21 +125,6 @@ Examples: pgset "mpls 0" turn off mpls (or any invalid argument works too!) - pgset "vlan_id 77" set VLAN ID 0-4095 - pgset "vlan_p 3" set priority bit 0-7 (default 0) - pgset "vlan_cfi 0" set canonical format identifier 0-1 (default 0) - - pgset "svlan_id 22" set SVLAN ID 0-4095 - pgset "svlan_p 3" set priority bit 0-7 (default 0) - pgset "svlan_cfi 0" set canonical format identifier 0-1 (default 0) - - pgset "vlan_id 9999" > 4095 remove vlan and svlan tags - pgset "svlan 9999" > 4095 remove svlan tag - - - pgset "tos XX" set former IPv4 TOS field (e.g. "tos 28" for AF11 no ECN, default 00) - pgset "traffic_class XX" set former IPv6 TRAFFIC CLASS (e.g. "traffic_class B8" for EF no ECN, default 00) - pgset stop aborts injection. Also, ^C aborts generator. diff --git a/trunk/Documentation/nommu-mmap.txt b/trunk/Documentation/nommu-mmap.txt index 7714f57caad5..b88ebe4d808c 100644 --- a/trunk/Documentation/nommu-mmap.txt +++ b/trunk/Documentation/nommu-mmap.txt @@ -116,9 +116,6 @@ FURTHER NOTES ON NO-MMU MMAP (*) A list of all the mappings on the system is visible through /proc/maps in no-MMU mode. - (*) A list of all the mappings in use by a process is visible through - /proc//maps in no-MMU mode. - (*) Supplying MAP_FIXED or a requesting a particular mapping address will result in an error. @@ -128,49 +125,6 @@ FURTHER NOTES ON NO-MMU MMAP error will result if they don't. This is most likely to be encountered with character device files, pipes, fifos and sockets. - -========================== -INTERPROCESS SHARED MEMORY -========================== - -Both SYSV IPC SHM shared memory and POSIX shared memory is supported in NOMMU -mode. The former through the usual mechanism, the latter through files created -on ramfs or tmpfs mounts. - - -======= -FUTEXES -======= - -Futexes are supported in NOMMU mode if the arch supports them. An error will -be given if an address passed to the futex system call lies outside the -mappings made by a process or if the mapping in which the address lies does not -support futexes (such as an I/O chardev mapping). - - -============= -NO-MMU MREMAP -============= - -The mremap() function is partially supported. It may change the size of a -mapping, and may move it[*] if MREMAP_MAYMOVE is specified and if the new size -of the mapping exceeds the size of the slab object currently occupied by the -memory to which the mapping refers, or if a smaller slab object could be used. - -MREMAP_FIXED is not supported, though it is ignored if there's no change of -address and the object does not need to be moved. - -Shared mappings may not be moved. Shareable mappings may not be moved either, -even if they are not currently shared. - -The mremap() function must be given an exact match for base address and size of -a previously mapped object. It may not be used to create holes in existing -mappings, move parts of existing mappings or resize parts of mappings. It must -act on a complete mapping. - -[*] Not currently supported. - - ============================================ PROVIDING SHAREABLE CHARACTER DEVICE SUPPORT ============================================ diff --git a/trunk/Documentation/pcieaer-howto.txt b/trunk/Documentation/pcieaer-howto.txt deleted file mode 100644 index 16c251230c82..000000000000 --- a/trunk/Documentation/pcieaer-howto.txt +++ /dev/null @@ -1,253 +0,0 @@ - The PCI Express Advanced Error Reporting Driver Guide HOWTO - T. Long Nguyen - Yanmin Zhang - 07/29/2006 - - -1. Overview - -1.1 About this guide - -This guide describes the basics of the PCI Express Advanced Error -Reporting (AER) driver and provides information on how to use it, as -well as how to enable the drivers of endpoint devices to conform with -PCI Express AER driver. - -1.2 Copyright © Intel Corporation 2006. - -1.3 What is the PCI Express AER Driver? - -PCI Express error signaling can occur on the PCI Express link itself -or on behalf of transactions initiated on the link. PCI Express -defines two error reporting paradigms: the baseline capability and -the Advanced Error Reporting capability. The baseline capability is -required of all PCI Express components providing a minimum defined -set of error reporting requirements. Advanced Error Reporting -capability is implemented with a PCI Express advanced error reporting -extended capability structure providing more robust error reporting. - -The PCI Express AER driver provides the infrastructure to support PCI -Express Advanced Error Reporting capability. The PCI Express AER -driver provides three basic functions: - -- Gathers the comprehensive error information if errors occurred. -- Reports error to the users. -- Performs error recovery actions. - -AER driver only attaches root ports which support PCI-Express AER -capability. - - -2. User Guide - -2.1 Include the PCI Express AER Root Driver into the Linux Kernel - -The PCI Express AER Root driver is a Root Port service driver attached -to the PCI Express Port Bus driver. If a user wants to use it, the driver -has to be compiled. Option CONFIG_PCIEAER supports this capability. It -depends on CONFIG_PCIEPORTBUS, so pls. set CONFIG_PCIEPORTBUS=y and -CONFIG_PCIEAER = y. - -2.2 Load PCI Express AER Root Driver -There is a case where a system has AER support in BIOS. Enabling the AER -Root driver and having AER support in BIOS may result unpredictable -behavior. To avoid this conflict, a successful load of the AER Root driver -requires ACPI _OSC support in the BIOS to allow the AER Root driver to -request for native control of AER. See the PCI FW 3.0 Specification for -details regarding OSC usage. Currently, lots of firmwares don't provide -_OSC support while they use PCI Express. To support such firmwares, -forceload, a parameter of type bool, could enable AER to continue to -be initiated although firmwares have no _OSC support. To enable the -walkaround, pls. add aerdriver.forceload=y to kernel boot parameter line -when booting kernel. Note that forceload=n by default. - -2.3 AER error output -When a PCI-E AER error is captured, an error message will be outputed to -console. If it's a correctable error, it is outputed as a warning. -Otherwise, it is printed as an error. So users could choose different -log level to filter out correctable error messages. - -Below shows an example. -+------ PCI-Express Device Error -----+ -Error Severity : Uncorrected (Fatal) -PCIE Bus Error type : Transaction Layer -Unsupported Request : First -Requester ID : 0500 -VendorID=8086h, DeviceID=0329h, Bus=05h, Device=00h, Function=00h -TLB Header: -04000001 00200a03 05010000 00050100 - -In the example, 'Requester ID' means the ID of the device who sends -the error message to root port. Pls. refer to pci express specs for -other fields. - - -3. Developer Guide - -To enable AER aware support requires a software driver to configure -the AER capability structure within its device and to provide callbacks. - -To support AER better, developers need understand how AER does work -firstly. - -PCI Express errors are classified into two types: correctable errors -and uncorrectable errors. This classification is based on the impacts -of those errors, which may result in degraded performance or function -failure. - -Correctable errors pose no impacts on the functionality of the -interface. The PCI Express protocol can recover without any software -intervention or any loss of data. These errors are detected and -corrected by hardware. Unlike correctable errors, uncorrectable -errors impact functionality of the interface. Uncorrectable errors -can cause a particular transaction or a particular PCI Express link -to be unreliable. Depending on those error conditions, uncorrectable -errors are further classified into non-fatal errors and fatal errors. -Non-fatal errors cause the particular transaction to be unreliable, -but the PCI Express link itself is fully functional. Fatal errors, on -the other hand, cause the link to be unreliable. - -When AER is enabled, a PCI Express device will automatically send an -error message to the PCIE root port above it when the device captures -an error. The Root Port, upon receiving an error reporting message, -internally processes and logs the error message in its PCI Express -capability structure. Error information being logged includes storing -the error reporting agent's requestor ID into the Error Source -Identification Registers and setting the error bits of the Root Error -Status Register accordingly. If AER error reporting is enabled in Root -Error Command Register, the Root Port generates an interrupt if an -error is detected. - -Note that the errors as described above are related to the PCI Express -hierarchy and links. These errors do not include any device specific -errors because device specific errors will still get sent directly to -the device driver. - -3.1 Configure the AER capability structure - -AER aware drivers of PCI Express component need change the device -control registers to enable AER. They also could change AER registers, -including mask and severity registers. Helper function -pci_enable_pcie_error_reporting could be used to enable AER. See -section 3.3. - -3.2. Provide callbacks - -3.2.1 callback reset_link to reset pci express link - -This callback is used to reset the pci express physical link when a -fatal error happens. The root port aer service driver provides a -default reset_link function, but different upstream ports might -have different specifications to reset pci express link, so all -upstream ports should provide their own reset_link functions. - -In struct pcie_port_service_driver, a new pointer, reset_link, is -added. - -pci_ers_result_t (*reset_link) (struct pci_dev *dev); - -Section 3.2.2.2 provides more detailed info on when to call -reset_link. - -3.2.2 PCI error-recovery callbacks - -The PCI Express AER Root driver uses error callbacks to coordinate -with downstream device drivers associated with a hierarchy in question -when performing error recovery actions. - -Data struct pci_driver has a pointer, err_handler, to point to -pci_error_handlers who consists of a couple of callback function -pointers. AER driver follows the rules defined in -pci-error-recovery.txt except pci express specific parts (e.g. -reset_link). Pls. refer to pci-error-recovery.txt for detailed -definitions of the callbacks. - -Below sections specify when to call the error callback functions. - -3.2.2.1 Correctable errors - -Correctable errors pose no impacts on the functionality of -the interface. The PCI Express protocol can recover without any -software intervention or any loss of data. These errors do not -require any recovery actions. The AER driver clears the device's -correctable error status register accordingly and logs these errors. - -3.2.2.2 Non-correctable (non-fatal and fatal) errors - -If an error message indicates a non-fatal error, performing link reset -at upstream is not required. The AER driver calls error_detected(dev, -pci_channel_io_normal) to all drivers associated within a hierarchy in -question. for example, -EndPoint<==>DownstreamPort B<==>UpstreamPort A<==>RootPort. -If Upstream port A captures an AER error, the hierarchy consists of -Downstream port B and EndPoint. - -A driver may return PCI_ERS_RESULT_CAN_RECOVER, -PCI_ERS_RESULT_DISCONNECT, or PCI_ERS_RESULT_NEED_RESET, depending on -whether it can recover or the AER driver calls mmio_enabled as next. - -If an error message indicates a fatal error, kernel will broadcast -error_detected(dev, pci_channel_io_frozen) to all drivers within -a hierarchy in question. Then, performing link reset at upstream is -necessary. As different kinds of devices might use different approaches -to reset link, AER port service driver is required to provide the -function to reset link. Firstly, kernel looks for if the upstream -component has an aer driver. If it has, kernel uses the reset_link -callback of the aer driver. If the upstream component has no aer driver -and the port is downstream port, we will use the aer driver of the -root port who reports the AER error. As for upstream ports, -they should provide their own aer service drivers with reset_link -function. If error_detected returns PCI_ERS_RESULT_CAN_RECOVER and -reset_link returns PCI_ERS_RESULT_RECOVERED, the error handling goes -to mmio_enabled. - -3.3 helper functions - -3.3.1 int pci_find_aer_capability(struct pci_dev *dev); -pci_find_aer_capability locates the PCI Express AER capability -in the device configuration space. If the device doesn't support -PCI-Express AER, the function returns 0. - -3.3.2 int pci_enable_pcie_error_reporting(struct pci_dev *dev); -pci_enable_pcie_error_reporting enables the device to send error -messages to root port when an error is detected. Note that devices -don't enable the error reporting by default, so device drivers need -call this function to enable it. - -3.3.3 int pci_disable_pcie_error_reporting(struct pci_dev *dev); -pci_disable_pcie_error_reporting disables the device to send error -messages to root port when an error is detected. - -3.3.4 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev); -pci_cleanup_aer_uncorrect_error_status cleanups the uncorrectable -error status register. - -3.4 Frequent Asked Questions - -Q: What happens if a PCI Express device driver does not provide an -error recovery handler (pci_driver->err_handler is equal to NULL)? - -A: The devices attached with the driver won't be recovered. If the -error is fatal, kernel will print out warning messages. Please refer -to section 3 for more information. - -Q: What happens if an upstream port service driver does not provide -callback reset_link? - -A: Fatal error recovery will fail if the errors are reported by the -upstream ports who are attached by the service driver. - -Q: How does this infrastructure deal with driver that is not PCI -Express aware? - -A: This infrastructure calls the error callback functions of the -driver when an error happens. But if the driver is not aware of -PCI Express, the device might not report its own errors to root -port. - -Q: What modifications will that driver need to make it compatible -with the PCI Express AER Root driver? - -A: It could call the helper functions to enable AER in devices and -cleanup uncorrectable status register. Pls. refer to section 3.3. - diff --git a/trunk/Documentation/power/devices.txt b/trunk/Documentation/power/devices.txt index d0e79d5820a5..fba1e05c47c7 100644 --- a/trunk/Documentation/power/devices.txt +++ b/trunk/Documentation/power/devices.txt @@ -1,553 +1,208 @@ -Most of the code in Linux is device drivers, so most of the Linux power -management code is also driver-specific. Most drivers will do very little; -others, especially for platforms with small batteries (like cell phones), -will do a lot. - -This writeup gives an overview of how drivers interact with system-wide -power management goals, emphasizing the models and interfaces that are -shared by everything that hooks up to the driver model core. Read it as -background for the domain-specific work you'd do with any specific driver. - - -Two Models for Device Power Management -====================================== -Drivers will use one or both of these models to put devices into low-power -states: - - System Sleep model: - Drivers can enter low power states as part of entering system-wide - low-power states like "suspend-to-ram", or (mostly for systems with - disks) "hibernate" (suspend-to-disk). - - This is something that device, bus, and class drivers collaborate on - by implementing various role-specific suspend and resume methods to - cleanly power down hardware and software subsystems, then reactivate - them without loss of data. - - Some drivers can manage hardware wakeup events, which make the system - leave that low-power state. This feature may be disabled using the - relevant /sys/devices/.../power/wakeup file; enabling it may cost some - power usage, but let the whole system enter low power states more often. - - Runtime Power Management model: - Drivers may also enter low power states while the system is running, - independently of other power management activity. Upstream drivers - will normally not know (or care) if the device is in some low power - state when issuing requests; the driver will auto-resume anything - that's needed when it gets a request. - - This doesn't have, or need much infrastructure; it's just something you - should do when writing your drivers. For example, clk_disable() unused - clocks as part of minimizing power drain for currently-unused hardware. - Of course, sometimes clusters of drivers will collaborate with each - other, which could involve task-specific power management. - -There's not a lot to be said about those low power states except that they -are very system-specific, and often device-specific. Also, that if enough -drivers put themselves into low power states (at "runtime"), the effect may be -the same as entering some system-wide low-power state (system sleep) ... and -that synergies exist, so that several drivers using runtime pm might put the -system into a state where even deeper power saving options are available. - -Most suspended devices will have quiesced all I/O: no more DMA or irqs, no -more data read or written, and requests from upstream drivers are no longer -accepted. A given bus or platform may have different requirements though. - -Examples of hardware wakeup events include an alarm from a real time clock, -network wake-on-LAN packets, keyboard or mouse activity, and media insertion -or removal (for PCMCIA, MMC/SD, USB, and so on). - - -Interfaces for Entering System Sleep States -=========================================== -Most of the programming interfaces a device driver needs to know about -relate to that first model: entering a system-wide low power state, -rather than just minimizing power consumption by one device. - - -Bus Driver Methods ------------------- -The core methods to suspend and resume devices reside in struct bus_type. -These are mostly of interest to people writing infrastructure for busses -like PCI or USB, or because they define the primitives that device drivers -may need to apply in domain-specific ways to their devices: -struct bus_type { - ... - int (*suspend)(struct device *dev, pm_message_t state); - int (*suspend_late)(struct device *dev, pm_message_t state); +Device Power Management - int (*resume_early)(struct device *dev); - int (*resume)(struct device *dev); -}; -Bus drivers implement those methods as appropriate for the hardware and -the drivers using it; PCI works differently from USB, and so on. Not many -people write bus drivers; most driver code is a "device driver" that -builds on top of bus-specific framework code. - -For more information on these driver calls, see the description later; -they are called in phases for every device, respecting the parent-child -sequencing in the driver model tree. Note that as this is being written, -only the suspend() and resume() are widely available; not many bus drivers -leverage all of those phases, or pass them down to lower driver levels. - - -/sys/devices/.../power/wakeup files ------------------------------------ -All devices in the driver model have two flags to control handling of -wakeup events, which are hardware signals that can force the device and/or -system out of a low power state. These are initialized by bus or device -driver code using device_init_wakeup(dev,can_wakeup). - -The "can_wakeup" flag just records whether the device (and its driver) can -physically support wakeup events. When that flag is clear, the sysfs -"wakeup" file is empty, and device_may_wakeup() returns false. - -For devices that can issue wakeup events, a separate flag controls whether -that device should try to use its wakeup mechanism. The initial value of -device_may_wakeup() will be true, so that the device's "wakeup" file holds -the value "enabled". Userspace can change that to "disabled" so that -device_may_wakeup() returns false; or change it back to "enabled" (so that -it returns true again). - - -EXAMPLE: PCI Device Driver Methods ------------------------------------ -PCI framework software calls these methods when the PCI device driver bound -to a device device has provided them: - -struct pci_driver { - ... - int (*suspend)(struct pci_device *pdev, pm_message_t state); - int (*suspend_late)(struct pci_device *pdev, pm_message_t state); - - int (*resume_early)(struct pci_device *pdev); - int (*resume)(struct pci_device *pdev); -}; +Device power management encompasses two areas - the ability to save +state and transition a device to a low-power state when the system is +entering a low-power state; and the ability to transition a device to +a low-power state while the system is running (and independently of +any other power management activity). -Drivers will implement those methods, and call PCI-specific procedures -like pci_set_power_state(), pci_enable_wake(), pci_save_state(), and -pci_restore_state() to manage PCI-specific mechanisms. (PCI config space -could be saved during driver probe, if it weren't for the fact that some -systems rely on userspace tweaking using setpci.) Devices are suspended -before their bridges enter low power states, and likewise bridges resume -before their devices. - - -Upper Layers of Driver Stacks ------------------------------ -Device drivers generally have at least two interfaces, and the methods -sketched above are the ones which apply to the lower level (nearer PCI, USB, -or other bus hardware). The network and block layers are examples of upper -level interfaces, as is a character device talking to userspace. - -Power management requests normally need to flow through those upper levels, -which often use domain-oriented requests like "blank that screen". In -some cases those upper levels will have power management intelligence that -relates to end-user activity, or other devices that work in cooperation. - -When those interfaces are structured using class interfaces, there is a -standard way to have the upper layer stop issuing requests to a given -class device (and restart later): - -struct class { - ... - int (*suspend)(struct device *dev, pm_message_t state); - int (*resume)(struct device *dev); -}; -Those calls are issued in specific phases of the process by which the -system enters a low power "suspend" state, or resumes from it. - - -Calling Drivers to Enter System Sleep States -============================================ -When the system enters a low power state, each device's driver is asked -to suspend the device by putting it into state compatible with the target -system state. That's usually some version of "off", but the details are -system-specific. Also, wakeup-enabled devices will usually stay partly -functional in order to wake the system. - -When the system leaves that low power state, the device's driver is asked -to resume it. The suspend and resume operations always go together, and -both are multi-phase operations. - -For simple drivers, suspend might quiesce the device using the class code -and then turn its hardware as "off" as possible with late_suspend. The -matching resume calls would then completely reinitialize the hardware -before reactivating its class I/O queues. - -More power-aware drivers drivers will use more than one device low power -state, either at runtime or during system sleep states, and might trigger -system wakeup events. - - -Call Sequence Guarantees ------------------------- -To ensure that bridges and similar links needed to talk to a device are -available when the device is suspended or resumed, the device tree is -walked in a bottom-up order to suspend devices. A top-down order is -used to resume those devices. - -The ordering of the device tree is defined by the order in which devices -get registered: a child can never be registered, probed or resumed before -its parent; and can't be removed or suspended after that parent. - -The policy is that the device tree should match hardware bus topology. -(Or at least the control bus, for devices which use multiple busses.) - - -Suspending Devices ------------------- -Suspending a given device is done in several phases. Suspending the -system always includes every phase, executing calls for every device -before the next phase begins. Not all busses or classes support all -these callbacks; and not all drivers use all the callbacks. - -The phases are seen by driver notifications issued in this order: - - 1 class.suspend(dev, message) is called after tasks are frozen, for - devices associated with a class that has such a method. This - method may sleep. - - Since I/O activity usually comes from such higher layers, this is - a good place to quiesce all drivers of a given type (and keep such - code out of those drivers). - - 2 bus.suspend(dev, message) is called next. This method may sleep, - and is often morphed into a device driver call with bus-specific - parameters and/or rules. - - This call should handle parts of device suspend logic that require - sleeping. It probably does work to quiesce the device which hasn't - been abstracted into class.suspend() or bus.suspend_late(). - - 3 bus.suspend_late(dev, message) is called with IRQs disabled, and - with only one CPU active. Until the bus.resume_early() phase - completes (see later), IRQs are not enabled again. This method - won't be exposed by all busses; for message based busses like USB, - I2C, or SPI, device interactions normally require IRQs. This bus - call may be morphed into a driver call with bus-specific parameters. - - This call might save low level hardware state that might otherwise - be lost in the upcoming low power state, and actually put the - device into a low power state ... so that in some cases the device - may stay partly usable until this late. This "late" call may also - help when coping with hardware that behaves badly. - -The pm_message_t parameter is currently used to refine those semantics -(described later). - -At the end of those phases, drivers should normally have stopped all I/O -transactions (DMA, IRQs), saved enough state that they can re-initialize -or restore previous state (as needed by the hardware), and placed the -device into a low-power state. On many platforms they will also use -clk_disable() to gate off one or more clock sources; sometimes they will -also switch off power supplies, or reduce voltages. Drivers which have -runtime PM support may already have performed some or all of the steps -needed to prepare for the upcoming system sleep state. - -When any driver sees that its device_can_wakeup(dev), it should make sure -to use the relevant hardware signals to trigger a system wakeup event. -For example, enable_irq_wake() might identify GPIO signals hooked up to -a switch or other external hardware, and pci_enable_wake() does something -similar for PCI's PME# signal. - -If a driver (or bus, or class) fails it suspend method, the system won't -enter the desired low power state; it will resume all the devices it's -suspended so far. - -Note that drivers may need to perform different actions based on the target -system lowpower/sleep state. At this writing, there are only platform -specific APIs through which drivers could determine those target states. - - -Device Low Power (suspend) States ---------------------------------- -Device low-power states aren't very standard. One device might only handle -"on" and "off, while another might support a dozen different versions of -"on" (how many engines are active?), plus a state that gets back to "on" -faster than from a full "off". - -Some busses define rules about what different suspend states mean. PCI -gives one example: after the suspend sequence completes, a non-legacy -PCI device may not perform DMA or issue IRQs, and any wakeup events it -issues would be issued through the PME# bus signal. Plus, there are -several PCI-standard device states, some of which are optional. - -In contrast, integrated system-on-chip processors often use irqs as the -wakeup event sources (so drivers would call enable_irq_wake) and might -be able to treat DMA completion as a wakeup event (sometimes DMA can stay -active too, it'd only be the CPU and some peripherals that sleep). - -Some details here may be platform-specific. Systems may have devices that -can be fully active in certain sleep states, such as an LCD display that's -refreshed using DMA while most of the system is sleeping lightly ... and -its frame buffer might even be updated by a DSP or other non-Linux CPU while -the Linux control processor stays idle. - -Moreover, the specific actions taken may depend on the target system state. -One target system state might allow a given device to be very operational; -another might require a hard shut down with re-initialization on resume. -And two different target systems might use the same device in different -ways; the aforementioned LCD might be active in one product's "standby", -but a different product using the same SOC might work differently. - - -Meaning of pm_message_t.event ------------------------------ -Parameters to suspend calls include the device affected and a message of -type pm_message_t, which has one field: the event. If driver does not -recognize the event code, suspend calls may abort the request and return -a negative errno. However, most drivers will be fine if they implement -PM_EVENT_SUSPEND semantics for all messages. - -The event codes are used to refine the goal of suspending the device, and -mostly matter when creating or resuming system memory image snapshots, as -used with suspend-to-disk: - - PM_EVENT_SUSPEND -- quiesce the driver and put hardware into a low-power - state. When used with system sleep states like "suspend-to-RAM" or - "standby", the upcoming resume() call will often be able to rely on - state kept in hardware, or issue system wakeup events. When used - instead with suspend-to-disk, few devices support this capability; - most are completely powered off. - - PM_EVENT_FREEZE -- quiesce the driver, but don't necessarily change into - any low power mode. A system snapshot is about to be taken, often - followed by a call to the driver's resume() method. Neither wakeup - events nor DMA are allowed. - - PM_EVENT_PRETHAW -- quiesce the driver, knowing that the upcoming resume() - will restore a suspend-to-disk snapshot from a different kernel image. - Drivers that are smart enough to look at their hardware state during - resume() processing need that state to be correct ... a PRETHAW could - be used to invalidate that state (by resetting the device), like a - shutdown() invocation would before a kexec() or system halt. Other - drivers might handle this the same way as PM_EVENT_FREEZE. Neither - wakeup events nor DMA are allowed. - -To enter "standby" (ACPI S1) or "Suspend to RAM" (STR, ACPI S3) states, or -the similarly named APM states, only PM_EVENT_SUSPEND is used; for "Suspend -to Disk" (STD, hibernate, ACPI S4), all of those event codes are used. - -There's also PM_EVENT_ON, a value which never appears as a suspend event -but is sometimes used to record the "not suspended" device state. - - -Resuming Devices ----------------- -Resuming is done in multiple phases, much like suspending, with all -devices processing each phase's calls before the next phase begins. - -The phases are seen by driver notifications issued in this order: - - 1 bus.resume_early(dev) is called with IRQs disabled, and with - only one CPU active. As with bus.suspend_late(), this method - won't be supported on busses that require IRQs in order to - interact with devices. - - This reverses the effects of bus.suspend_late(). - - 2 bus.resume(dev) is called next. This may be morphed into a device - driver call with bus-specific parameters; implementations may sleep. - - This reverses the effects of bus.suspend(). - - 3 class.resume(dev) is called for devices associated with a class - that has such a method. Implementations may sleep. - - This reverses the effects of class.suspend(), and would usually - reactivate the device's I/O queue. - -At the end of those phases, drivers should normally be as functional as -they were before suspending: I/O can be performed using DMA and IRQs, and -the relevant clocks are gated on. The device need not be "fully on"; it -might be in a runtime lowpower/suspend state that acts as if it were. - -However, the details here may again be platform-specific. For example, -some systems support multiple "run" states, and the mode in effect at -the end of resume() might not be the one which preceded suspension. -That means availability of certain clocks or power supplies changed, -which could easily affect how a driver works. - - -Drivers need to be able to handle hardware which has been reset since the -suspend methods were called, for example by complete reinitialization. -This may be the hardest part, and the one most protected by NDA'd documents -and chip errata. It's simplest if the hardware state hasn't changed since -the suspend() was called, but that can't always be guaranteed. - -Drivers must also be prepared to notice that the device has been removed -while the system was powered off, whenever that's physically possible. -PCMCIA, MMC, USB, Firewire, SCSI, and even IDE are common examples of busses -where common Linux platforms will see such removal. Details of how drivers -will notice and handle such removals are currently bus-specific, and often -involve a separate thread. +Methods +The methods to suspend and resume devices reside in struct bus_type: -Note that the bus-specific runtime PM wakeup mechanism can exist, and might -be defined to share some of the same driver code as for system wakeup. For -example, a bus-specific device driver's resume() method might be used there, -so it wouldn't only be called from bus.resume() during system-wide wakeup. -See bus-specific information about how runtime wakeup events are handled. +struct bus_type { + ... + int (*suspend)(struct device * dev, pm_message_t state); + int (*resume)(struct device * dev); +}; +Each bus driver is responsible implementing these methods, translating +the call into a bus-specific request and forwarding the call to the +bus-specific drivers. For example, PCI drivers implement suspend() and +resume() methods in struct pci_driver. The PCI core is simply +responsible for translating the pointers to PCI-specific ones and +calling the low-level driver. + +This is done to a) ease transition to the new power management methods +and leverage the existing PM code in various bus drivers; b) allow +buses to implement generic and default PM routines for devices, and c) +make the flow of execution obvious to the reader. + + +System Power Management + +When the system enters a low-power state, the device tree is walked in +a depth-first fashion to transition each device into a low-power +state. The ordering of the device tree is guaranteed by the order in +which devices get registered - children are never registered before +their ancestors, and devices are placed at the back of the list when +registered. By walking the list in reverse order, we are guaranteed to +suspend devices in the proper order. + +Devices are suspended once with interrupts enabled. Drivers are +expected to stop I/O transactions, save device state, and place the +device into a low-power state. Drivers may sleep, allocate memory, +etc. at will. + +Some devices are broken and will inevitably have problems powering +down or disabling themselves with interrupts enabled. For these +special cases, they may return -EAGAIN. This will put the device on a +list to be taken care of later. When interrupts are disabled, before +we enter the low-power state, their drivers are called again to put +their device to sleep. + +On resume, the devices that returned -EAGAIN will be called to power +themselves back on with interrupts disabled. Once interrupts have been +re-enabled, the rest of the drivers will be called to resume their +devices. On resume, a driver is responsible for powering back on each +device, restoring state, and re-enabling I/O transactions for that +device. -System Devices --------------- System devices follow a slightly different API, which can be found in include/linux/sysdev.h drivers/base/sys.c -System devices will only be suspended with interrupts disabled, and after -all other devices have been suspended. On resume, they will be resumed -before any other devices, and also with interrupts disabled. +System devices will only be suspended with interrupts disabled, and +after all other devices have been suspended. On resume, they will be +resumed before any other devices, and also with interrupts disabled. -That is, IRQs are disabled, the suspend_late() phase begins, then the -sysdev_driver.suspend() phase, and the system enters a sleep state. Then -the sysdev_driver.resume() phase begins, followed by the resume_early() -phase, after which IRQs are enabled. -Code to actually enter and exit the system-wide low power state sometimes -involves hardware details that are only known to the boot firmware, and -may leave a CPU running software (from SRAM or flash memory) that monitors -the system and manages its wakeup sequence. +Runtime Power Management +Many devices are able to dynamically power down while the system is +still running. This feature is useful for devices that are not being +used, and can offer significant power savings on a running system. -Runtime Power Management -======================== -Many devices are able to dynamically power down while the system is still -running. This feature is useful for devices that are not being used, and -can offer significant power savings on a running system. These devices -often support a range of runtime power states, which might use names such -as "off", "sleep", "idle", "active", and so on. Those states will in some -cases (like PCI) be partially constrained by a bus the device uses, and will -usually include hardware states that are also used in system sleep states. - -However, note that if a driver puts a device into a runtime low power state -and the system then goes into a system-wide sleep state, it normally ought -to resume into that runtime low power state rather than "full on". Such -distinctions would be part of the driver-internal state machine for that -hardware; the whole point of runtime power management is to be sure that -drivers are decoupled in that way from the state machine governing phases -of the system-wide power/sleep state transitions. - - -Power Saving Techniques ------------------------ -Normally runtime power management is handled by the drivers without specific -userspace or kernel intervention, by device-aware use of techniques like: - - Using information provided by other system layers - - stay deeply "off" except between open() and close() - - if transceiver/PHY indicates "nobody connected", stay "off" - - application protocols may include power commands or hints - - Using fewer CPU cycles - - using DMA instead of PIO - - removing timers, or making them lower frequency - - shortening "hot" code paths - - eliminating cache misses - - (sometimes) offloading work to device firmware - - Reducing other resource costs - - gating off unused clocks in software (or hardware) - - switching off unused power supplies - - eliminating (or delaying/merging) IRQs - - tuning DMA to use word and/or burst modes - - Using device-specific low power states - - using lower voltages - - avoiding needless DMA transfers - -Read your hardware documentation carefully to see the opportunities that -may be available. If you can, measure the actual power usage and check -it against the budget established for your project. - - -Examples: USB hosts, system timer, system CPU ----------------------------------------------- -USB host controllers make interesting, if complex, examples. In many cases -these have no work to do: no USB devices are connected, or all of them are -in the USB "suspend" state. Linux host controller drivers can then disable -periodic DMA transfers that would otherwise be a constant power drain on the -memory subsystem, and enter a suspend state. In power-aware controllers, -entering that suspend state may disable the clock used with USB signaling, -saving a certain amount of power. - -The controller will be woken from that state (with an IRQ) by changes to the -signal state on the data lines of a given port, for example by an existing -peripheral requesting "remote wakeup" or by plugging a new peripheral. The -same wakeup mechanism usually works from "standby" sleep states, and on some -systems also from "suspend to RAM" (or even "suspend to disk") states. -(Except that ACPI may be involved instead of normal IRQs, on some hardware.) - -System devices like timers and CPUs may have special roles in the platform -power management scheme. For example, system timers using a "dynamic tick" -approach don't just save CPU cycles (by eliminating needless timer IRQs), -but they may also open the door to using lower power CPU "idle" states that -cost more than a jiffie to enter and exit. On x86 systems these are states -like "C3"; note that periodic DMA transfers from a USB host controller will -also prevent entry to a C3 state, much like a periodic timer IRQ. - -That kind of runtime mechanism interaction is common. "System On Chip" (SOC) -processors often have low power idle modes that can't be entered unless -certain medium-speed clocks (often 12 or 48 MHz) are gated off. When the -drivers gate those clocks effectively, then the system idle task may be able -to use the lower power idle modes and thereby increase battery life. - -If the CPU can have a "cpufreq" driver, there also may be opportunities -to shift to lower voltage settings and reduce the power cost of executing -a given number of instructions. (Without voltage adjustment, it's rare -for cpufreq to save much power; the cost-per-instruction must go down.) - - -/sys/devices/.../power/state files -================================== -For now you can also test some of this functionality using sysfs. - - DEPRECATED: USE "power/state" ONLY FOR DRIVER TESTING, AND - AVOID USING dev->power.power_state IN DRIVERS. - - THESE WILL BE REMOVED. IF THE "power/state" FILE GETS REPLACED, - IT WILL BECOME SOMETHING COUPLED TO THE BUS OR DRIVER. - -In each device's directory, there is a 'power' directory, which contains -at least a 'state' file. The value of this field is effectively boolean, -PM_EVENT_ON or PM_EVENT_SUSPEND. - - * Reading from this file displays a value corresponding to - the power.power_state.event field. All nonzero values are - displayed as "2", corresponding to a low power state; zero - is displayed as "0", corresponding to normal operation. - - * Writing to this file initiates a transition using the - specified event code number; only '0', '2', and '3' are - accepted (without a newline); '2' and '3' are both - mapped to PM_EVENT_SUSPEND. - -On writes, the PM core relies on that recorded event code and the device/bus -capabilities to determine whether it uses a partial suspend() or resume() -sequence to change things so that the recorded event corresponds to the -numeric parameter. - - - If the bus requires the irqs-disabled suspend_late()/resume_early() - phases, writes fail because those operations are not supported here. - - - If the recorded value is the expected value, nothing is done. - - - If the recorded value is nonzero, the device is partially resumed, - using the bus.resume() and/or class.resume() methods. - - - If the target value is nonzero, the device is partially suspended, - using the class.suspend() and/or bus.suspend() methods and the - PM_EVENT_SUSPEND message. - -Drivers have no way to tell whether their suspend() and resume() calls -have come through the sysfs power/state file or as part of entering a -system sleep state, except that when accessed through sysfs the normal -parent/child sequencing rules are ignored. Drivers (such as bus, bridge, -or hub drivers) which expose child devices may need to enforce those rules -on their own. +In each device's directory, there is a 'power' directory, which +contains at least a 'state' file. Reading from this file displays what +power state the device is currently in. Writing to this file initiates +a transition to the specified power state, which must be a decimal in +the range 1-3, inclusive; or 0 for 'On'. + +The PM core will call the ->suspend() method in the bus_type object +that the device belongs to if the specified state is not 0, or +->resume() if it is. + +Nothing will happen if the specified state is the same state the +device is currently in. + +If the device is already in a low-power state, and the specified state +is another, but different, low-power state, the ->resume() method will +first be called to power the device back on, then ->suspend() will be +called again with the new state. + +The driver is responsible for saving the working state of the device +and putting it into the low-power state specified. If this was +successful, it returns 0, and the device's power_state field is +updated. + +The driver must take care to know whether or not it is able to +properly resume the device, including all step of reinitialization +necessary. (This is the hardest part, and the one most protected by +NDA'd documents). + +The driver must also take care not to suspend a device that is +currently in use. It is their responsibility to provide their own +exclusion mechanisms. + +The runtime power transition happens with interrupts enabled. If a +device cannot support being powered down with interrupts, it may +return -EAGAIN (as it would during a system power management +transition), but it will _not_ be called again, and the transaction +will fail. + +There is currently no way to know what states a device or driver +supports a priori. This will change in the future. + +pm_message_t meaning + +pm_message_t has two fields. event ("major"), and flags. If driver +does not know event code, it aborts the request, returning error. Some +drivers may need to deal with special cases based on the actual type +of suspend operation being done at the system level. This is why +there are flags. + +Event codes are: + +ON -- no need to do anything except special cases like broken +HW. + +# NOTIFICATION -- pretty much same as ON? + +FREEZE -- stop DMA and interrupts, and be prepared to reinit HW from +scratch. That probably means stop accepting upstream requests, the +actual policy of what to do with them being specific to a given +driver. It's acceptable for a network driver to just drop packets +while a block driver is expected to block the queue so no request is +lost. (Use IDE as an example on how to do that). FREEZE requires no +power state change, and it's expected for drivers to be able to +quickly transition back to operating state. + +SUSPEND -- like FREEZE, but also put hardware into low-power state. If +there's need to distinguish several levels of sleep, additional flag +is probably best way to do that. + +Transitions are only from a resumed state to a suspended state, never +between 2 suspended states. (ON -> FREEZE or ON -> SUSPEND can happen, +FREEZE -> SUSPEND or SUSPEND -> FREEZE can not). + +All events are: + +[NOTE NOTE NOTE: If you are driver author, you should not care; you +should only look at event, and ignore flags.] + +#Prepare for suspend -- userland is still running but we are going to +#enter suspend state. This gives drivers chance to load firmware from +#disk and store it in memory, or do other activities taht require +#operating userland, ability to kmalloc GFP_KERNEL, etc... All of these +#are forbiden once the suspend dance is started.. event = ON, flags = +#PREPARE_TO_SUSPEND + +Apm standby -- prepare for APM event. Quiesce devices to make life +easier for APM BIOS. event = FREEZE, flags = APM_STANDBY + +Apm suspend -- same as APM_STANDBY, but it we should probably avoid +spinning down disks. event = FREEZE, flags = APM_SUSPEND + +System halt, reboot -- quiesce devices to make life easier for BIOS. event += FREEZE, flags = SYSTEM_HALT or SYSTEM_REBOOT + +System shutdown -- at least disks need to be spun down, or data may be +lost. Quiesce devices, just to make life easier for BIOS. event = +FREEZE, flags = SYSTEM_SHUTDOWN + +Kexec -- turn off DMAs and put hardware into some state where new +kernel can take over. event = FREEZE, flags = KEXEC + +Powerdown at end of swsusp -- very similar to SYSTEM_SHUTDOWN, except wake +may need to be enabled on some devices. This actually has at least 3 +subtypes, system can reboot, enter S4 and enter S5 at the end of +swsusp. event = FREEZE, flags = SWSUSP and one of SYSTEM_REBOOT, +SYSTEM_SHUTDOWN, SYSTEM_S4 + +Suspend to ram -- put devices into low power state. event = SUSPEND, +flags = SUSPEND_TO_RAM + +Freeze for swsusp snapshot -- stop DMA and interrupts. No need to put +devices into low power mode, but you must be able to reinitialize +device from scratch in resume method. This has two flavors, its done +once on suspending kernel, once on resuming kernel. event = FREEZE, +flags = DURING_SUSPEND or DURING_RESUME + +Device detach requested from /sys -- deinitialize device; proably same as +SYSTEM_SHUTDOWN, I do not understand this one too much. probably event += FREEZE, flags = DEV_DETACH. + +#These are not really events sent: +# +#System fully on -- device is working normally; this is probably never +#passed to suspend() method... event = ON, flags = 0 +# +#Ready after resume -- userland is now running, again. Time to free any +#memory you ate during prepare to suspend... event = ON, flags = +#READY_AFTER_RESUME +# diff --git a/trunk/Documentation/rt-mutex-design.txt b/trunk/Documentation/rt-mutex-design.txt index 4b736d24da7a..c472ffacc2f6 100644 --- a/trunk/Documentation/rt-mutex-design.txt +++ b/trunk/Documentation/rt-mutex-design.txt @@ -333,11 +333,11 @@ cmpxchg is basically the following function performed atomically: unsigned long _cmpxchg(unsigned long *A, unsigned long *B, unsigned long *C) { - unsigned long T = *A; - if (*A == *B) { - *A = *C; - } - return T; + unsigned long T = *A; + if (*A == *B) { + *A = *C; + } + return T; } #define cmpxchg(a,b,c) _cmpxchg(&a,&b,&c) @@ -582,7 +582,7 @@ contention). try_to_take_rt_mutex is used every time the task tries to grab a mutex in the slow path. The first thing that is done here is an atomic setting of the "Has Waiters" flag of the mutex's owner field. Yes, this could really -be false, because if the mutex has no owner, there are no waiters and +be false, because if the the mutex has no owner, there are no waiters and the current task also won't have any waiters. But we don't have the lock yet, so we assume we are going to be a waiter. The reason for this is to play nice for those architectures that do have CMPXCHG. By setting this flag @@ -735,7 +735,7 @@ do have CMPXCHG, that check is done in the fast path, but it is still needed in the slow path too. If a waiter of a mutex woke up because of a signal or timeout between the time the owner failed the fast path CMPXCHG check and the grabbing of the wait_lock, the mutex may not have any waiters, thus the -owner still needs to make this check. If there are no waiters then the mutex +owner still needs to make this check. If there are no waiters than the mutex owner field is set to NULL, the wait_lock is released and nothing more is needed. diff --git a/trunk/Documentation/seclvl.txt b/trunk/Documentation/seclvl.txt new file mode 100644 index 000000000000..97274d122d0e --- /dev/null +++ b/trunk/Documentation/seclvl.txt @@ -0,0 +1,97 @@ +BSD Secure Levels Linux Security Module +Michael A. Halcrow + + +Introduction + +Under the BSD Secure Levels security model, sets of policies are +associated with levels. Levels range from -1 to 2, with -1 being the +weakest and 2 being the strongest. These security policies are +enforced at the kernel level, so not even the superuser is able to +disable or circumvent them. This hardens the machine against attackers +who gain root access to the system. + + +Levels and Policies + +Level -1 (Permanently Insecure): + - Cannot increase the secure level + +Level 0 (Insecure): + - Cannot ptrace the init process + +Level 1 (Default): + - /dev/mem and /dev/kmem are read-only + - IMMUTABLE and APPEND extended attributes, if set, may not be unset + - Cannot load or unload kernel modules + - Cannot write directly to a mounted block device + - Cannot perform raw I/O operations + - Cannot perform network administrative tasks + - Cannot setuid any file + +Level 2 (Secure): + - Cannot decrement the system time + - Cannot write to any block device, whether mounted or not + - Cannot unmount any mounted filesystems + + +Compilation + +To compile the BSD Secure Levels LSM, seclvl.ko, enable the +SECURITY_SECLVL configuration option. This is found under Security +options -> BSD Secure Levels in the kernel configuration menu. + + +Basic Usage + +Once the machine is in a running state, with all the necessary modules +loaded and all the filesystems mounted, you can load the seclvl.ko +module: + +# insmod seclvl.ko + +The module defaults to secure level 1, except when compiled directly +into the kernel, in which case it defaults to secure level 0. To raise +the secure level to 2, the administrator writes ``2'' to the +seclvl/seclvl file under the sysfs mount point (assumed to be /sys in +these examples): + +# echo -n "2" > /sys/seclvl/seclvl + +Alternatively, you can initialize the module at secure level 2 with +the initlvl module parameter: + +# insmod seclvl.ko initlvl=2 + +At this point, it is impossible to remove the module or reduce the +secure level. If the administrator wishes to have the option of doing +so, he must provide a module parameter, sha1_passwd, that specifies +the SHA1 hash of the password that can be used to reduce the secure +level to 0. + +To generate this SHA1 hash, the administrator can use OpenSSL: + +# echo -n "boogabooga" | openssl sha1 +abeda4e0f33defa51741217592bf595efb8d289c + +In order to use password-instigated secure level reduction, the SHA1 +crypto module must be loaded or compiled into the kernel: + +# insmod sha1.ko + +The administrator can then insmod the seclvl module, including the +SHA1 hash of the password: + +# insmod seclvl.ko + sha1_passwd=abeda4e0f33defa51741217592bf595efb8d289c + +To reduce the secure level, write the password to seclvl/passwd under +your sysfs mount point: + +# echo -n "boogabooga" > /sys/seclvl/passwd + +The September 2004 edition of Sys Admin Magazine has an article about +the BSD Secure Levels LSM. I encourage you to refer to that article +for a more in-depth treatment of this security module: + +http://www.samag.com/documents/s=9304/sam0409a/0409a.htm diff --git a/trunk/Documentation/sh/new-machine.txt b/trunk/Documentation/sh/new-machine.txt index 73988e0d112b..eb2dd2e6993b 100644 --- a/trunk/Documentation/sh/new-machine.txt +++ b/trunk/Documentation/sh/new-machine.txt @@ -41,6 +41,11 @@ Board-specific code: | .. more boards here ... +It should also be noted that each board is required to have some certain +headers. At the time of this writing, io.h is the only thing that needs +to be provided for each board, and can generally just reference generic +functions (with the exception of isa_port2addr). + Next, for companion chips: . `-- arch @@ -99,13 +104,12 @@ and then populate that with sub-directories for each member of the family. Both the Solution Engine and the hp6xx boards are an example of this. After you have setup your new arch/sh/boards/ directory, remember that you -should also add a directory in include/asm-sh for headers localized to this -board (if there are going to be more than one). In order to interoperate -seamlessly with the build system, it's best to have this directory the same -as the arch/sh/boards/ directory name, though if your board is again part of -a family, the build system has ways of dealing with this (via incdir-y -overloading), and you can feel free to name the directory after the family -member itself. +also must add a directory in include/asm-sh for headers localized to this +board. In order to interoperate seamlessly with the build system, it's best +to have this directory the same as the arch/sh/boards/ directory name, +though if your board is again part of a family, the build system has ways +of dealing with this, and you can feel free to name the directory after +the family member itself. There are a few things that each board is required to have, both in the arch/sh/boards and the include/asm-sh/ heirarchy. In order to better @@ -118,7 +122,6 @@ might look something like: * arch/sh/boards/vapor/setup.c - Setup code for imaginary board */ #include -#include /* for board_time_init() */ const char *get_system_type(void) { @@ -149,57 +152,79 @@ int __init platform_setup(void) } Our new imaginary board will also have to tie into the machvec in order for it -to be of any use. +to be of any use. Currently the machvec is slowly on its way out, but is still +required for the time being. As such, let us take a look at what needs to be +done for the machvec assignment. machvec functions fall into a number of categories: - I/O functions to IO memory (inb etc) and PCI/main memory (readb etc). - - I/O mapping functions (ioport_map, ioport_unmap, etc). - - a 'heartbeat' function. - - PCI and IRQ initialization routines. - - Consistent allocators (for boards that need special allocators, - particularly for allocating out of some board-specific SRAM for DMA - handles). - -There are machvec functions added and removed over time, so always be sure to -consult include/asm-sh/machvec.h for the current state of the machvec. - -The kernel will automatically wrap in generic routines for undefined function -pointers in the machvec at boot time, as machvec functions are referenced -unconditionally throughout most of the tree. Some boards have incredibly -sparse machvecs (such as the dreamcast and sh03), whereas others must define -virtually everything (rts7751r2d). - -Adding a new machine is relatively trivial (using vapor as an example): - -If the board-specific definitions are quite minimalistic, as is the case for -the vast majority of boards, simply having a single board-specific header is -sufficient. - - - add a new file include/asm-sh/vapor.h which contains prototypes for + - I/O remapping functions (ioremap etc) + - some initialisation functions + - a 'heartbeat' function + - some miscellaneous flags + +The tree can be built in two ways: + - as a fully generic build. All drivers are linked in, and all functions + go through the machvec + - as a machine specific build. In this case only the required drivers + will be linked in, and some macros may be redefined to not go through + the machvec where performance is important (in particular IO functions). + +There are three ways in which IO can be performed: + - none at all. This is really only useful for the 'unknown' machine type, + which us designed to run on a machine about which we know nothing, and + so all all IO instructions do nothing. + - fully custom. In this case all IO functions go to a machine specific + set of functions which can do what they like + - a generic set of functions. These will cope with most situations, + and rely on a single function, mv_port2addr, which is called through the + machine vector, and converts an IO address into a memory address, which + can be read from/written to directly. + +Thus adding a new machine involves the following steps (I will assume I am +adding a machine called vapor): + + - add a new file include/asm-sh/vapor/io.h which contains prototypes for any machine specific IO functions prefixed with the machine name, for example vapor_inb. These will be needed when filling out the machine vector. - Note that these prototypes are generated automatically by setting - __IO_PREFIX to something sensible. A typical example would be: - - #define __IO_PREFIX vapor - #include - - somewhere in the board-specific header. Any boards being ported that still - have a legacy io.h should remove it entirely and switch to the new model. - - - Add machine vector definitions to the board's setup.c. At a bare minimum, - this must be defined as something like: - - struct sh_machine_vector mv_vapor __initmv = { - .mv_name = "vapor", - }; - ALIAS_MV(vapor) - - - finally add a file arch/sh/boards/vapor/io.c, which contains definitions of - the machine specific io functions (if there are enough to warrant it). + This is the minimum that is required, however there are ample + opportunities to optimise this. In particular, by making the prototypes + inline function definitions, it is possible to inline the function when + building machine specific versions. Note that the machine vector + functions will still be needed, so that a module built for a generic + setup can be loaded. + + - add a new file arch/sh/boards/vapor/mach.c. This contains the definition + of the machine vector. When building the machine specific version, this + will be the real machine vector (via an alias), while in the generic + version is used to initialise the machine vector, and then freed, by + making it initdata. This should be defined as: + + struct sh_machine_vector mv_vapor __initmv = { + .mv_name = "vapor", + } + ALIAS_MV(vapor) + + - finally add a file arch/sh/boards/vapor/io.c, which contains + definitions of the machine specific io functions. + +A note about initialisation functions. Three initialisation functions are +provided in the machine vector: + - mv_arch_init - called very early on from setup_arch + - mv_init_irq - called from init_IRQ, after the generic SH interrupt + initialisation + - mv_init_pci - currently not used + +Any other remaining functions which need to be called at start up can be +added to the list using the __initcalls macro (or module_init if the code +can be built as a module). Many generic drivers probe to see if the device +they are targeting is present, however this may not always be appropriate, +so a flag can be added to the machine vector which will be set on those +machines which have the hardware in question, reducing the probe to a +single conditional. 3. Hooking into the Build System ================================ @@ -278,3 +303,4 @@ which will in turn copy the defconfig for this board, run it through oldconfig (prompting you for any new options since the time of creation), and start you on your way to having a functional kernel for your new board. + diff --git a/trunk/Documentation/sh/register-banks.txt b/trunk/Documentation/sh/register-banks.txt deleted file mode 100644 index a6719f2f6594..000000000000 --- a/trunk/Documentation/sh/register-banks.txt +++ /dev/null @@ -1,33 +0,0 @@ - Notes on register bank usage in the kernel - ========================================== - -Introduction ------------- - -The SH-3 and SH-4 CPU families traditionally include a single partial register -bank (selected by SR.RB, only r0 ... r7 are banked), whereas other families -may have more full-featured banking or simply no such capabilities at all. - -SR.RB banking -------------- - -In the case of this type of banking, banked registers are mapped directly to -r0 ... r7 if SR.RB is set to the bank we are interested in, otherwise ldc/stc -can still be used to reference the banked registers (as r0_bank ... r7_bank) -when in the context of another bank. The developer must keep the SR.RB value -in mind when writing code that utilizes these banked registers, for obvious -reasons. Userspace is also not able to poke at the bank1 values, so these can -be used rather effectively as scratch registers by the kernel. - -Presently the kernel uses several of these registers. - - - r0_bank, r1_bank (referenced as k0 and k1, used for scratch - registers when doing exception handling). - - r2_bank (used to track the EXPEVT/INTEVT code) - - Used by do_IRQ() and friends for doing irq mapping based off - of the interrupt exception vector jump table offset - - r6_bank (global interrupt mask) - - The SR.IMASK interrupt handler makes use of this to set the - interrupt priority level (used by local_irq_enable()) - - r7_bank (current) - diff --git a/trunk/Documentation/usb/error-codes.txt b/trunk/Documentation/usb/error-codes.txt index 39c68f8c4e6c..867f4c38f356 100644 --- a/trunk/Documentation/usb/error-codes.txt +++ b/trunk/Documentation/usb/error-codes.txt @@ -98,13 +98,13 @@ one or more packets could finish before an error stops further endpoint I/O. error, a failure to respond (often caused by device disconnect), or some other fault. --ETIME (**) No response packet received within the prescribed +-ETIMEDOUT (**) No response packet received within the prescribed bus turn-around time. This error may instead be reported as -EPROTO or -EILSEQ. --ETIMEDOUT Synchronous USB message functions use this code - to indicate timeout expired before the transfer - completed, and no other error was reported by HC. + Note that the synchronous USB message functions + also use this code to indicate timeout expired + before the transfer completed. -EPIPE (**) Endpoint stalled. For non-control endpoints, reset this status with usb_clear_halt(). @@ -163,3 +163,6 @@ usb_get_*/usb_set_*(): usb_control_msg(): usb_bulk_msg(): -ETIMEDOUT Timeout expired before the transfer completed. + In the future this code may change to -ETIME, + whose definition is a closer match to this sort + of error. diff --git a/trunk/Documentation/usb/usb-serial.txt b/trunk/Documentation/usb/usb-serial.txt index a2dee6e6190d..02b0f7beb6d1 100644 --- a/trunk/Documentation/usb/usb-serial.txt +++ b/trunk/Documentation/usb/usb-serial.txt @@ -433,11 +433,6 @@ Options supported: See http://www.uuhaus.de/linux/palmconnect.html for up-to-date information on this driver. -AIRcable USB Dongle Bluetooth driver - If there is the cdc_acm driver loaded in the system, you will find that the - cdc_acm claims the device before AIRcable can. This is simply corrected - by unloading both modules and then loading the aircable module before - cdc_acm module Generic Serial driver diff --git a/trunk/Documentation/video4linux/CARDLIST.cx88 b/trunk/Documentation/video4linux/CARDLIST.cx88 index 669a09aa5bb4..00d9a1f2a54c 100644 --- a/trunk/Documentation/video4linux/CARDLIST.cx88 +++ b/trunk/Documentation/video4linux/CARDLIST.cx88 @@ -7,10 +7,10 @@ 6 -> AverTV Studio 303 (M126) [1461:000b] 7 -> MSI TV-@nywhere Master [1462:8606] 8 -> Leadtek Winfast DV2000 [107d:6620] - 9 -> Leadtek PVR 2000 [107d:663b,107d:663c,107d:6632] + 9 -> Leadtek PVR 2000 [107d:663b,107d:663C] 10 -> IODATA GV-VCP3/PCI [10fc:d003] 11 -> Prolink PlayTV PVR - 12 -> ASUS PVR-416 [1043:4823,1461:c111] + 12 -> ASUS PVR-416 [1043:4823] 13 -> MSI TV-@nywhere 14 -> KWorld/VStream XPert DVB-T [17de:08a6] 15 -> DViCO FusionHDTV DVB-T1 [18ac:db00] @@ -51,7 +51,3 @@ 50 -> NPG Tech Real TV FM Top 10 [14f1:0842] 51 -> WinFast DTV2000 H [107d:665e] 52 -> Geniatech DVB-S [14f1:0084] - 53 -> Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T [0070:1404] - 54 -> Norwood Micro TV Tuner - 55 -> Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM [c180:c980] - 56 -> Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder [0070:9600,0070:9601,0070:9602] diff --git a/trunk/Documentation/video4linux/CARDLIST.saa7134 b/trunk/Documentation/video4linux/CARDLIST.saa7134 index 94cf695b1378..9068b669f5ee 100644 --- a/trunk/Documentation/video4linux/CARDLIST.saa7134 +++ b/trunk/Documentation/video4linux/CARDLIST.saa7134 @@ -58,7 +58,7 @@ 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370] 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134 - 60 -> LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus [5168:0502,4e42:0502,1489:0502] + 60 -> LifeView/Typhoon FlyDVB-T Duo Cardbus [5168:0502,4e42:0502] 61 -> Philips TOUGH DVB-T reference design [1131:2004] 62 -> Compro VideoMate TV Gold+II 63 -> Kworld Xpert TV PVR7134 @@ -83,7 +83,7 @@ 82 -> MSI TV@Anywhere plus [1462:6231] 83 -> Terratec Cinergy 250 PCI TV [153b:1160] 84 -> LifeView FlyDVB Trio [5168:0319] - 85 -> AverTV DVB-T 777 [1461:2c05,1461:2c05] + 85 -> AverTV DVB-T 777 [1461:2c05] 86 -> LifeView FlyDVB-T / Genius VideoWonder DVB-T [5168:0301,1489:0301] 87 -> ADS Instant TV Duo Cardbus PTV331 [0331:1421] 88 -> Tevion/KWorld DVB-T 220RF [17de:7201] @@ -94,6 +94,3 @@ 93 -> Medion 7134 Bridge #2 [16be:0005] 94 -> LifeView FlyDVB-T Hybrid Cardbus [5168:3306,5168:3502] 95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138] - 96 -> Medion Md8800 Quadro [16be:0007,16be:0008] - 97 -> LifeView FlyDVB-S /Acorp TV134DS [5168:0300,4e42:0300] - 98 -> Proteus Pro 2309 [0919:2003] diff --git a/trunk/Documentation/video4linux/bttv/Insmod-options b/trunk/Documentation/video4linux/bttv/Insmod-options index bb7c2cac7917..fc94ff235ffa 100644 --- a/trunk/Documentation/video4linux/bttv/Insmod-options +++ b/trunk/Documentation/video4linux/bttv/Insmod-options @@ -54,12 +54,6 @@ bttv.o dropouts. chroma_agc=0/1 AGC of chroma signal, off by default. adc_crush=0/1 Luminance ADC crush, on by default. - i2c_udelay= Allow reduce I2C speed. Default is 5 usecs - (meaning 66,67 Kbps). The default is the - maximum supported speed by kernel bitbang - algoritm. You may use lower numbers, if I2C - messages are lost (16 is known to work on - all supported cards). bttv_gpio=0/1 gpiomask= diff --git a/trunk/Documentation/video4linux/cx2341x/README.hm12 b/trunk/Documentation/video4linux/cx2341x/README.hm12 deleted file mode 100644 index 0e213ed095e6..000000000000 --- a/trunk/Documentation/video4linux/cx2341x/README.hm12 +++ /dev/null @@ -1,116 +0,0 @@ -The cx23416 can produce (and the cx23415 can also read) raw YUV output. The -format of a YUV frame is specific to this chip and is called HM12. 'HM' stands -for 'Hauppauge Macroblock', which is a misnomer as 'Conexant Macroblock' would -be more accurate. - -The format is YUV 4:2:0 which uses 1 Y byte per pixel and 1 U and V byte per -four pixels. - -The data is encoded as two macroblock planes, the first containing the Y -values, the second containing UV macroblocks. - -The Y plane is divided into blocks of 16x16 pixels from left to right -and from top to bottom. Each block is transmitted in turn, line-by-line. - -So the first 16 bytes are the first line of the top-left block, the -second 16 bytes are the second line of the top-left block, etc. After -transmitting this block the first line of the block on the right to the -first block is transmitted, etc. - -The UV plane is divided into blocks of 16x8 UV values going from left -to right, top to bottom. Each block is transmitted in turn, line-by-line. - -So the first 16 bytes are the first line of the top-left block and -contain 8 UV value pairs (16 bytes in total). The second 16 bytes are the -second line of 8 UV pairs of the top-left block, etc. After transmitting -this block the first line of the block on the right to the first block is -transmitted, etc. - -The code below is given as an example on how to convert HM12 to separate -Y, U and V planes. This code assumes frames of 720x576 (PAL) pixels. - -The width of a frame is always 720 pixels, regardless of the actual specified -width. - --------------------------------------------------------------------------- - -#include -#include -#include - -static unsigned char frame[576*720*3/2]; -static unsigned char framey[576*720]; -static unsigned char frameu[576*720 / 4]; -static unsigned char framev[576*720 / 4]; - -static void de_macro_y(unsigned char* dst, unsigned char *src, int dstride, int w, int h) -{ - unsigned int y, x, i; - - // descramble Y plane - // dstride = 720 = w - // The Y plane is divided into blocks of 16x16 pixels - // Each block in transmitted in turn, line-by-line. - for (y = 0; y < h; y += 16) { - for (x = 0; x < w; x += 16) { - for (i = 0; i < 16; i++) { - memcpy(dst + x + (y + i) * dstride, src, 16); - src += 16; - } - } - } -} - -static void de_macro_uv(unsigned char *dstu, unsigned char *dstv, unsigned char *src, int dstride, int w, int h) -{ - unsigned int y, x, i; - - // descramble U/V plane - // dstride = 720 / 2 = w - // The U/V values are interlaced (UVUV...). - // Again, the UV plane is divided into blocks of 16x16 UV values. - // Each block in transmitted in turn, line-by-line. - for (y = 0; y < h; y += 16) { - for (x = 0; x < w; x += 8) { - for (i = 0; i < 16; i++) { - int idx = x + (y + i) * dstride; - - dstu[idx+0] = src[0]; dstv[idx+0] = src[1]; - dstu[idx+1] = src[2]; dstv[idx+1] = src[3]; - dstu[idx+2] = src[4]; dstv[idx+2] = src[5]; - dstu[idx+3] = src[6]; dstv[idx+3] = src[7]; - dstu[idx+4] = src[8]; dstv[idx+4] = src[9]; - dstu[idx+5] = src[10]; dstv[idx+5] = src[11]; - dstu[idx+6] = src[12]; dstv[idx+6] = src[13]; - dstu[idx+7] = src[14]; dstv[idx+7] = src[15]; - src += 16; - } - } - } -} - -/*************************************************************************/ -int main(int argc, char **argv) -{ - FILE *fin; - int i; - - if (argc == 1) fin = stdin; - else fin = fopen(argv[1], "r"); - - if (fin == NULL) { - fprintf(stderr, "cannot open input\n"); - exit(-1); - } - while (fread(frame, sizeof(frame), 1, fin) == 1) { - de_macro_y(framey, frame, 720, 720, 576); - de_macro_uv(frameu, framev, frame + 720 * 576, 720 / 2, 720 / 2, 576 / 2); - fwrite(framey, sizeof(framey), 1, stdout); - fwrite(framev, sizeof(framev), 1, stdout); - fwrite(frameu, sizeof(frameu), 1, stdout); - } - fclose(fin); - return 0; -} - --------------------------------------------------------------------------- diff --git a/trunk/Documentation/video4linux/cx2341x/README.vbi b/trunk/Documentation/video4linux/cx2341x/README.vbi deleted file mode 100644 index 5807cf156173..000000000000 --- a/trunk/Documentation/video4linux/cx2341x/README.vbi +++ /dev/null @@ -1,45 +0,0 @@ - -Format of embedded V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data -========================================================= - -This document describes the V4L2_MPEG_STREAM_VBI_FMT_IVTV format of the VBI data -embedded in an MPEG-2 program stream. This format is in part dictated by some -hardware limitations of the ivtv driver (the driver for the Conexant cx23415/6 -chips), in particular a maximum size for the VBI data. Anything longer is cut -off when the MPEG stream is played back through the cx23415. - -The advantage of this format is it is very compact and that all VBI data for -all lines can be stored while still fitting within the maximum allowed size. - -The stream ID of the VBI data is 0xBD. The maximum size of the embedded data is -4 + 43 * 36, which is 4 bytes for a header and 2 * 18 VBI lines with a 1 byte -header and a 42 bytes payload each. Anything beyond this limit is cut off by -the cx23415/6 firmware. Besides the data for the VBI lines we also need 36 bits -for a bitmask determining which lines are captured and 4 bytes for a magic cookie, -signifying that this data package contains V4L2_MPEG_STREAM_VBI_FMT_IVTV VBI data. -If all lines are used, then there is no longer room for the bitmask. To solve this -two different magic numbers were introduced: - -'itv0': After this magic number two unsigned longs follow. Bits 0-17 of the first -unsigned long denote which lines of the first field are captured. Bits 18-31 of -the first unsigned long and bits 0-3 of the second unsigned long are used for the -second field. - -'ITV0': This magic number assumes all VBI lines are captured, i.e. it implicitly -implies that the bitmasks are 0xffffffff and 0xf. - -After these magic cookies (and the 8 byte bitmask in case of cookie 'itv0') the -captured VBI lines start: - -For each line the least significant 4 bits of the first byte contain the data type. -Possible values are shown in the table below. The payload is in the following 42 -bytes. - -Here is the list of possible data types: - -#define IVTV_SLICED_TYPE_TELETEXT 0x1 // Teletext (uses lines 6-22 for PAL) -#define IVTV_SLICED_TYPE_CC 0x4 // Closed Captions (line 21 NTSC) -#define IVTV_SLICED_TYPE_WSS 0x5 // Wide Screen Signal (line 23 PAL) -#define IVTV_SLICED_TYPE_VPS 0x7 // Video Programming System (PAL) (line 16) - -Hans Verkuil diff --git a/trunk/Documentation/x86_64/boot-options.txt b/trunk/Documentation/x86_64/boot-options.txt index 74b77f9e91bc..6da24e7a56cb 100644 --- a/trunk/Documentation/x86_64/boot-options.txt +++ b/trunk/Documentation/x86_64/boot-options.txt @@ -199,11 +199,6 @@ IOMMU allowed overwrite iommu off workarounds for specific chipsets. soft Use software bounce buffering (default for Intel machines) noaperture Don't touch the aperture for AGP. - allowdac Allow DMA >4GB - When off all DMA over >4GB is forced through an IOMMU or bounce - buffering. - nodac Forbid DMA >4GB - panic Always panic when IOMMU overflows swiotlb=pages[,force] @@ -250,13 +245,6 @@ Debugging newfallback: use new unwinder but fall back to old if it gets stuck (default) - call_trace=[old|both|newfallback|new] - old: use old inexact backtracer - new: use new exact dwarf2 unwinder - both: print entries from both - newfallback: use new unwinder but fall back to old if it gets - stuck (default) - Misc noreplacement Don't replace instructions with more appropriate ones diff --git a/trunk/Documentation/x86_64/kernel-stacks b/trunk/Documentation/x86_64/kernel-stacks deleted file mode 100644 index bddfddd466ab..000000000000 --- a/trunk/Documentation/x86_64/kernel-stacks +++ /dev/null @@ -1,99 +0,0 @@ -Most of the text from Keith Owens, hacked by AK - -x86_64 page size (PAGE_SIZE) is 4K. - -Like all other architectures, x86_64 has a kernel stack for every -active thread. These thread stacks are THREAD_SIZE (2*PAGE_SIZE) big. -These stacks contain useful data as long as a thread is alive or a -zombie. While the thread is in user space the kernel stack is empty -except for the thread_info structure at the bottom. - -In addition to the per thread stacks, there are specialized stacks -associated with each cpu. These stacks are only used while the kernel -is in control on that cpu, when a cpu returns to user space the -specialized stacks contain no useful data. The main cpu stacks is - -* Interrupt stack. IRQSTACKSIZE - - Used for external hardware interrupts. If this is the first external - hardware interrupt (i.e. not a nested hardware interrupt) then the - kernel switches from the current task to the interrupt stack. Like - the split thread and interrupt stacks on i386 (with CONFIG_4KSTACKS), - this gives more room for kernel interrupt processing without having - to increase the size of every per thread stack. - - The interrupt stack is also used when processing a softirq. - -Switching to the kernel interrupt stack is done by software based on a -per CPU interrupt nest counter. This is needed because x86-64 "IST" -hardware stacks cannot nest without races. - -x86_64 also has a feature which is not available on i386, the ability -to automatically switch to a new stack for designated events such as -double fault or NMI, which makes it easier to handle these unusual -events on x86_64. This feature is called the Interrupt Stack Table -(IST). There can be up to 7 IST entries per cpu. The IST code is an -index into the Task State Segment (TSS), the IST entries in the TSS -point to dedicated stacks, each stack can be a different size. - -An IST is selected by an non-zero value in the IST field of an -interrupt-gate descriptor. When an interrupt occurs and the hardware -loads such a descriptor, the hardware automatically sets the new stack -pointer based on the IST value, then invokes the interrupt handler. If -software wants to allow nested IST interrupts then the handler must -adjust the IST values on entry to and exit from the interrupt handler. -(this is occasionally done, e.g. for debug exceptions) - -Events with different IST codes (i.e. with different stacks) can be -nested. For example, a debug interrupt can safely be interrupted by an -NMI. arch/x86_64/kernel/entry.S::paranoidentry adjusts the stack -pointers on entry to and exit from all IST events, in theory allowing -IST events with the same code to be nested. However in most cases, the -stack size allocated to an IST assumes no nesting for the same code. -If that assumption is ever broken then the stacks will become corrupt. - -The currently assigned IST stacks are :- - -* STACKFAULT_STACK. EXCEPTION_STKSZ (PAGE_SIZE). - - Used for interrupt 12 - Stack Fault Exception (#SS). - - This allows to recover from invalid stack segments. Rarely - happens. - -* DOUBLEFAULT_STACK. EXCEPTION_STKSZ (PAGE_SIZE). - - Used for interrupt 8 - Double Fault Exception (#DF). - - Invoked when handling a exception causes another exception. Happens - when the kernel is very confused (e.g. kernel stack pointer corrupt) - Using a separate stack allows to recover from it well enough in many - cases to still output an oops. - -* NMI_STACK. EXCEPTION_STKSZ (PAGE_SIZE). - - Used for non-maskable interrupts (NMI). - - NMI can be delivered at any time, including when the kernel is in the - middle of switching stacks. Using IST for NMI events avoids making - assumptions about the previous state of the kernel stack. - -* DEBUG_STACK. DEBUG_STKSZ - - Used for hardware debug interrupts (interrupt 1) and for software - debug interrupts (INT3). - - When debugging a kernel, debug interrupts (both hardware and - software) can occur at any time. Using IST for these interrupts - avoids making assumptions about the previous state of the kernel - stack. - -* MCE_STACK. EXCEPTION_STKSZ (PAGE_SIZE). - - Used for interrupt 18 - Machine Check Exception (#MC). - - MCE can be delivered at any time, including when the kernel is in the - middle of switching stacks. Using IST for MCE events avoids making - assumptions about the previous state of the kernel stack. - -For more details see the Intel IA32 or AMD AMD64 architecture manuals. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index f0cd5a3f6de6..63673e6513b7 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -501,7 +501,7 @@ S: Maintained BLOCK LAYER P: Jens Axboe -M: axboe@kernel.dk +M: axboe@suse.de L: linux-kernel@vger.kernel.org T: git kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git S: Maintained @@ -851,7 +851,7 @@ P: Doug Warzecha M: Douglas_Warzecha@dell.com S: Maintained -DEVICE-MAPPER (LVM) +DEVICE-MAPPER P: Alasdair Kergon L: dm-devel@redhat.com W: http://sources.redhat.com/dm @@ -1380,7 +1380,7 @@ S: Maintained IDE/ATAPI CDROM DRIVER P: Jens Axboe -M: axboe@kernel.dk +M: axboe@suse.de L: linux-kernel@vger.kernel.org W: http://www.kernel.dk S: Maintained @@ -1398,29 +1398,36 @@ M: Gadi Oxman L: linux-kernel@vger.kernel.org S: Maintained +IEEE 1394 ETHERNET (eth1394) +L: linux1394-devel@lists.sourceforge.net +W: http://www.linux1394.org/ +S: Orphan + IEEE 1394 SUBSYSTEM P: Ben Collins M: bcollins@debian.org -P: Stefan Richter -M: stefanr@s5r6.in-berlin.de +P: Jody McIntyre +M: scjody@modernduck.com L: linux1394-devel@lists.sourceforge.net W: http://www.linux1394.org/ -T: git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git +T: git kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git S: Maintained -IEEE 1394 IPV4 DRIVER (eth1394) -P: Stefan Richter -M: stefanr@s5r6.in-berlin.de +IEEE 1394 OHCI DRIVER +P: Ben Collins +M: bcollins@debian.org +P: Jody McIntyre +M: scjody@modernduck.com L: linux1394-devel@lists.sourceforge.net -S: Odd Fixes +W: http://www.linux1394.org/ +S: Maintained IEEE 1394 PCILYNX DRIVER P: Jody McIntyre M: scjody@modernduck.com -P: Stefan Richter -M: stefanr@s5r6.in-berlin.de L: linux1394-devel@lists.sourceforge.net -S: Odd Fixes +W: http://www.linux1394.org/ +S: Maintained IEEE 1394 RAW I/O DRIVER P: Ben Collins @@ -1428,6 +1435,16 @@ M: bcollins@debian.org P: Dan Dennedy M: dan@dennedy.org L: linux1394-devel@lists.sourceforge.net +W: http://www.linux1394.org/ +S: Maintained + +IEEE 1394 SBP2 +P: Ben Collins +M: bcollins@debian.org +P: Stefan Richter +M: stefanr@s5r6.in-berlin.de +L: linux1394-devel@lists.sourceforge.net +W: http://www.linux1394.org/ S: Maintained IMS TWINTURBO FRAMEBUFFER DRIVER @@ -2045,7 +2062,7 @@ L: linux-hams@vger.kernel.org W: http://www.linux-ax25.org/ S: Maintained -NETWORK BLOCK DEVICE (NBD) +NETWORK BLOCK DEVICE P: Paul Clements M: Paul.Clements@steeleye.com S: Maintained @@ -2531,7 +2548,7 @@ S: Maintained SCSI CDROM DRIVER P: Jens Axboe -M: axboe@kernel.dk +M: axboe@suse.de L: linux-scsi@vger.kernel.org W: http://www.kernel.dk S: Maintained @@ -2793,12 +2810,6 @@ M: R.E.Wolff@BitWizard.nl L: linux-kernel@vger.kernel.org ? S: Supported -SPIDERNET NETWORK DRIVER for CELL -P: Jim Lewis -M: jim@jklewis.com -L: netdev@vger.kernel.org -S: Supported - SRM (Alpha) environment access P: Jan-Benedict Glaw M: jbglaw@lug-owl.de @@ -2823,9 +2834,12 @@ S: Maintained SUPERH (sh) P: Paul Mundt M: lethal@linux-sh.org -L: linuxsh-dev@lists.sourceforge.net (subscribers-only) +P: Kazumoto Kojima +M: kkojima@rr.iij4u.or.jp +L: linuxsh-dev@lists.sourceforge.net W: http://www.linux-sh.org W: http://www.m17n.org/linux-sh/ +W: http://www.rr.iij4u.or.jp/~kkojima/linux-sh4.html S: Maintained SUPERH64 (sh64) @@ -2976,7 +2990,7 @@ S: Maintained UNIFORM CDROM DRIVER P: Jens Axboe -M: axboe@kernel.dk +M: axboe@suse.de L: linux-kernel@vger.kernel.org W: http://www.kernel.dk S: Maintained @@ -3295,12 +3309,6 @@ W: http://linuxtv.org T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git S: Maintained -VT1211 HARDWARE MONITOR DRIVER -P: Juerg Haefliger -M: juergh@gmail.com -L: lm-sensors@lm-sensors.org -S: Maintained - VT8231 HARDWARE MONITOR DRIVER P: Roger Lucas M: roger@planbit.co.uk diff --git a/trunk/Makefile b/trunk/Makefile index 4c6c5e32ef96..80dac0245d66 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1385,13 +1385,9 @@ endif #ifeq ($(config-targets),1) endif #ifeq ($(mixed-targets),1) PHONY += checkstack kernelrelease kernelversion - -# Use $(SUBARCH) here instead of $(ARCH) so that this works for UML. -# In the UML case, $(SUBARCH) is the name of the underlying -# architecture, while for all other arches, it is the same as $(ARCH). checkstack: $(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \ - $(PERL) $(src)/scripts/checkstack.pl $(SUBARCH) + $(PERL) $(src)/scripts/checkstack.pl $(ARCH) kernelrelease: $(if $(wildcard include/config/kernel.release), $(Q)echo $(KERNELRELEASE), \ diff --git a/trunk/arch/alpha/kernel/alpha_ksyms.c b/trunk/arch/alpha/kernel/alpha_ksyms.c index dbe327d32b6f..f042cc42b00f 100644 --- a/trunk/arch/alpha/kernel/alpha_ksyms.c +++ b/trunk/arch/alpha/kernel/alpha_ksyms.c @@ -36,6 +36,7 @@ #include #include +#define __KERNEL_SYSCALLS__ #include extern struct hwrpb_struct *hwrpb; @@ -115,7 +116,7 @@ EXPORT_SYMBOL(sys_dup); EXPORT_SYMBOL(sys_exit); EXPORT_SYMBOL(sys_write); EXPORT_SYMBOL(sys_lseek); -EXPORT_SYMBOL(kernel_execve); +EXPORT_SYMBOL(execve); EXPORT_SYMBOL(sys_setsid); EXPORT_SYMBOL(sys_wait4); diff --git a/trunk/arch/alpha/kernel/entry.S b/trunk/arch/alpha/kernel/entry.S index c95e95e1ab04..01ecd09d4a64 100644 --- a/trunk/arch/alpha/kernel/entry.S +++ b/trunk/arch/alpha/kernel/entry.S @@ -655,12 +655,12 @@ kernel_thread: .end kernel_thread /* - * kernel_execve(path, argv, envp) + * execve(path, argv, envp) */ .align 4 - .globl kernel_execve - .ent kernel_execve -kernel_execve: + .globl execve + .ent execve +execve: /* We can be called from a module. */ ldgp $gp, 0($27) lda $sp, -(32+SIZEOF_PT_REGS+8)($sp) @@ -704,7 +704,7 @@ kernel_execve: 1: lda $sp, 32+SIZEOF_PT_REGS+8($sp) ret -.end kernel_execve +.end execve /* diff --git a/trunk/arch/alpha/kernel/osf_sys.c b/trunk/arch/alpha/kernel/osf_sys.c index 8a31fc1bfb15..73c7622b5297 100644 --- a/trunk/arch/alpha/kernel/osf_sys.c +++ b/trunk/arch/alpha/kernel/osf_sys.c @@ -402,15 +402,15 @@ osf_utsname(char __user *name) down_read(&uts_sem); error = -EFAULT; - if (copy_to_user(name + 0, utsname()->sysname, 32)) + if (copy_to_user(name + 0, system_utsname.sysname, 32)) goto out; - if (copy_to_user(name + 32, utsname()->nodename, 32)) + if (copy_to_user(name + 32, system_utsname.nodename, 32)) goto out; - if (copy_to_user(name + 64, utsname()->release, 32)) + if (copy_to_user(name + 64, system_utsname.release, 32)) goto out; - if (copy_to_user(name + 96, utsname()->version, 32)) + if (copy_to_user(name + 96, system_utsname.version, 32)) goto out; - if (copy_to_user(name + 128, utsname()->machine, 32)) + if (copy_to_user(name + 128, system_utsname.machine, 32)) goto out; error = 0; @@ -449,8 +449,8 @@ osf_getdomainname(char __user *name, int namelen) down_read(&uts_sem); for (i = 0; i < len; ++i) { - __put_user(utsname()->domainname[i], name + i); - if (utsname()->domainname[i] == '\0') + __put_user(system_utsname.domainname[i], name + i); + if (system_utsname.domainname[i] == '\0') break; } up_read(&uts_sem); @@ -607,12 +607,12 @@ osf_sigstack(struct sigstack __user *uss, struct sigstack __user *uoss) asmlinkage long osf_sysinfo(int command, char __user *buf, long count) { - char *sysinfo_table[] = { - utsname()->sysname, - utsname()->nodename, - utsname()->release, - utsname()->version, - utsname()->machine, + static char * sysinfo_table[] = { + system_utsname.sysname, + system_utsname.nodename, + system_utsname.release, + system_utsname.version, + system_utsname.machine, "alpha", /* instruction set architecture */ "dummy", /* hardware serial number */ "dummy", /* hardware manufacturer */ diff --git a/trunk/arch/alpha/kernel/proto.h b/trunk/arch/alpha/kernel/proto.h index 21f71287b6f5..2a6e3da8144f 100644 --- a/trunk/arch/alpha/kernel/proto.h +++ b/trunk/arch/alpha/kernel/proto.h @@ -1,7 +1,5 @@ #include -#include -#include /* Prototypes of functions used across modules here in this directory. */ @@ -183,16 +181,9 @@ extern void titan_dispatch_irqs(u64, struct pt_regs *); extern void switch_to_system_map(void); extern void srm_paging_stop(void); -static inline int -__alpha_remap_area_pages(unsigned long address, unsigned long phys_addr, - unsigned long size, unsigned long flags) -{ - pgprot_t prot; - - prot = __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE - | _PAGE_KWE | flags); - return ioremap_page_range(address, address + size, phys_addr, prot); -} +/* ../mm/remap.c */ +extern int __alpha_remap_area_pages(unsigned long, unsigned long, + unsigned long, unsigned long); /* irq.c */ diff --git a/trunk/arch/alpha/kernel/srmcons.c b/trunk/arch/alpha/kernel/srmcons.c index 756923203860..9d7dff27f815 100644 --- a/trunk/arch/alpha/kernel/srmcons.c +++ b/trunk/arch/alpha/kernel/srmcons.c @@ -229,7 +229,7 @@ srmcons_close(struct tty_struct *tty, struct file *filp) static struct tty_driver *srmcons_driver; -static const struct tty_operations srmcons_ops = { +static struct tty_operations srmcons_ops = { .open = srmcons_open, .close = srmcons_close, .write = srmcons_write, diff --git a/trunk/arch/alpha/kernel/time.c b/trunk/arch/alpha/kernel/time.c index 581ddcc22fc5..b191cc759737 100644 --- a/trunk/arch/alpha/kernel/time.c +++ b/trunk/arch/alpha/kernel/time.c @@ -54,6 +54,8 @@ #include "proto.h" #include "irq_impl.h" +extern unsigned long wall_jiffies; /* kernel/timer.c */ + static int set_rtc_mmss(unsigned long); DEFINE_SPINLOCK(rtc_lock); @@ -130,7 +132,7 @@ irqreturn_t timer_interrupt(int irq, void *dev, struct pt_regs * regs) nticks = delta >> FIX_SHIFT; while (nticks > 0) { - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -411,7 +413,7 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; - unsigned long sec, usec, seq; + unsigned long sec, usec, lost, seq; unsigned long delta_cycles, delta_usec, partial_tick; do { @@ -421,13 +423,14 @@ do_gettimeofday(struct timeval *tv) sec = xtime.tv_sec; usec = (xtime.tv_nsec / 1000); partial_tick = state.partial_tick; + lost = jiffies - wall_jiffies; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); #ifdef CONFIG_SMP /* Until and unless we figure out how to get cpu cycle counters in sync and keep them there, we can't use the rpcc tricks. */ - delta_usec = 0; + delta_usec = lost * (1000000 / HZ); #else /* * usec = cycles * ticks_per_cycle * 2**48 * 1e6 / (2**48 * ticks) @@ -443,7 +446,8 @@ do_gettimeofday(struct timeval *tv) */ delta_usec = (delta_cycles * state.scaled_ticks_per_cycle - + partial_tick) * 15625; + + partial_tick + + (lost << FIX_SHIFT)) * 15625; delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2; #endif @@ -476,11 +480,12 @@ do_settimeofday(struct timespec *tv) time. Without this, a full-tick error is possible. */ #ifdef CONFIG_SMP - delta_nsec = 0; + delta_nsec = (jiffies - wall_jiffies) * (NSEC_PER_SEC / HZ); #else delta_nsec = rpcc() - state.last_time; delta_nsec = (delta_nsec * state.scaled_ticks_per_cycle - + state.partial_tick) * 15625; + + state.partial_tick + + ((jiffies - wall_jiffies) << FIX_SHIFT)) * 15625; delta_nsec = ((delta_nsec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2; delta_nsec *= 1000; #endif diff --git a/trunk/arch/alpha/mm/Makefile b/trunk/arch/alpha/mm/Makefile index 09399c5386cb..6edd9a09ea4f 100644 --- a/trunk/arch/alpha/mm/Makefile +++ b/trunk/arch/alpha/mm/Makefile @@ -4,6 +4,6 @@ EXTRA_CFLAGS := -Werror -obj-y := init.o fault.o extable.o +obj-y := init.o fault.o extable.o remap.o obj-$(CONFIG_DISCONTIGMEM) += numa.o diff --git a/trunk/arch/alpha/mm/fault.c b/trunk/arch/alpha/mm/fault.c index 8871529a34e2..622dabd84680 100644 --- a/trunk/arch/alpha/mm/fault.c +++ b/trunk/arch/alpha/mm/fault.c @@ -193,7 +193,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr, /* We ran out of memory, or some other thing happened to us that made us unable to handle the page fault gracefully. */ out_of_memory: - if (is_init(current)) { + if (current->pid == 1) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/alpha/mm/remap.c b/trunk/arch/alpha/mm/remap.c new file mode 100644 index 000000000000..a78356c3ead5 --- /dev/null +++ b/trunk/arch/alpha/mm/remap.c @@ -0,0 +1,86 @@ +#include +#include +#include + +static inline void +remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + unsigned long pfn; + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + pfn = phys_addr >> PAGE_SHIFT; + do { + if (!pte_none(*pte)) { + printk("remap_area_pte: page already exists\n"); + BUG(); + } + set_pte(pte, pfn_pte(pfn, + __pgprot(_PAGE_VALID | _PAGE_ASM | + _PAGE_KRE | _PAGE_KWE | flags))); + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); +} + +static inline int +remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pte_t * pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, + address + phys_addr, flags); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +int +__alpha_remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags) +{ + pgd_t * dir; + int error = 0; + unsigned long end = address + size; + + phys_addr -= address; + dir = pgd_offset(&init_mm, address); + flush_cache_all(); + if (address >= end) + BUG(); + do { + pmd_t *pmd; + pmd = pmd_alloc(&init_mm, dir, address); + error = -ENOMEM; + if (!pmd) + break; + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, flags)) + break; + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + return error; +} + diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index f9362ee9955f..f81a62380add 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -17,10 +17,6 @@ config ARM Europe. There is an ARM Linux project with a web page at . -config GENERIC_TIME - bool - default n - config MMU bool default y @@ -55,10 +51,6 @@ config GENERIC_HARDIRQS bool default y -config TRACE_IRQFLAGS_SUPPORT - bool - default y - config HARDIRQS_SW_RESEND bool default y @@ -99,7 +91,7 @@ config ARCH_MTD_XIP config VECTORS_BASE hex - default 0xffff0000 if MMU || CPU_HIGH_VECTOR + default 0xffff0000 if MMU default DRAM_BASE if REMAP_VECTORS_TO_RAM default 0x00000000 help @@ -206,27 +198,16 @@ config ARCH_IMX help Support for Motorola's i.MX family of processors (MX1, MXL). -config ARCH_IOP32X - bool "IOP32x-based" - depends on MMU - select PLAT_IOP - select PCI - help - Support for Intel's 80219 and IOP32X (XScale) family of - processors. - -config ARCH_IOP33X - bool "IOP33x-based" +config ARCH_IOP3XX + bool "IOP3xx-based" depends on MMU - select PLAT_IOP select PCI help - Support for Intel's IOP33X (XScale) family of processors. + Support for Intel's IOP3XX (XScale) family of processors. config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU - select GENERIC_TIME help Support for Intel's IXP4XX (XScale) family of processors. @@ -327,9 +308,7 @@ source "arch/arm/mach-footbridge/Kconfig" source "arch/arm/mach-integrator/Kconfig" -source "arch/arm/mach-iop32x/Kconfig" - -source "arch/arm/mach-iop33x/Kconfig" +source "arch/arm/mach-iop3xx/Kconfig" source "arch/arm/mach-ixp4xx/Kconfig" @@ -369,9 +348,6 @@ source "arch/arm/mach-netx/Kconfig" config ARCH_ACORN bool -config PLAT_IOP - bool - source arch/arm/mm/Kconfig # bool 'Use XScale PMU as timer source' CONFIG_XSCALE_PMU_TIMER @@ -626,7 +602,6 @@ config LEDS_CPU config ALIGNMENT_TRAP bool - depends on CPU_CP15_MMU default y if !ARCH_EBSA110 help ARM processors can not fetch/store information which is not @@ -658,12 +633,11 @@ config ZBOOT_ROM_BSS hex "Compressed ROM boot loader BSS address" default "0" help - The base address of an area of read/write memory in the target - for the ROM-able zImage which must be available while the - decompressor is running. It must be large enough to hold the - entire decompressed kernel plus an additional 128 KiB. - Platforms which normally make use of ROM-able zImage formats - normally set this to a suitable value in their defconfig file. + The base address of 64KiB of read/write memory in the target + for the ROM-able zImage, which must be available while the + decompressor is running. Platforms which normally make use of + ROM-able zImage formats normally set this to a suitable + value in their defconfig file. If ZBOOT_ROM is not enabled, this has no effect. @@ -858,7 +832,7 @@ source "drivers/base/Kconfig" source "drivers/connector/Kconfig" -if ALIGNMENT_TRAP || !CPU_CP15_MMU +if ALIGNMENT_TRAP source "drivers/mtd/Kconfig" endif @@ -870,7 +844,7 @@ source "drivers/block/Kconfig" source "drivers/acorn/block/Kconfig" -if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX \ +if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \ || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE \ || ARCH_IXP23XX diff --git a/trunk/arch/arm/Kconfig-nommu b/trunk/arch/arm/Kconfig-nommu index f087376748d1..e1574be2ded6 100644 --- a/trunk/arch/arm/Kconfig-nommu +++ b/trunk/arch/arm/Kconfig-nommu @@ -25,14 +25,6 @@ config FLASH_SIZE hex 'FLASH Size' if SET_MEM_PARAM default 0x00400000 -config PROCESSOR_ID - hex - default 0x00007700 - depends on !CPU_CP15 - help - If processor has no CP15 register, this processor ID is - used instead of the auto-probing which utilizes the register. - config REMAP_VECTORS_TO_RAM bool 'Install vectors to the begining of RAM' if DRAM_BASE depends on DRAM_BASE diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index 2a0b2c8a1fe0..92873cdee31f 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -55,12 +55,7 @@ arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3 # This selects how we optimise for the processor. tune-$(CONFIG_CPU_ARM610) :=-mtune=arm610 tune-$(CONFIG_CPU_ARM710) :=-mtune=arm710 -tune-$(CONFIG_CPU_ARM7TDMI) :=-mtune=arm7tdmi tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi -tune-$(CONFIG_CPU_ARM740T) :=-mtune=arm7tdmi -tune-$(CONFIG_CPU_ARM9TDMI) :=-mtune=arm9tdmi -tune-$(CONFIG_CPU_ARM940T) :=-mtune=arm9tdmi -tune-$(CONFIG_CPU_ARM946T) :=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi) tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi @@ -106,8 +101,7 @@ endif machine-$(CONFIG_ARCH_INTEGRATOR) := integrator textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 machine-$(CONFIG_ARCH_CLPS711X) := clps711x - machine-$(CONFIG_ARCH_IOP32X) := iop32x - machine-$(CONFIG_ARCH_IOP33X) := iop33x + machine-$(CONFIG_ARCH_IOP3XX) := iop3xx machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_IXP2000) := ixp2000 machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx @@ -163,7 +157,6 @@ core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ) core-$(CONFIG_VFP) += arch/arm/vfp/ # If we have a common platform directory, then include it in the build. -core-$(CONFIG_PLAT_IOP) += arch/arm/plat-iop/ core-$(CONFIG_ARCH_OMAP) += arch/arm/plat-omap/ drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ diff --git a/trunk/arch/arm/boot/compressed/Makefile b/trunk/arch/arm/boot/compressed/Makefile index adddc7131685..2adc1527e0eb 100644 --- a/trunk/arch/arm/boot/compressed/Makefile +++ b/trunk/arch/arm/boot/compressed/Makefile @@ -51,11 +51,7 @@ OBJS += head-at91rm9200.o endif ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) -ifeq ($(CONFIG_CPU_CP15),y) OBJS += big-endian.o -else -# The endian should be set by h/w design. -endif endif # diff --git a/trunk/arch/arm/boot/compressed/head.S b/trunk/arch/arm/boot/compressed/head.S index e5ab51b9cceb..14a9ff9c68df 100644 --- a/trunk/arch/arm/boot/compressed/head.S +++ b/trunk/arch/arm/boot/compressed/head.S @@ -20,21 +20,11 @@ #ifdef DEBUG #if defined(CONFIG_DEBUG_ICEDCC) - -#ifdef CONFIG_CPU_V6 - .macro loadsp, rb - .endm - .macro writeb, ch, rb - mcr p14, 0, \ch, c0, c5, 0 - .endm -#else .macro loadsp, rb .endm .macro writeb, ch, rb mcr p14, 0, \ch, c0, c1, 0 .endm -#endif - #else #include @@ -52,6 +42,12 @@ add \rb, \rb, #0x00010000 @ Ser1 #endif .endm +#elif defined(CONFIG_ARCH_IOP331) + .macro loadsp, rb + mov \rb, #0xff000000 + orr \rb, \rb, #0x00ff0000 + orr \rb, \rb, #0x0000f700 @ location of the UART + .endm #elif defined(CONFIG_ARCH_S3C2410) .macro loadsp, rb mov \rb, #0x50000000 @@ -82,11 +78,9 @@ kphex r6, 8 /* processor id */ kputc #':' kphex r7, 8 /* architecture id */ -#ifdef CONFIG_CPU_CP15 kputc #':' mrc p15, 0, r0, c1, c0 kphex r0, 8 /* control reg */ -#endif kputc #'\n' kphex r5, 8 /* decompressed kernel start */ kputc #'-' @@ -509,11 +503,7 @@ call_kernel: bl cache_clean_flush */ call_cache_fn: adr r12, proc_types -#ifdef CONFIG_CPU_CP15 mrc p15, 0, r6, c0, c0 @ get processor ID -#else - ldr r6, =CONFIG_PROCESSOR_ID -#endif 1: ldr r1, [r12, #0] @ get value ldr r2, [r12, #4] @ get mask eor r1, r1, r6 @ (real ^ match) diff --git a/trunk/arch/arm/boot/compressed/misc.c b/trunk/arch/arm/boot/compressed/misc.c index 283891c736c4..ace3fb5835d9 100644 --- a/trunk/arch/arm/boot/compressed/misc.c +++ b/trunk/arch/arm/boot/compressed/misc.c @@ -30,25 +30,6 @@ static void putstr(const char *ptr); #include #ifdef CONFIG_DEBUG_ICEDCC - -#ifdef CONFIG_CPU_V6 - -static void icedcc_putc(int ch) -{ - int status, i = 0x4000000; - - do { - if (--i < 0) - return; - - asm volatile ("mrc p14, 0, %0, c0, c1, 0" : "=r" (status)); - } while (status & (1 << 29)); - - asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch)); -} - -#else - static void icedcc_putc(int ch) { int status, i = 0x4000000; @@ -63,8 +44,6 @@ static void icedcc_putc(int ch) asm("mcr p14, 0, %0, c1, c0, 0" : : "r" (ch)); } -#endif - #define putc(ch) icedcc_putc(ch) #define flush() do { } while (0) #endif diff --git a/trunk/arch/arm/common/icst307.c b/trunk/arch/arm/common/icst307.c index 6d094c157540..bafe8b19be82 100644 --- a/trunk/arch/arm/common/icst307.c +++ b/trunk/arch/arm/common/icst307.c @@ -57,7 +57,7 @@ icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq) break; } while (i < ARRAY_SIZE(idx2s)); - if (i >= ARRAY_SIZE(idx2s)) + if (i > ARRAY_SIZE(idx2s)) return vco; vco.s = idx2s[i]; @@ -119,7 +119,7 @@ icst307_ps_to_vco(const struct icst307_params *p, unsigned long period) break; } while (i < ARRAY_SIZE(idx2s)); - if (i >= ARRAY_SIZE(idx2s)) + if (i > ARRAY_SIZE(idx2s)) return vco; vco.s = idx2s[i]; diff --git a/trunk/arch/arm/common/icst525.c b/trunk/arch/arm/common/icst525.c index 3d377c5bdef6..943ef88c0379 100644 --- a/trunk/arch/arm/common/icst525.c +++ b/trunk/arch/arm/common/icst525.c @@ -55,7 +55,7 @@ icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq) break; } while (i < ARRAY_SIZE(idx2s)); - if (i >= ARRAY_SIZE(idx2s)) + if (i > ARRAY_SIZE(idx2s)) return vco; vco.s = idx2s[i]; @@ -118,7 +118,7 @@ icst525_ps_to_vco(const struct icst525_params *p, unsigned long period) break; } while (i < ARRAY_SIZE(idx2s)); - if (i >= ARRAY_SIZE(idx2s)) + if (i > ARRAY_SIZE(idx2s)) return vco; vco.s = idx2s[i]; diff --git a/trunk/arch/arm/common/locomo.c b/trunk/arch/arm/common/locomo.c index 181ef1ead5b8..4e0dcaef6eb2 100644 --- a/trunk/arch/arm/common/locomo.c +++ b/trunk/arch/arm/common/locomo.c @@ -121,13 +121,6 @@ static struct locomo_dev_info locomo_devices[] = { .offset = 0, .length = 0, }, - { - .devid = LOCOMO_DEVID_SPI, - .irq = {}, - .name = "locomo-spi", - .offset = LOCOMO_SPI, - .length = 0x30, - }, }; @@ -381,7 +374,7 @@ static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc, struct irqdesc *d; void __iomem *mapbase = get_irq_chipdata(irq); - req = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIR) & 0x000F; + req = locomo_readl(mapbase + LOCOMO_SPIIR) & 0x000F; if (req) { irq = LOCOMO_IRQ_SPI_START; d = irq_desc + irq; @@ -398,35 +391,35 @@ static void locomo_spi_ack_irq(unsigned int irq) { void __iomem *mapbase = get_irq_chipdata(irq); unsigned int r; - r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE); + r = locomo_readl(mapbase + LOCOMO_SPIWE); r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE); + locomo_writel(r, mapbase + LOCOMO_SPIWE); - r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIS); + r = locomo_readl(mapbase + LOCOMO_SPIIS); r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIS); + locomo_writel(r, mapbase + LOCOMO_SPIIS); - r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE); + r = locomo_readl(mapbase + LOCOMO_SPIWE); r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE); + locomo_writel(r, mapbase + LOCOMO_SPIWE); } static void locomo_spi_mask_irq(unsigned int irq) { void __iomem *mapbase = get_irq_chipdata(irq); unsigned int r; - r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE); + r = locomo_readl(mapbase + LOCOMO_SPIIE); r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE); + locomo_writel(r, mapbase + LOCOMO_SPIIE); } static void locomo_spi_unmask_irq(unsigned int irq) { void __iomem *mapbase = get_irq_chipdata(irq); unsigned int r; - r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE); + r = locomo_readl(mapbase + LOCOMO_SPIIE); r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE); + locomo_writel(r, mapbase + LOCOMO_SPIIE); } static struct irq_chip locomo_spi_chip = { @@ -821,15 +814,12 @@ static inline struct locomo *locomo_chip_driver(struct locomo_dev *ldev) return (struct locomo *)dev_get_drvdata(ldev->dev.parent); } -void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir) +void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned int dir) { - struct locomo *lchip = dev_get_drvdata(dev); + struct locomo *lchip = locomo_chip_driver(ldev); unsigned long flags; unsigned int r; - if (!lchip) - return; - spin_lock_irqsave(&lchip->lock, flags); r = locomo_readl(lchip->base + LOCOMO_GPD); @@ -846,15 +836,12 @@ void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir spin_unlock_irqrestore(&lchip->lock, flags); } -int locomo_gpio_read_level(struct device *dev, unsigned int bits) +unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits) { - struct locomo *lchip = dev_get_drvdata(dev); + struct locomo *lchip = locomo_chip_driver(ldev); unsigned long flags; unsigned int ret; - if (!lchip) - return -ENODEV; - spin_lock_irqsave(&lchip->lock, flags); ret = locomo_readl(lchip->base + LOCOMO_GPL); spin_unlock_irqrestore(&lchip->lock, flags); @@ -863,15 +850,12 @@ int locomo_gpio_read_level(struct device *dev, unsigned int bits) return ret; } -int locomo_gpio_read_output(struct device *dev, unsigned int bits) +unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits) { - struct locomo *lchip = dev_get_drvdata(dev); + struct locomo *lchip = locomo_chip_driver(ldev); unsigned long flags; unsigned int ret; - if (!lchip) - return -ENODEV; - spin_lock_irqsave(&lchip->lock, flags); ret = locomo_readl(lchip->base + LOCOMO_GPO); spin_unlock_irqrestore(&lchip->lock, flags); @@ -880,15 +864,12 @@ int locomo_gpio_read_output(struct device *dev, unsigned int bits) return ret; } -void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set) +void locomo_gpio_write(struct locomo_dev *ldev, unsigned int bits, unsigned int set) { - struct locomo *lchip = dev_get_drvdata(dev); + struct locomo *lchip = locomo_chip_driver(ldev); unsigned long flags; unsigned int r; - if (!lchip) - return; - spin_lock_irqsave(&lchip->lock, flags); r = locomo_readl(lchip->base + LOCOMO_GPO); @@ -1077,9 +1058,9 @@ void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf) struct locomo *lchip = locomo_chip_driver(dev); if (vr) - locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 1); + locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 1); else - locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 0); + locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 0); spin_lock_irqsave(&lchip->lock, flags); locomo_writel(bpwf, lchip->base + LOCOMO_FRONTLIGHT + LOCOMO_ALS); diff --git a/trunk/arch/arm/common/sharpsl_pm.c b/trunk/arch/arm/common/sharpsl_pm.c index f412dedda684..59b5ddec480f 100644 --- a/trunk/arch/arm/common/sharpsl_pm.c +++ b/trunk/arch/arm/common/sharpsl_pm.c @@ -40,7 +40,6 @@ #define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */ #define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */ #define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */ - #define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */ #define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */ #define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */ @@ -576,9 +575,6 @@ static int corgi_pxa_pm_enter(suspend_state_t state) while (corgi_enter_suspend(alarm_time,alarm_status,state)) {} - if (sharpsl_pm.machinfo->earlyresume) - sharpsl_pm.machinfo->earlyresume(); - dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n"); return 0; diff --git a/trunk/arch/arm/configs/iop32x_defconfig b/trunk/arch/arm/configs/ep80219_defconfig similarity index 66% rename from trunk/arch/arm/configs/iop32x_defconfig rename to trunk/arch/arm/configs/ep80219_defconfig index 0d67f66e78c2..3c73b707c2f3 100644 --- a/trunk/arch/arm/configs/iop32x_defconfig +++ b/trunk/arch/arm/configs/ep80219_defconfig @@ -1,63 +1,50 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc7 -# Tue Sep 19 00:30:18 2006 +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 22:34:12 2005 # CONFIG_ARM=y CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_GENERIC_IOMAP=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y -CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -65,52 +52,24 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y -# -# Block layer -# -# CONFIG_BLK_DEV_IO_TRACE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" - # # System Type # -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91 is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IMX is not set -CONFIG_ARCH_IOP32X=y -# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_INTEGRATOR is not set +CONFIG_ARCH_IOP3XX=y # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set @@ -118,19 +77,28 @@ CONFIG_ARCH_IOP32X=y # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set # -# IOP32x Implementation Options +# IOP3xx Implementation Options # # -# IOP32x Platform Types +# IOP3xx Platform Types # -CONFIG_MACH_GLANTANK=y -CONFIG_ARCH_IQ80321=y +# CONFIG_ARCH_IQ80321 is not set CONFIG_ARCH_IQ31244=y -CONFIG_MACH_N2100=y -CONFIG_PLAT_IOP=y +# CONFIG_ARCH_IQ80331 is not set +# CONFIG_MACH_IQ80332 is not set +CONFIG_ARCH_EP80219=y +CONFIG_ARCH_IOP321=y +# CONFIG_ARCH_IOP331 is not set + +# +# IOP3xx Chipset Features +# # # Processor Type @@ -141,6 +109,7 @@ CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y # # Processor Features @@ -152,7 +121,8 @@ CONFIG_XSCALE_PMU=y # Bus support # CONFIG_PCI=y -# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_NAMES=y # # PCCARD (PCMCIA/CardBus) support @@ -163,19 +133,6 @@ CONFIG_PCI=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set -CONFIG_HZ=100 -# CONFIG_AEABI is not set -# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4096 -# CONFIG_RESOURCES_64BIT is not set CONFIG_ALIGNMENT_TRAP=y # @@ -183,7 +140,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp" +CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" # CONFIG_XIP_KERNEL is not set # @@ -209,93 +166,6 @@ CONFIG_BINFMT_AOUT=y # Power management options # # CONFIG_PM is not set -# CONFIG_APM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set # # Device Drivers @@ -307,13 +177,6 @@ CONFIG_TCP_CONG_BIC=y CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set # # Memory Technology Devices (MTD) @@ -337,7 +200,6 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set # # RAM/ROM/Flash chip drivers @@ -363,18 +225,18 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x0 -CONFIG_MTD_PHYSMAP_LEN=0x0 -CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +CONFIG_MTD_PHYSMAP_START=0xf0000000 +CONFIG_MTD_PHYSMAP_LEN=0x00800000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_EDB7312 is not set # # Self-contained MTD device drivers @@ -383,6 +245,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -397,11 +260,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # # CONFIG_MTD_NAND is not set -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - # # Parallel port support # @@ -414,6 +272,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # # Block devices # +# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -425,9 +284,17 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y # CONFIG_ATA_OVER_ETH is not set # @@ -438,7 +305,6 @@ CONFIG_BLK_DEV_INITRD=y # # SCSI device support # -# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -450,7 +316,6 @@ CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set CONFIG_CHR_DEV_SG=y -# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -465,12 +330,10 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set # # SCSI low-level drivers # -# CONFIG_ISCSI_TCP is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_ACARD is not set @@ -481,19 +344,25 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_DPT_I2O is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_LPFC is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set @@ -508,7 +377,8 @@ CONFIG_BLK_DEV_MD=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y # CONFIG_MD_RAID10 is not set -# CONFIG_MD_RAID456 is not set +CONFIG_MD_RAID5=y +# CONFIG_MD_RAID6 is not set # CONFIG_MD_MULTIPATH is not set # CONFIG_MD_FAULTY is not set CONFIG_BLK_DEV_DM=y @@ -522,9 +392,6 @@ CONFIG_BLK_DEV_DM=y # Fusion MPT device support # # CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support @@ -537,8 +404,71 @@ CONFIG_BLK_DEV_DM=y # CONFIG_I2O is not set # -# Network device support +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing # +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -550,11 +480,6 @@ CONFIG_NETDEVICES=y # # CONFIG_ARCNET is not set -# -# PHY device support -# -# CONFIG_PHYLIB is not set - # # Ethernet (10 or 100Mbit) # @@ -562,10 +487,8 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_SMC91X is not set -# CONFIG_DM9000 is not set # # Tulip family network device support @@ -603,23 +526,16 @@ CONFIG_E1000_NAPI=y # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set -CONFIG_R8169=y -# CONFIG_R8169_NAPI is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set +# CONFIG_R8169 is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) # -# CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -642,8 +558,6 @@ CONFIG_R8169=y # CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -681,6 +595,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # # CONFIG_SERIO is not set # CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -688,7 +603,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -696,9 +610,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set # @@ -706,7 +618,6 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -720,8 +631,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y # CONFIG_NVRAM is not set +# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -736,7 +647,6 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -761,13 +671,14 @@ CONFIG_I2C_CHARDEV=y # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_ISA is not set # CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -778,45 +689,15 @@ CONFIG_I2C_IOP3XX=y # CONFIG_I2C_PCA_ISA is not set # -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus +# Hardware Sensors Chip support # - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_I2C_SENSOR is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_FSCHER is not set # CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set @@ -831,45 +712,36 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set # -# LED drivers +# Other I2C Chip support # +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set # -# LED Triggers +# Misc devices # # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -879,7 +751,6 @@ CONFIG_VIDEO_V4L2=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # @@ -887,7 +758,6 @@ CONFIG_FIRMWARE_EDID=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -899,125 +769,7 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -# CONFIG_USB_DEVICEFS is not set -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_SPLIT_ISO=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_EHCI_TT_NEWSCHED=y -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_OHCI_HCD is not set -CONFIG_USB_UHCI_HCD=y -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=y -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_LIBUSUAL is not set - -# -# USB Input Devices -# -# CONFIG_USB_HID is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGETKIT is not set -# CONFIG_USB_PHIDGETSERVO is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set - -# -# USB DSL modem support -# +# CONFIG_USB is not set # # USB Gadget Support @@ -1029,18 +781,11 @@ CONFIG_USB_MON=y # # CONFIG_MMC is not set -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set - # # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set @@ -1050,22 +795,22 @@ CONFIG_JBD=y CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set + +# +# XFS support +# CONFIG_XFS_FS=y +CONFIG_XFS_EXPORT=y +# CONFIG_XFS_RT is not set # CONFIG_XFS_QUOTA is not set CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y -# CONFIG_XFS_RT is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -1085,10 +830,12 @@ CONFIG_DNOTIFY=y # CONFIG_PROC_FS=y CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -1103,9 +850,8 @@ CONFIG_RAMFS=y # CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y @@ -1122,19 +868,16 @@ CONFIG_JFFS2_RTIME=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set # CONFIG_NFSD_TCP is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set @@ -1143,7 +886,6 @@ CONFIG_SUNRPC=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types @@ -1163,7 +905,6 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # @@ -1180,34 +921,11 @@ CONFIG_MSDOS_PARTITION=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_RWSEMS is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set -# CONFIG_FORCED_INLINING is not set -# CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set -# CONFIG_DEBUG_ERRORS is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_ICEDCC is not set # # Security options @@ -1228,9 +946,7 @@ CONFIG_DEBUG_LL=y # Library routines # # CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y diff --git a/trunk/arch/arm/configs/ep93xx_defconfig b/trunk/arch/arm/configs/ep93xx_defconfig index 3b4802a849e4..2948b4589a8b 100644 --- a/trunk/arch/arm/configs/ep93xx_defconfig +++ b/trunk/arch/arm/configs/ep93xx_defconfig @@ -126,7 +126,6 @@ CONFIG_CRUNCH=y # EP93xx Platforms # CONFIG_MACH_EDB9302=y -CONFIG_MACH_EDB9312=y CONFIG_MACH_EDB9315=y CONFIG_MACH_EDB9315A=y CONFIG_MACH_GESBC9312=y diff --git a/trunk/arch/arm/configs/iq31244_defconfig b/trunk/arch/arm/configs/iq31244_defconfig new file mode 100644 index 000000000000..32467160a6df --- /dev/null +++ b/trunk/arch/arm/configs/iq31244_defconfig @@ -0,0 +1,922 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 02:10:38 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +CONFIG_ARCH_IOP3XX=y +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# IOP3xx Implementation Options +# + +# +# IOP3xx Platform Types +# +# CONFIG_ARCH_IQ80321 is not set +CONFIG_ARCH_IQ31244=y +# CONFIG_ARCH_IQ80331 is not set +# CONFIG_MACH_IQ80332 is not set +# CONFIG_ARCH_EP80219 is not set +CONFIG_ARCH_IOP321=y +# CONFIG_ARCH_IOP331 is not set + +# +# IOP3xx Chipset Features +# + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xf0000000 +CONFIG_MTD_PHYSMAP_LEN=0x00800000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +# CONFIG_MD_LINEAR is not set +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +# CONFIG_MD_RAID10 is not set +CONFIG_MD_RAID5=y +# CONFIG_MD_RAID6 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +CONFIG_E1000_NAPI=y +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +CONFIG_XFS_FS=y +CONFIG_XFS_EXPORT=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_QUOTA is not set +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/trunk/arch/arm/configs/iq80321_defconfig b/trunk/arch/arm/configs/iq80321_defconfig new file mode 100644 index 000000000000..b000da753c41 --- /dev/null +++ b/trunk/arch/arm/configs/iq80321_defconfig @@ -0,0 +1,843 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 13:24:10 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +CONFIG_ARCH_IOP3XX=y +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# IOP3xx Implementation Options +# + +# +# IOP3xx Platform Types +# +CONFIG_ARCH_IQ80321=y +# CONFIG_ARCH_IQ31244 is not set +# CONFIG_ARCH_IQ80331 is not set +# CONFIG_MACH_IQ80332 is not set +# CONFIG_ARCH_EP80219 is not set +CONFIG_ARCH_IOP321=y +# CONFIG_ARCH_IOP331 is not set + +# +# IOP3xx Chipset Features +# + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xf0000000 +CONFIG_MTD_PHYSMAP_LEN=0x00800000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +CONFIG_E1000_NAPI=y +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +CONFIG_XFS_FS=y +CONFIG_XFS_EXPORT=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_QUOTA is not set +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_NAND is not set +# CONFIG_JFFS2_FS_NOR_ECC is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/trunk/arch/arm/configs/iop33x_defconfig b/trunk/arch/arm/configs/iq80331_defconfig similarity index 74% rename from trunk/arch/arm/configs/iop33x_defconfig rename to trunk/arch/arm/configs/iq80331_defconfig index 2a8fc153969d..46c79e1efe07 100644 --- a/trunk/arch/arm/configs/iop33x_defconfig +++ b/trunk/arch/arm/configs/iq80331_defconfig @@ -1,63 +1,50 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc7 -# Tue Sep 19 00:30:42 2006 +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 15:13:37 2005 # CONFIG_ARM=y CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_GENERIC_IOMAP=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y -CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SHMEM=y -CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support @@ -65,52 +52,24 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y -# -# Block layer -# -# CONFIG_BLK_DEV_IO_TRACE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -CONFIG_DEFAULT_CFQ=y -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="cfq" - # # System Type # -# CONFIG_ARCH_AAEC2000 is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_REALVIEW is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91 is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set # CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_EP93XX is not set # CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_NETX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_IOP32X is not set -CONFIG_ARCH_IOP33X=y +# CONFIG_ARCH_INTEGRATOR is not set +CONFIG_ARCH_IOP3XX=y # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_IXP23XX is not set # CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PNX4008 is not set # CONFIG_ARCH_PXA is not set # CONFIG_ARCH_RPC is not set # CONFIG_ARCH_SA1100 is not set @@ -118,17 +77,28 @@ CONFIG_ARCH_IOP33X=y # CONFIG_ARCH_SHARK is not set # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set # -# IOP33x Implementation Options +# IOP3xx Implementation Options # # -# IOP33x Platform Types +# IOP3xx Platform Types # +# CONFIG_ARCH_IQ80321 is not set +# CONFIG_ARCH_IQ31244 is not set CONFIG_ARCH_IQ80331=y -CONFIG_MACH_IQ80332=y -CONFIG_PLAT_IOP=y +# CONFIG_MACH_IQ80332 is not set +# CONFIG_ARCH_EP80219 is not set +CONFIG_ARCH_IOP331=y + +# +# IOP3xx Chipset Features +# +CONFIG_IOP331_STEPD=y # # Processor Type @@ -139,6 +109,7 @@ CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV5T=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y # # Processor Features @@ -150,7 +121,8 @@ CONFIG_XSCALE_PMU=y # Bus support # CONFIG_PCI=y -# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_NAMES=y # # PCCARD (PCMCIA/CardBus) support @@ -161,19 +133,6 @@ CONFIG_PCI=y # Kernel Features # # CONFIG_PREEMPT is not set -# CONFIG_NO_IDLE_HZ is not set -CONFIG_HZ=100 -# CONFIG_AEABI is not set -# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4096 -# CONFIG_RESOURCES_64BIT is not set CONFIG_ALIGNMENT_TRAP=y # @@ -181,7 +140,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp" +CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" # CONFIG_XIP_KERNEL is not set # @@ -207,93 +166,6 @@ CONFIG_BINFMT_AOUT=y # Power management options # # CONFIG_PM is not set -# CONFIG_APM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set # # Device Drivers @@ -305,13 +177,6 @@ CONFIG_TCP_CONG_BIC=y CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_SYS_HYPERVISOR is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set # # Memory Technology Devices (MTD) @@ -335,7 +200,6 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set # # RAM/ROM/Flash chip drivers @@ -358,7 +222,6 @@ CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_I4 is not set # CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_OTP is not set CONFIG_MTD_CFI_INTELEXT=y # CONFIG_MTD_CFI_AMDSTD is not set # CONFIG_MTD_CFI_STAA is not set @@ -366,18 +229,18 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_XIP is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x0 -CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_START=0xc0000000 +CONFIG_MTD_PHYSMAP_LEN=0x00800000 CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_EDB7312 is not set # # Self-contained MTD device drivers @@ -386,6 +249,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set # CONFIG_MTD_BLOCK2MTD is not set # @@ -400,11 +264,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # # CONFIG_MTD_NAND is not set -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - # # Parallel port support # @@ -417,6 +276,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # # Block devices # +# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -428,9 +288,17 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y # CONFIG_ATA_OVER_ETH is not set # @@ -441,7 +309,6 @@ CONFIG_BLK_DEV_INITRD=y # # SCSI device support # -# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -453,7 +320,6 @@ CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set CONFIG_CHR_DEV_SG=y -# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -468,12 +334,10 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set # # SCSI low-level drivers # -# CONFIG_ISCSI_TCP is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_ACARD is not set @@ -484,19 +348,25 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_DPT_I2O is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_LPFC is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_NSP32 is not set @@ -511,7 +381,8 @@ CONFIG_MD_LINEAR=y CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y # CONFIG_MD_RAID10 is not set -# CONFIG_MD_RAID456 is not set +CONFIG_MD_RAID5=y +# CONFIG_MD_RAID6 is not set # CONFIG_MD_MULTIPATH is not set # CONFIG_MD_FAULTY is not set CONFIG_BLK_DEV_DM=y @@ -525,9 +396,6 @@ CONFIG_BLK_DEV_DM=y # Fusion MPT device support # # CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set # # IEEE 1394 (FireWire) support @@ -540,8 +408,71 @@ CONFIG_BLK_DEV_DM=y # CONFIG_I2O is not set # -# Network device support +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + # +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set # CONFIG_BONDING is not set @@ -553,10 +484,6 @@ CONFIG_NETDEVICES=y # # CONFIG_ARCNET is not set -# -# PHY device support -# - # # Ethernet (10 or 100Mbit) # @@ -574,20 +501,14 @@ CONFIG_E1000_NAPI=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set # CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) # -# CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -610,8 +531,6 @@ CONFIG_E1000_NAPI=y # CONFIG_NET_FC is not set # CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -649,6 +568,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # # CONFIG_SERIO is not set # CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -656,7 +576,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -664,9 +583,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y CONFIG_SERIAL_8250_NR_UARTS=4 -CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set # @@ -674,7 +591,6 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -688,8 +604,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y # CONFIG_NVRAM is not set +# CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -704,7 +620,6 @@ CONFIG_HW_RANDOM=y # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set # # I2C support @@ -729,13 +644,14 @@ CONFIG_I2C_CHARDEV=y # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_ISA is not set # CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set @@ -746,45 +662,15 @@ CONFIG_I2C_IOP3XX=y # CONFIG_I2C_PCA_ISA is not set # -# Miscellaneous I2C Chip support +# Hardware Sensors Chip support # -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ABITUGURU is not set +# CONFIG_I2C_SENSOR is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_FSCHER is not set # CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set @@ -799,45 +685,36 @@ CONFIG_HWMON=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set # -# LED drivers +# Other I2C Chip support # +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set # -# LED Triggers +# Misc devices # # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -847,7 +724,6 @@ CONFIG_VIDEO_V4L2=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # @@ -855,7 +731,6 @@ CONFIG_FIRMWARE_EDID=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -867,13 +742,8 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y # CONFIG_USB is not set -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - # # USB Gadget Support # @@ -884,18 +754,11 @@ CONFIG_USB_ARCH_HAS_EHCI=y # # CONFIG_MMC is not set -# -# Real Time Clock -# -CONFIG_RTC_LIB=y -# CONFIG_RTC_CLASS is not set - # # File systems # CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set @@ -905,22 +768,22 @@ CONFIG_JBD=y CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set + +# +# XFS support +# CONFIG_XFS_FS=y +CONFIG_XFS_EXPORT=y +# CONFIG_XFS_RT is not set # CONFIG_XFS_QUOTA is not set CONFIG_XFS_SECURITY=y CONFIG_XFS_POSIX_ACL=y -# CONFIG_XFS_RT is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -940,10 +803,12 @@ CONFIG_DNOTIFY=y # CONFIG_PROC_FS=y CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -969,19 +834,16 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set # CONFIG_NFSD_TCP is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set @@ -990,7 +852,6 @@ CONFIG_SUNRPC=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types @@ -1010,7 +871,6 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # @@ -1027,34 +887,11 @@ CONFIG_MSDOS_PARTITION=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_RWSEMS is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y -# CONFIG_UNWIND_INFO is not set -# CONFIG_FORCED_INLINING is not set -# CONFIG_RCU_TORTURE_TEST is not set CONFIG_DEBUG_USER=y -# CONFIG_DEBUG_WAITQ is not set -# CONFIG_DEBUG_ERRORS is not set -CONFIG_DEBUG_LL=y -# CONFIG_DEBUG_ICEDCC is not set # # Security options @@ -1075,7 +912,5 @@ CONFIG_DEBUG_LL=y # Library routines # # CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set # CONFIG_CRC32 is not set # CONFIG_LIBCRC32C is not set -CONFIG_PLIST=y diff --git a/trunk/arch/arm/configs/iq80332_defconfig b/trunk/arch/arm/configs/iq80332_defconfig new file mode 100644 index 000000000000..11959b705d82 --- /dev/null +++ b/trunk/arch/arm/configs/iq80332_defconfig @@ -0,0 +1,916 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc1-bk2 +# Sun Mar 27 17:33:39 2005 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +CONFIG_ARCH_IOP3XX=y +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set + +# +# IOP3xx Implementation Options +# + +# +# IOP3xx Platform Types +# +# CONFIG_ARCH_IQ80321 is not set +# CONFIG_ARCH_IQ31244 is not set +# CONFIG_ARCH_IQ80331 is not set +CONFIG_MACH_IQ80332=y +# CONFIG_ARCH_EP80219 is not set +CONFIG_ARCH_IOP331=y + +# +# IOP3xx Chipset Features +# +# CONFIG_IOP331_STEPD is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_MINICACHE=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_XSCALE_PMU=y + +# +# Bus support +# +CONFIG_PCI=y +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_PCI_NAMES=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_AOUT=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_XIP is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_START=0xc0000000 +CONFIG_MTD_PHYSMAP_LEN=0x00800000 +CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_EDB7312 is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +# CONFIG_MD_RAID10 is not set +CONFIG_MD_RAID5=y +# CONFIG_MD_RAID6 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_MD_FAULTY is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +CONFIG_E1000=y +CONFIG_E1000_NAPI=y +# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_ISA is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set + +# +# Other I2C Chip support +# +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +CONFIG_XFS_FS=y +CONFIG_XFS_EXPORT=y +# CONFIG_XFS_RT is not set +# CONFIG_XFS_QUOTA is not set +CONFIG_XFS_SECURITY=y +CONFIG_XFS_POSIX_ACL=y +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_XATTR is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V4 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_FRAME_POINTER=y +CONFIG_DEBUG_USER=y + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set diff --git a/trunk/arch/arm/configs/s3c2410_defconfig b/trunk/arch/arm/configs/s3c2410_defconfig index a83222641045..f20814e6f497 100644 --- a/trunk/arch/arm/configs/s3c2410_defconfig +++ b/trunk/arch/arm/configs/s3c2410_defconfig @@ -1,19 +1,14 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18 -# Wed Sep 20 20:27:31 2006 +# Linux kernel version: 2.6.17-git9 +# Sun Jun 25 23:56:32 2006 # CONFIG_ARM=y CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -CONFIG_HARDIRQS_SW_RESEND=y -CONFIG_GENERIC_IRQ_PROBE=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_VECTORS_BASE=0xffff0000 -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -31,15 +26,14 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set -CONFIG_UID16=y -CONFIG_SYSCTL=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -52,8 +46,6 @@ CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -92,7 +84,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_INTEGRATOR is not set # CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_AT91RM9200 is not set # CONFIG_ARCH_CLPS7500 is not set # CONFIG_ARCH_CLPS711X is not set # CONFIG_ARCH_CO285 is not set @@ -102,8 +94,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_IOP32X is not set -# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IOP3XX is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_IXP23XX is not set @@ -131,18 +122,13 @@ CONFIG_ARCH_SMDK2410=y CONFIG_ARCH_S3C2440=y CONFIG_SMDK2440_CPU2440=y CONFIG_SMDK2440_CPU2442=y -CONFIG_MACH_S3C2413=y CONFIG_MACH_SMDK2413=y CONFIG_MACH_VR1000=y CONFIG_MACH_RX3715=y CONFIG_MACH_OTOM=y CONFIG_MACH_NEXCODER_2440=y -CONFIG_MACH_VSTMS=y CONFIG_S3C2410_CLOCK=y -CONFIG_S3C2410_PM=y -CONFIG_CPU_S3C2410_DMA=y CONFIG_CPU_S3C2410=y -CONFIG_S3C2412_PM=y CONFIG_CPU_S3C2412=y CONFIG_CPU_S3C244X=y CONFIG_CPU_S3C2440=y @@ -170,7 +156,7 @@ CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_ARM926T=y -CONFIG_CPU_32v4T=y +CONFIG_CPU_32v4=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV4T=y CONFIG_CPU_ABRT_EV5TJ=y @@ -214,7 +200,6 @@ CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPLIT_PTLOCK_CPUS=4096 -# CONFIG_RESOURCES_64BIT is not set CONFIG_ALIGNMENT_TRAP=y # @@ -319,6 +304,7 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -474,7 +460,6 @@ CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set CONFIG_ATA_OVER_ETH=m @@ -655,7 +640,6 @@ CONFIG_SERIO_LIBPS2=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set CONFIG_SERIAL_NONSTANDARD=y # CONFIG_COMPUTONE is not set # CONFIG_ROCKETPORT is not set @@ -732,7 +716,6 @@ CONFIG_S3C2410_WATCHDOG=y # USB-based Watchdog Cards # # CONFIG_USBPCWATCHDOG is not set -CONFIG_HW_RANDOM=y # CONFIG_NVRAM is not set CONFIG_S3C2410_RTC=y # CONFIG_DTLK is not set @@ -874,12 +857,12 @@ CONFIG_VIDEO_V4L2=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_MACMODES is not set +CONFIG_FB_FIRMWARE_EDID=y # CONFIG_FB_BACKLIGHT is not set CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set @@ -1012,7 +995,7 @@ CONFIG_USB_MON=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set @@ -1112,7 +1095,6 @@ CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y # CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_FS_XATTR is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y @@ -1220,19 +1202,14 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_RWSEMS is not set +# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_INFO=y @@ -1274,4 +1251,3 @@ CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y -CONFIG_PLIST=y diff --git a/trunk/arch/arm/kernel/apm.c b/trunk/arch/arm/kernel/apm.c index ecf4f9472d94..33c55689f999 100644 --- a/trunk/arch/arm/kernel/apm.c +++ b/trunk/arch/arm/kernel/apm.c @@ -25,7 +25,6 @@ #include #include #include -#include #include /* apm_power_info */ #include @@ -81,7 +80,7 @@ struct apm_user { */ static int suspends_pending; static int apm_disabled; -static struct task_struct *kapmd_tsk; +static int arm_apm_active; static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); @@ -98,6 +97,7 @@ static LIST_HEAD(apm_user_list); * to be suspending the system. */ static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait); +static DECLARE_COMPLETION(kapmd_exit); static DEFINE_SPINLOCK(kapmd_queue_lock); static struct apm_queue kapmd_queue; @@ -468,13 +468,16 @@ static int apm_get_info(char *buf, char **start, off_t fpos, int length) static int kapmd(void *arg) { + daemonize("kapmd"); + current->flags |= PF_NOFREEZE; + do { apm_event_t event; wait_event_interruptible(kapmd_wait, - !queue_empty(&kapmd_queue) || kthread_should_stop()); + !queue_empty(&kapmd_queue) || !arm_apm_active); - if (kthread_should_stop()) + if (!arm_apm_active) break; spin_lock_irq(&kapmd_queue_lock); @@ -505,7 +508,7 @@ static int kapmd(void *arg) } } while (1); - return 0; + complete_and_exit(&kapmd_exit, 0); } static int __init apm_init(void) @@ -517,14 +520,13 @@ static int __init apm_init(void) return -ENODEV; } - kapmd_tsk = kthread_create(kapmd, NULL, "kapmd"); - if (IS_ERR(kapmd_tsk)) { - ret = PTR_ERR(kapmd_tsk); - kapmd_tsk = NULL; + arm_apm_active = 1; + + ret = kernel_thread(kapmd, NULL, CLONE_KERNEL); + if (ret < 0) { + arm_apm_active = 0; return ret; } - kapmd_tsk->flags |= PF_NOFREEZE; - wake_up_process(kapmd_tsk); #ifdef CONFIG_PROC_FS create_proc_info_entry("apm", 0, NULL, apm_get_info); @@ -533,7 +535,10 @@ static int __init apm_init(void) ret = misc_register(&apm_device); if (ret != 0) { remove_proc_entry("apm", NULL); - kthread_stop(kapmd_tsk); + + arm_apm_active = 0; + wake_up(&kapmd_wait); + wait_for_completion(&kapmd_exit); } return ret; @@ -544,7 +549,9 @@ static void __exit apm_exit(void) misc_deregister(&apm_device); remove_proc_entry("apm", NULL); - kthread_stop(kapmd_tsk); + arm_apm_active = 0; + wake_up(&kapmd_wait); + wait_for_completion(&kapmd_exit); } module_init(apm_init); diff --git a/trunk/arch/arm/kernel/debug.S b/trunk/arch/arm/kernel/debug.S index 5617566477b4..a5747e58a9dc 100644 --- a/trunk/arch/arm/kernel/debug.S +++ b/trunk/arch/arm/kernel/debug.S @@ -21,36 +21,6 @@ #if defined(CONFIG_DEBUG_ICEDCC) @@ debug using ARM EmbeddedICE DCC channel - -#if defined(CONFIG_CPU_V6) - - .macro addruart, rx - .endm - - .macro senduart, rd, rx - mcr p14, 0, \rd, c0, c5, 0 - .endm - - .macro busyuart, rd, rx -1001: - mrc p14, 0, \rx, c0, c1, 0 - tst \rx, #0x20000000 - beq 1001b - .endm - - .macro waituart, rd, rx - mov \rd, #0x2000000 -1001: - subs \rd, \rd, #1 - bmi 1002f - mrc p14, 0, \rx, c0, c1, 0 - tst \rx, #0x20000000 - bne 1001b -1002: - .endm - -#else - .macro addruart, rx .endm @@ -76,12 +46,9 @@ bne 1001b 1002: .endm - -#endif /* CONFIG_CPU_V6 */ - #else #include -#endif /* CONFIG_DEBUG_ICEDCC */ +#endif /* * Useful debugging routines diff --git a/trunk/arch/arm/kernel/ecard.c b/trunk/arch/arm/kernel/ecard.c index 3e14b1348c0b..eca248d9eba4 100644 --- a/trunk/arch/arm/kernel/ecard.c +++ b/trunk/arch/arm/kernel/ecard.c @@ -295,7 +295,7 @@ ecard_task(void * unused) */ static void ecard_call(struct ecard_request *req) { - DECLARE_COMPLETION_ONSTACK(completion); + DECLARE_COMPLETION(completion); req->complete = &completion; diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index bd623b73445f..de4e33137901 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -191,9 +191,6 @@ __dabt_svc: __irq_svc: svc_entry -#ifdef CONFIG_TRACE_IRQFLAGS - bl trace_hardirqs_off -#endif #ifdef CONFIG_PREEMPT get_thread_info tsk ldr r8, [tsk, #TI_PREEMPT] @ get preempt count @@ -214,10 +211,6 @@ preempt_return: #endif ldr r0, [sp, #S_PSR] @ irqs are already disabled msr spsr_cxsf, r0 -#ifdef CONFIG_TRACE_IRQFLAGS - tst r0, #PSR_I_BIT - bleq trace_hardirqs_on -#endif ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr .ltorg @@ -405,9 +398,6 @@ __dabt_usr: __irq_usr: usr_entry -#ifdef CONFIG_TRACE_IRQFLAGS - bl trace_hardirqs_off -#endif get_thread_info tsk #ifdef CONFIG_PREEMPT ldr r8, [tsk, #TI_PREEMPT] @ get preempt count @@ -422,9 +412,6 @@ __irq_usr: teq r0, r7 strne r0, [r0, -r0] #endif -#ifdef CONFIG_TRACE_IRQFLAGS - bl trace_hardirqs_on -#endif mov why, #0 b ret_to_user diff --git a/trunk/arch/arm/kernel/head-nommu.S b/trunk/arch/arm/kernel/head-nommu.S index f359a189dcf2..ac9eb3d30518 100644 --- a/trunk/arch/arm/kernel/head-nommu.S +++ b/trunk/arch/arm/kernel/head-nommu.S @@ -9,6 +9,7 @@ * published by the Free Software Foundation. * * Common kernel startup code (non-paged MM) + * for 32-bit CPUs which has a process ID register(CP15). * */ #include @@ -39,11 +40,7 @@ ENTRY(stext) msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | SVC_MODE @ ensure svc mode @ and irqs disabled -#ifndef CONFIG_CPU_CP15 - ldr r9, =CONFIG_PROCESSOR_ID -#else mrc p15, 0, r9, c0, c0 @ get processor id -#endif bl __lookup_processor_type @ r5=procinfo r9=cpuid movs r10, r5 @ invalid processor (r5=0)? beq __error_p @ yes, error 'p' @@ -61,7 +58,6 @@ ENTRY(stext) */ .type __after_proc_init, %function __after_proc_init: -#ifdef CONFIG_CPU_CP15 mrc p15, 0, r0, c1, c0, 0 @ read control reg #ifdef CONFIG_ALIGNMENT_TRAP orr r0, r0, #CR_A @@ -76,14 +72,8 @@ __after_proc_init: #endif #ifdef CONFIG_CPU_ICACHE_DISABLE bic r0, r0, #CR_I -#endif -#ifdef CONFIG_CPU_HIGH_VECTOR - orr r0, r0, #CR_V -#else - bic r0, r0, #CR_V #endif mcr p15, 0, r0, c1, c0, 0 @ write control reg -#endif /* CONFIG_CPU_CP15 */ mov pc, r13 @ clear the BSS and jump @ to start_kernel diff --git a/trunk/arch/arm/kernel/module.c b/trunk/arch/arm/kernel/module.c index 1b061583408e..298363d97047 100644 --- a/trunk/arch/arm/kernel/module.c +++ b/trunk/arch/arm/kernel/module.c @@ -2,7 +2,6 @@ * linux/arch/arm/kernel/module.c * * Copyright (C) 2002 Russell King. - * Modified for nommu by Hyok S. Choi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -33,7 +32,6 @@ extern void _etext; #define MODULE_START (((unsigned long)&_etext + ~PGDIR_MASK) & PGDIR_MASK) #endif -#ifdef CONFIG_MMU void *module_alloc(unsigned long size) { struct vm_struct *area; @@ -48,12 +46,6 @@ void *module_alloc(unsigned long size) return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL); } -#else /* CONFIG_MMU */ -void *module_alloc(unsigned long size) -{ - return size == 0 ? NULL : vmalloc(size); -} -#endif /* !CONFIG_MMU */ void module_free(struct module *module, void *region) { diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index bf35c178a877..3079535afccd 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -221,26 +221,16 @@ void __show_regs(struct pt_regs *regs) processor_modes[processor_mode(regs)], thumb_mode(regs) ? " (T)" : "", get_fs() == get_ds() ? "kernel" : "user"); -#if CONFIG_CPU_CP15 { - unsigned int ctrl; + unsigned int ctrl, transbase, dac; __asm__ ( " mrc p15, 0, %0, c1, c0\n" - : "=r" (ctrl)); - printk("Control: %04X\n", ctrl); + " mrc p15, 0, %1, c2, c0\n" + " mrc p15, 0, %2, c3, c0\n" + : "=r" (ctrl), "=r" (transbase), "=r" (dac)); + printk("Control: %04X Table: %08X DAC: %08X\n", + ctrl, transbase, dac); } -#ifdef CONFIG_CPU_CP15_MMU - { - unsigned int transbase, dac; - __asm__ ( - " mrc p15, 0, %0, c2, c0\n" - " mrc p15, 0, %1, c3, c0\n" - : "=r" (transbase), "=r" (dac)); - printk("Table: %08X DAC: %08X\n", - transbase, dac); - } -#endif -#endif } void show_regs(struct pt_regs * regs) diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index 6bbd93dd186a..0a722e77c143 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -348,7 +348,7 @@ static void __init setup_processor(void) cpu_name, processor_id, (int)processor_id & 15, proc_arch[cpu_architecture()], cr_alignment); - sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS); + sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS); sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); elf_hwcap = list->elf_hwcap; #ifndef CONFIG_ARM_THUMB diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index 421329f5e18e..68e9634d260a 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -36,9 +36,7 @@ * The online bitmask indicates that the CPU is up and running. */ cpumask_t cpu_possible_map; -EXPORT_SYMBOL(cpu_possible_map); cpumask_t cpu_online_map; -EXPORT_SYMBOL(cpu_online_map); /* * as from 2.5, kernels no longer have an init_tasks structure diff --git a/trunk/arch/arm/kernel/sys_arm.c b/trunk/arch/arm/kernel/sys_arm.c index 00c18d35913c..8170af471439 100644 --- a/trunk/arch/arm/kernel/sys_arm.c +++ b/trunk/arch/arm/kernel/sys_arm.c @@ -279,7 +279,7 @@ asmlinkage int sys_execve(char __user *filenamei, char __user * __user *argv, return error; } -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +long execve(const char *filename, char **argv, char **envp) { struct pt_regs regs; int ret; @@ -317,7 +317,7 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]) out: return ret; } -EXPORT_SYMBOL(kernel_execve); +EXPORT_SYMBOL(execve); /* * Since loff_t is a 64 bit type we avoid a lot of ABI hastle diff --git a/trunk/arch/arm/kernel/time.c b/trunk/arch/arm/kernel/time.c index b030320b17c7..09a67d771857 100644 --- a/trunk/arch/arm/kernel/time.c +++ b/trunk/arch/arm/kernel/time.c @@ -37,6 +37,8 @@ */ struct sys_timer *system_timer; +extern unsigned long wall_jiffies; + /* this needs a better home */ DEFINE_SPINLOCK(rtc_lock); @@ -67,12 +69,10 @@ EXPORT_SYMBOL(profile_pc); */ int (*set_rtc)(void); -#ifndef CONFIG_GENERIC_TIME static unsigned long dummy_gettimeoffset(void) { return 0; } -#endif /* * Scheduler clock - returns current time in nanosec units. @@ -230,16 +230,20 @@ static inline void do_leds(void) #define do_leds() #endif -#ifndef CONFIG_GENERIC_TIME void do_gettimeofday(struct timeval *tv) { unsigned long flags; unsigned long seq; - unsigned long usec, sec; + unsigned long usec, sec, lost; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = system_timer->offset(); + + lost = jiffies - wall_jiffies; + if (lost) + usec += lost * USECS_PER_JIFFY; + sec = xtime.tv_sec; usec += xtime.tv_nsec / 1000; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); @@ -272,6 +276,7 @@ int do_settimeofday(struct timespec *tv) * done, and then undo it! */ nsec -= system_timer->offset() * NSEC_PER_USEC; + nsec -= (jiffies - wall_jiffies) * TICK_NSEC; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -286,7 +291,6 @@ int do_settimeofday(struct timespec *tv) } EXPORT_SYMBOL(do_settimeofday); -#endif /* !CONFIG_GENERIC_TIME */ /** * save_time_delta - Save the offset between system time and RTC time @@ -329,7 +333,7 @@ void timer_tick(struct pt_regs *regs) profile_tick(CPU_PROFILING, regs); do_leds(); do_set_rtc(); - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -496,10 +500,8 @@ device_initcall(timer_init_sysfs); void __init time_init(void) { -#ifndef CONFIG_GENERIC_TIME if (system_timer->offset == NULL) system_timer->offset = dummy_gettimeoffset; -#endif system_timer->init(); #ifdef CONFIG_NO_IDLE_HZ diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c index bede380c07a9..aeeed806f991 100644 --- a/trunk/arch/arm/kernel/traps.c +++ b/trunk/arch/arm/kernel/traps.c @@ -191,7 +191,7 @@ void show_stack(struct task_struct *tsk, unsigned long *sp) if (tsk != current) fp = thread_saved_fp(tsk); else - asm("mov %0, fp" : "=r" (fp) : : "cc"); + asm("mov%? %0, fp" : "=r" (fp)); c_backtrace(fp, 0x10); barrier(); diff --git a/trunk/arch/arm/mach-at91rm9200/at91rm9200.c b/trunk/arch/arm/mach-at91rm9200/at91rm9200.c index dcf6136fedf9..0985b1c42c7c 100644 --- a/trunk/arch/arm/mach-at91rm9200/at91rm9200.c +++ b/trunk/arch/arm/mach-at91rm9200/at91rm9200.c @@ -17,7 +17,6 @@ #include #include "generic.h" -#include "clock.h" static struct map_desc at91rm9200_io_desc[] __initdata = { { @@ -27,224 +26,87 @@ static struct map_desc at91rm9200_io_desc[] __initdata = { .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_SPI, - .pfn = __phys_to_pfn(AT91RM9200_BASE_SPI), + .pfn = __phys_to_pfn(AT91_BASE_SPI), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_VA_BASE_SSC2, + .pfn = __phys_to_pfn(AT91_BASE_SSC2), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_VA_BASE_SSC1, + .pfn = __phys_to_pfn(AT91_BASE_SSC1), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_VA_BASE_SSC0, + .pfn = __phys_to_pfn(AT91_BASE_SSC0), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_VA_BASE_US3, + .pfn = __phys_to_pfn(AT91_BASE_US3), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_VA_BASE_US2, + .pfn = __phys_to_pfn(AT91_BASE_US2), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_VA_BASE_US1, + .pfn = __phys_to_pfn(AT91_BASE_US1), + .length = SZ_16K, + .type = MT_DEVICE, + }, { + .virtual = AT91_VA_BASE_US0, + .pfn = __phys_to_pfn(AT91_BASE_US0), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_EMAC, - .pfn = __phys_to_pfn(AT91RM9200_BASE_EMAC), + .pfn = __phys_to_pfn(AT91_BASE_EMAC), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_TWI, - .pfn = __phys_to_pfn(AT91RM9200_BASE_TWI), + .pfn = __phys_to_pfn(AT91_BASE_TWI), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_MCI, - .pfn = __phys_to_pfn(AT91RM9200_BASE_MCI), + .pfn = __phys_to_pfn(AT91_BASE_MCI), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_UDP, - .pfn = __phys_to_pfn(AT91RM9200_BASE_UDP), + .pfn = __phys_to_pfn(AT91_BASE_UDP), .length = SZ_16K, .type = MT_DEVICE, }, { - .virtual = AT91_SRAM_VIRT_BASE, - .pfn = __phys_to_pfn(AT91RM9200_SRAM_BASE), - .length = AT91RM9200_SRAM_SIZE, + .virtual = AT91_VA_BASE_TCB1, + .pfn = __phys_to_pfn(AT91_BASE_TCB1), + .length = SZ_16K, .type = MT_DEVICE, - }, -}; - -/* -------------------------------------------------------------------- - * Clocks - * -------------------------------------------------------------------- */ - -/* - * The peripheral clocks. - */ -static struct clk udc_clk = { - .name = "udc_clk", - .pmc_mask = 1 << AT91RM9200_ID_UDP, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ohci_clk = { - .name = "ohci_clk", - .pmc_mask = 1 << AT91RM9200_ID_UHP, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ether_clk = { - .name = "ether_clk", - .pmc_mask = 1 << AT91RM9200_ID_EMAC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc_clk = { - .name = "mci_clk", - .pmc_mask = 1 << AT91RM9200_ID_MCI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi_clk = { - .name = "twi_clk", - .pmc_mask = 1 << AT91RM9200_ID_TWI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .pmc_mask = 1 << AT91RM9200_ID_US0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .pmc_mask = 1 << AT91RM9200_ID_US1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .pmc_mask = 1 << AT91RM9200_ID_US2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart3_clk = { - .name = "usart3_clk", - .pmc_mask = 1 << AT91RM9200_ID_US3, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi_clk = { - .name = "spi_clk", - .pmc_mask = 1 << AT91RM9200_ID_SPI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioA_clk = { - .name = "pioA_clk", - .pmc_mask = 1 << AT91RM9200_ID_PIOA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioB_clk = { - .name = "pioB_clk", - .pmc_mask = 1 << AT91RM9200_ID_PIOB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioC_clk = { - .name = "pioC_clk", - .pmc_mask = 1 << AT91RM9200_ID_PIOC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pioD_clk = { - .name = "pioD_clk", - .pmc_mask = 1 << AT91RM9200_ID_PIOD, - .type = CLK_TYPE_PERIPHERAL, -}; - -static struct clk *periph_clocks[] __initdata = { - &pioA_clk, - &pioB_clk, - &pioC_clk, - &pioD_clk, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &usart3_clk, - &mmc_clk, - &udc_clk, - &twi_clk, - &spi_clk, - // ssc 0 .. ssc2 - // tc0 .. tc5 - &ohci_clk, - ðer_clk, - // irq0 .. irq6 -}; - -/* - * The four programmable clocks. - * You must configure pin multiplexing to bring these signals out. - */ -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 0, -}; -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 1, -}; -static struct clk pck2 = { - .name = "pck2", - .pmc_mask = AT91_PMC_PCK2, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 2, -}; -static struct clk pck3 = { - .name = "pck3", - .pmc_mask = AT91_PMC_PCK3, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 3, -}; - -static void __init at91rm9200_register_clocks(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) - clk_register(periph_clocks[i]); - - clk_register(&pck0); - clk_register(&pck1); - clk_register(&pck2); - clk_register(&pck3); -} - -/* -------------------------------------------------------------------- - * GPIO - * -------------------------------------------------------------------- */ - -static struct at91_gpio_bank at91rm9200_gpio[] = { - { - .id = AT91RM9200_ID_PIOA, - .offset = AT91_PIOA, - .clock = &pioA_clk, - }, { - .id = AT91RM9200_ID_PIOB, - .offset = AT91_PIOB, - .clock = &pioB_clk, }, { - .id = AT91RM9200_ID_PIOC, - .offset = AT91_PIOC, - .clock = &pioC_clk, + .virtual = AT91_VA_BASE_TCB0, + .pfn = __phys_to_pfn(AT91_BASE_TCB0), + .length = SZ_16K, + .type = MT_DEVICE, }, { - .id = AT91RM9200_ID_PIOD, - .offset = AT91_PIOD, - .clock = &pioD_clk, - } + .virtual = AT91_SRAM_VIRT_BASE, + .pfn = __phys_to_pfn(AT91_SRAM_BASE), + .length = AT91_SRAM_SIZE, + .type = MT_DEVICE, + }, }; -/* -------------------------------------------------------------------- - * AT91RM9200 processor initialization - * -------------------------------------------------------------------- */ -void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks) +void __init at91rm9200_map_io(void) { - /* Map peripherals */ iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc)); - - /* Init clock subsystem */ - at91_clock_init(main_clock); - - /* Register the processor-specific clocks */ - at91rm9200_register_clocks(); - - /* Initialize GPIO subsystem */ - at91_gpio_init(at91rm9200_gpio, banks); } - -/* -------------------------------------------------------------------- - * Interrupt initialization - * -------------------------------------------------------------------- */ - /* * The default interrupt priority levels (0 = lowest, 7 = highest). */ @@ -283,14 +145,10 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { 0 /* Advanced Interrupt Controller (IRQ6) */ }; -void __init at91rm9200_init_interrupts(unsigned int priority[NR_AIC_IRQS]) +void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS]) { if (!priority) priority = at91rm9200_default_irq_priority; - /* Initialize the AIC interrupt controller */ at91_aic_init(priority); - - /* Enable GPIO interrupts */ - at91_gpio_irq_setup(); } diff --git a/trunk/arch/arm/mach-at91rm9200/board-1arm.c b/trunk/arch/arm/mach-at91rm9200/board-1arm.c index 36eecd7161f5..dc79e0992af7 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-1arm.c +++ b/trunk/arch/arm/mach-at91rm9200/board-1arm.c @@ -34,11 +34,20 @@ #include #include +#include #include #include #include "generic.h" +static void __init onearm_init_irq(void) +{ + /* Initialize AIC controller */ + at91rm9200_init_irq(NULL); + + /* Set up the GPIO interrupts */ + at91_gpio_irq_setup(PQFP_GPIO_BANKS); +} /* * Serial port configuration. @@ -53,18 +62,15 @@ static struct at91_uart_config __initdata onearm_uart_config = { static void __init onearm_map_io(void) { - /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000, AT91RM9200_PQFP); + at91rm9200_map_io(); + + /* Initialize clocks: 18.432 MHz crystal */ + at91_clock_init(18432000); /* Setup the serial ports and console */ at91_init_serial(&onearm_uart_config); } -static void __init onearm_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata onearm_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, diff --git a/trunk/arch/arm/mach-at91rm9200/board-carmeva.c b/trunk/arch/arm/mach-at91rm9200/board-carmeva.c index 50e513681ae6..2c138b542ebe 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-carmeva.c +++ b/trunk/arch/arm/mach-at91rm9200/board-carmeva.c @@ -35,11 +35,20 @@ #include #include +#include #include #include #include "generic.h" +static void __init carmeva_init_irq(void) +{ + /* Initialize AIC controller */ + at91rm9200_init_irq(NULL); + + /* Set up the GPIO interrupts */ + at91_gpio_irq_setup(BGA_GPIO_BANKS); +} /* * Serial port configuration. @@ -54,19 +63,15 @@ static struct at91_uart_config __initdata carmeva_uart_config = { static void __init carmeva_map_io(void) { - /* Initialize processor: 20.000 MHz crystal */ - at91rm9200_initialize(20000000, AT91RM9200_BGA); + at91rm9200_map_io(); + + /* Initialize clocks: 20.000 MHz crystal */ + at91_clock_init(20000000); /* Setup the serial ports and console */ at91_init_serial(&carmeva_uart_config); } -static void __init carmeva_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - - static struct at91_eth_data __initdata carmeva_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, diff --git a/trunk/arch/arm/mach-at91rm9200/board-csb337.c b/trunk/arch/arm/mach-at91rm9200/board-csb337.c index 8eeae491ce71..794d3fbb449b 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-csb337.c +++ b/trunk/arch/arm/mach-at91rm9200/board-csb337.c @@ -34,11 +34,20 @@ #include #include +#include #include #include #include "generic.h" +static void __init csb337_init_irq(void) +{ + /* Initialize AIC controller */ + at91rm9200_init_irq(NULL); + + /* Set up the GPIO interrupts */ + at91_gpio_irq_setup(BGA_GPIO_BANKS); +} /* * Serial port configuration. @@ -53,8 +62,10 @@ static struct at91_uart_config __initdata csb337_uart_config = { static void __init csb337_map_io(void) { - /* Initialize processor: 3.6864 MHz crystal */ - at91rm9200_initialize(3686400, AT91RM9200_BGA); + at91rm9200_map_io(); + + /* Initialize clocks: 3.6864 MHz crystal */ + at91_clock_init(3686400); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); @@ -63,11 +74,6 @@ static void __init csb337_map_io(void) at91_init_serial(&csb337_uart_config); } -static void __init csb337_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata csb337_eth_data = { .phy_irq_pin = AT91_PIN_PC2, .is_rmii = 0, diff --git a/trunk/arch/arm/mach-at91rm9200/board-csb637.c b/trunk/arch/arm/mach-at91rm9200/board-csb637.c index a29fa0e822ce..c8b6f334246a 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-csb637.c +++ b/trunk/arch/arm/mach-at91rm9200/board-csb637.c @@ -33,11 +33,20 @@ #include #include +#include #include #include #include "generic.h" +static void __init csb637_init_irq(void) +{ + /* Initialize AIC controller */ + at91rm9200_init_irq(NULL); + + /* Set up the GPIO interrupts */ + at91_gpio_irq_setup(BGA_GPIO_BANKS); +} /* * Serial port configuration. @@ -52,8 +61,10 @@ static struct at91_uart_config __initdata csb637_uart_config = { static void __init csb637_map_io(void) { - /* Initialize processor: 3.6864 MHz crystal */ - at91rm9200_initialize(3686400, AT91RM9200_BGA); + at91rm9200_map_io(); + + /* Initialize clocks: 3.6864 MHz crystal */ + at91_clock_init(3686400); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); @@ -62,11 +73,6 @@ static void __init csb637_map_io(void) at91_init_serial(&csb637_uart_config); } -static void __init csb637_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata csb637_eth_data = { .phy_irq_pin = AT91_PIN_PC0, .is_rmii = 0, diff --git a/trunk/arch/arm/mach-at91rm9200/board-dk.c b/trunk/arch/arm/mach-at91rm9200/board-dk.c index c699f3984d4b..65873037e02a 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-dk.c +++ b/trunk/arch/arm/mach-at91rm9200/board-dk.c @@ -37,11 +37,20 @@ #include #include +#include #include #include #include "generic.h" +static void __init dk_init_irq(void) +{ + /* Initialize AIC controller */ + at91rm9200_init_irq(NULL); + + /* Set up the GPIO interrupts */ + at91_gpio_irq_setup(BGA_GPIO_BANKS); +} /* * Serial port configuration. @@ -56,8 +65,10 @@ static struct at91_uart_config __initdata dk_uart_config = { static void __init dk_map_io(void) { - /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000, AT91RM9200_BGA); + at91rm9200_map_io(); + + /* Initialize clocks: 18.432 MHz crystal */ + at91_clock_init(18432000); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); @@ -66,11 +77,6 @@ static void __init dk_map_io(void) at91_init_serial(&dk_uart_config); } -static void __init dk_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata dk_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, @@ -122,29 +128,6 @@ static struct spi_board_info dk_spi_devices[] = { #endif }; -static struct mtd_partition __initdata dk_nand_partition[] = { - { - .name = "NAND Partition 1", - .offset = 0, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct mtd_partition *nand_partitions(int size, int *num_partitions) -{ - *num_partitions = ARRAY_SIZE(dk_nand_partition); - return dk_nand_partition; -} - -static struct at91_nand_data __initdata dk_nand_data = { - .ale = 22, - .cle = 21, - .det_pin = AT91_PIN_PB1, - .rdy_pin = AT91_PIN_PC2, - // .enable_pin = ... not there - .partition_info = nand_partitions, -}; - static void __init dk_board_init(void) { /* Serial */ @@ -170,8 +153,6 @@ static void __init dk_board_init(void) at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ at91_add_device_mmc(&dk_mmc_data); #endif - /* NAND */ - at91_add_device_nand(&dk_nand_data); /* VGA */ // dk_add_device_video(); } diff --git a/trunk/arch/arm/mach-at91rm9200/board-eb9200.c b/trunk/arch/arm/mach-at91rm9200/board-eb9200.c index c6e0d51fbea0..a3e2df968a66 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-eb9200.c +++ b/trunk/arch/arm/mach-at91rm9200/board-eb9200.c @@ -35,11 +35,20 @@ #include #include +#include #include #include #include "generic.h" +static void __init eb9200_init_irq(void) +{ + /* Initialize AIC controller */ + at91rm9200_init_irq(NULL); + + /* Set up the GPIO interrupts */ + at91_gpio_irq_setup(BGA_GPIO_BANKS); +} /* * Serial port configuration. @@ -54,18 +63,15 @@ static struct at91_uart_config __initdata eb9200_uart_config = { static void __init eb9200_map_io(void) { - /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000, AT91RM9200_BGA); + at91rm9200_map_io(); + + /* Initialize clocks: 18.432 MHz crystal */ + at91_clock_init(18432000); /* Setup the serial ports and console */ at91_init_serial(&eb9200_uart_config); } -static void __init eb9200_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata eb9200_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, diff --git a/trunk/arch/arm/mach-at91rm9200/board-ek.c b/trunk/arch/arm/mach-at91rm9200/board-ek.c index 830eb7932178..868192351dda 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-ek.c +++ b/trunk/arch/arm/mach-at91rm9200/board-ek.c @@ -37,11 +37,20 @@ #include #include +#include #include #include #include "generic.h" +static void __init ek_init_irq(void) +{ + /* Initialize AIC controller */ + at91rm9200_init_irq(NULL); + + /* Set up the GPIO interrupts */ + at91_gpio_irq_setup(BGA_GPIO_BANKS); +} /* * Serial port configuration. @@ -56,8 +65,10 @@ static struct at91_uart_config __initdata ek_uart_config = { static void __init ek_map_io(void) { - /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000, AT91RM9200_BGA); + at91rm9200_map_io(); + + /* Initialize clocks: 18.432 MHz crystal */ + at91_clock_init(18432000); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); @@ -66,11 +77,6 @@ static void __init ek_map_io(void) at91_init_serial(&ek_uart_config); } -static void __init ek_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata ek_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 1, diff --git a/trunk/arch/arm/mach-at91rm9200/board-kafa.c b/trunk/arch/arm/mach-at91rm9200/board-kafa.c index 91e301924f2c..bf760c5e0c46 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-kafa.c +++ b/trunk/arch/arm/mach-at91rm9200/board-kafa.c @@ -34,11 +34,20 @@ #include #include +#include #include #include #include "generic.h" +static void __init kafa_init_irq(void) +{ + /* Initialize AIC controller */ + at91rm9200_init_irq(NULL); + + /* Set up the GPIO interrupts */ + at91_gpio_irq_setup(PQFP_GPIO_BANKS); +} /* * Serial port configuration. @@ -53,8 +62,10 @@ static struct at91_uart_config __initdata kafa_uart_config = { static void __init kafa_map_io(void) { - /* Initialize processor: 18.432 MHz crystal */ - at91rm9200_initialize(18432000, AT91RM9200_PQFP); + at91rm9200_map_io(); + + /* Initialize clocks: 18.432 MHz crystal */ + at91_clock_init(18432000); /* Set up the LEDs */ at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); @@ -63,11 +74,6 @@ static void __init kafa_map_io(void) at91_init_serial(&kafa_uart_config); } -static void __init kafa_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata kafa_eth_data = { .phy_irq_pin = AT91_PIN_PC4, .is_rmii = 0, diff --git a/trunk/arch/arm/mach-at91rm9200/board-kb9202.c b/trunk/arch/arm/mach-at91rm9200/board-kb9202.c index 272fe43bceca..f06d2b54cc9a 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-kb9202.c +++ b/trunk/arch/arm/mach-at91rm9200/board-kb9202.c @@ -35,11 +35,20 @@ #include #include +#include #include #include #include "generic.h" +static void __init kb9202_init_irq(void) +{ + /* Initialize AIC controller */ + at91rm9200_init_irq(NULL); + + /* Set up the GPIO interrupts */ + at91_gpio_irq_setup(PQFP_GPIO_BANKS); +} /* * Serial port configuration. @@ -54,8 +63,10 @@ static struct at91_uart_config __initdata kb9202_uart_config = { static void __init kb9202_map_io(void) { - /* Initialize processor: 10 MHz crystal */ - at91rm9200_initialize(10000000, AT91RM9200_PQFP); + at91rm9200_map_io(); + + /* Initialize clocks: 10 MHz crystal */ + at91_clock_init(10000000); /* Set up the LEDs */ at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); @@ -64,11 +75,6 @@ static void __init kb9202_map_io(void) at91_init_serial(&kb9202_uart_config); } -static void __init kb9202_init_irq(void) -{ - at91rm9200_init_interrupts(NULL); -} - static struct at91_eth_data __initdata kb9202_eth_data = { .phy_irq_pin = AT91_PIN_PB29, .is_rmii = 0, @@ -89,29 +95,6 @@ static struct at91_mmc_data __initdata kb9202_mmc_data = { .wire4 = 1, }; -static struct mtd_partition __initdata kb9202_nand_partition[] = { - { - .name = "nand_fs", - .offset = 0, - .size = MTDPART_SIZ_FULL, - }, -}; - -static struct mtd_partition *nand_partitions(int size, int *num_partitions) -{ - *num_partitions = ARRAY_SIZE(kb9202_nand_partition); - return kb9202_nand_partition; -} - -static struct at91_nand_data __initdata kb9202_nand_data = { - .ale = 22, - .cle = 21, - // .det_pin = ... not there - .rdy_pin = AT91_PIN_PC29, - .enable_pin = AT91_PIN_PC28, - .partition_info = nand_partitions, -}; - static void __init kb9202_board_init(void) { /* Serial */ @@ -128,8 +111,6 @@ static void __init kb9202_board_init(void) at91_add_device_i2c(); /* SPI */ at91_add_device_spi(NULL, 0); - /* NAND */ - at91_add_device_nand(&kb9202_nand_data); } MACHINE_START(KB9200, "KB920x") diff --git a/trunk/arch/arm/mach-at91rm9200/clock.c b/trunk/arch/arm/mach-at91rm9200/clock.c index a43b061a7c85..edc2cc837ae6 100644 --- a/trunk/arch/arm/mach-at91rm9200/clock.c +++ b/trunk/arch/arm/mach-at91rm9200/clock.c @@ -29,7 +29,7 @@ #include -#include "clock.h" +#include "generic.h" /* @@ -38,15 +38,23 @@ * PLLB be used at other rates (on boards that don't need USB), etc. */ -#define clk_is_primary(x) ((x)->type & CLK_TYPE_PRIMARY) -#define clk_is_programmable(x) ((x)->type & CLK_TYPE_PROGRAMMABLE) -#define clk_is_peripheral(x) ((x)->type & CLK_TYPE_PERIPHERAL) - - -static LIST_HEAD(clocks); -static DEFINE_SPINLOCK(clk_lock); +struct clk { + const char *name; /* unique clock name */ + const char *function; /* function of the clock */ + struct device *dev; /* device associated with function */ + unsigned long rate_hz; + struct clk *parent; + u32 pmc_mask; + void (*mode)(struct clk *, int); + unsigned id:2; /* PCK0..3, or 32k/main/a/b */ + unsigned primary:1; + unsigned pll:1; + unsigned programmable:1; + u16 users; +}; -static u32 at91_pllb_usb_init; +static spinlock_t clk_lock; +static u32 at91_pllb_usb_init; /* * Four primary clock sources: two crystal oscillators (32K, main), and @@ -59,20 +67,21 @@ static struct clk clk32k = { .rate_hz = AT91_SLOW_CLOCK, .users = 1, /* always on */ .id = 0, - .type = CLK_TYPE_PRIMARY, + .primary = 1, }; static struct clk main_clk = { .name = "main", .pmc_mask = AT91_PMC_MOSCS, /* in PMC_SR */ .id = 1, - .type = CLK_TYPE_PRIMARY, + .primary = 1, }; static struct clk plla = { .name = "plla", .parent = &main_clk, .pmc_mask = AT91_PMC_LOCKA, /* in PMC_SR */ .id = 2, - .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, + .primary = 1, + .pll = 1, }; static void pllb_mode(struct clk *clk, int is_on) @@ -85,7 +94,6 @@ static void pllb_mode(struct clk *clk, int is_on) } else value = 0; - // REVISIT: Add work-around for AT91RM9200 Errata #26 ? at91_sys_write(AT91_CKGR_PLLBR, value); do { @@ -99,7 +107,8 @@ static struct clk pllb = { .pmc_mask = AT91_PMC_LOCKB, /* in PMC_SR */ .mode = pllb_mode, .id = 3, - .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, + .primary = 1, + .pll = 1, }; static void pmc_sys_mode(struct clk *clk, int is_on) @@ -124,6 +133,41 @@ static struct clk uhpck = { .mode = pmc_sys_mode, }; +#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS +/* + * The four programmable clocks can be parented by any primary clock. + * You must configure pin multiplexing to bring these signals out. + */ +static struct clk pck0 = { + .name = "pck0", + .pmc_mask = AT91_PMC_PCK0, + .mode = pmc_sys_mode, + .programmable = 1, + .id = 0, +}; +static struct clk pck1 = { + .name = "pck1", + .pmc_mask = AT91_PMC_PCK1, + .mode = pmc_sys_mode, + .programmable = 1, + .id = 1, +}; +static struct clk pck2 = { + .name = "pck2", + .pmc_mask = AT91_PMC_PCK2, + .mode = pmc_sys_mode, + .programmable = 1, + .id = 2, +}; +static struct clk pck3 = { + .name = "pck3", + .pmc_mask = AT91_PMC_PCK3, + .mode = pmc_sys_mode, + .programmable = 1, + .id = 3, +}; +#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ + /* * The master clock is divided from the CPU clock (by 1-4). It's used for @@ -143,21 +187,131 @@ static void pmc_periph_mode(struct clk *clk, int is_on) at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask); } -static struct clk __init *at91_css_to_clk(unsigned long css) -{ - switch (css) { - case AT91_PMC_CSS_SLOW: - return &clk32k; - case AT91_PMC_CSS_MAIN: - return &main_clk; - case AT91_PMC_CSS_PLLA: - return &plla; - case AT91_PMC_CSS_PLLB: - return &pllb; - } +static struct clk udc_clk = { + .name = "udc_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_UDP, + .mode = pmc_periph_mode, +}; +static struct clk ohci_clk = { + .name = "ohci_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_UHP, + .mode = pmc_periph_mode, +}; +static struct clk ether_clk = { + .name = "ether_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_EMAC, + .mode = pmc_periph_mode, +}; +static struct clk mmc_clk = { + .name = "mci_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_MCI, + .mode = pmc_periph_mode, +}; +static struct clk twi_clk = { + .name = "twi_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_TWI, + .mode = pmc_periph_mode, +}; +static struct clk usart0_clk = { + .name = "usart0_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_US0, + .mode = pmc_periph_mode, +}; +static struct clk usart1_clk = { + .name = "usart1_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_US1, + .mode = pmc_periph_mode, +}; +static struct clk usart2_clk = { + .name = "usart2_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_US2, + .mode = pmc_periph_mode, +}; +static struct clk usart3_clk = { + .name = "usart3_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_US3, + .mode = pmc_periph_mode, +}; +static struct clk spi_clk = { + .name = "spi0_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_SPI, + .mode = pmc_periph_mode, +}; +static struct clk pioA_clk = { + .name = "pioA_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_PIOA, + .mode = pmc_periph_mode, +}; +static struct clk pioB_clk = { + .name = "pioB_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_PIOB, + .mode = pmc_periph_mode, +}; +static struct clk pioC_clk = { + .name = "pioC_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_PIOC, + .mode = pmc_periph_mode, +}; +static struct clk pioD_clk = { + .name = "pioD_clk", + .parent = &mck, + .pmc_mask = 1 << AT91_ID_PIOD, + .mode = pmc_periph_mode, +}; + +static struct clk *const clock_list[] = { + /* four primary clocks -- MUST BE FIRST! */ + &clk32k, + &main_clk, + &plla, + &pllb, + + /* PLLB children (USB) */ + &udpck, + &uhpck, + +#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS + /* programmable clocks */ + &pck0, + &pck1, + &pck2, + &pck3, +#endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ + + /* MCK and peripherals */ + &mck, + &usart0_clk, + &usart1_clk, + &usart2_clk, + &usart3_clk, + &mmc_clk, + &udc_clk, + &twi_clk, + &spi_clk, + &pioA_clk, + &pioB_clk, + &pioC_clk, + &pioD_clk, + // ssc0..ssc2 + // tc0..tc5 + // irq0..irq6 + &ohci_clk, + ðer_clk, +}; - return NULL; -} /* * Associate a particular clock with a function (eg, "uart") and device. @@ -175,12 +329,14 @@ void __init at91_clock_associate(const char *id, struct device *dev, const char clk->dev = dev; } -/* clocks cannot be de-registered no refcounting necessary */ +/* clocks are all static for now; no refcounting necessary */ struct clk *clk_get(struct device *dev, const char *id) { - struct clk *clk; + int i; + + for (i = 0; i < ARRAY_SIZE(clock_list); i++) { + struct clk *clk = clock_list[i]; - list_for_each_entry(clk, &clocks, node) { if (strcmp(id, clk->name) == 0) return clk; if (clk->function && (dev == clk->dev) && strcmp(id, clk->function) == 0) @@ -268,7 +424,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate) unsigned prescale; unsigned long actual; - if (!clk_is_programmable(clk)) + if (!clk->programmable) return -EINVAL; spin_lock_irqsave(&clk_lock, flags); @@ -290,7 +446,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) unsigned prescale; unsigned long actual; - if (!clk_is_programmable(clk)) + if (!clk->programmable) return -EINVAL; if (clk->users) return -EBUSY; @@ -328,7 +484,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent) if (clk->users) return -EBUSY; - if (!clk_is_primary(parent) || !clk_is_programmable(clk)) + if (!parent->primary || !clk->programmable) return -EINVAL; spin_lock_irqsave(&clk_lock, flags); @@ -341,18 +497,6 @@ int clk_set_parent(struct clk *clk, struct clk *parent) } EXPORT_SYMBOL(clk_set_parent); -/* establish PCK0..PCK3 parentage and rate */ -static void init_programmable_clock(struct clk *clk) -{ - struct clk *parent; - u32 pckr; - - pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); - parent = at91_css_to_clk(pckr & AT91_PMC_CSS); - clk->parent = parent; - clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3)); -} - #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ /*------------------------------------------------------------------------*/ @@ -362,7 +506,6 @@ static void init_programmable_clock(struct clk *clk) static int at91_clk_show(struct seq_file *s, void *unused) { u32 scsr, pcsr, sr; - struct clk *clk; unsigned i; seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); @@ -380,8 +523,9 @@ static int at91_clk_show(struct seq_file *s, void *unused) seq_printf(s, "\n"); - list_for_each_entry(clk, &clocks, node) { - char *state; + for (i = 0; i < ARRAY_SIZE(clock_list); i++) { + char *state; + struct clk *clk = clock_list[i]; if (clk->mode == pmc_sys_mode) state = (scsr & clk->pmc_mask) ? "on" : "off"; @@ -424,28 +568,6 @@ postcore_initcall(at91_clk_debugfs_init); #endif -/*------------------------------------------------------------------------*/ - -/* Register a new clock */ -int __init clk_register(struct clk *clk) -{ - if (clk_is_peripheral(clk)) { - clk->parent = &mck; - clk->mode = pmc_periph_mode; - list_add_tail(&clk->node, &clocks); - } -#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS - else if (clk_is_programmable(clk)) { - clk->mode = pmc_sys_mode; - init_programmable_clock(clk); - list_add_tail(&clk->node, &clocks); - } -#endif - - return 0; -} - - /*------------------------------------------------------------------------*/ static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg) @@ -518,17 +640,20 @@ static unsigned __init at91_pll_calc(unsigned main_freq, unsigned out_freq) return 0; } + /* * Several unused clocks may be active. Turn them off. */ -static void __init at91_periphclk_reset(void) +static void at91_periphclk_reset(void) { unsigned long reg; - struct clk *clk; + int i; reg = at91_sys_read(AT91_PMC_PCSR); - list_for_each_entry(clk, &clocks, node) { + for (i = 0; i < ARRAY_SIZE(clock_list); i++) { + struct clk *clk = clock_list[i]; + if (clk->mode != pmc_periph_mode) continue; @@ -539,25 +664,11 @@ static void __init at91_periphclk_reset(void) at91_sys_write(AT91_PMC_PCDR, reg); } -static struct clk *const standard_pmc_clocks[] __initdata = { - /* four primary clocks */ - &clk32k, - &main_clk, - &plla, - &pllb, - - /* PLLB children (USB) */ - &udpck, - &uhpck, - - /* MCK */ - &mck -}; - int __init at91_clock_init(unsigned long main_clock) { unsigned tmp, freq, mckr; - int i; + + spin_lock_init(&clk_lock); /* * When the bootloader initialized the main oscillator correctly, @@ -598,15 +709,11 @@ int __init at91_clock_init(unsigned long main_clock) * For now, assume this parentage won't change. */ mckr = at91_sys_read(AT91_PMC_MCKR); - mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); + mck.parent = clock_list[mckr & AT91_PMC_CSS]; freq = mck.parent->rate_hz; freq /= (1 << ((mckr >> 2) & 3)); /* prescale */ mck.rate_hz = freq / (1 + ((mckr >> 8) & 3)); /* mdiv */ - /* Register the PMC's standard clocks */ - for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) - list_add_tail(&standard_pmc_clocks[i]->node, &clocks); - /* MCK and CPU clock are "always on" */ clk_enable(&mck); @@ -615,8 +722,35 @@ int __init at91_clock_init(unsigned long main_clock) (unsigned) main_clock / 1000000, ((unsigned) main_clock % 1000000) / 1000); +#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS + /* establish PCK0..PCK3 parentage */ + for (tmp = 0; tmp < ARRAY_SIZE(clock_list); tmp++) { + struct clk *clk = clock_list[tmp], *parent; + u32 pckr; + + if (!clk->programmable) + continue; + + pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); + parent = clock_list[pckr & AT91_PMC_CSS]; + clk->parent = parent; + clk->rate_hz = parent->rate_hz / (1 << ((pckr >> 2) & 3)); + + if (clk->users == 0) { + /* not being used, so switch it off */ + at91_sys_write(AT91_PMC_SCDR, clk->pmc_mask); + } + } +#else /* disable all programmable clocks */ at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK0 | AT91_PMC_PCK1 | AT91_PMC_PCK2 | AT91_PMC_PCK3); +#endif + + /* enable the PIO clocks */ + clk_enable(&pioA_clk); + clk_enable(&pioB_clk); + clk_enable(&pioC_clk); + clk_enable(&pioD_clk); /* disable all other unused peripheral clocks */ at91_periphclk_reset(); diff --git a/trunk/arch/arm/mach-at91rm9200/clock.h b/trunk/arch/arm/mach-at91rm9200/clock.h deleted file mode 100644 index 0592e662ab37..000000000000 --- a/trunk/arch/arm/mach-at91rm9200/clock.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * linux/arch/arm/mach-at91rm9200/clock.h - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#define CLK_TYPE_PRIMARY 0x1 -#define CLK_TYPE_PLL 0x2 -#define CLK_TYPE_PROGRAMMABLE 0x4 -#define CLK_TYPE_PERIPHERAL 0x8 - - -struct clk { - struct list_head node; - const char *name; /* unique clock name */ - const char *function; /* function of the clock */ - struct device *dev; /* device associated with function */ - unsigned long rate_hz; - struct clk *parent; - u32 pmc_mask; - void (*mode)(struct clk *, int); - unsigned id:2; /* PCK0..3, or 32k/main/a/b */ - unsigned type; /* clock type */ - u16 users; -}; - - -extern int __init clk_register(struct clk *clk); diff --git a/trunk/arch/arm/mach-at91rm9200/devices.c b/trunk/arch/arm/mach-at91rm9200/devices.c index 01525530c287..4352acb88178 100644 --- a/trunk/arch/arm/mach-at91rm9200/devices.c +++ b/trunk/arch/arm/mach-at91rm9200/devices.c @@ -35,13 +35,13 @@ static struct at91_usbh_data usbh_data; static struct resource at91_usbh_resources[] = { [0] = { - .start = AT91RM9200_UHP_BASE, - .end = AT91RM9200_UHP_BASE + SZ_1M - 1, + .start = AT91_UHP_BASE, + .end = AT91_UHP_BASE + SZ_1M - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91RM9200_ID_UHP, - .end = AT91RM9200_ID_UHP, + .start = AT91_ID_UHP, + .end = AT91_ID_UHP, .flags = IORESOURCE_IRQ, }, }; @@ -80,13 +80,13 @@ static struct at91_udc_data udc_data; static struct resource at91_udc_resources[] = { [0] = { - .start = AT91RM9200_BASE_UDP, - .end = AT91RM9200_BASE_UDP + SZ_16K - 1, + .start = AT91_BASE_UDP, + .end = AT91_BASE_UDP + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91RM9200_ID_UDP, - .end = AT91RM9200_ID_UDP, + .start = AT91_ID_UDP, + .end = AT91_ID_UDP, .flags = IORESOURCE_IRQ, }, }; @@ -131,13 +131,13 @@ static struct at91_eth_data eth_data; static struct resource at91_eth_resources[] = { [0] = { - .start = AT91_VA_BASE_EMAC, - .end = AT91_VA_BASE_EMAC + SZ_16K - 1, + .start = AT91_BASE_EMAC, + .end = AT91_BASE_EMAC + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91RM9200_ID_EMAC, - .end = AT91RM9200_ID_EMAC, + .start = AT91_ID_EMAC, + .end = AT91_ID_EMAC, .flags = IORESOURCE_IRQ, }, }; @@ -263,13 +263,13 @@ static struct at91_mmc_data mmc_data; static struct resource at91_mmc_resources[] = { [0] = { - .start = AT91RM9200_BASE_MCI, - .end = AT91RM9200_BASE_MCI + SZ_16K - 1, + .start = AT91_BASE_MCI, + .end = AT91_BASE_MCI + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91RM9200_ID_MCI, - .end = AT91RM9200_ID_MCI, + .start = AT91_ID_MCI, + .end = AT91_ID_MCI, .flags = IORESOURCE_IRQ, }, }; @@ -423,13 +423,13 @@ static u64 spi_dmamask = 0xffffffffUL; static struct resource at91_spi_resources[] = { [0] = { - .start = AT91RM9200_BASE_SPI, - .end = AT91RM9200_BASE_SPI + SZ_16K - 1, + .start = AT91_BASE_SPI, + .end = AT91_BASE_SPI + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91RM9200_ID_SPI, - .end = AT91RM9200_ID_SPI, + .start = AT91_ID_SPI, + .end = AT91_ID_SPI, .flags = IORESOURCE_IRQ, }, }; @@ -582,13 +582,13 @@ static inline void configure_dbgu_pins(void) static struct resource uart0_resources[] = { [0] = { - .start = AT91RM9200_BASE_US0, - .end = AT91RM9200_BASE_US0 + SZ_16K - 1, + .start = AT91_BASE_US0, + .end = AT91_BASE_US0 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91RM9200_ID_US0, - .end = AT91RM9200_ID_US0, + .start = AT91_ID_US0, + .end = AT91_ID_US0, .flags = IORESOURCE_IRQ, }, }; @@ -624,13 +624,13 @@ static inline void configure_usart0_pins(void) static struct resource uart1_resources[] = { [0] = { - .start = AT91RM9200_BASE_US1, - .end = AT91RM9200_BASE_US1 + SZ_16K - 1, + .start = AT91_BASE_US1, + .end = AT91_BASE_US1 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91RM9200_ID_US1, - .end = AT91RM9200_ID_US1, + .start = AT91_ID_US1, + .end = AT91_ID_US1, .flags = IORESOURCE_IRQ, }, }; @@ -665,13 +665,13 @@ static inline void configure_usart1_pins(void) static struct resource uart2_resources[] = { [0] = { - .start = AT91RM9200_BASE_US2, - .end = AT91RM9200_BASE_US2 + SZ_16K - 1, + .start = AT91_BASE_US2, + .end = AT91_BASE_US2 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91RM9200_ID_US2, - .end = AT91RM9200_ID_US2, + .start = AT91_ID_US2, + .end = AT91_ID_US2, .flags = IORESOURCE_IRQ, }, }; @@ -700,13 +700,13 @@ static inline void configure_usart2_pins(void) static struct resource uart3_resources[] = { [0] = { - .start = AT91RM9200_BASE_US3, - .end = AT91RM9200_BASE_US3 + SZ_16K - 1, + .start = AT91_BASE_US3, + .end = AT91_BASE_US3 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91RM9200_ID_US3, - .end = AT91RM9200_ID_US3, + .start = AT91_ID_US3, + .end = AT91_ID_US3, .flags = IORESOURCE_IRQ, }, }; diff --git a/trunk/arch/arm/mach-at91rm9200/generic.h b/trunk/arch/arm/mach-at91rm9200/generic.h index 694e411e285f..7979d8ab7e07 100644 --- a/trunk/arch/arm/mach-at91rm9200/generic.h +++ b/trunk/arch/arm/mach-at91rm9200/generic.h @@ -8,17 +8,18 @@ * published by the Free Software Foundation. */ - /* Processors */ -extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks); - /* Interrupts */ -extern void __init at91rm9200_init_interrupts(unsigned int priority[]); +extern void __init at91rm9200_init_irq(unsigned int priority[]); extern void __init at91_aic_init(unsigned int priority[]); +extern void __init at91_gpio_irq_setup(unsigned banks); /* Timer */ struct sys_timer; extern struct sys_timer at91rm9200_timer; + /* Memory Map */ +extern void __init at91rm9200_map_io(void); + /* Clocks */ extern int __init at91_clock_init(unsigned long main_clock); struct device; @@ -28,14 +29,3 @@ extern void __init at91_clock_associate(const char *id, struct device *dev, cons extern void at91_irq_suspend(void); extern void at91_irq_resume(void); - /* GPIO */ -#define AT91RM9200_PQFP 3 /* AT91RM9200 PQFP package has 3 banks */ -#define AT91RM9200_BGA 4 /* AT91RM9200 BGA package has 4 banks */ - -struct at91_gpio_bank { - unsigned short id; /* peripheral ID */ - unsigned long offset; /* offset from system peripheral base */ - struct clk *clock; /* associated clock */ -}; -extern void __init at91_gpio_init(struct at91_gpio_bank *, int nr_banks); -extern void __init at91_gpio_irq_setup(void); diff --git a/trunk/arch/arm/mach-at91rm9200/gpio.c b/trunk/arch/arm/mach-at91rm9200/gpio.c index 58c9bf5e9520..cec199fd6721 100644 --- a/trunk/arch/arm/mach-at91rm9200/gpio.c +++ b/trunk/arch/arm/mach-at91rm9200/gpio.c @@ -9,7 +9,6 @@ * (at your option) any later version. */ -#include #include #include #include @@ -21,12 +20,12 @@ #include #include -#include "generic.h" - - -static struct at91_gpio_bank *gpio; -static int gpio_banks; - +static const u32 pio_controller_offset[4] = { + AT91_PIOA, + AT91_PIOB, + AT91_PIOC, + AT91_PIOD, +}; static inline void __iomem *pin_to_controller(unsigned pin) { @@ -34,8 +33,8 @@ static inline void __iomem *pin_to_controller(unsigned pin) pin -= PIN_BASE; pin /= 32; - if (likely(pin < gpio_banks)) - return sys_base + gpio[pin].offset; + if (likely(pin < BGA_GPIO_BANKS)) + return sys_base + pio_controller_offset[pin]; return NULL; } @@ -180,6 +179,7 @@ EXPORT_SYMBOL(at91_set_multi_drive); /*--------------------------------------------------------------------------*/ + /* * assuming the pin is muxed as a gpio output, set its value. */ @@ -216,8 +216,8 @@ EXPORT_SYMBOL(at91_get_gpio_value); #ifdef CONFIG_PM -static u32 wakeups[MAX_GPIO_BANKS]; -static u32 backups[MAX_GPIO_BANKS]; +static u32 wakeups[BGA_GPIO_BANKS]; +static u32 backups[BGA_GPIO_BANKS]; static int gpio_irq_set_wake(unsigned pin, unsigned state) { @@ -226,7 +226,7 @@ static int gpio_irq_set_wake(unsigned pin, unsigned state) pin -= PIN_BASE; pin /= 32; - if (unlikely(pin >= MAX_GPIO_BANKS)) + if (unlikely(pin >= BGA_GPIO_BANKS)) return -EINVAL; if (state) @@ -241,8 +241,8 @@ void at91_gpio_suspend(void) { int i; - for (i = 0; i < gpio_banks; i++) { - u32 pio = gpio[i].offset; + for (i = 0; i < BGA_GPIO_BANKS; i++) { + u32 pio = pio_controller_offset[i]; /* * Note: drivers should have disabled GPIO interrupts that @@ -257,14 +257,14 @@ void at91_gpio_suspend(void) * first place! */ backups[i] = at91_sys_read(pio + PIO_IMR); - at91_sys_write(pio + PIO_IDR, backups[i]); - at91_sys_write(pio + PIO_IER, wakeups[i]); + at91_sys_write(pio_controller_offset[i] + PIO_IDR, backups[i]); + at91_sys_write(pio_controller_offset[i] + PIO_IER, wakeups[i]); if (!wakeups[i]) { - disable_irq_wake(gpio[i].id); - at91_sys_write(AT91_PMC_PCDR, 1 << gpio[i].id); + disable_irq_wake(AT91_ID_PIOA + i); + at91_sys_write(AT91_PMC_PCDR, 1 << (AT91_ID_PIOA + i)); } else { - enable_irq_wake(gpio[i].id); + enable_irq_wake(AT91_ID_PIOA + i); #ifdef CONFIG_PM_DEBUG printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", "ABCD"[i], wakeups[i]); #endif @@ -276,13 +276,16 @@ void at91_gpio_resume(void) { int i; - for (i = 0; i < gpio_banks; i++) { - u32 pio = gpio[i].offset; - - at91_sys_write(pio + PIO_IDR, wakeups[i]); - at91_sys_write(pio + PIO_IER, backups[i]); - at91_sys_write(AT91_PMC_PCER, 1 << gpio[i].id); + for (i = 0; i < BGA_GPIO_BANKS; i++) { + at91_sys_write(pio_controller_offset[i] + PIO_IDR, wakeups[i]); + at91_sys_write(pio_controller_offset[i] + PIO_IER, backups[i]); } + + at91_sys_write(AT91_PMC_PCER, + (1 << AT91_ID_PIOA) + | (1 << AT91_ID_PIOB) + | (1 << AT91_ID_PIOC) + | (1 << AT91_ID_PIOD)); } #else @@ -374,25 +377,20 @@ static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs /* now it may re-trigger */ } -/*--------------------------------------------------------------------------*/ - -/* - * Called from the processor-specific init to enable GPIO interrupt support. - */ -void __init at91_gpio_irq_setup(void) +/* call this from board-specific init_irq */ +void __init at91_gpio_irq_setup(unsigned banks) { - unsigned pioc, pin; + unsigned pioc, pin, id; - for (pioc = 0, pin = PIN_BASE; - pioc < gpio_banks; - pioc++) { + if (banks > 4) + banks = 4; + for (pioc = 0, pin = PIN_BASE, id = AT91_ID_PIOA; + pioc < banks; + pioc++, id++) { void __iomem *controller; - unsigned id = gpio[pioc].id; unsigned i; - clk_enable(gpio[pioc].clock); /* enable PIO controller's clock */ - - controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset; + controller = (void __iomem *) AT91_VA_BASE_SYS + pio_controller_offset[pioc]; __raw_writel(~0, controller + PIO_IDR); set_irq_data(id, (void *) pin); @@ -410,16 +408,5 @@ void __init at91_gpio_irq_setup(void) set_irq_chained_handler(id, gpio_irq_handler); } - pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks); -} - -/* - * Called from the processor-specific init to enable GPIO pin support. - */ -void __init at91_gpio_init(struct at91_gpio_bank *data, int nr_banks) -{ - BUG_ON(nr_banks > MAX_GPIO_BANKS); - - gpio = data; - gpio_banks = nr_banks; + pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, banks); } diff --git a/trunk/arch/arm/mach-at91rm9200/irq.c b/trunk/arch/arm/mach-at91rm9200/irq.c index 3e488117ca91..c3a5e777f9f8 100644 --- a/trunk/arch/arm/mach-at91rm9200/irq.c +++ b/trunk/arch/arm/mach-at91rm9200/irq.c @@ -34,6 +34,8 @@ #include #include +#include "generic.h" + static void at91_aic_mask_irq(unsigned int irq) { @@ -59,12 +61,12 @@ static int at91_aic_set_type(unsigned irq, unsigned type) srctype = AT91_AIC_SRCTYPE_RISING; break; case IRQT_LOW: - if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */ + if ((irq > AT91_ID_FIQ) && (irq < AT91_ID_IRQ0)) /* only supported on external interrupts */ return -EINVAL; srctype = AT91_AIC_SRCTYPE_LOW; break; case IRQT_FALLING: - if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */ + if ((irq > AT91_ID_FIQ) && (irq < AT91_ID_IRQ0)) /* only supported on external interrupts */ return -EINVAL; srctype = AT91_AIC_SRCTYPE_FALLING; break; diff --git a/trunk/arch/arm/mach-at91rm9200/pm.c b/trunk/arch/arm/mach-at91rm9200/pm.c index 32c95d8eaacf..47e5480feb7e 100644 --- a/trunk/arch/arm/mach-at91rm9200/pm.c +++ b/trunk/arch/arm/mach-at91rm9200/pm.c @@ -123,13 +123,13 @@ static int at91_pm_enter(suspend_state_t state) (at91_sys_read(AT91_PMC_PCSR) | (1 << AT91_ID_FIQ) | (1 << AT91_ID_SYS) - | (1 << AT91RM9200_ID_IRQ0) - | (1 << AT91RM9200_ID_IRQ1) - | (1 << AT91RM9200_ID_IRQ2) - | (1 << AT91RM9200_ID_IRQ3) - | (1 << AT91RM9200_ID_IRQ4) - | (1 << AT91RM9200_ID_IRQ5) - | (1 << AT91RM9200_ID_IRQ6)) + | (1 << AT91_ID_IRQ0) + | (1 << AT91_ID_IRQ1) + | (1 << AT91_ID_IRQ2) + | (1 << AT91_ID_IRQ3) + | (1 << AT91_ID_IRQ4) + | (1 << AT91_ID_IRQ5) + | (1 << AT91_ID_IRQ6)) & at91_sys_read(AT91_AIC_IMR), state); diff --git a/trunk/arch/arm/mach-ep93xx/Kconfig b/trunk/arch/arm/mach-ep93xx/Kconfig index e346b03cd921..f1b740083aee 100644 --- a/trunk/arch/arm/mach-ep93xx/Kconfig +++ b/trunk/arch/arm/mach-ep93xx/Kconfig @@ -15,12 +15,6 @@ config MACH_EDB9302 Say 'Y' here if you want your kernel to support the Cirrus Logic EDB9302 Evaluation Board. -config MACH_EDB9312 - bool "Support Cirrus Logic EDB9312" - help - Say 'Y' here if you want your kernel to support the Cirrus - Logic EDB9312 Evaluation Board. - config MACH_EDB9315 bool "Support Cirrus Logic EDB9315" help diff --git a/trunk/arch/arm/mach-ep93xx/Makefile b/trunk/arch/arm/mach-ep93xx/Makefile index c2eb18b530c2..1f5a6b0487ee 100644 --- a/trunk/arch/arm/mach-ep93xx/Makefile +++ b/trunk/arch/arm/mach-ep93xx/Makefile @@ -7,7 +7,6 @@ obj-n := obj- := obj-$(CONFIG_MACH_EDB9302) += edb9302.o -obj-$(CONFIG_MACH_EDB9312) += edb9312.o obj-$(CONFIG_MACH_EDB9315) += edb9315.o obj-$(CONFIG_MACH_EDB9315A) += edb9315a.o obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o diff --git a/trunk/arch/arm/mach-ep93xx/edb9312.c b/trunk/arch/arm/mach-ep93xx/edb9312.c deleted file mode 100644 index 9e399211108c..000000000000 --- a/trunk/arch/arm/mach-ep93xx/edb9312.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * arch/arm/mach-ep93xx/edb9312.c - * Cirrus Logic EDB9312 support. - * - * Copyright (C) 2006 Infosys Technologies Limited - * Toufeeq Hussain - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct physmap_flash_data edb9312_flash_data = { - .width = 4, -}; - -static struct resource edb9312_flash_resource = { - .start = 0x60000000, - .end = 0x61ffffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device edb9312_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &edb9312_flash_data, - }, - .num_resources = 1, - .resource = &edb9312_flash_resource, -}; - -static void __init edb9312_init_machine(void) -{ - ep93xx_init_devices(); - platform_device_register(&edb9312_flash); -} - -MACHINE_START(EDB9312, "Cirrus Logic EDB9312 Evaluation Board") - /* Maintainer: Toufeeq Hussain */ - .phys_io = EP93XX_APB_PHYS_BASE, - .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, - .boot_params = 0x00000100, - .map_io = ep93xx_map_io, - .init_irq = ep93xx_init_irq, - .timer = &ep93xx_timer, - .init_machine = edb9312_init_machine, -MACHINE_END diff --git a/trunk/arch/arm/mach-footbridge/dc21285.c b/trunk/arch/arm/mach-footbridge/dc21285.c index a1ae49df5c3b..823e25d4547e 100644 --- a/trunk/arch/arm/mach-footbridge/dc21285.c +++ b/trunk/arch/arm/mach-footbridge/dc21285.c @@ -69,16 +69,16 @@ dc21285_read_config(struct pci_bus *bus, unsigned int devfn, int where, if (addr) switch (size) { case 1: - asm("ldrb %0, [%1, %2]" - : "=r" (v) : "r" (addr), "r" (where) : "cc"); + asm("ldr%?b %0, [%1, %2]" + : "=r" (v) : "r" (addr), "r" (where)); break; case 2: - asm("ldrh %0, [%1, %2]" - : "=r" (v) : "r" (addr), "r" (where) : "cc"); + asm("ldr%?h %0, [%1, %2]" + : "=r" (v) : "r" (addr), "r" (where)); break; case 4: - asm("ldr %0, [%1, %2]" - : "=r" (v) : "r" (addr), "r" (where) : "cc"); + asm("ldr%? %0, [%1, %2]" + : "=r" (v) : "r" (addr), "r" (where)); break; } @@ -103,19 +103,16 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where, if (addr) switch (size) { case 1: - asm("strb %0, [%1, %2]" - : : "r" (value), "r" (addr), "r" (where) - : "cc"); + asm("str%?b %0, [%1, %2]" + : : "r" (value), "r" (addr), "r" (where)); break; case 2: - asm("strh %0, [%1, %2]" - : : "r" (value), "r" (addr), "r" (where) - : "cc"); + asm("str%?h %0, [%1, %2]" + : : "r" (value), "r" (addr), "r" (where)); break; case 4: - asm("str %0, [%1, %2]" - : : "r" (value), "r" (addr), "r" (where) - : "cc"); + asm("str%? %0, [%1, %2]" + : : "r" (value), "r" (addr), "r" (where)); break; } diff --git a/trunk/arch/arm/mach-iop32x/Kconfig b/trunk/arch/arm/mach-iop32x/Kconfig deleted file mode 100644 index c072d94070da..000000000000 --- a/trunk/arch/arm/mach-iop32x/Kconfig +++ /dev/null @@ -1,35 +0,0 @@ -if ARCH_IOP32X - -menu "IOP32x Implementation Options" - -comment "IOP32x Platform Types" - -config MACH_GLANTANK - bool "Enable support for the IO-Data GLAN Tank" - help - Say Y here if you want to run your kernel on the GLAN Tank - NAS appliance or machines from IO-Data's HDL-Gxxx, HDL-GWxxx - and HDL-GZxxx series. - -config ARCH_IQ80321 - bool "Enable support for IQ80321" - help - Say Y here if you want to run your kernel on the Intel IQ80321 - evaluation kit for the IOP321 processor. - -config ARCH_IQ31244 - bool "Enable support for EP80219/IQ31244" - help - Say Y here if you want to run your kernel on the Intel EP80219 - evaluation kit for the Intel 80219 processor (a IOP321 variant) - or the IQ31244 evaluation kit for the IOP321 processor. - -config MACH_N2100 - bool "Enable support for the Thecus n2100" - help - Say Y here if you want to run your kernel on the Thecus n2100 - NAS appliance. - -endmenu - -endif diff --git a/trunk/arch/arm/mach-iop32x/Makefile b/trunk/arch/arm/mach-iop32x/Makefile deleted file mode 100644 index 7b05b37e1f94..000000000000 --- a/trunk/arch/arm/mach-iop32x/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# Makefile for the linux kernel. -# - -obj-y := irq.o -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_MACH_GLANTANK) += glantank.o -obj-$(CONFIG_ARCH_IQ80321) += iq80321.o -obj-$(CONFIG_ARCH_IQ31244) += iq31244.o -obj-$(CONFIG_MACH_N2100) += n2100.o diff --git a/trunk/arch/arm/mach-iop32x/Makefile.boot b/trunk/arch/arm/mach-iop32x/Makefile.boot deleted file mode 100644 index 47000dccd61f..000000000000 --- a/trunk/arch/arm/mach-iop32x/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y := 0xa0008000 -params_phys-y := 0xa0000100 -initrd_phys-y := 0xa0800000 diff --git a/trunk/arch/arm/mach-iop32x/glantank.c b/trunk/arch/arm/mach-iop32x/glantank.c deleted file mode 100644 index b9b765057dbe..000000000000 --- a/trunk/arch/arm/mach-iop32x/glantank.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * arch/arm/mach-iop32x/glantank.c - * - * Board support code for the GLAN Tank. - * - * Copyright (C) 2006 Martin Michlmayr - * Copyright (C) 2006 Lennert Buytenhek - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * GLAN Tank timer tick configuration. - */ -static void __init glantank_timer_init(void) -{ - /* 33.333 MHz crystal. */ - iop3xx_init_time(200000000); -} - -static struct sys_timer glantank_timer = { - .init = glantank_timer_init, - .offset = iop3xx_gettimeoffset, -}; - - -/* - * GLAN Tank I/O. - */ -static struct map_desc glantank_io_desc[] __initdata = { - { /* on-board devices */ - .virtual = GLANTANK_UART, - .pfn = __phys_to_pfn(GLANTANK_UART), - .length = 0x00100000, - .type = MT_DEVICE - }, -}; - -void __init glantank_map_io(void) -{ - iop3xx_map_io(); - iotable_init(glantank_io_desc, ARRAY_SIZE(glantank_io_desc)); -} - - -/* - * GLAN Tank PCI. - */ -#define INTA IRQ_IOP32X_XINT0 -#define INTB IRQ_IOP32X_XINT1 -#define INTC IRQ_IOP32X_XINT2 -#define INTD IRQ_IOP32X_XINT3 - -static inline int __init -glantank_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - static int pci_irq_table[][4] = { - /* - * PCI IDSEL/INTPIN->INTLINE - * A B C D - */ - {INTD, INTD, INTD, INTD}, /* UART (8250) */ - {INTA, INTA, INTA, INTA}, /* Ethernet (E1000) */ - {INTB, INTB, INTB, INTB}, /* IDE (AEC6280R) */ - {INTC, INTC, INTC, INTC}, /* USB (NEC) */ - }; - - BUG_ON(pin < 1 || pin > 4); - - return pci_irq_table[slot % 4][pin - 1]; -} - -static struct hw_pci glantank_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iop3xx_pci_setup, - .preinit = iop3xx_pci_preinit, - .scan = iop3xx_pci_scan_bus, - .map_irq = glantank_pci_map_irq, -}; - -static int __init glantank_pci_init(void) -{ - if (machine_is_glantank()) - pci_common_init(&glantank_pci); - - return 0; -} - -subsys_initcall(glantank_pci_init); - - -/* - * GLAN Tank machine initialization. - */ -static struct physmap_flash_data glantank_flash_data = { - .width = 1, -}; - -static struct resource glantank_flash_resource = { - .start = 0xf0000000, - .end = 0xf007ffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device glantank_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &glantank_flash_data, - }, - .num_resources = 1, - .resource = &glantank_flash_resource, -}; - -static struct plat_serial8250_port glantank_serial_port[] = { - { - .mapbase = GLANTANK_UART, - .membase = (char *)GLANTANK_UART, - .irq = IRQ_IOP32X_XINT3, - .flags = UPF_SKIP_TEST, - .iotype = UPIO_MEM, - .regshift = 0, - .uartclk = 1843200, - }, - { }, -}; - -static struct resource glantank_uart_resource = { - .start = GLANTANK_UART, - .end = GLANTANK_UART + 7, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device glantank_serial_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = glantank_serial_port, - }, - .num_resources = 1, - .resource = &glantank_uart_resource, -}; - -static void glantank_power_off(void) -{ - __raw_writeb(0x01, 0xfe8d0004); - - while (1) - ; -} - -static void __init glantank_init_machine(void) -{ - platform_device_register(&iop3xx_i2c0_device); - platform_device_register(&iop3xx_i2c1_device); - platform_device_register(&glantank_flash_device); - platform_device_register(&glantank_serial_device); - - pm_power_off = glantank_power_off; -} - -MACHINE_START(GLANTANK, "GLAN Tank") - /* Maintainer: Lennert Buytenhek */ - .phys_io = GLANTANK_UART, - .io_pg_offst = ((GLANTANK_UART) >> 18) & 0xfffc, - .boot_params = 0xa0000100, - .map_io = glantank_map_io, - .init_irq = iop32x_init_irq, - .timer = &glantank_timer, - .init_machine = glantank_init_machine, -MACHINE_END diff --git a/trunk/arch/arm/mach-iop32x/iq31244.c b/trunk/arch/arm/mach-iop32x/iq31244.c deleted file mode 100644 index be4aedfa0de6..000000000000 --- a/trunk/arch/arm/mach-iop32x/iq31244.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * arch/arm/mach-iop32x/iq31244.c - * - * Board support code for the Intel EP80219 and IQ31244 platforms. - * - * Author: Rory Bolt - * Copyright (C) 2002 Rory Bolt - * Copyright 2003 (c) MontaVista, Software, Inc. - * Copyright (C) 2004 Intel Corp. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* - * The EP80219 and IQ31244 use the same machine ID. To find out - * which of the two we're running on, we look at the processor ID. - */ -static int is_80219(void) -{ - extern int processor_id; - return !!((processor_id & 0xffffffe0) == 0x69052e20); -} - - -/* - * EP80219/IQ31244 timer tick configuration. - */ -static void __init iq31244_timer_init(void) -{ - if (is_80219()) { - /* 33.333 MHz crystal. */ - iop3xx_init_time(200000000); - } else { - /* 33.000 MHz crystal. */ - iop3xx_init_time(198000000); - } -} - -static struct sys_timer iq31244_timer = { - .init = iq31244_timer_init, - .offset = iop3xx_gettimeoffset, -}; - - -/* - * IQ31244 I/O. - */ -static struct map_desc iq31244_io_desc[] __initdata = { - { /* on-board devices */ - .virtual = IQ31244_UART, - .pfn = __phys_to_pfn(IQ31244_UART), - .length = 0x00100000, - .type = MT_DEVICE, - }, -}; - -void __init iq31244_map_io(void) -{ - iop3xx_map_io(); - iotable_init(iq31244_io_desc, ARRAY_SIZE(iq31244_io_desc)); -} - - -/* - * EP80219/IQ31244 PCI. - */ -static inline int __init -ep80219_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - int irq; - - if (slot == 0) { - /* CFlash */ - irq = IRQ_IOP32X_XINT1; - } else if (slot == 1) { - /* 82551 Pro 100 */ - irq = IRQ_IOP32X_XINT0; - } else if (slot == 2) { - /* PCI-X Slot */ - irq = IRQ_IOP32X_XINT3; - } else if (slot == 3) { - /* SATA */ - irq = IRQ_IOP32X_XINT2; - } else { - printk(KERN_ERR "ep80219_pci_map_irq() called for unknown " - "device PCI:%d:%d:%d\n", dev->bus->number, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - irq = -1; - } - - return irq; -} - -static struct hw_pci ep80219_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iop3xx_pci_setup, - .preinit = iop3xx_pci_preinit, - .scan = iop3xx_pci_scan_bus, - .map_irq = ep80219_pci_map_irq, -}; - -static inline int __init -iq31244_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - int irq; - - if (slot == 0) { - /* CFlash */ - irq = IRQ_IOP32X_XINT1; - } else if (slot == 1) { - /* SATA */ - irq = IRQ_IOP32X_XINT2; - } else if (slot == 2) { - /* PCI-X Slot */ - irq = IRQ_IOP32X_XINT3; - } else if (slot == 3) { - /* 82546 GigE */ - irq = IRQ_IOP32X_XINT0; - } else { - printk(KERN_ERR "iq31244_pci_map_irq called for unknown " - "device PCI:%d:%d:%d\n", dev->bus->number, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - irq = -1; - } - - return irq; -} - -static struct hw_pci iq31244_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iop3xx_pci_setup, - .preinit = iop3xx_pci_preinit, - .scan = iop3xx_pci_scan_bus, - .map_irq = iq31244_pci_map_irq, -}; - -static int __init iq31244_pci_init(void) -{ - if (machine_is_iq31244()) { - if (is_80219()) { - pci_common_init(&ep80219_pci); - } else { - pci_common_init(&iq31244_pci); - } - } - - return 0; -} - -subsys_initcall(iq31244_pci_init); - - -/* - * IQ31244 machine initialisation. - */ -static struct physmap_flash_data iq31244_flash_data = { - .width = 2, -}; - -static struct resource iq31244_flash_resource = { - .start = 0xf0000000, - .end = 0xf07fffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device iq31244_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &iq31244_flash_data, - }, - .num_resources = 1, - .resource = &iq31244_flash_resource, -}; - -static struct plat_serial8250_port iq31244_serial_port[] = { - { - .mapbase = IQ31244_UART, - .membase = (char *)IQ31244_UART, - .irq = IRQ_IOP32X_XINT1, - .flags = UPF_SKIP_TEST, - .iotype = UPIO_MEM, - .regshift = 0, - .uartclk = 1843200, - }, - { }, -}; - -static struct resource iq31244_uart_resource = { - .start = IQ31244_UART, - .end = IQ31244_UART + 7, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device iq31244_serial_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = iq31244_serial_port, - }, - .num_resources = 1, - .resource = &iq31244_uart_resource, -}; - -/* - * This function will send a SHUTDOWN_COMPLETE message to the PIC - * controller over I2C. We are not using the i2c subsystem since - * we are going to power off and it may be removed - */ -void ep80219_power_off(void) -{ - /* - * Send the Address byte w/ the start condition - */ - *IOP3XX_IDBR1 = 0x60; - *IOP3XX_ICR1 = 0xE9; - mdelay(1); - - /* - * Send the START_MSG byte w/ no start or stop condition - */ - *IOP3XX_IDBR1 = 0x0F; - *IOP3XX_ICR1 = 0xE8; - mdelay(1); - - /* - * Send the SHUTDOWN_COMPLETE Message ID byte w/ no start or - * stop condition - */ - *IOP3XX_IDBR1 = 0x03; - *IOP3XX_ICR1 = 0xE8; - mdelay(1); - - /* - * Send an ignored byte w/ stop condition - */ - *IOP3XX_IDBR1 = 0x00; - *IOP3XX_ICR1 = 0xEA; - - while (1) - ; -} - -static void __init iq31244_init_machine(void) -{ - platform_device_register(&iop3xx_i2c0_device); - platform_device_register(&iop3xx_i2c1_device); - platform_device_register(&iq31244_flash_device); - platform_device_register(&iq31244_serial_device); - - if (is_80219()) - pm_power_off = ep80219_power_off; -} - -MACHINE_START(IQ31244, "Intel IQ31244") - /* Maintainer: Intel Corp. */ - .phys_io = IQ31244_UART, - .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc, - .boot_params = 0xa0000100, - .map_io = iq31244_map_io, - .init_irq = iop32x_init_irq, - .timer = &iq31244_timer, - .init_machine = iq31244_init_machine, -MACHINE_END diff --git a/trunk/arch/arm/mach-iop32x/iq80321.c b/trunk/arch/arm/mach-iop32x/iq80321.c deleted file mode 100644 index 1f37b5501888..000000000000 --- a/trunk/arch/arm/mach-iop32x/iq80321.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * arch/arm/mach-iop32x/iq80321.c - * - * Board support code for the Intel IQ80321 platform. - * - * Author: Rory Bolt - * Copyright (C) 2002 Rory Bolt - * Copyright (C) 2004 Intel Corp. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * IQ80321 timer tick configuration. - */ -static void __init iq80321_timer_init(void) -{ - /* 33.333 MHz crystal. */ - iop3xx_init_time(200000000); -} - -static struct sys_timer iq80321_timer = { - .init = iq80321_timer_init, - .offset = iop3xx_gettimeoffset, -}; - - -/* - * IQ80321 I/O. - */ -static struct map_desc iq80321_io_desc[] __initdata = { - { /* on-board devices */ - .virtual = IQ80321_UART, - .pfn = __phys_to_pfn(IQ80321_UART), - .length = 0x00100000, - .type = MT_DEVICE, - }, -}; - -void __init iq80321_map_io(void) -{ - iop3xx_map_io(); - iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc)); -} - - -/* - * IQ80321 PCI. - */ -static inline int __init -iq80321_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - int irq; - - if ((slot == 2 || slot == 6) && pin == 1) { - /* PCI-X Slot INTA */ - irq = IRQ_IOP32X_XINT2; - } else if ((slot == 2 || slot == 6) && pin == 2) { - /* PCI-X Slot INTA */ - irq = IRQ_IOP32X_XINT3; - } else if ((slot == 2 || slot == 6) && pin == 3) { - /* PCI-X Slot INTA */ - irq = IRQ_IOP32X_XINT0; - } else if ((slot == 2 || slot == 6) && pin == 4) { - /* PCI-X Slot INTA */ - irq = IRQ_IOP32X_XINT1; - } else if (slot == 4 || slot == 8) { - /* Gig-E */ - irq = IRQ_IOP32X_XINT0; - } else { - printk(KERN_ERR "iq80321_pci_map_irq() called for unknown " - "device PCI:%d:%d:%d\n", dev->bus->number, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - irq = -1; - } - - return irq; -} - -static struct hw_pci iq80321_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iop3xx_pci_setup, - .preinit = iop3xx_pci_preinit, - .scan = iop3xx_pci_scan_bus, - .map_irq = iq80321_pci_map_irq, -}; - -static int __init iq80321_pci_init(void) -{ - if (machine_is_iq80321()) - pci_common_init(&iq80321_pci); - - return 0; -} - -subsys_initcall(iq80321_pci_init); - - -/* - * IQ80321 machine initialisation. - */ -static struct physmap_flash_data iq80321_flash_data = { - .width = 1, -}; - -static struct resource iq80321_flash_resource = { - .start = 0xf0000000, - .end = 0xf07fffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device iq80321_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &iq80321_flash_data, - }, - .num_resources = 1, - .resource = &iq80321_flash_resource, -}; - -static struct plat_serial8250_port iq80321_serial_port[] = { - { - .mapbase = IQ80321_UART, - .membase = (char *)IQ80321_UART, - .irq = IRQ_IOP32X_XINT1, - .flags = UPF_SKIP_TEST, - .iotype = UPIO_MEM, - .regshift = 0, - .uartclk = 1843200, - }, - { }, -}; - -static struct resource iq80321_uart_resource = { - .start = IQ80321_UART, - .end = IQ80321_UART + 7, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device iq80321_serial_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = iq80321_serial_port, - }, - .num_resources = 1, - .resource = &iq80321_uart_resource, -}; - -static void __init iq80321_init_machine(void) -{ - platform_device_register(&iop3xx_i2c0_device); - platform_device_register(&iop3xx_i2c1_device); - platform_device_register(&iq80321_flash_device); - platform_device_register(&iq80321_serial_device); -} - -MACHINE_START(IQ80321, "Intel IQ80321") - /* Maintainer: Intel Corp. */ - .phys_io = IQ80321_UART, - .io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc, - .boot_params = 0xa0000100, - .map_io = iq80321_map_io, - .init_irq = iop32x_init_irq, - .timer = &iq80321_timer, - .init_machine = iq80321_init_machine, -MACHINE_END diff --git a/trunk/arch/arm/mach-iop32x/irq.c b/trunk/arch/arm/mach-iop32x/irq.c deleted file mode 100644 index 69d6302f40cf..000000000000 --- a/trunk/arch/arm/mach-iop32x/irq.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * arch/arm/mach-iop32x/irq.c - * - * Generic IOP32X IRQ handling functionality - * - * Author: Rory Bolt - * Copyright (C) 2002 Rory Bolt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -static u32 iop32x_mask; - -static inline void intctl_write(u32 val) -{ - iop3xx_cp6_enable(); - asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); -} - -static inline void intstr_write(u32 val) -{ - iop3xx_cp6_enable(); - asm volatile("mcr p6, 0, %0, c4, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); -} - -static void -iop32x_irq_mask(unsigned int irq) -{ - iop32x_mask &= ~(1 << irq); - intctl_write(iop32x_mask); -} - -static void -iop32x_irq_unmask(unsigned int irq) -{ - iop32x_mask |= 1 << irq; - intctl_write(iop32x_mask); -} - -struct irq_chip ext_chip = { - .name = "IOP32x", - .ack = iop32x_irq_mask, - .mask = iop32x_irq_mask, - .unmask = iop32x_irq_unmask, -}; - -void __init iop32x_init_irq(void) -{ - int i; - - intctl_write(0); - intstr_write(0); - if (machine_is_glantank() || - machine_is_iq80321() || - machine_is_iq31244() || - machine_is_n2100()) - *IOP3XX_PCIIRSR = 0x0f; - - for (i = 0; i < NR_IRQS; i++) { - set_irq_chip(i, &ext_chip); - set_irq_handler(i, do_level_IRQ); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - } -} diff --git a/trunk/arch/arm/mach-iop32x/n2100.c b/trunk/arch/arm/mach-iop32x/n2100.c deleted file mode 100644 index a2c94a47b2b2..000000000000 --- a/trunk/arch/arm/mach-iop32x/n2100.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * arch/arm/mach-iop32x/n2100.c - * - * Board support code for the Thecus N2100 platform. - * - * Author: Rory Bolt - * Copyright (C) 2002 Rory Bolt - * Copyright 2003 (c) MontaVista, Software, Inc. - * Copyright (C) 2004 Intel Corp. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * N2100 timer tick configuration. - */ -static void __init n2100_timer_init(void) -{ - /* 33.000 MHz crystal. */ - iop3xx_init_time(198000000); -} - -static struct sys_timer n2100_timer = { - .init = n2100_timer_init, - .offset = iop3xx_gettimeoffset, -}; - - -/* - * N2100 I/O. - */ -static struct map_desc n2100_io_desc[] __initdata = { - { /* on-board devices */ - .virtual = N2100_UART, - .pfn = __phys_to_pfn(N2100_UART), - .length = 0x00100000, - .type = MT_DEVICE - }, -}; - -void __init n2100_map_io(void) -{ - iop3xx_map_io(); - iotable_init(n2100_io_desc, ARRAY_SIZE(n2100_io_desc)); -} - - -/* - * N2100 PCI. - */ -static inline int __init -n2100_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - int irq; - - if (PCI_SLOT(dev->devfn) == 1) { - /* RTL8110SB #1 */ - irq = IRQ_IOP32X_XINT0; - } else if (PCI_SLOT(dev->devfn) == 2) { - /* RTL8110SB #2 */ - irq = IRQ_IOP32X_XINT1; - } else if (PCI_SLOT(dev->devfn) == 3) { - /* Sil3512 */ - irq = IRQ_IOP32X_XINT2; - } else if (PCI_SLOT(dev->devfn) == 4 && pin == 1) { - /* VT6212 INTA */ - irq = IRQ_IOP32X_XINT1; - } else if (PCI_SLOT(dev->devfn) == 4 && pin == 2) { - /* VT6212 INTB */ - irq = IRQ_IOP32X_XINT0; - } else if (PCI_SLOT(dev->devfn) == 4 && pin == 3) { - /* VT6212 INTC */ - irq = IRQ_IOP32X_XINT2; - } else if (PCI_SLOT(dev->devfn) == 5) { - /* Mini-PCI slot */ - irq = IRQ_IOP32X_XINT3; - } else { - printk(KERN_ERR "n2100_pci_map_irq() called for unknown " - "device PCI:%d:%d:%d\n", dev->bus->number, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - irq = -1; - } - - return irq; -} - -static struct hw_pci n2100_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iop3xx_pci_setup, - .preinit = iop3xx_pci_preinit, - .scan = iop3xx_pci_scan_bus, - .map_irq = n2100_pci_map_irq, -}; - -static int __init n2100_pci_init(void) -{ - if (machine_is_n2100()) - pci_common_init(&n2100_pci); - - return 0; -} - -subsys_initcall(n2100_pci_init); - - -/* - * N2100 machine initialisation. - */ -static struct physmap_flash_data n2100_flash_data = { - .width = 2, -}; - -static struct resource n2100_flash_resource = { - .start = 0xf0000000, - .end = 0xf0ffffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device n2100_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &n2100_flash_data, - }, - .num_resources = 1, - .resource = &n2100_flash_resource, -}; - - -static struct plat_serial8250_port n2100_serial_port[] = { - { - .mapbase = N2100_UART, - .membase = (char *)N2100_UART, - .irq = 0, - .flags = UPF_SKIP_TEST, - .iotype = UPIO_MEM, - .regshift = 0, - .uartclk = 1843200, - }, - { }, -}; - -static struct resource n2100_uart_resource = { - .start = N2100_UART, - .end = N2100_UART + 7, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device n2100_serial_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = n2100_serial_port, - }, - .num_resources = 1, - .resource = &n2100_uart_resource, -}; - - -/* - * Pull PCA9532 GPIO #8 low to power off the machine. - */ -static void n2100_power_off(void) -{ - local_irq_disable(); - - /* Start condition, I2C address of PCA9532, write transaction. */ - *IOP3XX_IDBR0 = 0xc0; - *IOP3XX_ICR0 = 0xe9; - mdelay(1); - - /* Write address 0x08. */ - *IOP3XX_IDBR0 = 0x08; - *IOP3XX_ICR0 = 0xe8; - mdelay(1); - - /* Write data 0x01, stop condition. */ - *IOP3XX_IDBR0 = 0x01; - *IOP3XX_ICR0 = 0xea; - - while (1) - ; -} - - -static struct timer_list power_button_poll_timer; - -static void power_button_poll(unsigned long dummy) -{ - if (gpio_line_get(N2100_POWER_BUTTON) == 0) { - ctrl_alt_del(); - return; - } - - power_button_poll_timer.expires = jiffies + (HZ / 10); - add_timer(&power_button_poll_timer); -} - - -static void __init n2100_init_machine(void) -{ - platform_device_register(&iop3xx_i2c0_device); - platform_device_register(&n2100_flash_device); - platform_device_register(&n2100_serial_device); - - pm_power_off = n2100_power_off; - - init_timer(&power_button_poll_timer); - power_button_poll_timer.function = power_button_poll; - power_button_poll_timer.expires = jiffies + (HZ / 10); - add_timer(&power_button_poll_timer); -} - -MACHINE_START(N2100, "Thecus N2100") - /* Maintainer: Lennert Buytenhek */ - .phys_io = N2100_UART, - .io_pg_offst = ((N2100_UART) >> 18) & 0xfffc, - .boot_params = 0xa0000100, - .map_io = n2100_map_io, - .init_irq = iop32x_init_irq, - .timer = &n2100_timer, - .init_machine = n2100_init_machine, -MACHINE_END diff --git a/trunk/arch/arm/mach-iop33x/Kconfig b/trunk/arch/arm/mach-iop33x/Kconfig deleted file mode 100644 index 9aa016bb18f9..000000000000 --- a/trunk/arch/arm/mach-iop33x/Kconfig +++ /dev/null @@ -1,21 +0,0 @@ -if ARCH_IOP33X - -menu "IOP33x Implementation Options" - -comment "IOP33x Platform Types" - -config ARCH_IQ80331 - bool "Enable support for IQ80331" - help - Say Y here if you want to run your kernel on the Intel IQ80331 - evaluation kit for the IOP331 chipset. - -config MACH_IQ80332 - bool "Enable support for IQ80332" - help - Say Y here if you want to run your kernel on the Intel IQ80332 - evaluation kit for the IOP332 chipset. - -endmenu - -endif diff --git a/trunk/arch/arm/mach-iop33x/Makefile b/trunk/arch/arm/mach-iop33x/Makefile deleted file mode 100644 index 90081d8c9d16..000000000000 --- a/trunk/arch/arm/mach-iop33x/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for the linux kernel. -# - -obj-y := irq.o uart.o -obj-m := -obj-n := -obj- := - -obj-$(CONFIG_ARCH_IQ80331) += iq80331.o -obj-$(CONFIG_MACH_IQ80332) += iq80332.o diff --git a/trunk/arch/arm/mach-iop33x/Makefile.boot b/trunk/arch/arm/mach-iop33x/Makefile.boot deleted file mode 100644 index 67039c3e0c48..000000000000 --- a/trunk/arch/arm/mach-iop33x/Makefile.boot +++ /dev/null @@ -1,3 +0,0 @@ - zreladdr-y := 0x00008000 -params_phys-y := 0x00000100 -initrd_phys-y := 0x00800000 diff --git a/trunk/arch/arm/mach-iop33x/iq80331.c b/trunk/arch/arm/mach-iop33x/iq80331.c deleted file mode 100644 index 97a7b7488264..000000000000 --- a/trunk/arch/arm/mach-iop33x/iq80331.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * arch/arm/mach-iop33x/iq80331.c - * - * Board support code for the Intel IQ80331 platform. - * - * Author: Dave Jiang - * Copyright (C) 2003 Intel Corp. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * IQ80331 timer tick configuration. - */ -static void __init iq80331_timer_init(void) -{ - /* D-Step parts run at a higher internal bus frequency */ - if (*IOP3XX_ATURID >= 0xa) - iop3xx_init_time(333000000); - else - iop3xx_init_time(266000000); -} - -static struct sys_timer iq80331_timer = { - .init = iq80331_timer_init, - .offset = iop3xx_gettimeoffset, -}; - - -/* - * IQ80331 PCI. - */ -static inline int __init -iq80331_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - int irq; - - if (slot == 1 && pin == 1) { - /* PCI-X Slot INTA */ - irq = IRQ_IOP33X_XINT1; - } else if (slot == 1 && pin == 2) { - /* PCI-X Slot INTB */ - irq = IRQ_IOP33X_XINT2; - } else if (slot == 1 && pin == 3) { - /* PCI-X Slot INTC */ - irq = IRQ_IOP33X_XINT3; - } else if (slot == 1 && pin == 4) { - /* PCI-X Slot INTD */ - irq = IRQ_IOP33X_XINT0; - } else if (slot == 2) { - /* GigE */ - irq = IRQ_IOP33X_XINT2; - } else { - printk(KERN_ERR "iq80331_pci_map_irq() called for unknown " - "device PCI:%d:%d:%d\n", dev->bus->number, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - irq = -1; - } - - return irq; -} - -static struct hw_pci iq80331_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iop3xx_pci_setup, - .preinit = iop3xx_pci_preinit, - .scan = iop3xx_pci_scan_bus, - .map_irq = iq80331_pci_map_irq, -}; - -static int __init iq80331_pci_init(void) -{ - if (machine_is_iq80331()) - pci_common_init(&iq80331_pci); - - return 0; -} - -subsys_initcall(iq80331_pci_init); - - -/* - * IQ80331 machine initialisation. - */ -static struct physmap_flash_data iq80331_flash_data = { - .width = 1, -}; - -static struct resource iq80331_flash_resource = { - .start = 0xc0000000, - .end = 0xc07fffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device iq80331_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &iq80331_flash_data, - }, - .num_resources = 1, - .resource = &iq80331_flash_resource, -}; - -static void __init iq80331_init_machine(void) -{ - platform_device_register(&iop3xx_i2c0_device); - platform_device_register(&iop3xx_i2c1_device); - platform_device_register(&iop33x_uart0_device); - platform_device_register(&iop33x_uart1_device); - platform_device_register(&iq80331_flash_device); -} - -MACHINE_START(IQ80331, "Intel IQ80331") - /* Maintainer: Intel Corp. */ - .phys_io = 0xfefff000, - .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, - .boot_params = 0x00000100, - .map_io = iop3xx_map_io, - .init_irq = iop33x_init_irq, - .timer = &iq80331_timer, - .init_machine = iq80331_init_machine, -MACHINE_END diff --git a/trunk/arch/arm/mach-iop33x/iq80332.c b/trunk/arch/arm/mach-iop33x/iq80332.c deleted file mode 100644 index 9887bfc1c078..000000000000 --- a/trunk/arch/arm/mach-iop33x/iq80332.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * arch/arm/mach-iop33x/iq80332.c - * - * Board support code for the Intel IQ80332 platform. - * - * Author: Dave Jiang - * Copyright (C) 2004 Intel Corp. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * IQ80332 timer tick configuration. - */ -static void __init iq80332_timer_init(void) -{ - /* D-Step parts and the iop333 run at a higher internal bus frequency */ - if (*IOP3XX_ATURID >= 0xa || *IOP3XX_ATUDID == 0x374) - iop3xx_init_time(333000000); - else - iop3xx_init_time(266000000); -} - -static struct sys_timer iq80332_timer = { - .init = iq80332_timer_init, - .offset = iop3xx_gettimeoffset, -}; - - -/* - * IQ80332 PCI. - */ -static inline int __init -iq80332_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - int irq; - - if (slot == 4 && pin == 1) { - /* PCI-X Slot INTA */ - irq = IRQ_IOP33X_XINT0; - } else if (slot == 4 && pin == 2) { - /* PCI-X Slot INTB */ - irq = IRQ_IOP33X_XINT1; - } else if (slot == 4 && pin == 3) { - /* PCI-X Slot INTC */ - irq = IRQ_IOP33X_XINT2; - } else if (slot == 4 && pin == 4) { - /* PCI-X Slot INTD */ - irq = IRQ_IOP33X_XINT3; - } else if (slot == 6) { - /* GigE */ - irq = IRQ_IOP33X_XINT2; - } else { - printk(KERN_ERR "iq80332_pci_map_irq() called for unknown " - "device PCI:%d:%d:%d\n", dev->bus->number, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); - irq = -1; - } - - return irq; -} - -static struct hw_pci iq80332_pci __initdata = { - .swizzle = pci_std_swizzle, - .nr_controllers = 1, - .setup = iop3xx_pci_setup, - .preinit = iop3xx_pci_preinit, - .scan = iop3xx_pci_scan_bus, - .map_irq = iq80332_pci_map_irq, -}; - -static int __init iq80332_pci_init(void) -{ - if (machine_is_iq80332()) - pci_common_init(&iq80332_pci); - - return 0; -} - -subsys_initcall(iq80332_pci_init); - - -/* - * IQ80332 machine initialisation. - */ -static struct physmap_flash_data iq80332_flash_data = { - .width = 1, -}; - -static struct resource iq80332_flash_resource = { - .start = 0xc0000000, - .end = 0xc07fffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device iq80332_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &iq80332_flash_data, - }, - .num_resources = 1, - .resource = &iq80332_flash_resource, -}; - -static void __init iq80332_init_machine(void) -{ - platform_device_register(&iop3xx_i2c0_device); - platform_device_register(&iop3xx_i2c1_device); - platform_device_register(&iop33x_uart0_device); - platform_device_register(&iop33x_uart1_device); - platform_device_register(&iq80332_flash_device); -} - -MACHINE_START(IQ80332, "Intel IQ80332") - /* Maintainer: Intel Corp. */ - .phys_io = 0xfefff000, - .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, - .boot_params = 0x00000100, - .map_io = iop3xx_map_io, - .init_irq = iop33x_init_irq, - .timer = &iq80332_timer, - .init_machine = iq80332_init_machine, -MACHINE_END diff --git a/trunk/arch/arm/mach-iop33x/irq.c b/trunk/arch/arm/mach-iop33x/irq.c deleted file mode 100644 index 63304b3d0d76..000000000000 --- a/trunk/arch/arm/mach-iop33x/irq.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * arch/arm/mach-iop33x/irq.c - * - * Generic IOP331 IRQ handling functionality - * - * Author: Dave Jiang - * Copyright (C) 2003 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -static u32 iop33x_mask0; -static u32 iop33x_mask1; - -static inline void intctl0_write(u32 val) -{ - iop3xx_cp6_enable(); - asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); -} - -static inline void intctl1_write(u32 val) -{ - iop3xx_cp6_enable(); - asm volatile("mcr p6, 0, %0, c1, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); -} - -static inline void intstr0_write(u32 val) -{ - iop3xx_cp6_enable(); - asm volatile("mcr p6, 0, %0, c2, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); -} - -static inline void intstr1_write(u32 val) -{ - iop3xx_cp6_enable(); - asm volatile("mcr p6, 0, %0, c3, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); -} - -static inline void intbase_write(u32 val) -{ - iop3xx_cp6_enable(); - asm volatile("mcr p6, 0, %0, c12, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); -} - -static inline void intsize_write(u32 val) -{ - iop3xx_cp6_enable(); - asm volatile("mcr p6, 0, %0, c13, c0, 0" : : "r" (val)); - iop3xx_cp6_disable(); -} - -static void -iop33x_irq_mask1 (unsigned int irq) -{ - iop33x_mask0 &= ~(1 << irq); - intctl0_write(iop33x_mask0); -} - -static void -iop33x_irq_mask2 (unsigned int irq) -{ - iop33x_mask1 &= ~(1 << (irq - 32)); - intctl1_write(iop33x_mask1); -} - -static void -iop33x_irq_unmask1(unsigned int irq) -{ - iop33x_mask0 |= 1 << irq; - intctl0_write(iop33x_mask0); -} - -static void -iop33x_irq_unmask2(unsigned int irq) -{ - iop33x_mask1 |= (1 << (irq - 32)); - intctl1_write(iop33x_mask1); -} - -struct irq_chip iop33x_irqchip1 = { - .name = "IOP33x-1", - .ack = iop33x_irq_mask1, - .mask = iop33x_irq_mask1, - .unmask = iop33x_irq_unmask1, -}; - -struct irq_chip iop33x_irqchip2 = { - .name = "IOP33x-2", - .ack = iop33x_irq_mask2, - .mask = iop33x_irq_mask2, - .unmask = iop33x_irq_unmask2, -}; - -void __init iop33x_init_irq(void) -{ - int i; - - intctl0_write(0); - intctl1_write(0); - intstr0_write(0); - intstr1_write(0); - intbase_write(0); - intsize_write(1); - if (machine_is_iq80331()) - *IOP3XX_PCIIRSR = 0x0f; - - for (i = 0; i < NR_IRQS; i++) { - set_irq_chip(i, (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2); - set_irq_handler(i, do_level_IRQ); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - } -} diff --git a/trunk/arch/arm/mach-iop33x/uart.c b/trunk/arch/arm/mach-iop33x/uart.c deleted file mode 100644 index ac297cd0276c..000000000000 --- a/trunk/arch/arm/mach-iop33x/uart.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * arch/arm/mach-iop33x/uart.c - * - * Author: Dave Jiang (dave.jiang@intel.com) - * Copyright (C) 2004 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define IOP33X_UART_XTAL 33334000 - -static struct plat_serial8250_port iop33x_uart0_data[] = { - { - .membase = (char *)IOP33X_UART0_VIRT, - .mapbase = IOP33X_UART0_PHYS, - .irq = IRQ_IOP33X_UART0, - .uartclk = IOP33X_UART_XTAL, - .regshift = 2, - .iotype = UPIO_MEM, - .flags = UPF_SKIP_TEST, - }, - { }, -}; - -static struct resource iop33x_uart0_resources[] = { - [0] = { - .start = IOP33X_UART0_PHYS, - .end = IOP33X_UART0_PHYS + 0x3f, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP33X_UART0, - .end = IRQ_IOP33X_UART0, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device iop33x_uart0_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = iop33x_uart0_data, - }, - .num_resources = 2, - .resource = iop33x_uart0_resources, -}; - - -static struct resource iop33x_uart1_resources[] = { - [0] = { - .start = IOP33X_UART1_PHYS, - .end = IOP33X_UART1_PHYS + 0x3f, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP33X_UART1, - .end = IRQ_IOP33X_UART1, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct plat_serial8250_port iop33x_uart1_data[] = { - { - .membase = (char *)IOP33X_UART1_VIRT, - .mapbase = IOP33X_UART1_PHYS, - .irq = IRQ_IOP33X_UART1, - .uartclk = IOP33X_UART_XTAL, - .regshift = 2, - .iotype = UPIO_MEM, - .flags = UPF_SKIP_TEST, - }, - { }, -}; - -struct platform_device iop33x_uart1_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM1, - .dev = { - .platform_data = iop33x_uart1_data, - }, - .num_resources = 2, - .resource = iop33x_uart1_resources, -}; diff --git a/trunk/arch/arm/mach-iop3xx/Kconfig b/trunk/arch/arm/mach-iop3xx/Kconfig new file mode 100644 index 000000000000..4422f2388607 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/Kconfig @@ -0,0 +1,66 @@ +if ARCH_IOP3XX + +menu "IOP3xx Implementation Options" + +comment "IOP3xx Platform Types" + +config ARCH_IQ80321 + bool "Enable support for IQ80321" + select ARCH_IOP321 + help + Say Y here if you want to run your kernel on the Intel IQ80321 + evaluation kit for the IOP321 chipset. + +config ARCH_IQ31244 + bool "Enable support for IQ31244" + select ARCH_IOP321 + help + Say Y here if you want to run your kernel on the Intel IQ31244 + evaluation kit for the IOP321 chipset. + +config ARCH_IQ80331 + bool "Enable support for IQ80331" + select ARCH_IOP331 + help + Say Y here if you want to run your kernel on the Intel IQ80331 + evaluation kit for the IOP331 chipset. + +config MACH_IQ80332 + bool "Enable support for IQ80332" + select ARCH_IOP331 + help + Say Y here if you want to run your kernel on the Intel IQ80332 + evaluation kit for the IOP332 chipset. + +config ARCH_EP80219 + bool "Enable support for EP80219" + select ARCH_IOP321 + select ARCH_IQ31244 + help + Say Y here if you want to run your kernel on the Intel EP80219 + evaluation kit for the Intel 80219 chipset (a IOP321 variant). + +# Which IOP variant are we running? +config ARCH_IOP321 + bool + help + The IQ80321 uses the IOP321 variant. + The IQ31244 and EP80219 uses the IOP321 variant. + +config ARCH_IOP331 + bool + default ARCH_IQ80331 + help + The IQ80331, IQ80332, and IQ80333 uses the IOP331 variant. + +comment "IOP3xx Chipset Features" + +config IOP331_STEPD + bool "Chip stepping D of the IOP80331 processor or IOP80333" + depends on (ARCH_IOP331) + help + Say Y here if you have StepD of the IOP80331 or IOP8033 + based platforms. + +endmenu +endif diff --git a/trunk/arch/arm/mach-iop3xx/Makefile b/trunk/arch/arm/mach-iop3xx/Makefile new file mode 100644 index 000000000000..b17eb1f46102 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/Makefile @@ -0,0 +1,23 @@ +# +# Makefile for the linux kernel. +# + +# Object file lists. + +obj-y := common.o + +obj-m := +obj-n := +obj- := + +obj-$(CONFIG_ARCH_IOP321) += iop321-setup.o iop321-irq.o iop321-pci.o iop321-time.o + +obj-$(CONFIG_ARCH_IOP331) += iop331-setup.o iop331-irq.o iop331-pci.o iop331-time.o + +obj-$(CONFIG_ARCH_IQ80321) += iq80321-mm.o iq80321-pci.o + +obj-$(CONFIG_ARCH_IQ31244) += iq31244-mm.o iq31244-pci.o + +obj-$(CONFIG_ARCH_IQ80331) += iq80331-mm.o iq80331-pci.o + +obj-$(CONFIG_MACH_IQ80332) += iq80332-mm.o iq80332-pci.o diff --git a/trunk/arch/arm/mach-iop3xx/Makefile.boot b/trunk/arch/arm/mach-iop3xx/Makefile.boot new file mode 100644 index 000000000000..6387aa20461b --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/Makefile.boot @@ -0,0 +1,9 @@ + zreladdr-y := 0xa0008000 +params_phys-y := 0xa0000100 +initrd_phys-y := 0xa0800000 +ifeq ($(CONFIG_ARCH_IOP331),y) + zreladdr-y := 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 +endif + diff --git a/trunk/arch/arm/mach-iop3xx/common.c b/trunk/arch/arm/mach-iop3xx/common.c new file mode 100644 index 000000000000..d7f50e57e753 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/common.c @@ -0,0 +1,72 @@ +/* + * arch/arm/mach-iop3xx/common.c + * + * Common routines shared across all IOP3xx implementations + * + * Author: Deepak Saxena + * + * Copyright 2003 (c) MontaVista, Software, Inc. + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include + +/* + * Shared variables + */ +unsigned long iop3xx_pcibios_min_io = 0; +unsigned long iop3xx_pcibios_min_mem = 0; + +#ifdef CONFIG_ARCH_EP80219 +#include +/* + * Default power-off for EP80219 + */ + +static inline void ep80219_send_to_pic(__u8 c) { +} + +void ep80219_power_off(void) +{ + /* + * This function will send a SHUTDOWN_COMPLETE message to the PIC controller + * over I2C. We are not using the i2c subsystem since we are going to power + * off and it may be removed + */ + + /* Send the Address byte w/ the start condition */ + *IOP321_IDBR1 = 0x60; + *IOP321_ICR1 = 0xE9; + mdelay(1); + + /* Send the START_MSG byte w/ no start or stop condition */ + *IOP321_IDBR1 = 0x0F; + *IOP321_ICR1 = 0xE8; + mdelay(1); + + /* Send the SHUTDOWN_COMPLETE Message ID byte w/ no start or stop condition */ + *IOP321_IDBR1 = 0x03; + *IOP321_ICR1 = 0xE8; + mdelay(1); + + /* Send an ignored byte w/ stop condition */ + *IOP321_IDBR1 = 0x00; + *IOP321_ICR1 = 0xEA; + + while (1) ; +} + +#include +#include + +static int __init ep80219_init(void) +{ + pm_power_off = ep80219_power_off; + return 0; +} +arch_initcall(ep80219_init); +#endif diff --git a/trunk/arch/arm/mach-iop3xx/iop321-irq.c b/trunk/arch/arm/mach-iop3xx/iop321-irq.c new file mode 100644 index 000000000000..88ac333472c8 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iop321-irq.c @@ -0,0 +1,97 @@ +/* + * linux/arch/arm/mach-iop3xx/iop321-irq.c + * + * Generic IOP321 IRQ handling functionality + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Added IOP3XX chipset and IQ80321 board masking code. + * + */ +#include +#include +#include + +#include +#include +#include + +#include + +static u32 iop321_mask /* = 0 */; + +static inline void intctl_write(u32 val) +{ + asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val)); +} + +static inline void intstr_write(u32 val) +{ + asm volatile("mcr p6,0,%0,c4,c0,0"::"r" (val)); +} + +static void +iop321_irq_mask (unsigned int irq) +{ + + iop321_mask &= ~(1 << (irq - IOP321_IRQ_OFS)); + + intctl_write(iop321_mask); +} + +static void +iop321_irq_unmask (unsigned int irq) +{ + iop321_mask |= (1 << (irq - IOP321_IRQ_OFS)); + + intctl_write(iop321_mask); +} + +struct irq_chip ext_chip = { + .name = "IOP", + .ack = iop321_irq_mask, + .mask = iop321_irq_mask, + .unmask = iop321_irq_unmask, +}; + +void __init iop321_init_irq(void) +{ + unsigned int i, tmp; + + /* Enable access to coprocessor 6 for dealing with IRQs. + * From RMK: + * Basically, the Intel documentation here is poor. It appears that + * you need to set the bit to be able to access the coprocessor from + * SVC mode. Whether that allows access from user space or not is + * unclear. + */ + asm volatile ( + "mrc p15, 0, %0, c15, c1, 0\n\t" + "orr %0, %0, %1\n\t" + "mcr p15, 0, %0, c15, c1, 0\n\t" + /* The action is delayed, so we have to do this: */ + "mrc p15, 0, %0, c15, c1, 0\n\t" + "mov %0, %0\n\t" + "sub pc, pc, #4" + : "=r" (tmp) : "i" (1 << 6) ); + + intctl_write(0); // disable all interrupts + intstr_write(0); // treat all as IRQ + if(machine_is_iq80321() || + machine_is_iq31244()) // all interrupts are inputs to chip + *IOP321_PCIIRSR = 0x0f; + + for(i = IOP321_IRQ_OFS; i < NR_IOP321_IRQS; i++) + { + set_irq_chip(i, &ext_chip); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + + } +} + diff --git a/trunk/arch/arm/mach-iop3xx/iop321-pci.c b/trunk/arch/arm/mach-iop3xx/iop321-pci.c new file mode 100644 index 000000000000..8ba6a0e23134 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iop321-pci.c @@ -0,0 +1,220 @@ +/* + * arch/arm/mach-iop3xx/iop321-pci.c + * + * PCI support for the Intel IOP321 chipset + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +// #define DEBUG + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) do { } while (0) +#endif + +/* + * This routine builds either a type0 or type1 configuration command. If the + * bus is on the 80321 then a type0 made, else a type1 is created. + */ +static u32 iop321_cfg_address(struct pci_bus *bus, int devfn, int where) +{ + struct pci_sys_data *sys = bus->sysdata; + u32 addr; + + if (sys->busnr == bus->number) + addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11); + else + addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1; + + addr |= PCI_FUNC(devfn) << 8 | (where & ~3); + + return addr; +} + +/* + * This routine checks the status of the last configuration cycle. If an error + * was detected it returns a 1, else it returns a 0. The errors being checked + * are parity, master abort, target abort (master and target). These types of + * errors occure during a config cycle where there is no device, like during + * the discovery stage. + */ +static int iop321_pci_status(void) +{ + unsigned int status; + int ret = 0; + + /* + * Check the status registers. + */ + status = *IOP321_ATUSR; + if (status & 0xf900) + { + DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status); + *IOP321_ATUSR = status & 0xf900; + ret = 1; + } + status = *IOP321_ATUISR; + if (status & 0x679f) + { + DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status); + *IOP321_ATUISR = status & 0x679f; + ret = 1; + } + return ret; +} + +/* + * Simply write the address register and read the configuration + * data. Note that the 4 nop's ensure that we are able to handle + * a delayed abort (in theory.) + */ +static inline u32 iop321_read(unsigned long addr) +{ + u32 val; + + __asm__ __volatile__( + "str %1, [%2]\n\t" + "ldr %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : "=r" (val) + : "r" (addr), "r" (IOP321_OCCAR), "r" (IOP321_OCCDR)); + + return val; +} + +/* + * The read routines must check the error status of the last configuration + * cycle. If there was an error, the routine returns all hex f's. + */ +static int +iop321_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + unsigned long addr = iop321_cfg_address(bus, devfn, where); + u32 val = iop321_read(addr) >> ((where & 3) * 8); + + if( iop321_pci_status() ) + val = 0xffffffff; + + *value = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int +iop321_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + unsigned long addr = iop321_cfg_address(bus, devfn, where); + u32 val; + + if (size != 4) { + val = iop321_read(addr); + if (!iop321_pci_status() == 0) + return PCIBIOS_SUCCESSFUL; + + where = (where & 3) * 8; + + if (size == 1) + val &= ~(0xff << where); + else + val &= ~(0xffff << where); + + *IOP321_OCCDR = val | value << where; + } else { + asm volatile( + "str %1, [%2]\n\t" + "str %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : + : "r" (value), "r" (addr), + "r" (IOP321_OCCAR), "r" (IOP321_OCCDR)); + } + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops iop321_ops = { + .read = iop321_read_config, + .write = iop321_write_config, +}; + +/* + * When a PCI device does not exist during config cycles, the 80200 gets a + * bus error instead of returning 0xffffffff. This handler simply returns. + */ +int +iop321_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n", + addr, fsr, regs->ARM_pc, regs->ARM_lr); + + /* + * If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) + regs->ARM_pc += 4; + + return 0; +} + +/* + * Scan an IOP321 PCI bus. sys->bus defines which bus we scan. + */ +struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_bus(sys->busnr, &iop321_ops, sys); +} + +void iop321_init(void) +{ + DBG("PCI: Intel 80321 PCI init code.\n"); + DBG("ATU: IOP321_ATUCMD=0x%04x\n", *IOP321_ATUCMD); + DBG("ATU: IOP321_OMWTVR0=0x%04x, IOP321_OIOWTVR=0x%04x\n", + *IOP321_OMWTVR0, + *IOP321_OIOWTVR); + DBG("ATU: IOP321_ATUCR=0x%08x\n", *IOP321_ATUCR); + DBG("ATU: IOP321_IABAR0=0x%08x IOP321_IALR0=0x%08x IOP321_IATVR0=%08x\n", + *IOP321_IABAR0, *IOP321_IALR0, *IOP321_IATVR0); + DBG("ATU: IOP321_OMWTVR0=0x%08x\n", *IOP321_OMWTVR0); + DBG("ATU: IOP321_IABAR1=0x%08x IOP321_IALR1=0x%08x\n", + *IOP321_IABAR1, *IOP321_IALR1); + DBG("ATU: IOP321_ERBAR=0x%08x IOP321_ERLR=0x%08x IOP321_ERTVR=%08x\n", + *IOP321_ERBAR, *IOP321_ERLR, *IOP321_ERTVR); + DBG("ATU: IOP321_IABAR2=0x%08x IOP321_IALR2=0x%08x IOP321_IATVR2=%08x\n", + *IOP321_IABAR2, *IOP321_IALR2, *IOP321_IATVR2); + DBG("ATU: IOP321_IABAR3=0x%08x IOP321_IALR3=0x%08x IOP321_IATVR3=%08x\n", + *IOP321_IABAR3, *IOP321_IALR3, *IOP321_IATVR3); + + hook_fault_code(16+6, iop321_pci_abort, SIGBUS, "imprecise external abort"); +} + diff --git a/trunk/arch/arm/mach-iop3xx/iop321-setup.c b/trunk/arch/arm/mach-iop3xx/iop321-setup.c new file mode 100644 index 000000000000..b6d096903c4a --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iop321-setup.c @@ -0,0 +1,173 @@ +/* + * linux/arch/arm/mach-iop3xx/iop321-setup.c + * + * Author: Nicolas Pitre + * Copyright (C) 2001 MontaVista Software, Inc. + * Copyright (C) 2004 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IOP321_UART_XTAL 1843200 + +/* + * Standard IO mapping for all IOP321 based systems + */ +static struct map_desc iop321_std_desc[] __initdata = { + { /* mem mapped registers */ + .virtual = IOP321_VIRT_MEM_BASE, + .pfn = __phys_to_pfn(IOP321_PHYS_MEM_BASE), + .length = 0x00002000, + .type = MT_DEVICE + }, { /* PCI IO space */ + .virtual = IOP321_PCI_LOWER_IO_VA, + .pfn = __phys_to_pfn(IOP321_PCI_LOWER_IO_PA), + .length = IOP321_PCI_IO_WINDOW_SIZE, + .type = MT_DEVICE + } +}; + +#ifdef CONFIG_ARCH_IQ80321 +#define UARTBASE IQ80321_UART +#define IRQ_UART IRQ_IQ80321_UART +#endif + +#ifdef CONFIG_ARCH_IQ31244 +#define UARTBASE IQ31244_UART +#define IRQ_UART IRQ_IQ31244_UART +#endif + +static struct uart_port iop321_serial_ports[] = { + { + .membase = (char*)(UARTBASE), + .mapbase = (UARTBASE), + .irq = IRQ_UART, + .flags = UPF_SKIP_TEST, + .iotype = UPIO_MEM, + .regshift = 0, + .uartclk = IOP321_UART_XTAL, + .line = 0, + .type = PORT_16550A, + .fifosize = 16 + } +}; + +static struct resource iop32x_i2c_0_resources[] = { + [0] = { + .start = 0xfffff680, + .end = 0xfffff698, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP321_I2C_0, + .end = IRQ_IOP321_I2C_0, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop32x_i2c_1_resources[] = { + [0] = { + .start = 0xfffff6a0, + .end = 0xfffff6b8, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP321_I2C_1, + .end = IRQ_IOP321_I2C_1, + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device iop32x_i2c_0_controller = { + .name = "IOP3xx-I2C", + .id = 0, + .num_resources = 2, + .resource = iop32x_i2c_0_resources +}; + +static struct platform_device iop32x_i2c_1_controller = { + .name = "IOP3xx-I2C", + .id = 1, + .num_resources = 2, + .resource = iop32x_i2c_1_resources +}; + +static struct platform_device *iop32x_devices[] __initdata = { + &iop32x_i2c_0_controller, + &iop32x_i2c_1_controller +}; + +void __init iop32x_init(void) +{ + if(iop_is_321()) + { + platform_add_devices(iop32x_devices, + ARRAY_SIZE(iop32x_devices)); + } +} + +void __init iop321_map_io(void) +{ + iotable_init(iop321_std_desc, ARRAY_SIZE(iop321_std_desc)); + early_serial_setup(&iop321_serial_ports[0]); +} + +#ifdef CONFIG_ARCH_IQ80321 +extern void iq80321_map_io(void); +extern struct sys_timer iop321_timer; +extern void iop321_init_time(void); +#endif + +#ifdef CONFIG_ARCH_IQ31244 +extern void iq31244_map_io(void); +extern struct sys_timer iop321_timer; +extern void iop321_init_time(void); +#endif + +#if defined(CONFIG_ARCH_IQ80321) +MACHINE_START(IQ80321, "Intel IQ80321") + /* Maintainer: Intel Corporation */ + .phys_io = IQ80321_UART, + .io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc, + .map_io = iq80321_map_io, + .init_irq = iop321_init_irq, + .timer = &iop321_timer, + .boot_params = 0xa0000100, + .init_machine = iop32x_init, +MACHINE_END +#elif defined(CONFIG_ARCH_IQ31244) +MACHINE_START(IQ31244, "Intel IQ31244") + /* Maintainer: Intel Corp. */ + .phys_io = IQ31244_UART, + .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc, + .map_io = iq31244_map_io, + .init_irq = iop321_init_irq, + .timer = &iop321_timer, + .boot_params = 0xa0000100, + .init_machine = iop32x_init, +MACHINE_END +#else +#error No machine descriptor defined for this IOP3XX implementation +#endif diff --git a/trunk/arch/arm/mach-iop3xx/iop321-time.c b/trunk/arch/arm/mach-iop3xx/iop321-time.c new file mode 100644 index 000000000000..04b1a6f7ebae --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iop321-time.c @@ -0,0 +1,108 @@ +/* + * arch/arm/mach-iop3xx/iop321-time.c + * + * Timer code for IOP321 based systems + * + * Author: Deepak Saxena + * + * Copyright 2002-2003 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define IOP321_TIME_SYNC 0 + +static inline unsigned long get_elapsed(void) +{ + return LATCH - *IOP321_TU_TCR0; +} + +static unsigned long iop321_gettimeoffset(void) +{ + unsigned long elapsed, usec; + u32 tisr1, tisr2; + + /* + * If an interrupt was pending before we read the timer, + * we've already wrapped. Factor this into the time. + * If an interrupt was pending after we read the timer, + * it may have wrapped between checking the interrupt + * status and reading the timer. Re-read the timer to + * be sure its value is after the wrap. + */ + + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1)); + elapsed = get_elapsed(); + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2)); + + if(tisr1 & 1) + elapsed += LATCH; + else if (tisr2 & 1) + elapsed = LATCH + get_elapsed(); + + /* + * Now convert them to usec. + */ + usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000)); + + return usec; +} + +static irqreturn_t +iop321_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + u32 tisr; + + write_seqlock(&xtime_lock); + + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr)); + tisr |= 1; + asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr)); + + timer_tick(regs); + + write_sequnlock(&xtime_lock); + + return IRQ_HANDLED; +} + +static struct irqaction iop321_timer_irq = { + .name = "IOP321 Timer Tick", + .handler = iop321_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_TIMER, +}; + +static void __init iop321_timer_init(void) +{ + u32 timer_ctl; + + setup_irq(IRQ_IOP321_TIMER0, &iop321_timer_irq); + + timer_ctl = IOP321_TMR_EN | IOP321_TMR_PRIVILEGED | IOP321_TMR_RELOAD | + IOP321_TMR_RATIO_1_1; + + asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH)); + + asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); +} + +struct sys_timer iop321_timer = { + .init = &iop321_timer_init, + .offset = iop321_gettimeoffset, +}; diff --git a/trunk/arch/arm/mach-iop3xx/iop331-irq.c b/trunk/arch/arm/mach-iop3xx/iop331-irq.c new file mode 100644 index 000000000000..cab11722ced2 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iop331-irq.c @@ -0,0 +1,129 @@ +/* + * linux/arch/arm/mach-iop3xx/iop331-irq.c + * + * Generic IOP331 IRQ handling functionality + * + * Author: Dave Jiang + * Copyright (C) 2003 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * + */ +#include +#include +#include + +#include +#include +#include + +#include + +static u32 iop331_mask0 = 0; +static u32 iop331_mask1 = 0; + +static inline void intctl_write0(u32 val) +{ + // INTCTL0 + asm volatile("mcr p6,0,%0,c0,c0,0"::"r" (val)); +} + +static inline void intctl_write1(u32 val) +{ + // INTCTL1 + asm volatile("mcr p6,0,%0,c1,c0,0"::"r" (val)); +} + +static inline void intstr_write0(u32 val) +{ + // INTSTR0 + asm volatile("mcr p6,0,%0,c2,c0,0"::"r" (val)); +} + +static inline void intstr_write1(u32 val) +{ + // INTSTR1 + asm volatile("mcr p6,0,%0,c3,c0,0"::"r" (val)); +} + +static void +iop331_irq_mask1 (unsigned int irq) +{ + iop331_mask0 &= ~(1 << (irq - IOP331_IRQ_OFS)); + intctl_write0(iop331_mask0); +} + +static void +iop331_irq_mask2 (unsigned int irq) +{ + iop331_mask1 &= ~(1 << (irq - IOP331_IRQ_OFS - 32)); + intctl_write1(iop331_mask1); +} + +static void +iop331_irq_unmask1(unsigned int irq) +{ + iop331_mask0 |= (1 << (irq - IOP331_IRQ_OFS)); + intctl_write0(iop331_mask0); +} + +static void +iop331_irq_unmask2(unsigned int irq) +{ + iop331_mask1 |= (1 << (irq - IOP331_IRQ_OFS - 32)); + intctl_write1(iop331_mask1); +} + +struct irq_chip iop331_irqchip1 = { + .name = "IOP-1", + .ack = iop331_irq_mask1, + .mask = iop331_irq_mask1, + .unmask = iop331_irq_unmask1, +}; + +struct irq_chip iop331_irqchip2 = { + .name = "IOP-2", + .ack = iop331_irq_mask2, + .mask = iop331_irq_mask2, + .unmask = iop331_irq_unmask2, +}; + +void __init iop331_init_irq(void) +{ + unsigned int i, tmp; + + /* Enable access to coprocessor 6 for dealing with IRQs. + * From RMK: + * Basically, the Intel documentation here is poor. It appears that + * you need to set the bit to be able to access the coprocessor from + * SVC mode. Whether that allows access from user space or not is + * unclear. + */ + asm volatile ( + "mrc p15, 0, %0, c15, c1, 0\n\t" + "orr %0, %0, %1\n\t" + "mcr p15, 0, %0, c15, c1, 0\n\t" + /* The action is delayed, so we have to do this: */ + "mrc p15, 0, %0, c15, c1, 0\n\t" + "mov %0, %0\n\t" + "sub pc, pc, #4" + : "=r" (tmp) : "i" (1 << 6) ); + + intctl_write0(0); // disable all interrupts + intctl_write1(0); + intstr_write0(0); // treat all as IRQ + intstr_write1(0); + if(machine_is_iq80331()) // all interrupts are inputs to chip + *IOP331_PCIIRSR = 0x0f; + + for(i = IOP331_IRQ_OFS; i < NR_IOP331_IRQS; i++) + { + set_irq_chip(i, (i < 32) ? &iop331_irqchip1 : &iop331_irqchip2); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } +} + diff --git a/trunk/arch/arm/mach-iop3xx/iop331-pci.c b/trunk/arch/arm/mach-iop3xx/iop331-pci.c new file mode 100644 index 000000000000..44dd213b48a3 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iop331-pci.c @@ -0,0 +1,222 @@ +/* + * arch/arm/mach-iop3xx/iop331-pci.c + * + * PCI support for the Intel IOP331 chipset + * + * Author: Dave Jiang (dave.jiang@intel.com) + * Copyright (C) 2003, 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#undef DEBUG +#undef DEBUG1 + +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) do { } while (0) +#endif + +#ifdef DEBUG1 +#define DBG1(x...) printk(x) +#else +#define DBG1(x...) do { } while (0) +#endif + +/* + * This routine builds either a type0 or type1 configuration command. If the + * bus is on the 80331 then a type0 made, else a type1 is created. + */ +static u32 iop331_cfg_address(struct pci_bus *bus, int devfn, int where) +{ + struct pci_sys_data *sys = bus->sysdata; + u32 addr; + + if (sys->busnr == bus->number) + addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11); + else + addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1; + + addr |= PCI_FUNC(devfn) << 8 | (where & ~3); + + return addr; +} + +/* + * This routine checks the status of the last configuration cycle. If an error + * was detected it returns a 1, else it returns a 0. The errors being checked + * are parity, master abort, target abort (master and target). These types of + * errors occure during a config cycle where there is no device, like during + * the discovery stage. + */ +static int iop331_pci_status(void) +{ + unsigned int status; + int ret = 0; + + /* + * Check the status registers. + */ + status = *IOP331_ATUSR; + if (status & 0xf900) + { + DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status); + *IOP331_ATUSR = status & 0xf900; + ret = 1; + } + status = *IOP331_ATUISR; + if (status & 0x679f) + { + DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status); + *IOP331_ATUISR = status & 0x679f; + ret = 1; + } + return ret; +} + +/* + * Simply write the address register and read the configuration + * data. Note that the 4 nop's ensure that we are able to handle + * a delayed abort (in theory.) + */ +static inline u32 iop331_read(unsigned long addr) +{ + u32 val; + + __asm__ __volatile__( + "str %1, [%2]\n\t" + "ldr %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : "=r" (val) + : "r" (addr), "r" (IOP331_OCCAR), "r" (IOP331_OCCDR)); + + return val; +} + +/* + * The read routines must check the error status of the last configuration + * cycle. If there was an error, the routine returns all hex f's. + */ +static int +iop331_read_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 *value) +{ + unsigned long addr = iop331_cfg_address(bus, devfn, where); + u32 val = iop331_read(addr) >> ((where & 3) * 8); + + if( iop331_pci_status() ) + val = 0xffffffff; + + *value = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int +iop331_write_config(struct pci_bus *bus, unsigned int devfn, int where, + int size, u32 value) +{ + unsigned long addr = iop331_cfg_address(bus, devfn, where); + u32 val; + + if (size != 4) { + val = iop331_read(addr); + if (!iop331_pci_status() == 0) + return PCIBIOS_SUCCESSFUL; + + where = (where & 3) * 8; + + if (size == 1) + val &= ~(0xff << where); + else + val &= ~(0xffff << where); + + *IOP331_OCCDR = val | value << where; + } else { + asm volatile( + "str %1, [%2]\n\t" + "str %0, [%3]\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + : + : "r" (value), "r" (addr), + "r" (IOP331_OCCAR), "r" (IOP331_OCCDR)); + } + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops iop331_ops = { + .read = iop331_read_config, + .write = iop331_write_config, +}; + +/* + * When a PCI device does not exist during config cycles, the XScale gets a + * bus error instead of returning 0xffffffff. This handler simply returns. + */ +int +iop331_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +{ + DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n", + addr, fsr, regs->ARM_pc, regs->ARM_lr); + + /* + * If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) + regs->ARM_pc += 4; + + return 0; +} + +/* + * Scan an IOP331 PCI bus. sys->bus defines which bus we scan. + */ +struct pci_bus *iop331_scan_bus(int nr, struct pci_sys_data *sys) +{ + return pci_scan_bus(sys->busnr, &iop331_ops, sys); +} + +void iop331_init(void) +{ + DBG1("PCI: Intel 80331 PCI init code.\n"); + DBG1("\tATU: IOP331_ATUCMD=0x%04x\n", *IOP331_ATUCMD); + DBG1("\tATU: IOP331_OMWTVR0=0x%04x, IOP331_OIOWTVR=0x%04x\n", + *IOP331_OMWTVR0, + *IOP331_OIOWTVR); + DBG1("\tATU: IOP331_OMWTVR1=0x%04x\n", *IOP331_OMWTVR1); + DBG1("\tATU: IOP331_ATUCR=0x%08x\n", *IOP331_ATUCR); + DBG1("\tATU: IOP331_IABAR0=0x%08x IOP331_IALR0=0x%08x IOP331_IATVR0=%08x\n", *IOP331_IABAR0, *IOP331_IALR0, *IOP331_IATVR0); + DBG1("\tATU: IOP31_IABAR1=0x%08x IOP331_IALR1=0x%08x\n", *IOP331_IABAR1, *IOP331_IALR1); + DBG1("\tATU: IOP331_ERBAR=0x%08x IOP331_ERLR=0x%08x IOP331_ERTVR=%08x\n", *IOP331_ERBAR, *IOP331_ERLR, *IOP331_ERTVR); + DBG1("\tATU: IOP331_IABAR2=0x%08x IOP331_IALR2=0x%08x IOP331_IATVR2=%08x\n", *IOP331_IABAR2, *IOP331_IALR2, *IOP331_IATVR2); + DBG1("\tATU: IOP331_IABAR3=0x%08x IOP331_IALR3=0x%08x IOP331_IATVR3=%08x\n", *IOP331_IABAR3, *IOP331_IALR3, *IOP331_IATVR3); + + hook_fault_code(16+6, iop331_pci_abort, SIGBUS, "imprecise external abort"); +} + diff --git a/trunk/arch/arm/mach-iop3xx/iop331-setup.c b/trunk/arch/arm/mach-iop3xx/iop331-setup.c new file mode 100644 index 000000000000..3cc98d892ad4 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iop331-setup.c @@ -0,0 +1,221 @@ +/* + * linux/arch/arm/mach-iop3xx/iop331-setup.c + * + * Author: Dave Jiang (dave.jiang@intel.com) + * Copyright (C) 2004 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IOP331_UART_XTAL 33334000 + +/* + * Standard IO mapping for all IOP331 based systems + */ +static struct map_desc iop331_std_desc[] __initdata = { + { /* mem mapped registers */ + .virtual = IOP331_VIRT_MEM_BASE, + .pfn = __phys_to_pfn(IOP331_PHYS_MEM_BASE), + .length = 0x00002000, + .type = MT_DEVICE + }, { /* PCI IO space */ + .virtual = IOP331_PCI_LOWER_IO_VA, + .pfn = __phys_to_pfn(IOP331_PCI_LOWER_IO_PA), + .length = IOP331_PCI_IO_WINDOW_SIZE, + .type = MT_DEVICE + } +}; + +static struct resource iop33x_uart0_resources[] = { + [0] = { + .start = IOP331_UART0_PHYS, + .end = IOP331_UART0_PHYS + 0x3f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP331_UART0, + .end = IRQ_IOP331_UART0, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop33x_uart1_resources[] = { + [0] = { + .start = IOP331_UART1_PHYS, + .end = IOP331_UART1_PHYS + 0x3f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP331_UART1, + .end = IRQ_IOP331_UART1, + .flags = IORESOURCE_IRQ + } +}; + +static struct plat_serial8250_port iop33x_uart0_data[] = { + { + .membase = (char*)(IOP331_UART0_VIRT), + .mapbase = (IOP331_UART0_PHYS), + .irq = IRQ_IOP331_UART0, + .uartclk = IOP331_UART_XTAL, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_SKIP_TEST, + }, + { }, +}; + +static struct plat_serial8250_port iop33x_uart1_data[] = { + { + .membase = (char*)(IOP331_UART1_VIRT), + .mapbase = (IOP331_UART1_PHYS), + .irq = IRQ_IOP331_UART1, + .uartclk = IOP331_UART_XTAL, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device iop33x_uart0 = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev.platform_data = iop33x_uart0_data, + .num_resources = 2, + .resource = iop33x_uart0_resources, +}; + +static struct platform_device iop33x_uart1 = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM1, + .dev.platform_data = iop33x_uart1_data, + .num_resources = 2, + .resource = iop33x_uart1_resources, +}; + +static struct resource iop33x_i2c_0_resources[] = { + [0] = { + .start = 0xfffff680, + .end = 0xfffff698, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP331_I2C_0, + .end = IRQ_IOP331_I2C_0, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop33x_i2c_1_resources[] = { + [0] = { + .start = 0xfffff6a0, + .end = 0xfffff6b8, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP331_I2C_1, + .end = IRQ_IOP331_I2C_1, + .flags = IORESOURCE_IRQ + } +}; + +static struct platform_device iop33x_i2c_0_controller = { + .name = "IOP3xx-I2C", + .id = 0, + .num_resources = 2, + .resource = iop33x_i2c_0_resources +}; + +static struct platform_device iop33x_i2c_1_controller = { + .name = "IOP3xx-I2C", + .id = 1, + .num_resources = 2, + .resource = iop33x_i2c_1_resources +}; + +static struct platform_device *iop33x_devices[] __initdata = { + &iop33x_uart0, + &iop33x_uart1, + &iop33x_i2c_0_controller, + &iop33x_i2c_1_controller +}; + +void __init iop33x_init(void) +{ + if(iop_is_331()) + { + platform_add_devices(iop33x_devices, + ARRAY_SIZE(iop33x_devices)); + } +} + +void __init iop331_map_io(void) +{ + iotable_init(iop331_std_desc, ARRAY_SIZE(iop331_std_desc)); +} + +#ifdef CONFIG_ARCH_IOP331 +extern void iop331_init_irq(void); +extern struct sys_timer iop331_timer; +#endif + +#ifdef CONFIG_ARCH_IQ80331 +extern void iq80331_map_io(void); +#endif + +#ifdef CONFIG_MACH_IQ80332 +extern void iq80332_map_io(void); +#endif + +#if defined(CONFIG_ARCH_IQ80331) +MACHINE_START(IQ80331, "Intel IQ80331") + /* Maintainer: Intel Corp. */ + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical + .map_io = iq80331_map_io, + .init_irq = iop331_init_irq, + .timer = &iop331_timer, + .boot_params = 0x0100, + .init_machine = iop33x_init, +MACHINE_END + +#elif defined(CONFIG_MACH_IQ80332) +MACHINE_START(IQ80332, "Intel IQ80332") + /* Maintainer: Intel Corp. */ + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical + .map_io = iq80332_map_io, + .init_irq = iop331_init_irq, + .timer = &iop331_timer, + .boot_params = 0x0100, + .init_machine = iop33x_init, +MACHINE_END + +#else +#error No machine descriptor defined for this IOP3XX implementation +#endif + + diff --git a/trunk/arch/arm/mach-iop3xx/iop331-time.c b/trunk/arch/arm/mach-iop3xx/iop331-time.c new file mode 100644 index 000000000000..0c09e74c5740 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iop331-time.c @@ -0,0 +1,106 @@ +/* + * arch/arm/mach-iop3xx/iop331-time.c + * + * Timer code for IOP331 based systems + * + * Author: Dave Jiang + * + * Copyright 2003 Intel Corp. + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static inline unsigned long get_elapsed(void) +{ + return LATCH - *IOP331_TU_TCR0; +} + +static unsigned long iop331_gettimeoffset(void) +{ + unsigned long elapsed, usec; + u32 tisr1, tisr2; + + /* + * If an interrupt was pending before we read the timer, + * we've already wrapped. Factor this into the time. + * If an interrupt was pending after we read the timer, + * it may have wrapped between checking the interrupt + * status and reading the timer. Re-read the timer to + * be sure its value is after the wrap. + */ + + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr1)); + elapsed = get_elapsed(); + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr2)); + + if(tisr1 & 1) + elapsed += LATCH; + else if (tisr2 & 1) + elapsed = LATCH + get_elapsed(); + + /* + * Now convert them to usec. + */ + usec = (unsigned long)(elapsed / (CLOCK_TICK_RATE/1000000)); + + return usec; +} + +static irqreturn_t +iop331_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + u32 tisr; + + write_seqlock(&xtime_lock); + + asm volatile("mrc p6, 0, %0, c6, c1, 0" : "=r" (tisr)); + tisr |= 1; + asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (tisr)); + + timer_tick(regs); + + write_sequnlock(&xtime_lock); + return IRQ_HANDLED; +} + +static struct irqaction iop331_timer_irq = { + .name = "IOP331 Timer Tick", + .handler = iop331_timer_interrupt, + .flags = IRQF_DISABLED | IRQF_TIMER, +}; + +static void __init iop331_timer_init(void) +{ + u32 timer_ctl; + + setup_irq(IRQ_IOP331_TIMER0, &iop331_timer_irq); + + timer_ctl = IOP331_TMR_EN | IOP331_TMR_PRIVILEGED | IOP331_TMR_RELOAD | + IOP331_TMR_RATIO_1_1; + + asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (LATCH)); + + asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); + +} + +struct sys_timer iop331_timer = { + .init = iop331_timer_init, + .offset = iop331_gettimeoffset, +}; diff --git a/trunk/arch/arm/mach-iop3xx/iq31244-mm.c b/trunk/arch/arm/mach-iop3xx/iq31244-mm.c new file mode 100644 index 000000000000..e874b54eefe3 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iq31244-mm.c @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/mach-iop3xx/mm.c + * + * Low level memory initialization for iq80321 platform + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * + * 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. + * + */ + +#include +#include + +#include +#include +#include + +#include + + +/* + * IQ80321 specific IO mappings + * + * We use RedBoot's setup for the onboard devices. + */ +static struct map_desc iq31244_io_desc[] __initdata = { + { /* on-board devices */ + .virtual = IQ31244_UART, + .pfn = __phys_to_pfn(IQ31244_UART), + .length = 0x00100000, + .type = MT_DEVICE + } +}; + +void __init iq31244_map_io(void) +{ + iop321_map_io(); + + iotable_init(iq31244_io_desc, ARRAY_SIZE(iq31244_io_desc)); +} diff --git a/trunk/arch/arm/mach-iop3xx/iq31244-pci.c b/trunk/arch/arm/mach-iop3xx/iq31244-pci.c new file mode 100644 index 000000000000..f3c6413fa5bd --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iq31244-pci.c @@ -0,0 +1,129 @@ +/* + * arch/arm/mach-iop3xx/iq80321-pci.c + * + * PCI support for the Intel IQ80321 reference board + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * Copyright (C) 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * The following macro is used to lookup irqs in a standard table + * format for those systems that do not already have PCI + * interrupts properly routed. We assume 1 <= pin <= 4 + */ +#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ +({ int _ctl_ = -1; \ + unsigned int _idsel = idsel - minid; \ + if (_idsel <= maxid) \ + _ctl_ = pci_irq_table[_idsel][pin-1]; \ + _ctl_; }) + +#define INTA IRQ_IQ31244_INTA +#define INTB IRQ_IQ31244_INTB +#define INTC IRQ_IQ31244_INTC +#define INTD IRQ_IQ31244_INTD + +#define INTE IRQ_IQ31244_I82546 + +static inline int __init +iq31244_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + static int pci_irq_table[][4] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ +#ifdef CONFIG_ARCH_EP80219 + {INTB, INTB, INTB, INTB}, /* CFlash */ + {INTE, INTE, INTE, INTE}, /* 82551 Pro 100 */ + {INTD, INTD, INTD, INTD}, /* PCI-X Slot */ + {INTC, INTC, INTC, INTC}, /* SATA */ +#else + {INTB, INTB, INTB, INTB}, /* CFlash */ + {INTC, INTC, INTC, INTC}, /* SATA */ + {INTD, INTD, INTD, INTD}, /* PCI-X Slot */ + {INTE, INTE, INTE, INTE}, /* 82546 GigE */ +#endif // CONFIG_ARCH_EP80219 + }; + + BUG_ON(pin < 1 || pin > 4); + + return PCI_IRQ_TABLE_LOOKUP(0, 7); +} + +static int iq31244_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if(nr != 0) + return 0; + + res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + res[0].start = IOP321_PCI_LOWER_IO_VA; + res[0].end = IOP321_PCI_UPPER_IO_VA; + res[0].name = "IQ31244 PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP321_PCI_LOWER_MEM_PA; + res[1].end = IOP321_PCI_UPPER_MEM_PA; + res[1].name = "IQ31244 PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->mem_offset = IOP321_PCI_MEM_OFFSET; + sys->io_offset = IOP321_PCI_IO_OFFSET; + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +static void iq31244_preinit(void) +{ + iop321_init(); +} + +static struct hw_pci iq31244_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iq31244_setup, + .scan = iop321_scan_bus, + .preinit = iq31244_preinit, + .map_irq = iq31244_map_irq +}; + +static int __init iq31244_pci_init(void) +{ + if (machine_is_iq31244()) + pci_common_init(&iq31244_pci); + return 0; +} + +subsys_initcall(iq31244_pci_init); + + + + diff --git a/trunk/arch/arm/mach-iop3xx/iq80321-mm.c b/trunk/arch/arm/mach-iop3xx/iq80321-mm.c new file mode 100644 index 000000000000..d9cac5e1fc3d --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iq80321-mm.c @@ -0,0 +1,45 @@ +/* + * linux/arch/arm/mach-iop3xx/mm.c + * + * Low level memory initialization for iq80321 platform + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * + * 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. + * + */ + +#include +#include + +#include +#include +#include + +#include + + +/* + * IQ80321 specific IO mappings + * + * We use RedBoot's setup for the onboard devices. + */ +static struct map_desc iq80321_io_desc[] __initdata = { + { /* on-board devices */ + .virtual = IQ80321_UART, + .pfn = __phys_to_pfn(IQ80321_UART), + .length = 0x00100000, + .type = MT_DEVICE + } +}; + +void __init iq80321_map_io(void) +{ + iop321_map_io(); + + iotable_init(iq80321_io_desc, ARRAY_SIZE(iq80321_io_desc)); +} diff --git a/trunk/arch/arm/mach-iop3xx/iq80321-pci.c b/trunk/arch/arm/mach-iop3xx/iq80321-pci.c new file mode 100644 index 000000000000..d9758d3f6e7f --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iq80321-pci.c @@ -0,0 +1,123 @@ +/* + * arch/arm/mach-iop3xx/iq80321-pci.c + * + * PCI support for the Intel IQ80321 reference board + * + * Author: Rory Bolt + * Copyright (C) 2002 Rory Bolt + * Copyright (C) 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * The following macro is used to lookup irqs in a standard table + * format for those systems that do not already have PCI + * interrupts properly routed. We assume 1 <= pin <= 4 + */ +#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ +({ int _ctl_ = -1; \ + unsigned int _idsel = idsel - minid; \ + if (_idsel <= maxid) \ + _ctl_ = pci_irq_table[_idsel][pin-1]; \ + _ctl_; }) + +#define INTA IRQ_IQ80321_INTA +#define INTB IRQ_IQ80321_INTB +#define INTC IRQ_IQ80321_INTC +#define INTD IRQ_IQ80321_INTD + +#define INTE IRQ_IQ80321_I82544 + +static inline int __init +iq80321_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + static int pci_irq_table[][4] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + {INTE, INTE, INTE, INTE}, /* Gig-E */ + {-1, -1, -1, -1}, /* Unused */ + {INTC, INTD, INTA, INTB}, /* PCI-X Slot */ + {-1, -1, -1, -1}, + }; + + BUG_ON(pin < 1 || pin > 4); + +// return PCI_IRQ_TABLE_LOOKUP(4, 7); + return pci_irq_table[idsel%4][pin-1]; +} + +static int iq80321_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if(nr != 0) + return 0; + + res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + res[0].start = IOP321_PCI_LOWER_IO_VA; + res[0].end = IOP321_PCI_UPPER_IO_VA; + res[0].name = "IQ80321 PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP321_PCI_LOWER_MEM_PA; + res[1].end = IOP321_PCI_UPPER_MEM_PA; + res[1].name = "IQ80321 PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->mem_offset = IOP321_PCI_MEM_OFFSET; + sys->io_offset = IOP321_PCI_IO_OFFSET; + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +static void iq80321_preinit(void) +{ + iop321_init(); +} + +static struct hw_pci iq80321_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iq80321_setup, + .scan = iop321_scan_bus, + .preinit = iq80321_preinit, + .map_irq = iq80321_map_irq +}; + +static int __init iq80321_pci_init(void) +{ + if (machine_is_iq80321()) + pci_common_init(&iq80321_pci); + return 0; +} + +subsys_initcall(iq80321_pci_init); + + + + diff --git a/trunk/arch/arm/mach-iop3xx/iq80331-mm.c b/trunk/arch/arm/mach-iop3xx/iq80331-mm.c new file mode 100644 index 000000000000..129eb49b0670 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iq80331-mm.c @@ -0,0 +1,35 @@ +/* + * linux/arch/arm/mach-iop3xx/mm.c + * + * Low level memory initialization for iq80331 platform + * + * Author: Dave Jiang + * Copyright (C) 2003 Intel Corp. + * + * 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. + * + */ + +#include +#include + +#include +#include +#include + +#include + + +/* + * IQ80331 specific IO mappings + * + * We use RedBoot's setup for the onboard devices. + */ + +void __init iq80331_map_io(void) +{ + iop331_map_io(); +} diff --git a/trunk/arch/arm/mach-iop3xx/iq80331-pci.c b/trunk/arch/arm/mach-iop3xx/iq80331-pci.c new file mode 100644 index 000000000000..40d861002492 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iq80331-pci.c @@ -0,0 +1,119 @@ +/* + * arch/arm/mach-iop3xx/iq80331-pci.c + * + * PCI support for the Intel IQ80331 reference board + * + * Author: Dave Jiang + * Copyright (C) 2003, 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * The following macro is used to lookup irqs in a standard table + * format for those systems that do not already have PCI + * interrupts properly routed. We assume 1 <= pin <= 4 + */ +#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ +({ int _ctl_ = -1; \ + unsigned int _idsel = idsel - minid; \ + if (_idsel <= maxid) \ + _ctl_ = pci_irq_table[_idsel][pin-1]; \ + _ctl_; }) + +#define INTA IRQ_IQ80331_INTA +#define INTB IRQ_IQ80331_INTB +#define INTC IRQ_IQ80331_INTC +#define INTD IRQ_IQ80331_INTD + +//#define INTE IRQ_IQ80331_I82544 + +static inline int __init +iq80331_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + static int pci_irq_table[][4] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + {INTB, INTC, INTD, INTA}, /* PCI-X Slot */ + {INTC, INTC, INTC, INTC}, /* GigE */ + }; + + BUG_ON(pin < 1 || pin > 4); + + return PCI_IRQ_TABLE_LOOKUP(1, 7); +} + +static int iq80331_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if(nr != 0) + return 0; + + res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + res[0].start = IOP331_PCI_LOWER_IO_VA; + res[0].end = IOP331_PCI_UPPER_IO_VA; + res[0].name = "IQ80331 PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP331_PCI_LOWER_MEM_PA; + res[1].end = IOP331_PCI_UPPER_MEM_PA; + res[1].name = "IQ80331 PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->mem_offset = IOP331_PCI_MEM_OFFSET; + sys->io_offset = IOP331_PCI_IO_OFFSET; + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +static void iq80331_preinit(void) +{ + iop331_init(); +} + +static struct hw_pci iq80331_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iq80331_setup, + .scan = iop331_scan_bus, + .preinit = iq80331_preinit, + .map_irq = iq80331_map_irq +}; + +static int __init iq80331_pci_init(void) +{ + if (machine_is_iq80331()) + pci_common_init(&iq80331_pci); + return 0; +} + +subsys_initcall(iq80331_pci_init); + + + + diff --git a/trunk/arch/arm/mach-iop3xx/iq80332-mm.c b/trunk/arch/arm/mach-iop3xx/iq80332-mm.c new file mode 100644 index 000000000000..2feaf7591f53 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iq80332-mm.c @@ -0,0 +1,35 @@ +/* + * linux/arch/arm/mach-iop3xx/mm.c + * + * Low level memory initialization for iq80332 platform + * + * Author: Dave Jiang + * Copyright (C) 2004 Intel Corp. + * + * 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. + * + */ + +#include +#include + +#include +#include +#include + +#include + + +/* + * IQ80332 specific IO mappings + * + * We use RedBoot's setup for the onboard devices. + */ + +void __init iq80332_map_io(void) +{ + iop331_map_io(); +} diff --git a/trunk/arch/arm/mach-iop3xx/iq80332-pci.c b/trunk/arch/arm/mach-iop3xx/iq80332-pci.c new file mode 100644 index 000000000000..afc0676318e4 --- /dev/null +++ b/trunk/arch/arm/mach-iop3xx/iq80332-pci.c @@ -0,0 +1,125 @@ +/* + * arch/arm/mach-iop3xx/iq80332-pci.c + * + * PCI support for the Intel IQ80332 reference board + * + * Author: Dave Jiang + * Copyright (C) 2004 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * The following macro is used to lookup irqs in a standard table + * format for those systems that do not already have PCI + * interrupts properly routed. We assume 1 <= pin <= 4 + */ +#define PCI_IRQ_TABLE_LOOKUP(minid,maxid) \ +({ int _ctl_ = -1; \ + unsigned int _idsel = idsel - minid; \ + if (_idsel <= maxid) \ + _ctl_ = pci_irq_table[_idsel][pin-1]; \ + _ctl_; }) + +#define INTA IRQ_IQ80332_INTA +#define INTB IRQ_IQ80332_INTB +#define INTC IRQ_IQ80332_INTC +#define INTD IRQ_IQ80332_INTD + +//#define INTE IRQ_IQ80332_I82544 + +static inline int __init +iq80332_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) +{ + static int pci_irq_table[][8] = { + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + {-1, -1, -1, -1}, + {-1, -1, -1, -1}, + {-1, -1, -1, -1}, + {INTA, INTB, INTC, INTD}, /* PCI-X Slot */ + {-1, -1, -1, -1}, + {INTC, INTC, INTC, INTC}, /* GigE */ + {-1, -1, -1, -1}, + {-1, -1, -1, -1}, + }; + + BUG_ON(pin < 1 || pin > 4); + + return PCI_IRQ_TABLE_LOOKUP(1, 7); +} + +static int iq80332_setup(int nr, struct pci_sys_data *sys) +{ + struct resource *res; + + if(nr != 0) + return 0; + + res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); + if (!res) + panic("PCI: unable to alloc resources"); + + res[0].start = IOP331_PCI_LOWER_IO_VA; + res[0].end = IOP331_PCI_UPPER_IO_VA; + res[0].name = "IQ80332 PCI I/O Space"; + res[0].flags = IORESOURCE_IO; + + res[1].start = IOP331_PCI_LOWER_MEM_PA; + res[1].end = IOP331_PCI_UPPER_MEM_PA; + res[1].name = "IQ80332 PCI Memory Space"; + res[1].flags = IORESOURCE_MEM; + + request_resource(&ioport_resource, &res[0]); + request_resource(&iomem_resource, &res[1]); + + sys->mem_offset = IOP331_PCI_MEM_OFFSET; + sys->io_offset = IOP331_PCI_IO_OFFSET; + + sys->resource[0] = &res[0]; + sys->resource[1] = &res[1]; + sys->resource[2] = NULL; + + return 1; +} + +static void iq80332_preinit(void) +{ + iop331_init(); +} + +static struct hw_pci iq80332_pci __initdata = { + .swizzle = pci_std_swizzle, + .nr_controllers = 1, + .setup = iq80332_setup, + .scan = iop331_scan_bus, + .preinit = iq80332_preinit, + .map_irq = iq80332_map_irq +}; + +static int __init iq80332_pci_init(void) +{ + if (machine_is_iq80332()) + pci_common_init(&iq80332_pci); + return 0; +} + +subsys_initcall(iq80332_pci_init); + + + + diff --git a/trunk/arch/arm/mach-ixp4xx/common.c b/trunk/arch/arm/mach-ixp4xx/common.c index 35dd8b3824b0..7c25dbd5a181 100644 --- a/trunk/arch/arm/mach-ixp4xx/common.c +++ b/trunk/arch/arm/mach-ixp4xx/common.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -256,6 +255,16 @@ static unsigned volatile last_jiffy_time; #define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC) +/* IRQs are disabled before entering here from do_gettimeofday() */ +static unsigned long ixp4xx_gettimeoffset(void) +{ + u32 elapsed; + + elapsed = *IXP4XX_OSTS - last_jiffy_time; + + return elapsed / CLOCK_TICKS_PER_USEC; +} + static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { write_seqlock(&xtime_lock); @@ -300,6 +309,7 @@ static void __init ixp4xx_timer_init(void) struct sys_timer ixp4xx_timer = { .init = ixp4xx_timer_init, + .offset = ixp4xx_gettimeoffset, }; static struct resource ixp46x_i2c_resources[] = { @@ -355,29 +365,3 @@ void __init ixp4xx_sys_init(void) ixp4xx_exp_bus_size >> 20); } -cycle_t ixp4xx_get_cycles(void) -{ - return *IXP4XX_OSTS; -} - -static struct clocksource clocksource_ixp4xx = { - .name = "OSTS", - .rating = 200, - .read = ixp4xx_get_cycles, - .mask = CLOCKSOURCE_MASK(32), - .shift = 20, - .is_continuous = 1, -}; - -unsigned long ixp4xx_timer_freq = FREQ; -static int __init ixp4xx_clocksource_init(void) -{ - clocksource_ixp4xx.mult = - clocksource_hz2mult(ixp4xx_timer_freq, - clocksource_ixp4xx.shift); - clocksource_register(&clocksource_ixp4xx); - - return 0; -} - -device_initcall(ixp4xx_clocksource_init); diff --git a/trunk/arch/arm/mach-ixp4xx/nslu2-setup.c b/trunk/arch/arm/mach-ixp4xx/nslu2-setup.c index 162c266e5f8f..749a337494d3 100644 --- a/trunk/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/trunk/arch/arm/mach-ixp4xx/nslu2-setup.c @@ -159,8 +159,6 @@ static void nslu2_power_off(void) static void __init nslu2_init(void) { - ixp4xx_timer_freq = NSLU2_FREQ; - ixp4xx_sys_init(); nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); diff --git a/trunk/arch/arm/mach-omap1/board-fsample.c b/trunk/arch/arm/mach-omap1/board-fsample.c index 62e42c7a628e..c753a3c5aadd 100644 --- a/trunk/arch/arm/mach-omap1/board-fsample.c +++ b/trunk/arch/arm/mach-omap1/board-fsample.c @@ -172,11 +172,9 @@ static struct resource kp_resources[] = { }; static struct omap_kp_platform_data kp_data = { - .rows = 8, - .cols = 8, - .keymap = fsample_keymap, - .keymapsize = ARRAY_SIZE(fsample_keymap), - .delay = 4, + .rows = 8, + .cols = 8, + .keymap = fsample_keymap, }; static struct platform_device kp_device = { diff --git a/trunk/arch/arm/mach-omap1/board-h2.c b/trunk/arch/arm/mach-omap1/board-h2.c index 6e113078f7ab..cd3a06dfc0a8 100644 --- a/trunk/arch/arm/mach-omap1/board-h2.c +++ b/trunk/arch/arm/mach-omap1/board-h2.c @@ -167,13 +167,10 @@ static struct resource h2_kp_resources[] = { }; static struct omap_kp_platform_data h2_kp_data = { - .rows = 8, - .cols = 8, - .keymap = h2_keymap, - .keymapsize = ARRAY_SIZE(h2_keymap), - .rep = 1, - .delay = 9, - .dbounce = 1, + .rows = 8, + .cols = 8, + .keymap = h2_keymap, + .rep = 1, }; static struct platform_device h2_kp_device = { diff --git a/trunk/arch/arm/mach-omap1/board-h3.c b/trunk/arch/arm/mach-omap1/board-h3.c index f225a083dee1..7b206116cd03 100644 --- a/trunk/arch/arm/mach-omap1/board-h3.c +++ b/trunk/arch/arm/mach-omap1/board-h3.c @@ -247,13 +247,10 @@ static struct resource h3_kp_resources[] = { }; static struct omap_kp_platform_data h3_kp_data = { - .rows = 8, - .cols = 8, - .keymap = h3_keymap, - .keymapsize = ARRAY_SIZE(h3_keymap), - .rep = 1, - .delay = 9, - .dbounce = 1, + .rows = 8, + .cols = 8, + .keymap = h3_keymap, + .rep = 1, }; static struct platform_device h3_kp_device = { diff --git a/trunk/arch/arm/mach-omap1/board-innovator.c b/trunk/arch/arm/mach-omap1/board-innovator.c index cb00530ad279..4cbc62db5b5d 100644 --- a/trunk/arch/arm/mach-omap1/board-innovator.c +++ b/trunk/arch/arm/mach-omap1/board-innovator.c @@ -159,11 +159,9 @@ static struct resource innovator_kp_resources[] = { }; static struct omap_kp_platform_data innovator_kp_data = { - .rows = 8, - .cols = 8, - .keymap = innovator_keymap, - .keymapsize = ARRAY_SIZE(innovator_keymap), - .delay = 4, + .rows = 8, + .cols = 8, + .keymap = innovator_keymap, }; static struct platform_device innovator_kp_device = { diff --git a/trunk/arch/arm/mach-omap1/board-nokia770.c b/trunk/arch/arm/mach-omap1/board-nokia770.c index dbc555d209ff..02b980d77b12 100644 --- a/trunk/arch/arm/mach-omap1/board-nokia770.c +++ b/trunk/arch/arm/mach-omap1/board-nokia770.c @@ -71,11 +71,9 @@ static struct resource nokia770_kp_resources[] = { }; static struct omap_kp_platform_data nokia770_kp_data = { - .rows = 8, - .cols = 8, - .keymap = nokia770_keymap, - .keymapsize = ARRAY_SIZE(nokia770_keymap) - .delay = 4, + .rows = 8, + .cols = 8, + .keymap = nokia770_keymap }; static struct platform_device nokia770_kp_device = { diff --git a/trunk/arch/arm/mach-omap1/board-osk.c b/trunk/arch/arm/mach-omap1/board-osk.c index 6b05647a6c01..b742261c97ad 100644 --- a/trunk/arch/arm/mach-omap1/board-osk.c +++ b/trunk/arch/arm/mach-omap1/board-osk.c @@ -266,11 +266,9 @@ static const int osk_keymap[] = { }; static struct omap_kp_platform_data osk_kp_data = { - .rows = 8, - .cols = 8, - .keymap = (int *) osk_keymap, - .keymapsize = ARRAY_SIZE(osk_keymap), - .delay = 9, + .rows = 8, + .cols = 8, + .keymap = (int *) osk_keymap, }; static struct resource osk5912_kp_resources[] = { diff --git a/trunk/arch/arm/mach-omap1/board-perseus2.c b/trunk/arch/arm/mach-omap1/board-perseus2.c index fa4be962df67..64b45d8ae357 100644 --- a/trunk/arch/arm/mach-omap1/board-perseus2.c +++ b/trunk/arch/arm/mach-omap1/board-perseus2.c @@ -171,12 +171,9 @@ static struct resource kp_resources[] = { }; static struct omap_kp_platform_data kp_data = { - .rows = 8, - .cols = 8, - .keymap = p2_keymap, - .keymapsize = ARRAY_SIZE(p2_keymap), - .delay = 4, - .dbounce = 1, + .rows = 8, + .cols = 8, + .keymap = p2_keymap, }; static struct platform_device kp_device = { diff --git a/trunk/arch/arm/mach-omap1/clock.c b/trunk/arch/arm/mach-omap1/clock.c index 638490e62d5f..f1958e882e86 100644 --- a/trunk/arch/arm/mach-omap1/clock.c +++ b/trunk/arch/arm/mach-omap1/clock.c @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -587,53 +586,77 @@ static int omap1_clk_set_rate(struct clk *clk, unsigned long rate) *-------------------------------------------------------------------------*/ #ifdef CONFIG_OMAP_RESET_CLOCKS +/* + * Resets some clocks that may be left on from bootloader, + * but leaves serial clocks on. See also omap_late_clk_reset(). + */ +static inline void omap1_early_clk_reset(void) +{ + //omap_writel(0x3 << 29, MOD_CONF_CTRL_0); +} -static void __init omap1_clk_disable_unused(struct clk *clk) +static int __init omap1_late_clk_reset(void) { + /* Turn off all unused clocks */ + struct clk *p; __u32 regval32; - /* Clocks in the DSP domain need api_ck. Just assume bootloader - * has not enabled any DSP clocks */ - if ((u32)clk->enable_reg == DSP_IDLECT2) { - printk(KERN_INFO "Skipping reset check for DSP domain " - "clock \"%s\"\n", clk->name); - return; - } + /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ + regval32 = omap_readw(SOFT_REQ_REG) & (1 << 4); + omap_writew(regval32, SOFT_REQ_REG); + omap_writew(0, SOFT_REQ_REG2); - /* Is the clock already disabled? */ - if (clk->flags & ENABLE_REG_32BIT) { - if (clk->flags & VIRTUAL_IO_ADDRESS) - regval32 = __raw_readl(clk->enable_reg); + list_for_each_entry(p, &clocks, node) { + if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) || + p->enable_reg == 0) + continue; + + /* Clocks in the DSP domain need api_ck. Just assume bootloader + * has not enabled any DSP clocks */ + if ((u32)p->enable_reg == DSP_IDLECT2) { + printk(KERN_INFO "Skipping reset check for DSP domain " + "clock \"%s\"\n", p->name); + continue; + } + + /* Is the clock already disabled? */ + if (p->flags & ENABLE_REG_32BIT) { + if (p->flags & VIRTUAL_IO_ADDRESS) + regval32 = __raw_readl(p->enable_reg); else - regval32 = omap_readl(clk->enable_reg); - } else { - if (clk->flags & VIRTUAL_IO_ADDRESS) - regval32 = __raw_readw(clk->enable_reg); - else - regval32 = omap_readw(clk->enable_reg); - } + regval32 = omap_readl(p->enable_reg); + } else { + if (p->flags & VIRTUAL_IO_ADDRESS) + regval32 = __raw_readw(p->enable_reg); + else + regval32 = omap_readw(p->enable_reg); + } - if ((regval32 & (1 << clk->enable_bit)) == 0) - return; + if ((regval32 & (1 << p->enable_bit)) == 0) + continue; - /* FIXME: This clock seems to be necessary but no-one - * has asked for its activation. */ - if (clk == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera - || clk == &ck_dpll1out.clk // FIX: SoSSI, SSR - || clk == &arm_gpio_ck // FIX: GPIO code for 1510 - ) { - printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n", - clk->name); - return; + /* FIXME: This clock seems to be necessary but no-one + * has asked for its activation. */ + if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera + || p == &ck_dpll1out.clk // FIX: SoSSI, SSR + || p == &arm_gpio_ck // FIX: GPIO code for 1510 + ) { + printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n", + p->name); + continue; + } + + printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name); + p->disable(p); + printk(" done\n"); } - printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name); - clk->disable(clk); - printk(" done\n"); + return 0; } +late_initcall(omap1_late_clk_reset); #else -#define omap1_clk_disable_unused NULL +#define omap1_early_clk_reset() {} #endif static struct clk_functions omap1_clk_functions = { @@ -641,7 +664,6 @@ static struct clk_functions omap1_clk_functions = { .clk_disable = omap1_clk_disable, .clk_round_rate = omap1_clk_round_rate, .clk_set_rate = omap1_clk_set_rate, - .clk_disable_unused = omap1_clk_disable_unused, }; int __init omap1_clk_init(void) @@ -649,13 +671,8 @@ int __init omap1_clk_init(void) struct clk ** clkp; const struct omap_clock_config *info; int crystal_type = 0; /* Default 12 MHz */ - u32 reg; - - /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ - reg = omap_readw(SOFT_REQ_REG) & (1 << 4); - omap_writew(reg, SOFT_REQ_REG); - omap_writew(0, SOFT_REQ_REG2); + omap1_early_clk_reset(); clk_init(&omap1_clk_functions); /* By default all idlect1 clocks are allowed to idle */ @@ -755,12 +772,6 @@ int __init omap1_clk_init(void) omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL); #endif - /* Amstrad Delta wants BCLK high when inactive */ - if (machine_is_ams_delta()) - omap_writel(omap_readl(ULPD_CLOCK_CTRL) | - (1 << SDW_MCLK_INV_BIT), - ULPD_CLOCK_CTRL); - /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */ /* (on 730, bit 13 must not be cleared) */ if (cpu_is_omap730()) diff --git a/trunk/arch/arm/mach-omap1/clock.h b/trunk/arch/arm/mach-omap1/clock.h index f7df00205c4a..b7c68819c4e7 100644 --- a/trunk/arch/arm/mach-omap1/clock.h +++ b/trunk/arch/arm/mach-omap1/clock.h @@ -89,7 +89,6 @@ struct arm_idlect1_clk { #define EN_DSPTIMCK 5 /* Various register defines for clock controls scattered around OMAP chip */ -#define SDW_MCLK_INV_BIT 2 /* In ULPD_CLKC_CTRL */ #define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */ #define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */ #define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */ @@ -742,18 +741,6 @@ static struct clk i2c_fck = { .disable = &omap1_clk_disable_generic, }; -static struct clk i2c_ick = { - .name = "i2c_ick", - .id = 1, - .flags = CLOCK_IN_OMAP16XX | - VIRTUAL_CLOCK | CLOCK_NO_IDLE_PARENT | - ALWAYS_ENABLED, - .parent = &armper_ck.clk, - .recalc = &followparent_recalc, - .enable = &omap1_clk_enable_generic, - .disable = &omap1_clk_disable_generic, -}; - static struct clk * onchip_clks[] = { /* non-ULPD clocks */ &ck_ref, @@ -803,7 +790,6 @@ static struct clk * onchip_clks[] = { /* Virtual clocks */ &virtual_ck_mpu, &i2c_fck, - &i2c_ick, }; #endif diff --git a/trunk/arch/arm/mach-omap1/mux.c b/trunk/arch/arm/mach-omap1/mux.c index 5432335bc493..fa74ef7af15f 100644 --- a/trunk/arch/arm/mach-omap1/mux.c +++ b/trunk/arch/arm/mach-omap1/mux.c @@ -199,17 +199,6 @@ MUX_CFG("N14_1610_UWIRE_CS0", 8, 9, 1, 1, 21, 0, 1, 1, 1) MUX_CFG("P15_1610_UWIRE_CS3", 8, 12, 1, 1, 22, 0, 1, 1, 1) MUX_CFG("N15_1610_UWIRE_CS1", 7, 18, 2, 1, 14, 0, NA, 0, 1) -/* OMAP-1610 SPI */ -MUX_CFG("U19_1610_SPIF_SCK", 7, 21, 6, 1, 15, 0, 1, 1, 1) -MUX_CFG("U18_1610_SPIF_DIN", 8, 0, 6, 1, 18, 1, 1, 0, 1) -MUX_CFG("P20_1610_SPIF_DIN", 6, 27, 4, 1, 7, 1, 1, 0, 1) -MUX_CFG("W21_1610_SPIF_DOUT", 8, 3, 6, 1, 19, 0, 1, 0, 1) -MUX_CFG("R18_1610_SPIF_DOUT", 7, 9, 3, 1, 11, 0, 1, 0, 1) -MUX_CFG("N14_1610_SPIF_CS0", 8, 9, 6, 1, 21, 0, 1, 1, 1) -MUX_CFG("N15_1610_SPIF_CS1", 7, 18, 6, 1, 14, 0, 1, 1, 1) -MUX_CFG("T19_1610_SPIF_CS2", 7, 15, 4, 1, 13, 0, 1, 1, 1) -MUX_CFG("P15_1610_SPIF_CS3", 8, 12, 3, 1, 22, 0, 1, 1, 1) - /* OMAP-1610 Flash */ MUX_CFG("L3_1610_FLASH_CS2B_OE",10, 6, 1, NA, 0, 0, NA, 0, 1) MUX_CFG("M8_1610_FLASH_CS2B_WE",10, 3, 1, NA, 0, 0, NA, 0, 1) diff --git a/trunk/arch/arm/mach-omap2/board-apollon.c b/trunk/arch/arm/mach-omap2/board-apollon.c index 2db6b732b084..7993b7bae2bd 100644 --- a/trunk/arch/arm/mach-omap2/board-apollon.c +++ b/trunk/arch/arm/mach-omap2/board-apollon.c @@ -166,8 +166,8 @@ static struct omap_uart_config apollon_uart_config __initdata = { static struct omap_mmc_config apollon_mmc_config __initdata = { .mmc [0] = { - .enabled = 1, - .wire4 = 1, + .enabled = 0, + .wire4 = 0, .wp_pin = -1, .power_pin = -1, .switch_pin = -1, @@ -257,9 +257,6 @@ static void __init omap_apollon_init(void) /* REVISIT: where's the correct place */ omap_cfg_reg(W19_24XX_SYS_NIRQ); - /* Use Interal loop-back in MMC/SDIO Module Input Clock selection */ - CONTROL_DEVCONF |= (1 << 24); - /* * Make sure the serial ports are muxed on at this point. * You have to mux them off in device drivers later on diff --git a/trunk/arch/arm/mach-omap2/board-h4.c b/trunk/arch/arm/mach-omap2/board-h4.c index 996aeda1285d..4933fce766c8 100644 --- a/trunk/arch/arm/mach-omap2/board-h4.c +++ b/trunk/arch/arm/mach-omap2/board-h4.c @@ -245,7 +245,6 @@ static struct omap_kp_platform_data h4_kp_data = { .rows = 6, .cols = 7, .keymap = h4_keymap, - .keymapsize = ARRAY_SIZE(h4_keymap), .rep = 1, .row_gpios = row_gpios, .col_gpios = col_gpios, diff --git a/trunk/arch/arm/mach-omap2/clock.c b/trunk/arch/arm/mach-omap2/clock.c index 0de201c3d50b..d1b648a4efbf 100644 --- a/trunk/arch/arm/mach-omap2/clock.c +++ b/trunk/arch/arm/mach-omap2/clock.c @@ -32,14 +32,10 @@ #include "memory.h" #include "clock.h" -#undef DEBUG - //#define DOWN_VARIABLE_DPLL 1 /* Experimental */ static struct prcm_config *curr_prcm_set; static u32 curr_perf_level = PRCM_FULL_SPEED; -static struct clk *vclk; -static struct clk *sclk; /*------------------------------------------------------------------------- * Omap2 specific clock functions @@ -83,14 +79,6 @@ static void omap2_propagate_rate(struct clk * clk) propagate_rate(clk); } -static void omap2_set_osc_ck(int enable) -{ - if (enable) - PRCM_CLKSRC_CTRL &= ~(0x3 << 3); - else - PRCM_CLKSRC_CTRL |= 0x3 << 3; -} - /* Enable an APLL if off */ static void omap2_clk_fixed_enable(struct clk *clk) { @@ -113,54 +101,12 @@ static void omap2_clk_fixed_enable(struct clk *clk) else if (clk == &apll54_ck) cval = (1 << 6); - while (!(CM_IDLEST_CKGEN & cval)) { /* Wait for lock */ + while (!CM_IDLEST_CKGEN & cval) { /* Wait for lock */ ++i; udelay(1); - if (i == 100000) { - printk(KERN_ERR "Clock %s didn't lock\n", clk->name); - break; - } - } -} - -static void omap2_clk_wait_ready(struct clk *clk) -{ - unsigned long reg, other_reg, st_reg; - u32 bit; - int i; - - reg = (unsigned long) clk->enable_reg; - if (reg == (unsigned long) &CM_FCLKEN1_CORE || - reg == (unsigned long) &CM_FCLKEN2_CORE) - other_reg = (reg & ~0xf0) | 0x10; - else if (reg == (unsigned long) &CM_ICLKEN1_CORE || - reg == (unsigned long) &CM_ICLKEN2_CORE) - other_reg = (reg & ~0xf0) | 0x00; - else - return; - - /* No check for DSS or cam clocks */ - if ((reg & 0x0f) == 0) { - if (clk->enable_bit <= 1 || clk->enable_bit == 31) - return; - } - - /* Check if both functional and interface clocks - * are running. */ - bit = 1 << clk->enable_bit; - if (!(__raw_readl(other_reg) & bit)) - return; - st_reg = (other_reg & ~0xf0) | 0x20; - i = 0; - while (!(__raw_readl(st_reg) & bit)) { - i++; - if (i == 100000) { - printk(KERN_ERR "Timeout enabling clock %s\n", clk->name); + if (i == 100000) break; - } } - if (i) - pr_debug("Clock %s stable after %d loops\n", clk->name, i); } /* Enables clock without considering parent dependencies or use count @@ -173,11 +119,6 @@ static int _omap2_clk_enable(struct clk * clk) if (clk->flags & ALWAYS_ENABLED) return 0; - if (unlikely(clk == &osc_ck)) { - omap2_set_osc_ck(1); - return 0; - } - if (unlikely(clk->enable_reg == 0)) { printk(KERN_ERR "clock.c: Enable for %s without enable code\n", clk->name); @@ -192,9 +133,6 @@ static int _omap2_clk_enable(struct clk * clk) regval32 = __raw_readl(clk->enable_reg); regval32 |= (1 << clk->enable_bit); __raw_writel(regval32, clk->enable_reg); - wmb(); - - omap2_clk_wait_ready(clk); return 0; } @@ -217,11 +155,6 @@ static void _omap2_clk_disable(struct clk *clk) { u32 regval32; - if (unlikely(clk == &osc_ck)) { - omap2_set_osc_ck(0); - return; - } - if (clk->enable_reg == 0) return; @@ -233,7 +166,6 @@ static void _omap2_clk_disable(struct clk *clk) regval32 = __raw_readl(clk->enable_reg); regval32 &= ~(1 << clk->enable_bit); __raw_writel(regval32, clk->enable_reg); - wmb(); } static int omap2_clk_enable(struct clk *clk) @@ -763,14 +695,12 @@ static int omap2_clk_set_rate(struct clk *clk, unsigned long rate) reg_val = __raw_readl(reg); reg_val &= ~(field_mask << div_off); reg_val |= (field_val << div_off); + __raw_writel(reg_val, reg); - wmb(); clk->rate = clk->parent->rate / field_val; - if (clk->flags & DELAYED_APP) { + if (clk->flags & DELAYED_APP) __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); - wmb(); - } ret = 0; } else if (clk->set_rate != 0) ret = clk->set_rate(clk, rate); @@ -906,12 +836,10 @@ static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) reg_val = __raw_readl(reg) & ~(field_mask << src_off); reg_val |= (field_val << src_off); __raw_writel(reg_val, reg); - wmb(); - if (clk->flags & DELAYED_APP) { + if (clk->flags & DELAYED_APP) __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL); - wmb(); - } + if (clk->usecount > 0) _omap2_clk_enable(clk); @@ -1025,29 +953,12 @@ static int omap2_select_table_rate(struct clk * clk, unsigned long rate) * Omap2 clock reset and init functions *-------------------------------------------------------------------------*/ -#ifdef CONFIG_OMAP_RESET_CLOCKS -static void __init omap2_clk_disable_unused(struct clk *clk) -{ - u32 regval32; - - regval32 = __raw_readl(clk->enable_reg); - if ((regval32 & (1 << clk->enable_bit)) == 0) - return; - - printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name); - _omap2_clk_disable(clk); -} -#else -#define omap2_clk_disable_unused NULL -#endif - static struct clk_functions omap2_clk_functions = { .clk_enable = omap2_clk_enable, .clk_disable = omap2_clk_disable, .clk_round_rate = omap2_clk_round_rate, .clk_set_rate = omap2_clk_set_rate, .clk_set_parent = omap2_clk_set_parent, - .clk_disable_unused = omap2_clk_disable_unused, }; static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) @@ -1073,19 +984,27 @@ static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) sys->rate = sclk; } -/* - * Set clocks for bypass mode for reboot to work. - */ -void omap2_clk_prepare_for_reboot(void) +#ifdef CONFIG_OMAP_RESET_CLOCKS +static void __init omap2_disable_unused_clocks(void) { - u32 rate; + struct clk *ck; + u32 regval32; - if (vclk == NULL || sclk == NULL) - return; + list_for_each_entry(ck, &clocks, node) { + if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || + ck->enable_reg == 0) + continue; + + regval32 = __raw_readl(ck->enable_reg); + if ((regval32 & (1 << ck->enable_bit)) == 0) + continue; - rate = clk_get_rate(sclk); - clk_set_rate(vclk, rate); + printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name); + _omap2_clk_disable(ck); + } } +late_initcall(omap2_disable_unused_clocks); +#endif /* * Switch the MPU rate if specified on cmdline. @@ -1158,27 +1077,8 @@ int __init omap2_clk_init(void) */ clk_enable(&sync_32k_ick); clk_enable(&omapctrl_ick); - - /* Force the APLLs active during bootup to avoid disabling and - * enabling them unnecessarily. */ - clk_enable(&apll96_ck); - clk_enable(&apll54_ck); - if (cpu_is_omap2430()) clk_enable(&sdrc_ick); - /* Avoid sleeping sleeping during omap2_clk_prepare_for_reboot() */ - vclk = clk_get(NULL, "virt_prcm_set"); - sclk = clk_get(NULL, "sys_ck"); - - return 0; -} - -static int __init omap2_disable_aplls(void) -{ - clk_disable(&apll96_ck); - clk_disable(&apll54_ck); - return 0; } -late_initcall(omap2_disable_aplls); diff --git a/trunk/arch/arm/mach-omap2/clock.h b/trunk/arch/arm/mach-omap2/clock.h index 8816f5a33a28..2781dfbc5164 100644 --- a/trunk/arch/arm/mach-omap2/clock.h +++ b/trunk/arch/arm/mach-omap2/clock.h @@ -560,7 +560,7 @@ static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */ .name = "osc_ck", .rate = 26000000, /* fixed up in clock init */ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_FIXED | RATE_PROPAGATES, + RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES, }; /* With out modem likely 12MHz, with modem likely 13MHz */ @@ -1368,8 +1368,7 @@ static struct clk mcbsp5_fck = { }; static struct clk mcspi1_ick = { - .name = "mcspi_ick", - .id = 1, + .name = "mcspi1_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, @@ -1378,8 +1377,7 @@ static struct clk mcspi1_ick = { }; static struct clk mcspi1_fck = { - .name = "mcspi_fck", - .id = 1, + .name = "mcspi1_fck", .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, @@ -1388,8 +1386,7 @@ static struct clk mcspi1_fck = { }; static struct clk mcspi2_ick = { - .name = "mcspi_ick", - .id = 2, + .name = "mcspi2_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, @@ -1398,8 +1395,7 @@ static struct clk mcspi2_ick = { }; static struct clk mcspi2_fck = { - .name = "mcspi_fck", - .id = 2, + .name = "mcspi2_fck", .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, @@ -1408,8 +1404,7 @@ static struct clk mcspi2_fck = { }; static struct clk mcspi3_ick = { - .name = "mcspi_ick", - .id = 3, + .name = "mcspi3_ick", .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, @@ -1418,8 +1413,7 @@ static struct clk mcspi3_ick = { }; static struct clk mcspi3_fck = { - .name = "mcspi_fck", - .id = 3, + .name = "mcspi3_fck", .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN2_CORE, diff --git a/trunk/arch/arm/mach-omap2/gpmc.c b/trunk/arch/arm/mach-omap2/gpmc.c index f4f04d87df32..c7a48f921fef 100644 --- a/trunk/arch/arm/mach-omap2/gpmc.c +++ b/trunk/arch/arm/mach-omap2/gpmc.c @@ -13,8 +13,6 @@ #include #include #include -#include -#include #include #include @@ -43,19 +41,6 @@ #define GPMC_CS0 0x60 #define GPMC_CS_SIZE 0x30 -#define GPMC_CS_NUM 8 -#define GPMC_MEM_START 0x00000000 -#define GPMC_MEM_END 0x3FFFFFFF -#define BOOT_ROM_SPACE 0x100000 /* 1MB */ - -#define GPMC_CHUNK_SHIFT 24 /* 16 MB */ -#define GPMC_SECTION_SHIFT 28 /* 128 MB */ - -static struct resource gpmc_mem_root; -static struct resource gpmc_cs_mem[GPMC_CS_NUM]; -static spinlock_t gpmc_mem_lock = SPIN_LOCK_UNLOCKED; -static unsigned gpmc_cs_map; - static void __iomem *gpmc_base = (void __iomem *) IO_ADDRESS(GPMC_BASE); static void __iomem *gpmc_cs_base = @@ -202,168 +187,9 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) return 0; } -static void gpmc_cs_enable_mem(int cs, u32 base, u32 size) -{ - u32 l; - u32 mask; - - mask = (1 << GPMC_SECTION_SHIFT) - size; - l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); - l &= ~0x3f; - l = (base >> GPMC_CHUNK_SHIFT) & 0x3f; - l &= ~(0x0f << 8); - l |= ((mask >> GPMC_CHUNK_SHIFT) & 0x0f) << 8; - l |= 1 << 6; /* CSVALID */ - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); -} - -static void gpmc_cs_disable_mem(int cs) -{ - u32 l; - - l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); - l &= ~(1 << 6); /* CSVALID */ - gpmc_cs_write_reg(cs, GPMC_CS_CONFIG7, l); -} - -static void gpmc_cs_get_memconf(int cs, u32 *base, u32 *size) -{ - u32 l; - u32 mask; - - l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); - *base = (l & 0x3f) << GPMC_CHUNK_SHIFT; - mask = (l >> 8) & 0x0f; - *size = (1 << GPMC_SECTION_SHIFT) - (mask << GPMC_CHUNK_SHIFT); -} - -static int gpmc_cs_mem_enabled(int cs) -{ - u32 l; - - l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); - return l & (1 << 6); -} - -static void gpmc_cs_set_reserved(int cs, int reserved) +unsigned long gpmc_cs_get_base_addr(int cs) { - gpmc_cs_map &= ~(1 << cs); - gpmc_cs_map |= (reserved ? 1 : 0) << cs; -} - -static int gpmc_cs_reserved(int cs) -{ - return gpmc_cs_map & (1 << cs); -} - -static unsigned long gpmc_mem_align(unsigned long size) -{ - int order; - - size = (size - 1) >> (GPMC_CHUNK_SHIFT - 1); - order = GPMC_CHUNK_SHIFT - 1; - do { - size >>= 1; - order++; - } while (size); - size = 1 << order; - return size; -} - -static int gpmc_cs_insert_mem(int cs, unsigned long base, unsigned long size) -{ - struct resource *res = &gpmc_cs_mem[cs]; - int r; - - size = gpmc_mem_align(size); - spin_lock(&gpmc_mem_lock); - res->start = base; - res->end = base + size - 1; - r = request_resource(&gpmc_mem_root, res); - spin_unlock(&gpmc_mem_lock); - - return r; -} - -int gpmc_cs_request(int cs, unsigned long size, unsigned long *base) -{ - struct resource *res = &gpmc_cs_mem[cs]; - int r = -1; - - if (cs > GPMC_CS_NUM) - return -ENODEV; - - size = gpmc_mem_align(size); - if (size > (1 << GPMC_SECTION_SHIFT)) - return -ENOMEM; - - spin_lock(&gpmc_mem_lock); - if (gpmc_cs_reserved(cs)) { - r = -EBUSY; - goto out; - } - if (gpmc_cs_mem_enabled(cs)) - r = adjust_resource(res, res->start & ~(size - 1), size); - if (r < 0) - r = allocate_resource(&gpmc_mem_root, res, size, 0, ~0, - size, NULL, NULL); - if (r < 0) - goto out; - - gpmc_cs_enable_mem(cs, res->start, res->end - res->start + 1); - *base = res->start; - gpmc_cs_set_reserved(cs, 1); -out: - spin_unlock(&gpmc_mem_lock); - return r; -} - -void gpmc_cs_free(int cs) -{ - spin_lock(&gpmc_mem_lock); - if (cs >= GPMC_CS_NUM || !gpmc_cs_reserved(cs)) { - printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs); - BUG(); - spin_unlock(&gpmc_mem_lock); - return; - } - gpmc_cs_disable_mem(cs); - release_resource(&gpmc_cs_mem[cs]); - gpmc_cs_set_reserved(cs, 0); - spin_unlock(&gpmc_mem_lock); -} - -void __init gpmc_mem_init(void) -{ - int cs; - unsigned long boot_rom_space = 0; - - if (cpu_is_omap242x()) { - u32 l; - l = omap_readl(OMAP242X_CONTROL_STATUS); - /* In case of internal boot the 1st MB is redirected to the - * boot ROM memory space. - */ - if (l & (1 << 3)) - boot_rom_space = BOOT_ROM_SPACE; - } else - /* We assume internal boot if the mode can't be - * determined. - */ - boot_rom_space = BOOT_ROM_SPACE; - gpmc_mem_root.start = GPMC_MEM_START + boot_rom_space; - gpmc_mem_root.end = GPMC_MEM_END; - - /* Reserve all regions that has been set up by bootloader */ - for (cs = 0; cs < GPMC_CS_NUM; cs++) { - u32 base, size; - - if (!gpmc_cs_mem_enabled(cs)) - continue; - gpmc_cs_get_memconf(cs, &base, &size); - if (gpmc_cs_insert_mem(cs, base, size) < 0) - BUG(); - } + return (gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7) & 0x1f) << 24; } void __init gpmc_init(void) @@ -380,6 +206,4 @@ void __init gpmc_init(void) l &= 0x03 << 3; l |= (0x02 << 3) | (1 << 0); gpmc_write_reg(GPMC_SYSCONFIG, l); - - gpmc_mem_init(); } diff --git a/trunk/arch/arm/mach-omap2/irq.c b/trunk/arch/arm/mach-omap2/irq.c index 1ed2fff4691a..dfc3b35cc1ff 100644 --- a/trunk/arch/arm/mach-omap2/irq.c +++ b/trunk/arch/arm/mach-omap2/irq.c @@ -41,6 +41,18 @@ static struct omap_irq_bank { .nr_irqs = 96, }, { /* XXX: DSP INTC */ + +#if 0 + /* + * Commented out for now until we fix the IVA clocking + */ +#ifdef CONFIG_ARCH_OMAP2420 + }, { + /* IVA INTC (2420 only) */ + .base_reg = OMAP24XX_IVA_INTC_BASE, + .nr_irqs = 16, /* Actually 32, but only 16 are used */ +#endif +#endif } }; diff --git a/trunk/arch/arm/mach-omap2/mux.c b/trunk/arch/arm/mach-omap2/mux.c index f538d0fdb13c..60ef084faffd 100644 --- a/trunk/arch/arm/mach-omap2/mux.c +++ b/trunk/arch/arm/mach-omap2/mux.c @@ -104,20 +104,6 @@ MUX_CFG_24XX("P20_24XX_TSC_IRQ", 0x108, 0, 0, 0, 1) MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1) MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1) -/* MMC/SDIO */ -MUX_CFG_24XX("G19_24XX_MMC_CLKO", 0x0f3, 0, 0, 0, 1) -MUX_CFG_24XX("H18_24XX_MMC_CMD", 0x0f4, 0, 0, 0, 1) -MUX_CFG_24XX("F20_24XX_MMC_DAT0", 0x0f5, 0, 0, 0, 1) -MUX_CFG_24XX("H14_24XX_MMC_DAT1", 0x0f6, 0, 0, 0, 1) -MUX_CFG_24XX("E19_24XX_MMC_DAT2", 0x0f7, 0, 0, 0, 1) -MUX_CFG_24XX("D19_24XX_MMC_DAT3", 0x0f8, 0, 0, 0, 1) -MUX_CFG_24XX("F19_24XX_MMC_DAT_DIR0", 0x0f9, 0, 0, 0, 1) -MUX_CFG_24XX("E20_24XX_MMC_DAT_DIR1", 0x0fa, 0, 0, 0, 1) -MUX_CFG_24XX("F18_24XX_MMC_DAT_DIR2", 0x0fb, 0, 0, 0, 1) -MUX_CFG_24XX("E18_24XX_MMC_DAT_DIR3", 0x0fc, 0, 0, 0, 1) -MUX_CFG_24XX("G18_24XX_MMC_CMD_DIR", 0x0fd, 0, 0, 0, 1) -MUX_CFG_24XX("H15_24XX_MMC_CLKI", 0x0fe, 0, 0, 0, 1) - /* Keypad GPIO*/ MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1) MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1) diff --git a/trunk/arch/arm/mach-omap2/prcm.c b/trunk/arch/arm/mach-omap2/prcm.c index 90f530540c65..c2bf57ef6825 100644 --- a/trunk/arch/arm/mach-omap2/prcm.c +++ b/trunk/arch/arm/mach-omap2/prcm.c @@ -19,8 +19,6 @@ #include "prcm-regs.h" -extern void omap2_clk_prepare_for_reboot(void); - u32 omap_prcm_get_reset_sources(void) { return RM_RSTST_WKUP & 0x7f; @@ -30,6 +28,12 @@ EXPORT_SYMBOL(omap_prcm_get_reset_sources); /* Resets clock rates and reboots the system. Only called from system.h */ void omap_prcm_arch_reset(char mode) { - omap2_clk_prepare_for_reboot(); + u32 rate; + struct clk *vclk, *sclk; + + vclk = clk_get(NULL, "virt_prcm_set"); + sclk = clk_get(NULL, "sys_ck"); + rate = clk_get_rate(sclk); + clk_set_rate(vclk, rate); /* go to bypass for OMAP limitation */ RM_RSTCTRL_WKUP |= 2; } diff --git a/trunk/arch/arm/mach-pxa/corgi.c b/trunk/arch/arm/mach-pxa/corgi.c index 337c01c4ac37..cce26576999e 100644 --- a/trunk/arch/arm/mach-pxa/corgi.c +++ b/trunk/arch/arm/mach-pxa/corgi.c @@ -284,9 +284,21 @@ static struct pxaficp_platform_data corgi_ficp_platform_data = { /* * USB Device Controller */ +static void corgi_udc_command(int cmd) +{ + switch(cmd) { + case PXA2XX_UDC_CMD_CONNECT: + GPSR(CORGI_GPIO_USB_PULLUP) = GPIO_bit(CORGI_GPIO_USB_PULLUP); + break; + case PXA2XX_UDC_CMD_DISCONNECT: + GPCR(CORGI_GPIO_USB_PULLUP) = GPIO_bit(CORGI_GPIO_USB_PULLUP); + break; + } +} + static struct pxa2xx_udc_mach_info udc_info __initdata = { /* no connect GPIO; corgi can't tell connection status */ - .gpio_pullup = CORGI_GPIO_USB_PULLUP, + .udc_command = corgi_udc_command, }; @@ -338,6 +350,7 @@ static void __init corgi_init(void) corgi_ssp_set_machinfo(&corgi_ssp_machinfo); pxa_gpio_mode(CORGI_GPIO_IR_ON | GPIO_OUT); + pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT); pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN); pxa_set_udc_info(&udc_info); diff --git a/trunk/arch/arm/mach-s3c2410/Kconfig b/trunk/arch/arm/mach-s3c2410/Kconfig index df37594c30f8..bbd138be6a70 100644 --- a/trunk/arch/arm/mach-s3c2410/Kconfig +++ b/trunk/arch/arm/mach-s3c2410/Kconfig @@ -2,13 +2,6 @@ if ARCH_S3C2410 menu "S3C24XX Implementations" -config MACH_AML_M5900 - bool "AML M5900 Series" - select CPU_S3C2410 - help - Say Y here if you are using the American Microsystems M5900 Series - - config MACH_ANUBIS bool "Simtec Electronics ANUBIS" select CPU_S3C2440 @@ -133,12 +126,6 @@ config MACH_NEXCODER_2440 help Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board -config MACH_VSTMS - bool "VMSTMS" - select CPU_S3C2412 - help - Say Y here if you are using an VSTMS board - endmenu config S3C2410_CLOCK @@ -146,24 +133,10 @@ config S3C2410_CLOCK help Clock code for the S3C2410, and similar processors -config S3C2410_PM - bool - depends on CONFIG_PM - help - Power Management code common to S3C2410 and better - -config CPU_S3C2410_DMA - bool - depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442) - default y if CPU_S3C2410 || CPU_S3C2442 - help - DMA device selection for S3C2410 and compatible CPUs - config CPU_S3C2410 bool depends on ARCH_S3C2410 select S3C2410_CLOCK - select S3C2410_PM help Support for S3C2410 and S3C2410A family from the S3C24XX line of Samsung Mobile CPUs. @@ -176,13 +149,6 @@ config CPU_S3C2412_ONLY !CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412 default y if CPU_S3C2412 -config S3C2412_PM - bool - default y if PM - depends on CPU_S3C2412 - help - Internal config node to apply S3C2412 power management - config CPU_S3C2412 bool depends on ARCH_S3C2410 @@ -199,7 +165,6 @@ config CPU_S3C2440 bool depends on ARCH_S3C2410 select S3C2410_CLOCK - select S3C2410_PM select CPU_S3C244X help Support for S3C2440 Samsung Mobile CPU based systems. @@ -208,7 +173,6 @@ config CPU_S3C2442 bool depends on ARCH_S3C2420 select S3C2410_CLOCK - select S3C2410_PM select CPU_S3C244X help Support for S3C2442 Samsung Mobile CPU based systems. @@ -292,7 +256,7 @@ config S3C2410_PM_CHECK_CHUNKSIZE config PM_SIMTEC bool - depends on PM && (ARCH_BAST || MACH_VR1000 || MACH_AML_M5900) + depends on PM && (ARCH_BAST || MACH_VR1000) default y config S3C2410_LOWLEVEL_UART_PORT diff --git a/trunk/arch/arm/mach-s3c2410/Makefile b/trunk/arch/arm/mach-s3c2410/Makefile index d66013365b6b..0eadec916214 100644 --- a/trunk/arch/arm/mach-s3c2410/Makefile +++ b/trunk/arch/arm/mach-s3c2410/Makefile @@ -9,8 +9,6 @@ obj-y := cpu.o irq.o time.o gpio.o clock.o devs.o obj-m := obj-n := obj- := -obj-dma-y := -obj-dma-n := # DMA obj-$(CONFIG_S3C2410_DMA) += dma.o @@ -22,10 +20,6 @@ obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o obj-$(CONFIG_CPU_S3C2410) += s3c2410.o obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o -obj-$(CONFIG_CPU_S3C2410) += s3c2410-irq.o - -obj-$(CONFIG_S3C2410_PM) += s3c2410-pm.o s3c2410-sleep.o -obj-$(CONFIG_CPU_S3C2410_DMA) += s3c2410-dma.o # Power Management support @@ -36,9 +30,6 @@ obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o obj-$(CONFIG_CPU_S3C2412) += s3c2412.o obj-$(CONFIG_CPU_S3C2412) += s3c2412-irq.o obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o -obj-dma-$(CONFIG_CPU_S3C2412) += s3c2412-dma.o - -obj-$(CONFIG_S3C2412_PM) += s3c2412-pm.o # # S3C244X support @@ -56,7 +47,6 @@ obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o -obj-dma-$(CONFIG_CPU_S3C2440) += s3c2440-dma.o # S3C2442 support @@ -67,13 +57,8 @@ obj-$(CONFIG_CPU_S3C2442) += s3c2442-clock.o obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o -# merge in dma objects - -obj-y += $(obj-dma-y) - # machine specific support -obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o @@ -86,6 +71,5 @@ obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o obj-$(CONFIG_MACH_OTOM) += mach-otom.o obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o -obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o obj-$(CONFIG_MACH_SMDK) += common-smdk.o \ No newline at end of file diff --git a/trunk/arch/arm/mach-s3c2410/bast-irq.c b/trunk/arch/arm/mach-s3c2410/bast-irq.c index 440e9aa0211a..def4441d2442 100644 --- a/trunk/arch/arm/mach-s3c2410/bast-irq.c +++ b/trunk/arch/arm/mach-s3c2410/bast-irq.c @@ -18,6 +18,10 @@ * 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 + * + * Modifications: + * 08-Jan-2003 BJD Moved from central IRQ code + * 21-Aug-2005 BJD Fixed missing code and compile errors */ diff --git a/trunk/arch/arm/mach-s3c2410/cpu.c b/trunk/arch/arm/mach-s3c2410/cpu.c index 9d4899eddf1f..1c3c6adae6c4 100644 --- a/trunk/arch/arm/mach-s3c2410/cpu.c +++ b/trunk/arch/arm/mach-s3c2410/cpu.c @@ -124,15 +124,6 @@ static struct cpu_table cpu_ids[] __initdata = { .init = s3c2412_init, .name = name_s3c2412, }, - { /* a newer version of the s3c2412 */ - .idcode = 0x32412003, - .idmask = 0xffffffff, - .map_io = s3c2412_map_io, - .init_clocks = s3c2412_init_clocks, - .init_uarts = s3c2412_init_uarts, - .init = s3c2412_init, - .name = name_s3c2412, - }, { .idcode = 0x0, /* S3C2400 doesn't have an idcode */ .idmask = 0xffffffff, diff --git a/trunk/arch/arm/mach-s3c2410/devs.h b/trunk/arch/arm/mach-s3c2410/devs.h index 14fb0bade716..726e2eaf8797 100644 --- a/trunk/arch/arm/mach-s3c2410/devs.h +++ b/trunk/arch/arm/mach-s3c2410/devs.h @@ -8,6 +8,11 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. + * + * Modifications: + * 18-Aug-2004 BJD Created initial version + * 27-Aug-2004 BJD Added timers 0 through 3 + * 10-Feb-2005 BJD Added camera from guillaume.gourat@nexvision.tv */ #include diff --git a/trunk/arch/arm/mach-s3c2410/dma.c b/trunk/arch/arm/mach-s3c2410/dma.c index d264bbbd8bef..cc92a7b2db88 100644 --- a/trunk/arch/arm/mach-s3c2410/dma.c +++ b/trunk/arch/arm/mach-s3c2410/dma.c @@ -1,16 +1,35 @@ -/* linux/arch/arm/mach-s3c2410/dma.c +/* linux/arch/arm/mach-bast/dma.c * - * (c) 2003-2005,2006 Simtec Electronics + * (c) 2003-2005 Simtec Electronics * Ben Dooks * * S3C2410 DMA core * - * http://armlinux.simtec.co.uk/ + * http://www.simtec.co.uk/products/EB2410ITX/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. -*/ + * + * Changelog: + * 27-Feb-2005 BJD Added kmem cache for dma descriptors + * 18-Nov-2004 BJD Removed error for loading onto stopped channel + * 10-Nov-2004 BJD Ensure all external symbols exported for modules + * 10-Nov-2004 BJD Use sys_device and sysdev_class for power management + * 08-Aug-2004 BJD Apply rmk's suggestions + * 21-Jul-2004 BJD Ported to linux 2.6 + * 12-Jul-2004 BJD Finished re-write and change of API + * 06-Jul-2004 BJD Rewrote dma code to try and cope with various problems + * 23-May-2003 BJD Created file + * 19-Aug-2003 BJD Cleanup, header fix, added URL + * + * This file is based on the Sangwook Lee/Samsung patches, re-written due + * to various ommisions from the code (such as flexible dma configuration) + * for use with the BAST system board. + * + * The re-write is pretty much complete, and should be good enough for any + * possible DMA function + */ #ifdef CONFIG_S3C2410_DMA_DEBUG @@ -36,14 +55,10 @@ #include #include -#include "dma.h" - /* io map for dma */ static void __iomem *dma_base; static kmem_cache_t *dma_kmem; -struct s3c24xx_dma_selection dma_sel; - /* dma channel state information */ struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; @@ -64,6 +79,7 @@ dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val) pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg); writel(val, dma_regaddr(chan, reg)); } + #endif #define dma_rdreg(chan, reg) readl((chan)->regs + (reg)) @@ -135,20 +151,12 @@ dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan) #define dbg_showchan(chan) do { } while(0) #endif /* CONFIG_S3C2410_DMA_DEBUG */ -static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX]; +#define check_channel(chan) \ + do { if ((chan) >= S3C2410_DMA_CHANNELS) { \ + printk(KERN_ERR "%s: invalid channel %d\n", __FUNCTION__, (chan)); \ + return -EINVAL; \ + } } while(0) -/* lookup_dma_channel - * - * change the dma channel number given into a real dma channel id -*/ - -static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel) -{ - if (channel & DMACH_LOW_LEVEL) - return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL]; - else - return dma_chan_map[channel]; -} /* s3c2410_dma_stats_timeout * @@ -313,10 +321,8 @@ static inline void s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf, enum s3c2410_dma_buffresult result) { -#if 0 pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n", chan->callback_fn, buf, buf->id, buf->size, result); -#endif if (chan->callback_fn != NULL) { (chan->callback_fn)(chan, buf->id, buf->size, result); @@ -433,6 +439,7 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan) return 0; } + /* s3c2410_dma_enqueue * * queue an given buffer for dma transfer. @@ -453,12 +460,11 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan) int s3c2410_dma_enqueue(unsigned int channel, void *id, dma_addr_t data, int size) { - struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); + struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; struct s3c2410_dma_buf *buf; unsigned long flags; - if (chan == NULL) - return -EINVAL; + check_channel(channel); pr_debug("%s: id=%p, data=%08x, size=%d\n", __FUNCTION__, id, (unsigned int)data, size); @@ -556,10 +562,8 @@ s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf) static inline void s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan) { -#if 0 pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n", chan->number, chan->load_state); -#endif switch (chan->load_state) { case S3C2410_DMALOAD_NONE: @@ -714,8 +718,7 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs) if (chan->load_state == S3C2410_DMALOAD_NONE) { pr_debug("dma%d: end of transfer, stopping channel (%ld)\n", chan->number, jiffies); - s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL, - S3C2410_DMAOP_STOP); + s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP); } } @@ -723,34 +726,37 @@ s3c2410_dma_irq(int irq, void *devpw, struct pt_regs *regs) return IRQ_HANDLED; } -static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel); - /* s3c2410_request_dma * * get control of an dma channel */ -int s3c2410_dma_request(unsigned int channel, - struct s3c2410_dma_client *client, +int s3c2410_dma_request(unsigned int channel, struct s3c2410_dma_client *client, void *dev) { - struct s3c2410_dma_chan *chan; + struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; unsigned long flags; int err; pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n", channel, client->name, dev); - local_irq_save(flags); + check_channel(channel); - chan = s3c2410_dma_map_channel(channel); - if (chan == NULL) { - local_irq_restore(flags); - return -EBUSY; - } + local_irq_save(flags); dbg_showchan(chan); + if (chan->in_use) { + if (client != chan->client) { + printk(KERN_ERR "dma%d: already in use\n", channel); + local_irq_restore(flags); + return -EBUSY; + } else { + printk(KERN_ERR "dma%d: client already has channel\n", channel); + } + } + chan->client = client; chan->in_use = 1; @@ -803,14 +809,14 @@ EXPORT_SYMBOL(s3c2410_dma_request); int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client) { - struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); + struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; unsigned long flags; - if (chan == NULL) - return -EINVAL; + check_channel(channel); local_irq_save(flags); + if (chan->client != client) { printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n", channel, chan->client, client); @@ -831,12 +837,8 @@ int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client) if (chan->irq_claimed) free_irq(chan->irq, (void *)chan); - chan->irq_claimed = 0; - if (!(channel & DMACH_LOW_LEVEL)) - dma_chan_map[channel] = NULL; - local_irq_restore(flags); return 0; @@ -846,8 +848,8 @@ EXPORT_SYMBOL(s3c2410_dma_free); static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) { - unsigned long flags; unsigned long tmp; + unsigned long flags; pr_debug("%s:\n", __FUNCTION__); @@ -995,10 +997,9 @@ s3c2410_dma_started(struct s3c2410_dma_chan *chan) int s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op) { - struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); + struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; - if (chan == NULL) - return -EINVAL; + check_channel(channel); switch (op) { case S3C2410_DMAOP_START: @@ -1045,19 +1046,12 @@ int s3c2410_dma_config(dmach_t channel, int xferunit, int dcon) { - struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); + struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n", __FUNCTION__, channel, xferunit, dcon); - if (chan == NULL) - return -EINVAL; - - printk("Initial dcon is %08x\n", dcon); - - dcon |= chan->dcon & dma_sel.dcon_mask; - - printk("New dcon is %08x\n", dcon); + check_channel(channel); switch (xferunit) { case 1: @@ -1092,10 +1086,9 @@ EXPORT_SYMBOL(s3c2410_dma_config); int s3c2410_dma_setflags(dmach_t channel, unsigned int flags) { - struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); + struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; - if (chan == NULL) - return -EINVAL; + check_channel(channel); pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags); @@ -1113,10 +1106,9 @@ EXPORT_SYMBOL(s3c2410_dma_setflags); int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn) { - struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); + struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; - if (chan == NULL) - return -EINVAL; + check_channel(channel); pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn); @@ -1129,10 +1121,9 @@ EXPORT_SYMBOL(s3c2410_dma_set_opfn); int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn) { - struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); + struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; - if (chan == NULL) - return -EINVAL; + check_channel(channel); pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn); @@ -1162,10 +1153,9 @@ int s3c2410_dma_devconfig(int channel, int hwcfg, unsigned long devaddr) { - struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); + struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; - if (chan == NULL) - return -EINVAL; + check_channel(channel); pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n", __FUNCTION__, (int)source, hwcfg, devaddr); @@ -1210,10 +1200,9 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig); int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst) { - struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); + struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; - if (chan == NULL) - return -EINVAL; + check_channel(channel); if (src != NULL) *src = dma_rdreg(chan, S3C2410_DMA_DCSRC); @@ -1263,7 +1252,7 @@ static int s3c2410_dma_resume(struct sys_device *dev) #define s3c2410_dma_resume NULL #endif /* CONFIG_PM */ -struct sysdev_class dma_sysclass = { +static struct sysdev_class dma_sysclass = { set_kset_name("s3c24xx-dma"), .suspend = s3c2410_dma_suspend, .resume = s3c2410_dma_resume, @@ -1276,6 +1265,7 @@ static void s3c2410_dma_cache_ctor(void *p, kmem_cache_t *c, unsigned long f) memset(p, 0, sizeof(struct s3c2410_dma_buf)); } + /* initialisation code */ static int __init s3c2410_init_dma(void) @@ -1284,7 +1274,7 @@ static int __init s3c2410_init_dma(void) int channel; int ret; - printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n"); + printk("S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics\n"); dma_base = ioremap(S3C24XX_PA_DMA, 0x200); if (dma_base == NULL) { @@ -1292,8 +1282,6 @@ static int __init s3c2410_init_dma(void) return -ENOMEM; } - printk("Registering sysclass\n"); - ret = sysdev_class_register(&dma_sysclass); if (ret != 0) { printk(KERN_ERR "dma sysclass registration failed\n"); @@ -1347,95 +1335,4 @@ static int __init s3c2410_init_dma(void) return ret; } -core_initcall(s3c2410_init_dma); - -static inline int is_channel_valid(unsigned int channel) -{ - return (channel & DMA_CH_VALID); -} - -/* s3c2410_dma_map_channel() - * - * turn the virtual channel number into a real, and un-used hardware - * channel. - * - * currently this code uses first-free channel from the specified harware - * map, not taking into account anything that the board setup code may - * have to say about the likely peripheral set to be in use. -*/ - -struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) -{ - struct s3c24xx_dma_map *ch_map; - struct s3c2410_dma_chan *dmach; - int ch; - - if (dma_sel.map == NULL || channel > dma_sel.map_size) - return NULL; - - ch_map = dma_sel.map + channel; - - for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) { - if (!is_channel_valid(ch_map->channels[ch])) - continue; - - if (s3c2410_chans[ch].in_use == 0) { - printk("mapped channel %d to %d\n", channel, ch); - break; - } - } - - if (ch >= S3C2410_DMA_CHANNELS) - return NULL; - - /* update our channel mapping */ - - dmach = &s3c2410_chans[ch]; - dma_chan_map[channel] = dmach; - - /* select the channel */ - - (dma_sel.select)(dmach, ch_map); - - return dmach; -} - -static void s3c24xx_dma_show_ch(struct s3c24xx_dma_map *map, int ch) -{ - /* show the channel configuration */ - - printk("%2d: %20s, channels %c%c%c%c\n", ch, map->name, - (is_channel_valid(map->channels[0]) ? '0' : '-'), - (is_channel_valid(map->channels[1]) ? '1' : '-'), - (is_channel_valid(map->channels[2]) ? '2' : '-'), - (is_channel_valid(map->channels[3]) ? '3' : '-')); -} - -static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch) -{ - if (1) - s3c24xx_dma_show_ch(map, ch); - - return 0; -} - -int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel) -{ - struct s3c24xx_dma_map *nmap; - size_t map_sz = sizeof(*nmap) * sel->map_size; - int ptr; - - nmap = kmalloc(map_sz, GFP_KERNEL); - if (nmap == NULL) - return -ENOMEM; - - memcpy(nmap, sel->map, map_sz); - memcpy(&dma_sel, sel, sizeof(*sel)); - - dma_sel.map = nmap; - - for (ptr = 0; ptr < sel->map_size; ptr++) - s3c24xx_dma_check_entry(nmap+ptr, ptr); - - return 0; -} +__initcall(s3c2410_init_dma); diff --git a/trunk/arch/arm/mach-s3c2410/dma.h b/trunk/arch/arm/mach-s3c2410/dma.h deleted file mode 100644 index 0ebfe0aab80b..000000000000 --- a/trunk/arch/arm/mach-s3c2410/dma.h +++ /dev/null @@ -1,45 +0,0 @@ -/* arch/arm/mach-s3c2410/dma.h - * - * Copyright (C) 2006 Simtec Electronics - * Ben Dooks - * - * Samsung S3C24XX DMA support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -extern struct sysdev_class dma_sysclass; -extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; - -#define DMA_CH_VALID (1<<31) - -struct s3c24xx_dma_addr { - unsigned long from; - unsigned long to; -}; - -/* struct s3c24xx_dma_map - * - * this holds the mapping information for the channel selected - * to be connected to the specified device -*/ - -struct s3c24xx_dma_map { - const char *name; - struct s3c24xx_dma_addr hw_addr; - - unsigned long channels[S3C2410_DMA_CHANNELS]; -}; - -struct s3c24xx_dma_selection { - struct s3c24xx_dma_map *map; - unsigned long map_size; - unsigned long dcon_mask; - - void (*select)(struct s3c2410_dma_chan *chan, - struct s3c24xx_dma_map *map); -}; - -extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel); diff --git a/trunk/arch/arm/mach-s3c2410/gpio.c b/trunk/arch/arm/mach-s3c2410/gpio.c index db6393c99860..cd39e8684584 100644 --- a/trunk/arch/arm/mach-s3c2410/gpio.c +++ b/trunk/arch/arm/mach-s3c2410/gpio.c @@ -18,7 +18,21 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + * + * Changelog + * 13-Sep-2004 BJD Implemented change of MISCCR + * 14-Sep-2004 BJD Added getpin call + * 14-Sep-2004 BJD Fixed bug in setpin() call + * 30-Sep-2004 BJD Fixed cfgpin() mask bug + * 01-Oct-2004 BJD Added getcfg() to get pin configuration + * 01-Oct-2004 BJD Fixed mask bug in pullup() call + * 01-Oct-2004 BJD Added getirq() to turn pin into irqno + * 04-Oct-2004 BJD Added irq filter controls for GPIO + * 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code + * 13-Mar-2005 BJD Updates for __iomem + * 26-Oct-2005 BJD Added generic configuration types + * 15-Jan-2006 LCVR Added support for the S3C2400 + */ #include diff --git a/trunk/arch/arm/mach-s3c2410/irq.c b/trunk/arch/arm/mach-s3c2410/irq.c index 3e9f3462c61b..cd6139b35999 100644 --- a/trunk/arch/arm/mach-s3c2410/irq.c +++ b/trunk/arch/arm/mach-s3c2410/irq.c @@ -181,19 +181,17 @@ s3c_irq_unmask(unsigned int irqno) } struct irqchip s3c_irq_level_chip = { - .name = "s3c-level", - .ack = s3c_irq_maskack, - .mask = s3c_irq_mask, - .unmask = s3c_irq_unmask, - .set_wake = s3c_irq_wake + .ack = s3c_irq_maskack, + .mask = s3c_irq_mask, + .unmask = s3c_irq_unmask, + .set_wake = s3c_irq_wake }; static struct irqchip s3c_irq_chip = { - .name = "s3c", - .ack = s3c_irq_ack, - .mask = s3c_irq_mask, - .unmask = s3c_irq_unmask, - .set_wake = s3c_irq_wake + .ack = s3c_irq_ack, + .mask = s3c_irq_mask, + .unmask = s3c_irq_unmask, + .set_wake = s3c_irq_wake }; static void @@ -345,21 +343,19 @@ s3c_irqext_type(unsigned int irq, unsigned int type) } static struct irqchip s3c_irqext_chip = { - .name = "s3c-ext", - .mask = s3c_irqext_mask, - .unmask = s3c_irqext_unmask, - .ack = s3c_irqext_ack, - .set_type = s3c_irqext_type, - .set_wake = s3c_irqext_wake + .mask = s3c_irqext_mask, + .unmask = s3c_irqext_unmask, + .ack = s3c_irqext_ack, + .set_type = s3c_irqext_type, + .set_wake = s3c_irqext_wake }; static struct irqchip s3c_irq_eint0t4 = { - .name = "s3c-ext0", - .ack = s3c_irq_ack, - .mask = s3c_irq_mask, - .unmask = s3c_irq_unmask, - .set_wake = s3c_irq_wake, - .set_type = s3c_irqext_type, + .ack = s3c_irq_ack, + .mask = s3c_irq_mask, + .unmask = s3c_irq_unmask, + .set_wake = s3c_irq_wake, + .set_type = s3c_irqext_type, }; /* mask values for the parent registers for each of the interrupt types */ @@ -391,10 +387,9 @@ s3c_irq_uart0_ack(unsigned int irqno) } static struct irqchip s3c_irq_uart0 = { - .name = "s3c-uart0", - .mask = s3c_irq_uart0_mask, - .unmask = s3c_irq_uart0_unmask, - .ack = s3c_irq_uart0_ack, + .mask = s3c_irq_uart0_mask, + .unmask = s3c_irq_uart0_unmask, + .ack = s3c_irq_uart0_ack, }; /* UART1 */ @@ -418,10 +413,9 @@ s3c_irq_uart1_ack(unsigned int irqno) } static struct irqchip s3c_irq_uart1 = { - .name = "s3c-uart1", - .mask = s3c_irq_uart1_mask, - .unmask = s3c_irq_uart1_unmask, - .ack = s3c_irq_uart1_ack, + .mask = s3c_irq_uart1_mask, + .unmask = s3c_irq_uart1_unmask, + .ack = s3c_irq_uart1_ack, }; /* UART2 */ @@ -445,10 +439,9 @@ s3c_irq_uart2_ack(unsigned int irqno) } static struct irqchip s3c_irq_uart2 = { - .name = "s3c-uart2", - .mask = s3c_irq_uart2_mask, - .unmask = s3c_irq_uart2_unmask, - .ack = s3c_irq_uart2_ack, + .mask = s3c_irq_uart2_mask, + .unmask = s3c_irq_uart2_unmask, + .ack = s3c_irq_uart2_ack, }; /* ADC and Touchscreen */ @@ -472,10 +465,9 @@ s3c_irq_adc_ack(unsigned int irqno) } static struct irqchip s3c_irq_adc = { - .name = "s3c-adc", - .mask = s3c_irq_adc_mask, - .unmask = s3c_irq_adc_unmask, - .ack = s3c_irq_adc_ack, + .mask = s3c_irq_adc_mask, + .unmask = s3c_irq_adc_unmask, + .ack = s3c_irq_adc_ack, }; /* irq demux for adc */ @@ -577,104 +569,23 @@ s3c_irq_demux_uart2(unsigned int irq, } static void -s3c_irq_demux_extint8(unsigned int irq, - struct irqdesc *desc, - struct pt_regs *regs) +s3c_irq_demux_extint(unsigned int irq, + struct irqdesc *desc, + struct pt_regs *regs) { unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND); unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK); eintpnd &= ~eintmsk; - eintpnd &= ~0xff; /* ignore lower irqs */ - /* we may as well handle all the pending IRQs here */ + if (eintpnd) { + irq = fls(eintpnd); + irq += (IRQ_EINT4 - (4 + 1)); - while (eintpnd) { - irq = __ffs(eintpnd); - eintpnd &= ~(1< - - * 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 - * - * @History: - * derived from linux/arch/arm/mach-s3c2410/mach-bast.c, written by - * Ben Dooks - * - ***********************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "devs.h" -#include "cpu.h" - -#ifdef CONFIG_MTD_PARTITIONS - -#include -#include -#include -#include - -static struct resource amlm5900_nor_resource = { - .start = 0x00000000, - .end = 0x01000000 - 1, - .flags = IORESOURCE_MEM, -}; - - - -static struct mtd_partition amlm5900_mtd_partitions[] = { - { - .name = "System", - .size = 0x240000, - .offset = 0, - .mask_flags = MTD_WRITEABLE, /* force read-only */ - }, { - .name = "Kernel", - .size = 0x100000, - .offset = MTDPART_OFS_APPEND, - }, { - .name = "Ramdisk", - .size = 0x300000, - .offset = MTDPART_OFS_APPEND, - }, { - .name = "JFFS2", - .size = 0x9A0000, - .offset = MTDPART_OFS_APPEND, - }, { - .name = "Settings", - .size = MTDPART_SIZ_FULL, - .offset = MTDPART_OFS_APPEND, - } -}; - -static struct physmap_flash_data amlm5900_flash_data = { - .width = 2, - .parts = amlm5900_mtd_partitions, - .nr_parts = ARRAY_SIZE(amlm5900_mtd_partitions), -}; - -static struct platform_device amlm5900_device_nor = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &amlm5900_flash_data, - }, - .num_resources = 1, - .resource = &amlm5900_nor_resource, -}; -#endif - -static struct map_desc amlm5900_iodesc[] __initdata = { - { - .virtual = (u32)S3C24XX_VA_SPI, - .pfn = __phys_to_pfn(S3C2410_PA_SPI), - .length = SZ_1M, - .type = MT_DEVICE - } -}; - -#define UCON S3C2410_UCON_DEFAULT -#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB -#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE - -static struct s3c2410_uartcfg amlm5900_uartcfgs[] = { - [0] = { - .hwport = 0, - .flags = 0, - .ucon = UCON, - .ulcon = ULCON, - .ufcon = UFCON, - }, - [1] = { - .hwport = 1, - .flags = 0, - .ucon = UCON, - .ulcon = ULCON, - .ufcon = UFCON, - }, - [2] = { - .hwport = 2, - .flags = 0, - .ucon = UCON, - .ulcon = ULCON, - .ufcon = UFCON, - } -}; - - -static struct platform_device *amlm5900_devices[] __initdata = { -#ifdef CONFIG_FB_S3C2410 - &s3c_device_lcd, -#endif - &s3c_device_adc, - &s3c_device_wdt, - &s3c_device_i2c, - &s3c_device_usb, - &s3c_device_rtc, - &s3c_device_usbgadget, - &s3c_device_sdi, -#ifdef CONFIG_MTD_PARTITIONS - &amlm5900_device_nor, -#endif -}; - -static struct s3c24xx_board amlm5900_board __initdata = { - .devices = amlm5900_devices, - .devices_count = ARRAY_SIZE(amlm5900_devices) -}; - -void __init amlm5900_map_io(void) -{ - s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc)); - s3c24xx_init_clocks(0); - s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs)); - s3c24xx_set_board(&amlm5900_board); -} - -#ifdef CONFIG_FB_S3C2410 -static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = { - .width = 160, - .height = 160, - -/* commented out until stn patch is submitted -* .type = S3C2410_LCDCON1_STN4, -*/ - .gpccon = 0xaaaaaaaa, - .gpccon_mask = 0xffffffff, - .gpcup = 0x0000ffff, - .gpcup_mask = 0xffffffff, - - .gpdcon = 0xaaaaaaaa, - .gpdcon_mask = 0xffffffff, - .gpdup = 0x0000ffff, - .gpdup_mask = 0xffffffff, - - .xres = { - .min = 160, - .max = 160, - .defval = 160, - }, - - .yres = { - .min = 160, - .max = 160, - .defval = 160, - }, - - .bpp = { - .min = 4, - .max = 4, - .defval = 4, - }, - - .regs = { - .lcdcon1 = 0x00008225, - .lcdcon2 = 0x0027c000, - .lcdcon3 = 0x00182708, - .lcdcon4 = 0x00000002, - .lcdcon5 = 0x00000001, - } -}; -#endif - -static irqreturn_t -amlm5900_wake_interrupt(int irq, void *ignored, struct pt_regs *regs) -{ - return IRQ_HANDLED; -} - -static void amlm5900_init_pm(void) -{ - int ret = 0; - - ret = request_irq(IRQ_EINT9, &amlm5900_wake_interrupt, - IRQF_TRIGGER_RISING | IRQF_SHARED, - "amlm5900_wakeup", &amlm5900_wake_interrupt); - if (ret != 0) { - printk(KERN_ERR "AML-M5900: no wakeup irq, %d?\n", ret); - } else { - enable_irq_wake(IRQ_EINT9); - /* configure the suspend/resume status pin */ - s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_OUTP); - s3c2410_gpio_pullup(S3C2410_GPF2, 0); - } -} -static void __init amlm5900_init(void) -{ - amlm5900_init_pm(); -#ifdef CONFIG_FB_S3C2410 - s3c24xx_fb_set_platdata(&amlm5900_lcd_info); -#endif -} - -MACHINE_START(AML_M5900, "AML_M5900") - .phys_io = S3C2410_PA_UART, - .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, - .boot_params = S3C2410_SDRAM_PA + 0x100, - .map_io = amlm5900_map_io, - .init_irq = s3c24xx_init_irq, - .init_machine = amlm5900_init, - .timer = &s3c24xx_timer, -MACHINE_END diff --git a/trunk/arch/arm/mach-s3c2410/mach-anubis.c b/trunk/arch/arm/mach-s3c2410/mach-anubis.c index e94cdcd96591..60641d452db3 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-anubis.c +++ b/trunk/arch/arm/mach-s3c2410/mach-anubis.c @@ -4,9 +4,15 @@ * http://armlinux.simtec.co.uk/ * Ben Dooks * + * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. + * + * Modifications: + * 02-May-2005 BJD Copied from mach-bast.c + * 20-Sep-2005 BJD Added static to non-exported items */ #include diff --git a/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c b/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c index e2205ff1b0ee..d661c6b7ff56 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c @@ -11,6 +11,15 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * + * Modifications: + * 01-Nov-2004 BJD Initial version + * 12-Nov-2004 BJD Updated for release + * 04-Jan-2005 BJD Fixes for pre-release + * 22-Feb-2005 BJD Updated for 2.6.11-rc5 relesa + * 10-Mar-2005 LCVR Replaced S3C2410_VA by S3C24XX_VA + * 14-Mar-2005 BJD void __iomem fixes + * 20-Sep-2005 BJD Added static to non-exported items + * 26-Oct-2005 BJD Added framebuffer data */ #include diff --git a/trunk/arch/arm/mach-s3c2410/mach-vstms.c b/trunk/arch/arm/mach-s3c2410/mach-vstms.c deleted file mode 100644 index ea554e7c006e..000000000000 --- a/trunk/arch/arm/mach-s3c2410/mach-vstms.c +++ /dev/null @@ -1,168 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/mach-vstms.c - * - * (C) 2006 Thomas Gleixner - * - * Derived from mach-smdk2413.c - (C) 2006 Simtec Electronics - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include - -#include "s3c2410.h" -#include "s3c2412.h" -#include "clock.h" -#include "devs.h" -#include "cpu.h" - - -static struct map_desc vstms_iodesc[] __initdata = { -}; - -static struct s3c2410_uartcfg vstms_uartcfgs[] __initdata = { - [0] = { - .hwport = 0, - .flags = 0, - .ucon = 0x3c5, - .ulcon = 0x03, - .ufcon = 0x51, - }, - [1] = { - .hwport = 1, - .flags = 0, - .ucon = 0x3c5, - .ulcon = 0x03, - .ufcon = 0x51, - }, - [2] = { - .hwport = 2, - .flags = 0, - .ucon = 0x3c5, - .ulcon = 0x03, - .ufcon = 0x51, - } -}; - -static struct mtd_partition vstms_nand_part[] = { - [0] = { - .name = "Boot Agent", - .size = 0x7C000, - .offset = 0, - }, - [1] = { - .name = "UBoot Config", - .offset = 0x7C000, - .size = 0x4000, - }, - [2] = { - .name = "Kernel", - .offset = 0x80000, - .size = 0x200000, - }, - [3] = { - .name = "RFS", - .offset = 0x280000, - .size = 0x3d80000, - }, -}; - -static struct s3c2410_nand_set vstms_nand_sets[] = { - [0] = { - .name = "NAND", - .nr_chips = 1, - .nr_partitions = ARRAY_SIZE(vstms_nand_part), - .partitions = vstms_nand_part, - }, -}; - -/* choose a set of timings which should suit most 512Mbit - * chips and beyond. -*/ - -static struct s3c2410_platform_nand vstms_nand_info = { - .tacls = 20, - .twrph0 = 60, - .twrph1 = 20, - .nr_sets = ARRAY_SIZE(vstms_nand_sets), - .sets = vstms_nand_sets, -}; - -static struct platform_device *vstms_devices[] __initdata = { - &s3c_device_usb, - &s3c_device_wdt, - &s3c_device_i2c, - &s3c_device_iis, - &s3c_device_rtc, - &s3c_device_nand, -}; - -static struct s3c24xx_board vstms_board __initdata = { - .devices = vstms_devices, - .devices_count = ARRAY_SIZE(vstms_devices) -}; - -static void __init vstms_fixup(struct machine_desc *desc, - struct tag *tags, char **cmdline, - struct meminfo *mi) -{ - if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) { - mi->nr_banks=1; - mi->bank[0].start = 0x30000000; - mi->bank[0].size = SZ_64M; - mi->bank[0].node = 0; - } -} - -static void __init vstms_map_io(void) -{ - s3c_device_nand.dev.platform_data = &vstms_nand_info; - - s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc)); - s3c24xx_init_clocks(12000000); - s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs)); - s3c24xx_set_board(&vstms_board); -} - -MACHINE_START(VSTMS, "VSTMS") - .phys_io = S3C2410_PA_UART, - .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, - .boot_params = S3C2410_SDRAM_PA + 0x100, - - .fixup = vstms_fixup, - .init_irq = s3c24xx_init_irq, - .map_io = vstms_map_io, - .timer = &s3c24xx_timer, -MACHINE_END diff --git a/trunk/arch/arm/mach-s3c2410/pm-simtec.c b/trunk/arch/arm/mach-s3c2410/pm-simtec.c index 42cd05e298f8..7b244566a436 100644 --- a/trunk/arch/arm/mach-s3c2410/pm-simtec.c +++ b/trunk/arch/arm/mach-s3c2410/pm-simtec.c @@ -49,8 +49,7 @@ static __init int pm_simtec_init(void) /* check which machine we are running on */ if (!machine_is_bast() && !machine_is_vr1000() && - !machine_is_anubis() && !machine_is_osiris() && - !machine_is_aml_m5900()) + !machine_is_anubis() && !machine_is_osiris()) return 0; printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n"); diff --git a/trunk/arch/arm/mach-s3c2410/pm.c b/trunk/arch/arm/mach-s3c2410/pm.c index b49a0b3b72b3..a589fe76d915 100644 --- a/trunk/arch/arm/mach-s3c2410/pm.c +++ b/trunk/arch/arm/mach-s3c2410/pm.c @@ -1,9 +1,9 @@ /* linux/arch/arm/mach-s3c2410/pm.c * - * Copyright (c) 2004,2006 Simtec Electronics + * Copyright (c) 2004 Simtec Electronics * Ben Dooks * - * S3C24XX Power Manager (Suspend-To-RAM) support + * S3C2410 Power Manager (Suspend-To-RAM) support * * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information * @@ -24,6 +24,9 @@ * Parts based on arch/arm/mach-pxa/pm.c * * Thanks to Dimitry Andric for debugging + * + * Modifications: + * 10-Mar-2005 LCVR Changed S3C2410_VA_UART to S3C24XX_VA_UART */ #include @@ -35,7 +38,6 @@ #include #include -#include #include #include @@ -53,6 +55,14 @@ unsigned long s3c_pm_flags; +/* cache functions from arch/arm/mm/proc-arm920.S */ + +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH +extern void arm920_flush_kern_cache_all(void); +#else +static void arm920_flush_kern_cache_all(void) { } +#endif + #define PFX "s3c24xx-pm: " static struct sleep_save core_save[] = { @@ -82,6 +92,19 @@ static struct sleep_save core_save[] = { SAVE_ITEM(S3C2410_REFRESH), }; +/* this lot should be really saved by the IRQ code */ +static struct sleep_save irq_save[] = { + SAVE_ITEM(S3C2410_EXTINT0), + SAVE_ITEM(S3C2410_EXTINT1), + SAVE_ITEM(S3C2410_EXTINT2), + SAVE_ITEM(S3C2410_EINFLT0), + SAVE_ITEM(S3C2410_EINFLT1), + SAVE_ITEM(S3C2410_EINFLT2), + SAVE_ITEM(S3C2410_EINFLT3), + SAVE_ITEM(S3C2410_EINTMASK), + SAVE_ITEM(S3C2410_INTMSK) +}; + static struct sleep_save gpio_save[] = { SAVE_ITEM(S3C2410_GPACON), SAVE_ITEM(S3C2410_GPADAT), @@ -142,7 +165,7 @@ static struct sleep_save uart_save[] = { extern void printascii(const char *); -void pm_dbg(const char *fmt, ...) +static void pm_dbg(const char *fmt, ...) { va_list va; char buff[256]; @@ -486,9 +509,6 @@ static void s3c2410_pm_configure_extint(void) } } -void (*pm_cpu_prep)(void); -void (*pm_cpu_sleep)(void); - #define any_allowed(mask, allow) (((mask) & (allow)) != (allow)) /* s3c2410_pm_enter @@ -499,6 +519,7 @@ void (*pm_cpu_sleep)(void); static int s3c2410_pm_enter(suspend_state_t state) { unsigned long regs_save[16]; + unsigned long tmp; /* ensure the debug is initialised (if enabled) */ @@ -506,11 +527,6 @@ static int s3c2410_pm_enter(suspend_state_t state) DBG("s3c2410_pm_enter(%d)\n", state); - if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) { - printk(KERN_ERR PFX "error: no cpu sleep functions set\n"); - return -EINVAL; - } - if (state != PM_SUSPEND_MEM) { printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n"); return -EINVAL; @@ -538,9 +554,17 @@ static int s3c2410_pm_enter(suspend_state_t state) DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys); + /* ensure at least GESTATUS3 has the resume address */ + + __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3); + + DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3)); + DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4)); + /* save all necessary core registers not covered by the drivers */ s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save)); + s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save)); s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); @@ -557,16 +581,10 @@ static int s3c2410_pm_enter(suspend_state_t state) /* ack any outstanding external interrupts before we go to sleep */ __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND); - __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND); - __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND); - - /* call cpu specific preperation */ - - pm_cpu_prep(); /* flush cache back to ram */ - flush_cache_all(); + arm920_flush_kern_cache_all(); s3c2410_pm_check_store(); @@ -574,23 +592,23 @@ static int s3c2410_pm_enter(suspend_state_t state) __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */ - /* s3c2410_cpu_save will also act as our return point from when - * we resume as it saves its own register state, so use the return - * code to differentiate return from save and return from sleep */ - - if (s3c2410_cpu_save(regs_save) == 0) { - flush_cache_all(); - pm_cpu_sleep(); - } + s3c2410_cpu_suspend(regs_save); /* restore the cpu state */ cpu_init(); + /* unset the return-from-sleep flag, to ensure reset */ + + tmp = __raw_readl(S3C2410_GSTATUS2); + tmp &= S3C2410_GSTATUS2_OFFRESET; + __raw_writel(tmp, S3C2410_GSTATUS2); + /* restore the system state */ s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save)); s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); + s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); s3c2410_pm_debug_init(); diff --git a/trunk/arch/arm/mach-s3c2410/pm.h b/trunk/arch/arm/mach-s3c2410/pm.h index ffe197a119fb..7a5e714c7386 100644 --- a/trunk/arch/arm/mach-s3c2410/pm.h +++ b/trunk/arch/arm/mach-s3c2410/pm.h @@ -34,19 +34,13 @@ extern unsigned long s3c_irqwake_eintmask; extern unsigned long s3c_irqwake_intallow; extern unsigned long s3c_irqwake_eintallow; -/* per-cpu sleep functions */ - -extern void (*pm_cpu_prep)(void); -extern void (*pm_cpu_sleep)(void); - /* Flags for PM Control */ extern unsigned long s3c_pm_flags; /* from sleep.S */ -extern int s3c2410_cpu_save(unsigned long *saveblk); -extern void s3c2410_cpu_suspend(void); +extern void s3c2410_cpu_suspend(unsigned long *saveblk); extern void s3c2410_cpu_resume(void); extern unsigned long s3c2410_sleep_save_phys; @@ -63,11 +57,3 @@ struct sleep_save { extern void s3c2410_pm_do_save(struct sleep_save *ptr, int count); extern void s3c2410_pm_do_restore(struct sleep_save *ptr, int count); - -#ifdef CONFIG_PM -extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state); -extern int s3c24xx_irq_resume(struct sys_device *dev); -#else -#define s3c24xx_irq_suspend NULL -#define s3c24xx_irq_resume NULL -#endif diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410-dma.c b/trunk/arch/arm/mach-s3c2410/s3c2410-dma.c deleted file mode 100644 index 51e5098b32e8..000000000000 --- a/trunk/arch/arm/mach-s3c2410/s3c2410-dma.c +++ /dev/null @@ -1,158 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/s3c2410-dma.c - * - * (c) 2006 Simtec Electronics - * Ben Dooks - * - * S3C2410 DMA selection - * - * http://armlinux.simtec.co.uk/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include - -#include -#include -#include "dma.h" - -#include "cpu.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = { - [DMACH_XD0] = { - .name = "xdreq0", - .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID, - }, - [DMACH_XD1] = { - .name = "xdreq1", - .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID, - }, - [DMACH_SDI] = { - .name = "sdi", - .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID, - .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID, - .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, - .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, - }, - [DMACH_SPI0] = { - .name = "spi0", - .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT, - .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT, - }, - [DMACH_SPI1] = { - .name = "spi1", - .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT, - .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT, - }, - [DMACH_UART0] = { - .name = "uart0", - .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, - }, - [DMACH_UART1] = { - .name = "uart1", - .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, - }, - [DMACH_UART2] = { - .name = "uart2", - .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, - }, - [DMACH_TIMER] = { - .name = "timer", - .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID, - .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID, - .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID, - }, - [DMACH_I2S_IN] = { - .name = "i2s-sdi", - .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID, - .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID, - .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, - }, - [DMACH_I2S_OUT] = { - .name = "i2s-sdo", - .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, - }, - [DMACH_USB_EP1] = { - .name = "usb-ep1", - .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID, - }, - [DMACH_USB_EP2] = { - .name = "usb-ep2", - .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID, - }, - [DMACH_USB_EP3] = { - .name = "usb-ep3", - .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID, - }, - [DMACH_USB_EP4] = { - .name = "usb-ep4", - .channels[3] =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID, - }, -}; - -static void s3c2410_dma_select(struct s3c2410_dma_chan *chan, - struct s3c24xx_dma_map *map) -{ - chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID; -} - -static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = { - .select = s3c2410_dma_select, - .dcon_mask = 7 << 24, - .map = s3c2410_dma_mappings, - .map_size = ARRAY_SIZE(s3c2410_dma_mappings), -}; - -static int s3c2410_dma_add(struct sys_device *sysdev) -{ - return s3c24xx_dma_init_map(&s3c2410_dma_sel); -} - -static struct sysdev_driver s3c2410_dma_driver = { - .add = s3c2410_dma_add, -}; - -static int __init s3c2410_dma_init(void) -{ - return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver); -} - -arch_initcall(s3c2410_dma_init); - -/* S3C2442 DMA contains the same selection table as the S3C2410 */ - -static struct sysdev_driver s3c2442_dma_driver = { - .add = s3c2410_dma_add, -}; - -static int __init s3c2442_dma_init(void) -{ - return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver); -} - -arch_initcall(s3c2442_dma_init); - - diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410-irq.c b/trunk/arch/arm/mach-s3c2410/s3c2410-irq.c deleted file mode 100644 index c796c9c76e78..000000000000 --- a/trunk/arch/arm/mach-s3c2410/s3c2410-irq.c +++ /dev/null @@ -1,48 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/s3c2410-irq.c - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * 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 "cpu.h" -#include "pm.h" - -static int s3c2410_irq_add(struct sys_device *sysdev) -{ - return 0; -} - -static struct sysdev_driver s3c2410_irq_driver = { - .add = s3c2410_irq_add, - .suspend = s3c24xx_irq_suspend, - .resume = s3c24xx_irq_resume, -}; - -static int s3c2410_irq_init(void) -{ - return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver); -} - -arch_initcall(s3c2410_irq_init); diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410-pm.c b/trunk/arch/arm/mach-s3c2410/s3c2410-pm.c deleted file mode 100644 index e51d76669512..000000000000 --- a/trunk/arch/arm/mach-s3c2410/s3c2410-pm.c +++ /dev/null @@ -1,120 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/s3c2410-pm.c - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#include "cpu.h" -#include "pm.h" - -#ifdef CONFIG_S3C2410_PM_DEBUG -extern void pm_dbg(const char *fmt, ...); -#define DBG(fmt...) pm_dbg(fmt) -#else -#define DBG(fmt...) printk(KERN_DEBUG fmt) -#endif - -static void s3c2410_pm_prepare(void) -{ - /* ensure at least GSTATUS3 has the resume address */ - - __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3); - - DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3)); - DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4)); - - if ( machine_is_aml_m5900() ) - s3c2410_gpio_setpin(S3C2410_GPF2, 1); - -} - -int s3c2410_pm_resume(struct sys_device *dev) -{ - unsigned long tmp; - - /* unset the return-from-sleep flag, to ensure reset */ - - tmp = __raw_readl(S3C2410_GSTATUS2); - tmp &= S3C2410_GSTATUS2_OFFRESET; - __raw_writel(tmp, S3C2410_GSTATUS2); - - if ( machine_is_aml_m5900() ) - s3c2410_gpio_setpin(S3C2410_GPF2, 0); - - return 0; -} - -static int s3c2410_pm_add(struct sys_device *dev) -{ - pm_cpu_prep = s3c2410_pm_prepare; - pm_cpu_sleep = s3c2410_cpu_suspend; - - return 0; -} - -static struct sysdev_driver s3c2410_pm_driver = { - .add = s3c2410_pm_add, - .resume = s3c2410_pm_resume, -}; - -/* register ourselves */ - -static int __init s3c2410_pm_drvinit(void) -{ - return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver); -} - -arch_initcall(s3c2410_pm_drvinit); - -static struct sysdev_driver s3c2440_pm_driver = { - .add = s3c2410_pm_add, - .resume = s3c2410_pm_resume, -}; - -static int __init s3c2440_pm_drvinit(void) -{ - return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver); -} - -arch_initcall(s3c2440_pm_drvinit); - -static struct sysdev_driver s3c2442_pm_driver = { - .add = s3c2410_pm_add, - .resume = s3c2410_pm_resume, -}; - -static int __init s3c2442_pm_drvinit(void) -{ - return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver); -} - -arch_initcall(s3c2442_pm_drvinit); diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410-sleep.S b/trunk/arch/arm/mach-s3c2410/s3c2410-sleep.S deleted file mode 100644 index 9179a1024588..000000000000 --- a/trunk/arch/arm/mach-s3c2410/s3c2410-sleep.S +++ /dev/null @@ -1,68 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S - * - * Copyright (c) 2004 Simtec Electronics - * Ben Dooks - * - * S3C2410 Power Manager (Suspend-To-RAM) support - * - * Based on PXA/SA1100 sleep code by: - * Nicolas Pitre, (c) 2002 Monta Vista Software Inc - * Cliff Brake, (c) 2001 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include -#include -#include -#include - -#include -#include -#include -#include - - /* s3c2410_cpu_suspend - * - * put the cpu into sleep mode - */ - -ENTRY(s3c2410_cpu_suspend) - @@ prepare cpu to sleep - - ldr r4, =S3C2410_REFRESH - ldr r5, =S3C24XX_MISCCR - ldr r6, =S3C2410_CLKCON - ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB) - ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB) - ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB) - - orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command - orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals - orr r9, r9, #S3C2410_CLKCON_POWER @ power down command - - teq pc, #0 @ first as a trial-run to load cache - bl s3c2410_do_sleep - teq r0, r0 @ now do it for real - b s3c2410_do_sleep @ - - @@ align next bit of code to cache line - .align 8 -s3c2410_do_sleep: - streq r7, [ r4 ] @ SDRAM sleep command - streq r8, [ r5 ] @ SDRAM power-down config - streq r9, [ r6 ] @ CPU sleep -1: beq 1b - mov pc, r14 diff --git a/trunk/arch/arm/mach-s3c2410/s3c2410.c b/trunk/arch/arm/mach-s3c2410/s3c2410.c index 183e4033ce61..a110cff9cf6b 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2410.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2410.c @@ -8,6 +8,17 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. + * + * Modifications: + * 16-May-2003 BJD Created initial version + * 16-Aug-2003 BJD Fixed header files and copyright, added URL + * 05-Sep-2003 BJD Moved to kernel v2.6 + * 18-Jan-2004 BJD Added serial port configuration + * 21-Aug-2004 BJD Added new struct s3c2410_board handler + * 28-Sep-2004 BJD Updates for new serial port bits + * 04-Nov-2004 BJD Updated UART configuration process + * 10-Jan-2005 BJD Removed s3c2410_clock_tick_rate + * 13-Aug-2005 DA Removed UART from initial I/O mappings */ #include diff --git a/trunk/arch/arm/mach-s3c2410/s3c2412-dma.c b/trunk/arch/arm/mach-s3c2410/s3c2412-dma.c deleted file mode 100644 index 171f3706d36d..000000000000 --- a/trunk/arch/arm/mach-s3c2410/s3c2412-dma.c +++ /dev/null @@ -1,160 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/s3c2412-dma.c - * - * (c) 2006 Simtec Electronics - * Ben Dooks - * - * S3C2412 DMA selection - * - * http://armlinux.simtec.co.uk/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include - -#include -#include -#include - -#include "dma.h" -#include "cpu.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID } - -static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = { - [DMACH_XD0] = { - .name = "xdreq0", - .channels = MAP(S3C2412_DMAREQSEL_XDREQ0), - }, - [DMACH_XD1] = { - .name = "xdreq1", - .channels = MAP(S3C2412_DMAREQSEL_XDREQ1), - }, - [DMACH_SDI] = { - .name = "sdi", - .channels = MAP(S3C2412_DMAREQSEL_SDI), - .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, - .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, - }, - [DMACH_SPI0] = { - .name = "spi0", - .channels = MAP(S3C2412_DMAREQSEL_SPI0TX), - .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT, - .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT, - }, - [DMACH_SPI1] = { - .name = "spi1", - .channels = MAP(S3C2412_DMAREQSEL_SPI1TX), - .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT, - .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT, - }, - [DMACH_UART0] = { - .name = "uart0", - .channels = MAP(S3C2412_DMAREQSEL_UART0_0), - .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, - }, - [DMACH_UART1] = { - .name = "uart1", - .channels = MAP(S3C2412_DMAREQSEL_UART1_0), - .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, - }, - [DMACH_UART2] = { - .name = "uart2", - .channels = MAP(S3C2412_DMAREQSEL_UART2_0), - .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, - }, - [DMACH_UART0_SRC2] = { - .name = "uart0", - .channels = MAP(S3C2412_DMAREQSEL_UART0_1), - .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, - }, - [DMACH_UART1_SRC2] = { - .name = "uart1", - .channels = MAP(S3C2412_DMAREQSEL_UART1_1), - .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, - }, - [DMACH_UART2_SRC2] = { - .name = "uart2", - .channels = MAP(S3C2412_DMAREQSEL_UART2_1), - .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, - }, - [DMACH_TIMER] = { - .name = "timer", - .channels = MAP(S3C2412_DMAREQSEL_TIMER), - }, - [DMACH_I2S_IN] = { - .name = "i2s-sdi", - .channels = MAP(S3C2412_DMAREQSEL_I2SRX), - .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, - }, - [DMACH_I2S_OUT] = { - .name = "i2s-sdo", - .channels = MAP(S3C2412_DMAREQSEL_I2STX), - .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, - }, - [DMACH_USB_EP1] = { - .name = "usb-ep1", - .channels = MAP(S3C2412_DMAREQSEL_USBEP1), - }, - [DMACH_USB_EP2] = { - .name = "usb-ep2", - .channels = MAP(S3C2412_DMAREQSEL_USBEP2), - }, - [DMACH_USB_EP3] = { - .name = "usb-ep3", - .channels = MAP(S3C2412_DMAREQSEL_USBEP3), - }, - [DMACH_USB_EP4] = { - .name = "usb-ep4", - .channels = MAP(S3C2412_DMAREQSEL_USBEP4), - }, -}; - -static void s3c2412_dma_select(struct s3c2410_dma_chan *chan, - struct s3c24xx_dma_map *map) -{ - writel(chan->regs + S3C2412_DMA_DMAREQSEL, - map->channels[0] | S3C2412_DMAREQSEL_HW); -} - -static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = { - .select = s3c2412_dma_select, - .dcon_mask = 0, - .map = s3c2412_dma_mappings, - .map_size = ARRAY_SIZE(s3c2412_dma_mappings), -}; - -static int s3c2412_dma_add(struct sys_device *sysdev) -{ - return s3c24xx_dma_init_map(&s3c2412_dma_sel); -} - -static struct sysdev_driver s3c2412_dma_driver = { - .add = s3c2412_dma_add, -}; - -static int __init s3c2412_dma_init(void) -{ - return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_dma_driver); -} - -arch_initcall(s3c2412_dma_init); diff --git a/trunk/arch/arm/mach-s3c2410/s3c2412-irq.c b/trunk/arch/arm/mach-s3c2410/s3c2412-irq.c index 7f741547658f..c80ec93dfea9 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2412-irq.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2412-irq.c @@ -37,7 +37,6 @@ #include "cpu.h" #include "irq.h" -#include "pm.h" /* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by * having them turn up in both the INT* and the EINT* registers. Whilst @@ -121,8 +120,6 @@ static int s3c2412_irq_add(struct sys_device *sysdev) static struct sysdev_driver s3c2412_irq_driver = { .add = s3c2412_irq_add, - .suspend = s3c24xx_irq_suspend, - .resume = s3c24xx_irq_resume, }; static int s3c2412_irq_init(void) diff --git a/trunk/arch/arm/mach-s3c2410/s3c2412-pm.c b/trunk/arch/arm/mach-s3c2410/s3c2412-pm.c deleted file mode 100644 index 19b63322d259..000000000000 --- a/trunk/arch/arm/mach-s3c2410/s3c2412-pm.c +++ /dev/null @@ -1,128 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/s3c2412-pm.c - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * http://armlinux.simtec.co.uk/. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include "cpu.h" -#include "pm.h" - -#include "s3c2412.h" - -static void s3c2412_cpu_suspend(void) -{ - unsigned long tmp; - - /* set our standby method to sleep */ - - tmp = __raw_readl(S3C2412_PWRCFG); - tmp |= S3C2412_PWRCFG_STANDBYWFI_SLEEP; - __raw_writel(tmp, S3C2412_PWRCFG); - - /* issue the standby signal into the pm unit. Note, we - * issue a write-buffer drain just in case */ - - tmp = 0; - - asm("b 1f\n\t" - ".align 5\n\t" - "1:\n\t" - "mcr p15, 0, %0, c7, c10, 4\n\t" - "mcr p15, 0, %0, c7, c0, 4" :: "r" (tmp)); - - /* we should never get past here */ - - panic("sleep resumed to originator?"); -} - -static void s3c2412_pm_prepare(void) -{ -} - -static int s3c2412_pm_add(struct sys_device *sysdev) -{ - pm_cpu_prep = s3c2412_pm_prepare; - pm_cpu_sleep = s3c2412_cpu_suspend; - - return 0; -} - -static struct sleep_save s3c2412_sleep[] = { - SAVE_ITEM(S3C2412_DSC0), - SAVE_ITEM(S3C2412_DSC1), - SAVE_ITEM(S3C2413_GPJDAT), - SAVE_ITEM(S3C2413_GPJCON), - SAVE_ITEM(S3C2413_GPJUP), - - /* save the PWRCFG to get back to original sleep method */ - - SAVE_ITEM(S3C2412_PWRCFG), - - /* save the sleep configuration anyway, just in case these - * get damaged during wakeup */ - - SAVE_ITEM(S3C2412_GPBSLPCON), - SAVE_ITEM(S3C2412_GPCSLPCON), - SAVE_ITEM(S3C2412_GPDSLPCON), - SAVE_ITEM(S3C2412_GPESLPCON), - SAVE_ITEM(S3C2412_GPFSLPCON), - SAVE_ITEM(S3C2412_GPGSLPCON), - SAVE_ITEM(S3C2412_GPHSLPCON), - SAVE_ITEM(S3C2413_GPJSLPCON), -}; - -static int s3c2412_pm_suspend(struct sys_device *dev, pm_message_t state) -{ - s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); - return 0; -} - -static int s3c2412_pm_resume(struct sys_device *dev) -{ - unsigned long tmp; - - tmp = __raw_readl(S3C2412_PWRCFG); - tmp &= ~S3C2412_PWRCFG_STANDBYWFI_MASK; - tmp |= S3C2412_PWRCFG_STANDBYWFI_IDLE; - __raw_writel(tmp, S3C2412_PWRCFG); - - s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); - return 0; -} - -static struct sysdev_driver s3c2412_pm_driver = { - .add = s3c2412_pm_add, - .suspend = s3c2412_pm_suspend, - .resume = s3c2412_pm_resume, -}; - -static __init int s3c2412_pm_init(void) -{ - return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_pm_driver); -} - -arch_initcall(s3c2412_pm_init); diff --git a/trunk/arch/arm/mach-s3c2410/s3c2412.c b/trunk/arch/arm/mach-s3c2410/s3c2412.c index e76431c41461..2d163f7600be 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2412.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2412.c @@ -8,6 +8,17 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. + * + * Modifications: + * 16-May-2003 BJD Created initial version + * 16-Aug-2003 BJD Fixed header files and copyright, added URL + * 05-Sep-2003 BJD Moved to kernel v2.6 + * 18-Jan-2004 BJD Added serial port configuration + * 21-Aug-2004 BJD Added new struct s3c2410_board handler + * 28-Sep-2004 BJD Updates for new serial port bits + * 04-Nov-2004 BJD Updated UART configuration process + * 10-Jan-2005 BJD Removed s3c2410_clock_tick_rate + * 13-Aug-2005 DA Removed UART from initial I/O mappings */ #include @@ -45,13 +56,6 @@ #ifndef CONFIG_CPU_S3C2412_ONLY void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; - -static inline void s3c2412_init_gpio2(void) -{ - s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10; -} -#else -#define s3c2412_init_gpio2() do { } while(0) #endif /* Initial IO mappings */ @@ -72,7 +76,6 @@ void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no) /* rename devices that are s3c2412/s3c2413 specific */ s3c_device_sdi.name = "s3c2412-sdi"; - s3c_device_lcd.name = "s3c2412-lcd"; s3c_device_nand.name = "s3c2412-nand"; } @@ -107,7 +110,7 @@ void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size) { /* move base of IO */ - s3c2412_init_gpio2(); + s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10; /* set our idle function */ @@ -158,8 +161,48 @@ void __init s3c2412_init_clocks(int xtal) * as a driver which may support both 2410 and 2440 may try and use it. */ +#ifdef CONFIG_PM +static struct sleep_save s3c2412_sleep[] = { + SAVE_ITEM(S3C2412_DSC0), + SAVE_ITEM(S3C2412_DSC1), + SAVE_ITEM(S3C2413_GPJDAT), + SAVE_ITEM(S3C2413_GPJCON), + SAVE_ITEM(S3C2413_GPJUP), + + /* save the sleep configuration anyway, just in case these + * get damaged during wakeup */ + + SAVE_ITEM(S3C2412_GPBSLPCON), + SAVE_ITEM(S3C2412_GPCSLPCON), + SAVE_ITEM(S3C2412_GPDSLPCON), + SAVE_ITEM(S3C2412_GPESLPCON), + SAVE_ITEM(S3C2412_GPFSLPCON), + SAVE_ITEM(S3C2412_GPGSLPCON), + SAVE_ITEM(S3C2412_GPHSLPCON), + SAVE_ITEM(S3C2413_GPJSLPCON), +}; + +static int s3c2412_suspend(struct sys_device *dev, pm_message_t state) +{ + s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); + return 0; +} + +static int s3c2412_resume(struct sys_device *dev) +{ + s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep)); + return 0; +} + +#else +#define s3c2412_suspend NULL +#define s3c2412_resume NULL +#endif + struct sysdev_class s3c2412_sysclass = { set_kset_name("s3c2412-core"), + .suspend = s3c2412_suspend, + .resume = s3c2412_resume }; static int __init s3c2412_core_init(void) diff --git a/trunk/arch/arm/mach-s3c2410/s3c2440-dma.c b/trunk/arch/arm/mach-s3c2410/s3c2440-dma.c deleted file mode 100644 index 11e109c84a15..000000000000 --- a/trunk/arch/arm/mach-s3c2410/s3c2440-dma.c +++ /dev/null @@ -1,164 +0,0 @@ -/* linux/arch/arm/mach-s3c2410/s3c2440-dma.c - * - * (c) 2006 Simtec Electronics - * Ben Dooks - * - * S3C2440 DMA selection - * - * http://armlinux.simtec.co.uk/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#include -#include -#include - -#include -#include -#include "dma.h" - -#include "cpu.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = { - [DMACH_XD0] = { - .name = "xdreq0", - .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID, - }, - [DMACH_XD1] = { - .name = "xdreq1", - .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID, - }, - [DMACH_SDI] = { - .name = "sdi", - .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID, - .channels[1] = S3C2440_DCON_CH1_SDI | DMA_CH_VALID, - .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID, - .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, - .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, - }, - [DMACH_SPI0] = { - .name = "spi0", - .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT, - .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT, - }, - [DMACH_SPI1] = { - .name = "spi1", - .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT, - .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT, - }, - [DMACH_UART0] = { - .name = "uart0", - .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, - }, - [DMACH_UART1] = { - .name = "uart1", - .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, - }, - [DMACH_UART2] = { - .name = "uart2", - .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, - .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, - }, - [DMACH_TIMER] = { - .name = "timer", - .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID, - .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID, - .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID, - }, - [DMACH_I2S_IN] = { - .name = "i2s-sdi", - .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID, - .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID, - .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, - }, - [DMACH_I2S_OUT] = { - .name = "i2s-sdo", - .channels[0] = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID, - .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID, - .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, - }, - [DMACH_PCM_IN] = { - .name = "pcm-in", - .channels[0] = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID, - .channels[2] = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID, - .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, - }, - [DMACH_PCM_OUT] = { - .name = "pcm-out", - .channels[1] = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID, - .channels[3] = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID, - .hw_addr.to = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, - }, - [DMACH_MIC_IN] = { - .name = "mic-in", - .channels[2] = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID, - .channels[3] = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID, - .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA, - }, - [DMACH_USB_EP1] = { - .name = "usb-ep1", - .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID, - }, - [DMACH_USB_EP2] = { - .name = "usb-ep2", - .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID, - }, - [DMACH_USB_EP3] = { - .name = "usb-ep3", - .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID, - }, - [DMACH_USB_EP4] = { - .name = "usb-ep4", - .channels[3] = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID, - }, -}; - -static void s3c2440_dma_select(struct s3c2410_dma_chan *chan, - struct s3c24xx_dma_map *map) -{ - chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID; -} - -static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = { - .select = s3c2440_dma_select, - .dcon_mask = 7 << 24, - .map = s3c2440_dma_mappings, - .map_size = ARRAY_SIZE(s3c2440_dma_mappings), -}; - -static int s3c2440_dma_add(struct sys_device *sysdev) -{ - return s3c24xx_dma_init_map(&s3c2440_dma_sel); -} - -static struct sysdev_driver s3c2440_dma_driver = { - .add = s3c2440_dma_add, -}; - -static int __init s3c2440_dma_init(void) -{ - return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_dma_driver); -} - -arch_initcall(s3c2440_dma_init); - diff --git a/trunk/arch/arm/mach-s3c2410/s3c2440-dsc.c b/trunk/arch/arm/mach-s3c2410/s3c2440-dsc.c index c92ea66ba45e..16fa2a3b38fa 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2440-dsc.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2440-dsc.c @@ -8,6 +8,11 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. + * + * Modifications: + * 29-Aug-2004 BJD Start of drive-strength control + * 09-Nov-2004 BJD Added symbol export + * 11-Jan-2005 BJD Include fix */ #include diff --git a/trunk/arch/arm/mach-s3c2410/s3c2440-irq.c b/trunk/arch/arm/mach-s3c2410/s3c2440-irq.c index fc08febe2e54..1667ba1fa43d 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2440-irq.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2440-irq.c @@ -119,7 +119,7 @@ static int s3c2440_irq_add(struct sys_device *sysdev) } static struct sysdev_driver s3c2440_irq_driver = { - .add = s3c2440_irq_add, + .add = s3c2440_irq_add, }; static int s3c2440_irq_init(void) diff --git a/trunk/arch/arm/mach-s3c2410/s3c244x-irq.c b/trunk/arch/arm/mach-s3c2410/s3c244x-irq.c index 0d13546c3500..44c5affa9b89 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c244x-irq.c +++ b/trunk/arch/arm/mach-s3c2410/s3c244x-irq.c @@ -120,9 +120,7 @@ static int s3c244x_irq_add(struct sys_device *sysdev) } static struct sysdev_driver s3c2440_irq_driver = { - .add = s3c244x_irq_add, - .suspend = s3c24xx_irq_suspend, - .resume = s3c24xx_irq_resume, + .add = s3c244x_irq_add, }; static int s3c2440_irq_init(void) @@ -133,12 +131,9 @@ static int s3c2440_irq_init(void) arch_initcall(s3c2440_irq_init); static struct sysdev_driver s3c2442_irq_driver = { - .add = s3c244x_irq_add, - .suspend = s3c24xx_irq_suspend, - .resume = s3c24xx_irq_resume, + .add = s3c244x_irq_add, }; - static int s3c2442_irq_init(void) { return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_irq_driver); diff --git a/trunk/arch/arm/mach-s3c2410/sleep.S b/trunk/arch/arm/mach-s3c2410/sleep.S index 2018c2e1dcc5..a7561a79fc82 100644 --- a/trunk/arch/arm/mach-s3c2410/sleep.S +++ b/trunk/arch/arm/mach-s3c2410/sleep.S @@ -41,25 +41,15 @@ .text - /* s3c2410_cpu_save + /* s3c2410_cpu_suspend * - * save enough of the CPU state to allow us to re-start - * pm.c code. as we store items like the sp/lr, we will - * end up returning from this function when the cpu resumes - * so the return value is set to mark this. - * - * This arangement means we avoid having to flush the cache - * from this code. + * put the cpu into sleep mode * * entry: - * r0 = pointer to save block - * - * exit: - * r0 = 0 => we stored everything - * 1 => resumed from sleep + * r0 = sleep save block */ -ENTRY(s3c2410_cpu_save) +ENTRY(s3c2410_cpu_suspend) stmfd sp!, { r4 - r12, lr } @@ store co-processor registers @@ -72,14 +62,44 @@ ENTRY(s3c2410_cpu_save) stmia r0, { r4 - r13 } - mov r0, #0 - ldmfd sp, { r4 - r12, pc } + @@ flush the caches to ensure everything is back out to + @@ SDRAM before the core powers down + +#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH + bl arm920_flush_kern_cache_all +#endif + + @@ prepare cpu to sleep + + ldr r4, =S3C2410_REFRESH + ldr r5, =S3C24XX_MISCCR + ldr r6, =S3C2410_CLKCON + ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB) + ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB) + ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB) + + orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command + orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals + orr r9, r9, #S3C2410_CLKCON_POWER @ power down command + + teq pc, #0 @ first as a trial-run to load cache + bl s3c2410_do_sleep + teq r0, r0 @ now do it for real + b s3c2410_do_sleep @ + + @@ align next bit of code to cache line + .align 8 +s3c2410_do_sleep: + streq r7, [ r4 ] @ SDRAM sleep command + streq r8, [ r5 ] @ SDRAM power-down config + streq r9, [ r6 ] @ CPU sleep +1: beq 1b + mov pc, r14 @@ return to the caller, after having the MMU @@ turned on, this restores the last bits from the @@ stack resume_with_mmu: - mov r0, #1 ldmfd sp!, { r4 - r12, pc } .ltorg diff --git a/trunk/arch/arm/mach-s3c2410/usb-simtec.c b/trunk/arch/arm/mach-s3c2410/usb-simtec.c index c635efa7cd31..6b22d8f0a00d 100644 --- a/trunk/arch/arm/mach-s3c2410/usb-simtec.c +++ b/trunk/arch/arm/mach-s3c2410/usb-simtec.c @@ -10,6 +10,12 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. + * + * Modifications: + * 14-Sep-2004 BJD Created + * 18-Oct-2004 BJD Cleanups, and added code to report OC cleared + * 09-Aug-2005 BJD Renamed s3c2410_report_oc to s3c2410_usb_report_oc + * 09-Aug-2005 BJD Ports powered only if both are enabled */ #define DEBUG diff --git a/trunk/arch/arm/mach-sa1100/collie.c b/trunk/arch/arm/mach-sa1100/collie.c index 6496eb645cee..a0dfa390e34b 100644 --- a/trunk/arch/arm/mach-sa1100/collie.c +++ b/trunk/arch/arm/mach-sa1100/collie.c @@ -91,29 +91,30 @@ static struct mcp_plat_data collie_mcp_data = { /* * low-level UART features. */ -struct platform_device collie_locomo_device; +static struct locomo_dev *uart_dev = NULL; static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl) { + if (!uart_dev) return; + if (mctrl & TIOCM_RTS) - locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0); + locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 0); else - locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1); + locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 1); if (mctrl & TIOCM_DTR) - locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0); + locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 0); else - locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1); + locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 1); } static u_int collie_uart_get_mctrl(struct uart_port *port) { int ret = TIOCM_CD; unsigned int r; + if (!uart_dev) return ret; - r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR); - if (r == -ENODEV) - return ret; + r = locomo_gpio_read_output(uart_dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR); if (r & LOCOMO_GPIO_CTS) ret |= TIOCM_CTS; if (r & LOCOMO_GPIO_DSR) @@ -129,11 +130,13 @@ static struct sa1100_port_fns collie_port_fns __initdata = { static int collie_uart_probe(struct locomo_dev *dev) { + uart_dev = dev; return 0; } static int collie_uart_remove(struct locomo_dev *dev) { + uart_dev = NULL; return 0; } @@ -167,7 +170,7 @@ static struct resource locomo_resources[] = { }, }; -struct platform_device collie_locomo_device = { +static struct platform_device locomo_device = { .name = "locomo", .id = 0, .num_resources = ARRAY_SIZE(locomo_resources), @@ -175,7 +178,7 @@ struct platform_device collie_locomo_device = { }; static struct platform_device *devices[] __initdata = { - &collie_locomo_device, + &locomo_device, &colliescoop_device, }; diff --git a/trunk/arch/arm/mach-versatile/pci.c b/trunk/arch/arm/mach-versatile/pci.c index 13bbd08ff841..41b370090b60 100644 --- a/trunk/arch/arm/mach-versatile/pci.c +++ b/trunk/arch/arm/mach-versatile/pci.c @@ -117,6 +117,7 @@ static int versatile_read_config(struct pci_bus *bus, unsigned int devfn, int wh } else { switch (size) { case 1: + addr &= ~3; v = __raw_readb(addr); break; diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index c0bfb8212b77..b4f220dd5eb8 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -15,7 +15,6 @@ config CPU_ARM610 select CPU_32v3 select CPU_CACHE_V3 select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_COPY_V3 if MMU select CPU_TLB_V3 if MMU help @@ -25,20 +24,6 @@ config CPU_ARM610 Say Y if you want support for the ARM610 processor. Otherwise, say N. -# ARM7TDMI -config CPU_ARM7TDMI - bool "Support ARM7TDMI processor" - depends on !MMU - select CPU_32v4T - select CPU_ABRT_LV4T - select CPU_CACHE_V4 - help - A 32-bit RISC microprocessor based on the ARM7 processor core - which has no memory control unit and cache. - - Say Y if you want support for the ARM7TDMI processor. - Otherwise, say N. - # ARM710 config CPU_ARM710 bool "Support ARM710 processor" if !ARCH_CLPS7500 && ARCH_RPC @@ -46,7 +31,6 @@ config CPU_ARM710 select CPU_32v3 select CPU_CACHE_V3 select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_COPY_V3 if MMU select CPU_TLB_V3 if MMU help @@ -66,7 +50,6 @@ config CPU_ARM720T select CPU_ABRT_LV4T select CPU_CACHE_V4 select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_COPY_V4WT if MMU select CPU_TLB_V4WT if MMU help @@ -76,36 +59,6 @@ config CPU_ARM720T Say Y if you want support for the ARM720T processor. Otherwise, say N. -# ARM740T -config CPU_ARM740T - bool "Support ARM740T processor" if ARCH_INTEGRATOR - depends on !MMU - select CPU_32v4T - select CPU_ABRT_LV4T - select CPU_CACHE_V3 # although the core is v4t - select CPU_CP15_MPU - help - A 32-bit RISC processor with 8KB cache or 4KB variants, - write buffer and MPU(Protection Unit) built around - an ARM7TDMI core. - - Say Y if you want support for the ARM740T processor. - Otherwise, say N. - -# ARM9TDMI -config CPU_ARM9TDMI - bool "Support ARM9TDMI processor" - depends on !MMU - select CPU_32v4T - select CPU_ABRT_NOMMU - select CPU_CACHE_V4 - help - A 32-bit RISC microprocessor based on the ARM9 processor core - which has no memory control unit and cache. - - Say Y if you want support for the ARM9TDMI processor. - Otherwise, say N. - # ARM920T config CPU_ARM920T bool "Support ARM920T processor" @@ -115,7 +68,6 @@ config CPU_ARM920T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -137,7 +89,6 @@ config CPU_ARM922T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -157,7 +108,6 @@ config CPU_ARM925T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -176,7 +126,6 @@ config CPU_ARM926T select CPU_32v5 select CPU_ABRT_EV5TJ select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -187,39 +136,6 @@ config CPU_ARM926T Say Y if you want support for the ARM926T processor. Otherwise, say N. -# ARM940T -config CPU_ARM940T - bool "Support ARM940T processor" if ARCH_INTEGRATOR - depends on !MMU - select CPU_32v4T - select CPU_ABRT_NOMMU - select CPU_CACHE_VIVT - select CPU_CP15_MPU - help - ARM940T is a member of the ARM9TDMI family of general- - purpose microprocessors with MPU and seperate 4KB - instruction and 4KB data cases, each with a 4-word line - length. - - Say Y if you want support for the ARM940T processor. - Otherwise, say N. - -# ARM946E-S -config CPU_ARM946E - bool "Support ARM946E-S processor" if ARCH_INTEGRATOR - depends on !MMU - select CPU_32v5 - select CPU_ABRT_NOMMU - select CPU_CACHE_VIVT - select CPU_CP15_MPU - help - ARM946E-S is a member of the ARM9E-S family of high- - performance, 32-bit system-on-chip processor solutions. - The TCM and ARMv5TE 32-bit instruction set is supported. - - Say Y if you want support for the ARM946E-S processor. - Otherwise, say N. - # ARM1020 - needs validating config CPU_ARM1020 bool "Support ARM1020T (rev 0) processor" @@ -228,7 +144,6 @@ config CPU_ARM1020 select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU help @@ -246,7 +161,6 @@ config CPU_ARM1020E select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WBI if MMU depends on n @@ -258,7 +172,6 @@ config CPU_ARM1022 select CPU_32v5 select CPU_ABRT_EV4T select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_COPY_V4WB if MMU # can probably do better select CPU_TLB_V4WBI if MMU help @@ -276,7 +189,6 @@ config CPU_ARM1026 select CPU_32v5 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10 select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_COPY_V4WB if MMU # can probably do better select CPU_TLB_V4WBI if MMU help @@ -295,7 +207,6 @@ config CPU_SA110 select CPU_ABRT_EV4 select CPU_CACHE_V4WB select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_COPY_V4WB if MMU select CPU_TLB_V4WB if MMU help @@ -316,18 +227,16 @@ config CPU_SA1100 select CPU_ABRT_EV4 select CPU_CACHE_V4WB select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_TLB_V4WB if MMU # XScale config CPU_XSCALE bool - depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000 + depends on ARCH_IOP3XX || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000 default y select CPU_32v5 select CPU_ABRT_EV5T select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_TLB_V4WBI if MMU # XScale Core Version 3 @@ -338,7 +247,6 @@ config CPU_XSC3 select CPU_32v5 select CPU_ABRT_EV5T select CPU_CACHE_VIVT - select CPU_CP15_MMU select CPU_TLB_V4WBI if MMU select IO_36 @@ -350,7 +258,6 @@ config CPU_V6 select CPU_ABRT_EV6 select CPU_CACHE_V6 select CPU_CACHE_VIPT - select CPU_CP15_MMU select CPU_COPY_V6 if MMU select CPU_TLB_V6 if MMU @@ -392,9 +299,6 @@ config CPU_32v6 bool # The abort model -config CPU_ABRT_NOMMU - bool - config CPU_ABRT_EV4 bool @@ -476,23 +380,6 @@ config CPU_TLB_V6 endif -config CPU_CP15 - bool - help - Processor has the CP15 register. - -config CPU_CP15_MMU - bool - select CPU_CP15 - help - Processor has the CP15 register, which has MMU related registers. - -config CPU_CP15_MPU - bool - select CPU_CP15 - help - Processor has the CP15 register, which has MPU related registers. - # # CPU supports 36-bit I/O # @@ -503,7 +390,7 @@ comment "Processor Features" config ARM_THUMB bool "Support Thumb user binaries" - depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 + depends on CPU_ARM720T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_V6 default y help Say Y if you want to include kernel support for running user space @@ -524,48 +411,23 @@ config CPU_BIG_ENDIAN port must properly enable any big-endian related features of your chipset/board/processor. -config CPU_HIGH_VECTOR - depends !MMU && CPU_CP15 && !CPU_ARM740T - bool "Select the High exception vector" - default n - help - Say Y here to select high exception vector(0xFFFF0000~). - The exception vector can be vary depending on the platform - design in nommu mode. If your platform needs to select - high exception vector, say Y. - Otherwise or if you are unsure, say N, and the low exception - vector (0x00000000~) will be used. - config CPU_ICACHE_DISABLE - bool "Disable I-Cache (I-bit)" - depends on CPU_CP15 && !(CPU_ARM610 || CPU_ARM710 || CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3) + bool "Disable I-Cache" + depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6 help Say Y here to disable the processor instruction cache. Unless you have a reason not to or are unsure, say N. config CPU_DCACHE_DISABLE - bool "Disable D-Cache (C-bit)" - depends on CPU_CP15 + bool "Disable D-Cache" + depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6 help Say Y here to disable the processor data cache. Unless you have a reason not to or are unsure, say N. -config CPU_DCACHE_SIZE - hex - depends on CPU_ARM740T || CPU_ARM946E - default 0x00001000 if CPU_ARM740T - default 0x00002000 # default size for ARM946E-S - help - Some cores are synthesizable to have various sized cache. For - ARM946E-S case, it can vary from 0KB to 1MB. - To support such cache operations, it is efficient to know the size - before compile time. - If your SoC is configured to have a different size, define the value - here with proper conditions. - config CPU_DCACHE_WRITETHROUGH bool "Force write through D-cache" - depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE + depends on (CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE default y if CPU_ARM925T help Say Y here to use the data cache in writethrough mode. Unless you @@ -573,7 +435,7 @@ config CPU_DCACHE_WRITETHROUGH config CPU_CACHE_ROUND_ROBIN bool "Round robin I and D cache replacement algorithm" - depends on (CPU_ARM926T || CPU_ARM946E || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE) + depends on (CPU_ARM926T || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE) help Say Y here to use the predictable round-robin cache replacement policy. Unless you specifically require this or are unsure, say N. diff --git a/trunk/arch/arm/mm/Makefile b/trunk/arch/arm/mm/Makefile index d2f5672ecf62..21a2770226ee 100644 --- a/trunk/arch/arm/mm/Makefile +++ b/trunk/arch/arm/mm/Makefile @@ -6,7 +6,7 @@ obj-y := consistent.o extable.o fault.o init.o \ iomap.o obj-$(CONFIG_MMU) += fault-armv.o flush.o ioremap.o mmap.o \ - pgd.o mmu.o + mm-armv.o ifneq ($(CONFIG_MMU),y) obj-y += nommu.o @@ -17,7 +17,6 @@ obj-$(CONFIG_MODULES) += proc-syms.o obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o obj-$(CONFIG_DISCONTIGMEM) += discontig.o -obj-$(CONFIG_CPU_ABRT_NOMMU) += abort-nommu.o obj-$(CONFIG_CPU_ABRT_EV4) += abort-ev4.o obj-$(CONFIG_CPU_ABRT_EV4T) += abort-ev4t.o obj-$(CONFIG_CPU_ABRT_LV4T) += abort-lv4t.o @@ -34,7 +33,7 @@ obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o obj-$(CONFIG_CPU_COPY_V4WB) += copypage-v4wb.o -obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o context.o +obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o mmu.o obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o @@ -47,16 +46,11 @@ obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o -obj-$(CONFIG_CPU_ARM7TDMI) += proc-arm7tdmi.o obj-$(CONFIG_CPU_ARM720T) += proc-arm720.o -obj-$(CONFIG_CPU_ARM740T) += proc-arm740.o -obj-$(CONFIG_CPU_ARM9TDMI) += proc-arm9tdmi.o obj-$(CONFIG_CPU_ARM920T) += proc-arm920.o obj-$(CONFIG_CPU_ARM922T) += proc-arm922.o obj-$(CONFIG_CPU_ARM925T) += proc-arm925.o obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o -obj-$(CONFIG_CPU_ARM940T) += proc-arm940.o -obj-$(CONFIG_CPU_ARM946E) += proc-arm946.o obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o diff --git a/trunk/arch/arm/mm/abort-lv4t.S b/trunk/arch/arm/mm/abort-lv4t.S index 9fb7b0e25ea1..db743e510214 100644 --- a/trunk/arch/arm/mm/abort-lv4t.S +++ b/trunk/arch/arm/mm/abort-lv4t.S @@ -19,16 +19,11 @@ */ ENTRY(v4t_late_abort) tst r3, #PSR_T_BIT @ check for thumb mode -#ifdef CONFIG_CPU_CP15_MMU mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR - bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR -#else - mov r0, #0 @ clear r0, r1 (no FSR/FAR) - mov r1, #0 -#endif bne .data_thumb_abort ldr r8, [r2] @ read arm instruction + bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR tst r8, #1 << 20 @ L = 1 -> write? orreq r1, r1, #1 << 11 @ yes. and r7, r8, #15 << 24 diff --git a/trunk/arch/arm/mm/abort-nommu.S b/trunk/arch/arm/mm/abort-nommu.S deleted file mode 100644 index a7cc7f9ee45d..000000000000 --- a/trunk/arch/arm/mm/abort-nommu.S +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -/* - * Function: nommu_early_abort - * - * Params : r2 = address of aborted instruction - * : r3 = saved SPSR - * - * Returns : r0 = 0 (abort address) - * : r1 = 0 (FSR) - * - * Note: There is no FSR/FAR on !CPU_CP15_MMU cores. - * Just fill zero into the registers. - */ - .align 5 -ENTRY(nommu_early_abort) - mov r0, #0 @ clear r0, r1 (no FSR/FAR) - mov r1, #0 - mov pc, lr diff --git a/trunk/arch/arm/mm/alignment.c b/trunk/arch/arm/mm/alignment.c index aa109f074dd9..e0d21bbbe7d7 100644 --- a/trunk/arch/arm/mm/alignment.c +++ b/trunk/arch/arm/mm/alignment.c @@ -735,7 +735,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) /* * We got a fault - fix it up, or die. */ - do_bad_area(addr, fsr, regs); + do_bad_area(current, current->mm, addr, fsr, regs); return 0; swp: diff --git a/trunk/arch/arm/mm/cache-v4.S b/trunk/arch/arm/mm/cache-v4.S index b2908063ed6a..b8ad5d58ebe2 100644 --- a/trunk/arch/arm/mm/cache-v4.S +++ b/trunk/arch/arm/mm/cache-v4.S @@ -29,13 +29,9 @@ ENTRY(v4_flush_user_cache_all) * Clean and invalidate the entire cache. */ ENTRY(v4_flush_kern_cache_all) -#ifdef CPU_CP15 mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ flush ID cache mov pc, lr -#else - /* FALLTHROUGH */ -#endif /* * flush_user_cache_range(start, end, flags) @@ -48,13 +44,9 @@ ENTRY(v4_flush_kern_cache_all) * - flags - vma_area_struct flags describing address space */ ENTRY(v4_flush_user_cache_range) -#ifdef CPU_CP15 mov ip, #0 mcreq p15, 0, ip, c7, c7, 0 @ flush ID cache mov pc, lr -#else - /* FALLTHROUGH */ -#endif /* * coherent_kern_range(start, end) @@ -116,10 +108,8 @@ ENTRY(v4_dma_inv_range) * - end - virtual end address */ ENTRY(v4_dma_flush_range) -#ifdef CPU_CP15 mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ flush ID cache -#endif /* FALLTHROUGH */ /* diff --git a/trunk/arch/arm/mm/context.c b/trunk/arch/arm/mm/context.c deleted file mode 100644 index 79e800202424..000000000000 --- a/trunk/arch/arm/mm/context.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * linux/arch/arm/mm/context.c - * - * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include - -#include -#include - -unsigned int cpu_last_asid = { 1 << ASID_BITS }; - -/* - * We fork()ed a process, and we need a new context for the child - * to run in. We reserve version 0 for initial tasks so we will - * always allocate an ASID. - */ -void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) -{ - mm->context.id = 0; -} - -void __new_context(struct mm_struct *mm) -{ - unsigned int asid; - - asid = ++cpu_last_asid; - if (asid == 0) - asid = cpu_last_asid = 1 << ASID_BITS; - - /* - * If we've used up all our ASIDs, we need - * to start a new version and flush the TLB. - */ - if ((asid & ~ASID_MASK) == 0) - flush_tlb_all(); - - mm->context.id = asid; -} diff --git a/trunk/arch/arm/mm/copypage-v4mc.c b/trunk/arch/arm/mm/copypage-v4mc.c index df1645e14b4c..fc69dccdace1 100644 --- a/trunk/arch/arm/mm/copypage-v4mc.c +++ b/trunk/arch/arm/mm/copypage-v4mc.c @@ -20,8 +20,6 @@ #include #include -#include "mm.h" - /* * 0xffff8000 to 0xffffffff is reserved for any ARM architecture * specific hacks for copying pages efficiently. @@ -29,6 +27,8 @@ #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ L_PTE_CACHEABLE) +#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) + static DEFINE_SPINLOCK(minicache_lock); /* diff --git a/trunk/arch/arm/mm/copypage-v6.c b/trunk/arch/arm/mm/copypage-v6.c index 3d0d3a963d20..269ce6913ee9 100644 --- a/trunk/arch/arm/mm/copypage-v6.c +++ b/trunk/arch/arm/mm/copypage-v6.c @@ -17,8 +17,6 @@ #include #include -#include "mm.h" - #if SHMLBA > 16384 #error FIX ME #endif @@ -26,6 +24,8 @@ #define from_address (0xffff8000) #define to_address (0xffffc000) +#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) + static DEFINE_SPINLOCK(v6_lock); /* diff --git a/trunk/arch/arm/mm/copypage-xscale.c b/trunk/arch/arm/mm/copypage-xscale.c index 84ebe0aa379e..42a6ee255ce0 100644 --- a/trunk/arch/arm/mm/copypage-xscale.c +++ b/trunk/arch/arm/mm/copypage-xscale.c @@ -20,8 +20,6 @@ #include #include -#include "mm.h" - /* * 0xffff8000 to 0xffffffff is reserved for any ARM architecture * specific hacks for copying pages efficiently. @@ -31,6 +29,8 @@ #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ L_PTE_CACHEABLE) +#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) + static DEFINE_SPINLOCK(minicache_lock); /* diff --git a/trunk/arch/arm/mm/fault.c b/trunk/arch/arm/mm/fault.c index 5e658a874498..c5e0622c7765 100644 --- a/trunk/arch/arm/mm/fault.c +++ b/trunk/arch/arm/mm/fault.c @@ -131,11 +131,10 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr, force_sig_info(sig, &si, tsk); } -void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) +void +do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr, + unsigned int fsr, struct pt_regs *regs) { - struct task_struct *tsk = current; - struct mm_struct *mm = tsk->active_mm; - /* * If we are in kernel mode at this point, we * have no context to handle this fault with. @@ -171,7 +170,7 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, if (fsr & (1 << 11)) /* write? */ mask = VM_WRITE; else - mask = VM_READ|VM_EXEC|VM_WRITE; + mask = VM_READ|VM_EXEC; fault = VM_FAULT_BADACCESS; if (!(vma->vm_flags & mask)) @@ -198,7 +197,7 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, return fault; } - if (!is_init(tsk)) + if (tsk->pid != 1) goto out; /* @@ -320,6 +319,7 @@ static int do_translation_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { + struct task_struct *tsk; unsigned int index; pgd_t *pgd, *pgd_k; pmd_t *pmd, *pmd_k; @@ -351,7 +351,9 @@ do_translation_fault(unsigned long addr, unsigned int fsr, return 0; bad_area: - do_bad_area(addr, fsr, regs); + tsk = current; + + do_bad_area(tsk, tsk->active_mm, addr, fsr, regs); return 0; } @@ -362,7 +364,8 @@ do_translation_fault(unsigned long addr, unsigned int fsr, static int do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { - do_bad_area(addr, fsr, regs); + struct task_struct *tsk = current; + do_bad_area(tsk, tsk->active_mm, addr, fsr, regs); return 0; } diff --git a/trunk/arch/arm/mm/fault.h b/trunk/arch/arm/mm/fault.h index 49e9e3804de4..73b59e83227f 100644 --- a/trunk/arch/arm/mm/fault.h +++ b/trunk/arch/arm/mm/fault.h @@ -1,3 +1,6 @@ -void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs); +void do_bad_area(struct task_struct *tsk, struct mm_struct *mm, + unsigned long addr, unsigned int fsr, struct pt_regs *regs); + +void show_pte(struct mm_struct *mm, unsigned long addr); unsigned long search_exception_table(unsigned long addr); diff --git a/trunk/arch/arm/mm/flush.c b/trunk/arch/arm/mm/flush.c index 454205b789d5..d438ce41cdd5 100644 --- a/trunk/arch/arm/mm/flush.c +++ b/trunk/arch/arm/mm/flush.c @@ -15,12 +15,12 @@ #include #include -#include "mm.h" - #ifdef CONFIG_CPU_CACHE_VIPT #define ALIAS_FLUSH_START 0xffff4000 +#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) + static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) { unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); @@ -107,7 +107,7 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, /* VIPT non-aliasing cache */ if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask) && - vma->vm_flags & VM_EXEC) { + vma->vm_flags | VM_EXEC) { unsigned long addr = (unsigned long)kaddr; /* only flushing the kernel mapping on non-aliasing VIPT */ __cpuc_coherent_kern_range(addr, addr + len); diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index 22217fe2650b..fe3f7f625008 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -25,9 +25,10 @@ #include #include -#include "mm.h" +DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); -extern void _text, _etext, __data_start, _end, __init_begin, __init_end; +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; +extern void _stext, _text, _etext, __data_start, _end, __init_begin, __init_end; extern unsigned long phys_initrd_start; extern unsigned long phys_initrd_size; @@ -37,6 +38,12 @@ extern unsigned long phys_initrd_size; */ static struct meminfo meminfo __initdata = { 0, }; +/* + * empty_zero_page is a special page that is used for + * zero-initialized data and COW. + */ +struct page *empty_zero_page; + void show_mem(void) { int free = 0, total = 0, reserved = 0; @@ -76,6 +83,16 @@ void show_mem(void) printk("%d pages swap cached\n", cached); } +static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) +{ + return pmd_offset(pgd, virt); +} + +static inline pmd_t *pmd_off_k(unsigned long virt) +{ + return pmd_off(pgd_offset_k(virt), virt); +} + #define for_each_nodebank(iter,mi,no) \ for (iter = 0; iter < mi->nr_banks; iter++) \ if (mi->bank[iter].node == no) @@ -159,20 +176,62 @@ static int __init check_initrd(struct meminfo *mi) return initrd_node; } -static inline void map_memory_bank(struct membank *bank) +/* + * Reserve the various regions of node 0 + */ +static __init void reserve_node_zero(pg_data_t *pgdat) { -#ifdef CONFIG_MMU - struct map_desc map; + unsigned long res_size = 0; - map.pfn = __phys_to_pfn(bank->start); - map.virtual = __phys_to_virt(bank->start); - map.length = bank->size; - map.type = MT_MEMORY; + /* + * Register the kernel text and data with bootmem. + * Note that this can only be in node 0. + */ +#ifdef CONFIG_XIP_KERNEL + reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start); +#else + reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext); +#endif - create_mapping(&map); + /* + * Reserve the page tables. These are already in use, + * and can only be in node 0. + */ + reserve_bootmem_node(pgdat, __pa(swapper_pg_dir), + PTRS_PER_PGD * sizeof(pgd_t)); + + /* + * Hmm... This should go elsewhere, but we really really need to + * stop things allocating the low memory; ideally we need a better + * implementation of GFP_DMA which does not assume that DMA-able + * memory starts at zero. + */ + if (machine_is_integrator() || machine_is_cintegrator()) + res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; + + /* + * These should likewise go elsewhere. They pre-reserve the + * screen memory region at the start of main system memory. + */ + if (machine_is_edb7211()) + res_size = 0x00020000; + if (machine_is_p720t()) + res_size = 0x00014000; + +#ifdef CONFIG_SA1111 + /* + * Because of the SA1111 DMA bug, we want to preserve our + * precious DMA-able memory... + */ + res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; #endif + if (res_size) + reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size); } +void __init build_mem_type_table(void); +void __init create_mapping(struct map_desc *md); + static unsigned long __init bootmem_init_node(int node, int initrd_node, struct meminfo *mi) { @@ -189,18 +248,23 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi) * Calculate the pfn range, and map the memory banks for this node. */ for_each_nodebank(i, mi, node) { - struct membank *bank = &mi->bank[i]; unsigned long start, end; + struct map_desc map; - start = bank->start >> PAGE_SHIFT; - end = (bank->start + bank->size) >> PAGE_SHIFT; + start = mi->bank[i].start >> PAGE_SHIFT; + end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT; if (start_pfn > start) start_pfn = start; if (end_pfn < end) end_pfn = end; - map_memory_bank(bank); + map.pfn = __phys_to_pfn(mi->bank[i].start); + map.virtual = __phys_to_virt(mi->bank[i].start); + map.length = mi->bank[i].size; + map.type = MT_MEMORY; + + create_mapping(&map); } /* @@ -282,9 +346,9 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi) return end_pfn; } -void __init bootmem_init(struct meminfo *mi) +static void __init bootmem_init(struct meminfo *mi) { - unsigned long memend_pfn = 0; + unsigned long addr, memend_pfn = 0; int node, initrd_node, i; /* @@ -296,6 +360,26 @@ void __init bootmem_init(struct meminfo *mi) memcpy(&meminfo, mi, sizeof(meminfo)); + /* + * Clear out all the mappings below the kernel image. + */ + for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); +#ifdef CONFIG_XIP_KERNEL + /* The XIP kernel is mapped in the module area -- skip over it */ + addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK; +#endif + for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + + /* + * Clear out all the kernel space mappings, except for the first + * memory bank, up to the end of the vmalloc region. + */ + for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size); + addr < VMALLOC_END; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + /* * Locate which node contains the ramdisk image, if any. */ @@ -329,6 +413,114 @@ void __init bootmem_init(struct meminfo *mi) max_pfn = max_low_pfn = memend_pfn - PHYS_PFN_OFFSET; } +/* + * Set up device the mappings. Since we clear out the page tables for all + * mappings above VMALLOC_END, we will remove any debug device mappings. + * This means you have to be careful how you debug this function, or any + * called function. This means you can't use any function or debugging + * method which may touch any device, otherwise the kernel _will_ crash. + */ +static void __init devicemaps_init(struct machine_desc *mdesc) +{ + struct map_desc map; + unsigned long addr; + void *vectors; + + /* + * Allocate the vector page early. + */ + vectors = alloc_bootmem_low_pages(PAGE_SIZE); + BUG_ON(!vectors); + + for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) + pmd_clear(pmd_off_k(addr)); + + /* + * Map the kernel if it is XIP. + * It is always first in the modulearea. + */ +#ifdef CONFIG_XIP_KERNEL + map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & PGDIR_MASK); + map.virtual = MODULE_START; + map.length = ((unsigned long)&_etext - map.virtual + ~PGDIR_MASK) & PGDIR_MASK; + map.type = MT_ROM; + create_mapping(&map); +#endif + + /* + * Map the cache flushing regions. + */ +#ifdef FLUSH_BASE + map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS); + map.virtual = FLUSH_BASE; + map.length = SZ_1M; + map.type = MT_CACHECLEAN; + create_mapping(&map); +#endif +#ifdef FLUSH_BASE_MINICACHE + map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M); + map.virtual = FLUSH_BASE_MINICACHE; + map.length = SZ_1M; + map.type = MT_MINICLEAN; + create_mapping(&map); +#endif + + /* + * Create a mapping for the machine vectors at the high-vectors + * location (0xffff0000). If we aren't using high-vectors, also + * create a mapping at the low-vectors virtual address. + */ + map.pfn = __phys_to_pfn(virt_to_phys(vectors)); + map.virtual = 0xffff0000; + map.length = PAGE_SIZE; + map.type = MT_HIGH_VECTORS; + create_mapping(&map); + + if (!vectors_high()) { + map.virtual = 0; + map.type = MT_LOW_VECTORS; + create_mapping(&map); + } + + /* + * Ask the machine support to map in the statically mapped devices. + */ + if (mdesc->map_io) + mdesc->map_io(); + + /* + * Finally flush the caches and tlb to ensure that we're in a + * consistent state wrt the writebuffer. This also ensures that + * any write-allocated cache lines in the vector page are written + * back. After this point, we can start to touch devices again. + */ + local_flush_tlb_all(); + flush_cache_all(); +} + +/* + * paging_init() sets up the page tables, initialises the zone memory + * maps, and sets up the zero page, bad page and bad page tables. + */ +void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) +{ + void *zero_page; + + build_mem_type_table(); + bootmem_init(mi); + devicemaps_init(mdesc); + + top_pmd = pmd_off_k(0xffff0000); + + /* + * allocate the zero page. Note that we count on this going ok. + */ + zero_page = alloc_bootmem_low_pages(PAGE_SIZE); + memzero(zero_page, PAGE_SIZE); + empty_zero_page = virt_to_page(zero_page); + flush_dcache_page(empty_zero_page); +} + static inline void free_area(unsigned long addr, unsigned long end, char *s) { unsigned int size = (end - addr) >> 10; diff --git a/trunk/arch/arm/mm/mm-armv.c b/trunk/arch/arm/mm/mm-armv.c new file mode 100644 index 000000000000..38769f5862bc --- /dev/null +++ b/trunk/arch/arm/mm/mm-armv.c @@ -0,0 +1,663 @@ +/* + * linux/arch/arm/mm/mm-armv.c + * + * Copyright (C) 1998-2005 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Page table sludge for ARM v3 and v4 processor architectures. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#define CPOLICY_UNCACHED 0 +#define CPOLICY_BUFFERED 1 +#define CPOLICY_WRITETHROUGH 2 +#define CPOLICY_WRITEBACK 3 +#define CPOLICY_WRITEALLOC 4 + +static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK; +static unsigned int ecc_mask __initdata = 0; +pgprot_t pgprot_kernel; + +EXPORT_SYMBOL(pgprot_kernel); + +pmd_t *top_pmd; + +struct cachepolicy { + const char policy[16]; + unsigned int cr_mask; + unsigned int pmd; + unsigned int pte; +}; + +static struct cachepolicy cache_policies[] __initdata = { + { + .policy = "uncached", + .cr_mask = CR_W|CR_C, + .pmd = PMD_SECT_UNCACHED, + .pte = 0, + }, { + .policy = "buffered", + .cr_mask = CR_C, + .pmd = PMD_SECT_BUFFERED, + .pte = PTE_BUFFERABLE, + }, { + .policy = "writethrough", + .cr_mask = 0, + .pmd = PMD_SECT_WT, + .pte = PTE_CACHEABLE, + }, { + .policy = "writeback", + .cr_mask = 0, + .pmd = PMD_SECT_WB, + .pte = PTE_BUFFERABLE|PTE_CACHEABLE, + }, { + .policy = "writealloc", + .cr_mask = 0, + .pmd = PMD_SECT_WBWA, + .pte = PTE_BUFFERABLE|PTE_CACHEABLE, + } +}; + +/* + * These are useful for identifing cache coherency + * problems by allowing the cache or the cache and + * writebuffer to be turned off. (Note: the write + * buffer should not be on and the cache off). + */ +static void __init early_cachepolicy(char **p) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cache_policies); i++) { + int len = strlen(cache_policies[i].policy); + + if (memcmp(*p, cache_policies[i].policy, len) == 0) { + cachepolicy = i; + cr_alignment &= ~cache_policies[i].cr_mask; + cr_no_alignment &= ~cache_policies[i].cr_mask; + *p += len; + break; + } + } + if (i == ARRAY_SIZE(cache_policies)) + printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n"); + flush_cache_all(); + set_cr(cr_alignment); +} + +static void __init early_nocache(char **__unused) +{ + char *p = "buffered"; + printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p); + early_cachepolicy(&p); +} + +static void __init early_nowrite(char **__unused) +{ + char *p = "uncached"; + printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p); + early_cachepolicy(&p); +} + +static void __init early_ecc(char **p) +{ + if (memcmp(*p, "on", 2) == 0) { + ecc_mask = PMD_PROTECTION; + *p += 2; + } else if (memcmp(*p, "off", 3) == 0) { + ecc_mask = 0; + *p += 3; + } +} + +__early_param("nocache", early_nocache); +__early_param("nowb", early_nowrite); +__early_param("cachepolicy=", early_cachepolicy); +__early_param("ecc=", early_ecc); + +static int __init noalign_setup(char *__unused) +{ + cr_alignment &= ~CR_A; + cr_no_alignment &= ~CR_A; + set_cr(cr_alignment); + return 1; +} + +__setup("noalign", noalign_setup); + +#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) + +static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) +{ + return pmd_offset(pgd, virt); +} + +static inline pmd_t *pmd_off_k(unsigned long virt) +{ + return pmd_off(pgd_offset_k(virt), virt); +} + +/* + * need to get a 16k page for level 1 + */ +pgd_t *get_pgd_slow(struct mm_struct *mm) +{ + pgd_t *new_pgd, *init_pgd; + pmd_t *new_pmd, *init_pmd; + pte_t *new_pte, *init_pte; + + new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2); + if (!new_pgd) + goto no_pgd; + + memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t)); + + /* + * Copy over the kernel and IO PGD entries + */ + init_pgd = pgd_offset_k(0); + memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, + (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); + + clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); + + if (!vectors_high()) { + /* + * On ARM, first page must always be allocated since it + * contains the machine vectors. + */ + new_pmd = pmd_alloc(mm, new_pgd, 0); + if (!new_pmd) + goto no_pmd; + + new_pte = pte_alloc_map(mm, new_pmd, 0); + if (!new_pte) + goto no_pte; + + init_pmd = pmd_offset(init_pgd, 0); + init_pte = pte_offset_map_nested(init_pmd, 0); + set_pte(new_pte, *init_pte); + pte_unmap_nested(init_pte); + pte_unmap(new_pte); + } + + return new_pgd; + +no_pte: + pmd_free(new_pmd); +no_pmd: + free_pages((unsigned long)new_pgd, 2); +no_pgd: + return NULL; +} + +void free_pgd_slow(pgd_t *pgd) +{ + pmd_t *pmd; + struct page *pte; + + if (!pgd) + return; + + /* pgd is always present and good */ + pmd = pmd_off(pgd, 0); + if (pmd_none(*pmd)) + goto free; + if (pmd_bad(*pmd)) { + pmd_ERROR(*pmd); + pmd_clear(pmd); + goto free; + } + + pte = pmd_page(*pmd); + pmd_clear(pmd); + dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE); + pte_lock_deinit(pte); + pte_free(pte); + pmd_free(pmd); +free: + free_pages((unsigned long) pgd, 2); +} + +/* + * Create a SECTION PGD between VIRT and PHYS in domain + * DOMAIN with protection PROT. This operates on half- + * pgdir entry increments. + */ +static inline void +alloc_init_section(unsigned long virt, unsigned long phys, int prot) +{ + pmd_t *pmdp = pmd_off_k(virt); + + if (virt & (1 << 20)) + pmdp++; + + *pmdp = __pmd(phys | prot); + flush_pmd_entry(pmdp); +} + +/* + * Create a SUPER SECTION PGD between VIRT and PHYS with protection PROT + */ +static inline void +alloc_init_supersection(unsigned long virt, unsigned long phys, int prot) +{ + int i; + + for (i = 0; i < 16; i += 1) { + alloc_init_section(virt, phys, prot | PMD_SECT_SUPER); + + virt += (PGDIR_SIZE / 2); + } +} + +/* + * Add a PAGE mapping between VIRT and PHYS in domain + * DOMAIN with protection PROT. Note that due to the + * way we map the PTEs, we must allocate two PTE_SIZE'd + * blocks - one for the Linux pte table, and one for + * the hardware pte table. + */ +static inline void +alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) +{ + pmd_t *pmdp = pmd_off_k(virt); + pte_t *ptep; + + if (pmd_none(*pmdp)) { + ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * + sizeof(pte_t)); + + __pmd_populate(pmdp, __pa(ptep) | prot_l1); + } + ptep = pte_offset_kernel(pmdp, virt); + + set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); +} + +struct mem_types { + unsigned int prot_pte; + unsigned int prot_l1; + unsigned int prot_sect; + unsigned int domain; +}; + +static struct mem_types mem_types[] __initdata = { + [MT_DEVICE] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_WRITE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | + PMD_SECT_AP_WRITE, + .domain = DOMAIN_IO, + }, + [MT_CACHECLEAN] = { + .prot_sect = PMD_TYPE_SECT | PMD_BIT4, + .domain = DOMAIN_KERNEL, + }, + [MT_MINICLEAN] = { + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE, + .domain = DOMAIN_KERNEL, + }, + [MT_LOW_VECTORS] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_EXEC, + .prot_l1 = PMD_TYPE_TABLE, + .domain = DOMAIN_USER, + }, + [MT_HIGH_VECTORS] = { + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_USER | L_PTE_EXEC, + .prot_l1 = PMD_TYPE_TABLE, + .domain = DOMAIN_USER, + }, + [MT_MEMORY] = { + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE, + .domain = DOMAIN_KERNEL, + }, + [MT_ROM] = { + .prot_sect = PMD_TYPE_SECT | PMD_BIT4, + .domain = DOMAIN_KERNEL, + }, + [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */ + .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | + L_PTE_WRITE, + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | + PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE | + PMD_SECT_TEX(1), + .domain = DOMAIN_IO, + }, + [MT_NONSHARED_DEVICE] = { + .prot_l1 = PMD_TYPE_TABLE, + .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_NONSHARED_DEV | + PMD_SECT_AP_WRITE, + .domain = DOMAIN_IO, + } +}; + +/* + * Adjust the PMD section entries according to the CPU in use. + */ +void __init build_mem_type_table(void) +{ + struct cachepolicy *cp; + unsigned int cr = get_cr(); + unsigned int user_pgprot, kern_pgprot; + int cpu_arch = cpu_architecture(); + int i; + +#if defined(CONFIG_CPU_DCACHE_DISABLE) + if (cachepolicy > CPOLICY_BUFFERED) + cachepolicy = CPOLICY_BUFFERED; +#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH) + if (cachepolicy > CPOLICY_WRITETHROUGH) + cachepolicy = CPOLICY_WRITETHROUGH; +#endif + if (cpu_arch < CPU_ARCH_ARMv5) { + if (cachepolicy >= CPOLICY_WRITEALLOC) + cachepolicy = CPOLICY_WRITEBACK; + ecc_mask = 0; + } + + /* + * Xscale must not have PMD bit 4 set for section mappings. + */ + if (cpu_is_xscale()) + for (i = 0; i < ARRAY_SIZE(mem_types); i++) + mem_types[i].prot_sect &= ~PMD_BIT4; + + /* + * ARMv5 and lower, excluding Xscale, bit 4 must be set for + * page tables. + */ + if (cpu_arch < CPU_ARCH_ARMv6 && !cpu_is_xscale()) + for (i = 0; i < ARRAY_SIZE(mem_types); i++) + if (mem_types[i].prot_l1) + mem_types[i].prot_l1 |= PMD_BIT4; + + cp = &cache_policies[cachepolicy]; + kern_pgprot = user_pgprot = cp->pte; + + /* + * Enable CPU-specific coherency if supported. + * (Only available on XSC3 at the moment.) + */ + if (arch_is_coherent()) { + if (cpu_is_xsc3()) { + mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; + mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT; + } + } + + /* + * ARMv6 and above have extended page tables. + */ + if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { + /* + * bit 4 becomes XN which we must clear for the + * kernel memory mapping. + */ + mem_types[MT_MEMORY].prot_sect &= ~PMD_SECT_XN; + mem_types[MT_ROM].prot_sect &= ~PMD_SECT_XN; + + /* + * Mark cache clean areas and XIP ROM read only + * from SVC mode and no access from userspace. + */ + mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; + mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; + mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; + + /* + * Mark the device area as "shared device" + */ + mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE; + mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED; + + /* + * User pages need to be mapped with the ASID + * (iow, non-global) + */ + user_pgprot |= L_PTE_ASID; + +#ifdef CONFIG_SMP + /* + * Mark memory with the "shared" attribute for SMP systems + */ + user_pgprot |= L_PTE_SHARED; + kern_pgprot |= L_PTE_SHARED; + mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; +#endif + } + + for (i = 0; i < 16; i++) { + unsigned long v = pgprot_val(protection_map[i]); + v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot; + protection_map[i] = __pgprot(v); + } + + mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot; + mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot; + + if (cpu_arch >= CPU_ARCH_ARMv5) { +#ifndef CONFIG_SMP + /* + * Only use write-through for non-SMP systems + */ + mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; + mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; +#endif + } else { + mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); + } + + pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | + L_PTE_DIRTY | L_PTE_WRITE | + L_PTE_EXEC | kern_pgprot); + + mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; + mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; + mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; + mem_types[MT_ROM].prot_sect |= cp->pmd; + + switch (cp->pmd) { + case PMD_SECT_WT: + mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; + break; + case PMD_SECT_WB: + case PMD_SECT_WBWA: + mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB; + break; + } + printk("Memory policy: ECC %sabled, Data cache %s\n", + ecc_mask ? "en" : "dis", cp->policy); +} + +#define vectors_base() (vectors_high() ? 0xffff0000 : 0) + +/* + * Create the page directory entries and any necessary + * page tables for the mapping specified by `md'. We + * are able to cope here with varying sizes and address + * offsets, and we take full advantage of sections and + * supersections. + */ +void __init create_mapping(struct map_desc *md) +{ + unsigned long virt, length; + int prot_sect, prot_l1, domain; + pgprot_t prot_pte; + unsigned long off = (u32)__pfn_to_phys(md->pfn); + + if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { + printk(KERN_WARNING "BUG: not creating mapping for " + "0x%08llx at 0x%08lx in user region\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + return; + } + + if ((md->type == MT_DEVICE || md->type == MT_ROM) && + md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { + printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx " + "overlaps vmalloc space\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + } + + domain = mem_types[md->type].domain; + prot_pte = __pgprot(mem_types[md->type].prot_pte); + prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain); + prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain); + + /* + * Catch 36-bit addresses + */ + if(md->pfn >= 0x100000) { + if(domain) { + printk(KERN_ERR "MM: invalid domain in supersection " + "mapping for 0x%08llx at 0x%08lx\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + return; + } + if((md->virtual | md->length | __pfn_to_phys(md->pfn)) + & ~SUPERSECTION_MASK) { + printk(KERN_ERR "MM: cannot create mapping for " + "0x%08llx at 0x%08lx invalid alignment\n", + __pfn_to_phys((u64)md->pfn), md->virtual); + return; + } + + /* + * Shift bits [35:32] of address into bits [23:20] of PMD + * (See ARMv6 spec). + */ + off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20); + } + + virt = md->virtual; + off -= virt; + length = md->length; + + if (mem_types[md->type].prot_l1 == 0 && + (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) { + printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " + "be mapped using pages, ignoring.\n", + __pfn_to_phys(md->pfn), md->virtual); + return; + } + + while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) { + alloc_init_page(virt, virt + off, prot_l1, prot_pte); + + virt += PAGE_SIZE; + length -= PAGE_SIZE; + } + + /* N.B. ARMv6 supersections are only defined to work with domain 0. + * Since domain assignments can in fact be arbitrary, the + * 'domain == 0' check below is required to insure that ARMv6 + * supersections are only allocated for domain 0 regardless + * of the actual domain assignments in use. + */ + if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3()) + && domain == 0) { + /* + * Align to supersection boundary if !high pages. + * High pages have already been checked for proper + * alignment above and they will fail the SUPSERSECTION_MASK + * check because of the way the address is encoded into + * offset. + */ + if (md->pfn <= 0x100000) { + while ((virt & ~SUPERSECTION_MASK || + (virt + off) & ~SUPERSECTION_MASK) && + length >= (PGDIR_SIZE / 2)) { + alloc_init_section(virt, virt + off, prot_sect); + + virt += (PGDIR_SIZE / 2); + length -= (PGDIR_SIZE / 2); + } + } + + while (length >= SUPERSECTION_SIZE) { + alloc_init_supersection(virt, virt + off, prot_sect); + + virt += SUPERSECTION_SIZE; + length -= SUPERSECTION_SIZE; + } + } + + /* + * A section mapping covers half a "pgdir" entry. + */ + while (length >= (PGDIR_SIZE / 2)) { + alloc_init_section(virt, virt + off, prot_sect); + + virt += (PGDIR_SIZE / 2); + length -= (PGDIR_SIZE / 2); + } + + while (length >= PAGE_SIZE) { + alloc_init_page(virt, virt + off, prot_l1, prot_pte); + + virt += PAGE_SIZE; + length -= PAGE_SIZE; + } +} + +/* + * In order to soft-boot, we need to insert a 1:1 mapping in place of + * the user-mode pages. This will then ensure that we have predictable + * results when turning the mmu off + */ +void setup_mm_for_reboot(char mode) +{ + unsigned long base_pmdval; + pgd_t *pgd; + int i; + + if (current->mm && current->mm->pgd) + pgd = current->mm->pgd; + else + pgd = init_mm.pgd; + + base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT; + if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) + base_pmdval |= PMD_BIT4; + + for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) { + unsigned long pmdval = (i << PGDIR_SHIFT) | base_pmdval; + pmd_t *pmd; + + pmd = pmd_off(pgd, i << PGDIR_SHIFT); + pmd[0] = __pmd(pmdval); + pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); + flush_pmd_entry(pmd); + } +} + +/* + * Create the architecture specific mappings + */ +void __init iotable_init(struct map_desc *io_desc, int nr) +{ + int i; + + for (i = 0; i < nr; i++) + create_mapping(io_desc + i); +} diff --git a/trunk/arch/arm/mm/mm.h b/trunk/arch/arm/mm/mm.h deleted file mode 100644 index bb2bc9ab6bd3..000000000000 --- a/trunk/arch/arm/mm/mm.h +++ /dev/null @@ -1,22 +0,0 @@ -/* the upper-most page table pointer */ -extern pmd_t *top_pmd; - -#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) - -static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) -{ - return pmd_offset(pgd, virt); -} - -static inline pmd_t *pmd_off_k(unsigned long virt) -{ - return pmd_off(pgd_offset_k(virt), virt); -} - -struct map_desc; -struct meminfo; -struct pglist_data; - -void __init create_mapping(struct map_desc *md); -void __init bootmem_init(struct meminfo *mi); -void reserve_node_zero(struct pglist_data *pgdat); diff --git a/trunk/arch/arm/mm/mmap.c b/trunk/arch/arm/mm/mmap.c index b0b5f4694070..29e54807c5bc 100644 --- a/trunk/arch/arm/mm/mmap.c +++ b/trunk/arch/arm/mm/mmap.c @@ -114,25 +114,3 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, } } - -/* - * You really shouldn't be using read() or write() on /dev/mem. This - * might go away in the future. - */ -int valid_phys_addr_range(unsigned long addr, size_t size) -{ - if (addr + size > __pa(high_memory)) - return 0; - - return 1; -} - -/* - * We don't use supersection mappings for mmap() on /dev/mem, which - * means that we can't map the memory area above the 4G barrier into - * userspace. - */ -int valid_mmap_phys_addr_range(unsigned long pfn, size_t size) -{ - return !(pfn + (size >> PAGE_SHIFT) > 0x00100000); -} diff --git a/trunk/arch/arm/mm/mmu.c b/trunk/arch/arm/mm/mmu.c index e566cbe4b222..0d90227a0a32 100644 --- a/trunk/arch/arm/mm/mmu.c +++ b/trunk/arch/arm/mm/mmu.c @@ -1,771 +1,45 @@ /* * linux/arch/arm/mm/mmu.c * - * Copyright (C) 1995-2005 Russell King + * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include -#include -#include #include -#include -#include -#include +#include +#include -#include -#include -#include -#include +#include +#include -#include -#include - -#include "mm.h" - -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); - -extern void _stext, __data_start, _end; -extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; - -/* - * empty_zero_page is a special page that is used for - * zero-initialized data and COW. - */ -struct page *empty_zero_page; +unsigned int cpu_last_asid = { 1 << ASID_BITS }; /* - * The pmd table for the upper-most set of pages. + * We fork()ed a process, and we need a new context for the child + * to run in. We reserve version 0 for initial tasks so we will + * always allocate an ASID. */ -pmd_t *top_pmd; - -#define CPOLICY_UNCACHED 0 -#define CPOLICY_BUFFERED 1 -#define CPOLICY_WRITETHROUGH 2 -#define CPOLICY_WRITEBACK 3 -#define CPOLICY_WRITEALLOC 4 - -static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK; -static unsigned int ecc_mask __initdata = 0; -pgprot_t pgprot_kernel; - -EXPORT_SYMBOL(pgprot_kernel); - -struct cachepolicy { - const char policy[16]; - unsigned int cr_mask; - unsigned int pmd; - unsigned int pte; -}; - -static struct cachepolicy cache_policies[] __initdata = { - { - .policy = "uncached", - .cr_mask = CR_W|CR_C, - .pmd = PMD_SECT_UNCACHED, - .pte = 0, - }, { - .policy = "buffered", - .cr_mask = CR_C, - .pmd = PMD_SECT_BUFFERED, - .pte = PTE_BUFFERABLE, - }, { - .policy = "writethrough", - .cr_mask = 0, - .pmd = PMD_SECT_WT, - .pte = PTE_CACHEABLE, - }, { - .policy = "writeback", - .cr_mask = 0, - .pmd = PMD_SECT_WB, - .pte = PTE_BUFFERABLE|PTE_CACHEABLE, - }, { - .policy = "writealloc", - .cr_mask = 0, - .pmd = PMD_SECT_WBWA, - .pte = PTE_BUFFERABLE|PTE_CACHEABLE, - } -}; - -/* - * These are useful for identifing cache coherency - * problems by allowing the cache or the cache and - * writebuffer to be turned off. (Note: the write - * buffer should not be on and the cache off). - */ -static void __init early_cachepolicy(char **p) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(cache_policies); i++) { - int len = strlen(cache_policies[i].policy); - - if (memcmp(*p, cache_policies[i].policy, len) == 0) { - cachepolicy = i; - cr_alignment &= ~cache_policies[i].cr_mask; - cr_no_alignment &= ~cache_policies[i].cr_mask; - *p += len; - break; - } - } - if (i == ARRAY_SIZE(cache_policies)) - printk(KERN_ERR "ERROR: unknown or unsupported cache policy\n"); - flush_cache_all(); - set_cr(cr_alignment); -} -__early_param("cachepolicy=", early_cachepolicy); - -static void __init early_nocache(char **__unused) -{ - char *p = "buffered"; - printk(KERN_WARNING "nocache is deprecated; use cachepolicy=%s\n", p); - early_cachepolicy(&p); -} -__early_param("nocache", early_nocache); - -static void __init early_nowrite(char **__unused) -{ - char *p = "uncached"; - printk(KERN_WARNING "nowb is deprecated; use cachepolicy=%s\n", p); - early_cachepolicy(&p); -} -__early_param("nowb", early_nowrite); - -static void __init early_ecc(char **p) -{ - if (memcmp(*p, "on", 2) == 0) { - ecc_mask = PMD_PROTECTION; - *p += 2; - } else if (memcmp(*p, "off", 3) == 0) { - ecc_mask = 0; - *p += 3; - } -} -__early_param("ecc=", early_ecc); - -static int __init noalign_setup(char *__unused) +void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) { - cr_alignment &= ~CR_A; - cr_no_alignment &= ~CR_A; - set_cr(cr_alignment); - return 1; + mm->context.id = 0; } -__setup("noalign", noalign_setup); - -struct mem_types { - unsigned int prot_pte; - unsigned int prot_l1; - unsigned int prot_sect; - unsigned int domain; -}; -static struct mem_types mem_types[] __initdata = { - [MT_DEVICE] = { - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_WRITE, - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | - PMD_SECT_AP_WRITE, - .domain = DOMAIN_IO, - }, - [MT_CACHECLEAN] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4, - .domain = DOMAIN_KERNEL, - }, - [MT_MINICLEAN] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_MINICACHE, - .domain = DOMAIN_KERNEL, - }, - [MT_LOW_VECTORS] = { - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_EXEC, - .prot_l1 = PMD_TYPE_TABLE, - .domain = DOMAIN_USER, - }, - [MT_HIGH_VECTORS] = { - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_USER | L_PTE_EXEC, - .prot_l1 = PMD_TYPE_TABLE, - .domain = DOMAIN_USER, - }, - [MT_MEMORY] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_AP_WRITE, - .domain = DOMAIN_KERNEL, - }, - [MT_ROM] = { - .prot_sect = PMD_TYPE_SECT | PMD_BIT4, - .domain = DOMAIN_KERNEL, - }, - [MT_IXP2000_DEVICE] = { /* IXP2400 requires XCB=101 for on-chip I/O */ - .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | - L_PTE_WRITE, - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_UNCACHED | - PMD_SECT_AP_WRITE | PMD_SECT_BUFFERABLE | - PMD_SECT_TEX(1), - .domain = DOMAIN_IO, - }, - [MT_NONSHARED_DEVICE] = { - .prot_l1 = PMD_TYPE_TABLE, - .prot_sect = PMD_TYPE_SECT | PMD_BIT4 | PMD_SECT_NONSHARED_DEV | - PMD_SECT_AP_WRITE, - .domain = DOMAIN_IO, - } -}; - -/* - * Adjust the PMD section entries according to the CPU in use. - */ -static void __init build_mem_type_table(void) +void __new_context(struct mm_struct *mm) { - struct cachepolicy *cp; - unsigned int cr = get_cr(); - unsigned int user_pgprot, kern_pgprot; - int cpu_arch = cpu_architecture(); - int i; + unsigned int asid; -#if defined(CONFIG_CPU_DCACHE_DISABLE) - if (cachepolicy > CPOLICY_BUFFERED) - cachepolicy = CPOLICY_BUFFERED; -#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH) - if (cachepolicy > CPOLICY_WRITETHROUGH) - cachepolicy = CPOLICY_WRITETHROUGH; -#endif - if (cpu_arch < CPU_ARCH_ARMv5) { - if (cachepolicy >= CPOLICY_WRITEALLOC) - cachepolicy = CPOLICY_WRITEBACK; - ecc_mask = 0; - } - - /* - * Xscale must not have PMD bit 4 set for section mappings. - */ - if (cpu_is_xscale()) - for (i = 0; i < ARRAY_SIZE(mem_types); i++) - mem_types[i].prot_sect &= ~PMD_BIT4; + asid = ++cpu_last_asid; + if (asid == 0) + asid = cpu_last_asid = 1 << ASID_BITS; /* - * ARMv5 and lower, excluding Xscale, bit 4 must be set for - * page tables. + * If we've used up all our ASIDs, we need + * to start a new version and flush the TLB. */ - if (cpu_arch < CPU_ARCH_ARMv6 && !cpu_is_xscale()) - for (i = 0; i < ARRAY_SIZE(mem_types); i++) - if (mem_types[i].prot_l1) - mem_types[i].prot_l1 |= PMD_BIT4; - - cp = &cache_policies[cachepolicy]; - kern_pgprot = user_pgprot = cp->pte; - - /* - * Enable CPU-specific coherency if supported. - * (Only available on XSC3 at the moment.) - */ - if (arch_is_coherent()) { - if (cpu_is_xsc3()) { - mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; - mem_types[MT_MEMORY].prot_pte |= L_PTE_COHERENT; - } - } - - /* - * ARMv6 and above have extended page tables. - */ - if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) { - /* - * bit 4 becomes XN which we must clear for the - * kernel memory mapping. - */ - mem_types[MT_MEMORY].prot_sect &= ~PMD_SECT_XN; - mem_types[MT_ROM].prot_sect &= ~PMD_SECT_XN; - - /* - * Mark cache clean areas and XIP ROM read only - * from SVC mode and no access from userspace. - */ - mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; - mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; - mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE; - - /* - * Mark the device area as "shared device" - */ - mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE; - mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED; - - /* - * User pages need to be mapped with the ASID - * (iow, non-global) - */ - user_pgprot |= L_PTE_ASID; - -#ifdef CONFIG_SMP - /* - * Mark memory with the "shared" attribute for SMP systems - */ - user_pgprot |= L_PTE_SHARED; - kern_pgprot |= L_PTE_SHARED; - mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; -#endif - } - - for (i = 0; i < 16; i++) { - unsigned long v = pgprot_val(protection_map[i]); - v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot; - protection_map[i] = __pgprot(v); - } - - mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot; - mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot; - - if (cpu_arch >= CPU_ARCH_ARMv5) { -#ifndef CONFIG_SMP - /* - * Only use write-through for non-SMP systems - */ - mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; - mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; -#endif - } else { - mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); - } - - pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | - L_PTE_DIRTY | L_PTE_WRITE | - L_PTE_EXEC | kern_pgprot); - - mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; - mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; - mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; - mem_types[MT_ROM].prot_sect |= cp->pmd; - - switch (cp->pmd) { - case PMD_SECT_WT: - mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; - break; - case PMD_SECT_WB: - case PMD_SECT_WBWA: - mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB; - break; - } - printk("Memory policy: ECC %sabled, Data cache %s\n", - ecc_mask ? "en" : "dis", cp->policy); -} - -#define vectors_base() (vectors_high() ? 0xffff0000 : 0) - -/* - * Create a SECTION PGD between VIRT and PHYS in domain - * DOMAIN with protection PROT. This operates on half- - * pgdir entry increments. - */ -static inline void -alloc_init_section(unsigned long virt, unsigned long phys, int prot) -{ - pmd_t *pmdp = pmd_off_k(virt); - - if (virt & (1 << 20)) - pmdp++; - - *pmdp = __pmd(phys | prot); - flush_pmd_entry(pmdp); -} - -/* - * Create a SUPER SECTION PGD between VIRT and PHYS with protection PROT - */ -static inline void -alloc_init_supersection(unsigned long virt, unsigned long phys, int prot) -{ - int i; - - for (i = 0; i < 16; i += 1) { - alloc_init_section(virt, phys, prot | PMD_SECT_SUPER); - - virt += (PGDIR_SIZE / 2); - } -} - -/* - * Add a PAGE mapping between VIRT and PHYS in domain - * DOMAIN with protection PROT. Note that due to the - * way we map the PTEs, we must allocate two PTE_SIZE'd - * blocks - one for the Linux pte table, and one for - * the hardware pte table. - */ -static inline void -alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) -{ - pmd_t *pmdp = pmd_off_k(virt); - pte_t *ptep; - - if (pmd_none(*pmdp)) { - ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * - sizeof(pte_t)); - - __pmd_populate(pmdp, __pa(ptep) | prot_l1); - } - ptep = pte_offset_kernel(pmdp, virt); - - set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); -} - -/* - * Create the page directory entries and any necessary - * page tables for the mapping specified by `md'. We - * are able to cope here with varying sizes and address - * offsets, and we take full advantage of sections and - * supersections. - */ -void __init create_mapping(struct map_desc *md) -{ - unsigned long virt, length; - int prot_sect, prot_l1, domain; - pgprot_t prot_pte; - unsigned long off = (u32)__pfn_to_phys(md->pfn); - - if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { - printk(KERN_WARNING "BUG: not creating mapping for " - "0x%08llx at 0x%08lx in user region\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - return; - } - - if ((md->type == MT_DEVICE || md->type == MT_ROM) && - md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { - printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx " - "overlaps vmalloc space\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - } - - domain = mem_types[md->type].domain; - prot_pte = __pgprot(mem_types[md->type].prot_pte); - prot_l1 = mem_types[md->type].prot_l1 | PMD_DOMAIN(domain); - prot_sect = mem_types[md->type].prot_sect | PMD_DOMAIN(domain); - - /* - * Catch 36-bit addresses - */ - if(md->pfn >= 0x100000) { - if(domain) { - printk(KERN_ERR "MM: invalid domain in supersection " - "mapping for 0x%08llx at 0x%08lx\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - return; - } - if((md->virtual | md->length | __pfn_to_phys(md->pfn)) - & ~SUPERSECTION_MASK) { - printk(KERN_ERR "MM: cannot create mapping for " - "0x%08llx at 0x%08lx invalid alignment\n", - __pfn_to_phys((u64)md->pfn), md->virtual); - return; - } - - /* - * Shift bits [35:32] of address into bits [23:20] of PMD - * (See ARMv6 spec). - */ - off |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20); - } - - virt = md->virtual; - off -= virt; - length = md->length; - - if (mem_types[md->type].prot_l1 == 0 && - (virt & 0xfffff || (virt + off) & 0xfffff || (virt + length) & 0xfffff)) { - printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " - "be mapped using pages, ignoring.\n", - __pfn_to_phys(md->pfn), md->virtual); - return; - } - - while ((virt & 0xfffff || (virt + off) & 0xfffff) && length >= PAGE_SIZE) { - alloc_init_page(virt, virt + off, prot_l1, prot_pte); - - virt += PAGE_SIZE; - length -= PAGE_SIZE; - } - - /* N.B. ARMv6 supersections are only defined to work with domain 0. - * Since domain assignments can in fact be arbitrary, the - * 'domain == 0' check below is required to insure that ARMv6 - * supersections are only allocated for domain 0 regardless - * of the actual domain assignments in use. - */ - if ((cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3()) - && domain == 0) { - /* - * Align to supersection boundary if !high pages. - * High pages have already been checked for proper - * alignment above and they will fail the SUPSERSECTION_MASK - * check because of the way the address is encoded into - * offset. - */ - if (md->pfn <= 0x100000) { - while ((virt & ~SUPERSECTION_MASK || - (virt + off) & ~SUPERSECTION_MASK) && - length >= (PGDIR_SIZE / 2)) { - alloc_init_section(virt, virt + off, prot_sect); - - virt += (PGDIR_SIZE / 2); - length -= (PGDIR_SIZE / 2); - } - } - - while (length >= SUPERSECTION_SIZE) { - alloc_init_supersection(virt, virt + off, prot_sect); - - virt += SUPERSECTION_SIZE; - length -= SUPERSECTION_SIZE; - } - } - - /* - * A section mapping covers half a "pgdir" entry. - */ - while (length >= (PGDIR_SIZE / 2)) { - alloc_init_section(virt, virt + off, prot_sect); - - virt += (PGDIR_SIZE / 2); - length -= (PGDIR_SIZE / 2); - } - - while (length >= PAGE_SIZE) { - alloc_init_page(virt, virt + off, prot_l1, prot_pte); - - virt += PAGE_SIZE; - length -= PAGE_SIZE; - } -} - -/* - * Create the architecture specific mappings - */ -void __init iotable_init(struct map_desc *io_desc, int nr) -{ - int i; - - for (i = 0; i < nr; i++) - create_mapping(io_desc + i); -} - -static inline void prepare_page_table(struct meminfo *mi) -{ - unsigned long addr; - - /* - * Clear out all the mappings below the kernel image. - */ - for (addr = 0; addr < MODULE_START; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); - -#ifdef CONFIG_XIP_KERNEL - /* The XIP kernel is mapped in the module area -- skip over it */ - addr = ((unsigned long)&_etext + PGDIR_SIZE - 1) & PGDIR_MASK; -#endif - for ( ; addr < PAGE_OFFSET; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); - - /* - * Clear out all the kernel space mappings, except for the first - * memory bank, up to the end of the vmalloc region. - */ - for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size); - addr < VMALLOC_END; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); -} - -/* - * Reserve the various regions of node 0 - */ -void __init reserve_node_zero(pg_data_t *pgdat) -{ - unsigned long res_size = 0; - - /* - * Register the kernel text and data with bootmem. - * Note that this can only be in node 0. - */ -#ifdef CONFIG_XIP_KERNEL - reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start); -#else - reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext); -#endif - - /* - * Reserve the page tables. These are already in use, - * and can only be in node 0. - */ - reserve_bootmem_node(pgdat, __pa(swapper_pg_dir), - PTRS_PER_PGD * sizeof(pgd_t)); - - /* - * Hmm... This should go elsewhere, but we really really need to - * stop things allocating the low memory; ideally we need a better - * implementation of GFP_DMA which does not assume that DMA-able - * memory starts at zero. - */ - if (machine_is_integrator() || machine_is_cintegrator()) - res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; - - /* - * These should likewise go elsewhere. They pre-reserve the - * screen memory region at the start of main system memory. - */ - if (machine_is_edb7211()) - res_size = 0x00020000; - if (machine_is_p720t()) - res_size = 0x00014000; - -#ifdef CONFIG_SA1111 - /* - * Because of the SA1111 DMA bug, we want to preserve our - * precious DMA-able memory... - */ - res_size = __pa(swapper_pg_dir) - PHYS_OFFSET; -#endif - if (res_size) - reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size); -} - -/* - * Set up device the mappings. Since we clear out the page tables for all - * mappings above VMALLOC_END, we will remove any debug device mappings. - * This means you have to be careful how you debug this function, or any - * called function. This means you can't use any function or debugging - * method which may touch any device, otherwise the kernel _will_ crash. - */ -static void __init devicemaps_init(struct machine_desc *mdesc) -{ - struct map_desc map; - unsigned long addr; - void *vectors; - - /* - * Allocate the vector page early. - */ - vectors = alloc_bootmem_low_pages(PAGE_SIZE); - BUG_ON(!vectors); - - for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE) - pmd_clear(pmd_off_k(addr)); - - /* - * Map the kernel if it is XIP. - * It is always first in the modulearea. - */ -#ifdef CONFIG_XIP_KERNEL - map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK); - map.virtual = MODULE_START; - map.length = ((unsigned long)&_etext - map.virtual + ~SECTION_MASK) & SECTION_MASK; - map.type = MT_ROM; - create_mapping(&map); -#endif - - /* - * Map the cache flushing regions. - */ -#ifdef FLUSH_BASE - map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS); - map.virtual = FLUSH_BASE; - map.length = SZ_1M; - map.type = MT_CACHECLEAN; - create_mapping(&map); -#endif -#ifdef FLUSH_BASE_MINICACHE - map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M); - map.virtual = FLUSH_BASE_MINICACHE; - map.length = SZ_1M; - map.type = MT_MINICLEAN; - create_mapping(&map); -#endif - - /* - * Create a mapping for the machine vectors at the high-vectors - * location (0xffff0000). If we aren't using high-vectors, also - * create a mapping at the low-vectors virtual address. - */ - map.pfn = __phys_to_pfn(virt_to_phys(vectors)); - map.virtual = 0xffff0000; - map.length = PAGE_SIZE; - map.type = MT_HIGH_VECTORS; - create_mapping(&map); - - if (!vectors_high()) { - map.virtual = 0; - map.type = MT_LOW_VECTORS; - create_mapping(&map); - } - - /* - * Ask the machine support to map in the statically mapped devices. - */ - if (mdesc->map_io) - mdesc->map_io(); - - /* - * Finally flush the caches and tlb to ensure that we're in a - * consistent state wrt the writebuffer. This also ensures that - * any write-allocated cache lines in the vector page are written - * back. After this point, we can start to touch devices again. - */ - local_flush_tlb_all(); - flush_cache_all(); -} - -/* - * paging_init() sets up the page tables, initialises the zone memory - * maps, and sets up the zero page, bad page and bad page tables. - */ -void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) -{ - void *zero_page; - - build_mem_type_table(); - prepare_page_table(mi); - bootmem_init(mi); - devicemaps_init(mdesc); - - top_pmd = pmd_off_k(0xffff0000); - - /* - * allocate the zero page. Note that we count on this going ok. - */ - zero_page = alloc_bootmem_low_pages(PAGE_SIZE); - memzero(zero_page, PAGE_SIZE); - empty_zero_page = virt_to_page(zero_page); - flush_dcache_page(empty_zero_page); -} - -/* - * In order to soft-boot, we need to insert a 1:1 mapping in place of - * the user-mode pages. This will then ensure that we have predictable - * results when turning the mmu off - */ -void setup_mm_for_reboot(char mode) -{ - unsigned long base_pmdval; - pgd_t *pgd; - int i; - - if (current->mm && current->mm->pgd) - pgd = current->mm->pgd; - else - pgd = init_mm.pgd; - - base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT; - if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale()) - base_pmdval |= PMD_BIT4; - - for (i = 0; i < FIRST_USER_PGD_NR + USER_PTRS_PER_PGD; i++, pgd++) { - unsigned long pmdval = (i << PGDIR_SHIFT) | base_pmdval; - pmd_t *pmd; + if ((asid & ~ASID_MASK) == 0) + flush_tlb_all(); - pmd = pmd_off(pgd, i << PGDIR_SHIFT); - pmd[0] = __pmd(pmdval); - pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); - flush_pmd_entry(pmd); - } + mm->context.id = asid; } diff --git a/trunk/arch/arm/mm/nommu.c b/trunk/arch/arm/mm/nommu.c index d0e66424a597..1464ed817b5d 100644 --- a/trunk/arch/arm/mm/nommu.c +++ b/trunk/arch/arm/mm/nommu.c @@ -11,49 +11,6 @@ #include #include -#include "mm.h" - -extern void _stext, __data_start, _end; - -/* - * Reserve the various regions of node 0 - */ -void __init reserve_node_zero(pg_data_t *pgdat) -{ - /* - * Register the kernel text and data with bootmem. - * Note that this can only be in node 0. - */ -#ifdef CONFIG_XIP_KERNEL - reserve_bootmem_node(pgdat, __pa(&__data_start), &_end - &__data_start); -#else - reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext); -#endif - - /* - * Register the exception vector page. - * some architectures which the DRAM is the exception vector to trap, - * alloc_page breaks with error, although it is not NULL, but "0." - */ - reserve_bootmem_node(pgdat, CONFIG_VECTORS_BASE, PAGE_SIZE); -} - -/* - * paging_init() sets up the page tables, initialises the zone memory - * maps, and sets up the zero page, bad page and bad page tables. - */ -void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) -{ - bootmem_init(mi); -} - -/* - * We don't need to do anything here for nommu machines. - */ -void setup_mm_for_reboot(char mode) -{ -} - void flush_dcache_page(struct page *page) { __cpuc_flush_dcache_page(page_address(page)); diff --git a/trunk/arch/arm/mm/pgd.c b/trunk/arch/arm/mm/pgd.c deleted file mode 100644 index 20c1b0df75f2..000000000000 --- a/trunk/arch/arm/mm/pgd.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * linux/arch/arm/mm/pgd.c - * - * Copyright (C) 1998-2005 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include - -#include -#include -#include - -#include "mm.h" - -#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) - -/* - * need to get a 16k page for level 1 - */ -pgd_t *get_pgd_slow(struct mm_struct *mm) -{ - pgd_t *new_pgd, *init_pgd; - pmd_t *new_pmd, *init_pmd; - pte_t *new_pte, *init_pte; - - new_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL, 2); - if (!new_pgd) - goto no_pgd; - - memzero(new_pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t)); - - /* - * Copy over the kernel and IO PGD entries - */ - init_pgd = pgd_offset_k(0); - memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, - (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); - - clean_dcache_area(new_pgd, PTRS_PER_PGD * sizeof(pgd_t)); - - if (!vectors_high()) { - /* - * On ARM, first page must always be allocated since it - * contains the machine vectors. - */ - new_pmd = pmd_alloc(mm, new_pgd, 0); - if (!new_pmd) - goto no_pmd; - - new_pte = pte_alloc_map(mm, new_pmd, 0); - if (!new_pte) - goto no_pte; - - init_pmd = pmd_offset(init_pgd, 0); - init_pte = pte_offset_map_nested(init_pmd, 0); - set_pte(new_pte, *init_pte); - pte_unmap_nested(init_pte); - pte_unmap(new_pte); - } - - return new_pgd; - -no_pte: - pmd_free(new_pmd); -no_pmd: - free_pages((unsigned long)new_pgd, 2); -no_pgd: - return NULL; -} - -void free_pgd_slow(pgd_t *pgd) -{ - pmd_t *pmd; - struct page *pte; - - if (!pgd) - return; - - /* pgd is always present and good */ - pmd = pmd_off(pgd, 0); - if (pmd_none(*pmd)) - goto free; - if (pmd_bad(*pmd)) { - pmd_ERROR(*pmd); - pmd_clear(pmd); - goto free; - } - - pte = pmd_page(*pmd); - pmd_clear(pmd); - dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE); - pte_lock_deinit(pte); - pte_free(pte); - pmd_free(pmd); -free: - free_pages((unsigned long) pgd, 2); -} diff --git a/trunk/arch/arm/mm/proc-arm740.S b/trunk/arch/arm/mm/proc-arm740.S deleted file mode 100644 index 40713818a87b..000000000000 --- a/trunk/arch/arm/mm/proc-arm740.S +++ /dev/null @@ -1,174 +0,0 @@ -/* - * linux/arch/arm/mm/arm740.S: utility functions for ARM740 - * - * Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@samsung.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include - - .text -/* - * cpu_arm740_proc_init() - * cpu_arm740_do_idle() - * cpu_arm740_dcache_clean_area() - * cpu_arm740_switch_mm() - * - * These are not required. - */ -ENTRY(cpu_arm740_proc_init) -ENTRY(cpu_arm740_do_idle) -ENTRY(cpu_arm740_dcache_clean_area) -ENTRY(cpu_arm740_switch_mm) - mov pc, lr - -/* - * cpu_arm740_proc_fin() - */ -ENTRY(cpu_arm740_proc_fin) - stmfd sp!, {lr} - mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE - msr cpsr_c, ip - mrc p15, 0, r0, c1, c0, 0 - bic r0, r0, #0x3f000000 @ bank/f/lock/s - bic r0, r0, #0x0000000c @ w-buffer/cache - mcr p15, 0, r0, c1, c0, 0 @ disable caches - mcr p15, 0, r0, c7, c0, 0 @ invalidate cache - ldmfd sp!, {pc} - -/* - * cpu_arm740_reset(loc) - * Params : r0 = address to jump to - * Notes : This sets up everything for a reset - */ -ENTRY(cpu_arm740_reset) - mov ip, #0 - mcr p15, 0, ip, c7, c0, 0 @ invalidate cache - mrc p15, 0, ip, c1, c0, 0 @ get ctrl register - bic ip, ip, #0x0000000c @ ............wc.. - mcr p15, 0, ip, c1, c0, 0 @ ctrl register - mov pc, r0 - - __INIT - - .type __arm740_setup, #function -__arm740_setup: - mov r0, #0 - mcr p15, 0, r0, c7, c0, 0 @ invalidate caches - - mcr p15, 0, r0, c6, c3 @ disable area 3~7 - mcr p15, 0, r0, c6, c4 - mcr p15, 0, r0, c6, c5 - mcr p15, 0, r0, c6, c6 - mcr p15, 0, r0, c6, c7 - - mov r0, #0x0000003F @ base = 0, size = 4GB - mcr p15, 0, r0, c6, c0 @ set area 0, default - - ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM - ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) - mov r2, #10 @ 11 is the minimum (4KB) -1: add r2, r2, #1 @ area size *= 2 - mov r1, r1, lsr #1 - bne 1b @ count not zero r-shift - orr r0, r0, r2, lsl #1 @ the area register value - orr r0, r0, #1 @ set enable bit - mcr p15, 0, r0, c6, c1 @ set area 1, RAM - - ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH - ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) - mov r2, #10 @ 11 is the minimum (4KB) -1: add r2, r2, #1 @ area size *= 2 - mov r1, r1, lsr #1 - bne 1b @ count not zero r-shift - orr r0, r0, r2, lsl #1 @ the area register value - orr r0, r0, #1 @ set enable bit - mcr p15, 0, r0, c6, c2 @ set area 2, ROM/FLASH - - mov r0, #0x06 - mcr p15, 0, r0, c2, c0 @ Region 1&2 cacheable -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH - mov r0, #0x00 @ disable whole write buffer -#else - mov r0, #0x02 @ Region 1 write bufferred -#endif - mcr p15, 0, r0, c3, c0 - - mov r0, #0x10000 - sub r0, r0, #1 @ r0 = 0xffff - mcr p15, 0, r0, c5, c0 @ all read/write access - - mrc p15, 0, r0, c1, c0 @ get control register - bic r0, r0, #0x3F000000 @ set to standard caching mode - @ need some benchmark - orr r0, r0, #0x0000000d @ MPU/Cache/WB - - mov pc, lr - - .size __arm740_setup, . - __arm740_setup - - __INITDATA - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm740_processor_functions, #object -ENTRY(arm740_processor_functions) - .word v4t_late_abort - .word cpu_arm740_proc_init - .word cpu_arm740_proc_fin - .word cpu_arm740_reset - .word cpu_arm740_do_idle - .word cpu_arm740_dcache_clean_area - .word cpu_arm740_switch_mm - .word 0 @ cpu_*_set_pte - .size arm740_processor_functions, . - arm740_processor_functions - - .section ".rodata" - - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm740_name, #object -cpu_arm740_name: - .ascii "ARM740T" - .size cpu_arm740_name, . - cpu_arm740_name - - .align - - .section ".proc.info.init", #alloc, #execinstr - .type __arm740_proc_info,#object -__arm740_proc_info: - .long 0x41807400 - .long 0xfffffff0 - .long 0 - b __arm740_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT - .long cpu_arm740_name - .long arm740_processor_functions - .long 0 - .long 0 - .long v3_cache_fns @ cache model - .size __arm740_proc_info, . - __arm740_proc_info - - diff --git a/trunk/arch/arm/mm/proc-arm7tdmi.S b/trunk/arch/arm/mm/proc-arm7tdmi.S deleted file mode 100644 index 22d7e3100ea6..000000000000 --- a/trunk/arch/arm/mm/proc-arm7tdmi.S +++ /dev/null @@ -1,249 +0,0 @@ -/* - * linux/arch/arm/mm/proc-arm7tdmi.S: utility functions for ARM7TDMI - * - * Copyright (C) 2003-2006 Hyok S. Choi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include - - .text -/* - * cpu_arm7tdmi_proc_init() - * cpu_arm7tdmi_do_idle() - * cpu_arm7tdmi_dcache_clean_area() - * cpu_arm7tdmi_switch_mm() - * - * These are not required. - */ -ENTRY(cpu_arm7tdmi_proc_init) -ENTRY(cpu_arm7tdmi_do_idle) -ENTRY(cpu_arm7tdmi_dcache_clean_area) -ENTRY(cpu_arm7tdmi_switch_mm) - mov pc, lr - -/* - * cpu_arm7tdmi_proc_fin() - */ -ENTRY(cpu_arm7tdmi_proc_fin) - mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE - msr cpsr_c, r0 - mov pc, lr - -/* - * Function: cpu_arm7tdmi_reset(loc) - * Params : loc(r0) address to jump to - * Purpose : Sets up everything for a reset and jump to the location for soft reset. - */ -ENTRY(cpu_arm7tdmi_reset) - mov pc, r0 - - __INIT - - .type __arm7tdmi_setup, #function -__arm7tdmi_setup: - mov pc, lr - .size __arm7tdmi_setup, . - __arm7tdmi_setup - - __INITDATA - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm7tdmi_processor_functions, #object -ENTRY(arm7tdmi_processor_functions) - .word v4t_late_abort - .word cpu_arm7tdmi_proc_init - .word cpu_arm7tdmi_proc_fin - .word cpu_arm7tdmi_reset - .word cpu_arm7tdmi_do_idle - .word cpu_arm7tdmi_dcache_clean_area - .word cpu_arm7tdmi_switch_mm - .word 0 @ cpu_*_set_pte - .size arm7tdmi_processor_functions, . - arm7tdmi_processor_functions - - .section ".rodata" - - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4t" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm7tdmi_name, #object -cpu_arm7tdmi_name: - .asciz "ARM7TDMI" - .size cpu_arm7tdmi_name, . - cpu_arm7tdmi_name - - .type cpu_triscenda7_name, #object -cpu_triscenda7_name: - .asciz "Triscend-A7x" - .size cpu_triscenda7_name, . - cpu_triscenda7_name - - .type cpu_at91_name, #object -cpu_at91_name: - .asciz "Atmel-AT91M40xxx" - .size cpu_at91_name, . - cpu_at91_name - - .type cpu_s3c3410_name, #object -cpu_s3c3410_name: - .asciz "Samsung-S3C3410" - .size cpu_s3c3410_name, . - cpu_s3c3410_name - - .type cpu_s3c44b0x_name, #object -cpu_s3c44b0x_name: - .asciz "Samsung-S3C44B0x" - .size cpu_s3c44b0x_name, . - cpu_s3c44b0x_name - - .type cpu_s3c4510b, #object -cpu_s3c4510b_name: - .asciz "Samsung-S3C4510B" - .size cpu_s3c4510b_name, . - cpu_s3c4510b_name - - .type cpu_s3c4530_name, #object -cpu_s3c4530_name: - .asciz "Samsung-S3C4530" - .size cpu_s3c4530_name, . - cpu_s3c4530_name - - .type cpu_netarm_name, #object -cpu_netarm_name: - .asciz "NETARM" - .size cpu_netarm_name, . - cpu_netarm_name - - .align - - .section ".proc.info.init", #alloc, #execinstr - - .type __arm7tdmi_proc_info, #object -__arm7tdmi_proc_info: - .long 0x41007700 - .long 0xfff8ff00 - .long 0 - .long 0 - b __arm7tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_26BIT - .long cpu_arm7tdmi_name - .long arm7tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __arm7tdmi_proc_info, . - __arm7dmi_proc_info - - .type __triscenda7_proc_info, #object -__triscenda7_proc_info: - .long 0x0001d2ff - .long 0x0001ffff - .long 0 - .long 0 - b __arm7tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_triscenda7_name - .long arm7tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __triscenda7_proc_info, . - __triscenda7_proc_info - - .type __at91_proc_info, #object -__at91_proc_info: - .long 0x14000040 - .long 0xfff000e0 - .long 0 - .long 0 - b __arm7tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_at91_name - .long arm7tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __at91_proc_info, . - __at91_proc_info - - .type __s3c4510b_proc_info, #object -__s3c4510b_proc_info: - .long 0x36365000 - .long 0xfffff000 - .long 0 - .long 0 - b __arm7tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_s3c4510b_name - .long arm7tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __s3c4510b_proc_info, . - __s3c4510b_proc_info - - .type __s3c4530_proc_info, #object -__s3c4530_proc_info: - .long 0x4c000000 - .long 0xfff000e0 - .long 0 - .long 0 - b __arm7tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_s3c4530_name - .long arm7tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __s3c4530_proc_info, . - __s3c4530_proc_info - - .type __s3c3410_proc_info, #object -__s3c3410_proc_info: - .long 0x34100000 - .long 0xffff0000 - .long 0 - .long 0 - b __arm7tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_s3c3410_name - .long arm7tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __s3c3410_proc_info, . - __s3c3410_proc_info - - .type __s3c44b0x_proc_info, #object -__s3c44b0x_proc_info: - .long 0x44b00000 - .long 0xffff0000 - .long 0 - .long 0 - b __arm7tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_s3c44b0x_name - .long arm7tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __s3c44b0x_proc_info, . - __s3c44b0x_proc_info diff --git a/trunk/arch/arm/mm/proc-arm940.S b/trunk/arch/arm/mm/proc-arm940.S deleted file mode 100644 index 2397f4b6e151..000000000000 --- a/trunk/arch/arm/mm/proc-arm940.S +++ /dev/null @@ -1,369 +0,0 @@ -/* - * linux/arch/arm/mm/arm940.S: utility functions for ARM940T - * - * Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@samsung.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include - -/* ARM940T has a 4KB DCache comprising 256 lines of 4 words */ -#define CACHE_DLINESIZE 16 -#define CACHE_DSEGMENTS 4 -#define CACHE_DENTRIES 64 - - .text -/* - * cpu_arm940_proc_init() - * cpu_arm940_switch_mm() - * - * These are not required. - */ -ENTRY(cpu_arm940_proc_init) -ENTRY(cpu_arm940_switch_mm) - mov pc, lr - -/* - * cpu_arm940_proc_fin() - */ -ENTRY(cpu_arm940_proc_fin) - stmfd sp!, {lr} - mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE - msr cpsr_c, ip - bl arm940_flush_kern_cache_all - mrc p15, 0, r0, c1, c0, 0 @ ctrl register - bic r0, r0, #0x00001000 @ i-cache - bic r0, r0, #0x00000004 @ d-cache - mcr p15, 0, r0, c1, c0, 0 @ disable caches - ldmfd sp!, {pc} - -/* - * cpu_arm940_reset(loc) - * Params : r0 = address to jump to - * Notes : This sets up everything for a reset - */ -ENTRY(cpu_arm940_reset) - mov ip, #0 - mcr p15, 0, ip, c7, c5, 0 @ flush I cache - mcr p15, 0, ip, c7, c6, 0 @ flush D cache - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mrc p15, 0, ip, c1, c0, 0 @ ctrl register - bic ip, ip, #0x00000005 @ .............c.p - bic ip, ip, #0x00001000 @ i-cache - mcr p15, 0, ip, c1, c0, 0 @ ctrl register - mov pc, r0 - -/* - * cpu_arm940_do_idle() - */ - .align 5 -ENTRY(cpu_arm940_do_idle) - mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt - mov pc, lr - -/* - * flush_user_cache_all() - */ -ENTRY(arm940_flush_user_cache_all) - /* FALLTHROUGH */ - -/* - * flush_kern_cache_all() - * - * Clean and invalidate the entire cache. - */ -ENTRY(arm940_flush_kern_cache_all) - mov r2, #VM_EXEC - /* FALLTHROUGH */ - -/* - * flush_user_cache_range(start, end, flags) - * - * There is no efficient way to flush a range of cache entries - * in the specified address range. Thus, flushes all. - * - * - start - start address (inclusive) - * - end - end address (exclusive) - * - flags - vm_flags describing address space - */ -ENTRY(arm940_flush_user_cache_range) - mov ip, #0 -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH - mcr p15, 0, ip, c7, c6, 0 @ flush D cache -#else - mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments -1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries -2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index - subs r3, r3, #1 << 26 - bcs 2b @ entries 63 to 0 - subs r1, r1, #1 << 4 - bcs 1b @ segments 3 to 0 -#endif - tst r2, #VM_EXEC - mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache - mcrne p15, 0, ip, c7, c10, 4 @ drain WB - mov pc, lr - -/* - * coherent_kern_range(start, end) - * - * Ensure coherency between the Icache and the Dcache in the - * region described by start, end. If you have non-snooping - * Harvard caches, you need to implement this function. - * - * - start - virtual start address - * - end - virtual end address - */ -ENTRY(arm940_coherent_kern_range) - /* FALLTHROUGH */ - -/* - * coherent_user_range(start, end) - * - * Ensure coherency between the Icache and the Dcache in the - * region described by start, end. If you have non-snooping - * Harvard caches, you need to implement this function. - * - * - start - virtual start address - * - end - virtual end address - */ -ENTRY(arm940_coherent_user_range) - /* FALLTHROUGH */ - -/* - * flush_kern_dcache_page(void *page) - * - * Ensure no D cache aliasing occurs, either with itself or - * the I cache - * - * - addr - page aligned address - */ -ENTRY(arm940_flush_kern_dcache_page) - mov ip, #0 - mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments -1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries -2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index - subs r3, r3, #1 << 26 - bcs 2b @ entries 63 to 0 - subs r1, r1, #1 << 4 - bcs 1b @ segments 7 to 0 - mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov pc, lr - -/* - * dma_inv_range(start, end) - * - * There is no efficient way to invalidate a specifid virtual - * address range. Thus, invalidates all. - * - * - start - virtual start address - * - end - virtual end address - */ -ENTRY(arm940_dma_inv_range) - mov ip, #0 - mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments -1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries -2: mcr p15, 0, r3, c7, c6, 2 @ flush D entry - subs r3, r3, #1 << 26 - bcs 2b @ entries 63 to 0 - subs r1, r1, #1 << 4 - bcs 1b @ segments 7 to 0 - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov pc, lr - -/* - * dma_clean_range(start, end) - * - * There is no efficient way to clean a specifid virtual - * address range. Thus, cleans all. - * - * - start - virtual start address - * - end - virtual end address - */ -ENTRY(arm940_dma_clean_range) -ENTRY(cpu_arm940_dcache_clean_area) - mov ip, #0 -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments -1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries -2: mcr p15, 0, r3, c7, c10, 2 @ clean D entry - subs r3, r3, #1 << 26 - bcs 2b @ entries 63 to 0 - subs r1, r1, #1 << 4 - bcs 1b @ segments 7 to 0 -#endif - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov pc, lr - -/* - * dma_flush_range(start, end) - * - * There is no efficient way to clean and invalidate a specifid - * virtual address range. - * - * - start - virtual start address - * - end - virtual end address - */ -ENTRY(arm940_dma_flush_range) - mov ip, #0 - mov r1, #(CACHE_DSEGMENTS - 1) << 4 @ 4 segments -1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries -2: -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - mcr p15, 0, r3, c7, c14, 2 @ clean/flush D entry -#else - mcr p15, 0, r3, c7, c10, 2 @ clean D entry -#endif - subs r3, r3, #1 << 26 - bcs 2b @ entries 63 to 0 - subs r1, r1, #1 << 4 - bcs 1b @ segments 7 to 0 - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mov pc, lr - -ENTRY(arm940_cache_fns) - .long arm940_flush_kern_cache_all - .long arm940_flush_user_cache_all - .long arm940_flush_user_cache_range - .long arm940_coherent_kern_range - .long arm940_coherent_user_range - .long arm940_flush_kern_dcache_page - .long arm940_dma_inv_range - .long arm940_dma_clean_range - .long arm940_dma_flush_range - - __INIT - - .type __arm940_setup, #function -__arm940_setup: - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache - mcr p15, 0, r0, c7, c6, 0 @ invalidate D cache - mcr p15, 0, r0, c7, c10, 4 @ drain WB - - mcr p15, 0, r0, c6, c3, 0 @ disable data area 3~7 - mcr p15, 0, r0, c6, c4, 0 - mcr p15, 0, r0, c6, c5, 0 - mcr p15, 0, r0, c6, c6, 0 - mcr p15, 0, r0, c6, c7, 0 - - mcr p15, 0, r0, c6, c3, 1 @ disable instruction area 3~7 - mcr p15, 0, r0, c6, c4, 1 - mcr p15, 0, r0, c6, c5, 1 - mcr p15, 0, r0, c6, c6, 1 - mcr p15, 0, r0, c6, c7, 1 - - mov r0, #0x0000003F @ base = 0, size = 4GB - mcr p15, 0, r0, c6, c0, 0 @ set area 0, default - mcr p15, 0, r0, c6, c0, 1 - - ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM - ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) - mov r2, #10 @ 11 is the minimum (4KB) -1: add r2, r2, #1 @ area size *= 2 - mov r1, r1, lsr #1 - bne 1b @ count not zero r-shift - orr r0, r0, r2, lsl #1 @ the area register value - orr r0, r0, #1 @ set enable bit - mcr p15, 0, r0, c6, c1, 0 @ set area 1, RAM - mcr p15, 0, r0, c6, c1, 1 - - ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH - ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) - mov r2, #10 @ 11 is the minimum (4KB) -1: add r2, r2, #1 @ area size *= 2 - mov r1, r1, lsr #1 - bne 1b @ count not zero r-shift - orr r0, r0, r2, lsl #1 @ the area register value - orr r0, r0, #1 @ set enable bit - mcr p15, 0, r0, c6, c2, 0 @ set area 2, ROM/FLASH - mcr p15, 0, r0, c6, c2, 1 - - mov r0, #0x06 - mcr p15, 0, r0, c2, c0, 0 @ Region 1&2 cacheable - mcr p15, 0, r0, c2, c0, 1 -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH - mov r0, #0x00 @ disable whole write buffer -#else - mov r0, #0x02 @ Region 1 write bufferred -#endif - mcr p15, 0, r0, c3, c0, 0 - - mov r0, #0x10000 - sub r0, r0, #1 @ r0 = 0xffff - mcr p15, 0, r0, c5, c0, 0 @ all read/write access - mcr p15, 0, r0, c5, c0, 1 - - mrc p15, 0, r0, c1, c0 @ get control register - orr r0, r0, #0x00001000 @ I-cache - orr r0, r0, #0x00000005 @ MPU/D-cache - - mov pc, lr - - .size __arm940_setup, . - __arm940_setup - - __INITDATA - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm940_processor_functions, #object -ENTRY(arm940_processor_functions) - .word nommu_early_abort - .word cpu_arm940_proc_init - .word cpu_arm940_proc_fin - .word cpu_arm940_reset - .word cpu_arm940_do_idle - .word cpu_arm940_dcache_clean_area - .word cpu_arm940_switch_mm - .word 0 @ cpu_*_set_pte - .size arm940_processor_functions, . - arm940_processor_functions - - .section ".rodata" - -.type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4t" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm940_name, #object -cpu_arm940_name: - .ascii "ARM940T" - .size cpu_arm940_name, . - cpu_arm940_name - - .align - - .section ".proc.info.init", #alloc, #execinstr - - .type __arm940_proc_info,#object -__arm940_proc_info: - .long 0x41009400 - .long 0xff00fff0 - .long 0 - b __arm940_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB - .long cpu_arm940_name - .long arm940_processor_functions - .long 0 - .long 0 - .long arm940_cache_fns - .size __arm940_proc_info, . - __arm940_proc_info - diff --git a/trunk/arch/arm/mm/proc-arm946.S b/trunk/arch/arm/mm/proc-arm946.S deleted file mode 100644 index e18617564421..000000000000 --- a/trunk/arch/arm/mm/proc-arm946.S +++ /dev/null @@ -1,424 +0,0 @@ -/* - * linux/arch/arm/mm/arm946.S: utility functions for ARM946E-S - * - * Copyright (C) 2004-2006 Hyok S. Choi (hyok.choi@samsung.com) - * - * (Many of cache codes are from proc-arm926.S) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include - -/* - * ARM946E-S is synthesizable to have 0KB to 1MB sized D-Cache, - * comprising 256 lines of 32 bytes (8 words). - */ -#define CACHE_DSIZE (CONFIG_CPU_DCACHE_SIZE) /* typically 8KB. */ -#define CACHE_DLINESIZE 32 /* fixed */ -#define CACHE_DSEGMENTS 4 /* fixed */ -#define CACHE_DENTRIES (CACHE_DSIZE / CACHE_DSEGMENTS / CACHE_DLINESIZE) -#define CACHE_DLIMIT (CACHE_DSIZE * 4) /* benchmark needed */ - - .text -/* - * cpu_arm946_proc_init() - * cpu_arm946_switch_mm() - * - * These are not required. - */ -ENTRY(cpu_arm946_proc_init) -ENTRY(cpu_arm946_switch_mm) - mov pc, lr - -/* - * cpu_arm946_proc_fin() - */ -ENTRY(cpu_arm946_proc_fin) - stmfd sp!, {lr} - mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE - msr cpsr_c, ip - bl arm946_flush_kern_cache_all - mrc p15, 0, r0, c1, c0, 0 @ ctrl register - bic r0, r0, #0x00001000 @ i-cache - bic r0, r0, #0x00000004 @ d-cache - mcr p15, 0, r0, c1, c0, 0 @ disable caches - ldmfd sp!, {pc} - -/* - * cpu_arm946_reset(loc) - * Params : r0 = address to jump to - * Notes : This sets up everything for a reset - */ -ENTRY(cpu_arm946_reset) - mov ip, #0 - mcr p15, 0, ip, c7, c5, 0 @ flush I cache - mcr p15, 0, ip, c7, c6, 0 @ flush D cache - mcr p15, 0, ip, c7, c10, 4 @ drain WB - mrc p15, 0, ip, c1, c0, 0 @ ctrl register - bic ip, ip, #0x00000005 @ .............c.p - bic ip, ip, #0x00001000 @ i-cache - mcr p15, 0, ip, c1, c0, 0 @ ctrl register - mov pc, r0 - -/* - * cpu_arm946_do_idle() - */ - .align 5 -ENTRY(cpu_arm946_do_idle) - mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt - mov pc, lr - -/* - * flush_user_cache_all() - */ -ENTRY(arm946_flush_user_cache_all) - /* FALLTHROUGH */ - -/* - * flush_kern_cache_all() - * - * Clean and invalidate the entire cache. - */ -ENTRY(arm946_flush_kern_cache_all) - mov r2, #VM_EXEC - mov ip, #0 -__flush_whole_cache: -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH - mcr p15, 0, ip, c7, c6, 0 @ flush D cache -#else - mov r1, #(CACHE_DSEGMENTS - 1) << 29 @ 4 segments -1: orr r3, r1, #(CACHE_DENTRIES - 1) << 4 @ n entries -2: mcr p15, 0, r3, c7, c14, 2 @ clean/flush D index - subs r3, r3, #1 << 4 - bcs 2b @ entries n to 0 - subs r1, r1, #1 << 29 - bcs 1b @ segments 3 to 0 -#endif - tst r2, #VM_EXEC - mcrne p15, 0, ip, c7, c5, 0 @ flush I cache - mcrne p15, 0, ip, c7, c10, 4 @ drain WB - mov pc, lr - -/* - * flush_user_cache_range(start, end, flags) - * - * Clean and invalidate a range of cache entries in the - * specified address range. - * - * - start - start address (inclusive) - * - end - end address (exclusive) - * - flags - vm_flags describing address space - * (same as arm926) - */ -ENTRY(arm946_flush_user_cache_range) - mov ip, #0 - sub r3, r1, r0 @ calculate total size - cmp r3, #CACHE_DLIMIT - bhs __flush_whole_cache - -1: tst r2, #VM_EXEC -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH - mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry - mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry - add r0, r0, #CACHE_DLINESIZE - mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry - mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry - add r0, r0, #CACHE_DLINESIZE -#else - mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry - mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry - add r0, r0, #CACHE_DLINESIZE - mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry - mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry - add r0, r0, #CACHE_DLINESIZE -#endif - cmp r0, r1 - blo 1b - tst r2, #VM_EXEC - mcrne p15, 0, ip, c7, c10, 4 @ drain WB - mov pc, lr - -/* - * coherent_kern_range(start, end) - * - * Ensure coherency between the Icache and the Dcache in the - * region described by start, end. If you have non-snooping - * Harvard caches, you need to implement this function. - * - * - start - virtual start address - * - end - virtual end address - */ -ENTRY(arm946_coherent_kern_range) - /* FALLTHROUGH */ - -/* - * coherent_user_range(start, end) - * - * Ensure coherency between the Icache and the Dcache in the - * region described by start, end. If you have non-snooping - * Harvard caches, you need to implement this function. - * - * - start - virtual start address - * - end - virtual end address - * (same as arm926) - */ -ENTRY(arm946_coherent_user_range) - bic r0, r0, #CACHE_DLINESIZE - 1 -1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry - mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry - add r0, r0, #CACHE_DLINESIZE - cmp r0, r1 - blo 1b - mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov pc, lr - -/* - * flush_kern_dcache_page(void *page) - * - * Ensure no D cache aliasing occurs, either with itself or - * the I cache - * - * - addr - page aligned address - * (same as arm926) - */ -ENTRY(arm946_flush_kern_dcache_page) - add r1, r0, #PAGE_SZ -1: mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry - add r0, r0, #CACHE_DLINESIZE - cmp r0, r1 - blo 1b - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache - mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov pc, lr - -/* - * dma_inv_range(start, end) - * - * Invalidate (discard) the specified virtual address range. - * May not write back any entries. If 'start' or 'end' - * are not cache line aligned, those lines must be written - * back. - * - * - start - virtual start address - * - end - virtual end address - * (same as arm926) - */ -ENTRY(arm946_dma_inv_range) -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - tst r0, #CACHE_DLINESIZE - 1 - mcrne p15, 0, r0, c7, c10, 1 @ clean D entry - tst r1, #CACHE_DLINESIZE - 1 - mcrne p15, 0, r1, c7, c10, 1 @ clean D entry -#endif - bic r0, r0, #CACHE_DLINESIZE - 1 -1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry - add r0, r0, #CACHE_DLINESIZE - cmp r0, r1 - blo 1b - mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov pc, lr - -/* - * dma_clean_range(start, end) - * - * Clean the specified virtual address range. - * - * - start - virtual start address - * - end - virtual end address - * - * (same as arm926) - */ -ENTRY(arm946_dma_clean_range) -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - bic r0, r0, #CACHE_DLINESIZE - 1 -1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry - add r0, r0, #CACHE_DLINESIZE - cmp r0, r1 - blo 1b -#endif - mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov pc, lr - -/* - * dma_flush_range(start, end) - * - * Clean and invalidate the specified virtual address range. - * - * - start - virtual start address - * - end - virtual end address - * - * (same as arm926) - */ -ENTRY(arm946_dma_flush_range) - bic r0, r0, #CACHE_DLINESIZE - 1 -1: -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH - mcr p15, 0, r0, c7, c14, 1 @ clean+invalidate D entry -#else - mcr p15, 0, r0, c7, c10, 1 @ clean D entry -#endif - add r0, r0, #CACHE_DLINESIZE - cmp r0, r1 - blo 1b - mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov pc, lr - -ENTRY(arm946_cache_fns) - .long arm946_flush_kern_cache_all - .long arm946_flush_user_cache_all - .long arm946_flush_user_cache_range - .long arm946_coherent_kern_range - .long arm946_coherent_user_range - .long arm946_flush_kern_dcache_page - .long arm946_dma_inv_range - .long arm946_dma_clean_range - .long arm946_dma_flush_range - - -ENTRY(cpu_arm946_dcache_clean_area) -#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry - add r0, r0, #CACHE_DLINESIZE - subs r1, r1, #CACHE_DLINESIZE - bhi 1b -#endif - mcr p15, 0, r0, c7, c10, 4 @ drain WB - mov pc, lr - - __INIT - - .type __arm946_setup, #function -__arm946_setup: - mov r0, #0 - mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache - mcr p15, 0, r0, c7, c6, 0 @ invalidate D cache - mcr p15, 0, r0, c7, c10, 4 @ drain WB - - mcr p15, 0, r0, c6, c3, 0 @ disable memory region 3~7 - mcr p15, 0, r0, c6, c4, 0 - mcr p15, 0, r0, c6, c5, 0 - mcr p15, 0, r0, c6, c6, 0 - mcr p15, 0, r0, c6, c7, 0 - - mov r0, #0x0000003F @ base = 0, size = 4GB - mcr p15, 0, r0, c6, c0, 0 @ set region 0, default - - ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM - ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) - mov r2, #10 @ 11 is the minimum (4KB) -1: add r2, r2, #1 @ area size *= 2 - mov r1, r1, lsr #1 - bne 1b @ count not zero r-shift - orr r0, r0, r2, lsl #1 @ the region register value - orr r0, r0, #1 @ set enable bit - mcr p15, 0, r0, c6, c1, 0 @ set region 1, RAM - - ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH - ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) - mov r2, #10 @ 11 is the minimum (4KB) -1: add r2, r2, #1 @ area size *= 2 - mov r1, r1, lsr #1 - bne 1b @ count not zero r-shift - orr r0, r0, r2, lsl #1 @ the region register value - orr r0, r0, #1 @ set enable bit - mcr p15, 0, r0, c6, c2, 0 @ set region 2, ROM/FLASH - - mov r0, #0x06 - mcr p15, 0, r0, c2, c0, 0 @ region 1,2 d-cacheable - mcr p15, 0, r0, c2, c0, 1 @ region 1,2 i-cacheable -#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH - mov r0, #0x00 @ disable whole write buffer -#else - mov r0, #0x02 @ region 1 write bufferred -#endif - mcr p15, 0, r0, c3, c0, 0 - -/* - * Access Permission Settings for future permission control by PU. - * - * priv. user - * region 0 (whole) rw -- : b0001 - * region 1 (RAM) rw rw : b0011 - * region 2 (FLASH) rw r- : b0010 - * region 3~7 (none) -- -- : b0000 - */ - mov r0, #0x00000031 - orr r0, r0, #0x00000200 - mcr p15, 0, r0, c5, c0, 2 @ set data access permission - mcr p15, 0, r0, c5, c0, 3 @ set inst. access permission - - mrc p15, 0, r0, c1, c0 @ get control register - orr r0, r0, #0x00001000 @ I-cache - orr r0, r0, #0x00000005 @ MPU/D-cache -#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN - orr r0, r0, #0x00004000 @ .1.. .... .... .... -#endif - mov pc, lr - - .size __arm946_setup, . - __arm946_setup - - __INITDATA - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm946_processor_functions, #object -ENTRY(arm946_processor_functions) - .word nommu_early_abort - .word cpu_arm946_proc_init - .word cpu_arm946_proc_fin - .word cpu_arm946_reset - .word cpu_arm946_do_idle - - .word cpu_arm946_dcache_clean_area - .word cpu_arm946_switch_mm - .word 0 @ cpu_*_set_pte - .size arm946_processor_functions, . - arm946_processor_functions - - .section ".rodata" - - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv5te" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v5t" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm946_name, #object -cpu_arm946_name: - .ascii "ARM946E-S" - .size cpu_arm946_name, . - cpu_arm946_name - - .align - - .section ".proc.info.init", #alloc, #execinstr - .type __arm946_proc_info,#object -__arm946_proc_info: - .long 0x41009460 - .long 0xff00fff0 - .long 0 - b __arm946_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB - .long cpu_arm946_name - .long arm946_processor_functions - .long 0 - .long 0 - .long arm940_cache_fns - .size __arm946_proc_info, . - __arm946_proc_info - diff --git a/trunk/arch/arm/mm/proc-arm9tdmi.S b/trunk/arch/arm/mm/proc-arm9tdmi.S deleted file mode 100644 index 918ebf65d4f6..000000000000 --- a/trunk/arch/arm/mm/proc-arm9tdmi.S +++ /dev/null @@ -1,134 +0,0 @@ -/* - * linux/arch/arm/mm/proc-arm9tdmi.S: utility functions for ARM9TDMI - * - * Copyright (C) 2003-2006 Hyok S. Choi - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include - - .text -/* - * cpu_arm9tdmi_proc_init() - * cpu_arm9tdmi_do_idle() - * cpu_arm9tdmi_dcache_clean_area() - * cpu_arm9tdmi_switch_mm() - * - * These are not required. - */ -ENTRY(cpu_arm9tdmi_proc_init) -ENTRY(cpu_arm9tdmi_do_idle) -ENTRY(cpu_arm9tdmi_dcache_clean_area) -ENTRY(cpu_arm9tdmi_switch_mm) - mov pc, lr - -/* - * cpu_arm9tdmi_proc_fin() - */ -ENTRY(cpu_arm9tdmi_proc_fin) - mov r0, #PSR_F_BIT | PSR_I_BIT | SVC_MODE - msr cpsr_c, r0 - mov pc, lr - -/* - * Function: cpu_arm9tdmi_reset(loc) - * Params : loc(r0) address to jump to - * Purpose : Sets up everything for a reset and jump to the location for soft reset. - */ -ENTRY(cpu_arm9tdmi_reset) - mov pc, r0 - - __INIT - - .type __arm9tdmi_setup, #function -__arm9tdmi_setup: - mov pc, lr - .size __arm9tdmi_setup, . - __arm9tdmi_setup - - __INITDATA - -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ - .type arm9tdmi_processor_functions, #object -ENTRY(arm9tdmi_processor_functions) - .word nommu_early_abort - .word cpu_arm9tdmi_proc_init - .word cpu_arm9tdmi_proc_fin - .word cpu_arm9tdmi_reset - .word cpu_arm9tdmi_do_idle - .word cpu_arm9tdmi_dcache_clean_area - .word cpu_arm9tdmi_switch_mm - .word 0 @ cpu_*_set_pte - .size arm9tdmi_processor_functions, . - arm9tdmi_processor_functions - - .section ".rodata" - - .type cpu_arch_name, #object -cpu_arch_name: - .asciz "armv4t" - .size cpu_arch_name, . - cpu_arch_name - - .type cpu_elf_name, #object -cpu_elf_name: - .asciz "v4" - .size cpu_elf_name, . - cpu_elf_name - - .type cpu_arm9tdmi_name, #object -cpu_arm9tdmi_name: - .asciz "ARM9TDMI" - .size cpu_arm9tdmi_name, . - cpu_arm9tdmi_name - - .type cpu_p2001_name, #object -cpu_p2001_name: - .asciz "P2001" - .size cpu_p2001_name, . - cpu_p2001_name - - .align - - .section ".proc.info.init", #alloc, #execinstr - - .type __arm9tdmi_proc_info, #object -__arm9tdmi_proc_info: - .long 0x41009900 - .long 0xfff8ff00 - .long 0 - .long 0 - b __arm9tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_arm9tdmi_name - .long arm9tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __arm9tdmi_proc_info, . - __arm9dmi_proc_info - - .type __p2001_proc_info, #object -__p2001_proc_info: - .long 0x41029000 - .long 0xffffffff - .long 0 - .long 0 - b __arm9tdmi_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP | HWCAP_THUMB | HWCAP_26BIT - .long cpu_p2001_name - .long arm9tdmi_processor_functions - .long 0 - .long 0 - .long v4_cache_fns - .size __p2001_proc_info, . - __p2001_proc_info diff --git a/trunk/arch/arm/mm/proc-xscale.S b/trunk/arch/arm/mm/proc-xscale.S index e8b377d637f6..3ca0c92e98a2 100644 --- a/trunk/arch/arm/mm/proc-xscale.S +++ b/trunk/arch/arm/mm/proc-xscale.S @@ -311,6 +311,12 @@ ENTRY(xscale_flush_kern_dcache_page) * - end - virtual end address */ ENTRY(xscale_dma_inv_range) + mrc p15, 0, r2, c0, c0, 0 @ read ID + eor r2, r2, #0x69000000 + eor r2, r2, #0x00052000 + bics r2, r2, #1 + beq xscale_dma_flush_range + tst r0, #CACHELINESIZE - 1 bic r0, r0, #CACHELINESIZE - 1 mcrne p15, 0, r0, c7, c10, 1 @ clean D entry @@ -369,30 +375,6 @@ ENTRY(xscale_cache_fns) .long xscale_dma_clean_range .long xscale_dma_flush_range -/* - * On stepping A0/A1 of the 80200, invalidating D-cache by line doesn't - * clear the dirty bits, which means that if we invalidate a dirty line, - * the dirty data can still be written back to external memory later on. - * - * The recommended workaround is to always do a clean D-cache line before - * doing an invalidate D-cache line, so on the affected processors, - * dma_inv_range() is implemented as dma_flush_range(). - * - * See erratum #25 of "Intel 80200 Processor Specification Update", - * revision January 22, 2003, available at: - * http://www.intel.com/design/iio/specupdt/273415.htm - */ -ENTRY(xscale_80200_A0_A1_cache_fns) - .long xscale_flush_kern_cache_all - .long xscale_flush_user_cache_all - .long xscale_flush_user_cache_range - .long xscale_coherent_kern_range - .long xscale_coherent_user_range - .long xscale_flush_kern_dcache_page - .long xscale_dma_flush_range - .long xscale_dma_clean_range - .long xscale_dma_flush_range - ENTRY(cpu_xscale_dcache_clean_area) 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry add r0, r0, #CACHELINESIZE @@ -549,11 +531,6 @@ cpu_elf_name: .asciz "v5" .size cpu_elf_name, . - cpu_elf_name - .type cpu_80200_A0_A1_name, #object -cpu_80200_A0_A1_name: - .asciz "XScale-80200 A0/A1" - .size cpu_80200_A0_A1_name, . - cpu_80200_A0_A1_name - .type cpu_80200_name, #object cpu_80200_name: .asciz "XScale-80200" @@ -618,29 +595,6 @@ cpu_pxa270_name: .section ".proc.info.init", #alloc, #execinstr - .type __80200_A0_A1_proc_info,#object -__80200_A0_A1_proc_info: - .long 0x69052000 - .long 0xfffffffe - .long PMD_TYPE_SECT | \ - PMD_SECT_BUFFERABLE | \ - PMD_SECT_CACHEABLE | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - .long PMD_TYPE_SECT | \ - PMD_SECT_AP_WRITE | \ - PMD_SECT_AP_READ - b __xscale_setup - .long cpu_arch_name - .long cpu_elf_name - .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP - .long cpu_80200_name - .long xscale_processor_functions - .long v4wbi_tlb_fns - .long xscale_mc_user_fns - .long xscale_80200_A0_A1_cache_fns - .size __80200_A0_A1_proc_info, . - __80200_A0_A1_proc_info - .type __80200_proc_info,#object __80200_proc_info: .long 0x69052000 diff --git a/trunk/arch/arm/oprofile/op_model_xscale.c b/trunk/arch/arm/oprofile/op_model_xscale.c index 6576143f2559..34fdc733743b 100644 --- a/trunk/arch/arm/oprofile/op_model_xscale.c +++ b/trunk/arch/arm/oprofile/op_model_xscale.c @@ -36,11 +36,11 @@ #ifdef CONFIG_ARCH_IOP310 #define XSCALE_PMU_IRQ IRQ_XS80200_PMU #endif -#ifdef CONFIG_ARCH_IOP32X -#define XSCALE_PMU_IRQ IRQ_IOP32X_CORE_PMU +#ifdef CONFIG_ARCH_IOP321 +#define XSCALE_PMU_IRQ IRQ_IOP321_CORE_PMU #endif -#ifdef CONFIG_ARCH_IOP33X -#define XSCALE_PMU_IRQ IRQ_IOP33X_CORE_PMU +#ifdef CONFIG_ARCH_IOP331 +#define XSCALE_PMU_IRQ IRQ_IOP331_CORE_PMU #endif #ifdef CONFIG_ARCH_PXA #define XSCALE_PMU_IRQ IRQ_PMU @@ -88,7 +88,7 @@ static struct pmu_counter results[MAX_COUNTERS]; /* * There are two versions of the PMU in current XScale processors * with differing register layouts and number of performance counters. - * e.g. IOP32x is xsc1 whilst IOP33x is xsc2. + * e.g. IOP321 is xsc1 whilst IOP331 is xsc2. * We detect which register layout to use in xscale_detect_pmu() */ enum { PMU_XSC1, PMU_XSC2 }; diff --git a/trunk/arch/arm/plat-iop/Makefile b/trunk/arch/arm/plat-iop/Makefile deleted file mode 100644 index 23da00b11517..000000000000 --- a/trunk/arch/arm/plat-iop/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# Makefile for the linux kernel. -# - -obj-y := gpio.o i2c.o pci.o setup.o time.o -obj-m := -obj-n := -obj- := diff --git a/trunk/arch/arm/plat-iop/gpio.c b/trunk/arch/arm/plat-iop/gpio.c deleted file mode 100644 index eda436083417..000000000000 --- a/trunk/arch/arm/plat-iop/gpio.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * arch/arm/plat-iop/gpio.c - * GPIO handling for Intel IOP3xx processors. - * - * Copyright (C) 2006 Lennert Buytenhek - * - * 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. - */ - -#include -#include - -void gpio_line_config(int line, int direction) -{ - unsigned long flags; - - local_irq_save(flags); - if (direction == GPIO_IN) { - *IOP3XX_GPOE |= 1 << line; - } else if (direction == GPIO_OUT) { - *IOP3XX_GPOE &= ~(1 << line); - } - local_irq_restore(flags); -} -EXPORT_SYMBOL(gpio_line_config); - -int gpio_line_get(int line) -{ - return !!(*IOP3XX_GPID & (1 << line)); -} -EXPORT_SYMBOL(gpio_line_get); - -void gpio_line_set(int line, int value) -{ - unsigned long flags; - - local_irq_save(flags); - if (value == GPIO_LOW) { - *IOP3XX_GPOD &= ~(1 << line); - } else if (value == GPIO_HIGH) { - *IOP3XX_GPOD |= 1 << line; - } - local_irq_restore(flags); -} -EXPORT_SYMBOL(gpio_line_set); diff --git a/trunk/arch/arm/plat-iop/i2c.c b/trunk/arch/arm/plat-iop/i2c.c deleted file mode 100644 index e99909bdba71..000000000000 --- a/trunk/arch/arm/plat-iop/i2c.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * arch/arm/plat-iop/i2c.c - * - * Author: Nicolas Pitre - * Copyright (C) 2001 MontaVista Software, Inc. - * Copyright (C) 2004 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_ARCH_IOP32X -#define IRQ_IOP3XX_I2C_0 IRQ_IOP32X_I2C_0 -#define IRQ_IOP3XX_I2C_1 IRQ_IOP32X_I2C_1 -#endif -#ifdef CONFIG_ARCH_IOP33X -#define IRQ_IOP3XX_I2C_0 IRQ_IOP33X_I2C_0 -#define IRQ_IOP3XX_I2C_1 IRQ_IOP33X_I2C_1 -#endif - -static struct resource iop3xx_i2c0_resources[] = { - [0] = { - .start = 0xfffff680, - .end = 0xfffff697, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP3XX_I2C_0, - .end = IRQ_IOP3XX_I2C_0, - .flags = IORESOURCE_IRQ, - }, -}; - -struct platform_device iop3xx_i2c0_device = { - .name = "IOP3xx-I2C", - .id = 0, - .num_resources = 2, - .resource = iop3xx_i2c0_resources, -}; - - -static struct resource iop3xx_i2c1_resources[] = { - [0] = { - .start = 0xfffff6a0, - .end = 0xfffff6b7, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = IRQ_IOP3XX_I2C_1, - .end = IRQ_IOP3XX_I2C_1, - .flags = IORESOURCE_IRQ, - } -}; - -struct platform_device iop3xx_i2c1_device = { - .name = "IOP3xx-I2C", - .id = 1, - .num_resources = 2, - .resource = iop3xx_i2c1_resources, -}; diff --git a/trunk/arch/arm/plat-iop/pci.c b/trunk/arch/arm/plat-iop/pci.c deleted file mode 100644 index e647812654f2..000000000000 --- a/trunk/arch/arm/plat-iop/pci.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * arch/arm/plat-iop/pci.c - * - * PCI support for the Intel IOP32X and IOP33X processors - * - * Author: Rory Bolt - * Copyright (C) 2002 Rory Bolt - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// #define DEBUG - -#ifdef DEBUG -#define DBG(x...) printk(x) -#else -#define DBG(x...) do { } while (0) -#endif - -/* - * This routine builds either a type0 or type1 configuration command. If the - * bus is on the 803xx then a type0 made, else a type1 is created. - */ -static u32 iop3xx_cfg_address(struct pci_bus *bus, int devfn, int where) -{ - struct pci_sys_data *sys = bus->sysdata; - u32 addr; - - if (sys->busnr == bus->number) - addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11); - else - addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1; - - addr |= PCI_FUNC(devfn) << 8 | (where & ~3); - - return addr; -} - -/* - * This routine checks the status of the last configuration cycle. If an error - * was detected it returns a 1, else it returns a 0. The errors being checked - * are parity, master abort, target abort (master and target). These types of - * errors occure during a config cycle where there is no device, like during - * the discovery stage. - */ -static int iop3xx_pci_status(void) -{ - unsigned int status; - int ret = 0; - - /* - * Check the status registers. - */ - status = *IOP3XX_ATUSR; - if (status & 0xf900) { - DBG("\t\t\tPCI: P0 - status = 0x%08x\n", status); - *IOP3XX_ATUSR = status & 0xf900; - ret = 1; - } - - status = *IOP3XX_ATUISR; - if (status & 0x679f) { - DBG("\t\t\tPCI: P1 - status = 0x%08x\n", status); - *IOP3XX_ATUISR = status & 0x679f; - ret = 1; - } - - return ret; -} - -/* - * Simply write the address register and read the configuration - * data. Note that the 4 nop's ensure that we are able to handle - * a delayed abort (in theory.) - */ -static inline u32 iop3xx_read(unsigned long addr) -{ - u32 val; - - __asm__ __volatile__( - "str %1, [%2]\n\t" - "ldr %0, [%3]\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - : "=r" (val) - : "r" (addr), "r" (IOP3XX_OCCAR), "r" (IOP3XX_OCCDR)); - - return val; -} - -/* - * The read routines must check the error status of the last configuration - * cycle. If there was an error, the routine returns all hex f's. - */ -static int -iop3xx_read_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 *value) -{ - unsigned long addr = iop3xx_cfg_address(bus, devfn, where); - u32 val = iop3xx_read(addr) >> ((where & 3) * 8); - - if (iop3xx_pci_status()) - val = 0xffffffff; - - *value = val; - - return PCIBIOS_SUCCESSFUL; -} - -static int -iop3xx_write_config(struct pci_bus *bus, unsigned int devfn, int where, - int size, u32 value) -{ - unsigned long addr = iop3xx_cfg_address(bus, devfn, where); - u32 val; - - if (size != 4) { - val = iop3xx_read(addr); - if (iop3xx_pci_status()) - return PCIBIOS_SUCCESSFUL; - - where = (where & 3) * 8; - - if (size == 1) - val &= ~(0xff << where); - else - val &= ~(0xffff << where); - - *IOP3XX_OCCDR = val | value << where; - } else { - asm volatile( - "str %1, [%2]\n\t" - "str %0, [%3]\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - "nop\n\t" - : - : "r" (value), "r" (addr), - "r" (IOP3XX_OCCAR), "r" (IOP3XX_OCCDR)); - } - - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops iop3xx_ops = { - .read = iop3xx_read_config, - .write = iop3xx_write_config, -}; - -/* - * When a PCI device does not exist during config cycles, the 80200 gets a - * bus error instead of returning 0xffffffff. This handler simply returns. - */ -static int -iop3xx_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) -{ - DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n", - addr, fsr, regs->ARM_pc, regs->ARM_lr); - - /* - * If it was an imprecise abort, then we need to correct the - * return address to be _after_ the instruction. - */ - if (fsr & (1 << 10)) - regs->ARM_pc += 4; - - return 0; -} - -int iop3xx_pci_setup(int nr, struct pci_sys_data *sys) -{ - struct resource *res; - - if (nr != 0) - return 0; - - res = kzalloc(2 * sizeof(struct resource), GFP_KERNEL); - if (!res) - panic("PCI: unable to alloc resources"); - - res[0].start = IOP3XX_PCI_LOWER_IO_VA; - res[0].end = IOP3XX_PCI_LOWER_IO_VA + IOP3XX_PCI_IO_WINDOW_SIZE - 1; - res[0].name = "IOP3XX PCI I/O Space"; - res[0].flags = IORESOURCE_IO; - request_resource(&ioport_resource, &res[0]); - - res[1].start = IOP3XX_PCI_LOWER_MEM_PA; - res[1].end = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE - 1; - res[1].name = "IOP3XX PCI Memory Space"; - res[1].flags = IORESOURCE_MEM; - request_resource(&iomem_resource, &res[1]); - - sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - IOP3XX_PCI_LOWER_MEM_BA; - sys->io_offset = IOP3XX_PCI_LOWER_IO_VA - IOP3XX_PCI_LOWER_IO_BA; - - sys->resource[0] = &res[0]; - sys->resource[1] = &res[1]; - sys->resource[2] = NULL; - - return 1; -} - -struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys) -{ - return pci_scan_bus(sys->busnr, &iop3xx_ops, sys); -} - -void iop3xx_pci_preinit(void) -{ - DBG("PCI: Intel 803xx PCI init code.\n"); - DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD); - DBG("ATU: IOP3XX_OMWTVR0=0x%04x, IOP3XX_OIOWTVR=0x%04x\n", - *IOP3XX_OMWTVR0, - *IOP3XX_OIOWTVR); - DBG("ATU: IOP3XX_ATUCR=0x%08x\n", *IOP3XX_ATUCR); - DBG("ATU: IOP3XX_IABAR0=0x%08x IOP3XX_IALR0=0x%08x IOP3XX_IATVR0=%08x\n", - *IOP3XX_IABAR0, *IOP3XX_IALR0, *IOP3XX_IATVR0); - DBG("ATU: IOP3XX_OMWTVR0=0x%08x\n", *IOP3XX_OMWTVR0); - DBG("ATU: IOP3XX_IABAR1=0x%08x IOP3XX_IALR1=0x%08x\n", - *IOP3XX_IABAR1, *IOP3XX_IALR1); - DBG("ATU: IOP3XX_ERBAR=0x%08x IOP3XX_ERLR=0x%08x IOP3XX_ERTVR=%08x\n", - *IOP3XX_ERBAR, *IOP3XX_ERLR, *IOP3XX_ERTVR); - DBG("ATU: IOP3XX_IABAR2=0x%08x IOP3XX_IALR2=0x%08x IOP3XX_IATVR2=%08x\n", - *IOP3XX_IABAR2, *IOP3XX_IALR2, *IOP3XX_IATVR2); - DBG("ATU: IOP3XX_IABAR3=0x%08x IOP3XX_IALR3=0x%08x IOP3XX_IATVR3=%08x\n", - *IOP3XX_IABAR3, *IOP3XX_IALR3, *IOP3XX_IATVR3); - - hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort"); -} diff --git a/trunk/arch/arm/plat-iop/setup.c b/trunk/arch/arm/plat-iop/setup.c deleted file mode 100644 index 4689db638e95..000000000000 --- a/trunk/arch/arm/plat-iop/setup.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * arch/arm/plat-iop/setup.c - * - * Author: Nicolas Pitre - * Copyright (C) 2001 MontaVista Software, Inc. - * Copyright (C) 2004 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -/* - * Standard IO mapping for all IOP3xx based systems - */ -static struct map_desc iop3xx_std_desc[] __initdata = { - { /* mem mapped registers */ - .virtual = IOP3XX_PERIPHERAL_VIRT_BASE, - .pfn = __phys_to_pfn(IOP3XX_PERIPHERAL_PHYS_BASE), - .length = IOP3XX_PERIPHERAL_SIZE, - .type = MT_DEVICE, - }, { /* PCI IO space */ - .virtual = IOP3XX_PCI_LOWER_IO_VA, - .pfn = __phys_to_pfn(IOP3XX_PCI_LOWER_IO_PA), - .length = IOP3XX_PCI_IO_WINDOW_SIZE, - .type = MT_DEVICE, - }, -}; - -void __init iop3xx_map_io(void) -{ - iotable_init(iop3xx_std_desc, ARRAY_SIZE(iop3xx_std_desc)); -} diff --git a/trunk/arch/arm/plat-iop/time.c b/trunk/arch/arm/plat-iop/time.c deleted file mode 100644 index 06282dffbdc6..000000000000 --- a/trunk/arch/arm/plat-iop/time.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * arch/arm/plat-iop/time.c - * - * Timer code for IOP32x and IOP33x based systems - * - * Author: Deepak Saxena - * - * Copyright 2002-2003 MontaVista Software Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_ARCH_IOP32X -#define IRQ_IOP3XX_TIMER0 IRQ_IOP32X_TIMER0 -#else -#ifdef CONFIG_ARCH_IOP33X -#define IRQ_IOP3XX_TIMER0 IRQ_IOP33X_TIMER0 -#endif -#endif - -static unsigned long ticks_per_jiffy; -static unsigned long ticks_per_usec; -static unsigned long next_jiffy_time; - -unsigned long iop3xx_gettimeoffset(void) -{ - unsigned long offset; - - offset = next_jiffy_time - *IOP3XX_TU_TCR1; - - return offset / ticks_per_usec; -} - -static irqreturn_t -iop3xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - write_seqlock(&xtime_lock); - - iop3xx_cp6_enable(); - asm volatile("mcr p6, 0, %0, c6, c1, 0" : : "r" (1)); - iop3xx_cp6_disable(); - - while ((signed long)(next_jiffy_time - *IOP3XX_TU_TCR1) - >= ticks_per_jiffy) { - timer_tick(regs); - next_jiffy_time -= ticks_per_jiffy; - } - - write_sequnlock(&xtime_lock); - - return IRQ_HANDLED; -} - -static struct irqaction iop3xx_timer_irq = { - .name = "IOP3XX Timer Tick", - .handler = iop3xx_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_TIMER, -}; - -void __init iop3xx_init_time(unsigned long tick_rate) -{ - u32 timer_ctl; - - ticks_per_jiffy = (tick_rate + HZ/2) / HZ; - ticks_per_usec = tick_rate / 1000000; - next_jiffy_time = 0xffffffff; - - timer_ctl = IOP3XX_TMR_EN | IOP3XX_TMR_PRIVILEGED | - IOP3XX_TMR_RELOAD | IOP3XX_TMR_RATIO_1_1; - - /* - * We use timer 0 for our timer interrupt, and timer 1 as - * monotonic counter for tracking missed jiffies. - */ - iop3xx_cp6_enable(); - asm volatile("mcr p6, 0, %0, c4, c1, 0" : : "r" (ticks_per_jiffy - 1)); - asm volatile("mcr p6, 0, %0, c0, c1, 0" : : "r" (timer_ctl)); - asm volatile("mcr p6, 0, %0, c5, c1, 0" : : "r" (0xffffffff)); - asm volatile("mcr p6, 0, %0, c1, c1, 0" : : "r" (timer_ctl)); - iop3xx_cp6_disable(); - - setup_irq(IRQ_IOP3XX_TIMER0, &iop3xx_timer_irq); -} diff --git a/trunk/arch/arm/plat-omap/clock.c b/trunk/arch/arm/plat-omap/clock.c index f1179ad4be1b..7f45c7c3e673 100644 --- a/trunk/arch/arm/plat-omap/clock.c +++ b/trunk/arch/arm/plat-omap/clock.c @@ -100,7 +100,6 @@ void clk_disable(struct clk *clk) return; spin_lock_irqsave(&clockfw_lock, flags); - BUG_ON(clk->usecount == 0); if (arch_clock->clk_disable) arch_clock->clk_disable(clk); spin_unlock_irqrestore(&clockfw_lock, flags); @@ -323,31 +322,6 @@ EXPORT_SYMBOL(clk_allow_idle); /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_OMAP_RESET_CLOCKS -/* - * Disable any unused clocks left on by the bootloader - */ -static int __init clk_disable_unused(void) -{ - struct clk *ck; - unsigned long flags; - - list_for_each_entry(ck, &clocks, node) { - if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) || - ck->enable_reg == 0) - continue; - - spin_lock_irqsave(&clockfw_lock, flags); - if (arch_clock->clk_disable_unused) - arch_clock->clk_disable_unused(ck); - spin_unlock_irqrestore(&clockfw_lock, flags); - } - - return 0; -} -late_initcall(clk_disable_unused); -#endif - int __init clk_init(struct clk_functions * custom_clocks) { if (!custom_clocks) { diff --git a/trunk/arch/arm/plat-omap/devices.c b/trunk/arch/arm/plat-omap/devices.c index dbc3f44e07a6..1812f237d12f 100644 --- a/trunk/arch/arm/plat-omap/devices.c +++ b/trunk/arch/arm/plat-omap/devices.c @@ -148,7 +148,7 @@ static inline void omap_init_kp(void) {} #ifdef CONFIG_ARCH_OMAP24XX #define OMAP_MMC1_BASE 0x4809c000 -#define OMAP_MMC1_INT INT_24XX_MMC_IRQ +#define OMAP_MMC1_INT 83 #else #define OMAP_MMC1_BASE 0xfffb7800 #define OMAP_MMC1_INT INT_MMC @@ -225,14 +225,7 @@ static void __init omap_init_mmc(void) /* block 1 is always available and has just one pinout option */ mmc = &mmc_conf->mmc[0]; if (mmc->enabled) { - if (cpu_is_omap24xx()) { - omap_cfg_reg(H18_24XX_MMC_CMD); - omap_cfg_reg(H15_24XX_MMC_CLKI); - omap_cfg_reg(G19_24XX_MMC_CLKO); - omap_cfg_reg(F20_24XX_MMC_DAT0); - omap_cfg_reg(F19_24XX_MMC_DAT_DIR0); - omap_cfg_reg(G18_24XX_MMC_CMD_DIR); - } else { + if (!cpu_is_omap24xx()) { omap_cfg_reg(MMC_CMD); omap_cfg_reg(MMC_CLK); omap_cfg_reg(MMC_DAT0); @@ -243,14 +236,7 @@ static void __init omap_init_mmc(void) } } if (mmc->wire4) { - if (cpu_is_omap24xx()) { - omap_cfg_reg(H14_24XX_MMC_DAT1); - omap_cfg_reg(E19_24XX_MMC_DAT2); - omap_cfg_reg(D19_24XX_MMC_DAT3); - omap_cfg_reg(E20_24XX_MMC_DAT_DIR1); - omap_cfg_reg(F18_24XX_MMC_DAT_DIR2); - omap_cfg_reg(E18_24XX_MMC_DAT_DIR3); - } else { + if (!cpu_is_omap24xx()) { omap_cfg_reg(MMC_DAT1); /* NOTE: DAT2 can be on W10 (here) or M15 */ if (!mmc->nomux) diff --git a/trunk/arch/arm/plat-omap/dma.c b/trunk/arch/arm/plat-omap/dma.c index 1bbb431843ce..9eddc9507147 100644 --- a/trunk/arch/arm/plat-omap/dma.c +++ b/trunk/arch/arm/plat-omap/dma.c @@ -119,41 +119,32 @@ static void clear_lch_regs(int lch) omap_writew(0, lch_base + i); } -void omap_set_dma_priority(int lch, int dst_port, int priority) +void omap_set_dma_priority(int dst_port, int priority) { unsigned long reg; u32 l; - if (cpu_class_is_omap1()) { - switch (dst_port) { - case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */ - reg = OMAP_TC_OCPT1_PRIOR; - break; - case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */ - reg = OMAP_TC_OCPT2_PRIOR; - break; - case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */ - reg = OMAP_TC_EMIFF_PRIOR; - break; - case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */ - reg = OMAP_TC_EMIFS_PRIOR; - break; - default: - BUG(); - return; - } - l = omap_readl(reg); - l &= ~(0xf << 8); - l |= (priority & 0xf) << 8; - omap_writel(l, reg); - } - - if (cpu_is_omap24xx()) { - if (priority) - OMAP_DMA_CCR_REG(lch) |= (1 << 6); - else - OMAP_DMA_CCR_REG(lch) &= ~(1 << 6); + switch (dst_port) { + case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */ + reg = OMAP_TC_OCPT1_PRIOR; + break; + case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */ + reg = OMAP_TC_OCPT2_PRIOR; + break; + case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */ + reg = OMAP_TC_EMIFF_PRIOR; + break; + case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */ + reg = OMAP_TC_EMIFS_PRIOR; + break; + default: + BUG(); + return; } + l = omap_readl(reg); + l &= ~(0xf << 8); + l |= (priority & 0xf) << 8; + omap_writel(l, reg); } void omap_set_dma_transfer_params(int lch, int data_type, int elem_count, @@ -243,14 +234,6 @@ void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color) OMAP1_DMA_LCH_CTRL_REG(lch) = w; } -void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode) -{ - if (cpu_is_omap24xx()) { - OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16); - OMAP_DMA_CSDP_REG(lch) |= (mode << 16); - } -} - /* Note that src_port is only for omap1 */ void omap_set_dma_src_params(int lch, int src_port, int src_amode, unsigned long src_start, @@ -714,32 +697,6 @@ void omap_stop_dma(int lch) dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE; } -/* - * Allows changing the DMA callback function or data. This may be needed if - * the driver shares a single DMA channel for multiple dma triggers. - */ -int omap_set_dma_callback(int lch, - void (* callback)(int lch, u16 ch_status, void *data), - void *data) -{ - unsigned long flags; - - if (lch < 0) - return -ENODEV; - - spin_lock_irqsave(&dma_chan_lock, flags); - if (dma_chan[lch].dev_id == -1) { - printk(KERN_ERR "DMA callback for not set for free channel\n"); - spin_unlock_irqrestore(&dma_chan_lock, flags); - return -EINVAL; - } - dma_chan[lch].callback = callback; - dma_chan[lch].data = data; - spin_unlock_irqrestore(&dma_chan_lock, flags); - - return 0; -} - /* * Returns current physical source address for the given DMA channel. * If the channel is running the caller must disable interrupts prior calling @@ -1382,14 +1339,6 @@ static int __init omap_init_dma(void) dma_chan_count = 16; } else dma_chan_count = 9; - if (cpu_is_omap16xx()) { - u16 w; - - /* this would prevent OMAP sleep */ - w = omap_readw(OMAP1610_DMA_LCD_CTRL); - w &= ~(1 << 8); - omap_writew(w, OMAP1610_DMA_LCD_CTRL); - } } else if (cpu_is_omap24xx()) { u8 revision = omap_readb(OMAP_DMA4_REVISION); printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", @@ -1465,13 +1414,11 @@ EXPORT_SYMBOL(omap_request_dma); EXPORT_SYMBOL(omap_free_dma); EXPORT_SYMBOL(omap_start_dma); EXPORT_SYMBOL(omap_stop_dma); -EXPORT_SYMBOL(omap_set_dma_callback); EXPORT_SYMBOL(omap_enable_dma_irq); EXPORT_SYMBOL(omap_disable_dma_irq); EXPORT_SYMBOL(omap_set_dma_transfer_params); EXPORT_SYMBOL(omap_set_dma_color_mode); -EXPORT_SYMBOL(omap_set_dma_write_mode); EXPORT_SYMBOL(omap_set_dma_src_params); EXPORT_SYMBOL(omap_set_dma_src_index); diff --git a/trunk/arch/arm/plat-omap/dmtimer.c b/trunk/arch/arm/plat-omap/dmtimer.c index bcbb8d7392be..50524436de63 100644 --- a/trunk/arch/arm/plat-omap/dmtimer.c +++ b/trunk/arch/arm/plat-omap/dmtimer.c @@ -75,14 +75,10 @@ struct omap_dm_timer { #endif void __iomem *io_base; unsigned reserved:1; - unsigned enabled:1; }; #ifdef CONFIG_ARCH_OMAP1 -#define omap_dm_clk_enable(x) -#define omap_dm_clk_disable(x) - static struct omap_dm_timer dm_timers[] = { { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 }, { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 }, @@ -96,9 +92,6 @@ static struct omap_dm_timer dm_timers[] = { #elif defined(CONFIG_ARCH_OMAP2) -#define omap_dm_clk_enable(x) clk_enable(x) -#define omap_dm_clk_disable(x) clk_disable(x) - static struct omap_dm_timer dm_timers[] = { { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 }, { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 }, @@ -161,28 +154,24 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer) { u32 l; - if (!cpu_class_is_omap2() || timer != &dm_timers[0]) { + if (timer != &dm_timers[0]) { omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); omap_dm_timer_wait_for_reset(timer); } - omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ); + omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_SYS_CLK); /* Set to smart-idle mode */ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_OCP_CFG_REG); l |= 0x02 << 3; - - if (cpu_class_is_omap2() && timer == &dm_timers[0]) { - /* Enable wake-up only for GPT1 on OMAP2 CPUs*/ - l |= 1 << 2; - /* Non-posted mode */ - omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0); - } omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_REG, l); } static void omap_dm_timer_prepare(struct omap_dm_timer *timer) { - omap_dm_timer_enable(timer); +#ifdef CONFIG_ARCH_OMAP2 + clk_enable(timer->iclk); + clk_enable(timer->fclk); +#endif omap_dm_timer_reset(timer); } @@ -234,36 +223,15 @@ struct omap_dm_timer *omap_dm_timer_request_specific(int id) void omap_dm_timer_free(struct omap_dm_timer *timer) { - omap_dm_timer_enable(timer); omap_dm_timer_reset(timer); - omap_dm_timer_disable(timer); - +#ifdef CONFIG_ARCH_OMAP2 + clk_disable(timer->iclk); + clk_disable(timer->fclk); +#endif WARN_ON(!timer->reserved); timer->reserved = 0; } -void omap_dm_timer_enable(struct omap_dm_timer *timer) -{ - if (timer->enabled) - return; - - omap_dm_clk_enable(timer->fclk); - omap_dm_clk_enable(timer->iclk); - - timer->enabled = 1; -} - -void omap_dm_timer_disable(struct omap_dm_timer *timer) -{ - if (!timer->enabled) - return; - - omap_dm_clk_disable(timer->iclk); - omap_dm_clk_disable(timer->fclk); - - timer->enabled = 0; -} - int omap_dm_timer_get_irq(struct omap_dm_timer *timer) { return timer->irq; @@ -308,7 +276,7 @@ __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer) { - return timer->fclk; + return timer->fclk; } __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask) @@ -438,16 +406,11 @@ void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value) { omap_dm_timer_write_reg(timer, OMAP_TIMER_INT_EN_REG, value); - omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, value); } unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) { - unsigned int l; - - l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); - - return l; + return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); } void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) @@ -457,16 +420,12 @@ void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer) { - unsigned int l; - - l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); - - return l; + return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); } void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) { - omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); + return omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); } int omap_dm_timers_active(void) @@ -477,14 +436,9 @@ int omap_dm_timers_active(void) struct omap_dm_timer *timer; timer = &dm_timers[i]; - - if (!timer->enabled) - continue; - if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) & - OMAP_TIMER_CTRL_ST) { + OMAP_TIMER_CTRL_ST) return 1; - } } return 0; } diff --git a/trunk/arch/arm/plat-omap/gpio.c b/trunk/arch/arm/plat-omap/gpio.c index f55f99ae58ae..cd7f973fb286 100644 --- a/trunk/arch/arm/plat-omap/gpio.c +++ b/trunk/arch/arm/plat-omap/gpio.c @@ -94,8 +94,6 @@ #define OMAP24XX_GPIO_SYSCONFIG 0x0010 #define OMAP24XX_GPIO_SYSSTATUS 0x0014 #define OMAP24XX_GPIO_IRQSTATUS1 0x0018 -#define OMAP24XX_GPIO_IRQSTATUS2 0x0028 -#define OMAP24XX_GPIO_IRQENABLE2 0x002c #define OMAP24XX_GPIO_IRQENABLE1 0x001c #define OMAP24XX_GPIO_CTRL 0x0030 #define OMAP24XX_GPIO_OE 0x0034 @@ -112,6 +110,8 @@ #define OMAP24XX_GPIO_CLEARDATAOUT 0x0090 #define OMAP24XX_GPIO_SETDATAOUT 0x0094 +#define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff) + struct gpio_bank { void __iomem *base; u16 irq; @@ -216,13 +216,11 @@ static inline int gpio_valid(int gpio) { if (gpio < 0) return -1; -#ifndef CONFIG_ARCH_OMAP24XX if (OMAP_GPIO_IS_MPUIO(gpio)) { - if (gpio >= OMAP_MAX_GPIO_LINES + 16) + if ((gpio & OMAP_MPUIO_MASK) > 16) return -1; return 0; } -#endif #ifdef CONFIG_ARCH_OMAP15XX if (cpu_is_omap15xx() && gpio < 16) return 0; @@ -531,10 +529,6 @@ static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) return; } __raw_writel(gpio_mask, reg); - - /* Workaround for clearing DSP GPIO interrupts to allow retention */ - if (cpu_is_omap2420()) - __raw_writel(gpio_mask, bank->base + OMAP24XX_GPIO_IRQSTATUS2); } static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio) @@ -668,14 +662,6 @@ static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable) } } -static void _reset_gpio(struct gpio_bank *bank, int gpio) -{ - _set_gpio_direction(bank, get_gpio_index(gpio), 1); - _set_gpio_irqenable(bank, gpio, 0); - _clear_gpio_irqstatus(bank, gpio); - _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); -} - /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ static int gpio_wake_enable(unsigned int irq, unsigned int enable) { @@ -686,7 +672,9 @@ static int gpio_wake_enable(unsigned int irq, unsigned int enable) if (check_gpio(gpio) < 0) return -ENODEV; bank = get_gpio_bank(gpio); + spin_lock(&bank->lock); retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable); + spin_unlock(&bank->lock); return retval; } @@ -708,9 +696,7 @@ int omap_request_gpio(int gpio) } bank->reserved_map |= (1 << get_gpio_index(gpio)); - /* Set trigger to none. You need to enable the desired trigger with - * request_irq() or set_irq_type(). - */ + /* Set trigger to none. You need to enable the trigger after request_irq */ _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); #ifdef CONFIG_ARCH_OMAP15XX @@ -770,7 +756,9 @@ void omap_free_gpio(int gpio) } #endif bank->reserved_map &= ~(1 << get_gpio_index(gpio)); - _reset_gpio(bank, gpio); + _set_gpio_direction(bank, get_gpio_index(gpio), 1); + _set_gpio_irqenable(bank, gpio, 0); + _clear_gpio_irqstatus(bank, gpio); spin_unlock(&bank->lock); } @@ -910,14 +898,6 @@ static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc, } -static void gpio_irq_shutdown(unsigned int irq) -{ - unsigned int gpio = irq - IH_GPIO_BASE; - struct gpio_bank *bank = get_gpio_bank(gpio); - - _reset_gpio(bank, gpio); -} - static void gpio_ack_irq(unsigned int irq) { unsigned int gpio = irq - IH_GPIO_BASE; @@ -966,7 +946,6 @@ static void mpuio_unmask_irq(unsigned int irq) static struct irq_chip gpio_irq_chip = { .name = "GPIO", - .shutdown = gpio_irq_shutdown, .ack = gpio_ack_irq, .mask = gpio_mask_irq, .unmask = gpio_unmask_irq, @@ -1006,7 +985,7 @@ static int __init _omap_gpio_init(void) else clk_enable(gpio_ick); gpio_fck = clk_get(NULL, "gpios_fck"); - if (IS_ERR(gpio_fck)) + if (IS_ERR(gpio_ick)) printk("Could not get gpios_fck\n"); else clk_enable(gpio_fck); @@ -1165,8 +1144,8 @@ static int omap_gpio_resume(struct sys_device *dev) wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; break; case METHOD_GPIO_24XX: - wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; - wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; + wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA; + wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; break; default: continue; diff --git a/trunk/arch/arm/plat-omap/mcbsp.c b/trunk/arch/arm/plat-omap/mcbsp.c index ade9a0fa6ef6..196aac3ac329 100644 --- a/trunk/arch/arm/plat-omap/mcbsp.c +++ b/trunk/arch/arm/plat-omap/mcbsp.c @@ -75,6 +75,8 @@ static struct clk *mcbsp1_ick = 0; static struct clk *mcbsp1_fck = 0; static struct clk *mcbsp2_ick = 0; static struct clk *mcbsp2_fck = 0; +static struct clk *sys_ck = 0; +static struct clk *sys_clkout = 0; #endif static void omap_mcbsp_dump_reg(u8 id) @@ -230,6 +232,7 @@ static void omap2_mcbsp2_mux_setup(void) omap_cfg_reg(W15_24XX_MCBSP2_DR); omap_cfg_reg(V15_24XX_MCBSP2_DX); omap_cfg_reg(V14_24XX_GPIO117); + omap_cfg_reg(W14_24XX_SYS_CLKOUT); } #endif @@ -981,7 +984,13 @@ static int __init omap_mcbsp_init(void) if (cpu_is_omap24xx()) { mcbsp_info = mcbsp_24xx; mcbsp_count = ARRAY_SIZE(mcbsp_24xx); + + /* REVISIT: where's the right place? */ omap2_mcbsp2_mux_setup(); + sys_ck = clk_get(0, "sys_ck"); + sys_clkout = clk_get(0, "sys_clkout"); + clk_set_parent(sys_clkout, sys_ck); + clk_enable(sys_clkout); } #endif for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) { diff --git a/trunk/arch/arm/plat-omap/pm.c b/trunk/arch/arm/plat-omap/pm.c new file mode 100644 index 000000000000..04b4102727a8 --- /dev/null +++ b/trunk/arch/arm/plat-omap/pm.c @@ -0,0 +1,670 @@ +/* + * linux/arch/arm/plat-omap/pm.c + * + * OMAP Power Management Routines + * + * Original code for the SA11x0: + * Copyright (c) 2001 Cliff Brake + * + * Modified for the PXA250 by Nicolas Pitre: + * Copyright (c) 2002 Monta Vista Software, Inc. + * + * Modified for the OMAP1510 by David Singleton: + * Copyright (c) 2002 Monta Vista Software, Inc. + * + * Cleanup 2004 for OMAP1510/1610 by Dirk Behme + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE]; +static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE]; +static unsigned int mpui730_sleep_save[MPUI730_SLEEP_SAVE_SIZE]; +static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE]; +static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE]; + +static void (*omap_sram_idle)(void) = NULL; +static void (*omap_sram_suspend)(unsigned long r0, unsigned long r1) = NULL; + +/* + * Let's power down on idle, but only if we are really + * idle, because once we start down the path of + * going idle we continue to do idle even if we get + * a clock tick interrupt . . + */ +void omap_pm_idle(void) +{ + unsigned int mask32 = 0; + + /* + * If the DSP is being used let's just idle the CPU, the overhead + * to wake up from Big Sleep is big, milliseconds versus micro + * seconds for wait for interrupt. + */ + + local_irq_disable(); + local_fiq_disable(); + if (need_resched()) { + local_fiq_enable(); + local_irq_enable(); + return; + } + mask32 = omap_readl(ARM_SYSST); + + /* + * Prevent the ULPD from entering low power state by setting + * POWER_CTRL_REG:4 = 0 + */ + omap_writew(omap_readw(ULPD_POWER_CTRL) & + ~ULPD_DEEP_SLEEP_TRANSITION_EN, ULPD_POWER_CTRL); + + /* + * Since an interrupt may set up a timer, we don't want to + * reprogram the hardware timer with interrupts enabled. + * Re-enable interrupts only after returning from idle. + */ + timer_dyn_reprogram(); + + if ((mask32 & DSP_IDLE) == 0) { + __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); + } else + omap_sram_idle(); + + local_fiq_enable(); + local_irq_enable(); +} + +/* + * Configuration of the wakeup event is board specific. For the + * moment we put it into this helper function. Later it may move + * to board specific files. + */ +static void omap_pm_wakeup_setup(void) +{ + u32 level1_wake = 0; + u32 level2_wake = OMAP_IRQ_BIT(INT_UART2); + + /* + * Turn off all interrupts except GPIO bank 1, L1-2nd level cascade, + * and the L2 wakeup interrupts: keypad and UART2. Note that the + * drivers must still separately call omap_set_gpio_wakeup() to + * wake up to a GPIO interrupt. + */ + if (cpu_is_omap730()) + level1_wake = OMAP_IRQ_BIT(INT_730_GPIO_BANK1) | + OMAP_IRQ_BIT(INT_730_IH2_IRQ); + else if (cpu_is_omap1510()) + level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) | + OMAP_IRQ_BIT(INT_1510_IH2_IRQ); + else if (cpu_is_omap16xx()) + level1_wake = OMAP_IRQ_BIT(INT_GPIO_BANK1) | + OMAP_IRQ_BIT(INT_1610_IH2_IRQ); + + omap_writel(~level1_wake, OMAP_IH1_MIR); + + if (cpu_is_omap730()) { + omap_writel(~level2_wake, OMAP_IH2_0_MIR); + omap_writel(~(OMAP_IRQ_BIT(INT_730_WAKE_UP_REQ) | OMAP_IRQ_BIT(INT_730_MPUIO_KEYPAD)), OMAP_IH2_1_MIR); + } else if (cpu_is_omap1510()) { + level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD); + omap_writel(~level2_wake, OMAP_IH2_MIR); + } else if (cpu_is_omap16xx()) { + level2_wake |= OMAP_IRQ_BIT(INT_KEYBOARD); + omap_writel(~level2_wake, OMAP_IH2_0_MIR); + + /* INT_1610_WAKE_UP_REQ is needed for GPIO wakeup... */ + omap_writel(~OMAP_IRQ_BIT(INT_1610_WAKE_UP_REQ), OMAP_IH2_1_MIR); + omap_writel(~0x0, OMAP_IH2_2_MIR); + omap_writel(~0x0, OMAP_IH2_3_MIR); + } + + /* New IRQ agreement, recalculate in cascade order */ + omap_writel(1, OMAP_IH2_CONTROL); + omap_writel(1, OMAP_IH1_CONTROL); +} + +void omap_pm_suspend(void) +{ + unsigned long arg0 = 0, arg1 = 0; + + printk("PM: OMAP%x is trying to enter deep sleep...\n", system_rev); + + omap_serial_wake_trigger(1); + + if (machine_is_omap_osk()) { + /* Stop LED1 (D9) blink */ + tps65010_set_led(LED1, OFF); + } + + omap_writew(0xffff, ULPD_SOFT_DISABLE_REQ_REG); + + /* + * Step 1: turn off interrupts (FIXME: NOTE: already disabled) + */ + + local_irq_disable(); + local_fiq_disable(); + + /* + * Step 2: save registers + * + * The omap is a strange/beautiful device. The caches, memory + * and register state are preserved across power saves. + * We have to save and restore very little register state to + * idle the omap. + * + * Save interrupt, MPUI, ARM and UPLD control registers. + */ + + if (cpu_is_omap730()) { + MPUI730_SAVE(OMAP_IH1_MIR); + MPUI730_SAVE(OMAP_IH2_0_MIR); + MPUI730_SAVE(OMAP_IH2_1_MIR); + MPUI730_SAVE(MPUI_CTRL); + MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG); + MPUI730_SAVE(MPUI_DSP_API_CONFIG); + MPUI730_SAVE(EMIFS_CONFIG); + MPUI730_SAVE(EMIFF_SDRAM_CONFIG); + + } else if (cpu_is_omap1510()) { + MPUI1510_SAVE(OMAP_IH1_MIR); + MPUI1510_SAVE(OMAP_IH2_MIR); + MPUI1510_SAVE(MPUI_CTRL); + MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); + MPUI1510_SAVE(MPUI_DSP_API_CONFIG); + MPUI1510_SAVE(EMIFS_CONFIG); + MPUI1510_SAVE(EMIFF_SDRAM_CONFIG); + } else if (cpu_is_omap16xx()) { + MPUI1610_SAVE(OMAP_IH1_MIR); + MPUI1610_SAVE(OMAP_IH2_0_MIR); + MPUI1610_SAVE(OMAP_IH2_1_MIR); + MPUI1610_SAVE(OMAP_IH2_2_MIR); + MPUI1610_SAVE(OMAP_IH2_3_MIR); + MPUI1610_SAVE(MPUI_CTRL); + MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG); + MPUI1610_SAVE(MPUI_DSP_API_CONFIG); + MPUI1610_SAVE(EMIFS_CONFIG); + MPUI1610_SAVE(EMIFF_SDRAM_CONFIG); + } + + ARM_SAVE(ARM_CKCTL); + ARM_SAVE(ARM_IDLECT1); + ARM_SAVE(ARM_IDLECT2); + if (!(cpu_is_omap1510())) + ARM_SAVE(ARM_IDLECT3); + ARM_SAVE(ARM_EWUPCT); + ARM_SAVE(ARM_RSTCT1); + ARM_SAVE(ARM_RSTCT2); + ARM_SAVE(ARM_SYSST); + ULPD_SAVE(ULPD_CLOCK_CTRL); + ULPD_SAVE(ULPD_STATUS_REQ); + + /* (Step 3 removed - we now allow deep sleep by default) */ + + /* + * Step 4: OMAP DSP Shutdown + */ + + + /* + * Step 5: Wakeup Event Setup + */ + + omap_pm_wakeup_setup(); + + /* + * Step 6: ARM and Traffic controller shutdown + */ + + /* disable ARM watchdog */ + omap_writel(0x00F5, OMAP_WDT_TIMER_MODE); + omap_writel(0x00A0, OMAP_WDT_TIMER_MODE); + + /* + * Step 6b: ARM and Traffic controller shutdown + * + * Step 6 continues here. Prepare jump to power management + * assembly code in internal SRAM. + * + * Since the omap_cpu_suspend routine has been copied to + * SRAM, we'll do an indirect procedure call to it and pass the + * contents of arm_idlect1 and arm_idlect2 so it can restore + * them when it wakes up and it will return. + */ + + arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1]; + arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2]; + + /* + * Step 6c: ARM and Traffic controller shutdown + * + * Jump to assembly code. The processor will stay there + * until wake up. + */ + omap_sram_suspend(arg0, arg1); + + /* + * If we are here, processor is woken up! + */ + + /* + * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did + */ + + if (!(cpu_is_omap1510())) + ARM_RESTORE(ARM_IDLECT3); + ARM_RESTORE(ARM_CKCTL); + ARM_RESTORE(ARM_EWUPCT); + ARM_RESTORE(ARM_RSTCT1); + ARM_RESTORE(ARM_RSTCT2); + ARM_RESTORE(ARM_SYSST); + ULPD_RESTORE(ULPD_CLOCK_CTRL); + ULPD_RESTORE(ULPD_STATUS_REQ); + + if (cpu_is_omap730()) { + MPUI730_RESTORE(EMIFS_CONFIG); + MPUI730_RESTORE(EMIFF_SDRAM_CONFIG); + MPUI730_RESTORE(OMAP_IH1_MIR); + MPUI730_RESTORE(OMAP_IH2_0_MIR); + MPUI730_RESTORE(OMAP_IH2_1_MIR); + } else if (cpu_is_omap1510()) { + MPUI1510_RESTORE(MPUI_CTRL); + MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG); + MPUI1510_RESTORE(MPUI_DSP_API_CONFIG); + MPUI1510_RESTORE(EMIFS_CONFIG); + MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG); + MPUI1510_RESTORE(OMAP_IH1_MIR); + MPUI1510_RESTORE(OMAP_IH2_MIR); + } else if (cpu_is_omap16xx()) { + MPUI1610_RESTORE(MPUI_CTRL); + MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG); + MPUI1610_RESTORE(MPUI_DSP_API_CONFIG); + MPUI1610_RESTORE(EMIFS_CONFIG); + MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG); + + MPUI1610_RESTORE(OMAP_IH1_MIR); + MPUI1610_RESTORE(OMAP_IH2_0_MIR); + MPUI1610_RESTORE(OMAP_IH2_1_MIR); + MPUI1610_RESTORE(OMAP_IH2_2_MIR); + MPUI1610_RESTORE(OMAP_IH2_3_MIR); + } + + omap_writew(0, ULPD_SOFT_DISABLE_REQ_REG); + + /* + * Reenable interrupts + */ + + local_irq_enable(); + local_fiq_enable(); + + omap_serial_wake_trigger(0); + + printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev); + + if (machine_is_omap_osk()) { + /* Let LED1 (D9) blink again */ + tps65010_set_led(LED1, BLINK); + } +} + +#if defined(DEBUG) && defined(CONFIG_PROC_FS) +static int g_read_completed; + +/* + * Read system PM registers for debugging + */ +static int omap_pm_read_proc( + char *page_buffer, + char **my_first_byte, + off_t virtual_start, + int length, + int *eof, + void *data) +{ + int my_buffer_offset = 0; + char * const my_base = page_buffer; + + ARM_SAVE(ARM_CKCTL); + ARM_SAVE(ARM_IDLECT1); + ARM_SAVE(ARM_IDLECT2); + if (!(cpu_is_omap1510())) + ARM_SAVE(ARM_IDLECT3); + ARM_SAVE(ARM_EWUPCT); + ARM_SAVE(ARM_RSTCT1); + ARM_SAVE(ARM_RSTCT2); + ARM_SAVE(ARM_SYSST); + + ULPD_SAVE(ULPD_IT_STATUS); + ULPD_SAVE(ULPD_CLOCK_CTRL); + ULPD_SAVE(ULPD_SOFT_REQ); + ULPD_SAVE(ULPD_STATUS_REQ); + ULPD_SAVE(ULPD_DPLL_CTRL); + ULPD_SAVE(ULPD_POWER_CTRL); + + if (cpu_is_omap730()) { + MPUI730_SAVE(MPUI_CTRL); + MPUI730_SAVE(MPUI_DSP_STATUS); + MPUI730_SAVE(MPUI_DSP_BOOT_CONFIG); + MPUI730_SAVE(MPUI_DSP_API_CONFIG); + MPUI730_SAVE(EMIFF_SDRAM_CONFIG); + MPUI730_SAVE(EMIFS_CONFIG); + } else if (cpu_is_omap1510()) { + MPUI1510_SAVE(MPUI_CTRL); + MPUI1510_SAVE(MPUI_DSP_STATUS); + MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG); + MPUI1510_SAVE(MPUI_DSP_API_CONFIG); + MPUI1510_SAVE(EMIFF_SDRAM_CONFIG); + MPUI1510_SAVE(EMIFS_CONFIG); + } else if (cpu_is_omap16xx()) { + MPUI1610_SAVE(MPUI_CTRL); + MPUI1610_SAVE(MPUI_DSP_STATUS); + MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG); + MPUI1610_SAVE(MPUI_DSP_API_CONFIG); + MPUI1610_SAVE(EMIFF_SDRAM_CONFIG); + MPUI1610_SAVE(EMIFS_CONFIG); + } + + if (virtual_start == 0) { + g_read_completed = 0; + + my_buffer_offset += sprintf(my_base + my_buffer_offset, + "ARM_CKCTL_REG: 0x%-8x \n" + "ARM_IDLECT1_REG: 0x%-8x \n" + "ARM_IDLECT2_REG: 0x%-8x \n" + "ARM_IDLECT3_REG: 0x%-8x \n" + "ARM_EWUPCT_REG: 0x%-8x \n" + "ARM_RSTCT1_REG: 0x%-8x \n" + "ARM_RSTCT2_REG: 0x%-8x \n" + "ARM_SYSST_REG: 0x%-8x \n" + "ULPD_IT_STATUS_REG: 0x%-4x \n" + "ULPD_CLOCK_CTRL_REG: 0x%-4x \n" + "ULPD_SOFT_REQ_REG: 0x%-4x \n" + "ULPD_DPLL_CTRL_REG: 0x%-4x \n" + "ULPD_STATUS_REQ_REG: 0x%-4x \n" + "ULPD_POWER_CTRL_REG: 0x%-4x \n", + ARM_SHOW(ARM_CKCTL), + ARM_SHOW(ARM_IDLECT1), + ARM_SHOW(ARM_IDLECT2), + ARM_SHOW(ARM_IDLECT3), + ARM_SHOW(ARM_EWUPCT), + ARM_SHOW(ARM_RSTCT1), + ARM_SHOW(ARM_RSTCT2), + ARM_SHOW(ARM_SYSST), + ULPD_SHOW(ULPD_IT_STATUS), + ULPD_SHOW(ULPD_CLOCK_CTRL), + ULPD_SHOW(ULPD_SOFT_REQ), + ULPD_SHOW(ULPD_DPLL_CTRL), + ULPD_SHOW(ULPD_STATUS_REQ), + ULPD_SHOW(ULPD_POWER_CTRL)); + + if (cpu_is_omap730()) { + my_buffer_offset += sprintf(my_base + my_buffer_offset, + "MPUI730_CTRL_REG 0x%-8x \n" + "MPUI730_DSP_STATUS_REG: 0x%-8x \n" + "MPUI730_DSP_BOOT_CONFIG_REG: 0x%-8x \n" + "MPUI730_DSP_API_CONFIG_REG: 0x%-8x \n" + "MPUI730_SDRAM_CONFIG_REG: 0x%-8x \n" + "MPUI730_EMIFS_CONFIG_REG: 0x%-8x \n", + MPUI730_SHOW(MPUI_CTRL), + MPUI730_SHOW(MPUI_DSP_STATUS), + MPUI730_SHOW(MPUI_DSP_BOOT_CONFIG), + MPUI730_SHOW(MPUI_DSP_API_CONFIG), + MPUI730_SHOW(EMIFF_SDRAM_CONFIG), + MPUI730_SHOW(EMIFS_CONFIG)); + } else if (cpu_is_omap1510()) { + my_buffer_offset += sprintf(my_base + my_buffer_offset, + "MPUI1510_CTRL_REG 0x%-8x \n" + "MPUI1510_DSP_STATUS_REG: 0x%-8x \n" + "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n" + "MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n" + "MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n" + "MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n", + MPUI1510_SHOW(MPUI_CTRL), + MPUI1510_SHOW(MPUI_DSP_STATUS), + MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG), + MPUI1510_SHOW(MPUI_DSP_API_CONFIG), + MPUI1510_SHOW(EMIFF_SDRAM_CONFIG), + MPUI1510_SHOW(EMIFS_CONFIG)); + } else if (cpu_is_omap16xx()) { + my_buffer_offset += sprintf(my_base + my_buffer_offset, + "MPUI1610_CTRL_REG 0x%-8x \n" + "MPUI1610_DSP_STATUS_REG: 0x%-8x \n" + "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n" + "MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n" + "MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n" + "MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n", + MPUI1610_SHOW(MPUI_CTRL), + MPUI1610_SHOW(MPUI_DSP_STATUS), + MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG), + MPUI1610_SHOW(MPUI_DSP_API_CONFIG), + MPUI1610_SHOW(EMIFF_SDRAM_CONFIG), + MPUI1610_SHOW(EMIFS_CONFIG)); + } + + g_read_completed++; + } else if (g_read_completed >= 1) { + *eof = 1; + return 0; + } + g_read_completed++; + + *my_first_byte = page_buffer; + return my_buffer_offset; +} + +static void omap_pm_init_proc(void) +{ + struct proc_dir_entry *entry; + + entry = create_proc_read_entry("driver/omap_pm", + S_IWUSR | S_IRUGO, NULL, + omap_pm_read_proc, NULL); +} + +#endif /* DEBUG && CONFIG_PROC_FS */ + +/* + * omap_pm_prepare - Do preliminary suspend work. + * @state: suspend state we're entering. + * + */ +//#include + +static int omap_pm_prepare(suspend_state_t state) +{ + int error = 0; + + switch (state) + { + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + break; + + case PM_SUSPEND_DISK: + return -ENOTSUPP; + + default: + return -EINVAL; + } + + return error; +} + + +/* + * omap_pm_enter - Actually enter a sleep state. + * @state: State we're entering. + * + */ + +static int omap_pm_enter(suspend_state_t state) +{ + switch (state) + { + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + omap_pm_suspend(); + break; + + case PM_SUSPEND_DISK: + return -ENOTSUPP; + + default: + return -EINVAL; + } + + return 0; +} + + +/** + * omap_pm_finish - Finish up suspend sequence. + * @state: State we're coming out of. + * + * This is called after we wake back up (or if entering the sleep state + * failed). + */ + +static int omap_pm_finish(suspend_state_t state) +{ + return 0; +} + + +static irqreturn_t omap_wakeup_interrupt(int irq, void * dev, + struct pt_regs * regs) +{ + return IRQ_HANDLED; +} + +static struct irqaction omap_wakeup_irq = { + .name = "peripheral wakeup", + .flags = IRQF_DISABLED, + .handler = omap_wakeup_interrupt +}; + + + +static struct pm_ops omap_pm_ops ={ + .pm_disk_mode = 0, + .prepare = omap_pm_prepare, + .enter = omap_pm_enter, + .finish = omap_pm_finish, +}; + +static int __init omap_pm_init(void) +{ + printk("Power Management for TI OMAP.\n"); + /* + * We copy the assembler sleep/wakeup routines to SRAM. + * These routines need to be in SRAM as that's the only + * memory the MPU can see when it wakes up. + */ + if (cpu_is_omap730()) { + omap_sram_idle = omap_sram_push(omap730_idle_loop_suspend, + omap730_idle_loop_suspend_sz); + omap_sram_suspend = omap_sram_push(omap730_cpu_suspend, + omap730_cpu_suspend_sz); + } else if (cpu_is_omap1510()) { + omap_sram_idle = omap_sram_push(omap1510_idle_loop_suspend, + omap1510_idle_loop_suspend_sz); + omap_sram_suspend = omap_sram_push(omap1510_cpu_suspend, + omap1510_cpu_suspend_sz); + } else if (cpu_is_omap16xx()) { + omap_sram_idle = omap_sram_push(omap1610_idle_loop_suspend, + omap1610_idle_loop_suspend_sz); + omap_sram_suspend = omap_sram_push(omap1610_cpu_suspend, + omap1610_cpu_suspend_sz); + } + + if (omap_sram_idle == NULL || omap_sram_suspend == NULL) { + printk(KERN_ERR "PM not initialized: Missing SRAM support\n"); + return -ENODEV; + } + + pm_idle = omap_pm_idle; + + if (cpu_is_omap730()) + setup_irq(INT_730_WAKE_UP_REQ, &omap_wakeup_irq); + else if (cpu_is_omap16xx()) + setup_irq(INT_1610_WAKE_UP_REQ, &omap_wakeup_irq); + +#if 0 + /* --- BEGIN BOARD-DEPENDENT CODE --- */ + /* Sleepx mask direction */ + omap_writew((omap_readw(0xfffb5008) & ~2), 0xfffb5008); + /* Unmask sleepx signal */ + omap_writew((omap_readw(0xfffb5004) & ~2), 0xfffb5004); + /* --- END BOARD-DEPENDENT CODE --- */ +#endif + + /* Program new power ramp-up time + * (0 for most boards since we don't lower voltage when in deep sleep) + */ + omap_writew(ULPD_SETUP_ANALOG_CELL_3_VAL, ULPD_SETUP_ANALOG_CELL_3); + + /* Setup ULPD POWER_CTRL_REG - enter deep sleep whenever possible */ + omap_writew(ULPD_POWER_CTRL_REG_VAL, ULPD_POWER_CTRL); + + /* Configure IDLECT3 */ + if (cpu_is_omap730()) + omap_writel(OMAP730_IDLECT3_VAL, OMAP730_IDLECT3); + else if (cpu_is_omap16xx()) + omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3); + + pm_set_ops(&omap_pm_ops); + +#if defined(DEBUG) && defined(CONFIG_PROC_FS) + omap_pm_init_proc(); +#endif + + if (cpu_is_omap16xx()) { + /* configure LOW_PWR pin */ + omap_cfg_reg(T20_1610_LOW_PWR); + } + + return 0; +} +__initcall(omap_pm_init); + diff --git a/trunk/arch/arm/plat-omap/sram.c b/trunk/arch/arm/plat-omap/sram.c index 19014b2ff4c6..e75718301b0f 100644 --- a/trunk/arch/arm/plat-omap/sram.c +++ b/trunk/arch/arm/plat-omap/sram.c @@ -174,7 +174,10 @@ void __init omap_map_sram(void) if (cpu_is_omap24xx()) { omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; - base = OMAP2_SRAM_PA; + if (is_sram_locked()) + base = OMAP2_SRAM_PUB_PA; + else + base = OMAP2_SRAM_PA; base = ROUND_DOWN(base, PAGE_SIZE); omap_sram_io_desc[0].pfn = __phys_to_pfn(base); } diff --git a/trunk/arch/arm/plat-omap/timer32k.c b/trunk/arch/arm/plat-omap/timer32k.c index cf6df3378d37..281ecc7fcdfc 100644 --- a/trunk/arch/arm/plat-omap/timer32k.c +++ b/trunk/arch/arm/plat-omap/timer32k.c @@ -105,8 +105,6 @@ static inline unsigned long omap_32k_timer_read(int reg) static inline void omap_32k_timer_start(unsigned long load_val) { - if (!load_val) - load_val = 1; omap_32k_timer_write(load_val, OMAP1_32K_TIMER_TVR); omap_32k_timer_write(0x0f, OMAP1_32K_TIMER_CR); } @@ -194,11 +192,14 @@ unsigned long long sched_clock(void) * issues with dynamic tick. In the dynamic tick case, we need to lock * with irqsave. */ -static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, + struct pt_regs *regs) { + unsigned long flags; unsigned long now; + write_seqlock_irqsave(&xtime_lock, flags); + omap_32k_timer_ack_irq(); now = omap_32k_sync_timer_read(); @@ -214,23 +215,6 @@ static inline irqreturn_t _omap_32k_timer_interrupt(int irq, void *dev_id, * continuous timer can be overridden from pm_idle to be longer. */ omap_32k_timer_start(omap_32k_last_tick + OMAP_32K_TICKS_PER_HZ - now); - - return IRQ_HANDLED; -} - -static irqreturn_t omap_32k_timer_handler(int irq, void *dev_id, - struct pt_regs *regs) -{ - return _omap_32k_timer_interrupt(irq, dev_id, regs); -} - -static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, - struct pt_regs *regs) -{ - unsigned long flags; - - write_seqlock_irqsave(&xtime_lock, flags); - _omap_32k_timer_interrupt(irq, dev_id, regs); write_sequnlock_irqrestore(&xtime_lock, flags); return IRQ_HANDLED; @@ -246,15 +230,7 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, */ void omap_32k_timer_reprogram(unsigned long next_tick) { - unsigned long ticks = JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1; - unsigned long now = omap_32k_sync_timer_read(); - unsigned long idled = now - omap_32k_last_tick; - - if (idled + 1 < ticks) - ticks -= idled; - else - ticks = 1; - omap_32k_timer_start(ticks); + omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); } static struct irqaction omap_32k_timer_irq; @@ -276,7 +252,7 @@ static struct dyn_tick_timer omap_dyn_tick_timer = { .enable = omap_32k_timer_enable_dyn_tick, .disable = omap_32k_timer_disable_dyn_tick, .reprogram = omap_32k_timer_reprogram, - .handler = omap_32k_timer_handler, + .handler = omap_32k_timer_interrupt, }; #endif /* CONFIG_NO_IDLE_HZ */ diff --git a/trunk/arch/arm/plat-omap/usb.c b/trunk/arch/arm/plat-omap/usb.c index 7e8096809be2..9b815327b6a5 100644 --- a/trunk/arch/arm/plat-omap/usb.c +++ b/trunk/arch/arm/plat-omap/usb.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/arch/arm/tools/mach-types b/trunk/arch/arm/tools/mach-types index b02af1d740fa..e1372a25311d 100644 --- a/trunk/arch/arm/tools/mach-types +++ b/trunk/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Sat Sep 23 13:20:43 2006 +# Last update: Mon Jun 26 22:26:08 2006 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -329,7 +329,7 @@ nimbra29x ARCH_NIMBRA29X NIMBRA29X 311 nimbra210 ARCH_NIMBRA210 NIMBRA210 312 hhp_d95xx ARCH_HHP_D95XX HHP_D95XX 313 labarm ARCH_LABARM LABARM 314 -m825xx ARCH_M825XX M825XX 315 +comcerto ARCH_M825XX M825XX 315 m7100 SA1100_M7100 M7100 316 nipc2 ARCH_NIPC2 NIPC2 317 fu7202 ARCH_FU7202 FU7202 318 @@ -857,12 +857,12 @@ osiris MACH_OSIRIS OSIRIS 842 maestro MACH_MAESTRO MAESTRO 843 tunge2 MACH_TUNGE2 TUNGE2 844 ixbbm MACH_IXBBM IXBBM 845 -mx27ads MACH_MX27ADS MX27ADS 846 +mx27ads MACH_MX27 MX27 846 ax8004 MACH_AX8004 AX8004 847 at91sam9261ek MACH_AT91SAM9261EK AT91SAM9261EK 848 loft MACH_LOFT LOFT 849 magpie MACH_MAGPIE MAGPIE 850 -mx21ads MACH_MX21ADS MX21ADS 851 +mx21ads MACH_MX21 MX21 851 mb87m3400 MACH_MB87M3400 MB87M3400 852 mguard_delta MACH_MGUARD_DELTA MGUARD_DELTA 853 davinci_dvdp MACH_DAVINCI_DVDP DAVINCI_DVDP 854 @@ -1058,7 +1058,7 @@ akai9307 MACH_AKAI9307 AKAI9307 1044 fontaine MACH_FONTAINE FONTAINE 1045 wombat MACH_WOMBAT WOMBAT 1046 acq300 MACH_ACQ300 ACQ300 1047 -mod272 MACH_MOD_270 MOD_270 1048 +mod_270 MACH_MOD_270 MOD_270 1048 vmc_vc0820 MACH_VC0820 VC0820 1049 ani_aim MACH_ANI_AIM ANI_AIM 1050 jellyfish MACH_JELLYFISH JELLYFISH 1051 @@ -1093,67 +1093,3 @@ msm6100 MACH_MSM6100 MSM6100 1079 eti_b1 MACH_ETI_B1 ETI_B1 1080 za9l_series MACH_ZILOG_ZA9L ZILOG_ZA9L 1081 bit2440 MACH_BIT2440 BIT2440 1082 -nbi MACH_NBI NBI 1083 -smdk2443 MACH_SMDK2443 SMDK2443 1084 -vdavinci MACH_VDAVINCI VDAVINCI 1085 -atc6 MACH_ATC6 ATC6 1086 -multmdw MACH_MULTMDW MULTMDW 1087 -mba2440 MACH_MBA2440 MBA2440 1088 -ecsd MACH_ECSD ECSD 1089 -zire31 MACH_ZIRE31 ZIRE31 1090 -fsg MACH_FSG FSG 1091 -razor101 MACH_RAZOR101 RAZOR101 1092 -opera_tdm MACH_OPERA_TDM OPERA_TDM 1093 -comcerto MACH_COMCERTO COMCERTO 1094 -tb0319 MACH_TB0319 TB0319 1095 -kws8000 MACH_KWS8000 KWS8000 1096 -b2 MACH_B2 B2 1097 -lcl54 MACH_LCL54 LCL54 1098 -at91sam9260ek MACH_AT91SAM9260EK AT91SAM9260EK 1099 -glantank MACH_GLANTANK GLANTANK 1100 -n2100 MACH_N2100 N2100 1101 -n4100 MACH_N4100 N4100 1102 -rsc4 MACH_VERTICAL_RSC4 VERTICAL_RSC4 1103 -sg8100 MACH_SG8100 SG8100 1104 -im42xx MACH_IM42XX IM42XX 1105 -ftxx MACH_FTXX FTXX 1106 -lwfusion MACH_LWFUSION LWFUSION 1107 -qt2410 MACH_QT2410 QT2410 1108 -kixrp435 MACH_KIXRP435 KIXRP435 1109 -ccw9c MACH_CCW9C CCW9C 1110 -dabhs MACH_DABHS DABHS 1111 -gzmx MACH_GZMX GZMX 1112 -ipnw100ap MACH_IPNW100AP IPNW100AP 1113 -cc9p9360dev MACH_CC9P9360DEV CC9P9360DEV 1114 -cc9p9750dev MACH_CC9P9750DEV CC9P9750DEV 1115 -cc9p9360val MACH_CC9P9360VAL CC9P9360VAL 1116 -cc9p9750val MACH_CC9P9750VAL CC9P9750VAL 1117 -nx70v MACH_NX70V NX70V 1118 -at91rm9200df MACH_AT91RM9200DF AT91RM9200DF 1119 -se_pilot2 MACH_SE_PILOT2 SE_PILOT2 1120 -mtcn_t800 MACH_MTCN_T800 MTCN_T800 1121 -vcmx212 MACH_VCMX212 VCMX212 1122 -lynx MACH_LYNX LYNX 1123 -at91sam9260id MACH_AT91SAM9260ID AT91SAM9260ID 1124 -hw86052 MACH_HW86052 HW86052 1125 -pilz_pmi3 MACH_PILZ_PMI3 PILZ_PMI3 1126 -edb9302a MACH_EDB9302A EDB9302A 1127 -edb9307a MACH_EDB9307A EDB9307A 1128 -ct_dfs MACH_CT_DFS CT_DFS 1129 -pilz_pmi4 MACH_PILZ_PMI4 PILZ_PMI4 1130 -xceednp_ixp MACH_XCEEDNP_IXP XCEEDNP_IXP 1131 -smdk2442b MACH_SMDK2442B SMDK2442B 1132 -xnode MACH_XNODE XNODE 1133 -aidx270 MACH_AIDX270 AIDX270 1134 -rema MACH_REMA REMA 1135 -bps1000 MACH_BPS1000 BPS1000 1136 -hw90350 MACH_HW90350 HW90350 1137 -omap_sdp3430 MACH_OMAP_SDP3430 OMAP_SDP3430 1138 -bluetouch MACH_BLUETOUCH BLUETOUCH 1139 -vstms MACH_VSTMS VSTMS 1140 -xsbase270 MACH_XSBASE270 XSBASE270 1141 -at91sam9260ek_cn MACH_AT91SAM9260EK_CN AT91SAM9260EK_CN 1142 -adsturboxb MACH_ADSTURBOXB ADSTURBOXB 1143 -oti4110 MACH_OTI4110 OTI4110 1144 -hme_pxa MACH_HME_PXA HME_PXA 1145 -deisterdca MACH_DEISTERDCA DEISTERDCA 1146 diff --git a/trunk/arch/arm/vfp/vfp.h b/trunk/arch/arm/vfp/vfp.h index f2797896e6d5..96fdf30f6a3b 100644 --- a/trunk/arch/arm/vfp/vfp.h +++ b/trunk/arch/arm/vfp/vfp.h @@ -355,18 +355,3 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand); * we check for an error. */ #define VFP_EXCEPTION_ERROR ((u32)-1 & ~VFP_NAN_FLAG) - -/* - * A flag to tell vfp instruction type. - * OP_SCALAR - this operation always operates in scalar mode - * OP_SD - the instruction exceptionally writes to a single precision result. - * OP_DD - the instruction exceptionally writes to a double precision result. - */ -#define OP_SCALAR (1 << 0) -#define OP_SD (1 << 1) -#define OP_DD (1 << 1) - -struct op { - u32 (* const fn)(int dd, int dn, int dm, u32 fpscr); - u32 flags; -}; diff --git a/trunk/arch/arm/vfp/vfpdouble.c b/trunk/arch/arm/vfp/vfpdouble.c index 4fc05ee0a2ef..add48e36c2dc 100644 --- a/trunk/arch/arm/vfp/vfpdouble.c +++ b/trunk/arch/arm/vfp/vfpdouble.c @@ -659,22 +659,22 @@ static u32 vfp_double_ftosiz(int dd, int unused, int dm, u32 fpscr) } -static struct op fops_ext[32] = { - [FEXT_TO_IDX(FEXT_FCPY)] = { vfp_double_fcpy, 0 }, - [FEXT_TO_IDX(FEXT_FABS)] = { vfp_double_fabs, 0 }, - [FEXT_TO_IDX(FEXT_FNEG)] = { vfp_double_fneg, 0 }, - [FEXT_TO_IDX(FEXT_FSQRT)] = { vfp_double_fsqrt, 0 }, - [FEXT_TO_IDX(FEXT_FCMP)] = { vfp_double_fcmp, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FCMPE)] = { vfp_double_fcmpe, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FCMPZ)] = { vfp_double_fcmpz, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FCMPEZ)] = { vfp_double_fcmpez, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FCVT)] = { vfp_double_fcvts, OP_SCALAR|OP_SD }, - [FEXT_TO_IDX(FEXT_FUITO)] = { vfp_double_fuito, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FSITO)] = { vfp_double_fsito, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FTOUI)] = { vfp_double_ftoui, OP_SCALAR|OP_SD }, - [FEXT_TO_IDX(FEXT_FTOUIZ)] = { vfp_double_ftouiz, OP_SCALAR|OP_SD }, - [FEXT_TO_IDX(FEXT_FTOSI)] = { vfp_double_ftosi, OP_SCALAR|OP_SD }, - [FEXT_TO_IDX(FEXT_FTOSIZ)] = { vfp_double_ftosiz, OP_SCALAR|OP_SD }, +static u32 (* const fop_extfns[32])(int dd, int unused, int dm, u32 fpscr) = { + [FEXT_TO_IDX(FEXT_FCPY)] = vfp_double_fcpy, + [FEXT_TO_IDX(FEXT_FABS)] = vfp_double_fabs, + [FEXT_TO_IDX(FEXT_FNEG)] = vfp_double_fneg, + [FEXT_TO_IDX(FEXT_FSQRT)] = vfp_double_fsqrt, + [FEXT_TO_IDX(FEXT_FCMP)] = vfp_double_fcmp, + [FEXT_TO_IDX(FEXT_FCMPE)] = vfp_double_fcmpe, + [FEXT_TO_IDX(FEXT_FCMPZ)] = vfp_double_fcmpz, + [FEXT_TO_IDX(FEXT_FCMPEZ)] = vfp_double_fcmpez, + [FEXT_TO_IDX(FEXT_FCVT)] = vfp_double_fcvts, + [FEXT_TO_IDX(FEXT_FUITO)] = vfp_double_fuito, + [FEXT_TO_IDX(FEXT_FSITO)] = vfp_double_fsito, + [FEXT_TO_IDX(FEXT_FTOUI)] = vfp_double_ftoui, + [FEXT_TO_IDX(FEXT_FTOUIZ)] = vfp_double_ftouiz, + [FEXT_TO_IDX(FEXT_FTOSI)] = vfp_double_ftosi, + [FEXT_TO_IDX(FEXT_FTOSIZ)] = vfp_double_ftosiz, }; @@ -1108,16 +1108,16 @@ static u32 vfp_double_fdiv(int dd, int dn, int dm, u32 fpscr) return FPSCR_IOC; } -static struct op fops[16] = { - [FOP_TO_IDX(FOP_FMAC)] = { vfp_double_fmac, 0 }, - [FOP_TO_IDX(FOP_FNMAC)] = { vfp_double_fnmac, 0 }, - [FOP_TO_IDX(FOP_FMSC)] = { vfp_double_fmsc, 0 }, - [FOP_TO_IDX(FOP_FNMSC)] = { vfp_double_fnmsc, 0 }, - [FOP_TO_IDX(FOP_FMUL)] = { vfp_double_fmul, 0 }, - [FOP_TO_IDX(FOP_FNMUL)] = { vfp_double_fnmul, 0 }, - [FOP_TO_IDX(FOP_FADD)] = { vfp_double_fadd, 0 }, - [FOP_TO_IDX(FOP_FSUB)] = { vfp_double_fsub, 0 }, - [FOP_TO_IDX(FOP_FDIV)] = { vfp_double_fdiv, 0 }, +static u32 (* const fop_fns[16])(int dd, int dn, int dm, u32 fpscr) = { + [FOP_TO_IDX(FOP_FMAC)] = vfp_double_fmac, + [FOP_TO_IDX(FOP_FNMAC)] = vfp_double_fnmac, + [FOP_TO_IDX(FOP_FMSC)] = vfp_double_fmsc, + [FOP_TO_IDX(FOP_FNMSC)] = vfp_double_fnmsc, + [FOP_TO_IDX(FOP_FMUL)] = vfp_double_fmul, + [FOP_TO_IDX(FOP_FNMUL)] = vfp_double_fnmul, + [FOP_TO_IDX(FOP_FADD)] = vfp_double_fadd, + [FOP_TO_IDX(FOP_FSUB)] = vfp_double_fsub, + [FOP_TO_IDX(FOP_FDIV)] = vfp_double_fdiv, }; #define FREG_BANK(x) ((x) & 0x0c) @@ -1131,60 +1131,69 @@ u32 vfp_double_cpdo(u32 inst, u32 fpscr) unsigned int dn = vfp_get_dn(inst); unsigned int dm = vfp_get_dm(inst); unsigned int vecitr, veclen, vecstride; - struct op *fop; + u32 (*fop)(int, int, s32, u32); + veclen = fpscr & FPSCR_LENGTH_MASK; vecstride = (1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK)) * 2; - fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)]; - /* * fcvtds takes an sN register number as destination, not dN. * It also always operates on scalars. */ - if (fop->flags & OP_SD) + if ((inst & FEXT_MASK) == FEXT_FCVT) { + veclen = 0; dest = vfp_get_sd(inst); - else + } else dest = vfp_get_dd(inst); /* * If destination bank is zero, vector length is always '1'. * ARM DDI0100F C5.1.3, C5.3.2. */ - if ((fop->flags & OP_SCALAR) || (FREG_BANK(dest) == 0)) + if (FREG_BANK(dest) == 0) veclen = 0; - else - veclen = fpscr & FPSCR_LENGTH_MASK; pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, (veclen >> FPSCR_LENGTH_BIT) + 1); - if (!fop->fn) + fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)]; + if (!fop) goto invalid; for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { u32 except; - char type; - type = fop->flags & OP_SD ? 's' : 'd'; - if (op == FOP_EXT) - pr_debug("VFP: itr%d (%c%u) = op[%u] (d%u)\n", + if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT) + pr_debug("VFP: itr%d (s%u) = op[%u] (d%u)\n", + vecitr >> FPSCR_LENGTH_BIT, + dest, dn, dm); + else if (op == FOP_EXT) + pr_debug("VFP: itr%d (d%u) = op[%u] (d%u)\n", vecitr >> FPSCR_LENGTH_BIT, - type, dest, dn, dm); + dest, dn, dm); else - pr_debug("VFP: itr%d (%c%u) = (d%u) op[%u] (d%u)\n", + pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n", vecitr >> FPSCR_LENGTH_BIT, - type, dest, dn, FOP_TO_IDX(op), dm); + dest, dn, FOP_TO_IDX(op), dm); - except = fop->fn(dest, dn, dm, fpscr); + except = fop(dest, dn, dm, fpscr); pr_debug("VFP: itr%d: exceptions=%08x\n", vecitr >> FPSCR_LENGTH_BIT, except); exceptions |= except; + /* + * This ensures that comparisons only operate on scalars; + * comparisons always return with one FPSCR status bit set. + */ + if (except & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) + break; + /* * CHECK: It appears to be undefined whether we stop when * we encounter an exception. We continue. */ + dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 6); dn = FREG_BANK(dn) + ((FREG_IDX(dn) + vecstride) & 6); if (FREG_BANK(dm) != 0) diff --git a/trunk/arch/arm/vfp/vfpinstr.h b/trunk/arch/arm/vfp/vfpinstr.h index 7f343a4beca0..6c819aeae006 100644 --- a/trunk/arch/arm/vfp/vfpinstr.h +++ b/trunk/arch/arm/vfp/vfpinstr.h @@ -73,14 +73,14 @@ #define fmrx(_vfp_) ({ \ u32 __v; \ - asm("mrc p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_ \ - : "=r" (__v) : : "cc"); \ + asm("mrc%? p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_ \ + : "=r" (__v)); \ __v; \ }) #define fmxr(_vfp_,_var_) \ - asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \ - : : "r" (_var_) : "cc") + asm("mcr%? p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \ + : : "r" (_var_)) u32 vfp_single_cpdo(u32 inst, u32 fpscr); u32 vfp_single_cprt(u32 inst, u32 fpscr, struct pt_regs *regs); diff --git a/trunk/arch/arm/vfp/vfpmodule.c b/trunk/arch/arm/vfp/vfpmodule.c index dedbb449632e..4178f6cc3d37 100644 --- a/trunk/arch/arm/vfp/vfpmodule.c +++ b/trunk/arch/arm/vfp/vfpmodule.c @@ -40,19 +40,10 @@ unsigned int VFP_arch; static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) { struct thread_info *thread = v; - union vfp_state *vfp; + union vfp_state *vfp = &thread->vfpstate; - if (likely(cmd == THREAD_NOTIFY_SWITCH)) { - /* - * Always disable VFP so we can lazily save/restore the - * old state. - */ - fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); - return NOTIFY_DONE; - } - - vfp = &thread->vfpstate; - if (cmd == THREAD_NOTIFY_FLUSH) { + switch (cmd) { + case THREAD_NOTIFY_FLUSH: /* * Per-thread VFP initialisation. */ @@ -65,11 +56,28 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v) * Disable VFP to ensure we initialise it first. */ fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); - } - /* flush and release case: Per-thread VFP cleanup. */ - if (last_VFP_context == vfp) - last_VFP_context = NULL; + /* + * FALLTHROUGH: Ensure we don't try to overwrite our newly + * initialised state information on the first fault. + */ + + case THREAD_NOTIFY_RELEASE: + /* + * Per-thread VFP cleanup. + */ + if (last_VFP_context == vfp) + last_VFP_context = NULL; + break; + + case THREAD_NOTIFY_SWITCH: + /* + * Always disable VFP so we can lazily save/restore the + * old state. + */ + fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE); + break; + } return NOTIFY_DONE; } diff --git a/trunk/arch/arm/vfp/vfpsingle.c b/trunk/arch/arm/vfp/vfpsingle.c index ab5e9503bae5..8f6c179cafbe 100644 --- a/trunk/arch/arm/vfp/vfpsingle.c +++ b/trunk/arch/arm/vfp/vfpsingle.c @@ -702,22 +702,22 @@ static u32 vfp_single_ftosiz(int sd, int unused, s32 m, u32 fpscr) return vfp_single_ftosi(sd, unused, m, FPSCR_ROUND_TOZERO); } -static struct op fops_ext[32] = { - [FEXT_TO_IDX(FEXT_FCPY)] = { vfp_single_fcpy, 0 }, - [FEXT_TO_IDX(FEXT_FABS)] = { vfp_single_fabs, 0 }, - [FEXT_TO_IDX(FEXT_FNEG)] = { vfp_single_fneg, 0 }, - [FEXT_TO_IDX(FEXT_FSQRT)] = { vfp_single_fsqrt, 0 }, - [FEXT_TO_IDX(FEXT_FCMP)] = { vfp_single_fcmp, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FCMPE)] = { vfp_single_fcmpe, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FCMPZ)] = { vfp_single_fcmpz, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FCMPEZ)] = { vfp_single_fcmpez, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FCVT)] = { vfp_single_fcvtd, OP_SCALAR|OP_DD }, - [FEXT_TO_IDX(FEXT_FUITO)] = { vfp_single_fuito, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FSITO)] = { vfp_single_fsito, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FTOUI)] = { vfp_single_ftoui, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FTOUIZ)] = { vfp_single_ftouiz, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FTOSI)] = { vfp_single_ftosi, OP_SCALAR }, - [FEXT_TO_IDX(FEXT_FTOSIZ)] = { vfp_single_ftosiz, OP_SCALAR }, +static u32 (* const fop_extfns[32])(int sd, int unused, s32 m, u32 fpscr) = { + [FEXT_TO_IDX(FEXT_FCPY)] = vfp_single_fcpy, + [FEXT_TO_IDX(FEXT_FABS)] = vfp_single_fabs, + [FEXT_TO_IDX(FEXT_FNEG)] = vfp_single_fneg, + [FEXT_TO_IDX(FEXT_FSQRT)] = vfp_single_fsqrt, + [FEXT_TO_IDX(FEXT_FCMP)] = vfp_single_fcmp, + [FEXT_TO_IDX(FEXT_FCMPE)] = vfp_single_fcmpe, + [FEXT_TO_IDX(FEXT_FCMPZ)] = vfp_single_fcmpz, + [FEXT_TO_IDX(FEXT_FCMPEZ)] = vfp_single_fcmpez, + [FEXT_TO_IDX(FEXT_FCVT)] = vfp_single_fcvtd, + [FEXT_TO_IDX(FEXT_FUITO)] = vfp_single_fuito, + [FEXT_TO_IDX(FEXT_FSITO)] = vfp_single_fsito, + [FEXT_TO_IDX(FEXT_FTOUI)] = vfp_single_ftoui, + [FEXT_TO_IDX(FEXT_FTOUIZ)] = vfp_single_ftouiz, + [FEXT_TO_IDX(FEXT_FTOSI)] = vfp_single_ftosi, + [FEXT_TO_IDX(FEXT_FTOSIZ)] = vfp_single_ftosiz, }; @@ -1151,16 +1151,16 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr) return FPSCR_IOC; } -static struct op fops[16] = { - [FOP_TO_IDX(FOP_FMAC)] = { vfp_single_fmac, 0 }, - [FOP_TO_IDX(FOP_FNMAC)] = { vfp_single_fnmac, 0 }, - [FOP_TO_IDX(FOP_FMSC)] = { vfp_single_fmsc, 0 }, - [FOP_TO_IDX(FOP_FNMSC)] = { vfp_single_fnmsc, 0 }, - [FOP_TO_IDX(FOP_FMUL)] = { vfp_single_fmul, 0 }, - [FOP_TO_IDX(FOP_FNMUL)] = { vfp_single_fnmul, 0 }, - [FOP_TO_IDX(FOP_FADD)] = { vfp_single_fadd, 0 }, - [FOP_TO_IDX(FOP_FSUB)] = { vfp_single_fsub, 0 }, - [FOP_TO_IDX(FOP_FDIV)] = { vfp_single_fdiv, 0 }, +static u32 (* const fop_fns[16])(int sd, int sn, s32 m, u32 fpscr) = { + [FOP_TO_IDX(FOP_FMAC)] = vfp_single_fmac, + [FOP_TO_IDX(FOP_FNMAC)] = vfp_single_fnmac, + [FOP_TO_IDX(FOP_FMSC)] = vfp_single_fmsc, + [FOP_TO_IDX(FOP_FNMSC)] = vfp_single_fnmsc, + [FOP_TO_IDX(FOP_FMUL)] = vfp_single_fmul, + [FOP_TO_IDX(FOP_FNMUL)] = vfp_single_fnmul, + [FOP_TO_IDX(FOP_FADD)] = vfp_single_fadd, + [FOP_TO_IDX(FOP_FSUB)] = vfp_single_fsub, + [FOP_TO_IDX(FOP_FDIV)] = vfp_single_fdiv, }; #define FREG_BANK(x) ((x) & 0x18) @@ -1174,63 +1174,70 @@ u32 vfp_single_cpdo(u32 inst, u32 fpscr) unsigned int sn = vfp_get_sn(inst); unsigned int sm = vfp_get_sm(inst); unsigned int vecitr, veclen, vecstride; - struct op *fop; + u32 (*fop)(int, int, s32, u32); + veclen = fpscr & FPSCR_LENGTH_MASK; vecstride = 1 + ((fpscr & FPSCR_STRIDE_MASK) == FPSCR_STRIDE_MASK); - fop = (op == FOP_EXT) ? &fops_ext[FEXT_TO_IDX(inst)] : &fops[FOP_TO_IDX(op)]; - /* * fcvtsd takes a dN register number as destination, not sN. * Technically, if bit 0 of dd is set, this is an invalid * instruction. However, we ignore this for efficiency. * It also only operates on scalars. */ - if (fop->flags & OP_DD) + if ((inst & FEXT_MASK) == FEXT_FCVT) { + veclen = 0; dest = vfp_get_dd(inst); - else + } else dest = vfp_get_sd(inst); /* * If destination bank is zero, vector length is always '1'. * ARM DDI0100F C5.1.3, C5.3.2. */ - if ((fop->flags & OP_SCALAR) || FREG_BANK(dest) == 0) + if (FREG_BANK(dest) == 0) veclen = 0; - else - veclen = fpscr & FPSCR_LENGTH_MASK; pr_debug("VFP: vecstride=%u veclen=%u\n", vecstride, (veclen >> FPSCR_LENGTH_BIT) + 1); - if (!fop->fn) + fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)]; + if (!fop) goto invalid; for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { s32 m = vfp_get_float(sm); u32 except; - char type; - type = fop->flags & OP_DD ? 'd' : 's'; - if (op == FOP_EXT) - pr_debug("VFP: itr%d (%c%u) = op[%u] (s%u=%08x)\n", - vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, - sm, m); + if (op == FOP_EXT && (inst & FEXT_MASK) == FEXT_FCVT) + pr_debug("VFP: itr%d (d%u) = op[%u] (s%u=%08x)\n", + vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m); + else if (op == FOP_EXT) + pr_debug("VFP: itr%d (s%u) = op[%u] (s%u=%08x)\n", + vecitr >> FPSCR_LENGTH_BIT, dest, sn, sm, m); else - pr_debug("VFP: itr%d (%c%u) = (s%u) op[%u] (s%u=%08x)\n", - vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, + pr_debug("VFP: itr%d (s%u) = (s%u) op[%u] (s%u=%08x)\n", + vecitr >> FPSCR_LENGTH_BIT, dest, sn, FOP_TO_IDX(op), sm, m); - except = fop->fn(dest, sn, m, fpscr); + except = fop(dest, sn, m, fpscr); pr_debug("VFP: itr%d: exceptions=%08x\n", vecitr >> FPSCR_LENGTH_BIT, except); exceptions |= except; + /* + * This ensures that comparisons only operate on scalars; + * comparisons always return with one FPSCR status bit set. + */ + if (except & (FPSCR_N|FPSCR_Z|FPSCR_C|FPSCR_V)) + break; + /* * CHECK: It appears to be undefined whether we stop when * we encounter an exception. We continue. */ + dest = FREG_BANK(dest) + ((FREG_IDX(dest) + vecstride) & 7); sn = FREG_BANK(sn) + ((FREG_IDX(sn) + vecstride) & 7); if (FREG_BANK(sm) != 0) diff --git a/trunk/arch/arm26/kernel/setup.c b/trunk/arch/arm26/kernel/setup.c index 466ddb54b44f..e7eb070f794f 100644 --- a/trunk/arch/arm26/kernel/setup.c +++ b/trunk/arch/arm26/kernel/setup.c @@ -143,7 +143,7 @@ static void __init setup_processor(void) dump_cpu_info(); - sprintf(init_utsname()->machine, "%s", list->arch_name); + sprintf(system_utsname.machine, "%s", list->arch_name); sprintf(elf_platform, "%s", list->elf_name); elf_hwcap = list->elf_hwcap; diff --git a/trunk/arch/arm26/kernel/sys_arm.c b/trunk/arch/arm26/kernel/sys_arm.c index dc05aba58baf..85457897b8a9 100644 --- a/trunk/arch/arm26/kernel/sys_arm.c +++ b/trunk/arch/arm26/kernel/sys_arm.c @@ -283,7 +283,7 @@ asmlinkage int sys_execve(char *filenamei, char **argv, char **envp, struct pt_r } /* FIXME - see if this is correct for arm26 */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) +long execve(const char *filename, char **argv, char **envp) { struct pt_regs regs; int ret; @@ -320,4 +320,4 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[]) return ret; } -EXPORT_SYMBOL(kernel_execve); +EXPORT_SYMBOL(execve); diff --git a/trunk/arch/arm26/kernel/time.c b/trunk/arch/arm26/kernel/time.c index 1206469b2b86..db63d75d0715 100644 --- a/trunk/arch/arm26/kernel/time.c +++ b/trunk/arch/arm26/kernel/time.c @@ -33,6 +33,8 @@ #include #include +extern unsigned long wall_jiffies; + /* this needs a better home */ DEFINE_SPINLOCK(rtc_lock); @@ -134,11 +136,16 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; unsigned long seq; - unsigned long usec, sec; + unsigned long usec, sec, lost; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = gettimeoffset(); + + lost = jiffies - wall_jiffies; + if (lost) + usec += lost * USECS_PER_JIFFY; + sec = xtime.tv_sec; usec += xtime.tv_nsec / 1000; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); @@ -167,7 +174,8 @@ int do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * done, and then undo it! */ - tv->tv_nsec -= 1000 * gettimeoffset(); + tv->tv_nsec -= 1000 * (gettimeoffset() + + (jiffies - wall_jiffies) * USECS_PER_JIFFY); while (tv->tv_nsec < 0) { tv->tv_nsec += NSEC_PER_SEC; @@ -186,7 +194,7 @@ EXPORT_SYMBOL(do_settimeofday); static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif diff --git a/trunk/arch/arm26/mm/fault.c b/trunk/arch/arm26/mm/fault.c index a1f6d8a9cc32..761938b56679 100644 --- a/trunk/arch/arm26/mm/fault.c +++ b/trunk/arch/arm26/mm/fault.c @@ -155,7 +155,7 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, */ good_area: if (READ_FAULT(fsr)) /* read? */ - mask = VM_READ|VM_EXEC|VM_WRITE; + mask = VM_READ|VM_EXEC; else mask = VM_WRITE; @@ -185,7 +185,7 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, } fault = -3; /* out of memory */ - if (!is_init(tsk)) + if (tsk->pid != 1) goto out; /* diff --git a/trunk/arch/avr32/kernel/sys_avr32.c b/trunk/arch/avr32/kernel/sys_avr32.c index 8deb6003ee62..6ec5693da448 100644 --- a/trunk/arch/avr32/kernel/sys_avr32.c +++ b/trunk/arch/avr32/kernel/sys_avr32.c @@ -49,17 +49,3 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, fput(file); return error; } - -int kernel_execve(const char *file, char **argv, char **envp) -{ - register long scno asm("r8") = __NR_execve; - register long sc1 asm("r12") = (long)file; - register long sc2 asm("r11") = (long)argv; - register long sc3 asm("r10") = (long)envp; - - asm volatile("scall" - : "=r"(sc1) - : "r"(scno), "0"(sc1), "r"(sc2), "r"(sc3) - : "cc", "memory"); - return sc1; -} diff --git a/trunk/arch/avr32/kernel/time.c b/trunk/arch/avr32/kernel/time.c index 3e56b9f4358a..b0e6b5855a38 100644 --- a/trunk/arch/avr32/kernel/time.c +++ b/trunk/arch/avr32/kernel/time.c @@ -148,7 +148,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * Call the generic timer interrupt handler */ write_seqlock(&xtime_lock); - do_timer(1); + do_timer(regs); write_sequnlock(&xtime_lock); /* diff --git a/trunk/arch/avr32/mm/ioremap.c b/trunk/arch/avr32/mm/ioremap.c index 8cfec65e37f7..536021877df6 100644 --- a/trunk/arch/avr32/mm/ioremap.c +++ b/trunk/arch/avr32/mm/ioremap.c @@ -7,11 +7,119 @@ */ #include #include -#include +#include #include +#include +#include #include +static inline int remap_area_pte(pte_t *pte, unsigned long address, + unsigned long end, unsigned long phys_addr, + pgprot_t prot) +{ + unsigned long pfn; + + pfn = phys_addr >> PAGE_SHIFT; + do { + WARN_ON(!pte_none(*pte)); + + set_pte(pte, pfn_pte(pfn, prot)); + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); + + return 0; +} + +static inline int remap_area_pmd(pmd_t *pmd, unsigned long address, + unsigned long end, unsigned long phys_addr, + pgprot_t prot) +{ + unsigned long next; + + phys_addr -= address; + + do { + pte_t *pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + + next = (address + PMD_SIZE) & PMD_MASK; + if (remap_area_pte(pte, address, next, + address + phys_addr, prot)) + return -ENOMEM; + + address = next; + pmd++; + } while (address && (address < end)); + return 0; +} + +static int remap_area_pud(pud_t *pud, unsigned long address, + unsigned long end, unsigned long phys_addr, + pgprot_t prot) +{ + unsigned long next; + + phys_addr -= address; + + do { + pmd_t *pmd = pmd_alloc(&init_mm, pud, address); + if (!pmd) + return -ENOMEM; + next = (address + PUD_SIZE) & PUD_MASK; + if (remap_area_pmd(pmd, address, next, + phys_addr + address, prot)) + return -ENOMEM; + + address = next; + pud++; + } while (address && address < end); + + return 0; +} + +static int remap_area_pages(unsigned long address, unsigned long phys_addr, + size_t size, pgprot_t prot) +{ + unsigned long end = address + size; + unsigned long next; + pgd_t *pgd; + int err = 0; + + phys_addr -= address; + + pgd = pgd_offset_k(address); + flush_cache_all(); + BUG_ON(address >= end); + + spin_lock(&init_mm.page_table_lock); + do { + pud_t *pud = pud_alloc(&init_mm, pgd, address); + + err = -ENOMEM; + if (!pud) + break; + + next = (address + PGDIR_SIZE) & PGDIR_MASK; + if (next < address || next > end) + next = end; + err = remap_area_pud(pud, address, next, + phys_addr + address, prot); + if (err) + break; + + address = next; + pgd++; + } while (address && (address < end)); + + spin_unlock(&init_mm.page_table_lock); + flush_tlb_all(); + return err; +} + /* * Re-map an arbitrary physical address space into the kernel virtual * address space. Needed when the kernel wants to access physical @@ -20,7 +128,7 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size, unsigned long flags) { - unsigned long addr; + void *addr; struct vm_struct *area; unsigned long offset, last_addr; pgprot_t prot; @@ -51,7 +159,7 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size, phys_addr &= PAGE_MASK; size = PAGE_ALIGN(last_addr + 1) - phys_addr; - prot = __pgprot(_PAGE_PRESENT | _PAGE_GLOBAL | _PAGE_RW | _PAGE_DIRTY + prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_TYPE_SMALL | flags); /* @@ -61,9 +169,9 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size, if (!area) return NULL; area->phys_addr = phys_addr; - addr = (unsigned long )area->addr; - if (ioremap_page_range(addr, addr + size, phys_addr, prot)) { - vunmap((void *)addr); + addr = area->addr; + if (remap_area_pages((unsigned long)addr, phys_addr, size, prot)) { + vunmap(addr); return NULL; } diff --git a/trunk/arch/avr32/mm/tlb.c b/trunk/arch/avr32/mm/tlb.c index 7b073052203d..5d0523bbe298 100644 --- a/trunk/arch/avr32/mm/tlb.c +++ b/trunk/arch/avr32/mm/tlb.c @@ -15,8 +15,7 @@ void show_dtlb_entry(unsigned int index) { - unsigned int tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save; - unsigned long flags; + unsigned int tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save, flags; local_irq_save(flags); mmucr_save = sysreg_read(MMUCR); @@ -306,8 +305,7 @@ static void tlb_stop(struct seq_file *tlb, void *v) static int tlb_show(struct seq_file *tlb, void *v) { - unsigned int tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save; - unsigned long flags; + unsigned int tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save, flags; unsigned long *index = v; if (*index == 0) diff --git a/trunk/arch/cris/arch-v10/kernel/time.c b/trunk/arch/cris/arch-v10/kernel/time.c index ebacf1457d91..9c22b76e129a 100644 --- a/trunk/arch/cris/arch-v10/kernel/time.c +++ b/trunk/arch/cris/arch-v10/kernel/time.c @@ -227,7 +227,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* call the real timer interrupt handler */ - do_timer(1); + do_timer(regs); cris_do_profile(regs); /* Save profiling information */ diff --git a/trunk/arch/cris/arch-v32/kernel/smp.c b/trunk/arch/cris/arch-v32/kernel/smp.c index 2d0023f2d49b..464ecaec3bc0 100644 --- a/trunk/arch/cris/arch-v32/kernel/smp.c +++ b/trunk/arch/cris/arch-v32/kernel/smp.c @@ -28,7 +28,6 @@ spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED}; /* CPU masks */ cpumask_t cpu_online_map = CPU_MASK_NONE; -EXPORT_SYMBOL(cpu_online_map); cpumask_t phys_cpu_present_map = CPU_MASK_NONE; EXPORT_SYMBOL(phys_cpu_present_map); diff --git a/trunk/arch/cris/arch-v32/kernel/time.c b/trunk/arch/cris/arch-v32/kernel/time.c index be0a01657d4f..50f3f93293d6 100644 --- a/trunk/arch/cris/arch-v32/kernel/time.c +++ b/trunk/arch/cris/arch-v32/kernel/time.c @@ -219,7 +219,7 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; /* call the real timer interrupt handler */ - do_timer(1); + do_timer(regs); /* * If we have an externally synchronized Linux clock, then update diff --git a/trunk/arch/cris/kernel/setup.c b/trunk/arch/cris/kernel/setup.c index ca8b45a0fe2e..7af3d5d43e43 100644 --- a/trunk/arch/cris/kernel/setup.c +++ b/trunk/arch/cris/kernel/setup.c @@ -160,7 +160,7 @@ setup_arch(char **cmdline_p) show_etrax_copyright(); /* Setup utsname */ - strcpy(init_utsname()->machine, cris_machine_name); + strcpy(system_utsname.machine, cris_machine_name); } static void *c_start(struct seq_file *m, loff_t *pos) diff --git a/trunk/arch/cris/kernel/time.c b/trunk/arch/cris/kernel/time.c index 0f9213cbd48e..66ba8898db07 100644 --- a/trunk/arch/cris/kernel/time.c +++ b/trunk/arch/cris/kernel/time.c @@ -37,6 +37,7 @@ int have_rtc; /* used to remember if we have an RTC or not */; #define TICK_SIZE tick +extern unsigned long wall_jiffies; extern unsigned long loops_per_jiffy; /* init/main.c */ unsigned long loops_per_usec; @@ -57,6 +58,11 @@ void do_gettimeofday(struct timeval *tv) local_irq_save(flags); local_irq_disable(); usec = do_gettimeoffset(); + { + unsigned long lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + } /* * If time_adjust is negative then NTP is slowing the clock @@ -97,6 +103,7 @@ int do_settimeofday(struct timespec *tv) * made, and then undo it! */ nsec -= do_gettimeoffset() * NSEC_PER_USEC; + nsec -= (jiffies - wall_jiffies) * TICK_NSEC; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); diff --git a/trunk/arch/cris/mm/ioremap.c b/trunk/arch/cris/mm/ioremap.c index 8b0b9348b574..1780df3ed9e5 100644 --- a/trunk/arch/cris/mm/ioremap.c +++ b/trunk/arch/cris/mm/ioremap.c @@ -10,10 +10,93 @@ */ #include -#include +#include #include +#include +#include #include +static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long phys_addr, pgprot_t prot) +{ + unsigned long end; + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + do { + if (!pte_none(*pte)) { + printk("remap_area_pte: page already exists\n"); + BUG(); + } + set_pte(pte, mk_pte_phys(phys_addr, prot)); + address += PAGE_SIZE; + phys_addr += PAGE_SIZE; + pte++; + } while (address && (address < end)); +} + +static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, pgprot_t prot) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pte_t * pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, address + phys_addr, prot); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +static int remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, pgprot_t prot) +{ + int error; + pgd_t * dir; + unsigned long end = address + size; + + phys_addr -= address; + dir = pgd_offset(&init_mm, address); + flush_cache_all(); + if (address >= end) + BUG(); + do { + pud_t *pud; + pmd_t *pmd; + + error = -ENOMEM; + pud = pud_alloc(&init_mm, dir, address); + if (!pud) + break; + pmd = pmd_alloc(&init_mm, pud, address); + + if (!pmd) + break; + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, prot)) + break; + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + flush_tlb_all(); + return error; +} + /* * Generic mapping function (not visible outside): */ @@ -52,8 +135,7 @@ void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgpro if (!area) return NULL; addr = (void __iomem *)area->addr; - if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, - phys_addr, prot)) { + if (remap_area_pages((unsigned long) addr, phys_addr, size, prot)) { vfree((void __force *)addr); return NULL; } diff --git a/trunk/arch/frv/kernel/Makefile b/trunk/arch/frv/kernel/Makefile index e8f73ed28b52..32db3499c461 100644 --- a/trunk/arch/frv/kernel/Makefile +++ b/trunk/arch/frv/kernel/Makefile @@ -8,7 +8,7 @@ heads-$(CONFIG_MMU) := head-mmu-fr451.o extra-y:= head.o init_task.o vmlinux.lds obj-y := $(heads-y) entry.o entry-table.o break.o switch_to.o kernel_thread.o \ - kernel_execve.o process.o traps.o ptrace.o signal.o dma.o \ + process.o traps.o ptrace.o signal.o dma.o \ sys_frv.o time.o semaphore.o setup.o frv_ksyms.o \ debug-stub.o irq.o sleep.o uaccess.o diff --git a/trunk/arch/frv/kernel/kernel_execve.S b/trunk/arch/frv/kernel/kernel_execve.S deleted file mode 100644 index 9b074a16a052..000000000000 --- a/trunk/arch/frv/kernel/kernel_execve.S +++ /dev/null @@ -1,33 +0,0 @@ -/* in-kernel program execution - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * 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. - */ - -#include -#include - -############################################################################### -# -# Do a system call from kernel instead of calling sys_execve so we end up with -# proper pt_regs. -# -# int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -# -# On entry: GR8/GR9/GR10: arguments to function -# On return: GR8: syscall return. -# -############################################################################### - .globl kernel_execve - .type kernel_execve,@function -kernel_execve: - setlos __NR_execve,gr7 - tira gr0,#0 - bralr - - .size kernel_execve,.-kernel_execve diff --git a/trunk/arch/frv/kernel/time.c b/trunk/arch/frv/kernel/time.c index 7e55884135ed..3d0284bccb94 100644 --- a/trunk/arch/frv/kernel/time.c +++ b/trunk/arch/frv/kernel/time.c @@ -70,7 +70,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs) */ write_seqlock(&xtime_lock); - do_timer(1); + do_timer(regs); update_process_times(user_mode(regs)); profile_tick(CPU_PROFILING, regs); diff --git a/trunk/arch/h8300/kernel/sys_h8300.c b/trunk/arch/h8300/kernel/sys_h8300.c index 302a2dfe634a..0f61b7ad69ab 100644 --- a/trunk/arch/h8300/kernel/sys_h8300.c +++ b/trunk/arch/h8300/kernel/sys_h8300.c @@ -25,7 +25,6 @@ #include #include #include -#include /* * sys_pipe() is the normal C calling standard for creating @@ -281,26 +280,3 @@ asmlinkage void syscall_print(void *dummy,...) ((regs->pc)&0xffffff)-2,regs->orig_er0,regs->er1,regs->er2,regs->er3,regs->er0); } #endif - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register long res __asm__("er0"); - register const char * _a __asm__("er1") = filename; - register void *_b __asm__("er2") = argv; - register void *_c __asm__("er3") = envp; - __asm__ __volatile__ ("mov.l %1,er0\n\t" - "trapa #0\n\t" - : "=r" (res) - : "g" (__NR_execve), - "g" (_a), - "g" (_b), - "g" (_c) - : "cc", "memory"); - return res; -} - - diff --git a/trunk/arch/h8300/kernel/time.c b/trunk/arch/h8300/kernel/time.c index e569d17b4ae6..688a5100604c 100644 --- a/trunk/arch/h8300/kernel/time.c +++ b/trunk/arch/h8300/kernel/time.c @@ -41,7 +41,7 @@ static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs) /* may need to kick the hardware timer */ platform_timer_eoi(); - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index af219e51734f..6189b0c28d6f 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -166,6 +166,7 @@ config X86_VISWS config X86_GENERICARCH bool "Generic architecture (Summit, bigsmp, ES7000, default)" + depends on SMP help This option compiles in the Summit, bigsmp, ES7000, default subarchitectures. It is intended for a generic binary kernel. @@ -262,7 +263,7 @@ source "kernel/Kconfig.preempt" config X86_UP_APIC bool "Local APIC support on uniprocessors" - depends on !SMP && !(X86_VISWS || X86_VOYAGER || X86_GENERICARCH) + depends on !SMP && !(X86_VISWS || X86_VOYAGER) help A local APIC (Advanced Programmable Interrupt Controller) is an integrated interrupt controller in the CPU. If you have a single-CPU @@ -287,12 +288,12 @@ config X86_UP_IOAPIC config X86_LOCAL_APIC bool - depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) || X86_GENERICARCH + depends on X86_UP_APIC || ((X86_VISWS || SMP) && !X86_VOYAGER) default y config X86_IO_APIC bool - depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) || X86_GENERICARCH + depends on X86_UP_IOAPIC || (SMP && !(X86_VISWS || X86_VOYAGER)) default y config X86_VISWS_APIC @@ -401,7 +402,6 @@ config X86_REBOOTFIXUPS config MICROCODE tristate "/dev/cpu/microcode - Intel IA32 CPU microcode support" - select FW_LOADER ---help--- If you say Y here and also to "/dev file system support" in the 'File systems' section, you will be able to update the microcode on @@ -417,11 +417,6 @@ config MICROCODE To compile this driver as a module, choose M here: the module will be called microcode. -config MICROCODE_OLD_INTERFACE - bool - depends on MICROCODE - default y - config X86_MSR tristate "/dev/cpu/*/msr - Model-specific register support" help @@ -604,11 +599,13 @@ config ARCH_SELECT_MEMORY_MODEL def_bool y depends on ARCH_SPARSEMEM_ENABLE -config ARCH_POPULATES_NODE_MAP - def_bool y - source "mm/Kconfig" +config HAVE_ARCH_EARLY_PFN_TO_NID + bool + default y + depends on NUMA + config HIGHPTE bool "Allocate 3rd-level pagetables from highmem" depends on HIGHMEM4G || HIGHMEM64G @@ -744,7 +741,8 @@ config SECCOMP source kernel/Kconfig.hz config KEXEC - bool "kexec system call" + bool "kexec system call (EXPERIMENTAL)" + depends on EXPERIMENTAL help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot @@ -765,13 +763,6 @@ config CRASH_DUMP depends on HIGHMEM help Generate crash dump after being started by kexec. - This should be normally only set in special crash dump kernels - which are loaded in the main kernel with kexec-tools into - a specially reserved region and then later executed after - a crash by kdump/kexec. The crash dump kernel must be compiled - to a memory address not used by the main kernel or BIOS using - PHYSICAL_START. - For more details see Documentation/kdump/kdump.txt config PHYSICAL_START hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) @@ -1142,7 +1133,7 @@ source "arch/i386/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on KALLSYMS && EXPERIMENTAL && MODULES + depends on EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/trunk/arch/i386/Makefile b/trunk/arch/i386/Makefile index 7cc0b189b82b..3e4adb1e2244 100644 --- a/trunk/arch/i386/Makefile +++ b/trunk/arch/i386/Makefile @@ -46,14 +46,6 @@ cflags-y += -ffreestanding # a lot more stack due to the lack of sharing of stacklots: CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;) -# do binutils support CFI? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) - -# is .cfi_signal_frame supported too? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) - CFLAGS += $(cflags-y) # Default subarch .c files diff --git a/trunk/arch/i386/boot/edd.S b/trunk/arch/i386/boot/edd.S index 34321368011a..4b84ea216f2b 100644 --- a/trunk/arch/i386/boot/edd.S +++ b/trunk/arch/i386/boot/edd.S @@ -15,95 +15,42 @@ #include #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) - -# It is assumed that %ds == INITSEG here - movb $0, (EDD_MBR_SIG_NR_BUF) movb $0, (EDDNR) -# Check the command line for options: +# Check the command line for two options: # edd=of disables EDD completely (edd=off) # edd=sk skips the MBR test (edd=skipmbr) -# edd=on re-enables EDD (edd=on) - pushl %esi - movw $edd_mbr_sig_start, %di # Default to edd=on - - movl %cs:(cmd_line_ptr), %esi - andl %esi, %esi - jz old_cl # Old boot protocol? - -# Convert to a real-mode pointer in fs:si - movl %esi, %eax - shrl $4, %eax - movw %ax, %fs - andw $0xf, %si - jmp have_cl_pointer - -# Old-style boot protocol? -old_cl: - push %ds # aka INITSEG - pop %fs - - cmpw $0xa33f, (0x20) - jne done_cl # No command line at all? - movw (0x22), %si # Pointer relative to INITSEG - -# fs:si has the pointer to the command line now -have_cl_pointer: - -# Loop through kernel command line one byte at a time. Just in -# case the loader is buggy and failed to null-terminate the command line -# terminate if we get close enough to the end of the segment that we -# cannot fit "edd=XX"... -cl_atspace: - cmpw $-5, %si # Watch for segment wraparound - jae done_cl - movl %fs:(%si), %eax - andb %al, %al # End of line? + cmpl $0, %cs:cmd_line_ptr jz done_cl - cmpl $EDD_CL_EQUALS, %eax + movl %cs:(cmd_line_ptr), %esi +# ds:esi has the pointer to the command line now + movl $(COMMAND_LINE_SIZE-7), %ecx +# loop through kernel command line one byte at a time +cl_loop: + cmpl $EDD_CL_EQUALS, (%si) jz found_edd_equals - cmpb $0x20, %al # <= space consider whitespace - ja cl_skipword - incw %si - jmp cl_atspace - -cl_skipword: - cmpw $-5, %si # Watch for segment wraparound - jae done_cl - movb %fs:(%si), %al # End of string? - andb %al, %al - jz done_cl - cmpb $0x20, %al - jbe cl_atspace - incw %si - jmp cl_skipword - + incl %esi + loop cl_loop + jmp done_cl found_edd_equals: # only looking at first two characters after equals -# late overrides early on the command line, so keep going after finding something - movw %fs:4(%si), %ax - cmpw $EDD_CL_OFF, %ax # edd=of - je do_edd_off - cmpw $EDD_CL_SKIP, %ax # edd=sk - je do_edd_skipmbr - cmpw $EDD_CL_ON, %ax # edd=on - je do_edd_on - jmp cl_skipword + addl $4, %esi + cmpw $EDD_CL_OFF, (%si) # edd=of + jz do_edd_off + cmpw $EDD_CL_SKIP, (%si) # edd=sk + jz do_edd_skipmbr + jmp done_cl do_edd_skipmbr: - movw $edd_start, %di - jmp cl_skipword + popl %esi + jmp edd_start do_edd_off: - movw $edd_done, %di - jmp cl_skipword -do_edd_on: - movw $edd_mbr_sig_start, %di - jmp cl_skipword - + popl %esi + jmp edd_done done_cl: popl %esi - jmpw *%di + # Read the first sector of each BIOS disk device and store the 4-byte signature edd_mbr_sig_start: diff --git a/trunk/arch/i386/boot/setup.S b/trunk/arch/i386/boot/setup.S index 3aec4538a113..d2b684cd620a 100644 --- a/trunk/arch/i386/boot/setup.S +++ b/trunk/arch/i386/boot/setup.S @@ -494,12 +494,12 @@ no_voyager: movw %cs, %ax # aka SETUPSEG subw $DELTA_INITSEG, %ax # aka INITSEG movw %ax, %ds - movb $0, (0x1ff) # default is no pointing device + movw $0, (0x1ff) # default is no pointing device int $0x11 # int 0x11: equipment list testb $0x04, %al # check if mouse installed jz no_psmouse - movb $0xAA, (0x1ff) # device present + movw $0xAA, (0x1ff) # device present no_psmouse: #if defined(CONFIG_X86_SPEEDSTEP_SMI) || defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE) diff --git a/trunk/arch/i386/boot/video.S b/trunk/arch/i386/boot/video.S index 2c5b5cc55f79..8c2a6faeeae5 100644 --- a/trunk/arch/i386/boot/video.S +++ b/trunk/arch/i386/boot/video.S @@ -11,6 +11,8 @@ * */ +#include /* for CONFIG_VIDEO_* */ + /* Enable autodetection of SVGA adapters and modes. */ #undef CONFIG_VIDEO_SVGA diff --git a/trunk/arch/i386/defconfig b/trunk/arch/i386/defconfig index ee2d79bd8af7..89ebb7a316ab 100644 --- a/trunk/arch/i386/defconfig +++ b/trunk/arch/i386/defconfig @@ -1,51 +1,41 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-git7 -# Wed Sep 27 21:53:10 2006 # CONFIG_X86_32=y -CONFIG_GENERIC_TIME=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_SEMAPHORE_SLEEPERS=y CONFIG_X86=y CONFIG_MMU=y CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_IOMAP=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_DMI=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options # CONFIG_EXPERIMENTAL=y -CONFIG_LOCK_KERNEL=y +CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup # CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_SWAP=y CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y +# CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y -# CONFIG_CPUSETS is not set -# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y +CONFIG_VM86=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set -CONFIG_UID16=y -CONFIG_SYSCTL=y CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y @@ -55,9 +45,11 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -68,45 +60,41 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set # CONFIG_KMOD is not set -CONFIG_STOP_MACHINE=y # # Block layer # -CONFIG_LBD=y -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set +# CONFIG_LBD is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_IOSCHED="cfq" # # Processor type and features # -CONFIG_SMP=y -# CONFIG_X86_PC is not set +CONFIG_X86_PC=y # CONFIG_X86_ELAN is not set # CONFIG_X86_VOYAGER is not set # CONFIG_X86_NUMAQ is not set # CONFIG_X86_SUMMIT is not set # CONFIG_X86_BIGSMP is not set # CONFIG_X86_VISWS is not set -CONFIG_X86_GENERICARCH=y +# CONFIG_X86_GENERICARCH is not set # CONFIG_X86_ES7000 is not set -CONFIG_X86_CYCLONE_TIMER=y # CONFIG_M386 is not set # CONFIG_M486 is not set # CONFIG_M586 is not set @@ -114,11 +102,11 @@ CONFIG_X86_CYCLONE_TIMER=y # CONFIG_M586MMX is not set # CONFIG_M686 is not set # CONFIG_MPENTIUMII is not set -CONFIG_MPENTIUMIII=y +# CONFIG_MPENTIUMIII is not set # CONFIG_MPENTIUMM is not set # CONFIG_MPENTIUM4 is not set # CONFIG_MK6 is not set -# CONFIG_MK7 is not set +CONFIG_MK7=y # CONFIG_MK8 is not set # CONFIG_MCRUSOE is not set # CONFIG_MEFFICEON is not set @@ -129,10 +117,10 @@ CONFIG_MPENTIUMIII=y # CONFIG_MGEODE_LX is not set # CONFIG_MCYRIXIII is not set # CONFIG_MVIAC3_2 is not set -CONFIG_X86_GENERIC=y +# CONFIG_X86_GENERIC is not set CONFIG_X86_CMPXCHG=y CONFIG_X86_XADD=y -CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_L1_CACHE_SHIFT=6 CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_X86_WP_WORKS_OK=y @@ -143,28 +131,26 @@ CONFIG_X86_CMPXCHG64=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_INTEL_USERCOPY=y CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_X86_USE_3DNOW=y CONFIG_X86_TSC=y -CONFIG_HPET_TIMER=y -CONFIG_HPET_EMULATE_RTC=y -CONFIG_NR_CPUS=32 -CONFIG_SCHED_SMT=y -CONFIG_SCHED_MC=y -# CONFIG_PREEMPT_NONE is not set -CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_HPET_TIMER is not set +# CONFIG_SMP is not set +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_PREEMPT_BKL=y +CONFIG_X86_UP_APIC=y +CONFIG_X86_UP_IOAPIC=y CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y CONFIG_X86_MCE=y CONFIG_X86_MCE_NONFATAL=y -CONFIG_X86_MCE_P4THERMAL=y -CONFIG_VM86=y +# CONFIG_X86_MCE_P4THERMAL is not set # CONFIG_TOSHIBA is not set # CONFIG_I8K is not set # CONFIG_X86_REBOOTFIXUPS is not set -CONFIG_MICROCODE=y -CONFIG_X86_MSR=y -CONFIG_X86_CPUID=y +# CONFIG_MICROCODE is not set +# CONFIG_X86_MSR is not set +# CONFIG_X86_CPUID is not set # # Firmware Drivers @@ -172,68 +158,68 @@ CONFIG_X86_CPUID=y # CONFIG_EDD is not set # CONFIG_DELL_RBU is not set # CONFIG_DCDBAS is not set -# CONFIG_NOHIGHMEM is not set -CONFIG_HIGHMEM4G=y +CONFIG_NOHIGHMEM=y +# CONFIG_HIGHMEM4G is not set # CONFIG_HIGHMEM64G is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_3G_OPT is not set +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set CONFIG_PAGE_OFFSET=0xC0000000 -CONFIG_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y # CONFIG_DISCONTIGMEM_MANUAL is not set # CONFIG_SPARSEMEM_MANUAL is not set CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPARSEMEM_STATIC=y CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_RESOURCES_64BIT=y -# CONFIG_HIGHPTE is not set # CONFIG_MATH_EMULATION is not set CONFIG_MTRR=y # CONFIG_EFI is not set -# CONFIG_IRQBALANCE is not set CONFIG_REGPARM=y -CONFIG_SECCOMP=y -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y +# CONFIG_SECCOMP is not set +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set # CONFIG_HZ_1000 is not set -CONFIG_HZ=250 +CONFIG_HZ=100 # CONFIG_KEXEC is not set -# CONFIG_CRASH_DUMP is not set CONFIG_PHYSICAL_START=0x100000 -# CONFIG_HOTPLUG_CPU is not set -CONFIG_COMPAT_VDSO=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_DOUBLEFAULT=y # # Power management options (ACPI, APM) # CONFIG_PM=y -CONFIG_PM_LEGACY=y +# CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set -CONFIG_PM_SYSFS_DEPRECATED=y +CONFIG_SOFTWARE_SUSPEND=y +CONFIG_PM_STD_PARTITION="" # # ACPI (Advanced Configuration and Power Interface) Support # CONFIG_ACPI=y -CONFIG_ACPI_AC=y -CONFIG_ACPI_BATTERY=y -CONFIG_ACPI_BUTTON=y +# CONFIG_ACPI_SLEEP is not set +# CONFIG_ACPI_AC is not set +# CONFIG_ACPI_BATTERY is not set +# CONFIG_ACPI_BUTTON is not set # CONFIG_ACPI_VIDEO is not set # CONFIG_ACPI_HOTKEY is not set -CONFIG_ACPI_FAN=y -# CONFIG_ACPI_DOCK is not set -CONFIG_ACPI_PROCESSOR=y -CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_FAN is not set +# CONFIG_ACPI_PROCESSOR is not set # CONFIG_ACPI_ASUS is not set # CONFIG_ACPI_IBM is not set # CONFIG_ACPI_TOSHIBA is not set -CONFIG_ACPI_BLACKLIST_YEAR=2001 -CONFIG_ACPI_DEBUG=y +CONFIG_ACPI_BLACKLIST_YEAR=0 +# CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_EC=y CONFIG_ACPI_POWER=y CONFIG_ACPI_SYSTEM=y -CONFIG_X86_PM_TIMER=y +# CONFIG_X86_PM_TIMER is not set # CONFIG_ACPI_CONTAINER is not set # @@ -244,41 +230,7 @@ CONFIG_X86_PM_TIMER=y # # CPU Frequency scaling # -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_TABLE=y -CONFIG_CPU_FREQ_DEBUG=y -CONFIG_CPU_FREQ_STAT=y -# CONFIG_CPU_FREQ_STAT_DETAILS is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set - -# -# CPUFreq processor drivers -# -CONFIG_X86_ACPI_CPUFREQ=y -# CONFIG_X86_POWERNOW_K6 is not set -# CONFIG_X86_POWERNOW_K7 is not set -CONFIG_X86_POWERNOW_K8=y -CONFIG_X86_POWERNOW_K8_ACPI=y -# CONFIG_X86_GX_SUSPMOD is not set -# CONFIG_X86_SPEEDSTEP_CENTRINO is not set -# CONFIG_X86_SPEEDSTEP_ICH is not set -# CONFIG_X86_SPEEDSTEP_SMI is not set -# CONFIG_X86_P4_CLOCKMOD is not set -# CONFIG_X86_CPUFREQ_NFORCE2 is not set -# CONFIG_X86_LONGRUN is not set -# CONFIG_X86_LONGHAUL is not set - -# -# shared options -# -CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y -# CONFIG_X86_SPEEDSTEP_LIB is not set +# CONFIG_CPU_FREQ is not set # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -292,14 +244,12 @@ CONFIG_PCI_BIOS=y CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y # CONFIG_PCIEPORTBUS is not set -CONFIG_PCI_MSI=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set -# CONFIG_PCI_DEBUG is not set +# CONFIG_PCI_MSI is not set +# CONFIG_PCI_LEGACY_PROC is not set CONFIG_ISA_DMA_API=y # CONFIG_ISA is not set # CONFIG_MCA is not set # CONFIG_SCx200 is not set -CONFIG_K8_NB=y # # PCCARD (PCMCIA/CardBus) support @@ -328,54 +278,93 @@ CONFIG_NET=y # # CONFIG_NETDEBUG is not set CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set +CONFIG_PACKET_MMAP=y CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set # CONFIG_NET_KEY is not set CONFIG_INET=y -CONFIG_IP_MULTICAST=y +# CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set # CONFIG_SYN_COOKIES is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -CONFIG_INET_XFRM_MODE_TRANSPORT=y -CONFIG_INET_XFRM_MODE_TUNNEL=y -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y +# CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -CONFIG_IPV6=y -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_IPV6_ROUTER_PREF is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_MIP6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -CONFIG_INET6_XFRM_MODE_TRANSPORT=y -CONFIG_INET6_XFRM_MODE_TUNNEL=y -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set +CONFIG_TCP_CONG_BIC=y + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK is not set +CONFIG_NETFILTER_XTABLES=y +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_HELPER is not set +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +# CONFIG_NETFILTER_XT_MATCH_MARK is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATE=y +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=y +# CONFIG_IP_NF_CT_ACCT is not set +# CONFIG_IP_NF_CONNTRACK_MARK is not set +# CONFIG_IP_NF_CONNTRACK_EVENTS is not set +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=y +# CONFIG_IP_NF_IRC is not set +# CONFIG_IP_NF_NETBIOS_NS is not set +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_PPTP is not set +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=y +# CONFIG_IP_NF_MATCH_IPRANGE is not set +# CONFIG_IP_NF_MATCH_MULTIPORT is not set +# CONFIG_IP_NF_MATCH_TOS is not set +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +# CONFIG_IP_NF_MATCH_AH_ESP is not set +# CONFIG_IP_NF_MATCH_TTL is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_HASHLIMIT is not set +CONFIG_IP_NF_FILTER=y +# CONFIG_IP_NF_TARGET_REJECT is not set +CONFIG_IP_NF_TARGET_LOG=y +# CONFIG_IP_NF_TARGET_ULOG is not set +# CONFIG_IP_NF_TARGET_TCPMSS is not set +# CONFIG_IP_NF_NAT is not set +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set # # DCCP Configuration (EXPERIMENTAL) @@ -400,6 +389,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -412,7 +402,6 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_TCPPROBE is not set # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set @@ -427,9 +416,7 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_FW_LOADER is not set # # Connector - unified userspace <-> kernelspace linker @@ -444,7 +431,13 @@ CONFIG_FW_LOADER=y # # Parallel port support # -# CONFIG_PARPORT is not set +CONFIG_PARPORT=y +CONFIG_PARPORT_PC=y +# CONFIG_PARPORT_SERIAL is not set +# CONFIG_PARPORT_PC_FIFO is not set +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_GSC is not set +CONFIG_PARPORT_1284=y # # Plug and Play support @@ -454,7 +447,8 @@ CONFIG_FW_LOADER=y # # Block devices # -CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_FD is not set +# CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set @@ -465,11 +459,8 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y +# CONFIG_BLK_DEV_RAM is not set CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -485,7 +476,7 @@ CONFIG_BLK_DEV_IDE=y # CONFIG_BLK_DEV_IDE_SATA is not set # CONFIG_BLK_DEV_HD_IDE is not set CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y +# CONFIG_IDEDISK_MULTI_MODE is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDETAPE is not set # CONFIG_BLK_DEV_IDEFLOPPY is not set @@ -495,10 +486,10 @@ CONFIG_BLK_DEV_IDECD=y # # IDE chipset support/bugfixes # -CONFIG_IDE_GENERIC=y +# CONFIG_IDE_GENERIC is not set # CONFIG_BLK_DEV_CMD640 is not set CONFIG_BLK_DEV_IDEPCI=y -# CONFIG_IDEPCI_SHARE_IRQ is not set +CONFIG_IDEPCI_SHARE_IRQ=y # CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_GENERIC is not set # CONFIG_BLK_DEV_OPTI621 is not set @@ -509,7 +500,7 @@ CONFIG_IDEDMA_PCI_AUTO=y # CONFIG_IDEDMA_ONLYDISK is not set # CONFIG_BLK_DEV_AEC62XX is not set # CONFIG_BLK_DEV_ALI15X3 is not set -CONFIG_BLK_DEV_AMD74XX=y +# CONFIG_BLK_DEV_AMD74XX is not set # CONFIG_BLK_DEV_ATIIXP is not set # CONFIG_BLK_DEV_CMD64X is not set # CONFIG_BLK_DEV_TRIFLEX is not set @@ -520,7 +511,7 @@ CONFIG_BLK_DEV_AMD74XX=y # CONFIG_BLK_DEV_HPT34X is not set # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set -CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_PIIX is not set # CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set @@ -530,7 +521,7 @@ CONFIG_BLK_DEV_PIIX=y # CONFIG_BLK_DEV_SIS5513 is not set # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_VIA82CXXX=y # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set @@ -542,7 +533,6 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -CONFIG_SCSI_NETLINK=y # CONFIG_SCSI_PROC_FS is not set # @@ -551,9 +541,8 @@ CONFIG_SCSI_NETLINK=y CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=y +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set # CONFIG_CHR_DEV_SCH is not set # @@ -564,44 +553,29 @@ CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transports +# SCSI Transport Attributes # -CONFIG_SCSI_SPI_ATTRS=y -CONFIG_SCSI_FC_ATTRS=y +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers # # CONFIG_ISCSI_TCP is not set -CONFIG_BLK_DEV_3W_XXXX_RAID=y +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set -CONFIG_SCSI_AIC7XXX=y -CONFIG_AIC7XXX_CMDS_PER_DEVICE=32 -CONFIG_AIC7XXX_RESET_DELAY_MS=5000 -CONFIG_AIC7XXX_DEBUG_ENABLE=y -CONFIG_AIC7XXX_DEBUG_MASK=0 -CONFIG_AIC7XXX_REG_PRETTY_PRINT=y +# CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set -CONFIG_SCSI_AIC79XX=y -CONFIG_AIC79XX_CMDS_PER_DEVICE=32 -CONFIG_AIC79XX_RESET_DELAY_MS=4000 -# CONFIG_AIC79XX_ENABLE_RD_STRM is not set -# CONFIG_AIC79XX_DEBUG_ENABLE is not set -CONFIG_AIC79XX_DEBUG_MASK=0 -# CONFIG_AIC79XX_REG_PRETTY_PRINT is not set -# CONFIG_SCSI_AIC94XX is not set +# CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_ARCMSR is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_SATA is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set @@ -610,9 +584,11 @@ CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set # CONFIG_SCSI_LPFC is not set @@ -621,115 +597,23 @@ CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_SCSI_NSP32 is not set # CONFIG_SCSI_DEBUG is not set -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -CONFIG_ATA=y -CONFIG_SATA_AHCI=y -CONFIG_SATA_SVW=y -CONFIG_ATA_PIIX=y -# CONFIG_SATA_MV is not set -CONFIG_SATA_NV=y -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -CONFIG_SATA_SIL=y -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -CONFIG_SATA_VIA=y -# CONFIG_SATA_VITESSE is not set -CONFIG_SATA_INTEL_COMBINED=y -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CS5535 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_LEGACY is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_QDI is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set - # # Multi-device support (RAID and LVM) # -CONFIG_MD=y -# CONFIG_BLK_DEV_MD is not set -CONFIG_BLK_DEV_DM=y -# CONFIG_DM_CRYPT is not set -# CONFIG_DM_SNAPSHOT is not set -# CONFIG_DM_MIRROR is not set -# CONFIG_DM_ZERO is not set -# CONFIG_DM_MULTIPATH is not set +# CONFIG_MD is not set # # Fusion MPT device support # -CONFIG_FUSION=y -CONFIG_FUSION_SPI=y +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set # CONFIG_FUSION_FC is not set # CONFIG_FUSION_SAS is not set -CONFIG_FUSION_MAX_SGE=128 -# CONFIG_FUSION_CTL is not set # # IEEE 1394 (FireWire) support # -CONFIG_IEEE1394=y - -# -# Subsystem Options -# -# CONFIG_IEEE1394_VERBOSEDEBUG is not set -# CONFIG_IEEE1394_OUI_DB is not set -# CONFIG_IEEE1394_EXTRA_CONFIG_ROMS is not set -# CONFIG_IEEE1394_EXPORT_FULL_API is not set - -# -# Device Drivers -# - -# -# Texas Instruments PCILynx requires I2C -# -CONFIG_IEEE1394_OHCI1394=y - -# -# Protocol Drivers -# -# CONFIG_IEEE1394_VIDEO1394 is not set -# CONFIG_IEEE1394_SBP2 is not set -# CONFIG_IEEE1394_ETH1394 is not set -# CONFIG_IEEE1394_DV1394 is not set -CONFIG_IEEE1394_RAWIO=y +# CONFIG_IEEE1394 is not set # # I2O device support @@ -768,63 +652,46 @@ CONFIG_MII=y # # Tulip family network device support # -CONFIG_NET_TULIP=y -# CONFIG_DE2104X is not set -CONFIG_TULIP=y -# CONFIG_TULIP_MWI is not set -# CONFIG_TULIP_MMIO is not set -# CONFIG_TULIP_NAPI is not set -# CONFIG_DE4X5 is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_DM9102 is not set -# CONFIG_ULI526X is not set +# CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set CONFIG_NET_PCI=y # CONFIG_PCNET32 is not set # CONFIG_AMD8111_ETH is not set # CONFIG_ADAPTEC_STARFIRE is not set -CONFIG_B44=y -CONFIG_FORCEDETH=y -# CONFIG_FORCEDETH_NAPI is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set -CONFIG_8139CP=y -CONFIG_8139TOO=y -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set +# CONFIG_NET_POCKET is not set # # Ethernet (1000 Mbit) # # CONFIG_ACENIC is not set # CONFIG_DL2K is not set -CONFIG_E1000=y -# CONFIG_E1000_NAPI is not set -# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set +# CONFIG_E1000 is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set -CONFIG_R8169=y -# CONFIG_R8169_NAPI is not set +# CONFIG_R8169 is not set # CONFIG_SIS190 is not set # CONFIG_SKGE is not set -CONFIG_SKY2=y +# CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set -CONFIG_TIGON3=y -CONFIG_BNX2=y -# CONFIG_QLA3XXX is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) @@ -832,7 +699,6 @@ CONFIG_BNX2=y # CONFIG_CHELSIO_T1 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set -# CONFIG_MYRI10GE is not set # # Token Ring devices @@ -850,15 +716,14 @@ CONFIG_BNX2=y # CONFIG_WAN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set +# CONFIG_PLIP is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set # CONFIG_NET_FC is not set # CONFIG_SHAPER is not set -CONFIG_NETCONSOLE=y -CONFIG_NETPOLL=y -# CONFIG_NETPOLL_RX is not set -# CONFIG_NETPOLL_TRAP is not set -CONFIG_NET_POLL_CONTROLLER=y +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set # # ISDN subsystem @@ -880,8 +745,8 @@ CONFIG_INPUT=y # CONFIG_INPUT_MOUSEDEV=y CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1280 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1024 # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_TSDEV is not set CONFIG_INPUT_EVDEV=y @@ -911,6 +776,7 @@ CONFIG_SERIO=y CONFIG_SERIO_I8042=y # CONFIG_SERIO_SERPORT is not set # CONFIG_SERIO_CT82C710 is not set +# CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set @@ -922,15 +788,14 @@ CONFIG_SERIO_LIBPS2=y CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y -# CONFIG_VT_HW_CONSOLE_BINDING is not set # CONFIG_SERIAL_NONSTANDARD is not set # # Serial drivers # CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_PCI=y +# CONFIG_SERIAL_8250_CONSOLE is not set +# CONFIG_SERIAL_8250_ACPI is not set CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set @@ -939,11 +804,14 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # Non-8250 serial port support # CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 +CONFIG_PRINTER=y +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set +# CONFIG_TIPAR is not set # # IPMI @@ -954,12 +822,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set -CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_INTEL=y -CONFIG_HW_RANDOM_AMD=y -CONFIG_HW_RANDOM_GEODE=y -CONFIG_HW_RANDOM_VIA=y -# CONFIG_NVRAM is not set +# CONFIG_HW_RANDOM is not set +CONFIG_NVRAM=y CONFIG_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -969,28 +833,31 @@ CONFIG_RTC=y # # Ftape, the floppy tape device driver # +# CONFIG_FTAPE is not set CONFIG_AGP=y # CONFIG_AGP_ALI is not set # CONFIG_AGP_ATI is not set # CONFIG_AGP_AMD is not set -CONFIG_AGP_AMD64=y -CONFIG_AGP_INTEL=y +# CONFIG_AGP_AMD64 is not set +# CONFIG_AGP_INTEL is not set # CONFIG_AGP_NVIDIA is not set # CONFIG_AGP_SIS is not set # CONFIG_AGP_SWORKS is not set -# CONFIG_AGP_VIA is not set +CONFIG_AGP_VIA=y # CONFIG_AGP_EFFICEON is not set -# CONFIG_DRM is not set +CONFIG_DRM=y +# CONFIG_DRM_TDFX is not set +# CONFIG_DRM_R128 is not set +CONFIG_DRM_RADEON=y +# CONFIG_DRM_MGA is not set +# CONFIG_DRM_SIS is not set +# CONFIG_DRM_VIA is not set +# CONFIG_DRM_SAVAGE is not set # CONFIG_MWAVE is not set -# CONFIG_PC8736x_GPIO is not set -# CONFIG_NSC_GPIO is not set # CONFIG_CS5535_GPIO is not set -CONFIG_RAW_DRIVER=y -CONFIG_MAX_RAW_DEVS=256 -CONFIG_HPET=y -# CONFIG_HPET_RTC_IRQ is not set -CONFIG_HPET_MMAP=y -CONFIG_HANGCHECK_TIMER=y +# CONFIG_RAW_DRIVER is not set +# CONFIG_HPET is not set +# CONFIG_HANGCHECK_TIMER is not set # # TPM devices @@ -1001,7 +868,59 @@ CONFIG_HANGCHECK_TIMER=y # # I2C support # -# CONFIG_I2C is not set +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y + +# +# I2C Algorithms +# +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set +CONFIG_I2C_ISA=y +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PARPORT is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PROSAVAGE is not set +# CONFIG_I2C_SAVAGE4 is not set +# CONFIG_SCx200_ACB is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_VIA is not set +CONFIG_I2C_VIAPRO=y +# CONFIG_I2C_VOODOO3 is not set +# CONFIG_I2C_PCA_ISA is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set +# CONFIG_RTC_X1205_I2C is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +# CONFIG_I2C_DEBUG_CHIP is not set # # SPI support @@ -1012,44 +931,169 @@ CONFIG_HANGCHECK_TIMER=y # # Dallas's 1-wire bus # +# CONFIG_W1 is not set # # Hardware Monitoring support # -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set +CONFIG_HWMON=y +CONFIG_HWMON_VID=y +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +CONFIG_SENSORS_IT87=y +# CONFIG_SENSORS_LM63 is not set +# CONFIG_SENSORS_LM75 is not set +# CONFIG_SENSORS_LM77 is not set +# CONFIG_SENSORS_LM78 is not set +# CONFIG_SENSORS_LM80 is not set +# CONFIG_SENSORS_LM83 is not set +# CONFIG_SENSORS_LM85 is not set +# CONFIG_SENSORS_LM87 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_HDAPS is not set +# CONFIG_HWMON_DEBUG_CHIP is not set # # Misc devices # # CONFIG_IBM_ASM is not set +# +# Multimedia Capabilities Port drivers +# + # # Multimedia devices # -# CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_DEV=y + +# +# Video For Linux +# + +# +# Video Adapters +# +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_BT848 is not set +# CONFIG_VIDEO_BWQCAM is not set +# CONFIG_VIDEO_CQCAM is not set +# CONFIG_VIDEO_W9966 is not set +# CONFIG_VIDEO_CPIA is not set +# CONFIG_VIDEO_SAA5246A is not set +# CONFIG_VIDEO_SAA5249 is not set +# CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_STRADIS is not set +# CONFIG_VIDEO_ZORAN is not set +CONFIG_VIDEO_SAA7134=y +# CONFIG_VIDEO_SAA7134_ALSA is not set +# CONFIG_VIDEO_MXB is not set +# CONFIG_VIDEO_DPC is not set +# CONFIG_VIDEO_HEXIUM_ORION is not set +# CONFIG_VIDEO_HEXIUM_GEMINI is not set +# CONFIG_VIDEO_CX88 is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_OVCAMCHIP is not set +# CONFIG_VIDEO_AUDIO_DECODER is not set +# CONFIG_VIDEO_DECODER is not set + +# +# Radio Adapters +# +# CONFIG_RADIO_GEMTEK_PCI is not set +# CONFIG_RADIO_MAXIRADIO is not set +# CONFIG_RADIO_MAESTRO is not set # # Digital Video Broadcasting Devices # # CONFIG_DVB is not set -# CONFIG_USB_DABUSB is not set +CONFIG_VIDEO_TUNER=y +CONFIG_VIDEO_BUF=y +CONFIG_VIDEO_IR=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y -# CONFIG_FB is not set +CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_MACMODES is not set +CONFIG_FB_MODE_HELPERS=y +# CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_CIRRUS is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +# CONFIG_FB_ARC is not set +# CONFIG_FB_ASILIANT is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_VGA16 is not set +# CONFIG_FB_VESA is not set +CONFIG_VIDEO_SELECT=y +# CONFIG_FB_HGA is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set +# CONFIG_FB_I810 is not set +# CONFIG_FB_INTEL is not set +# CONFIG_FB_MATROX is not set +# CONFIG_FB_RADEON_OLD is not set +CONFIG_FB_RADEON=y +CONFIG_FB_RADEON_I2C=y +# CONFIG_FB_RADEON_DEBUG is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_SAVAGE is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_NEOMAGIC is not set +# CONFIG_FB_KYRO is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_VOODOO1 is not set +# CONFIG_FB_CYBLA is not set +# CONFIG_FB_TRIDENT is not set +# CONFIG_FB_GEODE is not set +# CONFIG_FB_VIRTUAL is not set # # Console display driver support # CONFIG_VGA_CONSOLE=y -CONFIG_VGACON_SOFT_SCROLLBACK=y -CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=128 -CONFIG_VIDEO_SELECT=y CONFIG_DUMMY_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +# CONFIG_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y + +# +# Logo configuration +# +# CONFIG_LOGO is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -1060,30 +1104,97 @@ CONFIG_SOUND=y # # Advanced Linux Sound Architecture # -# CONFIG_SND is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_RAWMIDI=y +CONFIG_SND_SEQUENCER=y +# CONFIG_SND_SEQ_DUMMY is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_SEQUENCER_OSS is not set +CONFIG_SND_RTCTIMER=y +CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y +# CONFIG_SND_DYNAMIC_MINORS is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set + +# +# Generic devices +# +CONFIG_SND_MPU401_UART=y +CONFIG_SND_AC97_CODEC=y +CONFIG_SND_AC97_BUS=y +# CONFIG_SND_DUMMY is not set +# CONFIG_SND_VIRMIDI is not set +# CONFIG_SND_MTPAV is not set +# CONFIG_SND_SERIAL_U16550 is not set +# CONFIG_SND_MPU401 is not set + +# +# PCI devices +# +# CONFIG_SND_AD1889 is not set +# CONFIG_SND_ALS4000 is not set +# CONFIG_SND_ALI5451 is not set +# CONFIG_SND_ATIIXP is not set +# CONFIG_SND_ATIIXP_MODEM is not set +# CONFIG_SND_AU8810 is not set +# CONFIG_SND_AU8820 is not set +# CONFIG_SND_AU8830 is not set +# CONFIG_SND_AZT3328 is not set +# CONFIG_SND_BT87X is not set +# CONFIG_SND_CA0106 is not set +# CONFIG_SND_CMIPCI is not set +# CONFIG_SND_CS4281 is not set +# CONFIG_SND_CS46XX is not set +# CONFIG_SND_CS5535AUDIO is not set +# CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_ENS1370 is not set +# CONFIG_SND_ENS1371 is not set +# CONFIG_SND_ES1938 is not set +# CONFIG_SND_ES1968 is not set +# CONFIG_SND_FM801 is not set +# CONFIG_SND_HDA_INTEL is not set +# CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set +# CONFIG_SND_ICE1712 is not set +# CONFIG_SND_ICE1724 is not set +# CONFIG_SND_INTEL8X0 is not set +# CONFIG_SND_INTEL8X0M is not set +# CONFIG_SND_KORG1212 is not set +# CONFIG_SND_MAESTRO3 is not set +# CONFIG_SND_MIXART is not set +# CONFIG_SND_NM256 is not set +# CONFIG_SND_PCXHR is not set +# CONFIG_SND_RME32 is not set +# CONFIG_SND_RME96 is not set +# CONFIG_SND_RME9652 is not set +# CONFIG_SND_SONICVIBES is not set +# CONFIG_SND_TRIDENT is not set +CONFIG_SND_VIA82XX=y +# CONFIG_SND_VIA82XX_MODEM is not set +# CONFIG_SND_VX222 is not set +# CONFIG_SND_YMFPCI is not set + +# +# USB devices +# +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_USX2Y is not set # # Open Sound System # -CONFIG_SOUND_PRIME=y -CONFIG_OSS_OBSOLETE_DRIVER=y -# CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_EMU10K1 is not set -# CONFIG_SOUND_FUSION is not set -# CONFIG_SOUND_ES1371 is not set -CONFIG_SOUND_ICH=y -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set -# CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_PRIME is not set # # USB support # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -1102,19 +1213,17 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OHCI_HCD is not set CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set # # USB Device Class drivers # +# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set # CONFIG_USB_ACM is not set -CONFIG_USB_PRINTER=y +# CONFIG_USB_PRINTER is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' @@ -1139,17 +1248,21 @@ CONFIG_USB_STORAGE=y # # USB Input Devices # -CONFIG_USB_HID=y -CONFIG_USB_HIDINPUT=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set # CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set -# CONFIG_USB_TOUCHSCREEN is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set # CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -1163,6 +1276,21 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set +# CONFIG_USB_VICAM is not set +# CONFIG_USB_DSBR is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_IBMCAM is not set +# CONFIG_USB_KONICAWC is not set +# CONFIG_USB_OV511 is not set +# CONFIG_USB_SE401 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_STV680 is not set +# CONFIG_USB_PWC is not set + # # USB Network Adapters # @@ -1171,11 +1299,12 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y +# CONFIG_USB_MON is not set # # USB port drivers # +# CONFIG_USB_USS720 is not set # # USB Serial Converter support @@ -1192,12 +1321,10 @@ CONFIG_USB_MON=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TEST is not set @@ -1216,97 +1343,57 @@ CONFIG_USB_MON=y # # CONFIG_MMC is not set -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - # # InfiniBand support # # CONFIG_INFINIBAND is not set # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# -# CONFIG_EDAC is not set - -# -# Real Time Clock +# SN Devices # -# CONFIG_RTC_CLASS is not set # -# DMA Engine support -# -# CONFIG_DMA_ENGINE is not set - -# -# DMA Clients -# - -# -# DMA Devices +# EDAC - error detection and reporting (RAS) # +# CONFIG_EDAC is not set # # File systems # CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -CONFIG_REISERFS_FS=y -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -CONFIG_REISERFS_FS_XATTR=y -CONFIG_REISERFS_FS_POSIX_ACL=y -# CONFIG_REISERFS_FS_SECURITY is not set +# CONFIG_EXT3_FS is not set +# CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y +# CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -CONFIG_INOTIFY_USER=y +# CONFIG_INOTIFY is not set # CONFIG_QUOTA is not set CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=y +# CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems # CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=y # CONFIG_UDF_FS is not set # # DOS/FAT/NT Filesystems # CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y +# CONFIG_MSDOS_FS is not set CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_CODEPAGE=850 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set @@ -1317,9 +1404,10 @@ CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y CONFIG_TMPFS=y -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set # CONFIG_CONFIGFS_FS is not set # @@ -1342,26 +1430,13 @@ CONFIG_RAMFS=y # # Network File Systems # -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -# CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_NFS_FS is not set +# CONFIG_NFSD is not set # CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set +CONFIG_CIFS=y +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1370,18 +1445,33 @@ CONFIG_SUNRPC=y # # Partition Types # -# CONFIG_PARTITION_ADVANCED is not set +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set # # Native Language Support # CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_DEFAULT="iso8859-15" +# CONFIG_NLS_CODEPAGE_437 is not set # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set +CONFIG_NLS_CODEPAGE_850=y # CONFIG_NLS_CODEPAGE_852 is not set # CONFIG_NLS_CODEPAGE_855 is not set # CONFIG_NLS_CODEPAGE_857 is not set @@ -1401,7 +1491,7 @@ CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=y +# CONFIG_NLS_ASCII is not set CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set @@ -1420,51 +1510,20 @@ CONFIG_NLS_UTF8=y # # Instrumentation Support # -CONFIG_PROFILING=y -CONFIG_OPROFILE=y -CONFIG_KPROBES=y +# CONFIG_PROFILING is not set +# CONFIG_KPROBES is not set # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -# CONFIG_ENABLE_MUST_CHECK is not set CONFIG_MAGIC_SYSRQ=y -CONFIG_UNUSED_SYMBOLS=y -CONFIG_DEBUG_KERNEL=y -CONFIG_LOG_BUF_SHIFT=18 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set -# CONFIG_DEBUG_RWSEMS is not set -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_HIGHMEM is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_FRAME_POINTER is not set -CONFIG_UNWIND_INFO=y -CONFIG_STACK_UNWIND=y -# CONFIG_FORCED_INLINING is not set -# CONFIG_RCU_TORTURE_TEST is not set CONFIG_EARLY_PRINTK=y -CONFIG_DEBUG_STACKOVERFLOW=y -# CONFIG_DEBUG_STACK_USAGE is not set -# CONFIG_DEBUG_RODATA is not set -# CONFIG_4KSTACKS is not set CONFIG_X86_FIND_SMP_CONFIG=y CONFIG_X86_MPPARSE=y -CONFIG_DOUBLEFAULT=y # # Security options @@ -1477,6 +1536,10 @@ CONFIG_DOUBLEFAULT=y # # CONFIG_CRYPTO is not set +# +# Hardware crypto devices +# + # # Library routines # @@ -1485,12 +1548,7 @@ CONFIG_DOUBLEFAULT=y CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_PENDING_IRQ=y -CONFIG_X86_SMP=y -CONFIG_X86_HT=y CONFIG_X86_BIOS_REBOOT=y -CONFIG_X86_TRAMPOLINE=y CONFIG_KTIME_SCALAR=y diff --git a/trunk/arch/i386/kernel/Makefile b/trunk/arch/i386/kernel/Makefile index 1a884b6e6e5c..5427a842e841 100644 --- a/trunk/arch/i386/kernel/Makefile +++ b/trunk/arch/i386/kernel/Makefile @@ -4,7 +4,7 @@ extra-y := head.o init_task.o vmlinux.lds -obj-y := process.o signal.o entry.o traps.o irq.o \ +obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ pci-dma.o i386_ksyms.o i387.o bootflag.o \ quirks.o i8237.o topology.o alternative.o i8253.o tsc.o @@ -81,5 +81,4 @@ $(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \ $(call if_changed,syscall) k8-y += ../../x86_64/kernel/k8.o -stacktrace-y += ../../x86_64/kernel/stacktrace.o diff --git a/trunk/arch/i386/kernel/acpi/Makefile b/trunk/arch/i386/kernel/acpi/Makefile index 7f7be01f44e6..7e9ac99354f4 100644 --- a/trunk/arch/i386/kernel/acpi/Makefile +++ b/trunk/arch/i386/kernel/acpi/Makefile @@ -1,7 +1,5 @@ obj-$(CONFIG_ACPI) += boot.o -ifneq ($(CONFIG_PCI),) obj-$(CONFIG_X86_IO_APIC) += earlyquirk.o -endif obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup.o ifneq ($(CONFIG_ACPI_PROCESSOR),) diff --git a/trunk/arch/i386/kernel/acpi/boot.c b/trunk/arch/i386/kernel/acpi/boot.c index 1aaea6ab8c46..ee003bc0e8b1 100644 --- a/trunk/arch/i386/kernel/acpi/boot.c +++ b/trunk/arch/i386/kernel/acpi/boot.c @@ -26,12 +26,9 @@ #include #include #include -#include #include #include #include -#include -#include #include #include @@ -39,17 +36,11 @@ #include #include -static int __initdata acpi_force = 0; - -#ifdef CONFIG_ACPI -int acpi_disabled = 0; -#else -int acpi_disabled = 1; -#endif -EXPORT_SYMBOL(acpi_disabled); - #ifdef CONFIG_X86_64 +extern void __init clustered_apic_check(void); + +extern int gsi_irq_sharing(int gsi); #include static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return 0; } @@ -515,76 +506,16 @@ EXPORT_SYMBOL(acpi_register_gsi); #ifdef CONFIG_ACPI_HOTPLUG_CPU int acpi_map_lsapic(acpi_handle handle, int *pcpu) { - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *obj; - struct acpi_table_lapic *lapic; - cpumask_t tmp_map, new_map; - u8 physid; - int cpu; - - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_MAT", NULL, &buffer))) - return -EINVAL; - - if (!buffer.length || !buffer.pointer) - return -EINVAL; - - obj = buffer.pointer; - if (obj->type != ACPI_TYPE_BUFFER || - obj->buffer.length < sizeof(*lapic)) { - kfree(buffer.pointer); - return -EINVAL; - } - - lapic = (struct acpi_table_lapic *)obj->buffer.pointer; - - if ((lapic->header.type != ACPI_MADT_LAPIC) || - (!lapic->flags.enabled)) { - kfree(buffer.pointer); - return -EINVAL; - } - - physid = lapic->id; - - kfree(buffer.pointer); - buffer.length = ACPI_ALLOCATE_BUFFER; - buffer.pointer = NULL; - - tmp_map = cpu_present_map; - mp_register_lapic(physid, lapic->flags.enabled); - - /* - * If mp_register_lapic successfully generates a new logical cpu - * number, then the following will get us exactly what was mapped - */ - cpus_andnot(new_map, cpu_present_map, tmp_map); - if (cpus_empty(new_map)) { - printk ("Unable to map lapic to logical cpu number\n"); - return -EINVAL; - } - - cpu = first_cpu(new_map); - - *pcpu = cpu; - return 0; + /* TBD */ + return -EINVAL; } EXPORT_SYMBOL(acpi_map_lsapic); int acpi_unmap_lsapic(int cpu) { - int i; - - for_each_possible_cpu(i) { - if (x86_acpiid_to_apicid[i] == x86_cpu_to_apicid[cpu]) { - x86_acpiid_to_apicid[i] = -1; - break; - } - } - x86_cpu_to_apicid[cpu] = -1; - cpu_clear(cpu, cpu_present_map); - num_processors--; - - return (0); + /* TBD */ + return -EINVAL; } EXPORT_SYMBOL(acpi_unmap_lsapic); @@ -648,8 +579,6 @@ static int __init acpi_parse_sbf(unsigned long phys_addr, unsigned long size) static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) { struct acpi_table_hpet *hpet_tbl; - struct resource *hpet_res; - resource_size_t res_start; if (!phys || !size) return -EINVAL; @@ -665,26 +594,12 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) "memory.\n"); return -1; } - -#define HPET_RESOURCE_NAME_SIZE 9 - hpet_res = alloc_bootmem(sizeof(*hpet_res) + HPET_RESOURCE_NAME_SIZE); - if (hpet_res) { - memset(hpet_res, 0, sizeof(*hpet_res)); - hpet_res->name = (void *)&hpet_res[1]; - hpet_res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - snprintf((char *)hpet_res->name, HPET_RESOURCE_NAME_SIZE, - "HPET %u", hpet_tbl->number); - hpet_res->end = (1 * 1024) - 1; - } - #ifdef CONFIG_X86_64 vxtime.hpet_address = hpet_tbl->addr.addrl | ((long)hpet_tbl->addr.addrh << 32); printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", hpet_tbl->id, vxtime.hpet_address); - - res_start = vxtime.hpet_address; #else /* X86 */ { extern unsigned long hpet_address; @@ -692,17 +607,9 @@ static int __init acpi_parse_hpet(unsigned long phys, unsigned long size) hpet_address = hpet_tbl->addr.addrl; printk(KERN_INFO PREFIX "HPET id: %#x base: %#lx\n", hpet_tbl->id, hpet_address); - - res_start = hpet_address; } #endif /* X86 */ - if (hpet_res) { - hpet_res->start = res_start; - hpet_res->end += res_start; - insert_resource(&iomem_resource, hpet_res); - } - return 0; } #else @@ -953,6 +860,8 @@ static void __init acpi_process_madt(void) return; } +extern int acpi_force; + #ifdef __i386__ static int __init disable_acpi_irq(struct dmi_system_id *d) @@ -1254,75 +1163,3 @@ int __init acpi_boot_init(void) return 0; } - -static int __init parse_acpi(char *arg) -{ - if (!arg) - return -EINVAL; - - /* "acpi=off" disables both ACPI table parsing and interpreter */ - if (strcmp(arg, "off") == 0) { - disable_acpi(); - } - /* acpi=force to over-ride black-list */ - else if (strcmp(arg, "force") == 0) { - acpi_force = 1; - acpi_ht = 1; - acpi_disabled = 0; - } - /* acpi=strict disables out-of-spec workarounds */ - else if (strcmp(arg, "strict") == 0) { - acpi_strict = 1; - } - /* Limit ACPI just to boot-time to enable HT */ - else if (strcmp(arg, "ht") == 0) { - if (!acpi_force) - disable_acpi(); - acpi_ht = 1; - } - /* "acpi=noirq" disables ACPI interrupt routing */ - else if (strcmp(arg, "noirq") == 0) { - acpi_noirq_set(); - } else { - /* Core will printk when we return error. */ - return -EINVAL; - } - return 0; -} -early_param("acpi", parse_acpi); - -/* FIXME: Using pci= for an ACPI parameter is a travesty. */ -static int __init parse_pci(char *arg) -{ - if (arg && strcmp(arg, "noacpi") == 0) - acpi_disable_pci(); - return 0; -} -early_param("pci", parse_pci); - -#ifdef CONFIG_X86_IO_APIC -static int __init parse_acpi_skip_timer_override(char *arg) -{ - acpi_skip_timer_override = 1; - return 0; -} -early_param("acpi_skip_timer_override", parse_acpi_skip_timer_override); -#endif /* CONFIG_X86_IO_APIC */ - -static int __init setup_acpi_sci(char *s) -{ - if (!s) - return -EINVAL; - if (!strcmp(s, "edge")) - acpi_sci_flags.trigger = 1; - else if (!strcmp(s, "level")) - acpi_sci_flags.trigger = 3; - else if (!strcmp(s, "high")) - acpi_sci_flags.polarity = 1; - else if (!strcmp(s, "low")) - acpi_sci_flags.polarity = 3; - else - return -EINVAL; - return 0; -} -early_param("acpi_sci", setup_acpi_sci); diff --git a/trunk/arch/i386/kernel/acpi/earlyquirk.c b/trunk/arch/i386/kernel/acpi/earlyquirk.c index fe799b11ac0a..1649a175a206 100644 --- a/trunk/arch/i386/kernel/acpi/earlyquirk.c +++ b/trunk/arch/i386/kernel/acpi/earlyquirk.c @@ -48,11 +48,7 @@ void __init check_acpi_pci(void) int num, slot, func; /* Assume the machine supports type 1. If not it will - always read ffffffff and should not have any side effect. - Actually a few buggy systems can machine check. Allow the user - to disable it by command line option at least -AK */ - if (!early_pci_allowed()) - return; + always read ffffffff and should not have any side effect. */ /* Poor man's PCI discovery */ for (num = 0; num < 32; num++) { diff --git a/trunk/arch/i386/kernel/apic.c b/trunk/arch/i386/kernel/apic.c index 90faae5c5d30..8c844d07862f 100644 --- a/trunk/arch/i386/kernel/apic.c +++ b/trunk/arch/i386/kernel/apic.c @@ -52,18 +52,7 @@ static cpumask_t timer_bcast_ipi; /* * Knob to control our willingness to enable the local APIC. */ -static int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ - -static inline void lapic_disable(void) -{ - enable_local_apic = -1; - clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); -} - -static inline void lapic_enable(void) -{ - enable_local_apic = 1; -} +int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ /* * Debug level @@ -597,7 +586,8 @@ void __devinit setup_local_APIC(void) printk("No ESR for 82489DX.\n"); } - setup_apic_nmi_watchdog(NULL); + if (nmi_watchdog == NMI_LOCAL_APIC) + setup_apic_nmi_watchdog(); apic_pm_activate(); } @@ -1383,18 +1373,3 @@ int __init APIC_init_uniprocessor (void) return 0; } - -static int __init parse_lapic(char *arg) -{ - lapic_enable(); - return 0; -} -early_param("lapic", parse_lapic); - -static int __init parse_nolapic(char *arg) -{ - lapic_disable(); - return 0; -} -early_param("nolapic", parse_nolapic); - diff --git a/trunk/arch/i386/kernel/apm.c b/trunk/arch/i386/kernel/apm.c index b42f2d914af3..ff9ce4b5eaa8 100644 --- a/trunk/arch/i386/kernel/apm.c +++ b/trunk/arch/i386/kernel/apm.c @@ -225,7 +225,6 @@ #include #include #include -#include #include #include @@ -403,6 +402,8 @@ static int realmode_power_off = 1; #else static int realmode_power_off; #endif +static int exit_kapmd __read_mostly; +static int kapmd_running __read_mostly; #ifdef CONFIG_APM_ALLOW_INTS static int allow_ints = 1; #else @@ -418,8 +419,6 @@ static const struct desc_struct bad_bios_desc = { 0, 0x00409200 }; static const char driver_version[] = "1.16ac"; /* no spaces */ -static struct task_struct *kapmd_task; - /* * APM event names taken from the APM 1.2 specification. These are * the message codes that the BIOS uses to tell us about events @@ -1424,7 +1423,7 @@ static void apm_mainloop(void) set_current_state(TASK_INTERRUPTIBLE); for (;;) { schedule_timeout(APM_CHECK_TIMEOUT); - if (kthread_should_stop()) + if (exit_kapmd) break; /* * Ok, check all events, check for idle (and mark us sleeping @@ -1707,6 +1706,12 @@ static int apm(void *unused) char * power_stat; char * bat_stat; + kapmd_running = 1; + + daemonize("kapmd"); + + current->flags |= PF_NOFREEZE; + #ifdef CONFIG_SMP /* 2002/08/01 - WT * This is to avoid random crashes at boot time during initialization @@ -1816,6 +1821,7 @@ static int apm(void *unused) console_blank_hook = NULL; #endif } + kapmd_running = 0; return 0; } @@ -2214,7 +2220,7 @@ static int __init apm_init(void) { struct proc_dir_entry *apm_proc; struct desc_struct *gdt; - int err; + int ret; dmi_check_system(apm_dmi_table); @@ -2323,17 +2329,12 @@ static int __init apm_init(void) if (apm_proc) apm_proc->owner = THIS_MODULE; - kapmd_task = kthread_create(apm, NULL, "kapmd"); - if (IS_ERR(kapmd_task)) { - printk(KERN_ERR "apm: disabled - Unable to start kernel " - "thread.\n"); - err = PTR_ERR(kapmd_task); - kapmd_task = NULL; + ret = kernel_thread(apm, NULL, CLONE_KERNEL | SIGCHLD); + if (ret < 0) { + printk(KERN_ERR "apm: disabled - Unable to start kernel thread.\n"); remove_proc_entry("apm", NULL); - return err; + return -ENOMEM; } - kapmd_task->flags |= PF_NOFREEZE; - wake_up_process(kapmd_task); if (num_online_cpus() > 1 && !smp ) { printk(KERN_NOTICE @@ -2383,10 +2384,9 @@ static void __exit apm_exit(void) remove_proc_entry("apm", NULL); if (power_off) pm_power_off = NULL; - if (kapmd_task) { - kthread_stop(kapmd_task); - kapmd_task = NULL; - } + exit_kapmd = 1; + while (kapmd_running) + schedule(); #ifdef CONFIG_PM_LEGACY pm_active = 0; #endif diff --git a/trunk/arch/i386/kernel/cpu/amd.c b/trunk/arch/i386/kernel/cpu/amd.c index e4758095d87a..e6a2d6b80cda 100644 --- a/trunk/arch/i386/kernel/cpu/amd.c +++ b/trunk/arch/i386/kernel/cpu/amd.c @@ -22,7 +22,7 @@ extern void vide(void); __asm__(".align 4\nvide: ret"); -static void __cpuinit init_amd(struct cpuinfo_x86 *c) +static void __init init_amd(struct cpuinfo_x86 *c) { u32 l, h; int mbytes = num_physpages >> (20-PAGE_SHIFT); @@ -246,7 +246,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) num_cache_leaves = 3; } -static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) +static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) { /* AMD errata T13 (order #21922) */ if ((c->x86 == 6)) { @@ -259,7 +259,7 @@ static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned in return size; } -static struct cpu_dev amd_cpu_dev __cpuinitdata = { +static struct cpu_dev amd_cpu_dev __initdata = { .c_vendor = "AMD", .c_ident = { "AuthenticAMD" }, .c_models = { @@ -275,6 +275,7 @@ static struct cpu_dev amd_cpu_dev __cpuinitdata = { }, }, .c_init = init_amd, + .c_identify = generic_identify, .c_size_cache = amd_size_cache, }; diff --git a/trunk/arch/i386/kernel/cpu/centaur.c b/trunk/arch/i386/kernel/cpu/centaur.c index 8c25047975c0..bd75629dd262 100644 --- a/trunk/arch/i386/kernel/cpu/centaur.c +++ b/trunk/arch/i386/kernel/cpu/centaur.c @@ -9,7 +9,7 @@ #ifdef CONFIG_X86_OOSTORE -static u32 __cpuinit power2(u32 x) +static u32 __init power2(u32 x) { u32 s=1; while(s<=x) @@ -22,7 +22,7 @@ static u32 __cpuinit power2(u32 x) * Set up an actual MCR */ -static void __cpuinit centaur_mcr_insert(int reg, u32 base, u32 size, int key) +static void __init centaur_mcr_insert(int reg, u32 base, u32 size, int key) { u32 lo, hi; @@ -40,7 +40,7 @@ static void __cpuinit centaur_mcr_insert(int reg, u32 base, u32 size, int key) * Shortcut: We know you can't put 4Gig of RAM on a winchip */ -static u32 __cpuinit ramtop(void) /* 16388 */ +static u32 __init ramtop(void) /* 16388 */ { int i; u32 top = 0; @@ -91,7 +91,7 @@ static u32 __cpuinit ramtop(void) /* 16388 */ * Compute a set of MCR's to give maximum coverage */ -static int __cpuinit centaur_mcr_compute(int nr, int key) +static int __init centaur_mcr_compute(int nr, int key) { u32 mem = ramtop(); u32 root = power2(mem); @@ -166,7 +166,7 @@ static int __cpuinit centaur_mcr_compute(int nr, int key) return ct; } -static void __cpuinit centaur_create_optimal_mcr(void) +static void __init centaur_create_optimal_mcr(void) { int i; /* @@ -189,7 +189,7 @@ static void __cpuinit centaur_create_optimal_mcr(void) wrmsr(MSR_IDT_MCR0+i, 0, 0); } -static void __cpuinit winchip2_create_optimal_mcr(void) +static void __init winchip2_create_optimal_mcr(void) { u32 lo, hi; int i; @@ -227,7 +227,7 @@ static void __cpuinit winchip2_create_optimal_mcr(void) * Handle the MCR key on the Winchip 2. */ -static void __cpuinit winchip2_unprotect_mcr(void) +static void __init winchip2_unprotect_mcr(void) { u32 lo, hi; u32 key; @@ -239,7 +239,7 @@ static void __cpuinit winchip2_unprotect_mcr(void) wrmsr(MSR_IDT_MCR_CTRL, lo, hi); } -static void __cpuinit winchip2_protect_mcr(void) +static void __init winchip2_protect_mcr(void) { u32 lo, hi; @@ -257,7 +257,7 @@ static void __cpuinit winchip2_protect_mcr(void) #define RNG_ENABLED (1 << 3) #define RNG_ENABLE (1 << 6) /* MSR_VIA_RNG */ -static void __cpuinit init_c3(struct cpuinfo_x86 *c) +static void __init init_c3(struct cpuinfo_x86 *c) { u32 lo, hi; @@ -303,7 +303,7 @@ static void __cpuinit init_c3(struct cpuinfo_x86 *c) display_cacheinfo(c); } -static void __cpuinit init_centaur(struct cpuinfo_x86 *c) +static void __init init_centaur(struct cpuinfo_x86 *c) { enum { ECX8=1<<1, @@ -442,7 +442,7 @@ static void __cpuinit init_centaur(struct cpuinfo_x86 *c) } } -static unsigned int __cpuinit centaur_size_cache(struct cpuinfo_x86 * c, unsigned int size) +static unsigned int centaur_size_cache(struct cpuinfo_x86 * c, unsigned int size) { /* VIA C3 CPUs (670-68F) need further shifting. */ if ((c->x86 == 6) && ((c->x86_model == 7) || (c->x86_model == 8))) @@ -457,7 +457,7 @@ static unsigned int __cpuinit centaur_size_cache(struct cpuinfo_x86 * c, unsigne return size; } -static struct cpu_dev centaur_cpu_dev __cpuinitdata = { +static struct cpu_dev centaur_cpu_dev __initdata = { .c_vendor = "Centaur", .c_ident = { "CentaurHauls" }, .c_init = init_centaur, diff --git a/trunk/arch/i386/kernel/cpu/common.c b/trunk/arch/i386/kernel/cpu/common.c index 2799baaadf45..70c87de582c7 100644 --- a/trunk/arch/i386/kernel/cpu/common.c +++ b/trunk/arch/i386/kernel/cpu/common.c @@ -36,7 +36,7 @@ struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; extern int disable_pse; -static void __cpuinit default_init(struct cpuinfo_x86 * c) +static void default_init(struct cpuinfo_x86 * c) { /* Not much we can do here... */ /* Check if at least it has cpuid */ @@ -49,7 +49,7 @@ static void __cpuinit default_init(struct cpuinfo_x86 * c) } } -static struct cpu_dev __cpuinitdata default_cpu = { +static struct cpu_dev default_cpu = { .c_init = default_init, .c_vendor = "Unknown", }; @@ -265,7 +265,7 @@ static void __init early_cpu_detect(void) } } -static void __cpuinit generic_identify(struct cpuinfo_x86 * c) +void __cpuinit generic_identify(struct cpuinfo_x86 * c) { u32 tfms, xlvl; int ebx; @@ -675,7 +675,7 @@ void __cpuinit cpu_init(void) #endif /* Clear %fs and %gs. */ - asm volatile ("movl %0, %%fs; movl %0, %%gs" : : "r" (0)); + asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs"); /* Clear all 6 debug registers: */ set_debugreg(0, 0); diff --git a/trunk/arch/i386/kernel/cpu/cpu.h b/trunk/arch/i386/kernel/cpu/cpu.h index 2f6432cef6ff..5a1d4f163e84 100644 --- a/trunk/arch/i386/kernel/cpu/cpu.h +++ b/trunk/arch/i386/kernel/cpu/cpu.h @@ -24,5 +24,7 @@ extern struct cpu_dev * cpu_devs [X86_VENDOR_NUM]; extern int get_model_name(struct cpuinfo_x86 *c); extern void display_cacheinfo(struct cpuinfo_x86 *c); +extern void generic_identify(struct cpuinfo_x86 * c); + extern void early_intel_workaround(struct cpuinfo_x86 *c); diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index 57c880bf0bd6..ea19d091fd41 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -396,13 +396,13 @@ static int acpi_cpufreq_early_init_acpi(void) */ static int bios_with_sw_any_bug; -static int sw_any_bug_found(struct dmi_system_id *d) +static int __init sw_any_bug_found(struct dmi_system_id *d) { bios_with_sw_any_bug = 1; return 0; } -static struct dmi_system_id sw_any_bug_dmi_table[] = { +static struct dmi_system_id __initdata sw_any_bug_dmi_table[] = { { .callback = sw_any_bug_found, .ident = "Supermicro Server X6DLP", @@ -597,6 +597,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = { .name = "acpi-cpufreq", .owner = THIS_MODULE, .attr = acpi_cpufreq_attr, + .flags = CPUFREQ_STICKY, }; @@ -607,7 +608,7 @@ acpi_cpufreq_init (void) acpi_cpufreq_early_init_acpi(); - return cpufreq_register_driver(&acpi_cpufreq_driver); + return cpufreq_register_driver(&acpi_cpufreq_driver); } diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c index 7233abe5d695..f5cc9f5c9bab 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/longhaul.c @@ -178,17 +178,11 @@ static void do_powersaver(int cx_address, unsigned int clock_ratio_index) safe_halt(); /* Change frequency on next halt or sleep */ wrmsrl(MSR_VIA_LONGHAUL, longhaul.val); - if (port22_en) { - ACPI_FLUSH_CPU_CACHE(); - /* Invoke C1 */ - halt(); - } else { - ACPI_FLUSH_CPU_CACHE(); - /* Invoke C3 */ - inb(cx_address); - /* Dummy op - must do something useless after P_LVL3 read */ - t = inl(acpi_fadt.xpm_tmr_blk.address); - } + ACPI_FLUSH_CPU_CACHE(); + /* Invoke C3 */ + inb(cx_address); + /* Dummy op - must do something useless after P_LVL3 read */ + t = inl(acpi_fadt.xpm_tmr_blk.address); /* Disable bus ratio bit */ local_irq_disable(); @@ -573,23 +567,16 @@ static acpi_status longhaul_walk_callback(acpi_handle obj_handle, static int enable_arbiter_disable(void) { struct pci_dev *dev; - int reg; u8 pci_cmd; /* Find PLE133 host bridge */ - reg = 0x78; dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0, NULL); - /* Find CLE266 host bridge */ - if (dev == NULL) { - reg = 0x76; - dev = pci_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_862X_0, NULL); - } if (dev != NULL) { /* Enable access to port 0x22 */ - pci_read_config_byte(dev, reg, &pci_cmd); + pci_read_config_byte(dev, 0x78, &pci_cmd); if ( !(pci_cmd & 1<<7) ) { pci_cmd |= 1<<7; - pci_write_config_byte(dev, reg, pci_cmd); + pci_write_config_byte(dev, 0x78, pci_cmd); } return 1; } @@ -693,24 +680,19 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) if (longhaul_version == TYPE_POWERSAVER) { /* Check ACPI support for C3 state */ cx = &pr->power.states[ACPI_STATE_C3]; - if (cx->address > 0 && - (cx->latency <= 1000 || ignore_latency != 0) ) { - goto print_support_type; - } - } - /* Check ACPI support for bus master arbiter disable */ - if (!pr->flags.bm_control) { - if (enable_arbiter_disable()) { - port22_en = 1; - } else { + if (cx->address == 0 || + (cx->latency > 1000 && ignore_latency == 0) ) goto err_acpi; - } - } -print_support_type: - if (!port22_en) { - printk (KERN_INFO PFX "Using ACPI support.\n"); + } else { - printk (KERN_INFO PFX "Using northbridge support.\n"); + /* Check ACPI support for bus master arbiter disable */ + if (!pr->flags.bm_control) { + if (!enable_arbiter_disable()) { + printk(KERN_ERR PFX "No ACPI support. No VT8601 host bridge. Aborting.\n"); + return -ENODEV; + } else + port22_en = 1; + } } ret = longhaul_get_ranges(); @@ -734,7 +716,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) return 0; err_acpi: - printk(KERN_ERR PFX "No ACPI support. No VT8601 or VT8623 northbridge. Aborting.\n"); + printk(KERN_ERR PFX "No ACPI support for CPU frequency changes.\n"); return -ENODEV; } diff --git a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index e8993baf3d14..7a9325349e94 100644 --- a/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/trunk/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c @@ -386,7 +386,7 @@ static int centrino_cpu_early_init_acpi(void) * than OS intended it to run at. Detect it and handle it cleanly. */ static int bios_with_sw_any_bug; -static int sw_any_bug_found(struct dmi_system_id *d) +static int __init sw_any_bug_found(struct dmi_system_id *d) { bios_with_sw_any_bug = 1; return 0; diff --git a/trunk/arch/i386/kernel/cpu/cyrix.c b/trunk/arch/i386/kernel/cpu/cyrix.c index c0c3b59de32c..f03b7f94c304 100644 --- a/trunk/arch/i386/kernel/cpu/cyrix.c +++ b/trunk/arch/i386/kernel/cpu/cyrix.c @@ -12,7 +12,7 @@ /* * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU */ -static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1) +static void __init do_cyrix_devid(unsigned char *dir0, unsigned char *dir1) { unsigned char ccr2, ccr3; unsigned long flags; @@ -52,25 +52,25 @@ static void __cpuinit do_cyrix_devid(unsigned char *dir0, unsigned char *dir1) * Actually since bugs.h doesn't even reference this perhaps someone should * fix the documentation ??? */ -static unsigned char Cx86_dir0_msb __cpuinitdata = 0; +static unsigned char Cx86_dir0_msb __initdata = 0; -static char Cx86_model[][9] __cpuinitdata = { +static char Cx86_model[][9] __initdata = { "Cx486", "Cx486", "5x86 ", "6x86", "MediaGX ", "6x86MX ", "M II ", "Unknown" }; -static char Cx486_name[][5] __cpuinitdata = { +static char Cx486_name[][5] __initdata = { "SLC", "DLC", "SLC2", "DLC2", "SRx", "DRx", "SRx2", "DRx2" }; -static char Cx486S_name[][4] __cpuinitdata = { +static char Cx486S_name[][4] __initdata = { "S", "S2", "Se", "S2e" }; -static char Cx486D_name[][4] __cpuinitdata = { +static char Cx486D_name[][4] __initdata = { "DX", "DX2", "?", "?", "?", "DX4" }; -static char Cx86_cb[] __cpuinitdata = "?.5x Core/Bus Clock"; -static char cyrix_model_mult1[] __cpuinitdata = "12??43"; -static char cyrix_model_mult2[] __cpuinitdata = "12233445"; +static char Cx86_cb[] __initdata = "?.5x Core/Bus Clock"; +static char cyrix_model_mult1[] __initdata = "12??43"; +static char cyrix_model_mult2[] __initdata = "12233445"; /* * Reset the slow-loop (SLOP) bit on the 686(L) which is set by some old @@ -82,7 +82,7 @@ static char cyrix_model_mult2[] __cpuinitdata = "12233445"; extern void calibrate_delay(void) __init; -static void __cpuinit check_cx686_slop(struct cpuinfo_x86 *c) +static void __init check_cx686_slop(struct cpuinfo_x86 *c) { unsigned long flags; @@ -107,7 +107,7 @@ static void __cpuinit check_cx686_slop(struct cpuinfo_x86 *c) } -static void __cpuinit set_cx86_reorder(void) +static void __init set_cx86_reorder(void) { u8 ccr3; @@ -122,7 +122,7 @@ static void __cpuinit set_cx86_reorder(void) setCx86(CX86_CCR3, ccr3); } -static void __cpuinit set_cx86_memwb(void) +static void __init set_cx86_memwb(void) { u32 cr0; @@ -137,7 +137,7 @@ static void __cpuinit set_cx86_memwb(void) setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14 ); } -static void __cpuinit set_cx86_inc(void) +static void __init set_cx86_inc(void) { unsigned char ccr3; @@ -158,7 +158,7 @@ static void __cpuinit set_cx86_inc(void) * Configure later MediaGX and/or Geode processor. */ -static void __cpuinit geode_configure(void) +static void __init geode_configure(void) { unsigned long flags; u8 ccr3, ccr4; @@ -184,14 +184,14 @@ static void __cpuinit geode_configure(void) #ifdef CONFIG_PCI -static struct pci_device_id __cpuinitdata cyrix_55x0[] = { +static struct pci_device_id __initdata cyrix_55x0[] = { { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510) }, { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520) }, { }, }; #endif -static void __cpuinit init_cyrix(struct cpuinfo_x86 *c) +static void __init init_cyrix(struct cpuinfo_x86 *c) { unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0; char *buf = c->x86_model_id; @@ -346,7 +346,7 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c) /* * Handle National Semiconductor branded processors */ -static void __cpuinit init_nsc(struct cpuinfo_x86 *c) +static void __init init_nsc(struct cpuinfo_x86 *c) { /* There may be GX1 processors in the wild that are branded * NSC and not Cyrix. @@ -394,7 +394,7 @@ static inline int test_cyrix_52div(void) return (unsigned char) (test >> 8) == 0x02; } -static void __cpuinit cyrix_identify(struct cpuinfo_x86 * c) +static void cyrix_identify(struct cpuinfo_x86 * c) { /* Detect Cyrix with disabled CPUID */ if ( c->x86 == 4 && test_cyrix_52div() ) { @@ -427,9 +427,10 @@ static void __cpuinit cyrix_identify(struct cpuinfo_x86 * c) local_irq_restore(flags); } } + generic_identify(c); } -static struct cpu_dev cyrix_cpu_dev __cpuinitdata = { +static struct cpu_dev cyrix_cpu_dev __initdata = { .c_vendor = "Cyrix", .c_ident = { "CyrixInstead" }, .c_init = init_cyrix, @@ -452,10 +453,11 @@ static int __init cyrix_exit_cpu(void) late_initcall(cyrix_exit_cpu); -static struct cpu_dev nsc_cpu_dev __cpuinitdata = { +static struct cpu_dev nsc_cpu_dev __initdata = { .c_vendor = "NSC", .c_ident = { "Geode by NSC" }, .c_init = init_nsc, + .c_identify = generic_identify, }; int __init nsc_init_cpu(void) diff --git a/trunk/arch/i386/kernel/cpu/intel.c b/trunk/arch/i386/kernel/cpu/intel.c index 94a95aa5227e..5a2e270924b1 100644 --- a/trunk/arch/i386/kernel/cpu/intel.c +++ b/trunk/arch/i386/kernel/cpu/intel.c @@ -198,7 +198,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) } -static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) +static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) { /* Intel PIII Tualatin. This comes in two flavours. * One has 256kb of cache, the other 512. We have no way @@ -263,6 +263,7 @@ static struct cpu_dev intel_cpu_dev __cpuinitdata = { }, }, .c_init = init_intel, + .c_identify = generic_identify, .c_size_cache = intel_size_cache, }; diff --git a/trunk/arch/i386/kernel/cpu/mcheck/Makefile b/trunk/arch/i386/kernel/cpu/mcheck/Makefile index f1ebe1c1c17a..30808f3d6715 100644 --- a/trunk/arch/i386/kernel/cpu/mcheck/Makefile +++ b/trunk/arch/i386/kernel/cpu/mcheck/Makefile @@ -1,2 +1,2 @@ -obj-y = mce.o k7.o p4.o p5.o p6.o winchip.o therm_throt.o +obj-y = mce.o k7.o p4.o p5.o p6.o winchip.o obj-$(CONFIG_X86_MCE_NONFATAL) += non-fatal.o diff --git a/trunk/arch/i386/kernel/cpu/mcheck/p4.c b/trunk/arch/i386/kernel/cpu/mcheck/p4.c index 504434a46011..b95f1b3d53aa 100644 --- a/trunk/arch/i386/kernel/cpu/mcheck/p4.c +++ b/trunk/arch/i386/kernel/cpu/mcheck/p4.c @@ -13,8 +13,6 @@ #include #include -#include - #include "mce.h" /* as supported by the P4/Xeon family */ @@ -46,12 +44,25 @@ static void unexpected_thermal_interrupt(struct pt_regs *regs) /* P4/Xeon Thermal transition interrupt handler */ static void intel_thermal_interrupt(struct pt_regs *regs) { - __u64 msr_val; + u32 l, h; + unsigned int cpu = smp_processor_id(); + static unsigned long next[NR_CPUS]; ack_APIC_irq(); - rdmsrl(MSR_IA32_THERM_STATUS, msr_val); - therm_throt_process(msr_val & 0x1); + if (time_after(next[cpu], jiffies)) + return; + + next[cpu] = jiffies + HZ*5; + rdmsr(MSR_IA32_THERM_STATUS, l, h); + if (l & 0x1) { + printk(KERN_EMERG "CPU%d: Temperature above threshold\n", cpu); + printk(KERN_EMERG "CPU%d: Running in modulated clock mode\n", + cpu); + add_taint(TAINT_MACHINE_CHECK); + } else { + printk(KERN_INFO "CPU%d: Temperature/speed normal\n", cpu); + } } /* Thermal interrupt handler for this CPU setup */ @@ -111,13 +122,10 @@ static void intel_init_thermal(struct cpuinfo_x86 *c) rdmsr (MSR_IA32_MISC_ENABLE, l, h); wrmsr (MSR_IA32_MISC_ENABLE, l | (1<<3), h); - + l = apic_read (APIC_LVTTHMR); apic_write_around (APIC_LVTTHMR, l & ~APIC_LVT_MASKED); printk (KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu); - - /* enable thermal throttle processing */ - atomic_set(&therm_throt_en, 1); return; } #endif /* CONFIG_X86_MCE_P4THERMAL */ diff --git a/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c b/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c deleted file mode 100644 index 4f43047de406..000000000000 --- a/trunk/arch/i386/kernel/cpu/mcheck/therm_throt.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * linux/arch/i386/kerne/cpu/mcheck/therm_throt.c - * - * Thermal throttle event support code (such as syslog messaging and rate - * limiting) that was factored out from x86_64 (mce_intel.c) and i386 (p4.c). - * This allows consistent reporting of CPU thermal throttle events. - * - * Maintains a counter in /sys that keeps track of the number of thermal - * events, such that the user knows how bad the thermal problem might be - * (since the logging to syslog and mcelog is rate limited). - * - * Author: Dmitriy Zavin (dmitriyz@google.com) - * - * Credits: Adapted from Zwane Mwaikambo's original code in mce_intel.c. - * Inspired by Ross Biro's and Al Borchers' counter code. - */ - -#include -#include -#include -#include -#include -#include - -/* How long to wait between reporting thermal events */ -#define CHECK_INTERVAL (300 * HZ) - -static DEFINE_PER_CPU(__u64, next_check) = INITIAL_JIFFIES; -static DEFINE_PER_CPU(unsigned long, thermal_throttle_count); -atomic_t therm_throt_en = ATOMIC_INIT(0); - -#ifdef CONFIG_SYSFS -#define define_therm_throt_sysdev_one_ro(_name) \ - static SYSDEV_ATTR(_name, 0444, therm_throt_sysdev_show_##_name, NULL) - -#define define_therm_throt_sysdev_show_func(name) \ -static ssize_t therm_throt_sysdev_show_##name(struct sys_device *dev, \ - char *buf) \ -{ \ - unsigned int cpu = dev->id; \ - ssize_t ret; \ - \ - preempt_disable(); /* CPU hotplug */ \ - if (cpu_online(cpu)) \ - ret = sprintf(buf, "%lu\n", \ - per_cpu(thermal_throttle_##name, cpu)); \ - else \ - ret = 0; \ - preempt_enable(); \ - \ - return ret; \ -} - -define_therm_throt_sysdev_show_func(count); -define_therm_throt_sysdev_one_ro(count); - -static struct attribute *thermal_throttle_attrs[] = { - &attr_count.attr, - NULL -}; - -static struct attribute_group thermal_throttle_attr_group = { - .attrs = thermal_throttle_attrs, - .name = "thermal_throttle" -}; -#endif /* CONFIG_SYSFS */ - -/*** - * therm_throt_process - Process thermal throttling event from interrupt - * @curr: Whether the condition is current or not (boolean), since the - * thermal interrupt normally gets called both when the thermal - * event begins and once the event has ended. - * - * This function is called by the thermal interrupt after the - * IRQ has been acknowledged. - * - * It will take care of rate limiting and printing messages to the syslog. - * - * Returns: 0 : Event should NOT be further logged, i.e. still in - * "timeout" from previous log message. - * 1 : Event should be logged further, and a message has been - * printed to the syslog. - */ -int therm_throt_process(int curr) -{ - unsigned int cpu = smp_processor_id(); - __u64 tmp_jiffs = get_jiffies_64(); - - if (curr) - __get_cpu_var(thermal_throttle_count)++; - - if (time_before64(tmp_jiffs, __get_cpu_var(next_check))) - return 0; - - __get_cpu_var(next_check) = tmp_jiffs + CHECK_INTERVAL; - - /* if we just entered the thermal event */ - if (curr) { - printk(KERN_CRIT "CPU%d: Temperature above threshold, " - "cpu clock throttled (total events = %lu)\n", cpu, - __get_cpu_var(thermal_throttle_count)); - - add_taint(TAINT_MACHINE_CHECK); - } else { - printk(KERN_CRIT "CPU%d: Temperature/speed normal\n", cpu); - } - - return 1; -} - -#ifdef CONFIG_SYSFS -/* Add/Remove thermal_throttle interface for CPU device */ -static __cpuinit int thermal_throttle_add_dev(struct sys_device * sys_dev) -{ - sysfs_create_group(&sys_dev->kobj, &thermal_throttle_attr_group); - return 0; -} - -#ifdef CONFIG_HOTPLUG_CPU -static __cpuinit int thermal_throttle_remove_dev(struct sys_device * sys_dev) -{ - sysfs_remove_group(&sys_dev->kobj, &thermal_throttle_attr_group); - return 0; -} - -/* Mutex protecting device creation against CPU hotplug */ -static DEFINE_MUTEX(therm_cpu_lock); - -/* Get notified when a cpu comes on/off. Be hotplug friendly. */ -static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb, - unsigned long action, - void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - struct sys_device *sys_dev; - - sys_dev = get_cpu_sysdev(cpu); - mutex_lock(&therm_cpu_lock); - switch (action) { - case CPU_ONLINE: - thermal_throttle_add_dev(sys_dev); - break; - case CPU_DEAD: - thermal_throttle_remove_dev(sys_dev); - break; - } - mutex_unlock(&therm_cpu_lock); - return NOTIFY_OK; -} - -static struct notifier_block thermal_throttle_cpu_notifier = -{ - .notifier_call = thermal_throttle_cpu_callback, -}; -#endif /* CONFIG_HOTPLUG_CPU */ - -static __init int thermal_throttle_init_device(void) -{ - unsigned int cpu = 0; - - if (!atomic_read(&therm_throt_en)) - return 0; - - register_hotcpu_notifier(&thermal_throttle_cpu_notifier); - -#ifdef CONFIG_HOTPLUG_CPU - mutex_lock(&therm_cpu_lock); -#endif - /* connect live CPUs to sysfs */ - for_each_online_cpu(cpu) - thermal_throttle_add_dev(get_cpu_sysdev(cpu)); -#ifdef CONFIG_HOTPLUG_CPU - mutex_unlock(&therm_cpu_lock); -#endif - - return 0; -} - -device_initcall(thermal_throttle_init_device); -#endif /* CONFIG_SYSFS */ diff --git a/trunk/arch/i386/kernel/cpu/nexgen.c b/trunk/arch/i386/kernel/cpu/nexgen.c index 8bf23cc80c63..ad87fa58058d 100644 --- a/trunk/arch/i386/kernel/cpu/nexgen.c +++ b/trunk/arch/i386/kernel/cpu/nexgen.c @@ -10,7 +10,7 @@ * to have CPUID. (Thanks to Herbert Oppmann) */ -static int __cpuinit deep_magic_nexgen_probe(void) +static int __init deep_magic_nexgen_probe(void) { int ret; @@ -27,20 +27,21 @@ static int __cpuinit deep_magic_nexgen_probe(void) return ret; } -static void __cpuinit init_nexgen(struct cpuinfo_x86 * c) +static void __init init_nexgen(struct cpuinfo_x86 * c) { c->x86_cache_size = 256; /* A few had 1 MB... */ } -static void __cpuinit nexgen_identify(struct cpuinfo_x86 * c) +static void __init nexgen_identify(struct cpuinfo_x86 * c) { /* Detect NexGen with old hypercode */ if ( deep_magic_nexgen_probe() ) { strcpy(c->x86_vendor_id, "NexGenDriven"); } + generic_identify(c); } -static struct cpu_dev nexgen_cpu_dev __cpuinitdata = { +static struct cpu_dev nexgen_cpu_dev __initdata = { .c_vendor = "Nexgen", .c_ident = { "NexGenDriven" }, .c_models = { diff --git a/trunk/arch/i386/kernel/cpu/proc.c b/trunk/arch/i386/kernel/cpu/proc.c index 76aac088a323..f54a15268ed7 100644 --- a/trunk/arch/i386/kernel/cpu/proc.c +++ b/trunk/arch/i386/kernel/cpu/proc.c @@ -46,8 +46,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* Intel-defined (#2) */ "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est", - "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL, - NULL, NULL, "dca", NULL, NULL, NULL, NULL, NULL, + "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* VIA/Cyrix/Centaur-defined */ diff --git a/trunk/arch/i386/kernel/cpu/rise.c b/trunk/arch/i386/kernel/cpu/rise.c index 9317f7414989..d08d5a2811c8 100644 --- a/trunk/arch/i386/kernel/cpu/rise.c +++ b/trunk/arch/i386/kernel/cpu/rise.c @@ -5,7 +5,7 @@ #include "cpu.h" -static void __cpuinit init_rise(struct cpuinfo_x86 *c) +static void __init init_rise(struct cpuinfo_x86 *c) { printk("CPU: Rise iDragon"); if (c->x86_model > 2) @@ -28,7 +28,7 @@ static void __cpuinit init_rise(struct cpuinfo_x86 *c) set_bit(X86_FEATURE_CX8, c->x86_capability); } -static struct cpu_dev rise_cpu_dev __cpuinitdata = { +static struct cpu_dev rise_cpu_dev __initdata = { .c_vendor = "Rise", .c_ident = { "RiseRiseRise" }, .c_models = { diff --git a/trunk/arch/i386/kernel/cpu/transmeta.c b/trunk/arch/i386/kernel/cpu/transmeta.c index 4056fb7d2cdf..7214c9b577ab 100644 --- a/trunk/arch/i386/kernel/cpu/transmeta.c +++ b/trunk/arch/i386/kernel/cpu/transmeta.c @@ -5,7 +5,7 @@ #include #include "cpu.h" -static void __cpuinit init_transmeta(struct cpuinfo_x86 *c) +static void __init init_transmeta(struct cpuinfo_x86 *c) { unsigned int cap_mask, uk, max, dummy; unsigned int cms_rev1, cms_rev2; @@ -85,9 +85,10 @@ static void __cpuinit init_transmeta(struct cpuinfo_x86 *c) #endif } -static void __cpuinit transmeta_identify(struct cpuinfo_x86 * c) +static void __init transmeta_identify(struct cpuinfo_x86 * c) { u32 xlvl; + generic_identify(c); /* Transmeta-defined flags: level 0x80860001 */ xlvl = cpuid_eax(0x80860000); @@ -97,7 +98,7 @@ static void __cpuinit transmeta_identify(struct cpuinfo_x86 * c) } } -static struct cpu_dev transmeta_cpu_dev __cpuinitdata = { +static struct cpu_dev transmeta_cpu_dev __initdata = { .c_vendor = "Transmeta", .c_ident = { "GenuineTMx86", "TransmetaCPU" }, .c_init = init_transmeta, diff --git a/trunk/arch/i386/kernel/cpu/umc.c b/trunk/arch/i386/kernel/cpu/umc.c index 1bf3f87e9c5b..2cd988f6dc55 100644 --- a/trunk/arch/i386/kernel/cpu/umc.c +++ b/trunk/arch/i386/kernel/cpu/umc.c @@ -5,8 +5,12 @@ /* UMC chips appear to be only either 386 or 486, so no special init takes place. */ +static void __init init_umc(struct cpuinfo_x86 * c) +{ + +} -static struct cpu_dev umc_cpu_dev __cpuinitdata = { +static struct cpu_dev umc_cpu_dev __initdata = { .c_vendor = "UMC", .c_ident = { "UMC UMC UMC" }, .c_models = { @@ -17,6 +21,7 @@ static struct cpu_dev umc_cpu_dev __cpuinitdata = { } }, }, + .c_init = init_umc, }; int __init umc_init_cpu(void) diff --git a/trunk/arch/i386/kernel/crash.c b/trunk/arch/i386/kernel/crash.c index 144b43288965..5b96f038367f 100644 --- a/trunk/arch/i386/kernel/crash.c +++ b/trunk/arch/i386/kernel/crash.c @@ -22,9 +22,6 @@ #include #include #include -#include -#include - #include @@ -89,32 +86,23 @@ static void crash_save_self(struct pt_regs *regs) { int cpu; - cpu = safe_smp_processor_id(); + cpu = smp_processor_id(); crash_save_this_cpu(regs, cpu); } #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) static atomic_t waiting_for_crash_ipi; -static int crash_nmi_callback(struct notifier_block *self, - unsigned long val, void *data) +static int crash_nmi_callback(struct pt_regs *regs, int cpu) { - struct pt_regs *regs; struct pt_regs fixed_regs; - int cpu; - - if (val != DIE_NMI_IPI) - return NOTIFY_OK; - - regs = ((struct die_args *)data)->regs; - cpu = raw_smp_processor_id(); /* Don't do anything if this handler is invoked on crashing cpu. * Otherwise, system will completely hang. Crashing cpu can get * an NMI if system was initially booted with nmi_watchdog parameter. */ if (cpu == crashing_cpu) - return NOTIFY_STOP; + return 1; local_irq_disable(); if (!user_mode_vm(regs)) { @@ -134,24 +122,16 @@ static int crash_nmi_callback(struct notifier_block *self, static void smp_send_nmi_allbutself(void) { - cpumask_t mask = cpu_online_map; - cpu_clear(safe_smp_processor_id(), mask); - if (!cpus_empty(mask)) - send_IPI_mask(mask, NMI_VECTOR); + send_IPI_allbutself(NMI_VECTOR); } -static struct notifier_block crash_nmi_nb = { - .notifier_call = crash_nmi_callback, -}; - static void nmi_shootdown_cpus(void) { unsigned long msecs; atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); /* Would it be better to replace the trap vector here? */ - if (register_die_notifier(&crash_nmi_nb)) - return; /* return what? */ + set_nmi_callback(crash_nmi_callback); /* Ensure the new callback function is set before sending * out the NMI */ @@ -189,7 +169,7 @@ void machine_crash_shutdown(struct pt_regs *regs) local_irq_disable(); /* Make a note of crashing cpu. Will be used in NMI callback.*/ - crashing_cpu = safe_smp_processor_id(); + crashing_cpu = smp_processor_id(); nmi_shootdown_cpus(); lapic_shutdown(); #if defined(CONFIG_X86_IO_APIC) diff --git a/trunk/arch/i386/kernel/efi.c b/trunk/arch/i386/kernel/efi.c index f9436989473c..fe158042110b 100644 --- a/trunk/arch/i386/kernel/efi.c +++ b/trunk/arch/i386/kernel/efi.c @@ -65,7 +65,7 @@ static unsigned long efi_rt_eflags; static DEFINE_SPINLOCK(efi_rt_lock); static pgd_t efi_bak_pg_dir_pointer[2]; -static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) +static void efi_call_phys_prelog(void) { unsigned long cr4; unsigned long temp; @@ -109,7 +109,7 @@ static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) load_gdt(cpu_gdt_descr); } -static void efi_call_phys_epilog(void) __releases(efi_rt_lock) +static void efi_call_phys_epilog(void) { unsigned long cr4; struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); diff --git a/trunk/arch/i386/kernel/entry.S b/trunk/arch/i386/kernel/entry.S index 5a63d6fdb70e..87f9f60b803b 100644 --- a/trunk/arch/i386/kernel/entry.S +++ b/trunk/arch/i386/kernel/entry.S @@ -76,15 +76,8 @@ DF_MASK = 0x00000400 NT_MASK = 0x00004000 VM_MASK = 0x00020000 -/* These are replaces for paravirtualization */ -#define DISABLE_INTERRUPTS cli -#define ENABLE_INTERRUPTS sti -#define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit -#define INTERRUPT_RETURN iret -#define GET_CR0_INTO_EAX movl %cr0, %eax - #ifdef CONFIG_PREEMPT -#define preempt_stop DISABLE_INTERRUPTS; TRACE_IRQS_OFF +#define preempt_stop cli; TRACE_IRQS_OFF #else #define preempt_stop #define resume_kernel restore_nocheck @@ -183,21 +176,18 @@ VM_MASK = 0x00020000 #define RING0_INT_FRAME \ CFI_STARTPROC simple;\ - CFI_SIGNAL_FRAME;\ CFI_DEF_CFA esp, 3*4;\ /*CFI_OFFSET cs, -2*4;*/\ CFI_OFFSET eip, -3*4 #define RING0_EC_FRAME \ CFI_STARTPROC simple;\ - CFI_SIGNAL_FRAME;\ CFI_DEF_CFA esp, 4*4;\ /*CFI_OFFSET cs, -2*4;*/\ CFI_OFFSET eip, -3*4 #define RING0_PTREGS_FRAME \ CFI_STARTPROC simple;\ - CFI_SIGNAL_FRAME;\ CFI_DEF_CFA esp, OLDESP-EBX;\ /*CFI_OFFSET cs, CS-OLDESP;*/\ CFI_OFFSET eip, EIP-OLDESP;\ @@ -243,11 +233,10 @@ ret_from_intr: check_userspace: movl EFLAGS(%esp), %eax # mix EFLAGS and CS movb CS(%esp), %al - andl $(VM_MASK | SEGMENT_RPL_MASK), %eax - cmpl $USER_RPL, %eax - jb resume_kernel # not returning to v8086 or userspace + testl $(VM_MASK | 3), %eax + jz resume_kernel ENTRY(resume_userspace) - DISABLE_INTERRUPTS # make sure we don't miss an interrupt + cli # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret movl TI_flags(%ebp), %ecx @@ -258,7 +247,7 @@ ENTRY(resume_userspace) #ifdef CONFIG_PREEMPT ENTRY(resume_kernel) - DISABLE_INTERRUPTS + cli cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? jnz restore_nocheck need_resched: @@ -278,7 +267,6 @@ need_resched: # sysenter call handler stub ENTRY(sysenter_entry) CFI_STARTPROC simple - CFI_SIGNAL_FRAME CFI_DEF_CFA esp, 0 CFI_REGISTER esp, ebp movl TSS_sysenter_esp0(%esp),%esp @@ -287,7 +275,7 @@ sysenter_past_esp: * No need to follow this irqs on/off section: the syscall * disabled irqs and here we enable it straight after entry: */ - ENABLE_INTERRUPTS + sti pushl $(__USER_DS) CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET ss, 0*/ @@ -332,7 +320,7 @@ sysenter_past_esp: jae syscall_badsys call *sys_call_table(,%eax,4) movl %eax,EAX(%esp) - DISABLE_INTERRUPTS + cli TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx testw $_TIF_ALLWORK_MASK, %cx @@ -342,7 +330,8 @@ sysenter_past_esp: movl OLDESP(%esp), %ecx xorl %ebp,%ebp TRACE_IRQS_ON - ENABLE_INTERRUPTS_SYSEXIT + sti + sysexit CFI_ENDPROC @@ -367,7 +356,7 @@ syscall_call: call *sys_call_table(,%eax,4) movl %eax,EAX(%esp) # store the return value syscall_exit: - DISABLE_INTERRUPTS # make sure we don't miss an interrupt + cli # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret TRACE_IRQS_OFF @@ -382,8 +371,8 @@ restore_all: # See comments in process.c:copy_thread() for details. movb OLDSS(%esp), %ah movb CS(%esp), %al - andl $(VM_MASK | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax - cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax + andl $(VM_MASK | (4 << 8) | 3), %eax + cmpl $((4 << 8) | 3), %eax CFI_REMEMBER_STATE je ldt_ss # returning to user-space with LDT SS restore_nocheck: @@ -392,11 +381,11 @@ restore_nocheck_notrace: RESTORE_REGS addl $4, %esp CFI_ADJUST_CFA_OFFSET -4 -1: INTERRUPT_RETURN +1: iret .section .fixup,"ax" iret_exc: TRACE_IRQS_ON - ENABLE_INTERRUPTS + sti pushl $0 # no error code pushl $do_iret_error jmp error_code @@ -420,7 +409,7 @@ ldt_ss: * dosemu and wine happy. */ subl $8, %esp # reserve space for switch16 pointer CFI_ADJUST_CFA_OFFSET 8 - DISABLE_INTERRUPTS + cli TRACE_IRQS_OFF movl %esp, %eax /* Set up the 16bit stack frame with switch32 pointer on top, @@ -430,7 +419,7 @@ ldt_ss: TRACE_IRQS_IRET RESTORE_REGS lss 20+4(%esp), %esp # switch to 16bit stack -1: INTERRUPT_RETURN +1: iret .section __ex_table,"a" .align 4 .long 1b,iret_exc @@ -445,7 +434,7 @@ work_pending: jz work_notifysig work_resched: call schedule - DISABLE_INTERRUPTS # make sure we don't miss an interrupt + cli # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret TRACE_IRQS_OFF @@ -501,7 +490,7 @@ syscall_exit_work: testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl jz work_pending TRACE_IRQS_ON - ENABLE_INTERRUPTS # could let do_syscall_trace() call + sti # could let do_syscall_trace() call # schedule() instead movl %esp, %eax movl $1, %edx @@ -602,9 +591,11 @@ ENTRY(name) \ /* The include is where all of the SMP etc. interrupts come from */ #include "entry_arch.h" -KPROBE_ENTRY(page_fault) - RING0_EC_FRAME - pushl $do_page_fault +ENTRY(divide_error) + RING0_INT_FRAME + pushl $0 # no error code + CFI_ADJUST_CFA_OFFSET 4 + pushl $do_divide_error CFI_ADJUST_CFA_OFFSET 4 ALIGN error_code: @@ -654,7 +645,6 @@ error_code: call *%edi jmp ret_from_exception CFI_ENDPROC -KPROBE_END(page_fault) ENTRY(coprocessor_error) RING0_INT_FRAME @@ -679,7 +669,7 @@ ENTRY(device_not_available) pushl $-1 # mark this as an int CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL - GET_CR0_INTO_EAX + movl %cr0, %eax testl $0x4, %eax # EM (math emulation bit) jne device_not_available_emulate preempt_stop @@ -712,15 +702,9 @@ device_not_available_emulate: jne ok; \ label: \ movl TSS_sysenter_esp0+offset(%esp),%esp; \ - CFI_DEF_CFA esp, 0; \ - CFI_UNDEFINED eip; \ pushfl; \ - CFI_ADJUST_CFA_OFFSET 4; \ pushl $__KERNEL_CS; \ - CFI_ADJUST_CFA_OFFSET 4; \ - pushl $sysenter_past_esp; \ - CFI_ADJUST_CFA_OFFSET 4; \ - CFI_REL_OFFSET eip, 0 + pushl $sysenter_past_esp KPROBE_ENTRY(debug) RING0_INT_FRAME @@ -736,8 +720,7 @@ debug_stack_correct: call do_debug jmp ret_from_exception CFI_ENDPROC -KPROBE_END(debug) - + .previous .text /* * NMI is doubly nasty. It can happen _while_ we're handling * a debug fault, and the debug fault hasn't yet been able to @@ -746,7 +729,7 @@ KPROBE_END(debug) * check whether we got an NMI on the debug path where the debug * fault happened on the sysenter path. */ -KPROBE_ENTRY(nmi) +ENTRY(nmi) RING0_INT_FRAME pushl %eax CFI_ADJUST_CFA_OFFSET 4 @@ -771,7 +754,6 @@ KPROBE_ENTRY(nmi) cmpl $sysenter_entry,12(%esp) je nmi_debug_stack_check nmi_stack_correct: - /* We have a RING0_INT_FRAME here */ pushl %eax CFI_ADJUST_CFA_OFFSET 4 SAVE_ALL @@ -782,12 +764,9 @@ nmi_stack_correct: CFI_ENDPROC nmi_stack_fixup: - RING0_INT_FRAME FIX_STACK(12,nmi_stack_correct, 1) jmp nmi_stack_correct - nmi_debug_stack_check: - /* We have a RING0_INT_FRAME here */ cmpw $__KERNEL_CS,16(%esp) jne nmi_stack_correct cmpl $debug,(%esp) @@ -798,10 +777,8 @@ nmi_debug_stack_check: jmp nmi_stack_correct nmi_16bit_stack: - /* We have a RING0_INT_FRAME here. - * - * create the pointer to lss back - */ + RING0_INT_FRAME + /* create the pointer to lss back */ pushl %ss CFI_ADJUST_CFA_OFFSET 4 pushl %esp @@ -822,13 +799,12 @@ nmi_16bit_stack: call do_nmi RESTORE_REGS lss 12+4(%esp), %esp # back to 16bit stack -1: INTERRUPT_RETURN +1: iret CFI_ENDPROC .section __ex_table,"a" .align 4 .long 1b,iret_exc .previous -KPROBE_END(nmi) KPROBE_ENTRY(int3) RING0_INT_FRAME @@ -840,7 +816,7 @@ KPROBE_ENTRY(int3) call do_int3 jmp ret_from_exception CFI_ENDPROC -KPROBE_END(int3) + .previous .text ENTRY(overflow) RING0_INT_FRAME @@ -905,7 +881,7 @@ KPROBE_ENTRY(general_protection) CFI_ADJUST_CFA_OFFSET 4 jmp error_code CFI_ENDPROC -KPROBE_END(general_protection) + .previous .text ENTRY(alignment_check) RING0_EC_FRAME @@ -914,14 +890,13 @@ ENTRY(alignment_check) jmp error_code CFI_ENDPROC -ENTRY(divide_error) - RING0_INT_FRAME - pushl $0 # no error code - CFI_ADJUST_CFA_OFFSET 4 - pushl $do_divide_error +KPROBE_ENTRY(page_fault) + RING0_EC_FRAME + pushl $do_page_fault CFI_ADJUST_CFA_OFFSET 4 jmp error_code CFI_ENDPROC + .previous .text #ifdef CONFIG_X86_MCE ENTRY(machine_check) @@ -974,19 +949,6 @@ ENTRY(arch_unwind_init_running) ENDPROC(arch_unwind_init_running) #endif -ENTRY(kernel_thread_helper) - pushl $0 # fake return address for unwinder - CFI_STARTPROC - movl %edx,%eax - push %edx - CFI_ADJUST_CFA_OFFSET 4 - call *%ebx - push %eax - CFI_ADJUST_CFA_OFFSET 4 - call do_exit - CFI_ENDPROC -ENDPROC(kernel_thread_helper) - .section .rodata,"a" #include "syscall_table.S" diff --git a/trunk/arch/i386/kernel/head.S b/trunk/arch/i386/kernel/head.S index be9d883c62ce..a6b8bd89aa27 100644 --- a/trunk/arch/i386/kernel/head.S +++ b/trunk/arch/i386/kernel/head.S @@ -371,65 +371,8 @@ rp_sidt: addl $8,%edi dec %ecx jne rp_sidt - -.macro set_early_handler handler,trapno - lea \handler,%edx - movl $(__KERNEL_CS << 16),%eax - movw %dx,%ax - movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ - lea idt_table,%edi - movl %eax,8*\trapno(%edi) - movl %edx,8*\trapno+4(%edi) -.endm - - set_early_handler handler=early_divide_err,trapno=0 - set_early_handler handler=early_illegal_opcode,trapno=6 - set_early_handler handler=early_protection_fault,trapno=13 - set_early_handler handler=early_page_fault,trapno=14 - ret -early_divide_err: - xor %edx,%edx - pushl $0 /* fake errcode */ - jmp early_fault - -early_illegal_opcode: - movl $6,%edx - pushl $0 /* fake errcode */ - jmp early_fault - -early_protection_fault: - movl $13,%edx - jmp early_fault - -early_page_fault: - movl $14,%edx - jmp early_fault - -early_fault: - cld -#ifdef CONFIG_PRINTK - movl $(__KERNEL_DS),%eax - movl %eax,%ds - movl %eax,%es - cmpl $2,early_recursion_flag - je hlt_loop - incl early_recursion_flag - movl %cr2,%eax - pushl %eax - pushl %edx /* trapno */ - pushl $fault_msg -#ifdef CONFIG_EARLY_PRINTK - call early_printk -#else - call printk -#endif -#endif -hlt_loop: - hlt - jmp hlt_loop - /* This is the default interrupt "handler" :-) */ ALIGN ignore_int: @@ -443,9 +386,6 @@ ignore_int: movl $(__KERNEL_DS),%eax movl %eax,%ds movl %eax,%es - cmpl $2,early_recursion_flag - je hlt_loop - incl early_recursion_flag pushl 16(%esp) pushl 24(%esp) pushl 32(%esp) @@ -491,16 +431,9 @@ ENTRY(stack_start) ready: .byte 0 -early_recursion_flag: - .long 0 - int_msg: .asciz "Unknown interrupt or fault at EIP %p %p %p\n" -fault_msg: - .ascii "Int %d: CR2 %p err %p EIP %p CS %p flags %p\n" - .asciz "Stack: %p %p %p %p %p %p %p %p\n" - /* * The IDT and GDT 'descriptors' are a strange 48-bit object * only used by the lidt and lgdt instructions. They are not diff --git a/trunk/arch/i386/kernel/i8237.c b/trunk/arch/i386/kernel/i8237.c index 6f508e8d7c57..c36d1c006c2f 100644 --- a/trunk/arch/i386/kernel/i8237.c +++ b/trunk/arch/i386/kernel/i8237.c @@ -2,11 +2,6 @@ * i8237.c: 8237A DMA controller suspend functions. * * Written by Pierre Ossman, 2005. - * - * 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. */ #include diff --git a/trunk/arch/i386/kernel/i8259.c b/trunk/arch/i386/kernel/i8259.c index ea5f4e7958d8..d4756d154f47 100644 --- a/trunk/arch/i386/kernel/i8259.c +++ b/trunk/arch/i386/kernel/i8259.c @@ -45,8 +45,6 @@ static void end_8259A_irq (unsigned int irq) #define shutdown_8259A_irq disable_8259A_irq -static int i8259A_auto_eoi; - static void mask_and_ack_8259A(unsigned int); unsigned int startup_8259A_irq(unsigned int irq) @@ -255,7 +253,7 @@ static void save_ELCR(char *trigger) static int i8259A_resume(struct sys_device *dev) { - init_8259A(i8259A_auto_eoi); + init_8259A(0); restore_ELCR(irq_trigger); return 0; } @@ -303,8 +301,6 @@ void init_8259A(int auto_eoi) { unsigned long flags; - i8259A_auto_eoi = auto_eoi; - spin_lock_irqsave(&i8259A_lock, flags); outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ diff --git a/trunk/arch/i386/kernel/io_apic.c b/trunk/arch/i386/kernel/io_apic.c index fd0df75cfbda..4fb32c551fe0 100644 --- a/trunk/arch/i386/kernel/io_apic.c +++ b/trunk/arch/i386/kernel/io_apic.c @@ -40,7 +40,6 @@ #include #include -#include #include "io_ports.h" @@ -66,7 +65,7 @@ int sis_apic_bug = -1; */ int nr_ioapic_registers[MAX_IO_APICS]; -static int disable_timer_pin_1 __initdata; +int disable_timer_pin_1 __initdata; /* * Rough estimation of how many shared IRQs there are, can @@ -94,34 +93,6 @@ int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1}; #define vector_to_irq(vector) (vector) #endif - -union entry_union { - struct { u32 w1, w2; }; - struct IO_APIC_route_entry entry; -}; - -static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) -{ - union entry_union eu; - unsigned long flags; - spin_lock_irqsave(&ioapic_lock, flags); - eu.w1 = io_apic_read(apic, 0x10 + 2 * pin); - eu.w2 = io_apic_read(apic, 0x11 + 2 * pin); - spin_unlock_irqrestore(&ioapic_lock, flags); - return eu.entry; -} - -static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) -{ - unsigned long flags; - union entry_union eu; - eu.entry = e; - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apic, 0x10 + 2*pin, eu.w1); - io_apic_write(apic, 0x11 + 2*pin, eu.w2); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - /* * The common case is 1:1 IRQ<->pin mappings. Sometimes there are * shared ISA-space IRQs, so we have to support them. We are super @@ -229,9 +200,13 @@ static void unmask_IO_APIC_irq (unsigned int irq) static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) { struct IO_APIC_route_entry entry; + unsigned long flags; /* Check delivery_mode to be sure we're not clearing an SMI pin */ - entry = ioapic_read_entry(apic, pin); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); if (entry.delivery_mode == dest_SMI) return; @@ -240,7 +215,10 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) */ memset(&entry, 0, sizeof(entry)); entry.mask = 1; - ioapic_write_entry(apic, pin, entry); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0)); + io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1)); + spin_unlock_irqrestore(&ioapic_lock, flags); } static void clear_IO_APIC (void) @@ -1305,8 +1283,9 @@ static void __init setup_IO_APIC_irqs(void) if (!apic && (irq < 16)) disable_8259A_irq(irq); } - ioapic_write_entry(apic, pin, entry); spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); + io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); set_native_irq_info(irq, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -1322,6 +1301,7 @@ static void __init setup_IO_APIC_irqs(void) static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, int vector) { struct IO_APIC_route_entry entry; + unsigned long flags; memset(&entry,0,sizeof(entry)); @@ -1351,7 +1331,10 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in /* * Add it to the IO-APIC irq-routing table: */ - ioapic_write_entry(apic, pin, entry); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); + io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); + spin_unlock_irqrestore(&ioapic_lock, flags); enable_8259A_irq(0); } @@ -1461,7 +1444,10 @@ void __init print_IO_APIC(void) for (i = 0; i <= reg_01.bits.entries; i++) { struct IO_APIC_route_entry entry; - entry = ioapic_read_entry(apic, i); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2); + *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2); + spin_unlock_irqrestore(&ioapic_lock, flags); printk(KERN_DEBUG " %02x %03X %02X ", i, @@ -1680,7 +1666,10 @@ static void __init enable_IO_APIC(void) /* See if any of the pins is in ExtINT mode */ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { struct IO_APIC_route_entry entry; - entry = ioapic_read_entry(apic, pin); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); /* If the interrupt line is enabled and in ExtInt mode @@ -1737,6 +1726,7 @@ void disable_IO_APIC(void) */ if (ioapic_i8259.pin != -1) { struct IO_APIC_route_entry entry; + unsigned long flags; memset(&entry, 0, sizeof(entry)); entry.mask = 0; /* Enabled */ @@ -1753,7 +1743,12 @@ void disable_IO_APIC(void) /* * Add it to the IO-APIC irq-routing table: */ - ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin, + *(((int *)&entry)+1)); + io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin, + *(((int *)&entry)+0)); + spin_unlock_irqrestore(&ioapic_lock, flags); } disconnect_bsp_APIC(ioapic_i8259.pin != -1); } @@ -2218,13 +2213,17 @@ static inline void unlock_ExtINT_logic(void) int apic, pin, i; struct IO_APIC_route_entry entry0, entry1; unsigned char save_control, save_freq_select; + unsigned long flags; pin = find_isa_irq_pin(8, mp_INT); apic = find_isa_irq_apic(8, mp_INT); if (pin == -1) return; - entry0 = ioapic_read_entry(apic, pin); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int *)&entry0) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + *(((int *)&entry0) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); clear_IO_APIC_pin(apic, pin); memset(&entry1, 0, sizeof(entry1)); @@ -2237,7 +2236,10 @@ static inline void unlock_ExtINT_logic(void) entry1.trigger = 0; entry1.vector = 0; - ioapic_write_entry(apic, pin, entry1); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry1) + 1)); + io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry1) + 0)); + spin_unlock_irqrestore(&ioapic_lock, flags); save_control = CMOS_READ(RTC_CONTROL); save_freq_select = CMOS_READ(RTC_FREQ_SELECT); @@ -2256,7 +2258,10 @@ static inline void unlock_ExtINT_logic(void) CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); clear_IO_APIC_pin(apic, pin); - ioapic_write_entry(apic, pin, entry0); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry0) + 1)); + io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry0) + 0)); + spin_unlock_irqrestore(&ioapic_lock, flags); } int timer_uses_ioapic_pin_0; @@ -2456,12 +2461,17 @@ static int ioapic_suspend(struct sys_device *dev, pm_message_t state) { struct IO_APIC_route_entry *entry; struct sysfs_ioapic_data *data; + unsigned long flags; int i; data = container_of(dev, struct sysfs_ioapic_data, dev); entry = data->entry; - for (i = 0; i < nr_ioapic_registers[dev->id]; i ++) - entry[i] = ioapic_read_entry(dev->id, i); + spin_lock_irqsave(&ioapic_lock, flags); + for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { + *(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i); + *(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i); + } + spin_unlock_irqrestore(&ioapic_lock, flags); return 0; } @@ -2483,9 +2493,11 @@ static int ioapic_resume(struct sys_device *dev) reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid; io_apic_write(dev->id, 0, reg_00.raw); } + for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { + io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1)); + io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0)); + } spin_unlock_irqrestore(&ioapic_lock, flags); - for (i = 0; i < nr_ioapic_registers[dev->id]; i ++) - ioapic_write_entry(dev->id, i, entry[i]); return 0; } @@ -2682,8 +2694,9 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a if (!ioapic && (irq < 16)) disable_8259A_irq(irq); - ioapic_write_entry(ioapic, pin, entry); spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); + io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); @@ -2691,25 +2704,3 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a } #endif /* CONFIG_ACPI */ - -static int __init parse_disable_timer_pin_1(char *arg) -{ - disable_timer_pin_1 = 1; - return 0; -} -early_param("disable_timer_pin_1", parse_disable_timer_pin_1); - -static int __init parse_enable_timer_pin_1(char *arg) -{ - disable_timer_pin_1 = -1; - return 0; -} -early_param("enable_timer_pin_1", parse_enable_timer_pin_1); - -static int __init parse_noapic(char *arg) -{ - /* disable IO-APIC */ - disable_ioapic_setup(); - return 0; -} -early_param("noapic", parse_noapic); diff --git a/trunk/arch/i386/kernel/kprobes.c b/trunk/arch/i386/kernel/kprobes.c index d98e44b16fe2..afe6505ca0b3 100644 --- a/trunk/arch/i386/kernel/kprobes.c +++ b/trunk/arch/i386/kernel/kprobes.c @@ -230,20 +230,20 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { unsigned long *sara = (unsigned long *)®s->esp; + struct kretprobe_instance *ri; - struct kretprobe_instance *ri; - - if ((ri = get_free_rp_inst(rp)) != NULL) { - ri->rp = rp; - ri->task = current; + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; ri->ret_addr = (kprobe_opcode_t *) *sara; /* Replace the return addr with trampoline addr */ *sara = (unsigned long) &kretprobe_trampoline; - add_rp_inst(ri); - } else { - rp->nmissed++; - } + + add_rp_inst(ri); + } else { + rp->nmissed++; + } } /* @@ -359,7 +359,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) void __kprobes kretprobe_trampoline_holder(void) { asm volatile ( ".global kretprobe_trampoline\n" - "kretprobe_trampoline: \n" + "kretprobe_trampoline: \n" " pushf\n" /* skip cs, eip, orig_eax, es, ds */ " subl $20, %esp\n" @@ -395,15 +395,14 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) */ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *node, *tmp; + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; - INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); - head = kretprobe_inst_table_head(current); + head = kretprobe_inst_table_head(current); /* * It is possible to have multiple instances associated with a given @@ -414,14 +413,14 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) * We can handle this because: * - instances are always inserted at the head of the list * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the + * function, the first instance's ret_addr will point to the * real return address, and all the rest will point to * kretprobe_trampoline */ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { - if (ri->task != current) + if (ri->task != current) /* another task is sharing our hash bucket */ - continue; + continue; if (ri->rp && ri->rp->handler){ __get_cpu_var(current_kprobe) = &ri->rp->kp; @@ -430,7 +429,7 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) } orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); + recycle_rp_inst(ri); if (orig_ret_address != trampoline_address) /* @@ -445,10 +444,6 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); - hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } return (void*)orig_ret_address; } diff --git a/trunk/arch/i386/kernel/machine_kexec.c b/trunk/arch/i386/kernel/machine_kexec.c index 91966bafb3dc..6b1ae6ba76f0 100644 --- a/trunk/arch/i386/kernel/machine_kexec.c +++ b/trunk/arch/i386/kernel/machine_kexec.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -21,13 +20,70 @@ #include #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) -static u32 kexec_pgd[1024] PAGE_ALIGNED; -#ifdef CONFIG_X86_PAE -static u32 kexec_pmd0[1024] PAGE_ALIGNED; -static u32 kexec_pmd1[1024] PAGE_ALIGNED; + +#define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) +#define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) +#define L2_ATTR (_PAGE_PRESENT) + +#define LEVEL0_SIZE (1UL << 12UL) + +#ifndef CONFIG_X86_PAE +#define LEVEL1_SIZE (1UL << 22UL) +static u32 pgtable_level1[1024] PAGE_ALIGNED; + +static void identity_map_page(unsigned long address) +{ + unsigned long level1_index, level2_index; + u32 *pgtable_level2; + + /* Find the current page table */ + pgtable_level2 = __va(read_cr3()); + + /* Find the indexes of the physical address to identity map */ + level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE; + level2_index = address / LEVEL1_SIZE; + + /* Identity map the page table entry */ + pgtable_level1[level1_index] = address | L0_ATTR; + pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR; + + /* Flush the tlb so the new mapping takes effect. + * Global tlb entries are not flushed but that is not an issue. + */ + load_cr3(pgtable_level2); +} + +#else +#define LEVEL1_SIZE (1UL << 21UL) +#define LEVEL2_SIZE (1UL << 30UL) +static u64 pgtable_level1[512] PAGE_ALIGNED; +static u64 pgtable_level2[512] PAGE_ALIGNED; + +static void identity_map_page(unsigned long address) +{ + unsigned long level1_index, level2_index, level3_index; + u64 *pgtable_level3; + + /* Find the current page table */ + pgtable_level3 = __va(read_cr3()); + + /* Find the indexes of the physical address to identity map */ + level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE; + level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE; + level3_index = address / LEVEL2_SIZE; + + /* Identity map the page table entry */ + pgtable_level1[level1_index] = address | L0_ATTR; + pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR; + set_64bit(&pgtable_level3[level3_index], + __pa(pgtable_level2) | L2_ATTR); + + /* Flush the tlb so the new mapping takes effect. + * Global tlb entries are not flushed but that is not an issue. + */ + load_cr3(pgtable_level3); +} #endif -static u32 kexec_pte0[1024] PAGE_ALIGNED; -static u32 kexec_pte1[1024] PAGE_ALIGNED; static void set_idt(void *newidt, __u16 limit) { @@ -71,6 +127,16 @@ static void load_segments(void) #undef __STR } +typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)( + unsigned long indirection_page, + unsigned long reboot_code_buffer, + unsigned long start_address, + unsigned int has_pae) ATTRIB_NORET; + +extern const unsigned char relocate_new_kernel[]; +extern void relocate_new_kernel_end(void); +extern const unsigned int relocate_new_kernel_size; + /* * A architecture hook called to validate the * proposed image and prepare the control pages @@ -103,29 +169,25 @@ void machine_kexec_cleanup(struct kimage *image) */ NORET_TYPE void machine_kexec(struct kimage *image) { - unsigned long page_list[PAGES_NR]; - void *control_page; + unsigned long page_list; + unsigned long reboot_code_buffer; + + relocate_new_kernel_t rnk; /* Interrupts aren't acceptable while we reboot */ local_irq_disable(); - control_page = page_address(image->control_code_page); - memcpy(control_page, relocate_kernel, PAGE_SIZE); - - page_list[PA_CONTROL_PAGE] = __pa(control_page); - page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; - page_list[PA_PGD] = __pa(kexec_pgd); - page_list[VA_PGD] = (unsigned long)kexec_pgd; -#ifdef CONFIG_X86_PAE - page_list[PA_PMD_0] = __pa(kexec_pmd0); - page_list[VA_PMD_0] = (unsigned long)kexec_pmd0; - page_list[PA_PMD_1] = __pa(kexec_pmd1); - page_list[VA_PMD_1] = (unsigned long)kexec_pmd1; -#endif - page_list[PA_PTE_0] = __pa(kexec_pte0); - page_list[VA_PTE_0] = (unsigned long)kexec_pte0; - page_list[PA_PTE_1] = __pa(kexec_pte1); - page_list[VA_PTE_1] = (unsigned long)kexec_pte1; + /* Compute some offsets */ + reboot_code_buffer = page_to_pfn(image->control_code_page) + << PAGE_SHIFT; + page_list = image->head; + + /* Set up an identity mapping for the reboot_code_buffer */ + identity_map_page(reboot_code_buffer); + + /* copy it out */ + memcpy((void *)reboot_code_buffer, relocate_new_kernel, + relocate_new_kernel_size); /* The segment registers are funny things, they have both a * visible and an invisible part. Whenever the visible part is @@ -144,28 +206,6 @@ NORET_TYPE void machine_kexec(struct kimage *image) set_idt(phys_to_virt(0),0); /* now call it */ - relocate_kernel((unsigned long)image->head, (unsigned long)page_list, - image->start, cpu_has_pae); -} - -/* crashkernel=size@addr specifies the location to reserve for - * a crash kernel. By reserving this memory we guarantee - * that linux never sets it up as a DMA target. - * Useful for holding code to do something appropriate - * after a kernel panic. - */ -static int __init parse_crashkernel(char *arg) -{ - unsigned long size, base; - size = memparse(arg, &arg); - if (*arg == '@') { - base = memparse(arg+1, &arg); - /* FIXME: Do I want a sanity check - * to validate the memory range? - */ - crashk_res.start = base; - crashk_res.end = base + size - 1; - } - return 0; + rnk = (relocate_new_kernel_t) reboot_code_buffer; + (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae); } -early_param("crashkernel", parse_crashkernel); diff --git a/trunk/arch/i386/kernel/mca.c b/trunk/arch/i386/kernel/mca.c index eb57a851789d..cd5456f14af4 100644 --- a/trunk/arch/i386/kernel/mca.c +++ b/trunk/arch/i386/kernel/mca.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -415,8 +414,7 @@ subsys_initcall(mca_init); /*--------------------------------------------------------------------*/ -static __kprobes void -mca_handle_nmi_device(struct mca_device *mca_dev, int check_flag) +static void mca_handle_nmi_device(struct mca_device *mca_dev, int check_flag) { int slot = mca_dev->slot; @@ -446,7 +444,7 @@ mca_handle_nmi_device(struct mca_device *mca_dev, int check_flag) /*--------------------------------------------------------------------*/ -static int __kprobes mca_handle_nmi_callback(struct device *dev, void *data) +static int mca_handle_nmi_callback(struct device *dev, void *data) { struct mca_device *mca_dev = to_mca_device(dev); unsigned char pos5; @@ -464,7 +462,7 @@ static int __kprobes mca_handle_nmi_callback(struct device *dev, void *data) return 0; } -void __kprobes mca_handle_nmi(void) +void mca_handle_nmi(void) { /* First try - scan the various adapters and see if a specific * adapter was responsible for the error. diff --git a/trunk/arch/i386/kernel/microcode.c b/trunk/arch/i386/kernel/microcode.c index 9b9479768d5e..40b44cc0d14b 100644 --- a/trunk/arch/i386/kernel/microcode.c +++ b/trunk/arch/i386/kernel/microcode.c @@ -2,7 +2,6 @@ * Intel CPU Microcode Update Driver for Linux * * Copyright (C) 2000-2004 Tigran Aivazian - * 2006 Shaohua Li * * This driver allows to upgrade microcode on Intel processors * belonging to IA-32 family - PentiumPro, Pentium II, @@ -83,9 +82,6 @@ #include #include #include -#include -#include -#include #include #include @@ -95,6 +91,9 @@ MODULE_DESCRIPTION("Intel CPU (IA-32) Microcode Update Driver"); MODULE_AUTHOR("Tigran Aivazian "); MODULE_LICENSE("GPL"); +static int verbose; +module_param(verbose, int, 0644); + #define MICROCODE_VERSION "1.14a" #define DEFAULT_UCODE_DATASIZE (2000) /* 2000 bytes */ @@ -121,40 +120,55 @@ static DEFINE_SPINLOCK(microcode_update_lock); /* no concurrent ->write()s are allowed on /dev/cpu/microcode */ static DEFINE_MUTEX(microcode_mutex); +static void __user *user_buffer; /* user area microcode data buffer */ +static unsigned int user_buffer_size; /* it's size */ + +typedef enum mc_error_code { + MC_SUCCESS = 0, + MC_IGNORED = 1, + MC_NOTFOUND = 2, + MC_MARKED = 3, + MC_ALLOCATED = 4, +} mc_error_code_t; + static struct ucode_cpu_info { - int valid; unsigned int sig; - unsigned int pf; + unsigned int pf, orig_pf; unsigned int rev; + unsigned int cksum; + mc_error_code_t err; microcode_t *mc; } ucode_cpu_info[NR_CPUS]; + +static int microcode_open (struct inode *unused1, struct file *unused2) +{ + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; +} -static void collect_cpu_info(int cpu_num) +static void collect_cpu_info (void *unused) { + int cpu_num = smp_processor_id(); struct cpuinfo_x86 *c = cpu_data + cpu_num; struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; unsigned int val[2]; - /* We should bind the task to the CPU */ - BUG_ON(raw_smp_processor_id() != cpu_num); - uci->pf = uci->rev = 0; + uci->sig = uci->pf = uci->rev = uci->cksum = 0; + uci->err = MC_NOTFOUND; uci->mc = NULL; - uci->valid = 1; if (c->x86_vendor != X86_VENDOR_INTEL || c->x86 < 6 || cpu_has(c, X86_FEATURE_IA64)) { - printk(KERN_ERR "microcode: CPU%d not a capable Intel " - "processor\n", cpu_num); - uci->valid = 0; + printk(KERN_ERR "microcode: CPU%d not a capable Intel processor\n", cpu_num); return; - } - - uci->sig = cpuid_eax(0x00000001); + } else { + uci->sig = cpuid_eax(0x00000001); - if ((c->x86_model >= 5) || (c->x86 > 6)) { - /* get processor flags from MSR 0x17 */ - rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); - uci->pf = 1 << ((val[1] >> 18) & 7); + if ((c->x86_model >= 5) || (c->x86 > 6)) { + /* get processor flags from MSR 0x17 */ + rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]); + uci->pf = 1 << ((val[1] >> 18) & 7); + } + uci->orig_pf = uci->pf; } wrmsr(MSR_IA32_UCODE_REV, 0, 0); @@ -166,159 +180,218 @@ static void collect_cpu_info(int cpu_num) uci->sig, uci->pf, uci->rev); } -static inline int microcode_update_match(int cpu_num, - microcode_header_t *mc_header, int sig, int pf) +static inline void mark_microcode_update (int cpu_num, microcode_header_t *mc_header, int sig, int pf, int cksum) { struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; - if (!sigmatch(sig, uci->sig, pf, uci->pf) - || mc_header->rev <= uci->rev) - return 0; - return 1; + pr_debug("Microcode Found.\n"); + pr_debug(" Header Revision 0x%x\n", mc_header->hdrver); + pr_debug(" Loader Revision 0x%x\n", mc_header->ldrver); + pr_debug(" Revision 0x%x \n", mc_header->rev); + pr_debug(" Date %x/%x/%x\n", + ((mc_header->date >> 24 ) & 0xff), + ((mc_header->date >> 16 ) & 0xff), + (mc_header->date & 0xFFFF)); + pr_debug(" Signature 0x%x\n", sig); + pr_debug(" Type 0x%x Family 0x%x Model 0x%x Stepping 0x%x\n", + ((sig >> 12) & 0x3), + ((sig >> 8) & 0xf), + ((sig >> 4) & 0xf), + ((sig & 0xf))); + pr_debug(" Processor Flags 0x%x\n", pf); + pr_debug(" Checksum 0x%x\n", cksum); + + if (mc_header->rev < uci->rev) { + if (uci->err == MC_NOTFOUND) { + uci->err = MC_IGNORED; + uci->cksum = mc_header->rev; + } else if (uci->err == MC_IGNORED && uci->cksum < mc_header->rev) + uci->cksum = mc_header->rev; + } else if (mc_header->rev == uci->rev) { + if (uci->err < MC_MARKED) { + /* notify the caller of success on this cpu */ + uci->err = MC_SUCCESS; + } + } else if (uci->err != MC_ALLOCATED || mc_header->rev > uci->mc->hdr.rev) { + pr_debug("microcode: CPU%d found a matching microcode update with " + " revision 0x%x (current=0x%x)\n", cpu_num, mc_header->rev, uci->rev); + uci->cksum = cksum; + uci->pf = pf; /* keep the original mc pf for cksum calculation */ + uci->err = MC_MARKED; /* found the match */ + for_each_online_cpu(cpu_num) { + if (ucode_cpu_info + cpu_num != uci + && ucode_cpu_info[cpu_num].mc == uci->mc) { + uci->mc = NULL; + break; + } + } + if (uci->mc != NULL) { + vfree(uci->mc); + uci->mc = NULL; + } + } + return; } -static int microcode_sanity_check(void *mc) +static int find_matching_ucodes (void) { - microcode_header_t *mc_header = mc; - struct extended_sigtable *ext_header = NULL; - struct extended_signature *ext_sig; - unsigned long total_size, data_size, ext_table_size; - int sum, orig_sum, ext_sigcount = 0, i; - - total_size = get_totalsize(mc_header); - data_size = get_datasize(mc_header); - if (data_size + MC_HEADER_SIZE > total_size) { - printk(KERN_ERR "microcode: error! " - "Bad data size in microcode data file\n"); - return -EINVAL; - } + int cursor = 0; + int error = 0; - if (mc_header->ldrver != 1 || mc_header->hdrver != 1) { - printk(KERN_ERR "microcode: error! " - "Unknown microcode update format\n"); - return -EINVAL; - } - ext_table_size = total_size - (MC_HEADER_SIZE + data_size); - if (ext_table_size) { - if ((ext_table_size < EXT_HEADER_SIZE) - || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { - printk(KERN_ERR "microcode: error! " - "Small exttable size in microcode data file\n"); - return -EINVAL; + while (cursor + MC_HEADER_SIZE < user_buffer_size) { + microcode_header_t mc_header; + void *newmc = NULL; + int i, sum, cpu_num, allocated_flag, total_size, data_size, ext_table_size; + + if (copy_from_user(&mc_header, user_buffer + cursor, MC_HEADER_SIZE)) { + printk(KERN_ERR "microcode: error! Can not read user data\n"); + error = -EFAULT; + goto out; } - ext_header = mc + MC_HEADER_SIZE + data_size; - if (ext_table_size != exttable_size(ext_header)) { - printk(KERN_ERR "microcode: error! " - "Bad exttable size in microcode data file\n"); - return -EFAULT; + + total_size = get_totalsize(&mc_header); + if ((cursor + total_size > user_buffer_size) || (total_size < DEFAULT_UCODE_TOTALSIZE)) { + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); + error = -EINVAL; + goto out; } - ext_sigcount = ext_header->count; - } - /* check extended table checksum */ - if (ext_table_size) { - int ext_table_sum = 0; - int *ext_tablep = (int *)ext_header; - - i = ext_table_size / DWSIZE; - while (i--) - ext_table_sum += ext_tablep[i]; - if (ext_table_sum) { - printk(KERN_WARNING "microcode: aborting, " - "bad extended signature table checksum\n"); - return -EINVAL; + data_size = get_datasize(&mc_header); + if ((data_size + MC_HEADER_SIZE > total_size) || (data_size < DEFAULT_UCODE_DATASIZE)) { + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); + error = -EINVAL; + goto out; } - } - /* calculate the checksum */ - orig_sum = 0; - i = (MC_HEADER_SIZE + data_size) / DWSIZE; - while (i--) - orig_sum += ((int *)mc)[i]; - if (orig_sum) { - printk(KERN_ERR "microcode: aborting, bad checksum\n"); - return -EINVAL; - } - if (!ext_table_size) - return 0; - /* check extended signature checksum */ - for (i = 0; i < ext_sigcount; i++) { - ext_sig = (struct extended_signature *)((void *)ext_header - + EXT_HEADER_SIZE + EXT_SIGNATURE_SIZE * i); - sum = orig_sum - - (mc_header->sig + mc_header->pf + mc_header->cksum) - + (ext_sig->sig + ext_sig->pf + ext_sig->cksum); - if (sum) { - printk(KERN_ERR "microcode: aborting, bad checksum\n"); - return -EINVAL; + if (mc_header.ldrver != 1 || mc_header.hdrver != 1) { + printk(KERN_ERR "microcode: error! Unknown microcode update format\n"); + error = -EINVAL; + goto out; } - } - return 0; -} -/* - * return 0 - no update found - * return 1 - found update - * return < 0 - error - */ -static int get_maching_microcode(void *mc, int cpu) -{ - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - microcode_header_t *mc_header = mc; - struct extended_sigtable *ext_header; - unsigned long total_size = get_totalsize(mc_header); - int ext_sigcount, i; - struct extended_signature *ext_sig; - void *new_mc; - - if (microcode_update_match(cpu, mc_header, - mc_header->sig, mc_header->pf)) - goto find; - - if (total_size <= get_datasize(mc_header) + MC_HEADER_SIZE) - return 0; - - ext_header = (struct extended_sigtable *)(mc + - get_datasize(mc_header) + MC_HEADER_SIZE); - ext_sigcount = ext_header->count; - ext_sig = (struct extended_signature *)((void *)ext_header - + EXT_HEADER_SIZE); - for (i = 0; i < ext_sigcount; i++) { - if (microcode_update_match(cpu, mc_header, - ext_sig->sig, ext_sig->pf)) - goto find; - ext_sig++; - } - return 0; -find: - pr_debug("microcode: CPU %d found a matching microcode update with" - " version 0x%x (current=0x%x)\n", cpu, mc_header->rev,uci->rev); - new_mc = vmalloc(total_size); - if (!new_mc) { - printk(KERN_ERR "microcode: error! Can not allocate memory\n"); - return -ENOMEM; - } + for_each_online_cpu(cpu_num) { + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; + + if (sigmatch(mc_header.sig, uci->sig, mc_header.pf, uci->orig_pf)) + mark_microcode_update(cpu_num, &mc_header, mc_header.sig, mc_header.pf, mc_header.cksum); + } - /* free previous update file */ - vfree(uci->mc); + ext_table_size = total_size - (MC_HEADER_SIZE + data_size); + if (ext_table_size) { + struct extended_sigtable ext_header; + struct extended_signature ext_sig; + int ext_sigcount; - memcpy(new_mc, mc, total_size); - uci->mc = new_mc; - return 1; + if ((ext_table_size < EXT_HEADER_SIZE) + || ((ext_table_size - EXT_HEADER_SIZE) % EXT_SIGNATURE_SIZE)) { + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); + error = -EINVAL; + goto out; + } + if (copy_from_user(&ext_header, user_buffer + cursor + + MC_HEADER_SIZE + data_size, EXT_HEADER_SIZE)) { + printk(KERN_ERR "microcode: error! Can not read user data\n"); + error = -EFAULT; + goto out; + } + if (ext_table_size != exttable_size(&ext_header)) { + printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); + error = -EFAULT; + goto out; + } + + ext_sigcount = ext_header.count; + + for (i = 0; i < ext_sigcount; i++) { + if (copy_from_user(&ext_sig, user_buffer + cursor + MC_HEADER_SIZE + data_size + EXT_HEADER_SIZE + + EXT_SIGNATURE_SIZE * i, EXT_SIGNATURE_SIZE)) { + printk(KERN_ERR "microcode: error! Can not read user data\n"); + error = -EFAULT; + goto out; + } + for_each_online_cpu(cpu_num) { + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; + + if (sigmatch(ext_sig.sig, uci->sig, ext_sig.pf, uci->orig_pf)) { + mark_microcode_update(cpu_num, &mc_header, ext_sig.sig, ext_sig.pf, ext_sig.cksum); + } + } + } + } + /* now check if any cpu has matched */ + allocated_flag = 0; + sum = 0; + for_each_online_cpu(cpu_num) { + if (ucode_cpu_info[cpu_num].err == MC_MARKED) { + struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; + if (!allocated_flag) { + allocated_flag = 1; + newmc = vmalloc(total_size); + if (!newmc) { + printk(KERN_ERR "microcode: error! Can not allocate memory\n"); + error = -ENOMEM; + goto out; + } + if (copy_from_user(newmc + MC_HEADER_SIZE, + user_buffer + cursor + MC_HEADER_SIZE, + total_size - MC_HEADER_SIZE)) { + printk(KERN_ERR "microcode: error! Can not read user data\n"); + vfree(newmc); + error = -EFAULT; + goto out; + } + memcpy(newmc, &mc_header, MC_HEADER_SIZE); + /* check extended table checksum */ + if (ext_table_size) { + int ext_table_sum = 0; + int * ext_tablep = (((void *) newmc) + MC_HEADER_SIZE + data_size); + i = ext_table_size / DWSIZE; + while (i--) ext_table_sum += ext_tablep[i]; + if (ext_table_sum) { + printk(KERN_WARNING "microcode: aborting, bad extended signature table checksum\n"); + vfree(newmc); + error = -EINVAL; + goto out; + } + } + + /* calculate the checksum */ + i = (MC_HEADER_SIZE + data_size) / DWSIZE; + while (i--) sum += ((int *)newmc)[i]; + sum -= (mc_header.sig + mc_header.pf + mc_header.cksum); + } + ucode_cpu_info[cpu_num].mc = newmc; + ucode_cpu_info[cpu_num].err = MC_ALLOCATED; /* mc updated */ + if (sum + uci->sig + uci->pf + uci->cksum != 0) { + printk(KERN_ERR "microcode: CPU%d aborting, bad checksum\n", cpu_num); + error = -EINVAL; + goto out; + } + } + } + cursor += total_size; /* goto the next update patch */ + } /* end of while */ +out: + return error; } -static void apply_microcode(int cpu) +static void do_update_one (void * unused) { unsigned long flags; unsigned int val[2]; - int cpu_num = raw_smp_processor_id(); + int cpu_num = smp_processor_id(); struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; - /* We should bind the task to the CPU */ - BUG_ON(cpu_num != cpu); - - if (uci->mc == NULL) + if (uci->mc == NULL) { + if (verbose) { + if (uci->err == MC_SUCCESS) + printk(KERN_INFO "microcode: CPU%d already at revision 0x%x\n", + cpu_num, uci->rev); + else + printk(KERN_INFO "microcode: No new microcode data for CPU%d\n", cpu_num); + } return; + } /* serialize access to the physical write to MSR 0x79 */ spin_lock_irqsave(µcode_update_lock, flags); @@ -335,107 +408,68 @@ static void apply_microcode(int cpu) /* get the current revision from MSR 0x8B */ rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]); + /* notify the caller of success on this cpu */ + uci->err = MC_SUCCESS; spin_unlock_irqrestore(µcode_update_lock, flags); - if (val[1] != uci->mc->hdr.rev) { - printk(KERN_ERR "microcode: CPU%d updated from revision " - "0x%x to 0x%x failed\n", cpu_num, uci->rev, val[1]); - return; - } - pr_debug("microcode: CPU%d updated from revision " + printk(KERN_INFO "microcode: CPU%d updated from revision " "0x%x to 0x%x, date = %08x \n", cpu_num, uci->rev, val[1], uci->mc->hdr.date); - uci->rev = val[1]; + return; } -#ifdef CONFIG_MICROCODE_OLD_INTERFACE -static void __user *user_buffer; /* user area microcode data buffer */ -static unsigned int user_buffer_size; /* it's size */ - -static long get_next_ucode(void **mc, long offset) +static int do_microcode_update (void) { - microcode_header_t mc_header; - unsigned long total_size; - - /* No more data */ - if (offset >= user_buffer_size) - return 0; - if (copy_from_user(&mc_header, user_buffer + offset, MC_HEADER_SIZE)) { - printk(KERN_ERR "microcode: error! Can not read user data\n"); - return -EFAULT; - } - total_size = get_totalsize(&mc_header); - if (offset + total_size > user_buffer_size) { - printk(KERN_ERR "microcode: error! Bad total size in microcode " - "data file\n"); - return -EINVAL; - } - *mc = vmalloc(total_size); - if (!*mc) - return -ENOMEM; - if (copy_from_user(*mc, user_buffer + offset, total_size)) { - printk(KERN_ERR "microcode: error! Can not read user data\n"); - vfree(*mc); - return -EFAULT; + int i, error; + + if (on_each_cpu(collect_cpu_info, NULL, 1, 1) != 0) { + printk(KERN_ERR "microcode: Error! Could not run on all processors\n"); + error = -EIO; + goto out; } - return offset + total_size; -} -static int do_microcode_update (void) -{ - long cursor = 0; - int error = 0; - void *new_mc; - int cpu; - cpumask_t old; + if ((error = find_matching_ucodes())) { + printk(KERN_ERR "microcode: Error in the microcode data\n"); + goto out_free; + } - old = current->cpus_allowed; + if (on_each_cpu(do_update_one, NULL, 1, 1) != 0) { + printk(KERN_ERR "microcode: Error! Could not run on all processors\n"); + error = -EIO; + } - while ((cursor = get_next_ucode(&new_mc, cursor)) > 0) { - error = microcode_sanity_check(new_mc); - if (error) - goto out; - /* - * It's possible the data file has multiple matching ucode, - * lets keep searching till the latest version - */ - for_each_online_cpu(cpu) { - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - - if (!uci->valid) - continue; - set_cpus_allowed(current, cpumask_of_cpu(cpu)); - error = get_maching_microcode(new_mc, cpu); - if (error < 0) - goto out; - if (error == 1) - apply_microcode(cpu); +out_free: + for_each_online_cpu(i) { + if (ucode_cpu_info[i].mc) { + int j; + void *tmp = ucode_cpu_info[i].mc; + vfree(tmp); + for_each_online_cpu(j) { + if (ucode_cpu_info[j].mc == tmp) + ucode_cpu_info[j].mc = NULL; + } } - vfree(new_mc); + if (ucode_cpu_info[i].err == MC_IGNORED && verbose) + printk(KERN_WARNING "microcode: CPU%d not 'upgrading' to earlier revision" + " 0x%x (current=0x%x)\n", i, ucode_cpu_info[i].cksum, ucode_cpu_info[i].rev); } out: - if (cursor > 0) - vfree(new_mc); - if (cursor < 0) - error = cursor; - set_cpus_allowed(current, old); return error; } -static int microcode_open (struct inode *unused1, struct file *unused2) -{ - return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; -} - static ssize_t microcode_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos) { ssize_t ret; + if (len < DEFAULT_UCODE_TOTALSIZE) { + printk(KERN_ERR "microcode: not enough data\n"); + return -EINVAL; + } + if ((len >> PAGE_SHIFT) > num_physpages) { printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages); return -EINVAL; } - lock_cpu_hotplug(); mutex_lock(µcode_mutex); user_buffer = (void __user *) buf; @@ -446,7 +480,6 @@ static ssize_t microcode_write (struct file *file, const char __user *buf, size_ ret = (ssize_t)len; mutex_unlock(µcode_mutex); - unlock_cpu_hotplug(); return ret; } @@ -463,7 +496,7 @@ static struct miscdevice microcode_dev = { .fops = µcode_fops, }; -static int __init microcode_dev_init (void) +static int __init microcode_init (void) { int error; @@ -475,280 +508,6 @@ static int __init microcode_dev_init (void) return error; } - return 0; -} - -static void __exit microcode_dev_exit (void) -{ - misc_deregister(µcode_dev); -} - -MODULE_ALIAS_MISCDEV(MICROCODE_MINOR); -#else -#define microcode_dev_init() 0 -#define microcode_dev_exit() do { } while(0) -#endif - -static long get_next_ucode_from_buffer(void **mc, void *buf, - unsigned long size, long offset) -{ - microcode_header_t *mc_header; - unsigned long total_size; - - /* No more data */ - if (offset >= size) - return 0; - mc_header = (microcode_header_t *)(buf + offset); - total_size = get_totalsize(mc_header); - - if (offset + total_size > size) { - printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); - return -EINVAL; - } - - *mc = vmalloc(total_size); - if (!*mc) { - printk(KERN_ERR "microcode: error! Can not allocate memory\n"); - return -ENOMEM; - } - memcpy(*mc, buf + offset, total_size); - return offset + total_size; -} - -/* fake device for request_firmware */ -static struct platform_device *microcode_pdev; - -static int cpu_request_microcode(int cpu) -{ - char name[30]; - struct cpuinfo_x86 *c = cpu_data + cpu; - const struct firmware *firmware; - void *buf; - unsigned long size; - long offset = 0; - int error; - void *mc; - - /* We should bind the task to the CPU */ - BUG_ON(cpu != raw_smp_processor_id()); - sprintf(name,"intel-ucode/%02x-%02x-%02x", - c->x86, c->x86_model, c->x86_mask); - error = request_firmware(&firmware, name, µcode_pdev->dev); - if (error) { - pr_debug("ucode data file %s load failed\n", name); - return error; - } - buf = (void *)firmware->data; - size = firmware->size; - while ((offset = get_next_ucode_from_buffer(&mc, buf, size, offset)) - > 0) { - error = microcode_sanity_check(mc); - if (error) - break; - error = get_maching_microcode(mc, cpu); - if (error < 0) - break; - /* - * It's possible the data file has multiple matching ucode, - * lets keep searching till the latest version - */ - if (error == 1) { - apply_microcode(cpu); - error = 0; - } - vfree(mc); - } - if (offset > 0) - vfree(mc); - if (offset < 0) - error = offset; - release_firmware(firmware); - - return error; -} - -static void microcode_init_cpu(int cpu) -{ - cpumask_t old; - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - - old = current->cpus_allowed; - - set_cpus_allowed(current, cpumask_of_cpu(cpu)); - mutex_lock(µcode_mutex); - collect_cpu_info(cpu); - if (uci->valid) - cpu_request_microcode(cpu); - mutex_unlock(µcode_mutex); - set_cpus_allowed(current, old); -} - -static void microcode_fini_cpu(int cpu) -{ - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - - mutex_lock(µcode_mutex); - uci->valid = 0; - vfree(uci->mc); - uci->mc = NULL; - mutex_unlock(µcode_mutex); -} - -static ssize_t reload_store(struct sys_device *dev, const char *buf, size_t sz) -{ - struct ucode_cpu_info *uci = ucode_cpu_info + dev->id; - char *end; - unsigned long val = simple_strtoul(buf, &end, 0); - int err = 0; - int cpu = dev->id; - - if (end == buf) - return -EINVAL; - if (val == 1) { - cpumask_t old; - - old = current->cpus_allowed; - - lock_cpu_hotplug(); - set_cpus_allowed(current, cpumask_of_cpu(cpu)); - - mutex_lock(µcode_mutex); - if (uci->valid) - err = cpu_request_microcode(cpu); - mutex_unlock(µcode_mutex); - unlock_cpu_hotplug(); - set_cpus_allowed(current, old); - } - if (err) - return err; - return sz; -} - -static ssize_t version_show(struct sys_device *dev, char *buf) -{ - struct ucode_cpu_info *uci = ucode_cpu_info + dev->id; - - return sprintf(buf, "0x%x\n", uci->rev); -} - -static ssize_t pf_show(struct sys_device *dev, char *buf) -{ - struct ucode_cpu_info *uci = ucode_cpu_info + dev->id; - - return sprintf(buf, "0x%x\n", uci->pf); -} - -static SYSDEV_ATTR(reload, 0200, NULL, reload_store); -static SYSDEV_ATTR(version, 0400, version_show, NULL); -static SYSDEV_ATTR(processor_flags, 0400, pf_show, NULL); - -static struct attribute *mc_default_attrs[] = { - &attr_reload.attr, - &attr_version.attr, - &attr_processor_flags.attr, - NULL -}; - -static struct attribute_group mc_attr_group = { - .attrs = mc_default_attrs, - .name = "microcode", -}; - -static int mc_sysdev_add(struct sys_device *sys_dev) -{ - int cpu = sys_dev->id; - struct ucode_cpu_info *uci = ucode_cpu_info + cpu; - - if (!cpu_online(cpu)) - return 0; - pr_debug("Microcode:CPU %d added\n", cpu); - memset(uci, 0, sizeof(*uci)); - sysfs_create_group(&sys_dev->kobj, &mc_attr_group); - - microcode_init_cpu(cpu); - return 0; -} - -static int mc_sysdev_remove(struct sys_device *sys_dev) -{ - int cpu = sys_dev->id; - - if (!cpu_online(cpu)) - return 0; - pr_debug("Microcode:CPU %d removed\n", cpu); - microcode_fini_cpu(cpu); - sysfs_remove_group(&sys_dev->kobj, &mc_attr_group); - return 0; -} - -static int mc_sysdev_resume(struct sys_device *dev) -{ - int cpu = dev->id; - - if (!cpu_online(cpu)) - return 0; - pr_debug("Microcode:CPU %d resumed\n", cpu); - /* only CPU 0 will apply ucode here */ - apply_microcode(0); - return 0; -} - -static struct sysdev_driver mc_sysdev_driver = { - .add = mc_sysdev_add, - .remove = mc_sysdev_remove, - .resume = mc_sysdev_resume, -}; - -#ifdef CONFIG_HOTPLUG_CPU -static __cpuinit int -mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - struct sys_device *sys_dev; - - sys_dev = get_cpu_sysdev(cpu); - switch (action) { - case CPU_ONLINE: - case CPU_DOWN_FAILED: - mc_sysdev_add(sys_dev); - break; - case CPU_DOWN_PREPARE: - mc_sysdev_remove(sys_dev); - break; - } - return NOTIFY_OK; -} - -static struct notifier_block mc_cpu_notifier = { - .notifier_call = mc_cpu_callback, -}; -#endif - -static int __init microcode_init (void) -{ - int error; - - error = microcode_dev_init(); - if (error) - return error; - microcode_pdev = platform_device_register_simple("microcode", -1, - NULL, 0); - if (IS_ERR(microcode_pdev)) { - microcode_dev_exit(); - return PTR_ERR(microcode_pdev); - } - - lock_cpu_hotplug(); - error = sysdev_driver_register(&cpu_sysdev_class, &mc_sysdev_driver); - unlock_cpu_hotplug(); - if (error) { - microcode_dev_exit(); - platform_device_unregister(microcode_pdev); - return error; - } - - register_hotcpu_notifier(&mc_cpu_notifier); - printk(KERN_INFO "IA-32 Microcode Update Driver: v" MICROCODE_VERSION " \n"); return 0; @@ -756,16 +515,9 @@ static int __init microcode_init (void) static void __exit microcode_exit (void) { - microcode_dev_exit(); - - unregister_hotcpu_notifier(&mc_cpu_notifier); - - lock_cpu_hotplug(); - sysdev_driver_unregister(&cpu_sysdev_class, &mc_sysdev_driver); - unlock_cpu_hotplug(); - - platform_device_unregister(microcode_pdev); + misc_deregister(µcode_dev); } module_init(microcode_init) module_exit(microcode_exit) +MODULE_ALIAS_MISCDEV(MICROCODE_MINOR); diff --git a/trunk/arch/i386/kernel/mpparse.c b/trunk/arch/i386/kernel/mpparse.c index 442aaf8c77eb..a70b5fa0ef06 100644 --- a/trunk/arch/i386/kernel/mpparse.c +++ b/trunk/arch/i386/kernel/mpparse.c @@ -30,7 +30,6 @@ #include #include -#include #include #include @@ -69,7 +68,7 @@ unsigned int def_to_bigsmp = 0; /* Processor that is doing the boot up */ unsigned int boot_cpu_physical_apicid = -1U; /* Internal processor count */ -unsigned int __cpuinitdata num_processors; +static unsigned int __devinitdata num_processors; /* Bitmask of physically existing CPUs */ physid_mask_t phys_cpu_present_map; @@ -229,14 +228,12 @@ static void __init MP_bus_info (struct mpc_config_bus *m) mpc_oem_bus_info(m, str, translation_table[mpc_record]); -#if MAX_MP_BUSSES < 256 if (m->mpc_busid >= MAX_MP_BUSSES) { printk(KERN_WARNING "MP table busid value (%d) for bustype %s " " is too large, max. supported is %d\n", m->mpc_busid, str, MAX_MP_BUSSES - 1); return; } -#endif if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; @@ -296,6 +293,19 @@ static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m) m->mpc_irqtype, m->mpc_irqflag & 3, (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid, m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint); + /* + * Well it seems all SMP boards in existence + * use ExtINT/LVT1 == LINT0 and + * NMI/LVT2 == LINT1 - the following check + * will show us if this assumptions is false. + * Until then we do not have to add baggage. + */ + if ((m->mpc_irqtype == mp_ExtINT) && + (m->mpc_destapiclint != 0)) + BUG(); + if ((m->mpc_irqtype == mp_NMI) && + (m->mpc_destapiclint != 1)) + BUG(); } #ifdef CONFIG_X86_NUMAQ @@ -812,7 +822,8 @@ int es7000_plat; #ifdef CONFIG_ACPI -void __init mp_register_lapic_address(u64 address) +void __init mp_register_lapic_address ( + u64 address) { mp_lapic_addr = (unsigned long) address; @@ -824,10 +835,13 @@ void __init mp_register_lapic_address(u64 address) Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid); } -void __devinit mp_register_lapic (u8 id, u8 enabled) + +void __devinit mp_register_lapic ( + u8 id, + u8 enabled) { struct mpc_config_processor processor; - int boot_cpu = 0; + int boot_cpu = 0; if (MAX_APICS - id <= 0) { printk(KERN_WARNING "Processor #%d invalid (max %d)\n", @@ -864,9 +878,11 @@ static struct mp_ioapic_routing { u32 pin_programmed[4]; } mp_ioapic_routing[MAX_IO_APICS]; -static int mp_find_ioapic (int gsi) + +static int mp_find_ioapic ( + int gsi) { - int i = 0; + int i = 0; /* Find the IOAPIC that manages this GSI. */ for (i = 0; i < nr_ioapics; i++) { @@ -879,11 +895,15 @@ static int mp_find_ioapic (int gsi) return -1; } + -void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) +void __init mp_register_ioapic ( + u8 id, + u32 address, + u32 gsi_base) { - int idx = 0; - int tmpid; + int idx = 0; + int tmpid; if (nr_ioapics >= MAX_IO_APICS) { printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " @@ -929,10 +949,16 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end); + + return; } -void __init -mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) + +void __init mp_override_legacy_irq ( + u8 bus_irq, + u8 polarity, + u8 trigger, + u32 gsi) { struct mpc_config_intsrc intsrc; int ioapic = -1; @@ -970,13 +996,15 @@ mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) mp_irqs[mp_irq_entries] = intsrc; if (++mp_irq_entries == MAX_IRQ_SOURCES) panic("Max # of irq sources exceeded!\n"); + + return; } void __init mp_config_acpi_legacy_irqs (void) { struct mpc_config_intsrc intsrc; - int i = 0; - int ioapic = -1; + int i = 0; + int ioapic = -1; /* * Fabricate the legacy ISA bus (bus #31). @@ -1045,12 +1073,12 @@ void __init mp_config_acpi_legacy_irqs (void) #define MAX_GSI_NUM 4096 -int mp_register_gsi(u32 gsi, int triggering, int polarity) +int mp_register_gsi (u32 gsi, int triggering, int polarity) { - int ioapic = -1; - int ioapic_pin = 0; - int idx, bit = 0; - static int pci_irq = 16; + int ioapic = -1; + int ioapic_pin = 0; + int idx, bit = 0; + static int pci_irq = 16; /* * Mapping between Global System Interrups, which * represent all possible interrupts, and IRQs diff --git a/trunk/arch/i386/kernel/nmi.c b/trunk/arch/i386/kernel/nmi.c index 3e8e3adb0489..acb351478e42 100644 --- a/trunk/arch/i386/kernel/nmi.c +++ b/trunk/arch/i386/kernel/nmi.c @@ -13,6 +13,7 @@ * Mikael Pettersson : PM converted to driver model. Disable/enable API. */ +#include #include #include #include @@ -20,177 +21,83 @@ #include #include #include -#include -#include #include #include -#include #include #include "mach_traps.h" -int unknown_nmi_panic; -int nmi_watchdog_enabled; - -/* perfctr_nmi_owner tracks the ownership of the perfctr registers: - * evtsel_nmi_owner tracks the ownership of the event selection - * - different performance counters/ event selection may be reserved for - * different subsystems this reservation system just tries to coordinate - * things a little - */ -static DEFINE_PER_CPU(unsigned long, perfctr_nmi_owner); -static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[3]); +unsigned int nmi_watchdog = NMI_NONE; +extern int unknown_nmi_panic; +static unsigned int nmi_hz = HZ; +static unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ +static unsigned int nmi_p4_cccr_val; +extern void show_registers(struct pt_regs *regs); -/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's - * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) +/* + * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: + * - it may be reserved by some other driver, or not + * - when not reserved by some other driver, it may be used for + * the NMI watchdog, or not + * + * This is maintained separately from nmi_active because the NMI + * watchdog may also be driven from the I/O APIC timer. */ -#define NMI_MAX_COUNTER_BITS 66 +static DEFINE_SPINLOCK(lapic_nmi_owner_lock); +static unsigned int lapic_nmi_owner; +#define LAPIC_NMI_WATCHDOG (1<<0) +#define LAPIC_NMI_RESERVED (1<<1) /* nmi_active: - * >0: the lapic NMI watchdog is active, but can be disabled - * <0: the lapic NMI watchdog has not been set up, and cannot + * +1: the lapic NMI watchdog is active, but can be disabled + * 0: the lapic NMI watchdog has not been set up, and cannot * be enabled - * 0: the lapic NMI watchdog is disabled, but can be enabled + * -1: the lapic NMI watchdog is disabled, but can be enabled */ -atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ +int nmi_active; -unsigned int nmi_watchdog = NMI_DEFAULT; -static unsigned int nmi_hz = HZ; - -struct nmi_watchdog_ctlblk { - int enabled; - u64 check_bit; - unsigned int cccr_msr; - unsigned int perfctr_msr; /* the MSR to reset in NMI handler */ - unsigned int evntsel_msr; /* the MSR to select the events to handle */ -}; -static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk); - -/* local prototypes */ -static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu); - -extern void show_registers(struct pt_regs *regs); -extern int unknown_nmi_panic; - -/* converts an msr to an appropriate reservation bit */ -static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) -{ - /* returns the bit offset of the performance counter register */ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return (msr - MSR_K7_PERFCTR0); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return (msr - MSR_ARCH_PERFMON_PERFCTR0); - - switch (boot_cpu_data.x86) { - case 6: - return (msr - MSR_P6_PERFCTR0); - case 15: - return (msr - MSR_P4_BPU_PERFCTR0); - } - } - return 0; -} - -/* converts an msr to an appropriate reservation bit */ -static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) -{ - /* returns the bit offset of the event selection register */ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return (msr - MSR_K7_EVNTSEL0); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return (msr - MSR_ARCH_PERFMON_EVENTSEL0); - - switch (boot_cpu_data.x86) { - case 6: - return (msr - MSR_P6_EVNTSEL0); - case 15: - return (msr - MSR_P4_BSU_ESCR0); - } - } - return 0; -} - -/* checks for a bit availability (hack for oprofile) */ -int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) -{ - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner))); -} - -/* checks the an msr for availability */ -int avail_to_resrv_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner))); -} - -int reserve_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - if (!test_and_set_bit(counter, &__get_cpu_var(perfctr_nmi_owner))) - return 1; - return 0; -} - -void release_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - clear_bit(counter, &__get_cpu_var(perfctr_nmi_owner)); -} - -int reserve_evntsel_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - if (!test_and_set_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0])) - return 1; - return 0; -} - -void release_evntsel_nmi(unsigned int msr) -{ - unsigned int counter; +#define K7_EVNTSEL_ENABLE (1 << 22) +#define K7_EVNTSEL_INT (1 << 20) +#define K7_EVNTSEL_OS (1 << 17) +#define K7_EVNTSEL_USR (1 << 16) +#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 +#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); +#define P6_EVNTSEL0_ENABLE (1 << 22) +#define P6_EVNTSEL_INT (1 << 20) +#define P6_EVNTSEL_OS (1 << 17) +#define P6_EVNTSEL_USR (1 << 16) +#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79 +#define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED - clear_bit(counter, &__get_cpu_var(evntsel_nmi_owner)[0]); -} +#define MSR_P4_MISC_ENABLE 0x1A0 +#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) +#define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL (1<<12) +#define MSR_P4_PERFCTR0 0x300 +#define MSR_P4_CCCR0 0x360 +#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) +#define P4_ESCR_OS (1<<3) +#define P4_ESCR_USR (1<<2) +#define P4_CCCR_OVF_PMI0 (1<<26) +#define P4_CCCR_OVF_PMI1 (1<<27) +#define P4_CCCR_THRESHOLD(N) ((N)<<20) +#define P4_CCCR_COMPLEMENT (1<<19) +#define P4_CCCR_COMPARE (1<<18) +#define P4_CCCR_REQUIRED (3<<16) +#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) +#define P4_CCCR_ENABLE (1<<12) +/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter + CRU_ESCR0 (with any non-null event selector) through a complemented + max threshold. [IA32-Vol3, Section 14.9.9] */ +#define MSR_P4_IQ_COUNTER0 0x30C +#define P4_NMI_CRU_ESCR0 (P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR) +#define P4_NMI_IQ_CCCR0 \ + (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ + P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) -static __cpuinit inline int nmi_known_cpu(void) -{ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return ((boot_cpu_data.x86 == 15) || (boot_cpu_data.x86 == 6)); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return 1; - else - return ((boot_cpu_data.x86 == 15) || (boot_cpu_data.x86 == 6)); - } - return 0; -} +#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL +#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK #ifdef CONFIG_SMP /* The performance counters used by NMI_LOCAL_APIC don't trigger when @@ -218,18 +125,7 @@ static int __init check_nmi_watchdog(void) unsigned int *prev_nmi_count; int cpu; - /* Enable NMI watchdog for newer systems. - Actually it should be safe for most systems before 2004 too except - for some IBM systems that corrupt registers when NMI happens - during SMM. Unfortunately we don't have more exact information - on these and use this coarse check. */ - if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004) - nmi_watchdog = NMI_LOCAL_APIC; - - if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT)) - return 0; - - if (!atomic_read(&nmi_active)) + if (nmi_watchdog == NMI_NONE) return 0; prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); @@ -253,45 +149,25 @@ static int __init check_nmi_watchdog(void) if (!cpu_isset(cpu, cpu_callin_map)) continue; #endif - if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled) - continue; if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) { + endflag = 1; printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n", cpu, prev_nmi_count[cpu], nmi_count(cpu)); - per_cpu(nmi_watchdog_ctlblk, cpu).enabled = 0; - atomic_dec(&nmi_active); + nmi_active = 0; + lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG; + kfree(prev_nmi_count); + return -1; } } - if (!atomic_read(&nmi_active)) { - kfree(prev_nmi_count); - atomic_set(&nmi_active, -1); - return -1; - } endflag = 1; printk("OK.\n"); /* now that we know it works we can reduce NMI frequency to something more reasonable; makes a difference in some configs */ - if (nmi_watchdog == NMI_LOCAL_APIC) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - + if (nmi_watchdog == NMI_LOCAL_APIC) nmi_hz = 1; - /* - * On Intel CPUs with ARCH_PERFMON only 32 bits in the counter - * are writable, with higher bits sign extending from bit 31. - * So, we can only program the counter with 31 bit values and - * 32nd bit should be 1, for 33.. to be 1. - * Find the appropriate nmi_hz - */ - if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0 && - ((u64)cpu_khz * 1000) > 0x7fffffffULL) { - u64 count = (u64)cpu_khz * 1000; - do_div(count, 0x7fffffffUL); - nmi_hz = count + 1; - } - } kfree(prev_nmi_count); return 0; @@ -305,70 +181,124 @@ static int __init setup_nmi_watchdog(char *str) get_option(&str, &nmi); - if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE)) + if (nmi >= NMI_INVALID) return 0; + if (nmi == NMI_NONE) + nmi_watchdog = nmi; /* * If any other x86 CPU has a local APIC, then * please test the NMI stuff there and send me the * missing bits. Right now Intel P6/P4 and AMD K7 only. */ - if ((nmi == NMI_LOCAL_APIC) && (nmi_known_cpu() == 0)) - return 0; /* no lapic support */ - nmi_watchdog = nmi; + if ((nmi == NMI_LOCAL_APIC) && + (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && + (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15)) + nmi_watchdog = nmi; + if ((nmi == NMI_LOCAL_APIC) && + (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && + (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15)) + nmi_watchdog = nmi; + /* + * We can enable the IO-APIC watchdog + * unconditionally. + */ + if (nmi == NMI_IO_APIC) { + nmi_active = 1; + nmi_watchdog = nmi; + } return 1; } __setup("nmi_watchdog=", setup_nmi_watchdog); +static void disable_intel_arch_watchdog(void); + static void disable_lapic_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); - - if (atomic_read(&nmi_active) <= 0) + if (nmi_active <= 0) return; + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + wrmsr(MSR_K7_EVNTSEL0, 0, 0); + break; + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + disable_intel_arch_watchdog(); + break; + } + switch (boot_cpu_data.x86) { + case 6: + if (boot_cpu_data.x86_model > 0xd) + break; - on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); + wrmsr(MSR_P6_EVNTSEL0, 0, 0); + break; + case 15: + if (boot_cpu_data.x86_model > 0x4) + break; - BUG_ON(atomic_read(&nmi_active) != 0); + wrmsr(MSR_P4_IQ_CCCR0, 0, 0); + wrmsr(MSR_P4_CRU_ESCR0, 0, 0); + break; + } + break; + } + nmi_active = -1; + /* tell do_nmi() and others that we're not active any more */ + nmi_watchdog = 0; } static void enable_lapic_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); + if (nmi_active < 0) { + nmi_watchdog = NMI_LOCAL_APIC; + setup_apic_nmi_watchdog(); + } +} - /* are we already enabled */ - if (atomic_read(&nmi_active) != 0) - return; +int reserve_lapic_nmi(void) +{ + unsigned int old_owner; - /* are we lapic aware */ - if (nmi_known_cpu() <= 0) - return; + spin_lock(&lapic_nmi_owner_lock); + old_owner = lapic_nmi_owner; + lapic_nmi_owner |= LAPIC_NMI_RESERVED; + spin_unlock(&lapic_nmi_owner_lock); + if (old_owner & LAPIC_NMI_RESERVED) + return -EBUSY; + if (old_owner & LAPIC_NMI_WATCHDOG) + disable_lapic_nmi_watchdog(); + return 0; +} - on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); - touch_nmi_watchdog(); +void release_lapic_nmi(void) +{ + unsigned int new_owner; + + spin_lock(&lapic_nmi_owner_lock); + new_owner = lapic_nmi_owner & ~LAPIC_NMI_RESERVED; + lapic_nmi_owner = new_owner; + spin_unlock(&lapic_nmi_owner_lock); + if (new_owner & LAPIC_NMI_WATCHDOG) + enable_lapic_nmi_watchdog(); } void disable_timer_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_IO_APIC); - - if (atomic_read(&nmi_active) <= 0) + if ((nmi_watchdog != NMI_IO_APIC) || (nmi_active <= 0)) return; - disable_irq(0); - on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); - - BUG_ON(atomic_read(&nmi_active) != 0); + unset_nmi_callback(); + nmi_active = -1; + nmi_watchdog = NMI_NONE; } void enable_timer_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_IO_APIC); - - if (atomic_read(&nmi_active) == 0) { + if (nmi_active < 0) { + nmi_watchdog = NMI_IO_APIC; touch_nmi_watchdog(); - on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); - enable_irq(0); + nmi_active = 1; } } @@ -378,20 +308,15 @@ static int nmi_pm_active; /* nmi_active before suspend */ static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state) { - /* only CPU0 goes here, other CPUs should be offline */ - nmi_pm_active = atomic_read(&nmi_active); - stop_apic_nmi_watchdog(NULL); - BUG_ON(atomic_read(&nmi_active) != 0); + nmi_pm_active = nmi_active; + disable_lapic_nmi_watchdog(); return 0; } static int lapic_nmi_resume(struct sys_device *dev) { - /* only CPU0 goes here, other CPUs should be offline */ - if (nmi_pm_active > 0) { - setup_apic_nmi_watchdog(NULL); - touch_nmi_watchdog(); - } + if (nmi_pm_active > 0) + enable_lapic_nmi_watchdog(); return 0; } @@ -411,13 +336,7 @@ static int __init init_lapic_nmi_sysfs(void) { int error; - /* should really be a BUG_ON but b/c this is an - * init call, it just doesn't work. -dcz - */ - if (nmi_watchdog != NMI_LOCAL_APIC) - return 0; - - if ( atomic_read(&nmi_active) < 0 ) + if (nmi_active == 0 || nmi_watchdog != NMI_LOCAL_APIC) return 0; error = sysdev_class_register(&nmi_sysclass); @@ -435,269 +354,138 @@ late_initcall(init_lapic_nmi_sysfs); * Original code written by Keith Owens. */ -static void write_watchdog_counter(unsigned int perfctr_msr, const char *descr) +static void clear_msr_range(unsigned int base, unsigned int n) +{ + unsigned int i; + + for(i = 0; i < n; ++i) + wrmsr(base+i, 0, 0); +} + +static void write_watchdog_counter(const char *descr) { u64 count = (u64)cpu_khz * 1000; do_div(count, nmi_hz); if(descr) Dprintk("setting %s to -0x%08Lx\n", descr, count); - wrmsrl(perfctr_msr, 0 - count); + wrmsrl(nmi_perfctr_msr, 0 - count); } -/* Note that these events don't tick when the CPU idles. This means - the frequency varies with CPU load. */ - -#define K7_EVNTSEL_ENABLE (1 << 22) -#define K7_EVNTSEL_INT (1 << 20) -#define K7_EVNTSEL_OS (1 << 17) -#define K7_EVNTSEL_USR (1 << 16) -#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 -#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING - -static int setup_k7_watchdog(void) +static void setup_k7_watchdog(void) { - unsigned int perfctr_msr, evntsel_msr; unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - perfctr_msr = MSR_K7_PERFCTR0; - evntsel_msr = MSR_K7_EVNTSEL0; - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; + nmi_perfctr_msr = MSR_K7_PERFCTR0; - wrmsrl(perfctr_msr, 0UL); + clear_msr_range(MSR_K7_EVNTSEL0, 4); + clear_msr_range(MSR_K7_PERFCTR0, 4); evntsel = K7_EVNTSEL_INT | K7_EVNTSEL_OS | K7_EVNTSEL_USR | K7_NMI_EVENT; - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - write_watchdog_counter(perfctr_msr, "K7_PERFCTR0"); + wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); + write_watchdog_counter("K7_PERFCTR0"); apic_write(APIC_LVTPC, APIC_DM_NMI); evntsel |= K7_EVNTSEL_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL<<63; - return 1; -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; -} - -static void stop_k7_watchdog(void) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->evntsel_msr, 0, 0); - - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); + wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); } -#define P6_EVNTSEL0_ENABLE (1 << 22) -#define P6_EVNTSEL_INT (1 << 20) -#define P6_EVNTSEL_OS (1 << 17) -#define P6_EVNTSEL_USR (1 << 16) -#define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79 -#define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED - -static int setup_p6_watchdog(void) +static void setup_p6_watchdog(void) { - unsigned int perfctr_msr, evntsel_msr; unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - perfctr_msr = MSR_P6_PERFCTR0; - evntsel_msr = MSR_P6_EVNTSEL0; - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; + nmi_perfctr_msr = MSR_P6_PERFCTR0; - wrmsrl(perfctr_msr, 0UL); + clear_msr_range(MSR_P6_EVNTSEL0, 2); + clear_msr_range(MSR_P6_PERFCTR0, 2); evntsel = P6_EVNTSEL_INT | P6_EVNTSEL_OS | P6_EVNTSEL_USR | P6_NMI_EVENT; - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - write_watchdog_counter(perfctr_msr, "P6_PERFCTR0"); + wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); + write_watchdog_counter("P6_PERFCTR0"); apic_write(APIC_LVTPC, APIC_DM_NMI); evntsel |= P6_EVNTSEL0_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL<<39; - return 1; -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; -} - -static void stop_p6_watchdog(void) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->evntsel_msr, 0, 0); - - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); + wrmsr(MSR_P6_EVNTSEL0, evntsel, 0); } -/* Note that these events don't tick when the CPU idles. This means - the frequency varies with CPU load. */ - -#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) -#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) -#define P4_ESCR_OS (1<<3) -#define P4_ESCR_USR (1<<2) -#define P4_CCCR_OVF_PMI0 (1<<26) -#define P4_CCCR_OVF_PMI1 (1<<27) -#define P4_CCCR_THRESHOLD(N) ((N)<<20) -#define P4_CCCR_COMPLEMENT (1<<19) -#define P4_CCCR_COMPARE (1<<18) -#define P4_CCCR_REQUIRED (3<<16) -#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) -#define P4_CCCR_ENABLE (1<<12) -#define P4_CCCR_OVF (1<<31) -/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter - CRU_ESCR0 (with any non-null event selector) through a complemented - max threshold. [IA32-Vol3, Section 14.9.9] */ - static int setup_p4_watchdog(void) { - unsigned int perfctr_msr, evntsel_msr, cccr_msr; - unsigned int evntsel, cccr_val; unsigned int misc_enable, dummy; - unsigned int ht_num; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - rdmsr(MSR_IA32_MISC_ENABLE, misc_enable, dummy); + rdmsr(MSR_P4_MISC_ENABLE, misc_enable, dummy); if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) return 0; + nmi_perfctr_msr = MSR_P4_IQ_COUNTER0; + nmi_p4_cccr_val = P4_NMI_IQ_CCCR0; #ifdef CONFIG_SMP - /* detect which hyperthread we are on */ - if (smp_num_siblings == 2) { - unsigned int ebx, apicid; - - ebx = cpuid_ebx(1); - apicid = (ebx >> 24) & 0xff; - ht_num = apicid & 1; - } else + if (smp_num_siblings == 2) + nmi_p4_cccr_val |= P4_CCCR_OVF_PMI1; #endif - ht_num = 0; - /* performance counters are shared resources - * assign each hyperthread its own set - * (re-use the ESCR0 register, seems safe - * and keeps the cccr_val the same) - */ - if (!ht_num) { - /* logical cpu 0 */ - perfctr_msr = MSR_P4_IQ_PERFCTR0; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR0; - cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4); + if (!(misc_enable & MSR_P4_MISC_ENABLE_PEBS_UNAVAIL)) + clear_msr_range(0x3F1, 2); + /* MSR 0x3F0 seems to have a default value of 0xFC00, but current + docs doesn't fully define it, so leave it alone for now. */ + if (boot_cpu_data.x86_model >= 0x3) { + /* MSR_P4_IQ_ESCR0/1 (0x3ba/0x3bb) removed */ + clear_msr_range(0x3A0, 26); + clear_msr_range(0x3BC, 3); } else { - /* logical cpu 1 */ - perfctr_msr = MSR_P4_IQ_PERFCTR1; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR1; - cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); + clear_msr_range(0x3A0, 31); } - - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; - - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; - - evntsel = P4_ESCR_EVENT_SELECT(0x3F) - | P4_ESCR_OS - | P4_ESCR_USR; - - cccr_val |= P4_CCCR_THRESHOLD(15) - | P4_CCCR_COMPLEMENT - | P4_CCCR_COMPARE - | P4_CCCR_REQUIRED; - - wrmsr(evntsel_msr, evntsel, 0); - wrmsr(cccr_msr, cccr_val, 0); - write_watchdog_counter(perfctr_msr, "P4_IQ_COUNTER0"); + clear_msr_range(0x3C0, 6); + clear_msr_range(0x3C8, 6); + clear_msr_range(0x3E0, 2); + clear_msr_range(MSR_P4_CCCR0, 18); + clear_msr_range(MSR_P4_PERFCTR0, 18); + + wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0); + wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0); + write_watchdog_counter("P4_IQ_COUNTER0"); apic_write(APIC_LVTPC, APIC_DM_NMI); - cccr_val |= P4_CCCR_ENABLE; - wrmsr(cccr_msr, cccr_val, 0); - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = cccr_msr; - wd->check_bit = 1ULL<<39; + wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); return 1; -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; } -static void stop_p4_watchdog(void) +static void disable_intel_arch_watchdog(void) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->cccr_msr, 0, 0); - wrmsr(wd->evntsel_msr, 0, 0); + unsigned ebx; - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); + /* + * Check whether the Architectural PerfMon supports + * Unhalted Core Cycles Event or not. + * NOTE: Corresponding bit = 0 in ebp indicates event present. + */ + ebx = cpuid_ebx(10); + if (!(ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, 0, 0); } -#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL -#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK - static int setup_intel_arch_watchdog(void) { - unsigned int ebx; - union cpuid10_eax eax; - unsigned int unused; - unsigned int perfctr_msr, evntsel_msr; unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + unsigned ebx; /* * Check whether the Architectural PerfMon supports * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebx indicates event present. + * NOTE: Corresponding bit = 0 in ebp indicates event present. */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); - if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || - (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - goto fail; - - perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; - evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0; - - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; + ebx = cpuid_ebx(10); + if ((ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + return 0; - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; + nmi_perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; - wrmsrl(perfctr_msr, 0UL); + clear_msr_range(MSR_ARCH_PERFMON_EVENTSEL0, 2); + clear_msr_range(MSR_ARCH_PERFMON_PERFCTR0, 2); evntsel = ARCH_PERFMON_EVENTSEL_INT | ARCH_PERFMON_EVENTSEL_OS @@ -705,145 +493,51 @@ static int setup_intel_arch_watchdog(void) | ARCH_PERFMON_NMI_EVENT_SEL | ARCH_PERFMON_NMI_EVENT_UMASK; - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - write_watchdog_counter(perfctr_msr, "INTEL_ARCH_PERFCTR0"); + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); + write_watchdog_counter("INTEL_ARCH_PERFCTR0"); apic_write(APIC_LVTPC, APIC_DM_NMI); evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL << (eax.split.bit_width - 1); + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); return 1; -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; -} - -static void stop_intel_arch_watchdog(void) -{ - unsigned int ebx; - union cpuid10_eax eax; - unsigned int unused; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* - * Check whether the Architectural PerfMon supports - * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebx indicates event present. - */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); - if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || - (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - return; - - wrmsr(wd->evntsel_msr, 0, 0); - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); } -void setup_apic_nmi_watchdog (void *unused) +void setup_apic_nmi_watchdog (void) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* only support LOCAL and IO APICs for now */ - if ((nmi_watchdog != NMI_LOCAL_APIC) && - (nmi_watchdog != NMI_IO_APIC)) - return; - - if (wd->enabled == 1) - return; - - /* cheap hack to support suspend/resume */ - /* if cpu0 is not active neither should the other cpus */ - if ((smp_processor_id() != 0) && (atomic_read(&nmi_active) <= 0)) - return; - - if (nmi_watchdog == NMI_LOCAL_APIC) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15) + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15) + return; + setup_k7_watchdog(); + break; + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + if (!setup_intel_arch_watchdog()) return; - if (!setup_k7_watchdog()) + break; + } + switch (boot_cpu_data.x86) { + case 6: + if (boot_cpu_data.x86_model > 0xd) return; + + setup_p6_watchdog(); break; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - if (!setup_intel_arch_watchdog()) - return; - break; - } - switch (boot_cpu_data.x86) { - case 6: - if (boot_cpu_data.x86_model > 0xd) - return; - - if (!setup_p6_watchdog()) - return; - break; - case 15: - if (boot_cpu_data.x86_model > 0x4) - return; + case 15: + if (boot_cpu_data.x86_model > 0x4) + return; - if (!setup_p4_watchdog()) - return; - break; - default: + if (!setup_p4_watchdog()) return; - } break; default: return; } - } - wd->enabled = 1; - atomic_inc(&nmi_active); -} - -void stop_apic_nmi_watchdog(void *unused) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* only support LOCAL and IO APICs for now */ - if ((nmi_watchdog != NMI_LOCAL_APIC) && - (nmi_watchdog != NMI_IO_APIC)) - return; - - if (wd->enabled == 0) + break; + default: return; - - if (nmi_watchdog == NMI_LOCAL_APIC) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - stop_k7_watchdog(); - break; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - stop_intel_arch_watchdog(); - break; - } - switch (boot_cpu_data.x86) { - case 6: - if (boot_cpu_data.x86_model > 0xd) - break; - stop_p6_watchdog(); - break; - case 15: - if (boot_cpu_data.x86_model > 0x4) - break; - stop_p4_watchdog(); - break; - } - break; - default: - return; - } } - wd->enabled = 0; - atomic_dec(&nmi_active); + lapic_nmi_owner = LAPIC_NMI_WATCHDOG; + nmi_active = 1; } /* @@ -885,7 +579,7 @@ EXPORT_SYMBOL(touch_nmi_watchdog); extern void die_nmi(struct pt_regs *, const char *msg); -__kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) +void nmi_watchdog_tick (struct pt_regs * regs) { /* @@ -894,23 +588,11 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) * smp_processor_id(). */ unsigned int sum; - int touched = 0; int cpu = smp_processor_id(); - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - u64 dummy; - int rc=0; - - /* check for other users first */ - if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) - == NOTIFY_STOP) { - rc = 1; - touched = 1; - } sum = per_cpu(irq_stat, cpu).apic_timer_irqs; - /* if the apic timer isn't firing, this cpu isn't doing much */ - if (!touched && last_irq_sums[cpu] == sum) { + if (last_irq_sums[cpu] == sum) { /* * Ayiee, looks like this CPU is stuck ... * wait a few IRQs (5 seconds) before doing the oops ... @@ -925,59 +607,27 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) last_irq_sums[cpu] = sum; alert_counter[cpu] = 0; } - /* see if the nmi watchdog went off */ - if (wd->enabled) { - if (nmi_watchdog == NMI_LOCAL_APIC) { - rdmsrl(wd->perfctr_msr, dummy); - if (dummy & wd->check_bit){ - /* this wasn't a watchdog timer interrupt */ - goto done; - } - - /* only Intel P4 uses the cccr msr */ - if (wd->cccr_msr != 0) { - /* - * P4 quirks: - * - An overflown perfctr will assert its interrupt - * until the OVF flag in its CCCR is cleared. - * - LVTPC is masked on interrupt and must be - * unmasked by the LVTPC handler. - */ - rdmsrl(wd->cccr_msr, dummy); - dummy &= ~P4_CCCR_OVF; - wrmsrl(wd->cccr_msr, dummy); - apic_write(APIC_LVTPC, APIC_DM_NMI); - } - else if (wd->perfctr_msr == MSR_P6_PERFCTR0 || - wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { - /* P6 based Pentium M need to re-unmask - * the apic vector but it doesn't hurt - * other P6 variant. - * ArchPerfom/Core Duo also needs this */ - apic_write(APIC_LVTPC, APIC_DM_NMI); - } - /* start the cycle over again */ - write_watchdog_counter(wd->perfctr_msr, NULL); - rc = 1; - } else if (nmi_watchdog == NMI_IO_APIC) { - /* don't know how to accurately check for this. - * just assume it was a watchdog timer interrupt - * This matches the old behaviour. + if (nmi_perfctr_msr) { + if (nmi_perfctr_msr == MSR_P4_IQ_COUNTER0) { + /* + * P4 quirks: + * - An overflown perfctr will assert its interrupt + * until the OVF flag in its CCCR is cleared. + * - LVTPC is masked on interrupt and must be + * unmasked by the LVTPC handler. */ - rc = 1; + wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); + apic_write(APIC_LVTPC, APIC_DM_NMI); } + else if (nmi_perfctr_msr == MSR_P6_PERFCTR0 || + nmi_perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { + /* Only P6 based Pentium M need to re-unmask + * the apic vector but it doesn't hurt + * other P6 variant */ + apic_write(APIC_LVTPC, APIC_DM_NMI); + } + write_watchdog_counter(NULL); } -done: - return rc; -} - -int do_nmi_callback(struct pt_regs * regs, int cpu) -{ -#ifdef CONFIG_SYSCTL - if (unknown_nmi_panic) - return unknown_nmi_panic_callback(regs, cpu); -#endif - return 0; } #ifdef CONFIG_SYSCTL @@ -987,46 +637,36 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) unsigned char reason = get_nmi_reason(); char buf[64]; - sprintf(buf, "NMI received for unknown reason %02x\n", reason); - die_nmi(regs, buf); + if (!(reason & 0xc0)) { + sprintf(buf, "NMI received for unknown reason %02x\n", reason); + die_nmi(regs, buf); + } return 0; } /* - * proc handler for /proc/sys/kernel/nmi + * proc handler for /proc/sys/kernel/unknown_nmi_panic */ -int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, +int proc_unknown_nmi_panic(ctl_table *table, int write, struct file *file, void __user *buffer, size_t *length, loff_t *ppos) { int old_state; - nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0; - old_state = nmi_watchdog_enabled; + old_state = unknown_nmi_panic; proc_dointvec(table, write, file, buffer, length, ppos); - if (!!old_state == !!nmi_watchdog_enabled) + if (!!old_state == !!unknown_nmi_panic) return 0; - if (atomic_read(&nmi_active) < 0) { - printk( KERN_WARNING "NMI watchdog is permanently disabled\n"); - return -EIO; - } - - if (nmi_watchdog == NMI_DEFAULT) { - if (nmi_known_cpu() > 0) - nmi_watchdog = NMI_LOCAL_APIC; - else - nmi_watchdog = NMI_IO_APIC; - } - - if (nmi_watchdog == NMI_LOCAL_APIC) { - if (nmi_watchdog_enabled) - enable_lapic_nmi_watchdog(); - else - disable_lapic_nmi_watchdog(); + if (unknown_nmi_panic) { + if (reserve_lapic_nmi() < 0) { + unknown_nmi_panic = 0; + return -EBUSY; + } else { + set_nmi_callback(unknown_nmi_panic_callback); + } } else { - printk( KERN_WARNING - "NMI watchdog doesn't know what hardware to touch\n"); - return -EIO; + release_lapic_nmi(); + unset_nmi_callback(); } return 0; } @@ -1035,11 +675,7 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); -EXPORT_SYMBOL(reserve_perfctr_nmi); -EXPORT_SYMBOL(release_perfctr_nmi); -EXPORT_SYMBOL(reserve_evntsel_nmi); -EXPORT_SYMBOL(release_evntsel_nmi); +EXPORT_SYMBOL(reserve_lapic_nmi); +EXPORT_SYMBOL(release_lapic_nmi); EXPORT_SYMBOL(disable_timer_nmi_watchdog); EXPORT_SYMBOL(enable_timer_nmi_watchdog); diff --git a/trunk/arch/i386/kernel/process.c b/trunk/arch/i386/kernel/process.c index dad02a960e03..8657c739656a 100644 --- a/trunk/arch/i386/kernel/process.c +++ b/trunk/arch/i386/kernel/process.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -297,9 +296,9 @@ void show_regs(struct pt_regs * regs) if (user_mode_vm(regs)) printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); printk(" EFLAGS: %08lx %s (%s %.*s)\n", - regs->eflags, print_tainted(), init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); + regs->eflags, print_tainted(), system_utsname.release, + (int)strcspn(system_utsname.version, " "), + system_utsname.version); printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", regs->eax,regs->ebx,regs->ecx,regs->edx); printk("ESI: %08lx EDI: %08lx EBP: %08lx", @@ -321,6 +320,15 @@ void show_regs(struct pt_regs * regs) * the "args". */ extern void kernel_thread_helper(void); +__asm__(".section .text\n" + ".align 4\n" + "kernel_thread_helper:\n\t" + "movl %edx,%eax\n\t" + "pushl %edx\n\t" + "call *%ebx\n\t" + "pushl %eax\n\t" + "call do_exit\n" + ".previous"); /* * Create a kernel thread @@ -338,7 +346,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) regs.xes = __USER_DS; regs.orig_eax = -1; regs.eip = (unsigned long) kernel_thread_helper; - regs.xcs = __KERNEL_CS | get_kernel_rpl(); + regs.xcs = __KERNEL_CS; regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; /* Ok, create the new process.. */ @@ -425,12 +433,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, tsk = current; if (unlikely(test_tsk_thread_flag(tsk, TIF_IO_BITMAP))) { - p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr, - IO_BITMAP_BYTES, GFP_KERNEL); + p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); if (!p->thread.io_bitmap_ptr) { p->thread.io_bitmap_max = 0; return -ENOMEM; } + memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr, + IO_BITMAP_BYTES); set_tsk_thread_flag(p, TIF_IO_BITMAP); } @@ -896,7 +905,7 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *u_info) unsigned long arch_align_stack(unsigned long sp) { - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) + if (randomize_va_space) sp -= get_random_int() % 8192; return sp & ~0xf; } diff --git a/trunk/arch/i386/kernel/ptrace.c b/trunk/arch/i386/kernel/ptrace.c index 775f50e9395b..d3db03f4085d 100644 --- a/trunk/arch/i386/kernel/ptrace.c +++ b/trunk/arch/i386/kernel/ptrace.c @@ -185,17 +185,17 @@ static unsigned long convert_eip_to_linear(struct task_struct *child, struct pt_ return addr; } -static inline int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs) +static inline int is_at_popf(struct task_struct *child, struct pt_regs *regs) { int i, copied; - unsigned char opcode[15]; + unsigned char opcode[16]; unsigned long addr = convert_eip_to_linear(child, regs); copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); for (i = 0; i < copied; i++) { switch (opcode[i]) { - /* popf and iret */ - case 0x9d: case 0xcf: + /* popf */ + case 0x9d: return 1; /* opcode and address size prefixes */ case 0x66: case 0x67: @@ -247,7 +247,7 @@ static void set_singlestep(struct task_struct *child) * don't mark it as being "us" that set it, so that we * won't clear it by hand later. */ - if (is_setting_trap_flag(child, regs)) + if (is_at_popf(child, regs)) return; child->ptrace |= PT_DTRACE; diff --git a/trunk/arch/i386/kernel/relocate_kernel.S b/trunk/arch/i386/kernel/relocate_kernel.S index f151d6fae462..d312616effa1 100644 --- a/trunk/arch/i386/kernel/relocate_kernel.S +++ b/trunk/arch/i386/kernel/relocate_kernel.S @@ -7,138 +7,16 @@ */ #include -#include -#include - -/* - * Must be relocatable PIC code callable as a C function - */ - -#define PTR(x) (x << 2) -#define PAGE_ALIGNED (1 << PAGE_SHIFT) -#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */ -#define PAE_PGD_ATTR 0x01 /* _PAGE_PRESENT */ - - .text - .align PAGE_ALIGNED - .globl relocate_kernel -relocate_kernel: - movl 8(%esp), %ebp /* list of pages */ - -#ifdef CONFIG_X86_PAE - /* map the control page at its virtual address */ - - movl PTR(VA_PGD)(%ebp), %edi - movl PTR(VA_CONTROL_PAGE)(%ebp), %eax - andl $0xc0000000, %eax - shrl $27, %eax - addl %edi, %eax - - movl PTR(PA_PMD_0)(%ebp), %edx - orl $PAE_PGD_ATTR, %edx - movl %edx, (%eax) - - movl PTR(VA_PMD_0)(%ebp), %edi - movl PTR(VA_CONTROL_PAGE)(%ebp), %eax - andl $0x3fe00000, %eax - shrl $18, %eax - addl %edi, %eax - - movl PTR(PA_PTE_0)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) - - movl PTR(VA_PTE_0)(%ebp), %edi - movl PTR(VA_CONTROL_PAGE)(%ebp), %eax - andl $0x001ff000, %eax - shrl $9, %eax - addl %edi, %eax - - movl PTR(PA_CONTROL_PAGE)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) - - /* identity map the control page at its physical address */ - - movl PTR(VA_PGD)(%ebp), %edi - movl PTR(PA_CONTROL_PAGE)(%ebp), %eax - andl $0xc0000000, %eax - shrl $27, %eax - addl %edi, %eax - - movl PTR(PA_PMD_1)(%ebp), %edx - orl $PAE_PGD_ATTR, %edx - movl %edx, (%eax) - - movl PTR(VA_PMD_1)(%ebp), %edi - movl PTR(PA_CONTROL_PAGE)(%ebp), %eax - andl $0x3fe00000, %eax - shrl $18, %eax - addl %edi, %eax - - movl PTR(PA_PTE_1)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) - - movl PTR(VA_PTE_1)(%ebp), %edi - movl PTR(PA_CONTROL_PAGE)(%ebp), %eax - andl $0x001ff000, %eax - shrl $9, %eax - addl %edi, %eax - - movl PTR(PA_CONTROL_PAGE)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) -#else - /* map the control page at its virtual address */ - - movl PTR(VA_PGD)(%ebp), %edi - movl PTR(VA_CONTROL_PAGE)(%ebp), %eax - andl $0xffc00000, %eax - shrl $20, %eax - addl %edi, %eax - - movl PTR(PA_PTE_0)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) - - movl PTR(VA_PTE_0)(%ebp), %edi - movl PTR(VA_CONTROL_PAGE)(%ebp), %eax - andl $0x003ff000, %eax - shrl $10, %eax - addl %edi, %eax - - movl PTR(PA_CONTROL_PAGE)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) - - /* identity map the control page at its physical address */ - - movl PTR(VA_PGD)(%ebp), %edi - movl PTR(PA_CONTROL_PAGE)(%ebp), %eax - andl $0xffc00000, %eax - shrl $20, %eax - addl %edi, %eax - - movl PTR(PA_PTE_1)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) - - movl PTR(VA_PTE_1)(%ebp), %edi - movl PTR(PA_CONTROL_PAGE)(%ebp), %eax - andl $0x003ff000, %eax - shrl $10, %eax - addl %edi, %eax - - movl PTR(PA_CONTROL_PAGE)(%ebp), %edx - orl $PAGE_ATTR, %edx - movl %edx, (%eax) -#endif + /* + * Must be relocatable PIC code callable as a C function, that once + * it starts can not use the previous processes stack. + */ + .globl relocate_new_kernel relocate_new_kernel: /* read the arguments and say goodbye to the stack */ movl 4(%esp), %ebx /* page_list */ - movl 8(%esp), %ebp /* list of pages */ + movl 8(%esp), %ebp /* reboot_code_buffer */ movl 12(%esp), %edx /* start address */ movl 16(%esp), %ecx /* cpu_has_pae */ @@ -146,26 +24,11 @@ relocate_new_kernel: pushl $0 popfl - /* get physical address of control page now */ - /* this is impossible after page table switch */ - movl PTR(PA_CONTROL_PAGE)(%ebp), %edi + /* set a new stack at the bottom of our page... */ + lea 4096(%ebp), %esp - /* switch to new set of page tables */ - movl PTR(PA_PGD)(%ebp), %eax - movl %eax, %cr3 - - /* setup a new stack at the end of the physical control page */ - lea 4096(%edi), %esp - - /* jump to identity mapped page */ - movl %edi, %eax - addl $(identity_mapped - relocate_kernel), %eax - pushl %eax - ret - -identity_mapped: - /* store the start address on the stack */ - pushl %edx + /* store the parameters back on the stack */ + pushl %edx /* store the start address */ /* Set cr0 to a known state: * 31 0 == Paging disabled @@ -250,3 +113,8 @@ identity_mapped: xorl %edi, %edi xorl %ebp, %ebp ret +relocate_new_kernel_end: + + .globl relocate_new_kernel_size +relocate_new_kernel_size: + .long relocate_new_kernel_end - relocate_new_kernel diff --git a/trunk/arch/i386/kernel/semaphore.c b/trunk/arch/i386/kernel/semaphore.c new file mode 100644 index 000000000000..98352c374c76 --- /dev/null +++ b/trunk/arch/i386/kernel/semaphore.c @@ -0,0 +1,134 @@ +/* + * i386 semaphore implementation. + * + * (C) Copyright 1999 Linus Torvalds + * + * Portions Copyright 1999 Red Hat, Inc. + * + * 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. + * + * rw semaphores implemented November 1999 by Benjamin LaHaise + */ +#include + +/* + * The semaphore operations have a special calling sequence that + * allow us to do a simpler in-line version of them. These routines + * need to convert that sequence back into the C sequence when + * there is contention on the semaphore. + * + * %eax contains the semaphore pointer on entry. Save the C-clobbered + * registers (%eax, %edx and %ecx) except %eax whish is either a return + * value or just clobbered.. + */ +asm( +".section .sched.text\n" +".align 4\n" +".globl __down_failed\n" +"__down_failed:\n\t" +#if defined(CONFIG_FRAME_POINTER) + "pushl %ebp\n\t" + "movl %esp,%ebp\n\t" +#endif + "pushl %edx\n\t" + "pushl %ecx\n\t" + "call __down\n\t" + "popl %ecx\n\t" + "popl %edx\n\t" +#if defined(CONFIG_FRAME_POINTER) + "movl %ebp,%esp\n\t" + "popl %ebp\n\t" +#endif + "ret" +); + +asm( +".section .sched.text\n" +".align 4\n" +".globl __down_failed_interruptible\n" +"__down_failed_interruptible:\n\t" +#if defined(CONFIG_FRAME_POINTER) + "pushl %ebp\n\t" + "movl %esp,%ebp\n\t" +#endif + "pushl %edx\n\t" + "pushl %ecx\n\t" + "call __down_interruptible\n\t" + "popl %ecx\n\t" + "popl %edx\n\t" +#if defined(CONFIG_FRAME_POINTER) + "movl %ebp,%esp\n\t" + "popl %ebp\n\t" +#endif + "ret" +); + +asm( +".section .sched.text\n" +".align 4\n" +".globl __down_failed_trylock\n" +"__down_failed_trylock:\n\t" +#if defined(CONFIG_FRAME_POINTER) + "pushl %ebp\n\t" + "movl %esp,%ebp\n\t" +#endif + "pushl %edx\n\t" + "pushl %ecx\n\t" + "call __down_trylock\n\t" + "popl %ecx\n\t" + "popl %edx\n\t" +#if defined(CONFIG_FRAME_POINTER) + "movl %ebp,%esp\n\t" + "popl %ebp\n\t" +#endif + "ret" +); + +asm( +".section .sched.text\n" +".align 4\n" +".globl __up_wakeup\n" +"__up_wakeup:\n\t" + "pushl %edx\n\t" + "pushl %ecx\n\t" + "call __up\n\t" + "popl %ecx\n\t" + "popl %edx\n\t" + "ret" +); + +/* + * rw spinlock fallbacks + */ +#if defined(CONFIG_SMP) +asm( +".section .sched.text\n" +".align 4\n" +".globl __write_lock_failed\n" +"__write_lock_failed:\n\t" + LOCK_PREFIX "addl $" RW_LOCK_BIAS_STR ",(%eax)\n" +"1: rep; nop\n\t" + "cmpl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" + "jne 1b\n\t" + LOCK_PREFIX "subl $" RW_LOCK_BIAS_STR ",(%eax)\n\t" + "jnz __write_lock_failed\n\t" + "ret" +); + +asm( +".section .sched.text\n" +".align 4\n" +".globl __read_lock_failed\n" +"__read_lock_failed:\n\t" + LOCK_PREFIX "incl (%eax)\n" +"1: rep; nop\n\t" + "cmpl $1,(%eax)\n\t" + "js 1b\n\t" + LOCK_PREFIX "decl (%eax)\n\t" + "js __read_lock_failed\n\t" + "ret" +); +#endif diff --git a/trunk/arch/i386/kernel/setup.c b/trunk/arch/i386/kernel/setup.c index 000cf03751fe..16d99444cf66 100644 --- a/trunk/arch/i386/kernel/setup.c +++ b/trunk/arch/i386/kernel/setup.c @@ -90,6 +90,18 @@ EXPORT_SYMBOL(boot_cpu_data); unsigned long mmu_cr4_features; +#ifdef CONFIG_ACPI + int acpi_disabled = 0; +#else + int acpi_disabled = 1; +#endif +EXPORT_SYMBOL(acpi_disabled); + +#ifdef CONFIG_ACPI +int __initdata acpi_force = 0; +extern acpi_interrupt_flags acpi_sci_flags; +#endif + /* for MCA, but anyone else can use it if they want */ unsigned int machine_id; #ifdef CONFIG_MCA @@ -137,6 +149,7 @@ EXPORT_SYMBOL(ist_info); struct e820map e820; extern void early_cpu_init(void); +extern void generic_apic_probe(char *); extern int root_mountflags; unsigned long saved_videomode; @@ -209,6 +222,9 @@ static struct resource adapter_rom_resources[] = { { .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM } }; +#define ADAPTER_ROM_RESOURCES \ + (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0]) + static struct resource video_rom_resource = { .name = "Video ROM", .start = 0xc0000, @@ -270,6 +286,9 @@ static struct resource standard_io_resources[] = { { .flags = IORESOURCE_BUSY | IORESOURCE_IO } }; +#define STANDARD_IO_RESOURCES \ + (sizeof standard_io_resources / sizeof standard_io_resources[0]) + #define romsignature(x) (*(unsigned short *)(x) == 0xaa55) static int __init romchecksum(unsigned char *rom, unsigned long length) @@ -326,7 +345,7 @@ static void __init probe_roms(void) } /* check for adapter roms on 2k boundaries */ - for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { + for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) { rom = isa_bus_to_virt(start); if (!romsignature(rom)) continue; @@ -682,132 +701,238 @@ static inline void copy_edd(void) } #endif -static int __initdata user_defined_memmap = 0; - -/* - * "mem=nopentium" disables the 4MB page tables. - * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM - * to , overriding the bios size. - * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from - * to +, overriding the bios size. - * - * HPA tells me bootloaders need to parse mem=, so no new - * option should be mem= [also see Documentation/i386/boot.txt] - */ -static int __init parse_mem(char *arg) +static void __init parse_cmdline_early (char ** cmdline_p) { - if (!arg) - return -EINVAL; + char c = ' ', *to = command_line, *from = saved_command_line; + int len = 0; + int userdef = 0; - if (strcmp(arg, "nopentium") == 0) { - clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); - disable_pse = 1; - } else { - /* If the user specifies memory size, we - * limit the BIOS-provided memory map to - * that size. exactmap can be used to specify - * the exact map. mem=number can be used to - * trim the existing memory map. + /* Save unparsed command line copy for /proc/cmdline */ + saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; + + for (;;) { + if (c != ' ') + goto next_char; + /* + * "mem=nopentium" disables the 4MB page tables. + * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM + * to , overriding the bios size. + * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from + * to +, overriding the bios size. + * + * HPA tells me bootloaders need to parse mem=, so no new + * option should be mem= [also see Documentation/i386/boot.txt] */ - unsigned long long mem_size; + if (!memcmp(from, "mem=", 4)) { + if (to != command_line) + to--; + if (!memcmp(from+4, "nopentium", 9)) { + from += 9+4; + clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); + disable_pse = 1; + } else { + /* If the user specifies memory size, we + * limit the BIOS-provided memory map to + * that size. exactmap can be used to specify + * the exact map. mem=number can be used to + * trim the existing memory map. + */ + unsigned long long mem_size; - mem_size = memparse(arg, &arg); - limit_regions(mem_size); - user_defined_memmap = 1; - } - return 0; -} -early_param("mem", parse_mem); - -static int __init parse_memmap(char *arg) -{ - if (!arg) - return -EINVAL; + mem_size = memparse(from+4, &from); + limit_regions(mem_size); + userdef=1; + } + } - if (strcmp(arg, "exactmap") == 0) { + else if (!memcmp(from, "memmap=", 7)) { + if (to != command_line) + to--; + if (!memcmp(from+7, "exactmap", 8)) { #ifdef CONFIG_CRASH_DUMP - /* If we are doing a crash dump, we - * still need to know the real mem - * size before original memory map is - * reset. - */ - find_max_pfn(); - saved_max_pfn = max_pfn; + /* If we are doing a crash dump, we + * still need to know the real mem + * size before original memory map is + * reset. + */ + find_max_pfn(); + saved_max_pfn = max_pfn; #endif - e820.nr_map = 0; - user_defined_memmap = 1; - } else { - /* If the user specifies memory size, we - * limit the BIOS-provided memory map to - * that size. exactmap can be used to specify - * the exact map. mem=number can be used to - * trim the existing memory map. + from += 8+7; + e820.nr_map = 0; + userdef = 1; + } else { + /* If the user specifies memory size, we + * limit the BIOS-provided memory map to + * that size. exactmap can be used to specify + * the exact map. mem=number can be used to + * trim the existing memory map. + */ + unsigned long long start_at, mem_size; + + mem_size = memparse(from+7, &from); + if (*from == '@') { + start_at = memparse(from+1, &from); + add_memory_region(start_at, mem_size, E820_RAM); + } else if (*from == '#') { + start_at = memparse(from+1, &from); + add_memory_region(start_at, mem_size, E820_ACPI); + } else if (*from == '$') { + start_at = memparse(from+1, &from); + add_memory_region(start_at, mem_size, E820_RESERVED); + } else { + limit_regions(mem_size); + userdef=1; + } + } + } + + else if (!memcmp(from, "noexec=", 7)) + noexec_setup(from + 7); + + +#ifdef CONFIG_X86_SMP + /* + * If the BIOS enumerates physical processors before logical, + * maxcpus=N at enumeration-time can be used to disable HT. */ - unsigned long long start_at, mem_size; - - mem_size = memparse(arg, &arg); - if (*arg == '@') { - start_at = memparse(arg+1, &arg); - add_memory_region(start_at, mem_size, E820_RAM); - } else if (*arg == '#') { - start_at = memparse(arg+1, &arg); - add_memory_region(start_at, mem_size, E820_ACPI); - } else if (*arg == '$') { - start_at = memparse(arg+1, &arg); - add_memory_region(start_at, mem_size, E820_RESERVED); - } else { - limit_regions(mem_size); - user_defined_memmap = 1; + else if (!memcmp(from, "maxcpus=", 8)) { + extern unsigned int maxcpus; + + maxcpus = simple_strtoul(from + 8, NULL, 0); } - } - return 0; -} -early_param("memmap", parse_memmap); +#endif -#ifdef CONFIG_PROC_VMCORE -/* elfcorehdr= specifies the location of elf core header - * stored by the crashed kernel. - */ -static int __init parse_elfcorehdr(char *arg) -{ - if (!arg) - return -EINVAL; +#ifdef CONFIG_ACPI + /* "acpi=off" disables both ACPI table parsing and interpreter */ + else if (!memcmp(from, "acpi=off", 8)) { + disable_acpi(); + } - elfcorehdr_addr = memparse(arg, &arg); - return 0; -} -early_param("elfcorehdr", parse_elfcorehdr); -#endif /* CONFIG_PROC_VMCORE */ + /* acpi=force to over-ride black-list */ + else if (!memcmp(from, "acpi=force", 10)) { + acpi_force = 1; + acpi_ht = 1; + acpi_disabled = 0; + } -/* - * highmem=size forces highmem to be exactly 'size' bytes. - * This works even on boxes that have no highmem otherwise. - * This also works to reduce highmem size on bigger boxes. - */ -static int __init parse_highmem(char *arg) -{ - if (!arg) - return -EINVAL; + /* acpi=strict disables out-of-spec workarounds */ + else if (!memcmp(from, "acpi=strict", 11)) { + acpi_strict = 1; + } - highmem_pages = memparse(arg, &arg) >> PAGE_SHIFT; - return 0; -} -early_param("highmem", parse_highmem); + /* Limit ACPI just to boot-time to enable HT */ + else if (!memcmp(from, "acpi=ht", 7)) { + if (!acpi_force) + disable_acpi(); + acpi_ht = 1; + } + + /* "pci=noacpi" disable ACPI IRQ routing and PCI scan */ + else if (!memcmp(from, "pci=noacpi", 10)) { + acpi_disable_pci(); + } + /* "acpi=noirq" disables ACPI interrupt routing */ + else if (!memcmp(from, "acpi=noirq", 10)) { + acpi_noirq_set(); + } -/* - * vmalloc=size forces the vmalloc area to be exactly 'size' - * bytes. This can be used to increase (or decrease) the - * vmalloc area - the default is 128m. - */ -static int __init parse_vmalloc(char *arg) -{ - if (!arg) - return -EINVAL; + else if (!memcmp(from, "acpi_sci=edge", 13)) + acpi_sci_flags.trigger = 1; - __VMALLOC_RESERVE = memparse(arg, &arg); - return 0; + else if (!memcmp(from, "acpi_sci=level", 14)) + acpi_sci_flags.trigger = 3; + + else if (!memcmp(from, "acpi_sci=high", 13)) + acpi_sci_flags.polarity = 1; + + else if (!memcmp(from, "acpi_sci=low", 12)) + acpi_sci_flags.polarity = 3; + +#ifdef CONFIG_X86_IO_APIC + else if (!memcmp(from, "acpi_skip_timer_override", 24)) + acpi_skip_timer_override = 1; + + if (!memcmp(from, "disable_timer_pin_1", 19)) + disable_timer_pin_1 = 1; + if (!memcmp(from, "enable_timer_pin_1", 18)) + disable_timer_pin_1 = -1; + + /* disable IO-APIC */ + else if (!memcmp(from, "noapic", 6)) + disable_ioapic_setup(); +#endif /* CONFIG_X86_IO_APIC */ +#endif /* CONFIG_ACPI */ + +#ifdef CONFIG_X86_LOCAL_APIC + /* enable local APIC */ + else if (!memcmp(from, "lapic", 5)) + lapic_enable(); + + /* disable local APIC */ + else if (!memcmp(from, "nolapic", 6)) + lapic_disable(); +#endif /* CONFIG_X86_LOCAL_APIC */ + +#ifdef CONFIG_KEXEC + /* crashkernel=size@addr specifies the location to reserve for + * a crash kernel. By reserving this memory we guarantee + * that linux never set's it up as a DMA target. + * Useful for holding code to do something appropriate + * after a kernel panic. + */ + else if (!memcmp(from, "crashkernel=", 12)) { + unsigned long size, base; + size = memparse(from+12, &from); + if (*from == '@') { + base = memparse(from+1, &from); + /* FIXME: Do I want a sanity check + * to validate the memory range? + */ + crashk_res.start = base; + crashk_res.end = base + size - 1; + } + } +#endif +#ifdef CONFIG_PROC_VMCORE + /* elfcorehdr= specifies the location of elf core header + * stored by the crashed kernel. + */ + else if (!memcmp(from, "elfcorehdr=", 11)) + elfcorehdr_addr = memparse(from+11, &from); +#endif + + /* + * highmem=size forces highmem to be exactly 'size' bytes. + * This works even on boxes that have no highmem otherwise. + * This also works to reduce highmem size on bigger boxes. + */ + else if (!memcmp(from, "highmem=", 8)) + highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT; + + /* + * vmalloc=size forces the vmalloc area to be exactly 'size' + * bytes. This can be used to increase (or decrease) the + * vmalloc area - the default is 128m. + */ + else if (!memcmp(from, "vmalloc=", 8)) + __VMALLOC_RESERVE = memparse(from+8, &from); + + next_char: + c = *(from++); + if (!c) + break; + if (COMMAND_LINE_SIZE <= ++len) + break; + *(to++) = c; + } + *to = '\0'; + *cmdline_p = command_line; + if (userdef) { + printk(KERN_INFO "user-defined physical RAM map:\n"); + print_memory_map("user"); + } } -early_param("vmalloc", parse_vmalloc); /* * reservetop=size reserves a hole at the top of the kernel address space which @@ -1064,14 +1189,6 @@ static unsigned long __init setup_memory(void) } printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", pages_to_mb(highend_pfn - highstart_pfn)); - num_physpages = highend_pfn; - high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; -#else - num_physpages = max_low_pfn; - high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1; -#endif -#ifdef CONFIG_FLATMEM - max_mapnr = num_physpages; #endif printk(KERN_NOTICE "%ldMB LOWMEM available.\n", pages_to_mb(max_low_pfn)); @@ -1083,20 +1200,22 @@ static unsigned long __init setup_memory(void) void __init zone_sizes_init(void) { + unsigned long zones_size[MAX_NR_ZONES] = { 0, }; + unsigned int max_dma, low; + + max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; + low = max_low_pfn; + + if (low < max_dma) + zones_size[ZONE_DMA] = low; + else { + zones_size[ZONE_DMA] = max_dma; + zones_size[ZONE_NORMAL] = low - max_dma; #ifdef CONFIG_HIGHMEM - unsigned long max_zone_pfns[MAX_NR_ZONES] = { - virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT, - max_low_pfn, - highend_pfn}; - add_active_range(0, 0, highend_pfn); -#else - unsigned long max_zone_pfns[MAX_NR_ZONES] = { - virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT, - max_low_pfn}; - add_active_range(0, 0, max_low_pfn); + zones_size[ZONE_HIGHMEM] = highend_pfn - low; #endif - - free_area_init_nodes(max_zone_pfns); + } + free_area_init(zones_size); } #else extern unsigned long __init setup_memory(void); @@ -1266,7 +1385,7 @@ static int __init request_standard_resources(void) request_resource(&iomem_resource, &video_ram_resource); /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) + for (i = 0; i < STANDARD_IO_RESOURCES; i++) request_resource(&ioport_resource, &standard_io_resources[i]); return 0; } @@ -1399,15 +1518,17 @@ void __init setup_arch(char **cmdline_p) data_resource.start = virt_to_phys(_etext); data_resource.end = virt_to_phys(_edata)-1; - parse_early_param(); + parse_cmdline_early(cmdline_p); - if (user_defined_memmap) { - printk(KERN_INFO "user-defined physical RAM map:\n"); - print_memory_map("user"); +#ifdef CONFIG_EARLY_PRINTK + { + char *s = strstr(*cmdline_p, "earlyprintk="); + if (s) { + setup_early_printk(strchr(s, '=') + 1); + printk("early console enabled\n"); + } } - - strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; +#endif max_low_pfn = setup_memory(); @@ -1436,7 +1557,7 @@ void __init setup_arch(char **cmdline_p) dmi_scan_machine(); #ifdef CONFIG_X86_GENERICARCH - generic_apic_probe(); + generic_apic_probe(*cmdline_p); #endif if (efi_enabled) efi_map_memmap(); @@ -1448,11 +1569,9 @@ void __init setup_arch(char **cmdline_p) acpi_boot_table_init(); #endif -#ifdef CONFIG_PCI #ifdef CONFIG_X86_IO_APIC check_acpi_pci(); /* Checks more than just ACPI actually */ #endif -#endif #ifdef CONFIG_ACPI acpi_boot_init(); diff --git a/trunk/arch/i386/kernel/smp.c b/trunk/arch/i386/kernel/smp.c index 1b080ab8a49f..465188e2d701 100644 --- a/trunk/arch/i386/kernel/smp.c +++ b/trunk/arch/i386/kernel/smp.c @@ -700,30 +700,3 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info, return 0; } EXPORT_SYMBOL(smp_call_function_single); - -static int convert_apicid_to_cpu(int apic_id) -{ - int i; - - for (i = 0; i < NR_CPUS; i++) { - if (x86_cpu_to_apicid[i] == apic_id) - return i; - } - return -1; -} - -int safe_smp_processor_id(void) -{ - int apicid, cpuid; - - if (!boot_cpu_has(X86_FEATURE_APIC)) - return 0; - - apicid = hard_smp_processor_id(); - if (apicid == BAD_APICID) - return 0; - - cpuid = convert_apicid_to_cpu(apicid); - - return cpuid >= 0 ? cpuid : 0; -} diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c index 9d93ecf6d999..efe07990e7fc 100644 --- a/trunk/arch/i386/kernel/smpboot.c +++ b/trunk/arch/i386/kernel/smpboot.c @@ -102,8 +102,6 @@ u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0xff }; EXPORT_SYMBOL(x86_cpu_to_apicid); -u8 apicid_2_node[MAX_APICID]; - /* * Trampoline 80x86 program as an array. */ @@ -179,9 +177,6 @@ static void __devinit smp_store_cpu_info(int id) */ if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) { - if (num_possible_cpus() == 1) - goto valid_k7; - /* Athlon 660/661 is valid. */ if ((c->x86_model==6) && ((c->x86_mask==0) || (c->x86_mask==1))) goto valid_k7; @@ -612,7 +607,6 @@ extern struct { /* which logical CPUs are on which nodes */ cpumask_t node_2_cpu_mask[MAX_NUMNODES] __read_mostly = { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE }; -EXPORT_SYMBOL(node_2_cpu_mask); /* which node each logical CPU is on */ int cpu_2_node[NR_CPUS] __read_mostly = { [0 ... NR_CPUS-1] = 0 }; EXPORT_SYMBOL(cpu_2_node); @@ -648,7 +642,7 @@ static void map_cpu_to_logical_apicid(void) { int cpu = smp_processor_id(); int apicid = logical_smp_processor_id(); - int node = apicid_to_node(hard_smp_processor_id()); + int node = apicid_to_node(apicid); if (!node_online(node)) node = first_online_node; @@ -957,7 +951,6 @@ static int __devinit do_boot_cpu(int apicid, int cpu) irq_ctx_init(cpu); - x86_cpu_to_apicid[cpu] = apicid; /* * This grunge runs the startup process for * the targeted processor. @@ -1062,7 +1055,7 @@ static void __cpuinit do_warm_boot_cpu(void *p) static int __cpuinit __smp_prepare_cpu(int cpu) { - DECLARE_COMPLETION_ONSTACK(done); + DECLARE_COMPLETION(done); struct warm_boot_cpu_info info; struct work_struct task; int apicid, ret; @@ -1383,8 +1376,7 @@ int __cpu_disable(void) */ if (cpu == 0) return -EBUSY; - if (nmi_watchdog == NMI_LOCAL_APIC) - stop_apic_nmi_watchdog(NULL); + clear_local_APIC(); /* Allow any queued timer interrupts to get serviced */ local_irq_enable(); @@ -1498,16 +1490,3 @@ void __init smp_intr_init(void) /* IPI for generic function call */ set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); } - -/* - * If the BIOS enumerates physical processors before logical, - * maxcpus=N at enumeration-time can be used to disable HT. - */ -static int __init parse_maxcpus(char *arg) -{ - extern unsigned int maxcpus; - - maxcpus = simple_strtoul(arg, NULL, 0); - return 0; -} -early_param("maxcpus", parse_maxcpus); diff --git a/trunk/arch/i386/kernel/srat.c b/trunk/arch/i386/kernel/srat.c index f7e735c077c3..83db411b3aa7 100644 --- a/trunk/arch/i386/kernel/srat.c +++ b/trunk/arch/i386/kernel/srat.c @@ -30,7 +30,6 @@ #include #include #include -#include /* * proximity macros and definitions @@ -55,7 +54,8 @@ struct node_memory_chunk_s { static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS]; static int num_memory_chunks; /* total number of memory chunks */ -static u8 __initdata apicid_to_pxm[MAX_APICID]; +static int zholes_size_init; +static unsigned long zholes_size[MAX_NUMNODES * MAX_NR_ZONES]; extern void * boot_ioremap(unsigned long, unsigned long); @@ -71,8 +71,6 @@ static void __init parse_cpu_affinity_structure(char *p) /* mark this node as "seen" in node bitmap */ BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain); - apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain; - printk("CPU 0x%02X in proximity domain 0x%02X\n", cpu_affinity->apic_id, cpu_affinity->proximity_domain); } @@ -137,6 +135,47 @@ static void __init parse_memory_affinity_structure (char *sratp) "enabled and removable" : "enabled" ) ); } +/* Take a chunk of pages from page frame cstart to cend and count the number + * of pages in each zone, returned via zones[]. + */ +static __init void chunk_to_zones(unsigned long cstart, unsigned long cend, + unsigned long *zones) +{ + unsigned long max_dma; + extern unsigned long max_low_pfn; + + int z; + unsigned long rend; + + /* FIXME: MAX_DMA_ADDRESS and max_low_pfn are trying to provide + * similarly scoped information and should be handled in a consistant + * manner. + */ + max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; + + /* Split the hole into the zones in which it falls. Repeatedly + * take the segment in which the remaining hole starts, round it + * to the end of that zone. + */ + memset(zones, 0, MAX_NR_ZONES * sizeof(long)); + while (cstart < cend) { + if (cstart < max_dma) { + z = ZONE_DMA; + rend = (cend < max_dma)? cend : max_dma; + + } else if (cstart < max_low_pfn) { + z = ZONE_NORMAL; + rend = (cend < max_low_pfn)? cend : max_low_pfn; + + } else { + z = ZONE_HIGHMEM; + rend = cend; + } + zones[z] += rend - cstart; + cstart = rend; + } +} + /* * The SRAT table always lists ascending addresses, so can always * assume that the first "start" address that you see is the real @@ -181,6 +220,7 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) memset(pxm_bitmap, 0, sizeof(pxm_bitmap)); /* init proximity domain bitmap */ memset(node_memory_chunk, 0, sizeof(node_memory_chunk)); + memset(zholes_size, 0, sizeof(zholes_size)); num_memory_chunks = 0; while (p < end) { @@ -239,15 +279,11 @@ static int __init acpi20_parse_srat(struct acpi_table_srat *sratp) printk("Number of logical nodes in system = %d\n", num_online_nodes()); printk("Number of memory chunks in system = %d\n", num_memory_chunks); - for (i = 0; i < MAX_APICID; i++) - apicid_2_node[i] = pxm_to_node(apicid_to_pxm[i]); - for (j = 0; j < num_memory_chunks; j++){ struct node_memory_chunk_s * chunk = &node_memory_chunk[j]; printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n", j, chunk->nid, chunk->start_pfn, chunk->end_pfn); node_read_chunk(chunk->nid, chunk); - add_active_range(chunk->nid, chunk->start_pfn, chunk->end_pfn); } for_each_online_node(nid) { @@ -356,7 +392,57 @@ int __init get_memcfg_from_srat(void) return acpi20_parse_srat((struct acpi_table_srat *)header); } out_err: - remove_all_active_ranges(); printk("failed to get NUMA memory information from SRAT table\n"); return 0; } + +/* For each node run the memory list to determine whether there are + * any memory holes. For each hole determine which ZONE they fall + * into. + * + * NOTE#1: this requires knowledge of the zone boundries and so + * _cannot_ be performed before those are calculated in setup_memory. + * + * NOTE#2: we rely on the fact that the memory chunks are ordered by + * start pfn number during setup. + */ +static void __init get_zholes_init(void) +{ + int nid; + int c; + int first; + unsigned long end = 0; + + for_each_online_node(nid) { + first = 1; + for (c = 0; c < num_memory_chunks; c++){ + if (node_memory_chunk[c].nid == nid) { + if (first) { + end = node_memory_chunk[c].end_pfn; + first = 0; + + } else { + /* Record any gap between this chunk + * and the previous chunk on this node + * against the zones it spans. + */ + chunk_to_zones(end, + node_memory_chunk[c].start_pfn, + &zholes_size[nid * MAX_NR_ZONES]); + } + } + } + } +} + +unsigned long * __init get_zholes_size(int nid) +{ + if (!zholes_size_init) { + zholes_size_init++; + get_zholes_init(); + } + if (nid >= MAX_NUMNODES || !node_online(nid)) + printk("%s: nid = %d is invalid/offline. num_online_nodes = %d", + __FUNCTION__, nid, num_online_nodes()); + return &zholes_size[nid * MAX_NR_ZONES]; +} diff --git a/trunk/arch/i386/kernel/stacktrace.c b/trunk/arch/i386/kernel/stacktrace.c new file mode 100644 index 000000000000..e62a037ab399 --- /dev/null +++ b/trunk/arch/i386/kernel/stacktrace.c @@ -0,0 +1,98 @@ +/* + * arch/i386/kernel/stacktrace.c + * + * Stack trace management functions + * + * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar + */ +#include +#include + +static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) +{ + return p > (void *)tinfo && + p < (void *)tinfo + THREAD_SIZE - 3; +} + +/* + * Save stack-backtrace addresses into a stack_trace buffer: + */ +static inline unsigned long +save_context_stack(struct stack_trace *trace, unsigned int skip, + struct thread_info *tinfo, unsigned long *stack, + unsigned long ebp) +{ + unsigned long addr; + +#ifdef CONFIG_FRAME_POINTER + while (valid_stack_ptr(tinfo, (void *)ebp)) { + addr = *(unsigned long *)(ebp + 4); + if (!skip) + trace->entries[trace->nr_entries++] = addr; + else + skip--; + if (trace->nr_entries >= trace->max_entries) + break; + /* + * break out of recursive entries (such as + * end_of_stack_stop_unwind_function): + */ + if (ebp == *(unsigned long *)ebp) + break; + + ebp = *(unsigned long *)ebp; + } +#else + while (valid_stack_ptr(tinfo, stack)) { + addr = *stack++; + if (__kernel_text_address(addr)) { + if (!skip) + trace->entries[trace->nr_entries++] = addr; + else + skip--; + if (trace->nr_entries >= trace->max_entries) + break; + } + } +#endif + + return ebp; +} + +/* + * Save stack-backtrace addresses into a stack_trace buffer. + * If all_contexts is set, all contexts (hardirq, softirq and process) + * are saved. If not set then only the current context is saved. + */ +void save_stack_trace(struct stack_trace *trace, + struct task_struct *task, int all_contexts, + unsigned int skip) +{ + unsigned long ebp; + unsigned long *stack = &ebp; + + WARN_ON(trace->nr_entries || !trace->max_entries); + + if (!task || task == current) { + /* Grab ebp right from our regs: */ + asm ("movl %%ebp, %0" : "=r" (ebp)); + } else { + /* ebp is the last reg pushed by switch_to(): */ + ebp = *(unsigned long *) task->thread.esp; + } + + while (1) { + struct thread_info *context = (struct thread_info *) + ((unsigned long)stack & (~(THREAD_SIZE - 1))); + + ebp = save_context_stack(trace, skip, context, stack, ebp); + stack = (unsigned long *)context->previous_esp; + if (!all_contexts || !stack || + trace->nr_entries >= trace->max_entries) + break; + trace->entries[trace->nr_entries++] = ULONG_MAX; + if (trace->nr_entries >= trace->max_entries) + break; + } +} + diff --git a/trunk/arch/i386/kernel/sys_i386.c b/trunk/arch/i386/kernel/sys_i386.c index 4048397f1740..8fdb1fb17a5f 100644 --- a/trunk/arch/i386/kernel/sys_i386.c +++ b/trunk/arch/i386/kernel/sys_i386.c @@ -21,7 +21,6 @@ #include #include -#include #include /* @@ -211,7 +210,7 @@ asmlinkage int sys_uname(struct old_utsname __user * name) if (!name) return -EFAULT; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err=copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } @@ -227,21 +226,16 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name) down_read(&uts_sem); - error = __copy_to_user(&name->sysname, &utsname()->sysname, - __OLD_UTS_LEN); - error |= __put_user(0, name->sysname + __OLD_UTS_LEN); - error |= __copy_to_user(&name->nodename, &utsname()->nodename, - __OLD_UTS_LEN); - error |= __put_user(0, name->nodename + __OLD_UTS_LEN); - error |= __copy_to_user(&name->release, &utsname()->release, - __OLD_UTS_LEN); - error |= __put_user(0, name->release + __OLD_UTS_LEN); - error |= __copy_to_user(&name->version, &utsname()->version, - __OLD_UTS_LEN); - error |= __put_user(0, name->version + __OLD_UTS_LEN); - error |= __copy_to_user(&name->machine, &utsname()->machine, - __OLD_UTS_LEN); - error |= __put_user(0, name->machine + __OLD_UTS_LEN); + error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); + error |= __put_user(0,name->sysname+__OLD_UTS_LEN); + error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); + error |= __put_user(0,name->nodename+__OLD_UTS_LEN); + error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); + error |= __put_user(0,name->release+__OLD_UTS_LEN); + error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); + error |= __put_user(0,name->version+__OLD_UTS_LEN); + error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); + error |= __put_user(0,name->machine+__OLD_UTS_LEN); up_read(&uts_sem); @@ -249,17 +243,3 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name) return error; } - - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - long __res; - asm volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" - : "=a" (__res) - : "0" (__NR_execve),"ri" (filename),"c" (argv), "d" (envp) : "memory"); - return __res; -} diff --git a/trunk/arch/i386/kernel/syscall_table.S b/trunk/arch/i386/kernel/syscall_table.S index 7e639f78b0b9..dd63d4775398 100644 --- a/trunk/arch/i386/kernel/syscall_table.S +++ b/trunk/arch/i386/kernel/syscall_table.S @@ -317,4 +317,3 @@ ENTRY(sys_call_table) .long sys_tee /* 315 */ .long sys_vmsplice .long sys_move_pages - .long sys_getcpu diff --git a/trunk/arch/i386/kernel/time.c b/trunk/arch/i386/kernel/time.c index 58a2d5582419..1302e4ab3c4f 100644 --- a/trunk/arch/i386/kernel/time.c +++ b/trunk/arch/i386/kernel/time.c @@ -76,6 +76,8 @@ int pit_latch_buggy; /* extern */ unsigned int cpu_khz; /* Detected as we calibrate the TSC */ EXPORT_SYMBOL(cpu_khz); +extern unsigned long wall_jiffies; + DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -128,33 +130,18 @@ static int set_rtc_mmss(unsigned long nowtime) int timer_ack; +#if defined(CONFIG_SMP) && defined(CONFIG_FRAME_POINTER) unsigned long profile_pc(struct pt_regs *regs) { unsigned long pc = instruction_pointer(regs); -#ifdef CONFIG_SMP - if (!user_mode_vm(regs) && in_lock_functions(pc)) { -#ifdef CONFIG_FRAME_POINTER + if (!user_mode_vm(regs) && in_lock_functions(pc)) return *(unsigned long *)(regs->ebp + 4); -#else - unsigned long *sp; - if ((regs->xcs & 3) == 0) - sp = (unsigned long *)®s->esp; - else - sp = (unsigned long *)regs->esp; - /* Return address is either directly at stack pointer - or above a saved eflags. Eflags has bits 22-31 zero, - kernel addresses don't. */ - if (sp[0] >> 22) - return sp[0]; - if (sp[1] >> 22) - return sp[1]; -#endif - } -#endif + return pc; } EXPORT_SYMBOL(profile_pc); +#endif /* * This is the same as the above, except we _also_ save the current @@ -327,6 +314,7 @@ static int timer_resume(struct sys_device *dev) do_settimeofday(&ts); write_seqlock_irqsave(&xtime_lock, flags); jiffies_64 += sleep_length; + wall_jiffies += sleep_length; write_sequnlock_irqrestore(&xtime_lock, flags); touch_softlockup_watchdog(); return 0; diff --git a/trunk/arch/i386/kernel/topology.c b/trunk/arch/i386/kernel/topology.c index 07d6da36a825..e2e281d4bcc8 100644 --- a/trunk/arch/i386/kernel/topology.c +++ b/trunk/arch/i386/kernel/topology.c @@ -28,7 +28,6 @@ #include #include #include -#include #include static struct i386_cpu cpu_devices[NR_CPUS]; @@ -56,18 +55,34 @@ EXPORT_SYMBOL(arch_register_cpu); EXPORT_SYMBOL(arch_unregister_cpu); #endif /*CONFIG_HOTPLUG_CPU*/ + + +#ifdef CONFIG_NUMA +#include + static int __init topology_init(void) { int i; -#ifdef CONFIG_NUMA for_each_online_node(i) register_one_node(i); -#endif /* CONFIG_NUMA */ for_each_present_cpu(i) arch_register_cpu(i); return 0; } +#else /* !CONFIG_NUMA */ + +static int __init topology_init(void) +{ + int i; + + for_each_present_cpu(i) + arch_register_cpu(i); + return 0; +} + +#endif /* CONFIG_NUMA */ + subsys_initcall(topology_init); diff --git a/trunk/arch/i386/kernel/traps.c b/trunk/arch/i386/kernel/traps.c index 00489b706d27..4fcc6690be99 100644 --- a/trunk/arch/i386/kernel/traps.c +++ b/trunk/arch/i386/kernel/traps.c @@ -28,7 +28,6 @@ #include #include #include -#include #ifdef CONFIG_EISA #include @@ -41,6 +40,7 @@ #include #include +#include #include #include #include @@ -51,14 +51,11 @@ #include #include #include -#include #include #include "mach_traps.h" -int panic_on_unrecovered_nmi; - asmlinkage int system_call(void); struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, @@ -121,16 +118,26 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) p < (void *)tinfo + THREAD_SIZE - 3; } +/* + * Print one address/symbol entries per line. + */ +static inline void print_addr_and_symbol(unsigned long addr, char *log_lvl) +{ + printk(" [<%08lx>] ", addr); + + print_symbol("%s\n", addr); +} + static inline unsigned long print_context_stack(struct thread_info *tinfo, unsigned long *stack, unsigned long ebp, - struct stacktrace_ops *ops, void *data) + char *log_lvl) { unsigned long addr; #ifdef CONFIG_FRAME_POINTER while (valid_stack_ptr(tinfo, (void *)ebp)) { addr = *(unsigned long *)(ebp + 4); - ops->address(data, addr); + print_addr_and_symbol(addr, log_lvl); /* * break out of recursive entries (such as * end_of_stack_stop_unwind_function): @@ -143,37 +150,30 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo, while (valid_stack_ptr(tinfo, stack)) { addr = *stack++; if (__kernel_text_address(addr)) - ops->address(data, addr); + print_addr_and_symbol(addr, log_lvl); } #endif return ebp; } -struct ops_and_data { - struct stacktrace_ops *ops; - void *data; -}; - static asmlinkage int -dump_trace_unwind(struct unwind_frame_info *info, void *data) +show_trace_unwind(struct unwind_frame_info *info, void *log_lvl) { - struct ops_and_data *oad = (struct ops_and_data *)data; int n = 0; while (unwind(info) == 0 && UNW_PC(info)) { n++; - oad->ops->address(oad->data, UNW_PC(info)); + print_addr_and_symbol(UNW_PC(info), log_lvl); if (arch_unw_user_mode(info)) break; } return n; } -void dump_trace(struct task_struct *task, struct pt_regs *regs, - unsigned long *stack, - struct stacktrace_ops *ops, void *data) +static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, char *log_lvl) { - unsigned long ebp = 0; + unsigned long ebp; if (!task) task = current; @@ -181,116 +181,54 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, if (call_trace >= 0) { int unw_ret = 0; struct unwind_frame_info info; - struct ops_and_data oad = { .ops = ops, .data = data }; if (regs) { if (unwind_init_frame_info(&info, task, regs) == 0) - unw_ret = dump_trace_unwind(&info, &oad); + unw_ret = show_trace_unwind(&info, log_lvl); } else if (task == current) - unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad); + unw_ret = unwind_init_running(&info, show_trace_unwind, log_lvl); else { if (unwind_init_blocked(&info, task) == 0) - unw_ret = dump_trace_unwind(&info, &oad); + unw_ret = show_trace_unwind(&info, log_lvl); } if (unw_ret > 0) { if (call_trace == 1 && !arch_unw_user_mode(&info)) { - ops->warning_symbol(data, "DWARF2 unwinder stuck at %s\n", + print_symbol("DWARF2 unwinder stuck at %s\n", UNW_PC(&info)); if (UNW_SP(&info) >= PAGE_OFFSET) { - ops->warning(data, "Leftover inexact backtrace:\n"); + printk("Leftover inexact backtrace:\n"); stack = (void *)UNW_SP(&info); - if (!stack) - return; - ebp = UNW_FP(&info); } else - ops->warning(data, "Full inexact backtrace again:\n"); + printk("Full inexact backtrace again:\n"); } else if (call_trace >= 1) return; else - ops->warning(data, "Full inexact backtrace again:\n"); + printk("Full inexact backtrace again:\n"); } else - ops->warning(data, "Inexact backtrace:\n"); - } - if (!stack) { - unsigned long dummy; - stack = &dummy; - if (task && task != current) - stack = (unsigned long *)task->thread.esp; + printk("Inexact backtrace:\n"); } -#ifdef CONFIG_FRAME_POINTER - if (!ebp) { - if (task == current) { - /* Grab ebp right from our regs */ - asm ("movl %%ebp, %0" : "=r" (ebp) : ); - } else { - /* ebp is the last reg pushed by switch_to */ - ebp = *(unsigned long *) task->thread.esp; - } + if (task == current) { + /* Grab ebp right from our regs */ + asm ("movl %%ebp, %0" : "=r" (ebp) : ); + } else { + /* ebp is the last reg pushed by switch_to */ + ebp = *(unsigned long *) task->thread.esp; } -#endif while (1) { struct thread_info *context; context = (struct thread_info *) ((unsigned long)stack & (~(THREAD_SIZE - 1))); - ebp = print_context_stack(context, stack, ebp, ops, data); - /* Should be after the line below, but somewhere - in early boot context comes out corrupted and we - can't reference it -AK */ - if (ops->stack(data, "IRQ") < 0) - break; + ebp = print_context_stack(context, stack, ebp, log_lvl); stack = (unsigned long*)context->previous_esp; if (!stack) break; + printk("%s =======================\n", log_lvl); } } -EXPORT_SYMBOL(dump_trace); - -static void -print_trace_warning_symbol(void *data, char *msg, unsigned long symbol) -{ - printk(data); - print_symbol(msg, symbol); - printk("\n"); -} - -static void print_trace_warning(void *data, char *msg) -{ - printk("%s%s\n", (char *)data, msg); -} -static int print_trace_stack(void *data, char *name) -{ - return 0; -} - -/* - * Print one address/symbol entries per line. - */ -static void print_trace_address(void *data, unsigned long addr) -{ - printk("%s [<%08lx>] ", (char *)data, addr); - print_symbol("%s\n", addr); -} - -static struct stacktrace_ops print_trace_ops = { - .warning = print_trace_warning, - .warning_symbol = print_trace_warning_symbol, - .stack = print_trace_stack, - .address = print_trace_address, -}; - -static void -show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, - unsigned long * stack, char *log_lvl) -{ - dump_trace(task, regs, stack, &print_trace_ops, log_lvl); - printk("%s =======================\n", log_lvl); -} - -void show_trace(struct task_struct *task, struct pt_regs *regs, - unsigned long * stack) +void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long * stack) { show_trace_log_lvl(task, regs, stack, ""); } @@ -353,13 +291,12 @@ void show_registers(struct pt_regs *regs) ss = regs->xss & 0xffff; } print_modules(); - printk(KERN_EMERG "CPU: %d\n" - KERN_EMERG "EIP: %04x:[<%08lx>] %s VLI\n" - KERN_EMERG "EFLAGS: %08lx (%s %.*s)\n", + printk(KERN_EMERG "CPU: %d\nEIP: %04x:[<%08lx>] %s VLI\n" + "EFLAGS: %08lx (%s %.*s) \n", smp_processor_id(), 0xffff & regs->xcs, regs->eip, - print_tainted(), regs->eflags, init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); + print_tainted(), regs->eflags, system_utsname.release, + (int)strcspn(system_utsname.version, " "), + system_utsname.version); print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip); printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", regs->eax, regs->ebx, regs->ecx, regs->edx); @@ -411,7 +348,7 @@ static void handle_BUG(struct pt_regs *regs) if (eip < PAGE_OFFSET) return; - if (probe_kernel_address((unsigned short __user *)eip, ud2)) + if (__get_user(ud2, (unsigned short __user *)eip)) return; if (ud2 != 0x0b0f) return; @@ -424,8 +361,7 @@ static void handle_BUG(struct pt_regs *regs) char *file; char c; - if (probe_kernel_address((unsigned short __user *)(eip + 2), - line)) + if (__get_user(line, (unsigned short __user *)(eip + 2))) break; if (__get_user(file, (char * __user *)(eip + 4)) || (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) @@ -698,24 +634,18 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs, } } -static __kprobes void -mem_parity_error(unsigned char reason, struct pt_regs * regs) +static void mem_parity_error(unsigned char reason, struct pt_regs * regs) { - printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x on " - "CPU %d.\n", reason, smp_processor_id()); + printk(KERN_EMERG "Uhhuh. NMI received. Dazed and confused, but trying " + "to continue\n"); printk(KERN_EMERG "You probably have a hardware problem with your RAM " "chips\n"); - if (panic_on_unrecovered_nmi) - panic("NMI: Not continuing"); - - printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); /* Clear and disable the memory parity error line. */ clear_mem_error(reason); } -static __kprobes void -io_check_error(unsigned char reason, struct pt_regs * regs) +static void io_check_error(unsigned char reason, struct pt_regs * regs) { unsigned long i; @@ -731,8 +661,7 @@ io_check_error(unsigned char reason, struct pt_regs * regs) outb(reason, 0x61); } -static __kprobes void -unknown_nmi_error(unsigned char reason, struct pt_regs * regs) +static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) { #ifdef CONFIG_MCA /* Might actually be able to figure out what the guilty party @@ -742,18 +671,15 @@ unknown_nmi_error(unsigned char reason, struct pt_regs * regs) return; } #endif - printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x on " - "CPU %d.\n", reason, smp_processor_id()); - printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n"); - if (panic_on_unrecovered_nmi) - panic("NMI: Not continuing"); - - printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); + printk("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n", + reason, smp_processor_id()); + printk("Dazed and confused, but trying to continue\n"); + printk("Do you have a strange power saving mode enabled?\n"); } static DEFINE_SPINLOCK(nmi_print_lock); -void __kprobes die_nmi(struct pt_regs *regs, const char *msg) +void die_nmi (struct pt_regs *regs, const char *msg) { if (notify_die(DIE_NMIWATCHDOG, msg, regs, 0, 2, SIGINT) == NOTIFY_STOP) @@ -785,7 +711,7 @@ void __kprobes die_nmi(struct pt_regs *regs, const char *msg) do_exit(SIGSEGV); } -static __kprobes void default_do_nmi(struct pt_regs * regs) +static void default_do_nmi(struct pt_regs * regs) { unsigned char reason = 0; @@ -802,12 +728,12 @@ static __kprobes void default_do_nmi(struct pt_regs * regs) * Ok, so this is none of the documented NMI sources, * so it must be the NMI watchdog. */ - if (nmi_watchdog_tick(regs, reason)) + if (nmi_watchdog) { + nmi_watchdog_tick(regs); return; - if (!do_nmi_callback(regs, smp_processor_id())) + } #endif - unknown_nmi_error(reason, regs); - + unknown_nmi_error(reason, regs); return; } if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) @@ -823,7 +749,14 @@ static __kprobes void default_do_nmi(struct pt_regs * regs) reassert_nmi(); } -fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code) +static int dummy_nmi_callback(struct pt_regs * regs, int cpu) +{ + return 0; +} + +static nmi_callback_t nmi_callback = dummy_nmi_callback; + +fastcall void do_nmi(struct pt_regs * regs, long error_code) { int cpu; @@ -833,11 +766,25 @@ fastcall __kprobes void do_nmi(struct pt_regs * regs, long error_code) ++nmi_count(cpu); - default_do_nmi(regs); + if (!rcu_dereference(nmi_callback)(regs, cpu)) + default_do_nmi(regs); nmi_exit(); } +void set_nmi_callback(nmi_callback_t callback) +{ + vmalloc_sync_all(); + rcu_assign_pointer(nmi_callback, callback); +} +EXPORT_SYMBOL_GPL(set_nmi_callback); + +void unset_nmi_callback(void) +{ + nmi_callback = dummy_nmi_callback; +} +EXPORT_SYMBOL_GPL(unset_nmi_callback); + #ifdef CONFIG_KPROBES fastcall void __kprobes do_int3(struct pt_regs *regs, long error_code) { @@ -1177,6 +1124,20 @@ void __init trap_init_f00f_bug(void) } #endif +#define _set_gate(gate_addr,type,dpl,addr,seg) \ +do { \ + int __d0, __d1; \ + __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ + "movw %4,%%dx\n\t" \ + "movl %%eax,%0\n\t" \ + "movl %%edx,%1" \ + :"=m" (*((long *) (gate_addr))), \ + "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \ + :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ + "3" ((char *) (addr)),"2" ((seg) << 16)); \ +} while (0) + + /* * This needs to use 'idt_table' rather than 'idt', and * thus use the _nonmapped_ version of the IDT, as the @@ -1185,7 +1146,7 @@ void __init trap_init_f00f_bug(void) */ void set_intr_gate(unsigned int n, void *addr) { - _set_gate(n, DESCTYPE_INT, addr, __KERNEL_CS); + _set_gate(idt_table+n,14,0,addr,__KERNEL_CS); } /* @@ -1193,22 +1154,22 @@ void set_intr_gate(unsigned int n, void *addr) */ static inline void set_system_intr_gate(unsigned int n, void *addr) { - _set_gate(n, DESCTYPE_INT | DESCTYPE_DPL3, addr, __KERNEL_CS); + _set_gate(idt_table+n, 14, 3, addr, __KERNEL_CS); } static void __init set_trap_gate(unsigned int n, void *addr) { - _set_gate(n, DESCTYPE_TRAP, addr, __KERNEL_CS); + _set_gate(idt_table+n,15,0,addr,__KERNEL_CS); } static void __init set_system_gate(unsigned int n, void *addr) { - _set_gate(n, DESCTYPE_TRAP | DESCTYPE_DPL3, addr, __KERNEL_CS); + _set_gate(idt_table+n,15,3,addr,__KERNEL_CS); } static void __init set_task_gate(unsigned int n, unsigned int gdt_entry) { - _set_gate(n, DESCTYPE_TASK, (void *)0, (gdt_entry<<3)); + _set_gate(idt_table+n,5,0,0,(gdt_entry<<3)); } diff --git a/trunk/arch/i386/kernel/tsc.c b/trunk/arch/i386/kernel/tsc.c index b8fa0a8b2e47..7e0d8dab2075 100644 --- a/trunk/arch/i386/kernel/tsc.c +++ b/trunk/arch/i386/kernel/tsc.c @@ -192,7 +192,7 @@ int recalibrate_cpu_khz(void) EXPORT_SYMBOL(recalibrate_cpu_khz); -void __init tsc_init(void) +void tsc_init(void) { if (!cpu_has_tsc || tsc_disable) return; diff --git a/trunk/arch/i386/lib/Makefile b/trunk/arch/i386/lib/Makefile index d86a548b8d54..914933e9ec3d 100644 --- a/trunk/arch/i386/lib/Makefile +++ b/trunk/arch/i386/lib/Makefile @@ -4,6 +4,6 @@ lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \ - bitops.o semaphore.o + bitops.o lib-$(CONFIG_X86_USE_3DNOW) += mmx.o diff --git a/trunk/arch/i386/lib/delay.c b/trunk/arch/i386/lib/delay.c index f6edb11364df..3c0714c4b669 100644 --- a/trunk/arch/i386/lib/delay.c +++ b/trunk/arch/i386/lib/delay.c @@ -11,6 +11,7 @@ */ #include +#include #include #include diff --git a/trunk/arch/i386/lib/semaphore.S b/trunk/arch/i386/lib/semaphore.S deleted file mode 100644 index 01f80b5c45d2..000000000000 --- a/trunk/arch/i386/lib/semaphore.S +++ /dev/null @@ -1,217 +0,0 @@ -/* - * i386 semaphore implementation. - * - * (C) Copyright 1999 Linus Torvalds - * - * Portions Copyright 1999 Red Hat, Inc. - * - * 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. - * - * rw semaphores implemented November 1999 by Benjamin LaHaise - */ - -#include -#include -#include -#include -#include -#include - -/* - * The semaphore operations have a special calling sequence that - * allow us to do a simpler in-line version of them. These routines - * need to convert that sequence back into the C sequence when - * there is contention on the semaphore. - * - * %eax contains the semaphore pointer on entry. Save the C-clobbered - * registers (%eax, %edx and %ecx) except %eax whish is either a return - * value or just clobbered.. - */ - .section .sched.text -ENTRY(__down_failed) - CFI_STARTPROC - FRAME - pushl %edx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edx,0 - pushl %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - call __down - popl %ecx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE ecx - popl %edx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE edx - ENDFRAME - ret - CFI_ENDPROC - END(__down_failed) - -ENTRY(__down_failed_interruptible) - CFI_STARTPROC - FRAME - pushl %edx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edx,0 - pushl %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - call __down_interruptible - popl %ecx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE ecx - popl %edx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE edx - ENDFRAME - ret - CFI_ENDPROC - END(__down_failed_interruptible) - -ENTRY(__down_failed_trylock) - CFI_STARTPROC - FRAME - pushl %edx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edx,0 - pushl %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - call __down_trylock - popl %ecx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE ecx - popl %edx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE edx - ENDFRAME - ret - CFI_ENDPROC - END(__down_failed_trylock) - -ENTRY(__up_wakeup) - CFI_STARTPROC - FRAME - pushl %edx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edx,0 - pushl %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - call __up - popl %ecx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE ecx - popl %edx - CFI_ADJUST_CFA_OFFSET -4 - CFI_RESTORE edx - ENDFRAME - ret - CFI_ENDPROC - END(__up_wakeup) - -/* - * rw spinlock fallbacks - */ -#ifdef CONFIG_SMP -ENTRY(__write_lock_failed) - CFI_STARTPROC simple - FRAME -2: LOCK_PREFIX - addl $ RW_LOCK_BIAS,(%eax) -1: rep; nop - cmpl $ RW_LOCK_BIAS,(%eax) - jne 1b - LOCK_PREFIX - subl $ RW_LOCK_BIAS,(%eax) - jnz 2b - ENDFRAME - ret - CFI_ENDPROC - END(__write_lock_failed) - -ENTRY(__read_lock_failed) - CFI_STARTPROC - FRAME -2: LOCK_PREFIX - incl (%eax) -1: rep; nop - cmpl $1,(%eax) - js 1b - LOCK_PREFIX - decl (%eax) - js 2b - ENDFRAME - ret - CFI_ENDPROC - END(__read_lock_failed) - -#endif - -/* Fix up special calling conventions */ -ENTRY(call_rwsem_down_read_failed) - CFI_STARTPROC - push %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - push %edx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edx,0 - call rwsem_down_read_failed - pop %edx - CFI_ADJUST_CFA_OFFSET -4 - pop %ecx - CFI_ADJUST_CFA_OFFSET -4 - ret - CFI_ENDPROC - END(call_rwsem_down_read_failed) - -ENTRY(call_rwsem_down_write_failed) - CFI_STARTPROC - push %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - calll rwsem_down_write_failed - pop %ecx - CFI_ADJUST_CFA_OFFSET -4 - ret - CFI_ENDPROC - END(call_rwsem_down_write_failed) - -ENTRY(call_rwsem_wake) - CFI_STARTPROC - decw %dx /* do nothing if still outstanding active readers */ - jnz 1f - push %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - call rwsem_wake - pop %ecx - CFI_ADJUST_CFA_OFFSET -4 -1: ret - CFI_ENDPROC - END(call_rwsem_wake) - -/* Fix up special calling conventions */ -ENTRY(call_rwsem_downgrade_wake) - CFI_STARTPROC - push %ecx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET ecx,0 - push %edx - CFI_ADJUST_CFA_OFFSET 4 - CFI_REL_OFFSET edx,0 - call rwsem_downgrade_wake - pop %edx - CFI_ADJUST_CFA_OFFSET -4 - pop %ecx - CFI_ADJUST_CFA_OFFSET -4 - ret - CFI_ENDPROC - END(call_rwsem_downgrade_wake) - diff --git a/trunk/arch/i386/lib/usercopy.c b/trunk/arch/i386/lib/usercopy.c index 08502fc6d0cb..efc7e7d5f4d0 100644 --- a/trunk/arch/i386/lib/usercopy.c +++ b/trunk/arch/i386/lib/usercopy.c @@ -739,7 +739,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from, retval = get_user_pages(current, current->mm, (unsigned long )to, 1, 1, 0, &pg, NULL); - if (retval == -ENOMEM && is_init(current)) { + if (retval == -ENOMEM && current->pid == 1) { up_read(¤t->mm->mmap_sem); blk_congestion_wait(WRITE, HZ/50); goto survive; diff --git a/trunk/arch/i386/mach-generic/bigsmp.c b/trunk/arch/i386/mach-generic/bigsmp.c index 33d9f93557ba..ef7a6e6fcb9f 100644 --- a/trunk/arch/i386/mach-generic/bigsmp.c +++ b/trunk/arch/i386/mach-generic/bigsmp.c @@ -5,7 +5,6 @@ #define APIC_DEFINITION 1 #include #include -#include #include #include #include diff --git a/trunk/arch/i386/mach-generic/es7000.c b/trunk/arch/i386/mach-generic/es7000.c index aa144d82334d..845cdd0b3593 100644 --- a/trunk/arch/i386/mach-generic/es7000.c +++ b/trunk/arch/i386/mach-generic/es7000.c @@ -4,7 +4,6 @@ #define APIC_DEFINITION 1 #include #include -#include #include #include #include diff --git a/trunk/arch/i386/mach-generic/probe.c b/trunk/arch/i386/mach-generic/probe.c index 94b1fd9cbe3c..bcd1bcfaa723 100644 --- a/trunk/arch/i386/mach-generic/probe.c +++ b/trunk/arch/i386/mach-generic/probe.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -30,24 +29,7 @@ struct genapic *apic_probe[] __initdata = { NULL, }; -static int cmdline_apic __initdata; -static int __init parse_apic(char *arg) -{ - int i; - - if (!arg) - return -EINVAL; - - for (i = 0; apic_probe[i]; i++) { - if (!strcmp(apic_probe[i]->name, arg)) { - genapic = apic_probe[i]; - cmdline_apic = 1; - return 0; - } - } - return -ENOENT; -} -early_param("apic", parse_apic); +static int cmdline_apic; void __init generic_bigsmp_probe(void) { @@ -66,20 +48,40 @@ void __init generic_bigsmp_probe(void) } } -void __init generic_apic_probe(void) +void __init generic_apic_probe(char *command_line) { - if (!cmdline_apic) { - int i; - for (i = 0; apic_probe[i]; i++) { - if (apic_probe[i]->probe()) { + char *s; + int i; + int changed = 0; + + s = strstr(command_line, "apic="); + if (s && (s == command_line || isspace(s[-1]))) { + char *p = strchr(s, ' '), old; + if (!p) + p = strchr(s, '\0'); + old = *p; + *p = 0; + for (i = 0; !changed && apic_probe[i]; i++) { + if (!strcmp(apic_probe[i]->name, s+5)) { + changed = 1; genapic = apic_probe[i]; - break; } } - /* Not visible without early console */ - if (!apic_probe[i]) - panic("Didn't find an APIC driver"); + if (!changed) + printk(KERN_ERR "Unknown genapic `%s' specified.\n", s); + *p = old; + cmdline_apic = changed; + } + for (i = 0; !changed && apic_probe[i]; i++) { + if (apic_probe[i]->probe()) { + changed = 1; + genapic = apic_probe[i]; + } } + /* Not visible without early console */ + if (!changed) + panic("Didn't find an APIC driver"); + printk(KERN_INFO "Using APIC driver %s\n", genapic->name); } @@ -117,9 +119,7 @@ int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id) return 0; } -#ifdef CONFIG_SMP int hard_smp_processor_id(void) { return genapic->get_apic_id(*(unsigned long *)(APIC_BASE+APIC_ID)); } -#endif diff --git a/trunk/arch/i386/mach-generic/summit.c b/trunk/arch/i386/mach-generic/summit.c index f7e5d66648dc..b73501ddd653 100644 --- a/trunk/arch/i386/mach-generic/summit.c +++ b/trunk/arch/i386/mach-generic/summit.c @@ -4,7 +4,6 @@ #define APIC_DEFINITION 1 #include #include -#include #include #include #include diff --git a/trunk/arch/i386/mach-voyager/voyager_smp.c b/trunk/arch/i386/mach-voyager/voyager_smp.c index 856c73fcb7e7..6c86575ffdcb 100644 --- a/trunk/arch/i386/mach-voyager/voyager_smp.c +++ b/trunk/arch/i386/mach-voyager/voyager_smp.c @@ -99,7 +99,6 @@ static void do_boot_cpu(__u8 cpuid); static void do_quad_bootstrap(void); int hard_smp_processor_id(void); -int safe_smp_processor_id(void); /* Inline functions */ static inline void @@ -1248,12 +1247,6 @@ hard_smp_processor_id(void) return 0; } -int -safe_smp_processor_id(void) -{ - return hard_smp_processor_id(); -} - /* broadcast a halt to all other CPUs */ void smp_send_stop(void) diff --git a/trunk/arch/i386/mm/discontig.c b/trunk/arch/i386/mm/discontig.c index 51e3739dd227..fb5d8b747de4 100644 --- a/trunk/arch/i386/mm/discontig.c +++ b/trunk/arch/i386/mm/discontig.c @@ -157,6 +157,21 @@ static void __init find_max_pfn_node(int nid) BUG(); } +/* Find the owning node for a pfn. */ +int early_pfn_to_nid(unsigned long pfn) +{ + int nid; + + for_each_node(nid) { + if (node_end_pfn[nid] == 0) + break; + if (node_start_pfn[nid] <= pfn && node_end_pfn[nid] >= pfn) + return nid; + } + + return 0; +} + /* * Allocate memory for the pg_data_t for this node via a crude pre-bootmem * method. For node zero take this from the bottom of memory, for @@ -212,8 +227,6 @@ static unsigned long calculate_numa_remap_pages(void) unsigned long pfn; for_each_online_node(nid) { - unsigned old_end_pfn = node_end_pfn[nid]; - /* * The acpi/srat node info can show hot-add memroy zones * where memory could be added but not currently present. @@ -263,7 +276,6 @@ static unsigned long calculate_numa_remap_pages(void) node_end_pfn[nid] -= size; node_remap_start_pfn[nid] = node_end_pfn[nid]; - shrink_active_range(nid, old_end_pfn, node_end_pfn[nid]); } printk("Reserving total of %ld pages for numa KVA remap\n", reserve_pages); @@ -310,11 +322,6 @@ unsigned long __init setup_memory(void) highstart_pfn = system_max_low_pfn; printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", pages_to_mb(highend_pfn - highstart_pfn)); - num_physpages = highend_pfn; - high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; -#else - num_physpages = system_max_low_pfn; - high_memory = (void *) __va(system_max_low_pfn * PAGE_SIZE - 1) + 1; #endif printk(KERN_NOTICE "%ldMB LOWMEM available.\n", pages_to_mb(system_max_low_pfn)); @@ -357,22 +364,45 @@ void __init numa_kva_reserve(void) void __init zone_sizes_init(void) { int nid; - unsigned long max_zone_pfns[MAX_NR_ZONES] = { - virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT, - max_low_pfn, - highend_pfn - }; - - /* If SRAT has not registered memory, register it now */ - if (find_max_pfn_with_active_regions() == 0) { - for_each_online_node(nid) { - if (node_has_online_mem(nid)) - add_active_range(nid, node_start_pfn[nid], - node_end_pfn[nid]); + + + for_each_online_node(nid) { + unsigned long zones_size[MAX_NR_ZONES] = {0, }; + unsigned long *zholes_size; + unsigned int max_dma; + + unsigned long low = max_low_pfn; + unsigned long start = node_start_pfn[nid]; + unsigned long high = node_end_pfn[nid]; + + max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; + + if (node_has_online_mem(nid)){ + if (start > low) { +#ifdef CONFIG_HIGHMEM + BUG_ON(start > high); + zones_size[ZONE_HIGHMEM] = high - start; +#endif + } else { + if (low < max_dma) + zones_size[ZONE_DMA] = low; + else { + BUG_ON(max_dma > low); + BUG_ON(low > high); + zones_size[ZONE_DMA] = max_dma; + zones_size[ZONE_NORMAL] = low - max_dma; +#ifdef CONFIG_HIGHMEM + zones_size[ZONE_HIGHMEM] = high - low; +#endif + } + } } - } - free_area_init_nodes(max_zone_pfns); + zholes_size = get_zholes_size(nid); + + free_area_init_node(nid, NODE_DATA(nid), zones_size, start, + zholes_size); + } return; } diff --git a/trunk/arch/i386/mm/extable.c b/trunk/arch/i386/mm/extable.c index 0ce4f22a2635..de03c5430abc 100644 --- a/trunk/arch/i386/mm/extable.c +++ b/trunk/arch/i386/mm/extable.c @@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs) const struct exception_table_entry *fixup; #ifdef CONFIG_PNPBIOS - if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs))) + if (unlikely((regs->xcs & ~15) == (GDT_ENTRY_PNPBIOS_BASE << 3))) { extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp; extern u32 pnp_bios_is_utter_crap; diff --git a/trunk/arch/i386/mm/fault.c b/trunk/arch/i386/mm/fault.c index 2581575786c1..f7279468323a 100644 --- a/trunk/arch/i386/mm/fault.c +++ b/trunk/arch/i386/mm/fault.c @@ -27,24 +27,21 @@ #include #include #include -#include extern void die(const char *,struct pt_regs *,long); -static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); - +#ifdef CONFIG_KPROBES +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); int register_page_fault_notifier(struct notifier_block *nb) { vmalloc_sync_all(); return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); } -EXPORT_SYMBOL_GPL(register_page_fault_notifier); int unregister_page_fault_notifier(struct notifier_block *nb) { return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); } -EXPORT_SYMBOL_GPL(unregister_page_fault_notifier); static inline int notify_page_fault(enum die_val val, const char *str, struct pt_regs *regs, long err, int trap, int sig) @@ -58,6 +55,14 @@ static inline int notify_page_fault(enum die_val val, const char *str, }; return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); } +#else +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + return NOTIFY_DONE; +} +#endif + /* * Unlock any spinlocks which will prevent us from getting the @@ -114,10 +119,10 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs, } /* The standard kernel/user address space limit. */ - *eip_limit = user_mode(regs) ? USER_DS.seg : KERNEL_DS.seg; + *eip_limit = (seg & 3) ? USER_DS.seg : KERNEL_DS.seg; /* By far the most common cases. */ - if (likely(SEGMENT_IS_FLAT_CODE(seg))) + if (likely(seg == __USER_CS || seg == __KERNEL_CS)) return eip; /* Check the segment exists, is within the current LDT/GDT size, @@ -431,7 +436,11 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, write = 0; switch (error_code & 3) { default: /* 3: write, present */ - /* fall through */ +#ifdef TEST_VERIFY_AREA + if (regs->cs == KERNEL_CS) + printk("WP fault at %08lx\n", regs->eip); +#endif + /* fall through */ case 2: /* write, not present */ if (!(vma->vm_flags & VM_WRITE)) goto bad_area; @@ -440,7 +449,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, case 1: /* read, present */ goto bad_area; case 0: /* read, not present */ - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } @@ -589,7 +598,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_init(tsk)) { + if (tsk->pid == 1) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/i386/mm/highmem.c b/trunk/arch/i386/mm/highmem.c index f9f647cdbc7b..b6eb4dcb8777 100644 --- a/trunk/arch/i386/mm/highmem.c +++ b/trunk/arch/i386/mm/highmem.c @@ -38,20 +38,23 @@ void *kmap_atomic(struct page *page, enum km_type type) idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); +#ifdef CONFIG_DEBUG_HIGHMEM if (!pte_none(*(kmap_pte-idx))) BUG(); +#endif set_pte(kmap_pte-idx, mk_pte(page, kmap_prot)); + __flush_tlb_one(vaddr); return (void*) vaddr; } void kunmap_atomic(void *kvaddr, enum km_type type) { +#ifdef CONFIG_DEBUG_HIGHMEM unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); -#ifdef CONFIG_DEBUG_HIGHMEM - if (vaddr >= PAGE_OFFSET && vaddr < (unsigned long)high_memory) { + if (vaddr < FIXADDR_START) { // FIXME dec_preempt_count(); preempt_check_resched(); return; @@ -59,14 +62,14 @@ void kunmap_atomic(void *kvaddr, enum km_type type) if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx)) BUG(); -#endif + /* - * Force other mappings to Oops if they'll try to access this pte - * without first remap it. Keeping stale mappings around is a bad idea - * also, in case the page changes cacheability attributes or becomes - * a protected page in a hypervisor. + * force other mappings to Oops if they'll try to access + * this pte without first remap it */ - kpte_clear_flush(kmap_pte-idx, vaddr); + pte_clear(&init_mm, vaddr, kmap_pte-idx); + __flush_tlb_one(vaddr); +#endif dec_preempt_count(); preempt_check_resched(); @@ -85,6 +88,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot)); + __flush_tlb_one(vaddr); return (void*) vaddr; } diff --git a/trunk/arch/i386/mm/init.c b/trunk/arch/i386/mm/init.c index 90089c14c23d..efd0bcdac65d 100644 --- a/trunk/arch/i386/mm/init.c +++ b/trunk/arch/i386/mm/init.c @@ -435,22 +435,16 @@ u64 __supported_pte_mask __read_mostly = ~_PAGE_NX; * on Enable * off Disable */ -static int __init noexec_setup(char *str) +void __init noexec_setup(const char *str) { - if (!str || !strcmp(str, "on")) { - if (cpu_has_nx) { - __supported_pte_mask |= _PAGE_NX; - disable_nx = 0; - } - } else if (!strcmp(str,"off")) { + if (!strncmp(str, "on",2) && cpu_has_nx) { + __supported_pte_mask |= _PAGE_NX; + disable_nx = 0; + } else if (!strncmp(str,"off",3)) { disable_nx = 1; __supported_pte_mask &= ~_PAGE_NX; - } else - return -EINVAL; - - return 0; + } } -early_param("noexec", noexec_setup); int nx_enabled = 0; #ifdef CONFIG_X86_PAE @@ -493,7 +487,6 @@ int __init set_kernel_exec(unsigned long vaddr, int enable) pte->pte_high &= ~(1 << (_PAGE_BIT_NX - 32)); else pte->pte_high |= 1 << (_PAGE_BIT_NX - 32); - pte_update_defer(&init_mm, vaddr, pte); __flush_tlb_all(); out: return ret; @@ -559,6 +552,18 @@ static void __init test_wp_bit(void) } } +static void __init set_max_mapnr_init(void) +{ +#ifdef CONFIG_HIGHMEM + num_physpages = highend_pfn; +#else + num_physpages = max_low_pfn; +#endif +#ifdef CONFIG_FLATMEM + max_mapnr = num_physpages; +#endif +} + static struct kcore_list kcore_mem, kcore_vmalloc; void __init mem_init(void) @@ -585,6 +590,14 @@ void __init mem_init(void) } #endif + set_max_mapnr_init(); + +#ifdef CONFIG_HIGHMEM + high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; +#else + high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1; +#endif + /* this will put all low memory onto the freelists */ totalram_pages += free_all_bootmem(); diff --git a/trunk/arch/i386/mm/ioremap.c b/trunk/arch/i386/mm/ioremap.c index fff08ae7b5ed..247fde76aaed 100644 --- a/trunk/arch/i386/mm/ioremap.c +++ b/trunk/arch/i386/mm/ioremap.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include @@ -21,6 +21,82 @@ #define ISA_START_ADDRESS 0xa0000 #define ISA_END_ADDRESS 0x100000 +static int ioremap_pte_range(pmd_t *pmd, unsigned long addr, + unsigned long end, unsigned long phys_addr, unsigned long flags) +{ + pte_t *pte; + unsigned long pfn; + + pfn = phys_addr >> PAGE_SHIFT; + pte = pte_alloc_kernel(pmd, addr); + if (!pte) + return -ENOMEM; + do { + BUG_ON(!pte_none(*pte)); + set_pte(pte, pfn_pte(pfn, __pgprot(_PAGE_PRESENT | _PAGE_RW | + _PAGE_DIRTY | _PAGE_ACCESSED | flags))); + pfn++; + } while (pte++, addr += PAGE_SIZE, addr != end); + return 0; +} + +static inline int ioremap_pmd_range(pud_t *pud, unsigned long addr, + unsigned long end, unsigned long phys_addr, unsigned long flags) +{ + pmd_t *pmd; + unsigned long next; + + phys_addr -= addr; + pmd = pmd_alloc(&init_mm, pud, addr); + if (!pmd) + return -ENOMEM; + do { + next = pmd_addr_end(addr, end); + if (ioremap_pte_range(pmd, addr, next, phys_addr + addr, flags)) + return -ENOMEM; + } while (pmd++, addr = next, addr != end); + return 0; +} + +static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr, + unsigned long end, unsigned long phys_addr, unsigned long flags) +{ + pud_t *pud; + unsigned long next; + + phys_addr -= addr; + pud = pud_alloc(&init_mm, pgd, addr); + if (!pud) + return -ENOMEM; + do { + next = pud_addr_end(addr, end); + if (ioremap_pmd_range(pud, addr, next, phys_addr + addr, flags)) + return -ENOMEM; + } while (pud++, addr = next, addr != end); + return 0; +} + +static int ioremap_page_range(unsigned long addr, + unsigned long end, unsigned long phys_addr, unsigned long flags) +{ + pgd_t *pgd; + unsigned long next; + int err; + + BUG_ON(addr >= end); + flush_cache_all(); + phys_addr -= addr; + pgd = pgd_offset_k(addr); + do { + next = pgd_addr_end(addr, end); + err = ioremap_pud_range(pgd, addr, next, phys_addr+addr, flags); + if (err) + break; + } while (pgd++, addr = next, addr != end); + flush_tlb_all(); + return err; +} + /* * Generic mapping function (not visible outside): */ @@ -39,7 +115,6 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l void __iomem * addr; struct vm_struct * area; unsigned long offset, last_addr; - pgprot_t prot; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -67,9 +142,6 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l return NULL; } - prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY - | _PAGE_ACCESSED | flags); - /* * Mappings have to be page-aligned */ @@ -86,7 +158,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l area->phys_addr = phys_addr; addr = (void __iomem *) area->addr; if (ioremap_page_range((unsigned long) addr, - (unsigned long) addr + size, phys_addr, prot)) { + (unsigned long) addr + size, phys_addr, flags)) { vunmap((void __force *) addr); return NULL; } diff --git a/trunk/arch/i386/oprofile/nmi_int.c b/trunk/arch/i386/oprofile/nmi_int.c index 3700eef78743..5f8dc8a21bd7 100644 --- a/trunk/arch/i386/oprofile/nmi_int.c +++ b/trunk/arch/i386/oprofile/nmi_int.c @@ -17,15 +17,14 @@ #include #include #include -#include #include "op_counter.h" #include "op_x86_model.h" - + static struct op_x86_model_spec const * model; static struct op_msrs cpu_msrs[NR_CPUS]; static unsigned long saved_lvtpc[NR_CPUS]; - + static int nmi_start(void); static void nmi_stop(void); @@ -83,24 +82,13 @@ static void exit_driverfs(void) #define exit_driverfs() do { } while (0) #endif /* CONFIG_PM */ -static int profile_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data) -{ - struct die_args *args = (struct die_args *)data; - int ret = NOTIFY_DONE; - int cpu = smp_processor_id(); - switch(val) { - case DIE_NMI: - if (model->check_ctrs(args->regs, &cpu_msrs[cpu])) - ret = NOTIFY_STOP; - break; - default: - break; - } - return ret; +static int nmi_callback(struct pt_regs * regs, int cpu) +{ + return model->check_ctrs(regs, &cpu_msrs[cpu]); } - + + static void nmi_cpu_save_registers(struct op_msrs * msrs) { unsigned int const nr_ctrs = model->num_counters; @@ -110,19 +98,15 @@ static void nmi_cpu_save_registers(struct op_msrs * msrs) unsigned int i; for (i = 0; i < nr_ctrs; ++i) { - if (counters[i].addr){ - rdmsr(counters[i].addr, - counters[i].saved.low, - counters[i].saved.high); - } + rdmsr(counters[i].addr, + counters[i].saved.low, + counters[i].saved.high); } for (i = 0; i < nr_ctrls; ++i) { - if (controls[i].addr){ - rdmsr(controls[i].addr, - controls[i].saved.low, - controls[i].saved.high); - } + rdmsr(controls[i].addr, + controls[i].saved.low, + controls[i].saved.high); } } @@ -186,29 +170,27 @@ static void nmi_cpu_setup(void * dummy) apic_write(APIC_LVTPC, APIC_DM_NMI); } -static struct notifier_block profile_exceptions_nb = { - .notifier_call = profile_exceptions_notify, - .next = NULL, - .priority = 0 -}; static int nmi_setup(void) { - int err=0; - if (!allocate_msrs()) return -ENOMEM; - if ((err = register_die_notifier(&profile_exceptions_nb))){ + /* We walk a thin line between law and rape here. + * We need to be careful to install our NMI handler + * without actually triggering any NMIs as this will + * break the core code horrifically. + */ + if (reserve_lapic_nmi() < 0) { free_msrs(); - return err; + return -EBUSY; } - /* We need to serialize save and setup for HT because the subset * of msrs are distinct for save and setup operations */ on_each_cpu(nmi_save_registers, NULL, 0, 1); on_each_cpu(nmi_cpu_setup, NULL, 0, 1); + set_nmi_callback(nmi_callback); nmi_enabled = 1; return 0; } @@ -223,19 +205,15 @@ static void nmi_restore_registers(struct op_msrs * msrs) unsigned int i; for (i = 0; i < nr_ctrls; ++i) { - if (controls[i].addr){ - wrmsr(controls[i].addr, - controls[i].saved.low, - controls[i].saved.high); - } + wrmsr(controls[i].addr, + controls[i].saved.low, + controls[i].saved.high); } for (i = 0; i < nr_ctrs; ++i) { - if (counters[i].addr){ - wrmsr(counters[i].addr, - counters[i].saved.low, - counters[i].saved.high); - } + wrmsr(counters[i].addr, + counters[i].saved.low, + counters[i].saved.high); } } @@ -256,7 +234,6 @@ static void nmi_cpu_shutdown(void * dummy) apic_write(APIC_LVTPC, saved_lvtpc[cpu]); apic_write(APIC_LVTERR, v); nmi_restore_registers(msrs); - model->shutdown(msrs); } @@ -264,7 +241,8 @@ static void nmi_shutdown(void) { nmi_enabled = 0; on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1); - unregister_die_notifier(&profile_exceptions_nb); + unset_nmi_callback(); + release_lapic_nmi(); free_msrs(); } @@ -306,14 +284,6 @@ static int nmi_create_files(struct super_block * sb, struct dentry * root) struct dentry * dir; char buf[4]; - /* quick little hack to _not_ expose a counter if it is not - * available for use. This should protect userspace app. - * NOTE: assumes 1:1 mapping here (that counters are organized - * sequentially in their struct assignment). - */ - if (unlikely(!avail_to_resrv_perfctr_nmi_bit(i))) - continue; - snprintf(buf, sizeof(buf), "%d", i); dir = oprofilefs_mkdir(sb, root, buf); oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled); diff --git a/trunk/arch/i386/oprofile/nmi_timer_int.c b/trunk/arch/i386/oprofile/nmi_timer_int.c index abf0ba52a635..930a1127bb30 100644 --- a/trunk/arch/i386/oprofile/nmi_timer_int.c +++ b/trunk/arch/i386/oprofile/nmi_timer_int.c @@ -17,49 +17,34 @@ #include #include #include -#include -static int profile_timer_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data) +static int nmi_timer_callback(struct pt_regs * regs, int cpu) { - struct die_args *args = (struct die_args *)data; - int ret = NOTIFY_DONE; - - switch(val) { - case DIE_NMI: - oprofile_add_sample(args->regs, 0); - ret = NOTIFY_STOP; - break; - default: - break; - } - return ret; + oprofile_add_sample(regs, 0); + return 1; } -static struct notifier_block profile_timer_exceptions_nb = { - .notifier_call = profile_timer_exceptions_notify, - .next = NULL, - .priority = 0 -}; - static int timer_start(void) { - if (register_die_notifier(&profile_timer_exceptions_nb)) - return 1; + disable_timer_nmi_watchdog(); + set_nmi_callback(nmi_timer_callback); return 0; } static void timer_stop(void) { - unregister_die_notifier(&profile_timer_exceptions_nb); + enable_timer_nmi_watchdog(); + unset_nmi_callback(); synchronize_sched(); /* Allow already-started NMIs to complete. */ } int __init op_nmi_timer_init(struct oprofile_operations * ops) { - if ((nmi_watchdog != NMI_IO_APIC) || (atomic_read(&nmi_active) <= 0)) + extern int nmi_active; + + if (nmi_active <= 0) return -ENODEV; ops->start = timer_start; diff --git a/trunk/arch/i386/oprofile/op_model_athlon.c b/trunk/arch/i386/oprofile/op_model_athlon.c index 3057a19e4641..693bdea4a52b 100644 --- a/trunk/arch/i386/oprofile/op_model_athlon.c +++ b/trunk/arch/i386/oprofile/op_model_athlon.c @@ -21,12 +21,10 @@ #define NUM_COUNTERS 4 #define NUM_CONTROLS 4 -#define CTR_IS_RESERVED(msrs,c) (msrs->counters[(c)].addr ? 1 : 0) #define CTR_READ(l,h,msrs,c) do {rdmsr(msrs->counters[(c)].addr, (l), (h));} while (0) #define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters[(c)].addr, -(unsigned int)(l), -1);} while (0) #define CTR_OVERFLOWED(n) (!((n) & (1U<<31))) -#define CTRL_IS_RESERVED(msrs,c) (msrs->controls[(c)].addr ? 1 : 0) #define CTRL_READ(l,h,msrs,c) do {rdmsr(msrs->controls[(c)].addr, (l), (h));} while (0) #define CTRL_WRITE(l,h,msrs,c) do {wrmsr(msrs->controls[(c)].addr, (l), (h));} while (0) #define CTRL_SET_ACTIVE(n) (n |= (1<<22)) @@ -42,21 +40,15 @@ static unsigned long reset_value[NUM_COUNTERS]; static void athlon_fill_in_addresses(struct op_msrs * const msrs) { - int i; - - for (i=0; i < NUM_COUNTERS; i++) { - if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i)) - msrs->counters[i].addr = MSR_K7_PERFCTR0 + i; - else - msrs->counters[i].addr = 0; - } - - for (i=0; i < NUM_CONTROLS; i++) { - if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i)) - msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i; - else - msrs->controls[i].addr = 0; - } + msrs->counters[0].addr = MSR_K7_PERFCTR0; + msrs->counters[1].addr = MSR_K7_PERFCTR1; + msrs->counters[2].addr = MSR_K7_PERFCTR2; + msrs->counters[3].addr = MSR_K7_PERFCTR3; + + msrs->controls[0].addr = MSR_K7_EVNTSEL0; + msrs->controls[1].addr = MSR_K7_EVNTSEL1; + msrs->controls[2].addr = MSR_K7_EVNTSEL2; + msrs->controls[3].addr = MSR_K7_EVNTSEL3; } @@ -67,23 +59,19 @@ static void athlon_setup_ctrs(struct op_msrs const * const msrs) /* clear all counters */ for (i = 0 ; i < NUM_CONTROLS; ++i) { - if (unlikely(!CTRL_IS_RESERVED(msrs,i))) - continue; CTRL_READ(low, high, msrs, i); CTRL_CLEAR(low); CTRL_WRITE(low, high, msrs, i); } - + /* avoid a false detection of ctr overflows in NMI handler */ for (i = 0; i < NUM_COUNTERS; ++i) { - if (unlikely(!CTR_IS_RESERVED(msrs,i))) - continue; CTR_WRITE(1, msrs, i); } /* enable active counters */ for (i = 0; i < NUM_COUNTERS; ++i) { - if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs,i))) { + if (counter_config[i].enabled) { reset_value[i] = counter_config[i].count; CTR_WRITE(counter_config[i].count, msrs, i); @@ -110,8 +98,6 @@ static int athlon_check_ctrs(struct pt_regs * const regs, int i; for (i = 0 ; i < NUM_COUNTERS; ++i) { - if (!reset_value[i]) - continue; CTR_READ(low, high, msrs, i); if (CTR_OVERFLOWED(low)) { oprofile_add_sample(regs, i); @@ -146,27 +132,12 @@ static void athlon_stop(struct op_msrs const * const msrs) /* Subtle: stop on all counters to avoid race with * setting our pm callback */ for (i = 0 ; i < NUM_COUNTERS ; ++i) { - if (!reset_value[i]) - continue; CTRL_READ(low, high, msrs, i); CTRL_SET_INACTIVE(low); CTRL_WRITE(low, high, msrs, i); } } -static void athlon_shutdown(struct op_msrs const * const msrs) -{ - int i; - - for (i = 0 ; i < NUM_COUNTERS ; ++i) { - if (CTR_IS_RESERVED(msrs,i)) - release_perfctr_nmi(MSR_K7_PERFCTR0 + i); - } - for (i = 0 ; i < NUM_CONTROLS ; ++i) { - if (CTRL_IS_RESERVED(msrs,i)) - release_evntsel_nmi(MSR_K7_EVNTSEL0 + i); - } -} struct op_x86_model_spec const op_athlon_spec = { .num_counters = NUM_COUNTERS, @@ -175,6 +146,5 @@ struct op_x86_model_spec const op_athlon_spec = { .setup_ctrs = &athlon_setup_ctrs, .check_ctrs = &athlon_check_ctrs, .start = &athlon_start, - .stop = &athlon_stop, - .shutdown = &athlon_shutdown + .stop = &athlon_stop }; diff --git a/trunk/arch/i386/oprofile/op_model_p4.c b/trunk/arch/i386/oprofile/op_model_p4.c index 47925927b12f..7c61d357b82b 100644 --- a/trunk/arch/i386/oprofile/op_model_p4.c +++ b/trunk/arch/i386/oprofile/op_model_p4.c @@ -32,7 +32,7 @@ #define NUM_CONTROLS_HT2 (NUM_ESCRS_HT2 + NUM_CCCRS_HT2) static unsigned int num_counters = NUM_COUNTERS_NON_HT; -static unsigned int num_controls = NUM_CONTROLS_NON_HT; + /* this has to be checked dynamically since the hyper-threadedness of a chip is discovered at @@ -40,10 +40,8 @@ static unsigned int num_controls = NUM_CONTROLS_NON_HT; static inline void setup_num_counters(void) { #ifdef CONFIG_SMP - if (smp_num_siblings == 2){ + if (smp_num_siblings == 2) num_counters = NUM_COUNTERS_HT2; - num_controls = NUM_CONTROLS_HT2; - } #endif } @@ -99,6 +97,15 @@ static struct p4_counter_binding p4_counters [NUM_COUNTERS_NON_HT] = { #define NUM_UNUSED_CCCRS NUM_CCCRS_NON_HT - NUM_COUNTERS_NON_HT +/* All cccr we don't use. */ +static int p4_unused_cccr[NUM_UNUSED_CCCRS] = { + MSR_P4_BPU_CCCR1, MSR_P4_BPU_CCCR3, + MSR_P4_MS_CCCR1, MSR_P4_MS_CCCR3, + MSR_P4_FLAME_CCCR1, MSR_P4_FLAME_CCCR3, + MSR_P4_IQ_CCCR0, MSR_P4_IQ_CCCR1, + MSR_P4_IQ_CCCR2, MSR_P4_IQ_CCCR3 +}; + /* p4 event codes in libop/op_event.h are indices into this table. */ static struct p4_event_binding p4_events[NUM_EVENTS] = { @@ -365,8 +372,6 @@ static struct p4_event_binding p4_events[NUM_EVENTS] = { #define CCCR_OVF_P(cccr) ((cccr) & (1U<<31)) #define CCCR_CLEAR_OVF(cccr) ((cccr) &= (~(1U<<31))) -#define CTRL_IS_RESERVED(msrs,c) (msrs->controls[(c)].addr ? 1 : 0) -#define CTR_IS_RESERVED(msrs,c) (msrs->counters[(c)].addr ? 1 : 0) #define CTR_READ(l,h,i) do {rdmsr(p4_counters[(i)].counter_address, (l), (h));} while (0) #define CTR_WRITE(l,i) do {wrmsr(p4_counters[(i)].counter_address, -(u32)(l), -1);} while (0) #define CTR_OVERFLOW_P(ctr) (!((ctr) & 0x80000000)) @@ -396,34 +401,29 @@ static unsigned long reset_value[NUM_COUNTERS_NON_HT]; static void p4_fill_in_addresses(struct op_msrs * const msrs) { unsigned int i; - unsigned int addr, cccraddr, stag; + unsigned int addr, stag; setup_num_counters(); stag = get_stagger(); - /* initialize some registers */ + /* the counter registers we pay attention to */ for (i = 0; i < num_counters; ++i) { - msrs->counters[i].addr = 0; + msrs->counters[i].addr = + p4_counters[VIRT_CTR(stag, i)].counter_address; } - for (i = 0; i < num_controls; ++i) { - msrs->controls[i].addr = 0; + + /* FIXME: bad feeling, we don't save the 10 counters we don't use. */ + + /* 18 CCCR registers */ + for (i = 0, addr = MSR_P4_BPU_CCCR0 + stag; + addr <= MSR_P4_IQ_CCCR5; ++i, addr += addr_increment()) { + msrs->controls[i].addr = addr; } - /* the counter & cccr registers we pay attention to */ - for (i = 0; i < num_counters; ++i) { - addr = p4_counters[VIRT_CTR(stag, i)].counter_address; - cccraddr = p4_counters[VIRT_CTR(stag, i)].cccr_address; - if (reserve_perfctr_nmi(addr)){ - msrs->counters[i].addr = addr; - msrs->controls[i].addr = cccraddr; - } - } - /* 43 ESCR registers in three or four discontiguous group */ for (addr = MSR_P4_BSU_ESCR0 + stag; addr < MSR_P4_IQ_ESCR0; ++i, addr += addr_increment()) { - if (reserve_evntsel_nmi(addr)) - msrs->controls[i].addr = addr; + msrs->controls[i].addr = addr; } /* no IQ_ESCR0/1 on some models, we save a seconde time BSU_ESCR0/1 @@ -431,57 +431,47 @@ static void p4_fill_in_addresses(struct op_msrs * const msrs) if (boot_cpu_data.x86_model >= 0x3) { for (addr = MSR_P4_BSU_ESCR0 + stag; addr <= MSR_P4_BSU_ESCR1; ++i, addr += addr_increment()) { - if (reserve_evntsel_nmi(addr)) - msrs->controls[i].addr = addr; + msrs->controls[i].addr = addr; } } else { for (addr = MSR_P4_IQ_ESCR0 + stag; addr <= MSR_P4_IQ_ESCR1; ++i, addr += addr_increment()) { - if (reserve_evntsel_nmi(addr)) - msrs->controls[i].addr = addr; + msrs->controls[i].addr = addr; } } for (addr = MSR_P4_RAT_ESCR0 + stag; addr <= MSR_P4_SSU_ESCR0; ++i, addr += addr_increment()) { - if (reserve_evntsel_nmi(addr)) - msrs->controls[i].addr = addr; + msrs->controls[i].addr = addr; } for (addr = MSR_P4_MS_ESCR0 + stag; addr <= MSR_P4_TC_ESCR1; ++i, addr += addr_increment()) { - if (reserve_evntsel_nmi(addr)) - msrs->controls[i].addr = addr; + msrs->controls[i].addr = addr; } for (addr = MSR_P4_IX_ESCR0 + stag; addr <= MSR_P4_CRU_ESCR3; ++i, addr += addr_increment()) { - if (reserve_evntsel_nmi(addr)) - msrs->controls[i].addr = addr; + msrs->controls[i].addr = addr; } /* there are 2 remaining non-contiguously located ESCRs */ if (num_counters == NUM_COUNTERS_NON_HT) { /* standard non-HT CPUs handle both remaining ESCRs*/ - if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5)) - msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; - if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR4)) - msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; + msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; + msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; } else if (stag == 0) { /* HT CPUs give the first remainder to the even thread, as the 32nd control register */ - if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR4)) - msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; + msrs->controls[i++].addr = MSR_P4_CRU_ESCR4; } else { /* and two copies of the second to the odd thread, for the 22st and 23nd control registers */ - if (reserve_evntsel_nmi(MSR_P4_CRU_ESCR5)) { - msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; - msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; - } + msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; + msrs->controls[i++].addr = MSR_P4_CRU_ESCR5; } } @@ -554,6 +544,7 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs) { unsigned int i; unsigned int low, high; + unsigned int addr; unsigned int stag; stag = get_stagger(); @@ -566,24 +557,59 @@ static void p4_setup_ctrs(struct op_msrs const * const msrs) /* clear the cccrs we will use */ for (i = 0 ; i < num_counters ; i++) { - if (unlikely(!CTRL_IS_RESERVED(msrs,i))) - continue; rdmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); CCCR_CLEAR(low); CCCR_SET_REQUIRED_BITS(low); wrmsr(p4_counters[VIRT_CTR(stag, i)].cccr_address, low, high); } + /* clear cccrs outside our concern */ + for (i = stag ; i < NUM_UNUSED_CCCRS ; i += addr_increment()) { + rdmsr(p4_unused_cccr[i], low, high); + CCCR_CLEAR(low); + CCCR_SET_REQUIRED_BITS(low); + wrmsr(p4_unused_cccr[i], low, high); + } + /* clear all escrs (including those outside our concern) */ - for (i = num_counters; i < num_controls; i++) { - if (unlikely(!CTRL_IS_RESERVED(msrs,i))) - continue; - wrmsr(msrs->controls[i].addr, 0, 0); + for (addr = MSR_P4_BSU_ESCR0 + stag; + addr < MSR_P4_IQ_ESCR0; addr += addr_increment()) { + wrmsr(addr, 0, 0); + } + + /* On older models clear also MSR_P4_IQ_ESCR0/1 */ + if (boot_cpu_data.x86_model < 0x3) { + wrmsr(MSR_P4_IQ_ESCR0, 0, 0); + wrmsr(MSR_P4_IQ_ESCR1, 0, 0); } + for (addr = MSR_P4_RAT_ESCR0 + stag; + addr <= MSR_P4_SSU_ESCR0; ++i, addr += addr_increment()) { + wrmsr(addr, 0, 0); + } + + for (addr = MSR_P4_MS_ESCR0 + stag; + addr <= MSR_P4_TC_ESCR1; addr += addr_increment()){ + wrmsr(addr, 0, 0); + } + + for (addr = MSR_P4_IX_ESCR0 + stag; + addr <= MSR_P4_CRU_ESCR3; addr += addr_increment()){ + wrmsr(addr, 0, 0); + } + + if (num_counters == NUM_COUNTERS_NON_HT) { + wrmsr(MSR_P4_CRU_ESCR4, 0, 0); + wrmsr(MSR_P4_CRU_ESCR5, 0, 0); + } else if (stag == 0) { + wrmsr(MSR_P4_CRU_ESCR4, 0, 0); + } else { + wrmsr(MSR_P4_CRU_ESCR5, 0, 0); + } + /* setup all counters */ for (i = 0 ; i < num_counters ; ++i) { - if ((counter_config[i].enabled) && (CTRL_IS_RESERVED(msrs,i))) { + if (counter_config[i].enabled) { reset_value[i] = counter_config[i].count; pmc_setup_one_p4_counter(i); CTR_WRITE(counter_config[i].count, VIRT_CTR(stag, i)); @@ -670,32 +696,12 @@ static void p4_stop(struct op_msrs const * const msrs) stag = get_stagger(); for (i = 0; i < num_counters; ++i) { - if (!reset_value[i]) - continue; CCCR_READ(low, high, VIRT_CTR(stag, i)); CCCR_SET_DISABLE(low); CCCR_WRITE(low, high, VIRT_CTR(stag, i)); } } -static void p4_shutdown(struct op_msrs const * const msrs) -{ - int i; - - for (i = 0 ; i < num_counters ; ++i) { - if (CTR_IS_RESERVED(msrs,i)) - release_perfctr_nmi(msrs->counters[i].addr); - } - /* some of the control registers are specially reserved in - * conjunction with the counter registers (hence the starting offset). - * This saves a few bits. - */ - for (i = num_counters ; i < num_controls ; ++i) { - if (CTRL_IS_RESERVED(msrs,i)) - release_evntsel_nmi(msrs->controls[i].addr); - } -} - #ifdef CONFIG_SMP struct op_x86_model_spec const op_p4_ht2_spec = { @@ -705,8 +711,7 @@ struct op_x86_model_spec const op_p4_ht2_spec = { .setup_ctrs = &p4_setup_ctrs, .check_ctrs = &p4_check_ctrs, .start = &p4_start, - .stop = &p4_stop, - .shutdown = &p4_shutdown + .stop = &p4_stop }; #endif @@ -717,6 +722,5 @@ struct op_x86_model_spec const op_p4_spec = { .setup_ctrs = &p4_setup_ctrs, .check_ctrs = &p4_check_ctrs, .start = &p4_start, - .stop = &p4_stop, - .shutdown = &p4_shutdown + .stop = &p4_stop }; diff --git a/trunk/arch/i386/oprofile/op_model_ppro.c b/trunk/arch/i386/oprofile/op_model_ppro.c index ca2447e05e15..5c3ab4b027ad 100644 --- a/trunk/arch/i386/oprofile/op_model_ppro.c +++ b/trunk/arch/i386/oprofile/op_model_ppro.c @@ -22,12 +22,10 @@ #define NUM_COUNTERS 2 #define NUM_CONTROLS 2 -#define CTR_IS_RESERVED(msrs,c) (msrs->counters[(c)].addr ? 1 : 0) #define CTR_READ(l,h,msrs,c) do {rdmsr(msrs->counters[(c)].addr, (l), (h));} while (0) #define CTR_WRITE(l,msrs,c) do {wrmsr(msrs->counters[(c)].addr, -(u32)(l), -1);} while (0) #define CTR_OVERFLOWED(n) (!((n) & (1U<<31))) -#define CTRL_IS_RESERVED(msrs,c) (msrs->controls[(c)].addr ? 1 : 0) #define CTRL_READ(l,h,msrs,c) do {rdmsr((msrs->controls[(c)].addr), (l), (h));} while (0) #define CTRL_WRITE(l,h,msrs,c) do {wrmsr((msrs->controls[(c)].addr), (l), (h));} while (0) #define CTRL_SET_ACTIVE(n) (n |= (1<<22)) @@ -43,21 +41,11 @@ static unsigned long reset_value[NUM_COUNTERS]; static void ppro_fill_in_addresses(struct op_msrs * const msrs) { - int i; - - for (i=0; i < NUM_COUNTERS; i++) { - if (reserve_perfctr_nmi(MSR_P6_PERFCTR0 + i)) - msrs->counters[i].addr = MSR_P6_PERFCTR0 + i; - else - msrs->counters[i].addr = 0; - } + msrs->counters[0].addr = MSR_P6_PERFCTR0; + msrs->counters[1].addr = MSR_P6_PERFCTR1; - for (i=0; i < NUM_CONTROLS; i++) { - if (reserve_evntsel_nmi(MSR_P6_EVNTSEL0 + i)) - msrs->controls[i].addr = MSR_P6_EVNTSEL0 + i; - else - msrs->controls[i].addr = 0; - } + msrs->controls[0].addr = MSR_P6_EVNTSEL0; + msrs->controls[1].addr = MSR_P6_EVNTSEL1; } @@ -68,8 +56,6 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs) /* clear all counters */ for (i = 0 ; i < NUM_CONTROLS; ++i) { - if (unlikely(!CTRL_IS_RESERVED(msrs,i))) - continue; CTRL_READ(low, high, msrs, i); CTRL_CLEAR(low); CTRL_WRITE(low, high, msrs, i); @@ -77,14 +63,12 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs) /* avoid a false detection of ctr overflows in NMI handler */ for (i = 0; i < NUM_COUNTERS; ++i) { - if (unlikely(!CTR_IS_RESERVED(msrs,i))) - continue; CTR_WRITE(1, msrs, i); } /* enable active counters */ for (i = 0; i < NUM_COUNTERS; ++i) { - if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs,i))) { + if (counter_config[i].enabled) { reset_value[i] = counter_config[i].count; CTR_WRITE(counter_config[i].count, msrs, i); @@ -97,8 +81,6 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs) CTRL_SET_UM(low, counter_config[i].unit_mask); CTRL_SET_EVENT(low, counter_config[i].event); CTRL_WRITE(low, high, msrs, i); - } else { - reset_value[i] = 0; } } } @@ -111,8 +93,6 @@ static int ppro_check_ctrs(struct pt_regs * const regs, int i; for (i = 0 ; i < NUM_COUNTERS; ++i) { - if (!reset_value[i]) - continue; CTR_READ(low, high, msrs, i); if (CTR_OVERFLOWED(low)) { oprofile_add_sample(regs, i); @@ -138,44 +118,18 @@ static int ppro_check_ctrs(struct pt_regs * const regs, static void ppro_start(struct op_msrs const * const msrs) { unsigned int low,high; - int i; - - for (i = 0; i < NUM_COUNTERS; ++i) { - if (reset_value[i]) { - CTRL_READ(low, high, msrs, i); - CTRL_SET_ACTIVE(low); - CTRL_WRITE(low, high, msrs, i); - } - } + CTRL_READ(low, high, msrs, 0); + CTRL_SET_ACTIVE(low); + CTRL_WRITE(low, high, msrs, 0); } static void ppro_stop(struct op_msrs const * const msrs) { unsigned int low,high; - int i; - - for (i = 0; i < NUM_COUNTERS; ++i) { - if (!reset_value[i]) - continue; - CTRL_READ(low, high, msrs, i); - CTRL_SET_INACTIVE(low); - CTRL_WRITE(low, high, msrs, i); - } -} - -static void ppro_shutdown(struct op_msrs const * const msrs) -{ - int i; - - for (i = 0 ; i < NUM_COUNTERS ; ++i) { - if (CTR_IS_RESERVED(msrs,i)) - release_perfctr_nmi(MSR_P6_PERFCTR0 + i); - } - for (i = 0 ; i < NUM_CONTROLS ; ++i) { - if (CTRL_IS_RESERVED(msrs,i)) - release_evntsel_nmi(MSR_P6_EVNTSEL0 + i); - } + CTRL_READ(low, high, msrs, 0); + CTRL_SET_INACTIVE(low); + CTRL_WRITE(low, high, msrs, 0); } @@ -186,6 +140,5 @@ struct op_x86_model_spec const op_ppro_spec = { .setup_ctrs = &ppro_setup_ctrs, .check_ctrs = &ppro_check_ctrs, .start = &ppro_start, - .stop = &ppro_stop, - .shutdown = &ppro_shutdown + .stop = &ppro_stop }; diff --git a/trunk/arch/i386/oprofile/op_x86_model.h b/trunk/arch/i386/oprofile/op_x86_model.h index abb1aa95b979..123b7e90a9ee 100644 --- a/trunk/arch/i386/oprofile/op_x86_model.h +++ b/trunk/arch/i386/oprofile/op_x86_model.h @@ -40,7 +40,6 @@ struct op_x86_model_spec { struct op_msrs const * const msrs); void (*start)(struct op_msrs const * const msrs); void (*stop)(struct op_msrs const * const msrs); - void (*shutdown)(struct op_msrs const * const msrs); }; extern struct op_x86_model_spec const op_ppro_spec; diff --git a/trunk/arch/i386/pci/Makefile b/trunk/arch/i386/pci/Makefile index 1594d2f55c8f..62ad75c57e6a 100644 --- a/trunk/arch/i386/pci/Makefile +++ b/trunk/arch/i386/pci/Makefile @@ -11,4 +11,4 @@ pci-y += legacy.o irq.o pci-$(CONFIG_X86_VISWS) := visws.o fixup.o pci-$(CONFIG_X86_NUMAQ) := numa.o irq.o -obj-y += $(pci-y) common.o early.o +obj-y += $(pci-y) common.o diff --git a/trunk/arch/i386/pci/common.c b/trunk/arch/i386/pci/common.c index 68bce194e688..0a362e3aeac5 100644 --- a/trunk/arch/i386/pci/common.c +++ b/trunk/arch/i386/pci/common.c @@ -242,10 +242,6 @@ char * __devinit pcibios_setup(char *str) acpi_noirq_set(); return NULL; } - else if (!strcmp(str, "noearly")) { - pci_probe |= PCI_PROBE_NOEARLY; - return NULL; - } #ifndef CONFIG_X86_VISWS else if (!strcmp(str, "usepirqmask")) { pci_probe |= PCI_USE_PIRQ_MASK; diff --git a/trunk/arch/i386/pci/direct.c b/trunk/arch/i386/pci/direct.c index 5acf0b4743cf..5d81fb510375 100644 --- a/trunk/arch/i386/pci/direct.c +++ b/trunk/arch/i386/pci/direct.c @@ -254,16 +254,7 @@ static int __init pci_check_type2(void) return works; } -void __init pci_direct_init(int type) -{ - printk(KERN_INFO "PCI: Using configuration type %d\n", type); - if (type == 1) - raw_pci_ops = &pci_direct_conf1; - else - raw_pci_ops = &pci_direct_conf2; -} - -int __init pci_direct_probe(void) +void __init pci_direct_init(void) { struct resource *region, *region2; @@ -273,16 +264,19 @@ int __init pci_direct_probe(void) if (!region) goto type2; - if (pci_check_type1()) - return 1; + if (pci_check_type1()) { + printk(KERN_INFO "PCI: Using configuration type 1\n"); + raw_pci_ops = &pci_direct_conf1; + return; + } release_resource(region); type2: if ((pci_probe & PCI_PROBE_CONF2) == 0) - return 0; + return; region = request_region(0xCF8, 4, "PCI conf2"); if (!region) - return 0; + return; region2 = request_region(0xC000, 0x1000, "PCI conf2"); if (!region2) goto fail2; @@ -290,11 +284,10 @@ int __init pci_direct_probe(void) if (pci_check_type2()) { printk(KERN_INFO "PCI: Using configuration type 2\n"); raw_pci_ops = &pci_direct_conf2; - return 2; + return; } release_resource(region2); fail2: release_resource(region); - return 0; } diff --git a/trunk/arch/i386/pci/early.c b/trunk/arch/i386/pci/early.c deleted file mode 100644 index 713d6c866cae..000000000000 --- a/trunk/arch/i386/pci/early.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -#include -#include -#include "pci.h" - -/* Direct PCI access. This is used for PCI accesses in early boot before - the PCI subsystem works. */ - -#define PDprintk(x...) - -u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset) -{ - u32 v; - outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); - v = inl(0xcfc); - if (v != 0xffffffff) - PDprintk("%x reading 4 from %x: %x\n", slot, offset, v); - return v; -} - -u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset) -{ - u8 v; - outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); - v = inb(0xcfc + (offset&3)); - PDprintk("%x reading 1 from %x: %x\n", slot, offset, v); - return v; -} - -u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset) -{ - u16 v; - outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); - v = inw(0xcfc + (offset&2)); - PDprintk("%x reading 2 from %x: %x\n", slot, offset, v); - return v; -} - -void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, - u32 val) -{ - PDprintk("%x writing to %x: %x\n", slot, offset, val); - outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); - outl(val, 0xcfc); -} - -int early_pci_allowed(void) -{ - return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) == - PCI_PROBE_CONF1; -} diff --git a/trunk/arch/i386/pci/init.c b/trunk/arch/i386/pci/init.c index d028e1b05c36..51087a9d9172 100644 --- a/trunk/arch/i386/pci/init.c +++ b/trunk/arch/i386/pci/init.c @@ -6,13 +6,8 @@ in the right sequence from here. */ static __init int pci_access_init(void) { - int type = 0; - -#ifdef CONFIG_PCI_DIRECT - type = pci_direct_probe(); -#endif #ifdef CONFIG_PCI_MMCONFIG - pci_mmcfg_init(type); + pci_mmcfg_init(); #endif if (raw_pci_ops) return 0; @@ -26,7 +21,7 @@ static __init int pci_access_init(void) * fails. */ #ifdef CONFIG_PCI_DIRECT - pci_direct_init(type); + pci_direct_init(); #endif return 0; } diff --git a/trunk/arch/i386/pci/mmconfig.c b/trunk/arch/i386/pci/mmconfig.c index d0c3da3aa2aa..972180f738d9 100644 --- a/trunk/arch/i386/pci/mmconfig.c +++ b/trunk/arch/i386/pci/mmconfig.c @@ -67,10 +67,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) return 0; } -/* - * This is always called under pci_config_lock - */ -static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) +static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) { u32 dev_base = base | (bus << 20) | (devfn << 12); if (dev_base != mmcfg_last_accessed_device) { @@ -154,38 +151,6 @@ static struct pci_raw_ops pci_mmcfg = { .write = pci_mmcfg_write, }; - -static __init void pci_mmcfg_insert_resources(void) -{ -#define PCI_MMCFG_RESOURCE_NAME_LEN 19 - int i; - struct resource *res; - char *names; - unsigned num_buses; - - res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res), - pci_mmcfg_config_num, GFP_KERNEL); - - if (!res) { - printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n"); - return; - } - - names = (void *)&res[pci_mmcfg_config_num]; - for (i = 0; i < pci_mmcfg_config_num; i++, res++) { - num_buses = pci_mmcfg_config[i].end_bus_number - - pci_mmcfg_config[i].start_bus_number + 1; - res->name = names; - snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u", - pci_mmcfg_config[i].pci_segment_group_number); - res->start = pci_mmcfg_config[i].base_address; - res->end = res->start + (num_buses << 20) - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - insert_resource(&iomem_resource, res); - names += PCI_MMCFG_RESOURCE_NAME_LEN; - } -} - /* K8 systems have some devices (typically in the builtin northbridge) that are only accessible using type1 Normally this can be expressed in the MCFG by not listing them @@ -222,9 +187,7 @@ static __init void unreachable_devices(void) } } - - -void __init pci_mmcfg_init(int type) +void __init pci_mmcfg_init(void) { if ((pci_probe & PCI_PROBE_MMCONF) == 0) return; @@ -235,9 +198,7 @@ void __init pci_mmcfg_init(int type) (pci_mmcfg_config[0].base_address == 0)) return; - /* Only do this check when type 1 works. If it doesn't work - assume we run on a Mac and always use MCFG */ - if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].base_address, + if (!e820_all_mapped(pci_mmcfg_config[0].base_address, pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, E820_RESERVED)) { printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", @@ -251,5 +212,4 @@ void __init pci_mmcfg_init(int type) pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; unreachable_devices(); - pci_mmcfg_insert_resources(); } diff --git a/trunk/arch/i386/pci/pci.h b/trunk/arch/i386/pci/pci.h index 1814f74569c6..bf4e79335388 100644 --- a/trunk/arch/i386/pci/pci.h +++ b/trunk/arch/i386/pci/pci.h @@ -17,7 +17,6 @@ #define PCI_PROBE_CONF2 0x0004 #define PCI_PROBE_MMCONF 0x0008 #define PCI_PROBE_MASK 0x000f -#define PCI_PROBE_NOEARLY 0x0010 #define PCI_NO_SORT 0x0100 #define PCI_BIOS_SORT 0x0200 @@ -82,9 +81,7 @@ extern int pci_conf1_write(unsigned int seg, unsigned int bus, extern int pci_conf1_read(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 *value); -extern int pci_direct_probe(void); -extern void pci_direct_init(int type); +extern void pci_direct_init(void); extern void pci_pcbios_init(void); -extern void pci_mmcfg_init(int type); +extern void pci_mmcfg_init(void); extern void pcibios_sort(void); - diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index 70f7eb9fed35..f521f2f60a78 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -356,9 +356,6 @@ config NODES_SHIFT MAX_NUMNODES will be 2^(This value). If in doubt, use the default. -config ARCH_POPULATES_NODE_MAP - def_bool y - # VIRTUAL_MEM_MAP and FLAT_NODE_MEM_MAP are functionally equivalent. # VIRTUAL_MEM_MAP has been retained for historical reasons. config VIRTUAL_MEM_MAP @@ -423,14 +420,6 @@ config IA64_PALINFO config SGI_SN def_bool y if (IA64_SGI_SN2 || IA64_GENERIC) -config IA64_ESI - bool "ESI (Extensible SAL Interface) support" - help - If you say Y here, support is built into the kernel to - make ESI calls. ESI calls are used to support vendor-specific - firmware extensions, such as the ability to inject memory-errors - for test-purposes. If you're unsure, say N. - source "drivers/sn/Kconfig" source "drivers/firmware/Kconfig" @@ -516,7 +505,7 @@ source "arch/ia64/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on KALLSYMS && EXPERIMENTAL && MODULES + depends on EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/trunk/arch/ia64/hp/sim/simeth.c b/trunk/arch/ia64/hp/sim/simeth.c index e1a1b11473e2..b5195be62818 100644 --- a/trunk/arch/ia64/hp/sim/simeth.c +++ b/trunk/arch/ia64/hp/sim/simeth.c @@ -320,7 +320,7 @@ simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr) } printk(KERN_INFO "simeth_device_event: %s ipaddr=0x%x\n", - dev->name, ntohl(ifa->ifa_local)); + dev->name, htonl(ifa->ifa_local)); /* * XXX Fix me @@ -331,7 +331,7 @@ simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr) local = dev->priv; /* now do it for real */ r = event == NETDEV_UP ? - netdev_attach(local->simfd, dev->irq, ntohl(ifa->ifa_local)): + netdev_attach(local->simfd, dev->irq, htonl(ifa->ifa_local)): netdev_detach(local->simfd); printk(KERN_INFO "simeth: netdev_attach/detach: event=%s ->%d\n", diff --git a/trunk/arch/ia64/hp/sim/simserial.c b/trunk/arch/ia64/hp/sim/simserial.c index 246eb3d3757a..0daacc20ed36 100644 --- a/trunk/arch/ia64/hp/sim/simserial.c +++ b/trunk/arch/ia64/hp/sim/simserial.c @@ -940,7 +940,7 @@ static inline void show_serial_version(void) printk(KERN_INFO " no serial options enabled\n"); } -static const struct tty_operations hp_ops = { +static struct tty_operations hp_ops = { .open = rs_open, .close = rs_close, .write = rs_write, diff --git a/trunk/arch/ia64/ia32/sys_ia32.c b/trunk/arch/ia64/ia32/sys_ia32.c index bddbd22706ed..6aa3c51619ca 100644 --- a/trunk/arch/ia64/ia32/sys_ia32.c +++ b/trunk/arch/ia64/ia32/sys_ia32.c @@ -1942,7 +1942,7 @@ struct sysctl32 { unsigned int __unused[4]; }; -#ifdef CONFIG_SYSCTL_SYSCALL +#ifdef CONFIG_SYSCTL asmlinkage long sys32_sysctl (struct sysctl32 __user *args) { diff --git a/trunk/arch/ia64/kernel/Makefile b/trunk/arch/ia64/kernel/Makefile index 31497496eb4b..ad8215a3c586 100644 --- a/trunk/arch/ia64/kernel/Makefile +++ b/trunk/arch/ia64/kernel/Makefile @@ -32,11 +32,6 @@ obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR) += uncached.o obj-$(CONFIG_AUDIT) += audit.o mca_recovery-y += mca_drv.o mca_drv_asm.o -obj-$(CONFIG_IA64_ESI) += esi.o -ifneq ($(CONFIG_IA64_ESI),) -obj-y += esi_stub.o # must be in kernel proper -endif - # The gate DSO image is built using a special linker script. targets += gate.so gate-syms.o diff --git a/trunk/arch/ia64/kernel/entry.S b/trunk/arch/ia64/kernel/entry.S index e5b1be51b197..fef06571be99 100644 --- a/trunk/arch/ia64/kernel/entry.S +++ b/trunk/arch/ia64/kernel/entry.S @@ -492,11 +492,11 @@ GLOBAL_ENTRY(prefetch_stack) br.ret.sptk.many rp END(prefetch_stack) -GLOBAL_ENTRY(kernel_execve) +GLOBAL_ENTRY(execve) mov r15=__NR_execve // put syscall number in place break __BREAK_SYSCALL br.ret.sptk.many rp -END(kernel_execve) +END(execve) GLOBAL_ENTRY(clone) mov r15=__NR_clone // put syscall number in place @@ -1605,8 +1605,8 @@ sys_call_table: data8 sys_ni_syscall // 1295 reserved for ppoll data8 sys_unshare data8 sys_splice - data8 sys_set_robust_list - data8 sys_get_robust_list + data8 sys_ni_syscall // reserved for set_robust_list + data8 sys_ni_syscall // reserved for get_robust_list data8 sys_sync_file_range // 1300 data8 sys_tee data8 sys_vmsplice diff --git a/trunk/arch/ia64/kernel/esi.c b/trunk/arch/ia64/kernel/esi.c deleted file mode 100644 index ebf4e988e78c..000000000000 --- a/trunk/arch/ia64/kernel/esi.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Extensible SAL Interface (ESI) support routines. - * - * Copyright (C) 2006 Hewlett-Packard Co - * Alex Williamson - */ -#include -#include -#include -#include - -#include -#include - -MODULE_AUTHOR("Alex Williamson "); -MODULE_DESCRIPTION("Extensible SAL Interface (ESI) support"); -MODULE_LICENSE("GPL"); - -#define MODULE_NAME "esi" - -#define ESI_TABLE_GUID \ - EFI_GUID(0x43EA58DC, 0xCF28, 0x4b06, 0xB3, \ - 0x91, 0xB7, 0x50, 0x59, 0x34, 0x2B, 0xD4) - -enum esi_systab_entry_type { - ESI_DESC_ENTRY_POINT = 0 -}; - -/* - * Entry type: Size: - * 0 48 - */ -#define ESI_DESC_SIZE(type) "\060"[(unsigned) (type)] - -typedef struct ia64_esi_desc_entry_point { - u8 type; - u8 reserved1[15]; - u64 esi_proc; - u64 gp; - efi_guid_t guid; -} ia64_esi_desc_entry_point_t; - -struct pdesc { - void *addr; - void *gp; -}; - -static struct ia64_sal_systab *esi_systab; - -static int __init esi_init (void) -{ - efi_config_table_t *config_tables; - struct ia64_sal_systab *systab; - unsigned long esi = 0; - char *p; - int i; - - config_tables = __va(efi.systab->tables); - - for (i = 0; i < (int) efi.systab->nr_tables; ++i) { - if (efi_guidcmp(config_tables[i].guid, ESI_TABLE_GUID) == 0) { - esi = config_tables[i].table; - break; - } - } - - if (!esi) - return -ENODEV;; - - systab = __va(esi); - - if (strncmp(systab->signature, "ESIT", 4) != 0) { - printk(KERN_ERR "bad signature in ESI system table!"); - return -ENODEV; - } - - p = (char *) (systab + 1); - for (i = 0; i < systab->entry_count; i++) { - /* - * The first byte of each entry type contains the type - * descriptor. - */ - switch (*p) { - case ESI_DESC_ENTRY_POINT: - break; - default: - printk(KERN_WARNING "Unkown table type %d found in " - "ESI table, ignoring rest of table\n", *p); - return -ENODEV; - } - - p += ESI_DESC_SIZE(*p); - } - - esi_systab = systab; - return 0; -} - - -int ia64_esi_call (efi_guid_t guid, struct ia64_sal_retval *isrvp, - enum esi_proc_type proc_type, u64 func, - u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, - u64 arg7) -{ - struct ia64_fpreg fr[6]; - unsigned long flags = 0; - int i; - char *p; - - if (!esi_systab) - return -1; - - p = (char *) (esi_systab + 1); - for (i = 0; i < esi_systab->entry_count; i++) { - if (*p == ESI_DESC_ENTRY_POINT) { - ia64_esi_desc_entry_point_t *esi = (void *)p; - if (!efi_guidcmp(guid, esi->guid)) { - ia64_sal_handler esi_proc; - struct pdesc pdesc; - - pdesc.addr = __va(esi->esi_proc); - pdesc.gp = __va(esi->gp); - - esi_proc = (ia64_sal_handler) &pdesc; - - ia64_save_scratch_fpregs(fr); - if (proc_type == ESI_PROC_SERIALIZED) - spin_lock_irqsave(&sal_lock, flags); - else if (proc_type == ESI_PROC_MP_SAFE) - local_irq_save(flags); - else - preempt_disable(); - *isrvp = (*esi_proc)(func, arg1, arg2, arg3, - arg4, arg5, arg6, arg7); - if (proc_type == ESI_PROC_SERIALIZED) - spin_unlock_irqrestore(&sal_lock, - flags); - else if (proc_type == ESI_PROC_MP_SAFE) - local_irq_restore(flags); - else - preempt_enable(); - ia64_load_scratch_fpregs(fr); - return 0; - } - } - p += ESI_DESC_SIZE(*p); - } - return -1; -} -EXPORT_SYMBOL_GPL(ia64_esi_call); - -int ia64_esi_call_phys (efi_guid_t guid, struct ia64_sal_retval *isrvp, - u64 func, u64 arg1, u64 arg2, u64 arg3, u64 arg4, - u64 arg5, u64 arg6, u64 arg7) -{ - struct ia64_fpreg fr[6]; - unsigned long flags; - u64 esi_params[8]; - char *p; - int i; - - if (!esi_systab) - return -1; - - p = (char *) (esi_systab + 1); - for (i = 0; i < esi_systab->entry_count; i++) { - if (*p == ESI_DESC_ENTRY_POINT) { - ia64_esi_desc_entry_point_t *esi = (void *)p; - if (!efi_guidcmp(guid, esi->guid)) { - ia64_sal_handler esi_proc; - struct pdesc pdesc; - - pdesc.addr = (void *)esi->esi_proc; - pdesc.gp = (void *)esi->gp; - - esi_proc = (ia64_sal_handler) &pdesc; - - esi_params[0] = func; - esi_params[1] = arg1; - esi_params[2] = arg2; - esi_params[3] = arg3; - esi_params[4] = arg4; - esi_params[5] = arg5; - esi_params[6] = arg6; - esi_params[7] = arg7; - ia64_save_scratch_fpregs(fr); - spin_lock_irqsave(&sal_lock, flags); - *isrvp = esi_call_phys(esi_proc, esi_params); - spin_unlock_irqrestore(&sal_lock, flags); - ia64_load_scratch_fpregs(fr); - return 0; - } - } - p += ESI_DESC_SIZE(*p); - } - return -1; -} -EXPORT_SYMBOL_GPL(ia64_esi_call_phys); - -static void __exit esi_exit (void) -{ -} - -module_init(esi_init); -module_exit(esi_exit); /* makes module removable... */ diff --git a/trunk/arch/ia64/kernel/esi_stub.S b/trunk/arch/ia64/kernel/esi_stub.S deleted file mode 100644 index 6b3d6c1f99b6..000000000000 --- a/trunk/arch/ia64/kernel/esi_stub.S +++ /dev/null @@ -1,96 +0,0 @@ -/* - * ESI call stub. - * - * Copyright (C) 2005 Hewlett-Packard Co - * Alex Williamson - * - * Based on EFI call stub by David Mosberger. The stub is virtually - * identical to the one for EFI phys-mode calls, except that ESI - * calls may have up to 8 arguments, so they get passed to this routine - * through memory. - * - * This stub allows us to make ESI calls in physical mode with interrupts - * turned off. ESI calls may not support calling from virtual mode. - * - * Google for "Extensible SAL specification" for a document describing the - * ESI standard. - */ - -/* - * PSR settings as per SAL spec (Chapter 8 in the "IA-64 System - * Abstraction Layer Specification", revision 2.6e). Note that - * psr.dfl and psr.dfh MUST be cleared, despite what this manual says. - * Otherwise, SAL dies whenever it's trying to do an IA-32 BIOS call - * (the br.ia instruction fails unless psr.dfl and psr.dfh are - * cleared). Fortunately, SAL promises not to touch the floating - * point regs, so at least we don't have to save f2-f127. - */ -#define PSR_BITS_TO_CLEAR \ - (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_RT | \ - IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \ - IA64_PSR_DFL | IA64_PSR_DFH) - -#define PSR_BITS_TO_SET \ - (IA64_PSR_BN) - -#include -#include - -/* - * Inputs: - * in0 = address of function descriptor of ESI routine to call - * in1 = address of array of ESI parameters - * - * Outputs: - * r8 = result returned by called function - */ -GLOBAL_ENTRY(esi_call_phys) - .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2) - alloc loc1=ar.pfs,2,7,8,0 - ld8 r2=[in0],8 // load ESI function's entry point - mov loc0=rp - .body - ;; - ld8 out0=[in1],8 // ESI params loaded from array - ;; // passing all as inputs doesn't work - ld8 out1=[in1],8 - ;; - ld8 out2=[in1],8 - ;; - ld8 out3=[in1],8 - ;; - ld8 out4=[in1],8 - ;; - ld8 out5=[in1],8 - ;; - ld8 out6=[in1],8 - ;; - ld8 out7=[in1] - mov loc2=gp // save global pointer - mov loc4=ar.rsc // save RSE configuration - mov ar.rsc=0 // put RSE in enforced lazy, LE mode - ;; - ld8 gp=[in0] // load ESI function's global pointer - movl r16=PSR_BITS_TO_CLEAR - mov loc3=psr // save processor status word - movl r17=PSR_BITS_TO_SET - ;; - or loc3=loc3,r17 - mov b6=r2 - ;; - andcm r16=loc3,r16 // get psr with IT, DT, and RT bits cleared - br.call.sptk.many rp=ia64_switch_mode_phys -.ret0: mov loc5=r19 // old ar.bsp - mov loc6=r20 // old sp - br.call.sptk.many rp=b6 // call the ESI function -.ret1: mov ar.rsc=0 // put RSE in enforced lazy, LE mode - mov r16=loc3 // save virtual mode psr - mov r19=loc5 // save virtual mode bspstore - mov r20=loc6 // save virtual mode sp - br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode -.ret2: mov ar.rsc=loc4 // restore RSE configuration - mov ar.pfs=loc1 - mov rp=loc0 - mov gp=loc2 - br.ret.sptk.many rp -END(esi_call_phys) diff --git a/trunk/arch/ia64/kernel/ia64_ksyms.c b/trunk/arch/ia64/kernel/ia64_ksyms.c index 879c1817bd1c..3ead20fb6f4b 100644 --- a/trunk/arch/ia64/kernel/ia64_ksyms.c +++ b/trunk/arch/ia64/kernel/ia64_ksyms.c @@ -105,9 +105,5 @@ EXPORT_SYMBOL(ia64_spinlock_contention); # endif #endif -#if defined(CONFIG_IA64_ESI) || defined(CONFIG_IA64_ESI_MODULE) -extern void esi_call_phys (void); -EXPORT_SYMBOL_GPL(esi_call_phys); -#endif extern char ia64_ivt[]; EXPORT_SYMBOL(ia64_ivt); diff --git a/trunk/arch/ia64/kernel/kprobes.c b/trunk/arch/ia64/kernel/kprobes.c index 51217d63285e..781960f80b6f 100644 --- a/trunk/arch/ia64/kernel/kprobes.c +++ b/trunk/arch/ia64/kernel/kprobes.c @@ -90,7 +90,7 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint slot, p->ainsn.target_br_reg = 0; /* Check for Break instruction - * Bits 37:40 Major opcode to be zero + * Bits 37:40 Major opcode to be zero * Bits 27:32 X6 to be zero * Bits 32:35 X3 to be zero */ @@ -104,19 +104,19 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint slot, switch (major_opcode) { case INDIRECT_CALL_OPCODE: p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; - p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); - break; + p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); + break; case IP_RELATIVE_PREDICT_OPCODE: case IP_RELATIVE_BRANCH_OPCODE: p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR; - break; + break; case IP_RELATIVE_CALL_OPCODE: - p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR; - p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; - p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); - break; + p->ainsn.inst_flag |= INST_FLAG_FIX_RELATIVE_IP_ADDR; + p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; + p->ainsn.target_br_reg = ((kprobe_inst >> 6) & 0x7); + break; } - } else if (bundle_encoding[template][slot] == X) { + } else if (bundle_encoding[template][slot] == X) { switch (major_opcode) { case LONG_CALL_OPCODE: p->ainsn.inst_flag |= INST_FLAG_FIX_BRANCH_REG; @@ -136,8 +136,10 @@ static void __kprobes update_kprobe_inst_flag(uint template, uint slot, static int __kprobes unsupported_inst(uint template, uint slot, uint major_opcode, unsigned long kprobe_inst, - unsigned long addr) + struct kprobe *p) { + unsigned long addr = (unsigned long)p->addr; + if (bundle_encoding[template][slot] == I) { switch (major_opcode) { case 0x0: //I_UNIT_MISC_OPCODE: @@ -215,7 +217,7 @@ static void __kprobes prepare_break_inst(uint template, uint slot, struct kprobe *p) { unsigned long break_inst = BREAK_INST; - bundle_t *bundle = &p->opcode.bundle; + bundle_t *bundle = &p->ainsn.insn.bundle; /* * Copy the original kprobe_inst qualifying predicate(qp) @@ -258,18 +260,18 @@ static void __kprobes get_kprobe_inst(bundle_t *bundle, uint slot, switch (slot) { case 0: - *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT); - *kprobe_inst = bundle->quad0.slot0; - break; + *major_opcode = (bundle->quad0.slot0 >> SLOT0_OPCODE_SHIFT); + *kprobe_inst = bundle->quad0.slot0; + break; case 1: - *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT); - kprobe_inst_p0 = bundle->quad0.slot1_p0; - kprobe_inst_p1 = bundle->quad1.slot1_p1; - *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46)); + *major_opcode = (bundle->quad1.slot1_p1 >> SLOT1_p1_OPCODE_SHIFT); + kprobe_inst_p0 = bundle->quad0.slot1_p0; + kprobe_inst_p1 = bundle->quad1.slot1_p1; + *kprobe_inst = kprobe_inst_p0 | (kprobe_inst_p1 << (64-46)); break; case 2: - *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT); - *kprobe_inst = bundle->quad1.slot2; + *major_opcode = (bundle->quad1.slot2 >> SLOT2_OPCODE_SHIFT); + *kprobe_inst = bundle->quad1.slot2; break; } } @@ -290,11 +292,11 @@ static int __kprobes valid_kprobe_addr(int template, int slot, return -EINVAL; } - if (in_ivt_functions(addr)) { - printk(KERN_WARNING "Kprobes can't be inserted inside " + if (in_ivt_functions(addr)) { + printk(KERN_WARNING "Kprobes can't be inserted inside " "IVT functions at 0x%lx\n", addr); - return -EINVAL; - } + return -EINVAL; + } if (slot == 1 && bundle_encoding[template][1] != L) { printk(KERN_WARNING "Inserting kprobes on slot #1 " @@ -338,13 +340,12 @@ static void kretprobe_trampoline(void) int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; + struct hlist_head *head; struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address = ((struct fnptr *)kretprobe_trampoline)->ip; - INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); head = kretprobe_inst_table_head(current); @@ -370,7 +371,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) ri->rp->handler(ri, regs); orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); + recycle_rp_inst(ri); if (orig_ret_address != trampoline_address) /* @@ -388,10 +389,6 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); preempt_enable_no_resched(); - hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } /* * By returning a non-zero value, we are telling * kprobe_handler() that we don't want the post_handler @@ -426,45 +423,47 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) unsigned long *kprobe_addr = (unsigned long *)(addr & ~0xFULL); unsigned long kprobe_inst=0; unsigned int slot = addr & 0xf, template, major_opcode = 0; - bundle_t *bundle; + bundle_t *bundle = &p->ainsn.insn.bundle; - bundle = &((kprobe_opcode_t *)kprobe_addr)->bundle; - template = bundle->quad0.template; + memcpy(&p->opcode.bundle, kprobe_addr, sizeof(bundle_t)); + memcpy(&p->ainsn.insn.bundle, kprobe_addr, sizeof(bundle_t)); + + template = bundle->quad0.template; if(valid_kprobe_addr(template, slot, addr)) return -EINVAL; /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */ - if (slot == 1 && bundle_encoding[template][1] == L) - slot++; + if (slot == 1 && bundle_encoding[template][1] == L) + slot++; /* Get kprobe_inst and major_opcode from the bundle */ get_kprobe_inst(bundle, slot, &kprobe_inst, &major_opcode); - if (unsupported_inst(template, slot, major_opcode, kprobe_inst, addr)) + if (unsupported_inst(template, slot, major_opcode, kprobe_inst, p)) return -EINVAL; - - p->ainsn.insn = get_insn_slot(); - if (!p->ainsn.insn) - return -ENOMEM; - memcpy(&p->opcode, kprobe_addr, sizeof(kprobe_opcode_t)); - memcpy(p->ainsn.insn, kprobe_addr, sizeof(kprobe_opcode_t)); - prepare_break_inst(template, slot, major_opcode, kprobe_inst, p); return 0; } +void __kprobes flush_insn_slot(struct kprobe *p) +{ + unsigned long arm_addr; + + arm_addr = ((unsigned long)&p->opcode.bundle) & ~0xFULL; + flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t)); +} + void __kprobes arch_arm_kprobe(struct kprobe *p) { unsigned long addr = (unsigned long)p->addr; unsigned long arm_addr = addr & ~0xFULL; - flush_icache_range((unsigned long)p->ainsn.insn, - (unsigned long)p->ainsn.insn + sizeof(kprobe_opcode_t)); - memcpy((char *)arm_addr, &p->opcode, sizeof(kprobe_opcode_t)); - flush_icache_range(arm_addr, arm_addr + sizeof(kprobe_opcode_t)); + flush_insn_slot(p); + memcpy((char *)arm_addr, &p->ainsn.insn.bundle, sizeof(bundle_t)); + flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t)); } void __kprobes arch_disarm_kprobe(struct kprobe *p) @@ -472,18 +471,11 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) unsigned long addr = (unsigned long)p->addr; unsigned long arm_addr = addr & ~0xFULL; - /* p->ainsn.insn contains the original unaltered kprobe_opcode_t */ - memcpy((char *) arm_addr, (char *) p->ainsn.insn, - sizeof(kprobe_opcode_t)); - flush_icache_range(arm_addr, arm_addr + sizeof(kprobe_opcode_t)); + /* p->opcode contains the original unaltered bundle */ + memcpy((char *) arm_addr, (char *) &p->opcode.bundle, sizeof(bundle_t)); + flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t)); } -void __kprobes arch_remove_kprobe(struct kprobe *p) -{ - mutex_lock(&kprobe_mutex); - free_insn_slot(p->ainsn.insn); - mutex_unlock(&kprobe_mutex); -} /* * We are resuming execution after a single step fault, so the pt_regs * structure reflects the register state after we executed the instruction @@ -494,22 +486,21 @@ void __kprobes arch_remove_kprobe(struct kprobe *p) */ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) { - unsigned long bundle_addr = (unsigned long) (&p->ainsn.insn->bundle); - unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL; - unsigned long template; - int slot = ((unsigned long)p->addr & 0xf); + unsigned long bundle_addr = ((unsigned long) (&p->opcode.bundle)) & ~0xFULL; + unsigned long resume_addr = (unsigned long)p->addr & ~0xFULL; + unsigned long template; + int slot = ((unsigned long)p->addr & 0xf); - template = p->ainsn.insn->bundle.quad0.template; + template = p->opcode.bundle.quad0.template; - if (slot == 1 && bundle_encoding[template][1] == L) - slot = 2; + if (slot == 1 && bundle_encoding[template][1] == L) + slot = 2; if (p->ainsn.inst_flag) { if (p->ainsn.inst_flag & INST_FLAG_FIX_RELATIVE_IP_ADDR) { /* Fix relative IP address */ - regs->cr_iip = (regs->cr_iip - bundle_addr) + - resume_addr; + regs->cr_iip = (regs->cr_iip - bundle_addr) + resume_addr; } if (p->ainsn.inst_flag & INST_FLAG_FIX_BRANCH_REG) { @@ -546,23 +537,23 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) } if (slot == 2) { - if (regs->cr_iip == bundle_addr + 0x10) { - regs->cr_iip = resume_addr + 0x10; - } - } else { - if (regs->cr_iip == bundle_addr) { - regs->cr_iip = resume_addr; - } + if (regs->cr_iip == bundle_addr + 0x10) { + regs->cr_iip = resume_addr + 0x10; + } + } else { + if (regs->cr_iip == bundle_addr) { + regs->cr_iip = resume_addr; + } } turn_ss_off: - /* Turn off Single Step bit */ - ia64_psr(regs)->ss = 0; + /* Turn off Single Step bit */ + ia64_psr(regs)->ss = 0; } static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs) { - unsigned long bundle_addr = (unsigned long) &p->ainsn.insn->bundle; + unsigned long bundle_addr = (unsigned long) &p->opcode.bundle; unsigned long slot = (unsigned long)p->addr & 0xf; /* single step inline if break instruction */ @@ -593,7 +584,7 @@ static int __kprobes is_ia64_break_inst(struct pt_regs *regs) /* Move to slot 2, if bundle is MLX type and kprobe slot is 1 */ if (slot == 1 && bundle_encoding[template][1] == L) - slot++; + slot++; /* Get Kprobe probe instruction at given slot*/ get_kprobe_inst(&bundle, slot, &kprobe_inst, &major_opcode); @@ -633,7 +624,7 @@ static int __kprobes pre_kprobes_handler(struct die_args *args) if (p) { if ((kcb->kprobe_status == KPROBE_HIT_SS) && (p->ainsn.inst_flag == INST_FLAG_BREAK_INST)) { - ia64_psr(regs)->ss = 0; + ia64_psr(regs)->ss = 0; goto no_kprobe; } /* We have reentered the pre_kprobe_handler(), since @@ -777,12 +768,6 @@ static int __kprobes kprobes_fault_handler(struct pt_regs *regs, int trapnr) */ if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) return 1; - /* - * In case the user-specified fault handler returned - * zero, try to fix up. - */ - if (ia64_done_with_exception(regs)) - return 1; /* * Let ia64_do_page_fault() fix it. @@ -893,7 +878,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) * fix the return address to our jprobe_inst_return() function * in the jprobes.S file */ - regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip; + regs->b0 = ((struct fnptr *)(jprobe_inst_return))->ip; return 1; } diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index 663230183254..2fbe4536fe18 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -54,9 +54,6 @@ * * 2005-10-07 Keith Owens * Add notify_die() hooks. - * - * 2006-09-15 Hidetoshi Seto - * Add printing support for MCA/INIT. */ #include #include @@ -139,175 +136,11 @@ extern void salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe); static int mca_init __initdata; -/* - * limited & delayed printing support for MCA/INIT handler - */ - -#define mprintk(fmt...) ia64_mca_printk(fmt) - -#define MLOGBUF_SIZE (512+256*NR_CPUS) -#define MLOGBUF_MSGMAX 256 -static char mlogbuf[MLOGBUF_SIZE]; -static DEFINE_SPINLOCK(mlogbuf_wlock); /* mca context only */ -static DEFINE_SPINLOCK(mlogbuf_rlock); /* normal context only */ -static unsigned long mlogbuf_start; -static unsigned long mlogbuf_end; -static unsigned int mlogbuf_finished = 0; -static unsigned long mlogbuf_timestamp = 0; - -static int loglevel_save = -1; -#define BREAK_LOGLEVEL(__console_loglevel) \ - oops_in_progress = 1; \ - if (loglevel_save < 0) \ - loglevel_save = __console_loglevel; \ - __console_loglevel = 15; - -#define RESTORE_LOGLEVEL(__console_loglevel) \ - if (loglevel_save >= 0) { \ - __console_loglevel = loglevel_save; \ - loglevel_save = -1; \ - } \ - mlogbuf_finished = 0; \ - oops_in_progress = 0; - -/* - * Push messages into buffer, print them later if not urgent. - */ -void ia64_mca_printk(const char *fmt, ...) -{ - va_list args; - int printed_len; - char temp_buf[MLOGBUF_MSGMAX]; - char *p; - - va_start(args, fmt); - printed_len = vscnprintf(temp_buf, sizeof(temp_buf), fmt, args); - va_end(args); - - /* Copy the output into mlogbuf */ - if (oops_in_progress) { - /* mlogbuf was abandoned, use printk directly instead. */ - printk(temp_buf); - } else { - spin_lock(&mlogbuf_wlock); - for (p = temp_buf; *p; p++) { - unsigned long next = (mlogbuf_end + 1) % MLOGBUF_SIZE; - if (next != mlogbuf_start) { - mlogbuf[mlogbuf_end] = *p; - mlogbuf_end = next; - } else { - /* buffer full */ - break; - } - } - mlogbuf[mlogbuf_end] = '\0'; - spin_unlock(&mlogbuf_wlock); - } -} -EXPORT_SYMBOL(ia64_mca_printk); - -/* - * Print buffered messages. - * NOTE: call this after returning normal context. (ex. from salinfod) - */ -void ia64_mlogbuf_dump(void) -{ - char temp_buf[MLOGBUF_MSGMAX]; - char *p; - unsigned long index; - unsigned long flags; - unsigned int printed_len; - - /* Get output from mlogbuf */ - while (mlogbuf_start != mlogbuf_end) { - temp_buf[0] = '\0'; - p = temp_buf; - printed_len = 0; - - spin_lock_irqsave(&mlogbuf_rlock, flags); - - index = mlogbuf_start; - while (index != mlogbuf_end) { - *p = mlogbuf[index]; - index = (index + 1) % MLOGBUF_SIZE; - if (!*p) - break; - p++; - if (++printed_len >= MLOGBUF_MSGMAX - 1) - break; - } - *p = '\0'; - if (temp_buf[0]) - printk(temp_buf); - mlogbuf_start = index; - - mlogbuf_timestamp = 0; - spin_unlock_irqrestore(&mlogbuf_rlock, flags); - } -} -EXPORT_SYMBOL(ia64_mlogbuf_dump); - -/* - * Call this if system is going to down or if immediate flushing messages to - * console is required. (ex. recovery was failed, crash dump is going to be - * invoked, long-wait rendezvous etc.) - * NOTE: this should be called from monarch. - */ -static void ia64_mlogbuf_finish(int wait) -{ - BREAK_LOGLEVEL(console_loglevel); - - spin_lock_init(&mlogbuf_rlock); - ia64_mlogbuf_dump(); - printk(KERN_EMERG "mlogbuf_finish: printing switched to urgent mode, " - "MCA/INIT might be dodgy or fail.\n"); - - if (!wait) - return; - - /* wait for console */ - printk("Delaying for 5 seconds...\n"); - udelay(5*1000000); - - mlogbuf_finished = 1; -} -EXPORT_SYMBOL(ia64_mlogbuf_finish); - -/* - * Print buffered messages from INIT context. - */ -static void ia64_mlogbuf_dump_from_init(void) -{ - if (mlogbuf_finished) - return; - - if (mlogbuf_timestamp && (mlogbuf_timestamp + 30*HZ > jiffies)) { - printk(KERN_ERR "INIT: mlogbuf_dump is interrupted by INIT " - " and the system seems to be messed up.\n"); - ia64_mlogbuf_finish(0); - return; - } - - if (!spin_trylock(&mlogbuf_rlock)) { - printk(KERN_ERR "INIT: mlogbuf_dump is interrupted by INIT. " - "Generated messages other than stack dump will be " - "buffered to mlogbuf and will be printed later.\n"); - printk(KERN_ERR "INIT: If messages would not printed after " - "this INIT, wait 30sec and assert INIT again.\n"); - if (!mlogbuf_timestamp) - mlogbuf_timestamp = jiffies; - return; - } - spin_unlock(&mlogbuf_rlock); - ia64_mlogbuf_dump(); -} static void inline ia64_mca_spin(const char *func) { - if (monarch_cpu == smp_processor_id()) - ia64_mlogbuf_finish(0); - mprintk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func); + printk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func); while (1) cpu_relax(); } @@ -388,7 +221,7 @@ ia64_log_get(int sal_info_type, u8 **buffer, int irq_safe) { sal_log_record_header_t *log_buffer; u64 total_len = 0; - unsigned long s; + int s; IA64_LOG_LOCK(sal_info_type); @@ -511,6 +344,9 @@ ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs) /* SAL spec states this should run w/ interrupts enabled */ local_irq_enable(); + /* Get the CPE error record and log it */ + ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE); + spin_lock(&cpe_history_lock); if (!cpe_poll_enabled && cpe_vector >= 0) { @@ -539,7 +375,7 @@ ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs) mod_timer(&cpe_poll_timer, jiffies + MIN_CPE_POLL_INTERVAL); /* lock already released, get out now */ - goto out; + return IRQ_HANDLED; } else { cpe_history[index++] = now; if (index == CPE_HISTORY_LENGTH) @@ -547,10 +383,6 @@ ia64_mca_cpe_int_handler (int cpe_irq, void *arg, struct pt_regs *ptregs) } } spin_unlock(&cpe_history_lock); -out: - /* Get the CPE error record and log it */ - ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CPE); - return IRQ_HANDLED; } @@ -1156,22 +988,18 @@ ia64_wait_for_slaves(int monarch, const char *type) } if (!missing) goto all_in; - /* - * Maybe slave(s) dead. Print buffered messages immediately. - */ - ia64_mlogbuf_finish(0); - mprintk(KERN_INFO "OS %s slave did not rendezvous on cpu", type); + printk(KERN_INFO "OS %s slave did not rendezvous on cpu", type); for_each_online_cpu(c) { if (c == monarch) continue; if (ia64_mc_info.imi_rendez_checkin[c] == IA64_MCA_RENDEZ_CHECKIN_NOTDONE) - mprintk(" %d", c); + printk(" %d", c); } - mprintk("\n"); + printk("\n"); return; all_in: - mprintk(KERN_INFO "All OS %s slaves have reached rendezvous\n", type); + printk(KERN_INFO "All OS %s slaves have reached rendezvous\n", type); return; } @@ -1199,8 +1027,10 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, struct ia64_mca_notify_die nd = { .sos = sos, .monarch_cpu = &monarch_cpu }; - mprintk(KERN_INFO "Entered OS MCA handler. PSP=%lx cpu=%d " - "monarch=%ld\n", sos->proc_state_param, cpu, sos->monarch); + oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ + console_loglevel = 15; /* make sure printks make it to console */ + printk(KERN_INFO "Entered OS MCA handler. PSP=%lx cpu=%d monarch=%ld\n", + sos->proc_state_param, cpu, sos->monarch); previous_current = ia64_mca_modify_original_stack(regs, sw, sos, "MCA"); monarch_cpu = cpu; @@ -1236,9 +1066,6 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw, rh->severity = sal_log_severity_corrected; ia64_sal_clear_state_info(SAL_INFO_TYPE_MCA); sos->os_status = IA64_MCA_CORRECTED; - } else { - /* Dump buffered message to console */ - ia64_mlogbuf_finish(1); } if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover) == NOTIFY_STOP) @@ -1279,6 +1106,9 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs) /* SAL spec states this should run w/ interrupts enabled */ local_irq_enable(); + /* Get the CMC error record and log it */ + ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC); + spin_lock(&cmc_history_lock); if (!cmc_polling_enabled) { int i, count = 1; /* we know 1 happened now */ @@ -1311,7 +1141,7 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs) mod_timer(&cmc_poll_timer, jiffies + CMC_POLL_INTERVAL); /* lock already released, get out now */ - goto out; + return IRQ_HANDLED; } else { cmc_history[index++] = now; if (index == CMC_HISTORY_LENGTH) @@ -1319,10 +1149,6 @@ ia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs) } } spin_unlock(&cmc_history_lock); -out: - /* Get the CMC error record and log it */ - ia64_mca_log_sal_error_record(SAL_INFO_TYPE_CMC); - return IRQ_HANDLED; } @@ -1479,15 +1305,6 @@ default_monarch_init_process(struct notifier_block *self, unsigned long val, voi struct task_struct *g, *t; if (val != DIE_INIT_MONARCH_PROCESS) return NOTIFY_DONE; - - /* - * FIXME: mlogbuf will brim over with INIT stack dumps. - * To enable show_stack from INIT, we use oops_in_progress which should - * be used in real oops. This would cause something wrong after INIT. - */ - BREAK_LOGLEVEL(console_loglevel); - ia64_mlogbuf_dump_from_init(); - printk(KERN_ERR "Processes interrupted by INIT -"); for_each_online_cpu(c) { struct ia64_sal_os_state *s; @@ -1509,8 +1326,6 @@ default_monarch_init_process(struct notifier_block *self, unsigned long val, voi } while_each_thread (g, t); read_unlock(&tasklist_lock); } - /* FIXME: This will not restore zapped printk locks. */ - RESTORE_LOGLEVEL(console_loglevel); return NOTIFY_DONE; } @@ -1542,9 +1357,12 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, struct ia64_mca_notify_die nd = { .sos = sos, .monarch_cpu = &monarch_cpu }; + oops_in_progress = 1; /* FIXME: make printk NMI/MCA/INIT safe */ + console_loglevel = 15; /* make sure printks make it to console */ + (void) notify_die(DIE_INIT_ENTER, "INIT", regs, (long)&nd, 0, 0); - mprintk(KERN_INFO "Entered OS INIT handler. PSP=%lx cpu=%d monarch=%ld\n", + printk(KERN_INFO "Entered OS INIT handler. PSP=%lx cpu=%d monarch=%ld\n", sos->proc_state_param, cpu, sos->monarch); salinfo_log_wakeup(SAL_INFO_TYPE_INIT, NULL, 0, 0); @@ -1557,7 +1375,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, * fix their proms and get their customers updated. */ if (!sos->monarch && atomic_add_return(1, &slaves) == num_online_cpus()) { - mprintk(KERN_WARNING "%s: Promoting cpu %d to monarch.\n", + printk(KERN_WARNING "%s: Promoting cpu %d to monarch.\n", __FUNCTION__, cpu); atomic_dec(&slaves); sos->monarch = 1; @@ -1569,7 +1387,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, * fix their proms and get their customers updated. */ if (sos->monarch && atomic_add_return(1, &monarchs) > 1) { - mprintk(KERN_WARNING "%s: Demoting cpu %d to slave.\n", + printk(KERN_WARNING "%s: Demoting cpu %d to slave.\n", __FUNCTION__, cpu); atomic_dec(&monarchs); sos->monarch = 0; @@ -1590,7 +1408,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, if (notify_die(DIE_INIT_SLAVE_LEAVE, "INIT", regs, (long)&nd, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); - mprintk("Slave on cpu %d returning to normal service.\n", cpu); + printk("Slave on cpu %d returning to normal service.\n", cpu); set_curr_task(cpu, previous_current); ia64_mc_info.imi_rendez_checkin[cpu] = IA64_MCA_RENDEZ_CHECKIN_NOTDONE; atomic_dec(&slaves); @@ -1608,7 +1426,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, * same serial line, the user will need some time to switch out of the BMC before * the dump begins. */ - mprintk("Delaying for 5 seconds...\n"); + printk("Delaying for 5 seconds...\n"); udelay(5*1000000); ia64_wait_for_slaves(cpu, "INIT"); /* If nobody intercepts DIE_INIT_MONARCH_PROCESS then we drop through @@ -1621,7 +1439,7 @@ ia64_init_handler(struct pt_regs *regs, struct switch_stack *sw, if (notify_die(DIE_INIT_MONARCH_LEAVE, "INIT", regs, (long)&nd, 0, 0) == NOTIFY_STOP) ia64_mca_spin(__FUNCTION__); - mprintk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); + printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); atomic_dec(&monarchs); set_curr_task(cpu, previous_current); monarch_cpu = -1; diff --git a/trunk/arch/ia64/kernel/mca_asm.S b/trunk/arch/ia64/kernel/mca_asm.S index c6b607c00dee..96047491d1b9 100644 --- a/trunk/arch/ia64/kernel/mca_asm.S +++ b/trunk/arch/ia64/kernel/mca_asm.S @@ -1025,13 +1025,18 @@ ia64_old_stack: ia64_set_kernel_registers: add temp3=MCA_SP_OFFSET, r3 + add temp4=MCA_SOS_OFFSET+SOS(OS_GP), r3 mov b0=r2 // save return address GET_IA64_MCA_DATA(temp1) ;; + add temp4=temp4, temp1 // &struct ia64_sal_os_state.os_gp add r12=temp1, temp3 // kernel stack pointer on MCA/INIT stack add r13=temp1, r3 // set current to start of MCA/INIT stack add r20=temp1, r3 // physical start of MCA/INIT stack ;; + ld8 r1=[temp4] // OS GP from SAL OS state + ;; + DATA_PA_TO_VA(r1,temp1) DATA_PA_TO_VA(r12,temp2) DATA_PA_TO_VA(r13,temp3) ;; @@ -1062,10 +1067,6 @@ ia64_set_kernel_registers: mov cr.itir=r18 mov cr.ifa=r13 mov r20=IA64_TR_CURRENT_STACK - - movl r17=FPSR_DEFAULT - ;; - mov.m ar.fpsr=r17 // set ar.fpsr to kernel default value ;; itr.d dtr[r20]=r21 ;; diff --git a/trunk/arch/ia64/kernel/mca_drv.c b/trunk/arch/ia64/kernel/mca_drv.c index a45009d2bc90..8db6e0cedadc 100644 --- a/trunk/arch/ia64/kernel/mca_drv.c +++ b/trunk/arch/ia64/kernel/mca_drv.c @@ -79,30 +79,14 @@ static int fatal_mca(const char *fmt, ...) { va_list args; - char buf[256]; va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); + vprintk(fmt, args); va_end(args); - ia64_mca_printk(KERN_ALERT "MCA: %s\n", buf); return MCA_NOT_RECOVERED; } -static int -mca_recovered(const char *fmt, ...) -{ - va_list args; - char buf[256]; - - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); - va_end(args); - ia64_mca_printk(KERN_INFO "MCA: %s\n", buf); - - return MCA_RECOVERED; -} - /** * mca_page_isolate - isolate a poisoned page in order not to use it later * @paddr: poisoned memory location @@ -156,7 +140,6 @@ mca_page_isolate(unsigned long paddr) void mca_handler_bh(unsigned long paddr, void *iip, unsigned long ipsr) { - ia64_mlogbuf_dump(); printk(KERN_ERR "OS_MCA: process [cpu %d, pid: %d, uid: %d, " "iip: %p, psr: 0x%lx,paddr: 0x%lx](%s) encounters MCA.\n", raw_smp_processor_id(), current->pid, current->uid, @@ -457,7 +440,7 @@ recover_from_read_error(slidx_table_t *slidx, /* Is target address valid? */ if (!pbci->tv) - return fatal_mca("target address not valid"); + return fatal_mca(KERN_ALERT "MCA: target address not valid\n"); /* * cpu read or memory-mapped io read @@ -475,7 +458,7 @@ recover_from_read_error(slidx_table_t *slidx, /* Is minstate valid? */ if (!peidx_bottom(peidx) || !(peidx_bottom(peidx)->valid.minstate)) - return fatal_mca("minstate not valid"); + return fatal_mca(KERN_ALERT "MCA: minstate not valid\n"); psr1 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_ipsr); psr2 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_xpsr); @@ -509,14 +492,13 @@ recover_from_read_error(slidx_table_t *slidx, psr2->bn = 1; psr2->i = 0; - return mca_recovered("user memory corruption. " - "kill affected process - recovered."); + return MCA_RECOVERED; } } - return fatal_mca("kernel context not recovered, iip 0x%lx\n", - pmsa->pmsa_iip); + return fatal_mca(KERN_ALERT "MCA: kernel context not recovered," + " iip 0x%lx\n", pmsa->pmsa_iip); } /** @@ -602,13 +584,13 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, * The machine check is corrected. */ if (psp->cm == 1) - return mca_recovered("machine check is already corrected."); + return MCA_RECOVERED; /* * The error was not contained. Software must be reset. */ if (psp->us || psp->ci == 0) - return fatal_mca("error not contained"); + return fatal_mca(KERN_ALERT "MCA: error not contained\n"); /* * The cache check and bus check bits have four possible states @@ -619,22 +601,22 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, * 1 1 Memory error, attempt recovery */ if (psp->bc == 0 || pbci == NULL) - return fatal_mca("No bus check"); + return fatal_mca(KERN_ALERT "MCA: No bus check\n"); /* * Sorry, we cannot handle so many. */ if (peidx_bus_check_num(peidx) > 1) - return fatal_mca("Too many bus checks"); + return fatal_mca(KERN_ALERT "MCA: Too many bus checks\n"); /* * Well, here is only one bus error. */ if (pbci->ib) - return fatal_mca("Internal Bus error"); + return fatal_mca(KERN_ALERT "MCA: Internal Bus error\n"); if (pbci->cc) - return fatal_mca("Cache-cache error"); + return fatal_mca(KERN_ALERT "MCA: Cache-cache error\n"); if (pbci->eb && pbci->bsi > 0) - return fatal_mca("External bus check fatal status"); + return fatal_mca(KERN_ALERT "MCA: External bus check fatal status\n"); /* * This is a local MCA and estimated as recoverble external bus error. @@ -646,7 +628,7 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, /* * On account of strange SAL error record, we cannot recover. */ - return fatal_mca("Strange SAL record"); + return fatal_mca(KERN_ALERT "MCA: Strange SAL record\n"); } /** @@ -675,10 +657,10 @@ mca_try_to_recover(void *rec, struct ia64_sal_os_state *sos) /* Now, OS can recover when there is one processor error section */ if (n_proc_err > 1) - return fatal_mca("Too Many Errors"); + return fatal_mca(KERN_ALERT "MCA: Too Many Errors\n"); else if (n_proc_err == 0) - /* Weird SAL record ... We can't do anything */ - return fatal_mca("Weird SAL record"); + /* Weird SAL record ... We need not to recover */ + return fatal_mca(KERN_ALERT "MCA: Weird SAL record\n"); /* Make index of processor error section */ mca_make_peidx((sal_log_processor_info_t*) @@ -689,7 +671,7 @@ mca_try_to_recover(void *rec, struct ia64_sal_os_state *sos) /* Check whether MCA is global or not */ if (is_mca_global(&peidx, &pbci, sos)) - return fatal_mca("global MCA"); + return fatal_mca(KERN_ALERT "MCA: global MCA\n"); /* Try to recover a processor error */ return recover_from_processor_error(platform_err, &slidx, &peidx, diff --git a/trunk/arch/ia64/kernel/mca_drv.h b/trunk/arch/ia64/kernel/mca_drv.h index c85e943ba5fd..31a2e52bb16f 100644 --- a/trunk/arch/ia64/kernel/mca_drv.h +++ b/trunk/arch/ia64/kernel/mca_drv.h @@ -118,7 +118,3 @@ struct mca_table_entry { extern const struct mca_table_entry *search_mca_tables (unsigned long addr); extern int mca_recover_range(unsigned long); -extern void ia64_mca_printk(const char * fmt, ...) - __attribute__ ((format (printf, 1, 2))); -extern void ia64_mlogbuf_dump(void); - diff --git a/trunk/arch/ia64/kernel/numa.c b/trunk/arch/ia64/kernel/numa.c index a78b45f5fe2f..20340631179f 100644 --- a/trunk/arch/ia64/kernel/numa.c +++ b/trunk/arch/ia64/kernel/numa.c @@ -28,7 +28,6 @@ u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned; EXPORT_SYMBOL(cpu_to_node_map); cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned; -EXPORT_SYMBOL(node_to_cpu_mask); void __cpuinit map_cpu_to_node(int cpu, int nid) { diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index 281004ff7b00..7bb7696e4ce2 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -63,9 +63,6 @@ #define PFM_INVALID_ACTIVATION (~0UL) -#define PFM_NUM_PMC_REGS 64 /* PMC save area for ctxsw */ -#define PFM_NUM_PMD_REGS 64 /* PMD save area for ctxsw */ - /* * depth of message queue */ @@ -300,17 +297,14 @@ typedef struct pfm_context { unsigned long ctx_reload_pmcs[4]; /* bitmask of force reload PMC on ctxsw in */ unsigned long ctx_used_monitors[4]; /* bitmask of monitor PMC being used */ - unsigned long ctx_pmcs[PFM_NUM_PMC_REGS]; /* saved copies of PMC values */ + unsigned long ctx_pmcs[IA64_NUM_PMC_REGS]; /* saved copies of PMC values */ unsigned int ctx_used_ibrs[1]; /* bitmask of used IBR (speedup ctxsw in) */ unsigned int ctx_used_dbrs[1]; /* bitmask of used DBR (speedup ctxsw in) */ unsigned long ctx_dbrs[IA64_NUM_DBG_REGS]; /* DBR values (cache) when not loaded */ unsigned long ctx_ibrs[IA64_NUM_DBG_REGS]; /* IBR values (cache) when not loaded */ - pfm_counter_t ctx_pmds[PFM_NUM_PMD_REGS]; /* software state for PMDS */ - - unsigned long th_pmcs[PFM_NUM_PMC_REGS]; /* PMC thread save state */ - unsigned long th_pmds[PFM_NUM_PMD_REGS]; /* PMD thread save state */ + pfm_counter_t ctx_pmds[IA64_NUM_PMD_REGS]; /* software state for PMDS */ u64 ctx_saved_psr_up; /* only contains psr.up value */ @@ -874,6 +868,7 @@ static void pfm_mask_monitoring(struct task_struct *task) { pfm_context_t *ctx = PFM_GET_CTX(task); + struct thread_struct *th = &task->thread; unsigned long mask, val, ovfl_mask; int i; @@ -894,7 +889,7 @@ pfm_mask_monitoring(struct task_struct *task) * So in both cases, the live register contains the owner's * state. We can ONLY touch the PMU registers and NOT the PSR. * - * As a consequence to this call, the ctx->th_pmds[] array + * As a consequence to this call, the thread->pmds[] array * contains stale information which must be ignored * when context is reloaded AND monitoring is active (see * pfm_restart). @@ -929,9 +924,9 @@ pfm_mask_monitoring(struct task_struct *task) mask = ctx->ctx_used_monitors[0] >> PMU_FIRST_COUNTER; for(i= PMU_FIRST_COUNTER; mask; i++, mask>>=1) { if ((mask & 0x1) == 0UL) continue; - ia64_set_pmc(i, ctx->th_pmcs[i] & ~0xfUL); - ctx->th_pmcs[i] &= ~0xfUL; - DPRINT_ovfl(("pmc[%d]=0x%lx\n", i, ctx->th_pmcs[i])); + ia64_set_pmc(i, th->pmcs[i] & ~0xfUL); + th->pmcs[i] &= ~0xfUL; + DPRINT_ovfl(("pmc[%d]=0x%lx\n", i, th->pmcs[i])); } /* * make all of this visible @@ -948,6 +943,7 @@ static void pfm_restore_monitoring(struct task_struct *task) { pfm_context_t *ctx = PFM_GET_CTX(task); + struct thread_struct *th = &task->thread; unsigned long mask, ovfl_mask; unsigned long psr, val; int i, is_system; @@ -1013,9 +1009,9 @@ pfm_restore_monitoring(struct task_struct *task) mask = ctx->ctx_used_monitors[0] >> PMU_FIRST_COUNTER; for(i= PMU_FIRST_COUNTER; mask; i++, mask>>=1) { if ((mask & 0x1) == 0UL) continue; - ctx->th_pmcs[i] = ctx->ctx_pmcs[i]; - ia64_set_pmc(i, ctx->th_pmcs[i]); - DPRINT(("[%d] pmc[%d]=0x%lx\n", task->pid, i, ctx->th_pmcs[i])); + th->pmcs[i] = ctx->ctx_pmcs[i]; + ia64_set_pmc(i, th->pmcs[i]); + DPRINT(("[%d] pmc[%d]=0x%lx\n", task->pid, i, th->pmcs[i])); } ia64_srlz_d(); @@ -1074,6 +1070,7 @@ pfm_restore_pmds(unsigned long *pmds, unsigned long mask) static inline void pfm_copy_pmds(struct task_struct *task, pfm_context_t *ctx) { + struct thread_struct *thread = &task->thread; unsigned long ovfl_val = pmu_conf->ovfl_val; unsigned long mask = ctx->ctx_all_pmds[0]; unsigned long val; @@ -1095,11 +1092,11 @@ pfm_copy_pmds(struct task_struct *task, pfm_context_t *ctx) ctx->ctx_pmds[i].val = val & ~ovfl_val; val &= ovfl_val; } - ctx->th_pmds[i] = val; + thread->pmds[i] = val; DPRINT(("pmd[%d]=0x%lx soft_val=0x%lx\n", i, - ctx->th_pmds[i], + thread->pmds[i], ctx->ctx_pmds[i].val)); } } @@ -1110,6 +1107,7 @@ pfm_copy_pmds(struct task_struct *task, pfm_context_t *ctx) static inline void pfm_copy_pmcs(struct task_struct *task, pfm_context_t *ctx) { + struct thread_struct *thread = &task->thread; unsigned long mask = ctx->ctx_all_pmcs[0]; int i; @@ -1117,8 +1115,8 @@ pfm_copy_pmcs(struct task_struct *task, pfm_context_t *ctx) for (i=0; mask; i++, mask>>=1) { /* masking 0 with ovfl_val yields 0 */ - ctx->th_pmcs[i] = ctx->ctx_pmcs[i]; - DPRINT(("pmc[%d]=0x%lx\n", i, ctx->th_pmcs[i])); + thread->pmcs[i] = ctx->ctx_pmcs[i]; + DPRINT(("pmc[%d]=0x%lx\n", i, thread->pmcs[i])); } } @@ -2862,6 +2860,7 @@ pfm_reset_regs(pfm_context_t *ctx, unsigned long *ovfl_regs, int is_long_reset) static int pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) { + struct thread_struct *thread = NULL; struct task_struct *task; pfarg_reg_t *req = (pfarg_reg_t *)arg; unsigned long value, pmc_pm; @@ -2882,6 +2881,7 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) if (state == PFM_CTX_ZOMBIE) return -EINVAL; if (is_loaded) { + thread = &task->thread; /* * In system wide and when the context is loaded, access can only happen * when the caller is running on the CPU being monitored by the session. @@ -3036,7 +3036,7 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) * * The value in ctx_pmcs[] can only be changed in pfm_write_pmcs(). * - * The value in th_pmcs[] may be modified on overflow, i.e., when + * The value in thread->pmcs[] may be modified on overflow, i.e., when * monitoring needs to be stopped. */ if (is_monitor) CTX_USED_MONITOR(ctx, 1UL << cnum); @@ -3050,7 +3050,7 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) /* * write thread state */ - if (is_system == 0) ctx->th_pmcs[cnum] = value; + if (is_system == 0) thread->pmcs[cnum] = value; /* * write hardware register if we can @@ -3102,6 +3102,7 @@ pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) static int pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) { + struct thread_struct *thread = NULL; struct task_struct *task; pfarg_reg_t *req = (pfarg_reg_t *)arg; unsigned long value, hw_value, ovfl_mask; @@ -3125,6 +3126,7 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) * the owner of the local PMU. */ if (likely(is_loaded)) { + thread = &task->thread; /* * In system wide and when the context is loaded, access can only happen * when the caller is running on the CPU being monitored by the session. @@ -3232,7 +3234,7 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) /* * write thread state */ - if (is_system == 0) ctx->th_pmds[cnum] = hw_value; + if (is_system == 0) thread->pmds[cnum] = hw_value; /* * write hardware register if we can @@ -3298,6 +3300,7 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) static int pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) { + struct thread_struct *thread = NULL; struct task_struct *task; unsigned long val = 0UL, lval, ovfl_mask, sval; pfarg_reg_t *req = (pfarg_reg_t *)arg; @@ -3321,6 +3324,7 @@ pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) if (state == PFM_CTX_ZOMBIE) return -EINVAL; if (likely(is_loaded)) { + thread = &task->thread; /* * In system wide and when the context is loaded, access can only happen * when the caller is running on the CPU being monitored by the session. @@ -3382,7 +3386,7 @@ pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) * if context is zombie, then task does not exist anymore. * In this case, we use the full value saved in the context (pfm_flush_regs()). */ - val = is_loaded ? ctx->th_pmds[cnum] : 0UL; + val = is_loaded ? thread->pmds[cnum] : 0UL; } rd_func = pmu_conf->pmd_desc[cnum].read_check; @@ -4351,8 +4355,8 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) pfm_copy_pmds(task, ctx); pfm_copy_pmcs(task, ctx); - pmcs_source = ctx->th_pmcs; - pmds_source = ctx->th_pmds; + pmcs_source = thread->pmcs; + pmds_source = thread->pmds; /* * always the case for system-wide @@ -5861,12 +5865,14 @@ void pfm_save_regs(struct task_struct *task) { pfm_context_t *ctx; + struct thread_struct *t; unsigned long flags; u64 psr; ctx = PFM_GET_CTX(task); if (ctx == NULL) return; + t = &task->thread; /* * we always come here with interrupts ALREADY disabled by @@ -5924,19 +5930,19 @@ pfm_save_regs(struct task_struct *task) * guarantee we will be schedule at that same * CPU again. */ - pfm_save_pmds(ctx->th_pmds, ctx->ctx_used_pmds[0]); + pfm_save_pmds(t->pmds, ctx->ctx_used_pmds[0]); /* * save pmc0 ia64_srlz_d() done in pfm_save_pmds() * we will need it on the restore path to check * for pending overflow. */ - ctx->th_pmcs[0] = ia64_get_pmc(0); + t->pmcs[0] = ia64_get_pmc(0); /* * unfreeze PMU if had pending overflows */ - if (ctx->th_pmcs[0] & ~0x1UL) pfm_unfreeze_pmu(); + if (t->pmcs[0] & ~0x1UL) pfm_unfreeze_pmu(); /* * finally, allow context access. @@ -5981,6 +5987,7 @@ static void pfm_lazy_save_regs (struct task_struct *task) { pfm_context_t *ctx; + struct thread_struct *t; unsigned long flags; { u64 psr = pfm_get_psr(); @@ -5988,6 +5995,7 @@ pfm_lazy_save_regs (struct task_struct *task) } ctx = PFM_GET_CTX(task); + t = &task->thread; /* * we need to mask PMU overflow here to @@ -6012,19 +6020,19 @@ pfm_lazy_save_regs (struct task_struct *task) /* * save all the pmds we use */ - pfm_save_pmds(ctx->th_pmds, ctx->ctx_used_pmds[0]); + pfm_save_pmds(t->pmds, ctx->ctx_used_pmds[0]); /* * save pmc0 ia64_srlz_d() done in pfm_save_pmds() * it is needed to check for pended overflow * on the restore path */ - ctx->th_pmcs[0] = ia64_get_pmc(0); + t->pmcs[0] = ia64_get_pmc(0); /* * unfreeze PMU if had pending overflows */ - if (ctx->th_pmcs[0] & ~0x1UL) pfm_unfreeze_pmu(); + if (t->pmcs[0] & ~0x1UL) pfm_unfreeze_pmu(); /* * now get can unmask PMU interrupts, they will @@ -6043,6 +6051,7 @@ void pfm_load_regs (struct task_struct *task) { pfm_context_t *ctx; + struct thread_struct *t; unsigned long pmc_mask = 0UL, pmd_mask = 0UL; unsigned long flags; u64 psr, psr_up; @@ -6053,10 +6062,11 @@ pfm_load_regs (struct task_struct *task) BUG_ON(GET_PMU_OWNER()); + t = &task->thread; /* * possible on unload */ - if (unlikely((task->thread.flags & IA64_THREAD_PM_VALID) == 0)) return; + if (unlikely((t->flags & IA64_THREAD_PM_VALID) == 0)) return; /* * we always come here with interrupts ALREADY disabled by @@ -6138,21 +6148,21 @@ pfm_load_regs (struct task_struct *task) * * XXX: optimize here */ - if (pmd_mask) pfm_restore_pmds(ctx->th_pmds, pmd_mask); - if (pmc_mask) pfm_restore_pmcs(ctx->th_pmcs, pmc_mask); + if (pmd_mask) pfm_restore_pmds(t->pmds, pmd_mask); + if (pmc_mask) pfm_restore_pmcs(t->pmcs, pmc_mask); /* * check for pending overflow at the time the state * was saved. */ - if (unlikely(PMC0_HAS_OVFL(ctx->th_pmcs[0]))) { + if (unlikely(PMC0_HAS_OVFL(t->pmcs[0]))) { /* * reload pmc0 with the overflow information * On McKinley PMU, this will trigger a PMU interrupt */ - ia64_set_pmc(0, ctx->th_pmcs[0]); + ia64_set_pmc(0, t->pmcs[0]); ia64_srlz_d(); - ctx->th_pmcs[0] = 0UL; + t->pmcs[0] = 0UL; /* * will replay the PMU interrupt @@ -6205,6 +6215,7 @@ pfm_load_regs (struct task_struct *task) void pfm_load_regs (struct task_struct *task) { + struct thread_struct *t; pfm_context_t *ctx; struct task_struct *owner; unsigned long pmd_mask, pmc_mask; @@ -6213,6 +6224,7 @@ pfm_load_regs (struct task_struct *task) owner = GET_PMU_OWNER(); ctx = PFM_GET_CTX(task); + t = &task->thread; psr = pfm_get_psr(); BUG_ON(psr & (IA64_PSR_UP|IA64_PSR_PP)); @@ -6275,22 +6287,22 @@ pfm_load_regs (struct task_struct *task) */ pmc_mask = ctx->ctx_all_pmcs[0]; - pfm_restore_pmds(ctx->th_pmds, pmd_mask); - pfm_restore_pmcs(ctx->th_pmcs, pmc_mask); + pfm_restore_pmds(t->pmds, pmd_mask); + pfm_restore_pmcs(t->pmcs, pmc_mask); /* * check for pending overflow at the time the state * was saved. */ - if (unlikely(PMC0_HAS_OVFL(ctx->th_pmcs[0]))) { + if (unlikely(PMC0_HAS_OVFL(t->pmcs[0]))) { /* * reload pmc0 with the overflow information * On McKinley PMU, this will trigger a PMU interrupt */ - ia64_set_pmc(0, ctx->th_pmcs[0]); + ia64_set_pmc(0, t->pmcs[0]); ia64_srlz_d(); - ctx->th_pmcs[0] = 0UL; + t->pmcs[0] = 0UL; /* * will replay the PMU interrupt @@ -6365,11 +6377,11 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx) */ pfm_unfreeze_pmu(); } else { - pmc0 = ctx->th_pmcs[0]; + pmc0 = task->thread.pmcs[0]; /* * clear whatever overflow status bits there were */ - ctx->th_pmcs[0] = 0; + task->thread.pmcs[0] = 0; } ovfl_val = pmu_conf->ovfl_val; /* @@ -6390,7 +6402,7 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx) /* * can access PMU always true in system wide mode */ - val = pmd_val = can_access_pmu ? ia64_get_pmd(i) : ctx->th_pmds[i]; + val = pmd_val = can_access_pmu ? ia64_get_pmd(i) : task->thread.pmds[i]; if (PMD_IS_COUNTING(i)) { DPRINT(("[%d] pmd[%d] ctx_pmd=0x%lx hw_pmd=0x%lx\n", @@ -6422,7 +6434,7 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx) DPRINT(("[%d] ctx_pmd[%d]=0x%lx pmd_val=0x%lx\n", task->pid, i, val, pmd_val)); - if (is_self) ctx->th_pmds[i] = pmd_val; + if (is_self) task->thread.pmds[i] = pmd_val; ctx->ctx_pmds[i].val = val; } @@ -6666,7 +6678,7 @@ pfm_init(void) ffz(pmu_conf->ovfl_val)); /* sanity check */ - if (pmu_conf->num_pmds >= PFM_NUM_PMD_REGS || pmu_conf->num_pmcs >= PFM_NUM_PMC_REGS) { + if (pmu_conf->num_pmds >= IA64_NUM_PMD_REGS || pmu_conf->num_pmcs >= IA64_NUM_PMC_REGS) { printk(KERN_ERR "perfmon: not enough pmc/pmd, perfmon disabled\n"); pmu_conf = NULL; return -1; @@ -6741,6 +6753,7 @@ void dump_pmu_state(const char *from) { struct task_struct *task; + struct thread_struct *t; struct pt_regs *regs; pfm_context_t *ctx; unsigned long psr, dcr, info, flags; @@ -6785,14 +6798,16 @@ dump_pmu_state(const char *from) ia64_psr(regs)->up = 0; ia64_psr(regs)->pp = 0; + t = ¤t->thread; + for (i=1; PMC_IS_LAST(i) == 0; i++) { if (PMC_IS_IMPL(i) == 0) continue; - printk("->CPU%d pmc[%d]=0x%lx thread_pmc[%d]=0x%lx\n", this_cpu, i, ia64_get_pmc(i), i, ctx->th_pmcs[i]); + printk("->CPU%d pmc[%d]=0x%lx thread_pmc[%d]=0x%lx\n", this_cpu, i, ia64_get_pmc(i), i, t->pmcs[i]); } for (i=1; PMD_IS_LAST(i) == 0; i++) { if (PMD_IS_IMPL(i) == 0) continue; - printk("->CPU%d pmd[%d]=0x%lx thread_pmd[%d]=0x%lx\n", this_cpu, i, ia64_get_pmd(i), i, ctx->th_pmds[i]); + printk("->CPU%d pmd[%d]=0x%lx thread_pmd[%d]=0x%lx\n", this_cpu, i, ia64_get_pmd(i), i, t->pmds[i]); } if (ctx) { diff --git a/trunk/arch/ia64/kernel/process.c b/trunk/arch/ia64/kernel/process.c index 51922b98086a..ea914cc6812a 100644 --- a/trunk/arch/ia64/kernel/process.c +++ b/trunk/arch/ia64/kernel/process.c @@ -8,6 +8,8 @@ * 2005-10-07 Keith Owens * Add notify_die() hooks. */ +#define __KERNEL_SYSCALLS__ /* see */ + #include #include #include diff --git a/trunk/arch/ia64/kernel/salinfo.c b/trunk/arch/ia64/kernel/salinfo.c index e63b8ca5344a..9065f0f01ba3 100644 --- a/trunk/arch/ia64/kernel/salinfo.c +++ b/trunk/arch/ia64/kernel/salinfo.c @@ -266,7 +266,6 @@ salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe) /* Check for outstanding MCA/INIT records every minute (arbitrary) */ #define SALINFO_TIMER_DELAY (60*HZ) static struct timer_list salinfo_timer; -extern void ia64_mlogbuf_dump(void); static void salinfo_timeout_check(struct salinfo_data *data) @@ -284,7 +283,6 @@ salinfo_timeout_check(struct salinfo_data *data) static void salinfo_timeout (unsigned long arg) { - ia64_mlogbuf_dump(); salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_MCA); salinfo_timeout_check(salinfo_data + SAL_INFO_TYPE_INIT); salinfo_timer.expires = jiffies + SALINFO_TIMER_DELAY; @@ -334,8 +332,6 @@ salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t if (cpu == -1) goto retry; - ia64_mlogbuf_dump(); - /* for next read, start checking at next CPU */ data->cpu_check = cpu; if (++data->cpu_check == NR_CPUS) diff --git a/trunk/arch/ia64/kernel/setup.c b/trunk/arch/ia64/kernel/setup.c index 84f93c0f2c66..7ad0d9cc6db6 100644 --- a/trunk/arch/ia64/kernel/setup.c +++ b/trunk/arch/ia64/kernel/setup.c @@ -509,7 +509,7 @@ show_cpuinfo (struct seq_file *m, void *v) { 1UL << 1, "spontaneous deferral"}, { 1UL << 2, "16-byte atomic ops" } }; - char features[128], *cp, sep; + char family[32], features[128], *cp, sep; struct cpuinfo_ia64 *c = v; unsigned long mask; unsigned long proc_freq; @@ -517,6 +517,12 @@ show_cpuinfo (struct seq_file *m, void *v) mask = c->features; + switch (c->family) { + case 0x07: memcpy(family, "Itanium", 8); break; + case 0x1f: memcpy(family, "Itanium 2", 10); break; + default: sprintf(family, "%u", c->family); break; + } + /* build the feature string: */ memcpy(features, " standard", 10); cp = features; @@ -547,9 +553,8 @@ show_cpuinfo (struct seq_file *m, void *v) "processor : %d\n" "vendor : %s\n" "arch : IA-64\n" - "family : %u\n" + "family : %s\n" "model : %u\n" - "model name : %s\n" "revision : %u\n" "archrev : %u\n" "features :%s\n" /* don't change this---it _is_ right! */ @@ -558,8 +563,7 @@ show_cpuinfo (struct seq_file *m, void *v) "cpu MHz : %lu.%06lu\n" "itc MHz : %lu.%06lu\n" "BogoMIPS : %lu.%02lu\n", - cpunum, c->vendor, c->family, c->model, - c->model_name, c->revision, c->archrev, + cpunum, c->vendor, family, c->model, c->revision, c->archrev, features, c->ppn, c->number, proc_freq / 1000, proc_freq % 1000, c->itc_freq / 1000000, c->itc_freq % 1000000, @@ -607,31 +611,6 @@ struct seq_operations cpuinfo_op = { .show = show_cpuinfo }; -static char brandname[128]; - -static char * __cpuinit -get_model_name(__u8 family, __u8 model) -{ - char brand[128]; - - if (ia64_pal_get_brand_info(brand)) { - if (family == 0x7) - memcpy(brand, "Merced", 7); - else if (family == 0x1f) switch (model) { - case 0: memcpy(brand, "McKinley", 9); break; - case 1: memcpy(brand, "Madison", 8); break; - case 2: memcpy(brand, "Madison up to 9M cache", 23); break; - } else - memcpy(brand, "Unknown", 8); - } - if (brandname[0] == '\0') - return strcpy(brandname, brand); - else if (strcmp(brandname, brand) == 0) - return brandname; - else - return kstrdup(brand, GFP_KERNEL); -} - static void __cpuinit identify_cpu (struct cpuinfo_ia64 *c) { @@ -661,6 +640,7 @@ identify_cpu (struct cpuinfo_ia64 *c) pal_status_t status; unsigned long impl_va_msb = 50, phys_addr_size = 44; /* Itanium defaults */ int i; + for (i = 0; i < 5; ++i) cpuid.bits[i] = ia64_get_cpuid(i); @@ -683,7 +663,6 @@ identify_cpu (struct cpuinfo_ia64 *c) c->family = cpuid.field.family; c->archrev = cpuid.field.archrev; c->features = cpuid.field.features; - c->model_name = get_model_name(c->family, c->model); status = ia64_pal_vm_summary(&vm1, &vm2); if (status == PAL_STATUS_SUCCESS) { diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index f7d7f5668144..6203ed4ec8cf 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -879,27 +879,3 @@ identify_siblings(struct cpuinfo_ia64 *c) c->core_id = info.log1_cid; c->thread_id = info.log1_tid; } - -/* - * returns non zero, if multi-threading is enabled - * on at least one physical package. Due to hotplug cpu - * and (maxcpus=), all threads may not necessarily be enabled - * even though the processor supports multi-threading. - */ -int is_multithreading_enabled(void) -{ - int i, j; - - for_each_present_cpu(i) { - for_each_present_cpu(j) { - if (j == i) - continue; - if ((cpu_data(j)->socket_id == cpu_data(i)->socket_id)) { - if (cpu_data(j)->core_id == cpu_data(i)->core_id) - return 1; - } - } - } - return 0; -} -EXPORT_SYMBOL_GPL(is_multithreading_enabled); diff --git a/trunk/arch/ia64/kernel/time.c b/trunk/arch/ia64/kernel/time.c index 62e07f906e05..6928ef0d64d8 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -29,6 +29,8 @@ #include #include +extern unsigned long wall_jiffies; + volatile int time_keeper_id = 0; /* smp_processor_id() of time-keeper */ #ifdef CONFIG_IA64_DEBUG_IRQ @@ -76,7 +78,7 @@ timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) * xtime_lock. */ write_seqlock(&xtime_lock); - do_timer(1); + do_timer(regs); local_cpu_data->itm_next = new_itm; write_sequnlock(&xtime_lock); } else diff --git a/trunk/arch/ia64/kernel/topology.c b/trunk/arch/ia64/kernel/topology.c index 5629b45e89c6..05bdf7affb43 100644 --- a/trunk/arch/ia64/kernel/topology.c +++ b/trunk/arch/ia64/kernel/topology.c @@ -36,7 +36,9 @@ int arch_register_cpu(int num) */ if (!can_cpei_retarget() && is_cpu_cpei_target(num)) sysfs_cpus[num].cpu.no_control = 1; +#ifdef CONFIG_NUMA map_cpu_to_node(num, node_cpuid[num].nid); +#endif #endif return register_cpu(&sysfs_cpus[num].cpu, num); diff --git a/trunk/arch/ia64/kernel/vmlinux.lds.S b/trunk/arch/ia64/kernel/vmlinux.lds.S index b3b2e389d6b2..5b0d5f64a9b1 100644 --- a/trunk/arch/ia64/kernel/vmlinux.lds.S +++ b/trunk/arch/ia64/kernel/vmlinux.lds.S @@ -184,9 +184,7 @@ SECTIONS *(.data.gate) __stop_gate_section = .; } - . = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose - * kernel data - */ + . = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose kernel data */ .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) } @@ -204,9 +202,7 @@ SECTIONS *(.data.percpu) __per_cpu_end = .; } - . = __phys_per_cpu_start + PERCPU_PAGE_SIZE; /* ensure percpu data fits - * into percpu page size - */ + . = __phys_per_cpu_start + PERCPU_PAGE_SIZE; /* ensure percpu data fits into percpu page size */ data : { } :data .data : AT(ADDR(.data) - LOAD_OFFSET) diff --git a/trunk/arch/ia64/mm/contig.c b/trunk/arch/ia64/mm/contig.c index daf977ff2920..e004143ba86b 100644 --- a/trunk/arch/ia64/mm/contig.c +++ b/trunk/arch/ia64/mm/contig.c @@ -26,6 +26,7 @@ #include #ifdef CONFIG_VIRTUAL_MEM_MAP +static unsigned long num_dma_physpages; static unsigned long max_gap; #endif @@ -40,11 +41,10 @@ show_mem (void) int i, total = 0, reserved = 0; int shared = 0, cached = 0; - printk(KERN_INFO "Mem-info:\n"); + printk("Mem-info:\n"); show_free_areas(); - printk(KERN_INFO "Free swap: %6ldkB\n", - nr_swap_pages<<(PAGE_SHIFT-10)); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); i = max_mapnr; for (i = 0; i < max_mapnr; i++) { if (!pfn_valid(i)) { @@ -63,12 +63,12 @@ show_mem (void) else if (page_count(mem_map + i)) shared += page_count(mem_map + i) - 1; } - printk(KERN_INFO "%d pages of RAM\n", total); - printk(KERN_INFO "%d reserved pages\n", reserved); - printk(KERN_INFO "%d pages shared\n", shared); - printk(KERN_INFO "%d pages swap cached\n", cached); - printk(KERN_INFO "%ld pages in page table cache\n", - pgtable_quicklist_total_size()); + printk("%d pages of RAM\n", total); + printk("%d reserved pages\n", reserved); + printk("%d pages shared\n", shared); + printk("%d pages swap cached\n", cached); + printk("%ld pages in page table cache\n", + pgtable_quicklist_total_size()); } /* physical address where the bootmem map is located */ @@ -218,6 +218,18 @@ count_pages (u64 start, u64 end, void *arg) return 0; } +#ifdef CONFIG_VIRTUAL_MEM_MAP +static int +count_dma_pages (u64 start, u64 end, void *arg) +{ + unsigned long *count = arg; + + if (start < MAX_DMA_ADDRESS) + *count += (min(end, MAX_DMA_ADDRESS) - start) >> PAGE_SHIFT; + return 0; +} +#endif + /* * Set up the page tables. */ @@ -226,22 +238,45 @@ void __init paging_init (void) { unsigned long max_dma; - unsigned long nid = 0; - unsigned long max_zone_pfns[MAX_NR_ZONES]; + unsigned long zones_size[MAX_NR_ZONES]; +#ifdef CONFIG_VIRTUAL_MEM_MAP + unsigned long zholes_size[MAX_NR_ZONES]; +#endif + + /* initialize mem_map[] */ + + memset(zones_size, 0, sizeof(zones_size)); num_physpages = 0; efi_memmap_walk(count_pages, &num_physpages); max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; - max_zone_pfns[ZONE_DMA] = max_dma; - max_zone_pfns[ZONE_NORMAL] = max_low_pfn; #ifdef CONFIG_VIRTUAL_MEM_MAP - efi_memmap_walk(register_active_ranges, &nid); + memset(zholes_size, 0, sizeof(zholes_size)); + + num_dma_physpages = 0; + efi_memmap_walk(count_dma_pages, &num_dma_physpages); + + if (max_low_pfn < max_dma) { + zones_size[ZONE_DMA] = max_low_pfn; + zholes_size[ZONE_DMA] = max_low_pfn - num_dma_physpages; + } else { + zones_size[ZONE_DMA] = max_dma; + zholes_size[ZONE_DMA] = max_dma - num_dma_physpages; + if (num_physpages > num_dma_physpages) { + zones_size[ZONE_NORMAL] = max_low_pfn - max_dma; + zholes_size[ZONE_NORMAL] = + ((max_low_pfn - max_dma) - + (num_physpages - num_dma_physpages)); + } + } + efi_memmap_walk(find_largest_hole, (u64 *)&max_gap); if (max_gap < LARGE_GAP) { vmem_map = (struct page *) 0; - free_area_init_nodes(max_zone_pfns); + free_area_init_node(0, NODE_DATA(0), zones_size, 0, + zholes_size); } else { unsigned long map_size; @@ -253,19 +288,20 @@ paging_init (void) vmem_map = (struct page *) vmalloc_end; efi_memmap_walk(create_mem_map_page_table, NULL); - /* - * alloc_node_mem_map makes an adjustment for mem_map - * which isn't compatible with vmem_map. - */ - NODE_DATA(0)->node_mem_map = vmem_map + - find_min_pfn_with_active_regions(); - free_area_init_nodes(max_zone_pfns); + NODE_DATA(0)->node_mem_map = vmem_map; + free_area_init_node(0, NODE_DATA(0), zones_size, + 0, zholes_size); printk("Virtual mem_map starts at 0x%p\n", mem_map); } #else /* !CONFIG_VIRTUAL_MEM_MAP */ - add_active_range(0, 0, max_low_pfn); - free_area_init_nodes(max_zone_pfns); + if (max_low_pfn < max_dma) + zones_size[ZONE_DMA] = max_low_pfn; + else { + zones_size[ZONE_DMA] = max_dma; + zones_size[ZONE_NORMAL] = max_low_pfn - max_dma; + } + free_area_init(zones_size); #endif /* !CONFIG_VIRTUAL_MEM_MAP */ zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); } diff --git a/trunk/arch/ia64/mm/discontig.c b/trunk/arch/ia64/mm/discontig.c index d497b6b0f5b2..d260bffa01ab 100644 --- a/trunk/arch/ia64/mm/discontig.c +++ b/trunk/arch/ia64/mm/discontig.c @@ -547,16 +547,15 @@ void show_mem(void) unsigned long total_present = 0; pg_data_t *pgdat; - printk(KERN_INFO "Mem-info:\n"); + printk("Mem-info:\n"); show_free_areas(); - printk(KERN_INFO "Free swap: %6ldkB\n", - nr_swap_pages<<(PAGE_SHIFT-10)); - printk(KERN_INFO "Node memory in pages:\n"); + printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); for_each_online_pgdat(pgdat) { unsigned long present; unsigned long flags; int shared = 0, cached = 0, reserved = 0; + printk("Node ID: %d\n", pgdat->node_id); pgdat_resize_lock(pgdat, &flags); present = pgdat->node_present_pages; for(i = 0; i < pgdat->node_spanned_pages; i++) { @@ -580,17 +579,18 @@ void show_mem(void) total_reserved += reserved; total_cached += cached; total_shared += shared; - printk(KERN_INFO "Node %4d: RAM: %11ld, rsvd: %8d, " - "shrd: %10d, swpd: %10d\n", pgdat->node_id, - present, reserved, shared, cached); + printk("\t%ld pages of RAM\n", present); + printk("\t%d reserved pages\n", reserved); + printk("\t%d pages shared\n", shared); + printk("\t%d pages swap cached\n", cached); } - printk(KERN_INFO "%ld pages of RAM\n", total_present); - printk(KERN_INFO "%d reserved pages\n", total_reserved); - printk(KERN_INFO "%d pages shared\n", total_shared); - printk(KERN_INFO "%d pages swap cached\n", total_cached); - printk(KERN_INFO "Total of %ld pages in page table cache\n", - pgtable_quicklist_total_size()); - printk(KERN_INFO "%d free buffer pages\n", nr_free_buffer_pages()); + printk("%ld pages of RAM\n", total_present); + printk("%d reserved pages\n", total_reserved); + printk("%d pages shared\n", total_shared); + printk("%d pages swap cached\n", total_cached); + printk("Total of %ld pages in page table cache\n", + pgtable_quicklist_total_size()); + printk("%d free buffer pages\n", nr_free_buffer_pages()); } /** @@ -654,7 +654,6 @@ static __init int count_node_pages(unsigned long start, unsigned long len, int n { unsigned long end = start + len; - add_active_range(node, start >> PAGE_SHIFT, end >> PAGE_SHIFT); mem_data[node].num_physpages += len >> PAGE_SHIFT; if (start <= __pa(MAX_DMA_ADDRESS)) mem_data[node].num_dma_physpages += @@ -679,10 +678,10 @@ static __init int count_node_pages(unsigned long start, unsigned long len, int n void __init paging_init(void) { unsigned long max_dma; + unsigned long zones_size[MAX_NR_ZONES]; + unsigned long zholes_size[MAX_NR_ZONES]; unsigned long pfn_offset = 0; - unsigned long max_pfn = 0; int node; - unsigned long max_zone_pfns[MAX_NR_ZONES]; max_dma = virt_to_phys((void *) MAX_DMA_ADDRESS) >> PAGE_SHIFT; @@ -699,20 +698,47 @@ void __init paging_init(void) #endif for_each_online_node(node) { + memset(zones_size, 0, sizeof(zones_size)); + memset(zholes_size, 0, sizeof(zholes_size)); + num_physpages += mem_data[node].num_physpages; + + if (mem_data[node].min_pfn >= max_dma) { + /* All of this node's memory is above ZONE_DMA */ + zones_size[ZONE_NORMAL] = mem_data[node].max_pfn - + mem_data[node].min_pfn; + zholes_size[ZONE_NORMAL] = mem_data[node].max_pfn - + mem_data[node].min_pfn - + mem_data[node].num_physpages; + } else if (mem_data[node].max_pfn < max_dma) { + /* All of this node's memory is in ZONE_DMA */ + zones_size[ZONE_DMA] = mem_data[node].max_pfn - + mem_data[node].min_pfn; + zholes_size[ZONE_DMA] = mem_data[node].max_pfn - + mem_data[node].min_pfn - + mem_data[node].num_dma_physpages; + } else { + /* This node has memory in both zones */ + zones_size[ZONE_DMA] = max_dma - + mem_data[node].min_pfn; + zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] - + mem_data[node].num_dma_physpages; + zones_size[ZONE_NORMAL] = mem_data[node].max_pfn - + max_dma; + zholes_size[ZONE_NORMAL] = zones_size[ZONE_NORMAL] - + (mem_data[node].num_physpages - + mem_data[node].num_dma_physpages); + } + pfn_offset = mem_data[node].min_pfn; #ifdef CONFIG_VIRTUAL_MEM_MAP NODE_DATA(node)->node_mem_map = vmem_map + pfn_offset; #endif - if (mem_data[node].max_pfn > max_pfn) - max_pfn = mem_data[node].max_pfn; + free_area_init_node(node, NODE_DATA(node), zones_size, + pfn_offset, zholes_size); } - max_zone_pfns[ZONE_DMA] = max_dma; - max_zone_pfns[ZONE_NORMAL] = max_pfn; - free_area_init_nodes(max_zone_pfns); - zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); } diff --git a/trunk/arch/ia64/mm/fault.c b/trunk/arch/ia64/mm/fault.c index 59f3ab937615..14ef7cceb208 100644 --- a/trunk/arch/ia64/mm/fault.c +++ b/trunk/arch/ia64/mm/fault.c @@ -146,11 +146,9 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re # error File is out of sync with . Please update. # endif - if (((isr >> IA64_ISR_R_BIT) & 1UL) && (!(vma->vm_flags & (VM_READ | VM_WRITE)))) - goto bad_area; - mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT) - | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)); + | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT) + | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT)); if ((vma->vm_flags & mask) != mask) goto bad_area; @@ -280,7 +278,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re out_of_memory: up_read(&mm->mmap_sem); - if (is_init(current)) { + if (current->pid == 1) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c index ff87a5cba399..30617ccb4f7e 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -593,18 +593,6 @@ find_largest_hole (u64 start, u64 end, void *arg) last_end = end; return 0; } - -int __init -register_active_ranges(u64 start, u64 end, void *nid) -{ - BUG_ON(nid == NULL); - BUG_ON(*(unsigned long *)nid >= MAX_NUMNODES); - - add_active_range(*(unsigned long *)nid, - __pa(start) >> PAGE_SHIFT, - __pa(end) >> PAGE_SHIFT); - return 0; -} #endif /* CONFIG_VIRTUAL_MEM_MAP */ static int __init diff --git a/trunk/arch/ia64/mm/numa.c b/trunk/arch/ia64/mm/numa.c index 7807fc5c0422..64e4c21f311c 100644 --- a/trunk/arch/ia64/mm/numa.c +++ b/trunk/arch/ia64/mm/numa.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -70,21 +69,4 @@ int early_pfn_to_nid(unsigned long pfn) return 0; } - -#ifdef CONFIG_MEMORY_HOTPLUG -/* - * SRAT information is stored in node_memblk[], then we can use SRAT - * information at memory-hot-add if necessary. - */ - -int memory_add_physaddr_to_nid(u64 addr) -{ - int nid = paddr_to_nid(addr); - if (nid < 0) - return 0; - return nid; -} - -EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); -#endif #endif diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c index 15c7c670da39..60b45e79f080 100644 --- a/trunk/arch/ia64/pci/pci.c +++ b/trunk/arch/ia64/pci/pci.c @@ -562,8 +562,7 @@ pcibios_enable_device (struct pci_dev *dev, int mask) void pcibios_disable_device (struct pci_dev *dev) { - if (dev->is_enabled) - acpi_pci_irq_disable(dev); + acpi_pci_irq_disable(dev); } void diff --git a/trunk/arch/ia64/sn/kernel/bte.c b/trunk/arch/ia64/sn/kernel/bte.c index 7f73ad4408aa..27dee4584061 100644 --- a/trunk/arch/ia64/sn/kernel/bte.c +++ b/trunk/arch/ia64/sn/kernel/bte.c @@ -277,7 +277,8 @@ bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode) } /* temporary buffer used during unaligned transfers */ - bteBlock_unaligned = kmalloc(len + 3 * L1_CACHE_BYTES, GFP_KERNEL); + bteBlock_unaligned = kmalloc(len + 3 * L1_CACHE_BYTES, + GFP_KERNEL | GFP_DMA); if (bteBlock_unaligned == NULL) { return BTEFAIL_NOTAVAIL; } diff --git a/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 462ea178f49a..b632b9c1e3b3 100644 --- a/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/trunk/arch/ia64/sn/kernel/sn2/sn_hwperf.c @@ -423,7 +423,7 @@ static int sn_topology_show(struct seq_file *s, void *d) "coherency_domain %d, " "region_size %d\n", - partid, utsname()->nodename, + partid, system_utsname.nodename, shubtype ? "shub2" : "shub1", (u64)nasid_mask << nasid_shift, nasid_msb, nasid_shift, system_size, sharing_size, coher, region_size); diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c index 5eb1e1e078b4..1f0253bfe0a0 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c @@ -160,7 +160,7 @@ void pcibr_ate_free(struct pcibus_info *pcibus_info, int index) volatile u64 ate; int count; - unsigned long flags; + u64 flags; if (pcibr_invalidate_ate) { /* For debugging purposes, clear the valid bit in the ATE */ diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c index 1ee977fb6ebb..a86c7b945962 100644 --- a/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c +++ b/trunk/arch/ia64/sn/pci/pcibr/pcibr_dma.c @@ -237,7 +237,7 @@ void sn_dma_flush(u64 addr) int is_tio; int wid_num; int i, j; - unsigned long flags; + u64 flags; u64 itte; struct hubdev_info *hubinfo; struct sn_flush_device_kernel *p; diff --git a/trunk/arch/m32r/kernel/sys_m32r.c b/trunk/arch/m32r/kernel/sys_m32r.c index b567351f3c52..a9cea32eb824 100644 --- a/trunk/arch/m32r/kernel/sys_m32r.c +++ b/trunk/arch/m32r/kernel/sys_m32r.c @@ -25,8 +25,6 @@ #include #include #include -#include -#include /* * sys_tas() - test-and-set @@ -207,7 +205,7 @@ asmlinkage int sys_uname(struct old_utsname * name) if (!name) return -EFAULT; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err=copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } @@ -225,21 +223,3 @@ asmlinkage int sys_cachectl(char *addr, int nbytes, int op) return -ENOSYS; } -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register long __scno __asm__ ("r7") = __NR_execve; - register long __arg3 __asm__ ("r2") = (long)(envp); - register long __arg2 __asm__ ("r1") = (long)(argv); - register long __res __asm__ ("r0") = (long)(filename); - __asm__ __volatile__ ( - "trap #" SYSCALL_VECTOR "|| nop" - : "=r" (__res) - : "r" (__scno), "0" (__res), "r" (__arg2), - "r" (__arg3) - : "memory"); - return __res; -} diff --git a/trunk/arch/m32r/kernel/time.c b/trunk/arch/m32r/kernel/time.c index d8af155db984..ded0be07a476 100644 --- a/trunk/arch/m32r/kernel/time.c +++ b/trunk/arch/m32r/kernel/time.c @@ -38,6 +38,7 @@ extern void send_IPI_allbutself(int, int); extern void smp_local_timer_interrupt(struct pt_regs *); #endif +extern unsigned long wall_jiffies; #define TICK_SIZE (tick_nsec / 1000) /* @@ -107,17 +108,24 @@ void do_gettimeofday(struct timeval *tv) unsigned long max_ntp_tick = tick_usec - tickadj; do { + unsigned long lost; + seq = read_seqbegin(&xtime_lock); usec = do_gettimeoffset(); + lost = jiffies - wall_jiffies; /* * If time_adjust is negative then NTP is slowing the clock * so make sure not to go into next possible interval. * Better to lose some accuracy than have time go backwards.. */ - if (unlikely(time_adjust < 0)) + if (unlikely(time_adjust < 0)) { usec = min(usec, max_ntp_tick); + if (lost) + usec += lost * max_ntp_tick; + } else if (unlikely(lost)) + usec += lost * tick_usec; sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); @@ -150,6 +158,7 @@ int do_settimeofday(struct timespec *tv) * made, and then undo it! */ nsec -= do_gettimeoffset() * NSEC_PER_USEC; + nsec -= (jiffies - wall_jiffies) * TICK_NSEC; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -193,7 +202,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) #ifndef CONFIG_SMP profile_tick(CPU_PROFILING, regs); #endif - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); diff --git a/trunk/arch/m32r/mm/fault.c b/trunk/arch/m32r/mm/fault.c index 8d5f551b5754..dc18a33eefef 100644 --- a/trunk/arch/m32r/mm/fault.c +++ b/trunk/arch/m32r/mm/fault.c @@ -299,7 +299,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_init(tsk)) { + if (tsk->pid == 1) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/m32r/mm/ioremap.c b/trunk/arch/m32r/mm/ioremap.c index 5152c4e6ac80..a151849a605e 100644 --- a/trunk/arch/m32r/mm/ioremap.c +++ b/trunk/arch/m32r/mm/ioremap.c @@ -20,8 +20,92 @@ #include #include -#include +#include #include +#include +#include + +static inline void +remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + unsigned long pfn; + pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | _PAGE_READ + | _PAGE_WRITE | flags); + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + pfn = phys_addr >> PAGE_SHIFT; + do { + if (!pte_none(*pte)) { + printk("remap_area_pte: page already exists\n"); + BUG(); + } + set_pte(pte, pfn_pte(pfn, pgprot)); + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); +} + +static inline int +remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pte_t * pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, address + phys_addr, flags); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +static int +remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags) +{ + int error; + pgd_t * dir; + unsigned long end = address + size; + + phys_addr -= address; + dir = pgd_offset(&init_mm, address); + flush_cache_all(); + if (address >= end) + BUG(); + do { + pmd_t *pmd; + pmd = pmd_alloc(&init_mm, dir, address); + error = -ENOMEM; + if (!pmd) + break; + if (remap_area_pmd(pmd, address, end - address, + phys_addr + address, flags)) + break; + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + dir++; + } while (address && (address < end)); + flush_tlb_all(); + return error; +} /* * Generic mapping function (not visible outside): @@ -45,7 +129,6 @@ __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) void __iomem * addr; struct vm_struct * area; unsigned long offset, last_addr; - pgprot_t pgprot; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -74,9 +157,6 @@ __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) return NULL; } - pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | _PAGE_READ - | _PAGE_WRITE | flags); - /* * Mappings have to be page-aligned */ @@ -92,8 +172,7 @@ __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) return NULL; area->phys_addr = phys_addr; addr = (void __iomem *) area->addr; - if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, - phys_addr, pgprot)) { + if (remap_area_pages((unsigned long)addr, phys_addr, size, flags)) { vunmap((void __force *) addr); return NULL; } diff --git a/trunk/arch/m68k/kernel/sys_m68k.c b/trunk/arch/m68k/kernel/sys_m68k.c index 90238a8c9e14..143c552d38f3 100644 --- a/trunk/arch/m68k/kernel/sys_m68k.c +++ b/trunk/arch/m68k/kernel/sys_m68k.c @@ -27,7 +27,6 @@ #include #include #include -#include /* * sys_pipe() is the normal C calling standard for creating @@ -664,18 +663,3 @@ asmlinkage int sys_getpagesize(void) { return PAGE_SIZE; } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register long __res asm ("%d0") = __NR_execve; - register long __a asm ("%d1") = (long)(filename); - register long __b asm ("%d2") = (long)(argv); - register long __c asm ("%d3") = (long)(envp); - asm volatile ("trap #0" : "+d" (__res) - : "d" (__a), "d" (__b), "d" (__c)); - return __res; -} diff --git a/trunk/arch/m68k/kernel/time.c b/trunk/arch/m68k/kernel/time.c index 6cfc984380d9..98e4b1adfa29 100644 --- a/trunk/arch/m68k/kernel/time.c +++ b/trunk/arch/m68k/kernel/time.c @@ -40,7 +40,7 @@ static inline int set_rtc_mmss(unsigned long nowtime) */ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs) { - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -96,23 +96,31 @@ void time_init(void) void do_gettimeofday(struct timeval *tv) { unsigned long flags; + extern unsigned long wall_jiffies; unsigned long seq; - unsigned long usec, sec; + unsigned long usec, sec, lost; unsigned long max_ntp_tick = tick_usec - tickadj; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = mach_gettimeoffset(); + lost = jiffies - wall_jiffies; /* * If time_adjust is negative then NTP is slowing the clock * so make sure not to go into next possible interval. * Better to lose some accuracy than have time go backwards.. */ - if (unlikely(time_adjust < 0)) + if (unlikely(time_adjust < 0)) { usec = min(usec, max_ntp_tick); + if (lost) + usec += lost * max_ntp_tick; + } + else if (unlikely(lost)) + usec += lost * tick_usec; + sec = xtime.tv_sec; usec += xtime.tv_nsec/1000; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); @@ -133,6 +141,7 @@ int do_settimeofday(struct timespec *tv) { time_t wtm_sec, sec = tv->tv_sec; long wtm_nsec, nsec = tv->tv_nsec; + extern unsigned long wall_jiffies; if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) return -EINVAL; @@ -144,7 +153,8 @@ int do_settimeofday(struct timespec *tv) * Discover what correction gettimeofday * would have done, and then undo it! */ - nsec -= 1000 * mach_gettimeoffset(); + nsec -= 1000 * (mach_gettimeoffset() + + (jiffies - wall_jiffies) * (1000000 / HZ)); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); diff --git a/trunk/arch/m68k/mm/fault.c b/trunk/arch/m68k/mm/fault.c index 911f2ce3f53e..aec15270d334 100644 --- a/trunk/arch/m68k/mm/fault.c +++ b/trunk/arch/m68k/mm/fault.c @@ -144,7 +144,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, case 1: /* read, present */ goto acc_err; case 0: /* read, not present */ - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto acc_err; } @@ -181,7 +181,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_init(current)) { + if (current->pid == 1) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/m68k/sun3/sun3ints.c b/trunk/arch/m68k/sun3/sun3ints.c index dc4ea7e074a6..f18b9d3ef16d 100644 --- a/trunk/arch/m68k/sun3/sun3ints.c +++ b/trunk/arch/m68k/sun3/sun3ints.c @@ -65,7 +65,7 @@ static irqreturn_t sun3_int5(int irq, void *dev_id, struct pt_regs *fp) #ifdef CONFIG_SUN3 intersil_clear(); #endif - do_timer(1); + do_timer(fp); #ifndef CONFIG_SMP update_process_times(user_mode(fp)); #endif diff --git a/trunk/arch/m68knommu/kernel/sys_m68k.c b/trunk/arch/m68knommu/kernel/sys_m68k.c index c3494b8447d1..d87e1e0a1336 100644 --- a/trunk/arch/m68knommu/kernel/sys_m68k.c +++ b/trunk/arch/m68knommu/kernel/sys_m68k.c @@ -26,7 +26,6 @@ #include #include #include -#include /* * sys_pipe() is the normal C calling standard for creating @@ -207,17 +206,3 @@ asmlinkage int sys_getpagesize(void) return PAGE_SIZE; } -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register long __res asm ("%d0") = __NR_execve; - register long __a asm ("%d1") = (long)(filename); - register long __b asm ("%d2") = (long)(argv); - register long __c asm ("%d3") = (long)(envp); - asm volatile ("trap #0" : "+d" (__res) - : "d" (__a), "d" (__b), "d" (__c)); - return __res; -} diff --git a/trunk/arch/m68knommu/kernel/time.c b/trunk/arch/m68knommu/kernel/time.c index c5667bdddd5e..1db987272220 100644 --- a/trunk/arch/m68knommu/kernel/time.c +++ b/trunk/arch/m68knommu/kernel/time.c @@ -26,6 +26,8 @@ #define TICK_SIZE (tick_nsec / 1000) +extern unsigned long wall_jiffies; + static inline int set_rtc_mmss(unsigned long nowtime) { @@ -49,7 +51,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs) write_seqlock(&xtime_lock); - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -122,12 +124,15 @@ void time_init(void) void do_gettimeofday(struct timeval *tv) { unsigned long flags; - unsigned long seq; + unsigned long lost, seq; unsigned long usec, sec; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = mach_gettimeoffset ? mach_gettimeoffset() : 0; + lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 87cee341eb54..330f6abc7703 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -126,7 +126,7 @@ config BASLER_EXCITE select IRQ_CPU select IRQ_CPU_RM7K select IRQ_CPU_RM9K - select MIPS_RM9122 + select SERIAL_RM9000 select SYS_HAS_CPU_RM9000 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL @@ -203,6 +203,26 @@ config MIPS_EV64120 . Say Y here if you wish to build a kernel for this platform. +config MIPS_EV96100 + bool "Galileo EV96100 Evaluation board (EXPERIMENTAL)" + depends on EXPERIMENTAL + select DMA_NONCOHERENT + select HW_HAS_PCI + select IRQ_CPU + select MIPS_GT96100 + select RM7000_CPU_SCACHE + select SWAP_IO_SPACE + select SYS_HAS_CPU_R5000 + select SYS_HAS_CPU_RM7000 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL + select SYS_SUPPORTS_BIG_ENDIAN + help + This is an evaluation board based on the Galileo GT-96100 LAN/WAN + communications controllers containing a MIPS R5000 compatible core + running at 83MHz. Their website is . Say Y + here if you wish to build a kernel for this platform. + config MIPS_IVR bool "Globespan IVR board" select DMA_NONCOHERENT @@ -537,7 +557,6 @@ config QEMU select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_LITTLE_ENDIAN select ARCH_SPARSEMEM_ENABLE help Qemu is a software emulator which among other architectures also @@ -955,12 +974,6 @@ config MIPS_TX3927 bool select HAS_TXX9_SERIAL -config MIPS_RM9122 - bool - select SERIAL_RM9000 - select GPI_RM9000 - select WDT_RM9000 - config PCI_MARVELL bool @@ -1011,15 +1024,6 @@ config EMMA2RH depends on MARKEINS default y -config SERIAL_RM9000 - bool - -config GPI_RM9000 - bool - -config WDT_RM9000 - bool - # # Unfortunately not all GT64120 systems run the chip at the same clock. # As the user for the clock rate and try to minimize the available options. @@ -1050,6 +1054,10 @@ config AU1X00_USB_DEVICE depends on MIPS_PB1500 || MIPS_PB1100 || MIPS_PB1000 default n +config MIPS_GT96100 + bool + select MIPS_GT64120 + config IT8172_CIR bool depends on MIPS_ITE8172 || MIPS_IVR @@ -1519,7 +1527,6 @@ config MIPS_MT_SMTC select CPU_MIPSR2_SRS select MIPS_MT select SMP - select SYS_SUPPORTS_SMP help This is a kernel model which is known a SMTC or lately has been marketesed into SMVP. @@ -1531,7 +1538,6 @@ config MIPS_MT_SMP select CPU_MIPSR2_SRS select MIPS_MT select SMP - select SYS_SUPPORTS_SMP help This is a kernel model which is also known a VSMP or lately has been marketesed into SMVP. @@ -1643,7 +1649,9 @@ config GENERIC_IRQ_PROBE default y config IRQ_PER_CPU + depends on SMP bool + default y # # - Highmem only makes sense for the 32-bit kernel. @@ -1711,7 +1719,6 @@ source "mm/Kconfig" config SMP bool "Multi-Processing support" depends on SYS_SUPPORTS_SMP - select IRQ_PER_CPU help This enables support for systems with more than one CPU. If you have a system with only one CPU, like most personal computers, say N. If @@ -1842,14 +1849,6 @@ config RWSEM_GENERIC_SPINLOCK bool default y -config LOCKDEP_SUPPORT - bool - default y - -config STACKTRACE_SUPPORT - bool - default y - source "init/Kconfig" menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)" diff --git a/trunk/arch/mips/Makefile b/trunk/arch/mips/Makefile index e521826b4234..d333ce4ba26b 100644 --- a/trunk/arch/mips/Makefile +++ b/trunk/arch/mips/Makefile @@ -279,6 +279,13 @@ core-$(CONFIG_MIPS_EV64120) += arch/mips/gt64120/common/ cflags-$(CONFIG_MIPS_EV64120) += -Iinclude/asm-mips/mach-ev64120 load-$(CONFIG_MIPS_EV64120) += 0xffffffff80100000 +# +# Galileo EV96100 Board +# +core-$(CONFIG_MIPS_EV96100) += arch/mips/galileo-boards/ev96100/ +cflags-$(CONFIG_MIPS_EV96100) += -Iinclude/asm-mips/mach-ev96100 +load-$(CONFIG_MIPS_EV96100) += 0xffffffff80100000 + # # Wind River PPMC Board (4KC + GT64120) # @@ -323,7 +330,6 @@ load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000 # MIPS SEAD board # core-$(CONFIG_MIPS_SEAD) += arch/mips/mips-boards/sead/ -cflags-$(CONFIG_MIPS_SEAD) += -Iinclude/asm-mips/mach-mips load-$(CONFIG_MIPS_SEAD) += 0xffffffff80100000 # diff --git a/trunk/arch/mips/au1000/common/time.c b/trunk/arch/mips/au1000/common/time.c index 0a067f3113a5..7fbea1bf7b48 100644 --- a/trunk/arch/mips/au1000/common/time.c +++ b/trunk/arch/mips/au1000/common/time.c @@ -96,7 +96,7 @@ void mips_timer_interrupt(struct pt_regs *regs) timerlo = count; kstat_this_cpu.irqs[irq]++; - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -137,7 +137,7 @@ irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs) } while (time_elapsed > 0) { - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -156,7 +156,7 @@ irqreturn_t counter0_irq(int irq, void *dev_id, struct pt_regs *regs) if (jiffie_drift >= 999) { jiffie_drift -= 999; - do_timer(1); /* increment jiffies by one */ + do_timer(regs); /* increment jiffies by one */ #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif diff --git a/trunk/arch/mips/au1000/db1x00/Makefile b/trunk/arch/mips/au1000/db1x00/Makefile index 51d62bd5d900..4c7d763f2113 100644 --- a/trunk/arch/mips/au1000/db1x00/Makefile +++ b/trunk/arch/mips/au1000/db1x00/Makefile @@ -6,3 +6,4 @@ # Makefile for the Alchemy Semiconductor Db1x00 board. lib-y := init.o board_setup.o irqmap.o +obj-$(CONFIG_WM97XX_COMODULE) += mirage_ts.o diff --git a/trunk/arch/mips/au1000/db1x00/mirage_ts.c b/trunk/arch/mips/au1000/db1x00/mirage_ts.c new file mode 100644 index 000000000000..0942dcf69518 --- /dev/null +++ b/trunk/arch/mips/au1000/db1x00/mirage_ts.c @@ -0,0 +1,260 @@ +/* + * linux/arch/mips/au1000/db1x00/mirage_ts.c + * + * BRIEF MODULE DESCRIPTION + * Glue between Mirage board-specific touchscreen pieces + * and generic Wolfson Codec touchscreen support. + * + * Based on pb1100_ts.c used in Hydrogen II. + * + * Copyright (c) 2003 Embedded Edge, LLC + * dan@embeddededge.com + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * Imported interface to Wolfson Codec driver. + */ +extern void *wm97xx_ts_get_handle(int which); +extern int wm97xx_ts_ready(void* ts_handle); +extern void wm97xx_ts_set_cal(void* ts_handle, int xscale, int xtrans, int yscale, int ytrans); +extern u16 wm97xx_ts_get_ac97(void* ts_handle, u8 reg); +extern void wm97xx_ts_set_ac97(void* ts_handle, u8 reg, u16 val); +extern int wm97xx_ts_read_data(void* ts_handle, long* x, long* y, long* pressure); +extern void wm97xx_ts_send_data(void* ts_handle, long x, long y, long z); + +int wm97xx_comodule_present = 1; + + +#define TS_NAME "mirage_ts" + +#define err(format, arg...) printk(KERN_ERR TS_NAME ": " format "\n" , ## arg) +#define info(format, arg...) printk(KERN_INFO TS_NAME ": " format "\n" , ## arg) +#define warn(format, arg...) printk(KERN_WARNING TS_NAME ": " format "\n" , ## arg) +#define DPRINTK(format, arg...) printk("%s: " format "\n", __FUNCTION__ , ## arg) + + +#define PEN_DOWN_IRQ AU1000_GPIO_7 + +static struct task_struct *ts_task = 0; +static DECLARE_COMPLETION(ts_complete); +static DECLARE_WAIT_QUEUE_HEAD(pendown_wait); + +#ifdef CONFIG_WM97XX_FIVEWIRETS +static int release_pressure = 1; +#else +static int release_pressure = 50; +#endif + +typedef struct { + long x; + long y; +} DOWN_EVENT; + +#define SAMPLE_RATE 50 /* samples per second */ +#define PEN_DEBOUNCE 5 /* samples for settling - fn of SAMPLE_RATE */ +#define PEN_UP_TIMEOUT 10 /* in seconds */ +#define PEN_UP_SETTLE 5 /* samples per second */ + +static struct { + int xscale; + int xtrans; + int yscale; + int ytrans; +} mirage_ts_cal = +{ +#if 0 + .xscale = 84, + .xtrans = -157, + .yscale = 66, + .ytrans = -150, +#else + .xscale = 84, + .xtrans = -150, + .yscale = 66, + .ytrans = -146, +#endif +}; + + +static void pendown_irq(int irqnr, void *devid, struct pt_regs *regs) +{ +//DPRINTK("got one 0x%x", au_readl(SYS_PINSTATERD)); + wake_up(&pendown_wait); +} + +static int ts_thread(void *id) +{ + static int pen_was_down = 0; + static DOWN_EVENT pen_xy; + long x, y, z; + void *ts; /* handle */ + struct task_struct *tsk = current; + int timeout = HZ / SAMPLE_RATE; + + ts_task = tsk; + + daemonize(); + tsk->tty = NULL; + tsk->policy = SCHED_FIFO; + tsk->rt_priority = 1; + strcpy(tsk->comm, "touchscreen"); + + /* only want to receive SIGKILL */ + spin_lock_irq(&tsk->sigmask_lock); + siginitsetinv(&tsk->blocked, sigmask(SIGKILL)); + recalc_sigpending(tsk); + spin_unlock_irq(&tsk->sigmask_lock); + + /* get handle for codec */ + ts = wm97xx_ts_get_handle(0); + + /* proceed only after everybody is ready */ + wait_event_timeout(pendown_wait, wm97xx_ts_ready(ts), HZ/4); + + /* board-specific calibration */ + wm97xx_ts_set_cal(ts, + mirage_ts_cal.xscale, + mirage_ts_cal.xtrans, + mirage_ts_cal.yscale, + mirage_ts_cal.ytrans); + + /* route Wolfson pendown interrupts to our GPIO */ + au_sync(); + wm97xx_ts_set_ac97(ts, 0x4c, wm97xx_ts_get_ac97(ts, 0x4c) & ~0x0008); + au_sync(); + wm97xx_ts_set_ac97(ts, 0x56, wm97xx_ts_get_ac97(ts, 0x56) & ~0x0008); + au_sync(); + wm97xx_ts_set_ac97(ts, 0x52, wm97xx_ts_get_ac97(ts, 0x52) | 0x2008); + au_sync(); + + for (;;) { + interruptible_sleep_on_timeout(&pendown_wait, timeout); + disable_irq(PEN_DOWN_IRQ); + if (signal_pending(tsk)) { + break; + } + + /* read codec */ + if (!wm97xx_ts_read_data(ts, &x, &y, &z)) + z = 0; /* treat no-data and pen-up the same */ + + if (signal_pending(tsk)) { + break; + } + + if (z >= release_pressure) { + y = ~y; /* top to bottom */ + if (pen_was_down > 1 /*&& pen_was_down < PEN_DEBOUNCE*/) {//THXXX + /* bounce ? */ + x = pen_xy.x; + y = pen_xy.y; + --pen_was_down; + } else if (pen_was_down <= 1) { + pen_xy.x = x; + pen_xy.y = y; + if (pen_was_down) + wm97xx_ts_send_data(ts, x, y, z); + pen_was_down = PEN_DEBOUNCE; + } + //wm97xx_ts_send_data(ts, x, y, z); + timeout = HZ / SAMPLE_RATE; + } else { + if (pen_was_down) { + if (--pen_was_down) + z = release_pressure; + else //THXXX + wm97xx_ts_send_data(ts, pen_xy.x, pen_xy.y, z); + } + /* The pendown signal takes some time to settle after + * reading the pen pressure so wait a little + * before enabling the pen. + */ + if (! pen_was_down) { +// interruptible_sleep_on_timeout(&pendown_wait, HZ / PEN_UP_SETTLE); + timeout = HZ * PEN_UP_TIMEOUT; + } + } + enable_irq(PEN_DOWN_IRQ); + } + enable_irq(PEN_DOWN_IRQ); + ts_task = NULL; + complete(&ts_complete); + return 0; +} + +static int __init ts_mirage_init(void) +{ + int ret; + + /* pen down signal is connected to GPIO 7 */ + + ret = request_irq(PEN_DOWN_IRQ, pendown_irq, 0, "ts-pendown", NULL); + if (ret) { + err("unable to get pendown irq%d: [%d]", PEN_DOWN_IRQ, ret); + return ret; + } + + lock_kernel(); + ret = kernel_thread(ts_thread, NULL, CLONE_FS | CLONE_FILES); + if (ret < 0) { + unlock_kernel(); + return ret; + } + unlock_kernel(); + + info("Mirage touchscreen IRQ initialized."); + + return 0; +} + +static void __exit ts_mirage_exit(void) +{ + if (ts_task) { + send_sig(SIGKILL, ts_task, 1); + wait_for_completion(&ts_complete); + } + + free_irq(PEN_DOWN_IRQ, NULL); +} + +module_init(ts_mirage_init); +module_exit(ts_mirage_exit); + diff --git a/trunk/arch/mips/basler/excite/excite_device.c b/trunk/arch/mips/basler/excite/excite_device.c index cc1ce77eab4a..bbb4ea43da88 100644 --- a/trunk/arch/mips/basler/excite/excite_device.c +++ b/trunk/arch/mips/basler/excite/excite_device.c @@ -68,7 +68,7 @@ enum { static struct resource - excite_ctr_resource __attribute__((unused)) = { + excite_ctr_resource = { .name = "GPI counters", .start = 0, .end = 5, @@ -77,7 +77,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_gpislice_resource __attribute__((unused)) = { + excite_gpislice_resource = { .name = "GPI slices", .start = 0, .end = 1, @@ -86,7 +86,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_mdio_channel_resource __attribute__((unused)) = { + excite_mdio_channel_resource = { .name = "MDIO channels", .start = 0, .end = 1, @@ -95,7 +95,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_fifomem_resource __attribute__((unused)) = { + excite_fifomem_resource = { .name = "FIFO memory", .start = 0, .end = 767, @@ -104,7 +104,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_scram_resource __attribute__((unused)) = { + excite_scram_resource = { .name = "Scratch RAM", .start = EXCITE_PHYS_SCRAM, .end = EXCITE_PHYS_SCRAM + EXCITE_SIZE_SCRAM - 1, @@ -113,7 +113,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_fpga_resource __attribute__((unused)) = { + excite_fpga_resource = { .name = "System FPGA", .start = EXCITE_PHYS_FPGA, .end = EXCITE_PHYS_FPGA + EXCITE_SIZE_FPGA - 1, @@ -122,7 +122,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_nand_resource __attribute__((unused)) = { + excite_nand_resource = { .name = "NAND flash control", .start = EXCITE_PHYS_NAND, .end = EXCITE_PHYS_NAND + EXCITE_SIZE_NAND - 1, @@ -131,7 +131,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_titan_resource __attribute__((unused)) = { + excite_titan_resource = { .name = "TITAN registers", .start = EXCITE_PHYS_TITAN, .end = EXCITE_PHYS_TITAN + EXCITE_SIZE_TITAN - 1, diff --git a/trunk/arch/mips/basler/excite/excite_flashtest.c b/trunk/arch/mips/basler/excite/excite_flashtest.c new file mode 100644 index 000000000000..f0024a8e3294 --- /dev/null +++ b/trunk/arch/mips/basler/excite/excite_flashtest.c @@ -0,0 +1,294 @@ +/* +* Copyright (C) 2005 by Basler Vision Technologies AG +* Author: Thies Moeller +* +* 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 // for ocd_write +#include // for queue + +#include "excite_nandflash.h" +#include "nandflash.h" + +#define PFX "excite flashtest: " +typedef void __iomem *io_reg_t; + +#define io_readb(__a__) __raw_readb((__a__)) +#define io_writeb(__v__, __a__) __raw_writeb((__v__), (__a__)) + + + +static inline const struct resource *excite_nandflash_get_resource( + struct platform_device *d, unsigned long flags, const char *basename) +{ + const char fmt[] = "%s_%u"; + char buf[80]; + + if (unlikely(snprintf(buf, sizeof buf, fmt, basename, d->id) >= sizeof buf)) + return NULL; + + return platform_get_resource_byname(d, flags, buf); +} + +static inline io_reg_t +excite_nandflash_map_regs(struct platform_device *d, const char *basename) +{ + void *result = NULL; + const struct resource *const r = + excite_nandflash_get_resource(d, IORESOURCE_MEM, basename); + if (r) + result = ioremap_nocache(r->start, r->end + 1 - r->start); + return result; +} + +/* controller and mtd information */ + +struct excite_nandflash_drvdata { + struct mtd_info board_mtd; + struct nand_chip board_chip; + io_reg_t regs; +}; + + +/* command and control functions */ +static void excite_nandflash_hwcontrol(struct mtd_info *mtd, int cmd) +{ + struct nand_chip *this = mtd->priv; + io_reg_t regs = container_of(mtd,struct excite_nandflash_drvdata,board_mtd)->regs; + + switch (cmd) { + /* Select the command latch */ + case NAND_CTL_SETCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_CMD; + break; + /* Deselect the command latch */ + case NAND_CTL_CLRCLE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_DATA; + break; + /* Select the address latch */ + case NAND_CTL_SETALE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_ADDR; + break; + /* Deselect the address latch */ + case NAND_CTL_CLRALE: this->IO_ADDR_W = regs + EXCITE_NANDFLASH_DATA; + break; + /* Select the chip -- not used */ + case NAND_CTL_SETNCE: + break; + /* Deselect the chip -- not used */ + case NAND_CTL_CLRNCE: + break; + } + + this->IO_ADDR_R = this->IO_ADDR_W; +} + +/* excite_nandflash_devready() + * + * returns 0 if the nand is busy, 1 if it is ready + */ +static int excite_nandflash_devready(struct mtd_info *mtd) +{ + struct excite_nandflash_drvdata *drvdata = + container_of(mtd, struct excite_nandflash_drvdata, board_mtd); + + return io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS); +} + +/* device management functions */ + +/* excite_nandflash_remove + * + * called by device layer to remove the driver + * the binding to the mtd and all allocated + * resources are released + */ +static int excite_nandflash_remove(struct device *dev) +{ + struct excite_nandflash_drvdata *this = dev_get_drvdata(dev); + + pr_info(PFX "remove"); + + dev_set_drvdata(dev, NULL); + + if (this == NULL) { + pr_debug(PFX "call remove without private data!!"); + return 0; + } + + + /* free the common resources */ + if (this->regs != NULL) { + iounmap(this->regs); + this->regs = NULL; + } + + kfree(this); + + return 0; +} + +static int elapsed; + +void my_workqueue_handler(void *arg) +{ + elapsed = 1; +} + +DECLARE_WORK(sigElapsed, my_workqueue_handler, 0); + + +/* excite_nandflash_probe + * + * called by device layer when it finds a device matching + * one our driver can handled. This code checks to see if + * it can allocate all necessary resources then calls the + * nand layer to look for devices +*/ +static int excite_nandflash_probe(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + + struct excite_nandflash_drvdata *drvdata; /* private driver data */ + struct nand_chip *board_chip; /* private flash chip data */ + struct mtd_info *board_mtd; /* mtd info for this board */ + + int err = 0; + int count = 0; + struct timeval tv,endtv; + unsigned int dt; + + pr_info(PFX "probe dev: (%p)\n", dev); + + pr_info(PFX "adjust LB timing\n"); + ocd_writel(0x00000330, LDP2); + + drvdata = kmalloc(sizeof(*drvdata), GFP_KERNEL); + if (unlikely(!drvdata)) { + printk(KERN_ERR PFX "no memory for drvdata\n"); + err = -ENOMEM; + goto mem_error; + } + + /* Initialize structures */ + memset(drvdata, 0, sizeof(*drvdata)); + + /* bind private data into driver */ + dev_set_drvdata(dev, drvdata); + + /* allocate and map the resource */ + drvdata->regs = + excite_nandflash_map_regs(pdev, EXCITE_NANDFLASH_RESOURCE_REGS); + + if (unlikely(!drvdata->regs)) { + printk(KERN_ERR PFX "cannot reserve register region\n"); + err = -ENXIO; + goto io_error; + } + + /* initialise our chip */ + board_chip = &drvdata->board_chip; + + board_chip->IO_ADDR_R = drvdata->regs + EXCITE_NANDFLASH_DATA; + board_chip->IO_ADDR_W = drvdata->regs + EXCITE_NANDFLASH_DATA; + + board_chip->hwcontrol = excite_nandflash_hwcontrol; + board_chip->dev_ready = excite_nandflash_devready; + + board_chip->chip_delay = 25; + #if 0 + /* TODO: speedup the initial scan */ + board_chip->options = NAND_USE_FLASH_BBT; + #endif + board_chip->eccmode = NAND_ECC_SOFT; + + /* link chip to mtd */ + board_mtd = &drvdata->board_mtd; + board_mtd->priv = board_chip; + + + pr_info(PFX "FlashTest\n"); + elapsed = 0; +/* schedule_delayed_work(&sigElapsed, 1*HZ); + while (!elapsed) { + io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS); + count++; + } + pr_info(PFX "reads in 1 sec --> %d\n",count); +*/ + do_gettimeofday(&tv); + for (count = 0 ; count < 1000000; count ++) { + io_readb(drvdata->regs + EXCITE_NANDFLASH_STATUS); + } + do_gettimeofday(&endtv); + dt = (endtv.tv_sec - tv.tv_sec) * 1000000 + endtv.tv_usec - tv.tv_usec; + pr_info(PFX "%8d us timeval\n",dt); + pr_info(PFX "EndFlashTest\n"); + +/* return with error to unload everything +*/ +io_error: + iounmap(drvdata->regs); + +mem_error: + kfree(drvdata); + + if (err == 0) + err = -EINVAL; + return err; +} + +static struct device_driver excite_nandflash_driver = { + .name = "excite_nand", + .bus = &platform_bus_type, + .probe = excite_nandflash_probe, + .remove = excite_nandflash_remove, +}; + +static int __init excite_nandflash_init(void) +{ + pr_info(PFX "register Driver (Rev: $Revision:$)\n"); + return driver_register(&excite_nandflash_driver); +} + +static void __exit excite_nandflash_exit(void) +{ + driver_unregister(&excite_nandflash_driver); + pr_info(PFX "Driver unregistered"); +} + +module_init(excite_nandflash_init); +module_exit(excite_nandflash_exit); + +MODULE_AUTHOR("Thies Moeller "); +MODULE_DESCRIPTION("Basler eXcite NAND-Flash driver"); +MODULE_LICENSE("GPL"); diff --git a/trunk/include/asm-mips/mach-excite/excite_fpga.h b/trunk/arch/mips/basler/excite/excite_fpga.h similarity index 100% rename from trunk/include/asm-mips/mach-excite/excite_fpga.h rename to trunk/arch/mips/basler/excite/excite_fpga.h diff --git a/trunk/arch/mips/configs/atlas_defconfig b/trunk/arch/mips/configs/atlas_defconfig index 35931bedc3df..54274065e9a5 100644 --- a/trunk/arch/mips/configs/atlas_defconfig +++ b/trunk/arch/mips/configs/atlas_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -161,8 +162,6 @@ CONFIG_HZ=100 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1194,7 +1193,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -1306,7 +1305,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/bigsur_defconfig b/trunk/arch/mips/configs/bigsur_defconfig index c6a015940b41..887fd959482a 100644 --- a/trunk/arch/mips/configs/bigsur_defconfig +++ b/trunk/arch/mips/configs/bigsur_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -167,8 +168,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set # CONFIG_PREEMPT_BKL is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -906,7 +905,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/capcella_defconfig b/trunk/arch/mips/configs/capcella_defconfig index e5358121d2da..a01344f3a4c2 100644 --- a/trunk/arch/mips/configs/capcella_defconfig +++ b/trunk/arch/mips/configs/capcella_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -149,8 +150,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -893,7 +892,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/cobalt_defconfig b/trunk/arch/mips/configs/cobalt_defconfig index adf1e8c98c65..c95682445a28 100644 --- a/trunk/arch/mips/configs/cobalt_defconfig +++ b/trunk/arch/mips/configs/cobalt_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y CONFIG_MIPS_COBALT=y # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -146,8 +147,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -829,7 +828,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -891,7 +890,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/db1000_defconfig b/trunk/arch/mips/configs/db1000_defconfig index 4fd29ffdfb8d..c2f33d3af62c 100644 --- a/trunk/arch/mips/configs/db1000_defconfig +++ b/trunk/arch/mips/configs/db1000_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_DB1000=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -147,8 +148,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1008,7 +1007,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/db1100_defconfig b/trunk/arch/mips/configs/db1100_defconfig index 025b960ba990..8c44d16ae9a2 100644 --- a/trunk/arch/mips/configs/db1100_defconfig +++ b/trunk/arch/mips/configs/db1100_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_DB1100=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -147,8 +148,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1008,7 +1007,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/db1200_defconfig b/trunk/arch/mips/configs/db1200_defconfig index 80c9dd98f897..c13768e75ac5 100644 --- a/trunk/arch/mips/configs/db1200_defconfig +++ b/trunk/arch/mips/configs/db1200_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_DB1200=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -147,8 +148,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1089,7 +1088,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/db1500_defconfig b/trunk/arch/mips/configs/db1500_defconfig index 6caa90b0e176..8aea73fae7fb 100644 --- a/trunk/arch/mips/configs/db1500_defconfig +++ b/trunk/arch/mips/configs/db1500_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_DB1500=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -149,8 +150,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1292,7 +1291,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/db1550_defconfig b/trunk/arch/mips/configs/db1550_defconfig index c6cae86c6ab7..90ccb7359630 100644 --- a/trunk/arch/mips/configs/db1550_defconfig +++ b/trunk/arch/mips/configs/db1550_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_DB1550=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -148,8 +149,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1113,7 +1112,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ddb5477_defconfig b/trunk/arch/mips/configs/ddb5477_defconfig index 72f24001c99e..b598cf08f156 100644 --- a/trunk/arch/mips/configs/ddb5477_defconfig +++ b/trunk/arch/mips/configs/ddb5477_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -146,8 +147,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -854,7 +853,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/decstation_defconfig b/trunk/arch/mips/configs/decstation_defconfig index be901df7fefa..597150b14077 100644 --- a/trunk/arch/mips/configs/decstation_defconfig +++ b/trunk/arch/mips/configs/decstation_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set CONFIG_MACH_DECSTATION=y # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -147,8 +148,6 @@ CONFIG_HZ=128 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -830,7 +829,6 @@ CONFIG_ULTRIX_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/e55_defconfig b/trunk/arch/mips/configs/e55_defconfig index 6133c28beb8c..fa2996bb4b7c 100644 --- a/trunk/arch/mips/configs/e55_defconfig +++ b/trunk/arch/mips/configs/e55_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc2 -# Tue Jul 25 23:15:03 2006 +# Linux kernel version: 2.6.18-rc1 +# Thu Jul 6 10:04:02 2006 # CONFIG_MIPS=y @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -147,8 +148,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -228,6 +227,7 @@ CONFIG_MMU=y # # PCCARD (PCMCIA/CardBus) support # +# CONFIG_PCCARD is not set # # PCI Hotplug Support @@ -254,6 +254,7 @@ CONFIG_TRAD_SIGNALS=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set # @@ -283,7 +284,6 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set @@ -643,7 +643,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -651,7 +650,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x1f0,0x3f6,40 mem=8M" +CONFIG_CMDLINE="console=ttyVR0,19200 mem=8M" # # Security options diff --git a/trunk/arch/mips/configs/emma2rh_defconfig b/trunk/arch/mips/configs/emma2rh_defconfig index a484b7d396fc..375b2ac24a49 100644 --- a/trunk/arch/mips/configs/emma2rh_defconfig +++ b/trunk/arch/mips/configs/emma2rh_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -147,8 +148,6 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_PREEMPT_BKL=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1182,7 +1181,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ev64120_defconfig b/trunk/arch/mips/configs/ev64120_defconfig index 21bfcdebf8f5..b0afc118bd5c 100644 --- a/trunk/arch/mips/configs/ev64120_defconfig +++ b/trunk/arch/mips/configs/ev64120_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set CONFIG_MIPS_EV64120=y +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -148,8 +149,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -844,7 +843,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/sh/configs/shmin_defconfig b/trunk/arch/mips/configs/ev96100_defconfig similarity index 50% rename from trunk/arch/sh/configs/shmin_defconfig rename to trunk/arch/mips/configs/ev96100_defconfig index 382b3bd3963b..0bdc10f11610 100644 --- a/trunk/arch/sh/configs/shmin_defconfig +++ b/trunk/arch/mips/configs/ev96100_defconfig @@ -1,16 +1,159 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17 -# Wed Aug 2 01:45:03 2006 -# -CONFIG_SUPERH=y +# Linux kernel version: 2.6.18-rc1 +# Thu Jul 6 10:04:05 2006 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MIPS_MTX1 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_PB1550 is not set +# CONFIG_MIPS_PB1200 is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_DB1550 is not set +# CONFIG_MIPS_DB1200 is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_BASLER_EXCITE is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +CONFIG_MIPS_EV96100=y +# CONFIG_MIPS_IVR is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_WR_PPMC is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_3 is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_PNX8550_V2PCI is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_DDB5477 is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_MARKEINS is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SIBYTE_SWARM is not set +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_DMA_NEED_PCI_MAP_STATE=y +CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_IRQ_CPU=y +CONFIG_MIPS_GT64120=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_MIPS_GT96100=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_MIPS32_R1 is not set +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +CONFIG_CPU_RM7000=y +# CONFIG_CPU_RM9000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_SYS_HAS_CPU_R5000=y +CONFIG_SYS_HAS_CPU_RM7000=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y + +# +# Kernel type +# +CONFIG_32BIT=y +# CONFIG_64BIT is not set +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +CONFIG_BOARD_SCACHE=y +CONFIG_RM7000_CPU_SCACHE=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_MIPS_MT_DISABLED=y +# CONFIG_MIPS_MT_SMTC is not set +# CONFIG_MIPS_MT_SMP is not set +# CONFIG_MIPS_VPE_LOADER is not set +# CONFIG_64BIT_PHYS_ADDR is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_PTRACE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_RESOURCES_64BIT is not set +# CONFIG_HZ_48 is not set +# CONFIG_HZ_100 is not set +# CONFIG_HZ_128 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_256 is not set +CONFIG_HZ_1000=y +# CONFIG_HZ_1024 is not set +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_HZ=1000 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # Code maturity level options @@ -24,210 +167,70 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 # CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set -# CONFIG_SYSVIPC is not set +CONFIG_SWAP=y +CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_SYSCTL is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set +CONFIG_RELAY=y CONFIG_INITRAMFS_SOURCE="" -# CONFIG_UID16 is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=y -# CONFIG_KALLSYMS is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set # CONFIG_HOTPLUG is not set CONFIG_PRINTK=y -# CONFIG_BUG is not set -# CONFIG_ELF_CORE is not set -# CONFIG_BASE_FULL is not set -# CONFIG_FUTEX is not set -# CONFIG_EPOLL is not set -# CONFIG_SHMEM is not set -# CONFIG_SLAB is not set -CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=1 -CONFIG_SLOB=y -CONFIG_OBSOLETE_INTERMODULE=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set # # Loadable module support # -# CONFIG_MODULES is not set +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODVERSIONS=y +CONFIG_MODULE_SRCVERSION_ALL=y +# CONFIG_KMOD is not set # # Block layer # # CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set # # IO Schedulers # CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" - -# -# System type -# -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7709_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_STB1_HARP is not set -# CONFIG_SH_STB1_OVERDRIVE is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_CQREEK is not set -# CONFIG_SH_DMIDA is not set -# CONFIG_SH_EC3104 is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_CAT68701 is not set -# CONFIG_SH_BIGSUR is not set -# CONFIG_SH_SH2000 is not set -# CONFIG_SH_ADX is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_R7780RP is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -CONFIG_SH_SHMIN=y -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# -CONFIG_CPU_SH3=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -CONFIG_CPU_SUBTYPE_SH7706=y -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set - -# -# SH-4 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -# CONFIG_CPU_SUBTYPE_SH7751 is not set -# CONFIG_CPU_SUBTYPE_SH7751R is not set -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set -# CONFIG_CPU_SUBTYPE_SH7770 is not set -# CONFIG_CPU_SUBTYPE_SH7780 is not set - -# -# Memory management options -# -CONFIG_MMU=y -CONFIG_PAGE_OFFSET=0x80000000 -CONFIG_MEMORY_START=0x0c000000 -CONFIG_MEMORY_SIZE=0x00800000 -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set - -# -# Processor features -# -CONFIG_CPU_LITTLE_ENDIAN=y -# CONFIG_SH_FPU_EMU is not set -# CONFIG_SH_DSP is not set -# CONFIG_SH_ADC is not set -CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_SR_RB=y - -# -# Timer support -# -CONFIG_SH_TMU=y -CONFIG_SH_PCLK_FREQ=32000000 - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# DMA support -# -# CONFIG_SH_DMA is not set - -# -# Companion Chips -# -# CONFIG_HD6446X_SERIES is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" # -# Kernel features -# -# CONFIG_KEXEC is not set -# CONFIG_PREEMPT is not set -# CONFIG_SMP is not set - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x00210000 -# CONFIG_UBC_WAKEUP is not set -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttySC1,115200 root=1f01 mtdparts=phys_mapped_flash:64k(firm)ro,-(sys) netdev=34,0x300,eth0 " - -# -# Bus options +# Bus options (PCI, PCMCIA, EISA, ISA, TC) # +CONFIG_HW_HAS_PCI=y # CONFIG_PCI is not set +CONFIG_MMU=y # # PCCARD (PCMCIA/CardBus) support @@ -242,13 +245,8 @@ CONFIG_CMDLINE="console=ttySC1,115200 root=1f01 mtdparts=phys_mapped_flash:64k(f # Executable file formats # CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set # CONFIG_BINFMT_MISC is not set - -# -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set +CONFIG_TRAD_SIGNALS=y # # Networking @@ -261,14 +259,16 @@ CONFIG_NET=y # CONFIG_NETDEBUG is not set # CONFIG_PACKET is not set CONFIG_UNIX=y -# CONFIG_NET_KEY is not set +CONFIG_XFRM=y +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=y CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_FIB_HASH=y CONFIG_IP_PNP=y # CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set +CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set @@ -279,6 +279,8 @@ CONFIG_IP_PNP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set @@ -286,6 +288,7 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set +CONFIG_NETWORK_SECMARK=y # CONFIG_NETFILTER is not set # @@ -327,7 +330,13 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_IEEE80211 is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_WIRELESS_EXT=y # # Device Drivers @@ -339,92 +348,17 @@ CONFIG_TCP_CONG_BIC=y CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_FW_LOADER is not set +# CONFIG_SYS_HYPERVISOR is not set # # Connector - unified userspace <-> kernelspace linker # -# CONFIG_CONNECTOR is not set +CONFIG_CONNECTOR=m # # Memory Technology Devices (MTD) # -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y - -# -# User Modules And Translation Layers -# -# CONFIG_MTD_CHAR is not set -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0xa0000000 -CONFIG_MTD_PHYSMAP_LEN=0x80000 -CONFIG_MTD_PHYSMAP_BANKWIDTH=1 -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set +# CONFIG_MTD is not set # # Parallel port support @@ -439,13 +373,14 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # Block devices # # CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set +CONFIG_CDROM_PKTCDVD=m +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_ATA_OVER_ETH=m # # ATA/ATAPI/MFM/RLL support @@ -455,7 +390,7 @@ CONFIG_BLK_DEV_LOOP=y # # SCSI device support # -# CONFIG_RAID_ATTRS is not set +CONFIG_RAID_ATTRS=m # CONFIG_SCSI is not set # @@ -488,16 +423,26 @@ CONFIG_NETDEVICES=y # # PHY device support # -# CONFIG_PHYLIB is not set +CONFIG_PHYLIB=m + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m +CONFIG_VITESSE_PHY=m +CONFIG_SMSC_PHY=m # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y # CONFIG_MII is not set -# CONFIG_STNIC is not set -# CONFIG_SMC91X is not set -CONFIG_NE2000=y +CONFIG_MIPS_GT96100ETH=y +# CONFIG_DM9000 is not set # # Ethernet (1000 Mbit) @@ -540,31 +485,60 @@ CONFIG_NE2000=y # # Input device support # -# CONFIG_INPUT is not set +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Hardware I/O ports # -# CONFIG_SERIO is not set +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +CONFIG_SERIO_RAW=m # CONFIG_GAMEPORT is not set # # Character devices # -# CONFIG_VT is not set +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +CONFIG_VT_HW_CONSOLE_BINDING=y # CONFIG_SERIAL_NONSTANDARD is not set # # Serial drivers # -# CONFIG_SERIAL_8250 is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set # # Non-8250 serial port support # -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_NR_UARTS=2 -CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y @@ -580,6 +554,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_HW_RANDOM is not set # CONFIG_RTC is not set # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set @@ -636,8 +611,15 @@ CONFIG_VIDEO_V4L2=y # # Graphics support # +# CONFIG_FIRMWARE_EDID is not set # CONFIG_FB is not set +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + # # Sound # @@ -690,10 +672,25 @@ CONFIG_VIDEO_V4L2=y # # CONFIG_RTC_CLASS is not set +# +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + # # File systems # -# CONFIG_EXT2_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set @@ -702,12 +699,13 @@ CONFIG_VIDEO_V4L2=y # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set -# CONFIG_INOTIFY is not set +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set +CONFIG_FUSE_FS=m # # CD-ROM/DVD Filesystems @@ -726,12 +724,12 @@ CONFIG_VIDEO_V4L2=y # Pseudo filesystems # CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -# CONFIG_SYSFS is not set -CONFIG_TMPFS=y -# CONFIG_HUGETLBFS is not set +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -743,9 +741,7 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y +# CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set @@ -756,20 +752,19 @@ CONFIG_CRAMFS=y # Network File Systems # CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V3 is not set # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -796,22 +791,48 @@ CONFIG_MSDOS_PARTITION=y # # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set +# CONFIG_UNUSED_SYMBOLS is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_UNWIND_INFO is not set -CONFIG_SH_STANDARD_BIOS=y -CONFIG_EARLY_PRINTK=y -# CONFIG_KGDB is not set +# CONFIG_DEBUG_FS is not set +CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE="" # # Security options # -# CONFIG_KEYS is not set +CONFIG_KEYS=y +CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_SECURITY is not set # # Cryptographic options # -# CONFIG_CRYPTO is not set +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=m +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_TEST is not set # # Hardware crypto devices @@ -821,7 +842,9 @@ CONFIG_EARLY_PRINTK=y # Library routines # # CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y +CONFIG_CRC16=m +CONFIG_CRC32=m +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=m +CONFIG_ZLIB_DEFLATE=m +CONFIG_PLIST=y diff --git a/trunk/arch/mips/configs/excite_defconfig b/trunk/arch/mips/configs/excite_defconfig index 1a5b06cfb4d6..045ebd089893 100644 --- a/trunk/arch/mips/configs/excite_defconfig +++ b/trunk/arch/mips/configs/excite_defconfig @@ -26,6 +26,7 @@ CONFIG_BASLER_EXCITE=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -149,8 +150,6 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y CONFIG_PREEMPT_BKL=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1186,7 +1185,6 @@ CONFIG_NLS_ISO8859_1=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ip22_defconfig b/trunk/arch/mips/configs/ip22_defconfig index 21d53e0c9ee8..ef16d1fb5071 100644 --- a/trunk/arch/mips/configs/ip22_defconfig +++ b/trunk/arch/mips/configs/ip22_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -153,8 +154,6 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1014,7 +1013,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -1149,7 +1148,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ip27_defconfig b/trunk/arch/mips/configs/ip27_defconfig index e3e94c7e5ee1..4bf1ee7f5f00 100644 --- a/trunk/arch/mips/configs/ip27_defconfig +++ b/trunk/arch/mips/configs/ip27_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -162,8 +163,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_PREEMPT_BKL=y # CONFIG_MIPS_INSANE_LARGE is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -901,7 +900,7 @@ CONFIG_FUSE_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -982,7 +981,6 @@ CONFIG_SGI_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ip32_defconfig b/trunk/arch/mips/configs/ip32_defconfig index b4ab2bea9723..f83dc09c3ca9 100644 --- a/trunk/arch/mips/configs/ip32_defconfig +++ b/trunk/arch/mips/configs/ip32_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -153,8 +154,6 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -924,7 +923,6 @@ CONFIG_SGI_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/it8172_defconfig b/trunk/arch/mips/configs/it8172_defconfig index 18d20fb7d5f0..a91d72a9ca86 100644 --- a/trunk/arch/mips/configs/it8172_defconfig +++ b/trunk/arch/mips/configs/it8172_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set CONFIG_MIPS_ITE8172=y # CONFIG_MACH_JAZZ is not set @@ -147,8 +148,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -902,7 +901,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ivr_defconfig b/trunk/arch/mips/configs/ivr_defconfig index 99831d0bf76b..cebc67212d06 100644 --- a/trunk/arch/mips/configs/ivr_defconfig +++ b/trunk/arch/mips/configs/ivr_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set CONFIG_MIPS_IVR=y # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -144,8 +145,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -858,7 +857,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/jaguar-atx_defconfig b/trunk/arch/mips/configs/jaguar-atx_defconfig index 9d4d17ace123..5d9eb11aba3d 100644 --- a/trunk/arch/mips/configs/jaguar-atx_defconfig +++ b/trunk/arch/mips/configs/jaguar-atx_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -153,8 +154,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -732,7 +731,7 @@ CONFIG_FUSE_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y @@ -777,7 +776,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/jmr3927_defconfig b/trunk/arch/mips/configs/jmr3927_defconfig index d03746667a96..be45a9044d06 100644 --- a/trunk/arch/mips/configs/jmr3927_defconfig +++ b/trunk/arch/mips/configs/jmr3927_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -143,8 +144,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_RTC_DS1742=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -874,7 +873,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/lasat200_defconfig b/trunk/arch/mips/configs/lasat200_defconfig index 1db8249b4c0f..64dc9f45a19c 100644 --- a/trunk/arch/mips/configs/lasat200_defconfig +++ b/trunk/arch/mips/configs/lasat200_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -151,8 +152,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -906,7 +905,7 @@ CONFIG_FUSE_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -972,7 +971,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/malta_defconfig b/trunk/arch/mips/configs/malta_defconfig index aeefe2873e38..2690baf15a85 100644 --- a/trunk/arch/mips/configs/malta_defconfig +++ b/trunk/arch/mips/configs/malta_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -170,8 +171,6 @@ CONFIG_HZ=100 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1231,7 +1230,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -1343,7 +1342,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/mipssim_defconfig b/trunk/arch/mips/configs/mipssim_defconfig index a3cbd23bf217..c298979c18ae 100644 --- a/trunk/arch/mips/configs/mipssim_defconfig +++ b/trunk/arch/mips/configs/mipssim_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -148,8 +149,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -801,7 +800,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/mpc30x_defconfig b/trunk/arch/mips/configs/mpc30x_defconfig index 6570b47426ce..938b38ab5239 100644 --- a/trunk/arch/mips/configs/mpc30x_defconfig +++ b/trunk/arch/mips/configs/mpc30x_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc2 -# Tue Jul 25 23:16:46 2006 +# Linux kernel version: 2.6.18-rc1 +# Thu Jul 6 10:04:15 2006 # CONFIG_MIPS=y @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -70,6 +71,7 @@ CONFIG_MACH_VR41XX=y CONFIG_VICTOR_MPC30X=y # CONFIG_ZAO_CAPCELLA is not set CONFIG_PCI_VR41XX=y +CONFIG_VRC4173=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y @@ -148,8 +150,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -168,7 +168,6 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set @@ -842,7 +841,7 @@ CONFIG_USB_PEGASUS=m # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set @@ -983,6 +982,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -1007,7 +1007,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -1015,7 +1014,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="mem=32M console=ttyVR0,19200 ide0=0x170,0x376,73" +CONFIG_CMDLINE="mem=32M console=ttyVR0,19200" # # Security options diff --git a/trunk/arch/mips/configs/ocelot_3_defconfig b/trunk/arch/mips/configs/ocelot_3_defconfig index 440d65f93a94..ec5758f22676 100644 --- a/trunk/arch/mips/configs/ocelot_3_defconfig +++ b/trunk/arch/mips/configs/ocelot_3_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -153,8 +154,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1093,7 +1092,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ocelot_c_defconfig b/trunk/arch/mips/configs/ocelot_c_defconfig index c2c7ae77da3e..0d33d87de1a1 100644 --- a/trunk/arch/mips/configs/ocelot_c_defconfig +++ b/trunk/arch/mips/configs/ocelot_c_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -150,8 +151,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -775,7 +774,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -841,7 +840,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ocelot_defconfig b/trunk/arch/mips/configs/ocelot_defconfig index 67efe270e0cc..4b999102715e 100644 --- a/trunk/arch/mips/configs/ocelot_defconfig +++ b/trunk/arch/mips/configs/ocelot_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -154,8 +155,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -724,7 +723,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -790,7 +789,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/ocelot_g_defconfig b/trunk/arch/mips/configs/ocelot_g_defconfig index a10f34de5f7e..827b344f6010 100644 --- a/trunk/arch/mips/configs/ocelot_g_defconfig +++ b/trunk/arch/mips/configs/ocelot_g_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -153,8 +154,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -778,7 +777,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -844,7 +843,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/pb1100_defconfig b/trunk/arch/mips/configs/pb1100_defconfig index 741f8258075c..9ed60fef69e0 100644 --- a/trunk/arch/mips/configs/pb1100_defconfig +++ b/trunk/arch/mips/configs/pb1100_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_PB1100=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -149,8 +150,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1002,7 +1001,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/pb1500_defconfig b/trunk/arch/mips/configs/pb1500_defconfig index 8576340714da..6774254b1be6 100644 --- a/trunk/arch/mips/configs/pb1500_defconfig +++ b/trunk/arch/mips/configs/pb1500_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_PB1500=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -148,8 +149,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1108,7 +1107,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/pb1550_defconfig b/trunk/arch/mips/configs/pb1550_defconfig index 3db7427d1b55..1afe5bf6e765 100644 --- a/trunk/arch/mips/configs/pb1550_defconfig +++ b/trunk/arch/mips/configs/pb1550_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS_PB1550=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -148,8 +149,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1100,7 +1099,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/pnx8550-jbs_defconfig b/trunk/arch/mips/configs/pnx8550-jbs_defconfig index 26b0b9883496..ac616c82d348 100644 --- a/trunk/arch/mips/configs/pnx8550-jbs_defconfig +++ b/trunk/arch/mips/configs/pnx8550-jbs_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -153,8 +154,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -878,7 +877,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/pnx8550-v2pci_defconfig b/trunk/arch/mips/configs/pnx8550-v2pci_defconfig index e93266b37dd9..a8eb51bae3f3 100644 --- a/trunk/arch/mips/configs/pnx8550-v2pci_defconfig +++ b/trunk/arch/mips/configs/pnx8550-v2pci_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -153,8 +154,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1059,7 +1058,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/qemu_defconfig b/trunk/arch/mips/configs/qemu_defconfig index 9b0dab822bd0..6a63a113b7ea 100644 --- a/trunk/arch/mips/configs/qemu_defconfig +++ b/trunk/arch/mips/configs/qemu_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -145,8 +146,6 @@ CONFIG_HZ=100 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -688,7 +687,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y @@ -735,7 +734,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/rbhma4500_defconfig b/trunk/arch/mips/configs/rbhma4500_defconfig index dd0296036026..6779f449bd2d 100644 --- a/trunk/arch/mips/configs/rbhma4500_defconfig +++ b/trunk/arch/mips/configs/rbhma4500_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -155,8 +156,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1337,7 +1336,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/rm200_defconfig b/trunk/arch/mips/configs/rm200_defconfig index d8a498d64d62..b7826d3a2b77 100644 --- a/trunk/arch/mips/configs/rm200_defconfig +++ b/trunk/arch/mips/configs/rm200_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -158,8 +159,6 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1443,7 +1442,7 @@ CONFIG_NTFS_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -1586,7 +1585,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/sb1250-swarm_defconfig b/trunk/arch/mips/configs/sb1250-swarm_defconfig index 805a4fe450f5..625c1c619b6b 100644 --- a/trunk/arch/mips/configs/sb1250-swarm_defconfig +++ b/trunk/arch/mips/configs/sb1250-swarm_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -171,8 +172,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_PREEMPT_BKL=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -875,7 +874,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/sead_defconfig b/trunk/arch/mips/configs/sead_defconfig index 6fcb656d8d87..4401b602118f 100644 --- a/trunk/arch/mips/configs/sead_defconfig +++ b/trunk/arch/mips/configs/sead_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -151,8 +152,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -583,7 +582,6 @@ CONFIG_PARTITION_ADVANCED=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/tb0226_defconfig b/trunk/arch/mips/configs/tb0226_defconfig index dc312f19ada7..2ba4e25e8c34 100644 --- a/trunk/arch/mips/configs/tb0226_defconfig +++ b/trunk/arch/mips/configs/tb0226_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -151,8 +152,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1061,7 +1060,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/tb0229_defconfig b/trunk/arch/mips/configs/tb0229_defconfig index 85615d99b01a..fc8a407c1add 100644 --- a/trunk/arch/mips/configs/tb0229_defconfig +++ b/trunk/arch/mips/configs/tb0229_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -151,8 +152,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -970,7 +969,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/tb0287_defconfig b/trunk/arch/mips/configs/tb0287_defconfig index ad7271b3f266..effcb63b81a3 100644 --- a/trunk/arch/mips/configs/tb0287_defconfig +++ b/trunk/arch/mips/configs/tb0287_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -151,8 +152,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1148,7 +1147,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/workpad_defconfig b/trunk/arch/mips/configs/workpad_defconfig index 863f6a7cadfd..4891d02ef8ca 100644 --- a/trunk/arch/mips/configs/workpad_defconfig +++ b/trunk/arch/mips/configs/workpad_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc2 -# Tue Jul 25 23:13:04 2006 +# Linux kernel version: 2.6.18-rc1 +# Thu Jul 6 10:04:21 2006 # CONFIG_MIPS=y @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -147,8 +148,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -167,7 +166,6 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set @@ -381,7 +379,6 @@ CONFIG_CONNECTOR=m CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 # CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -858,6 +855,7 @@ CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set +# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set @@ -882,7 +880,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set @@ -890,7 +887,7 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x170,0x376,49 mem=16M" +CONFIG_CMDLINE="console=ttyVR0,19200 mem=16M" # # Security options diff --git a/trunk/arch/mips/configs/wrppmc_defconfig b/trunk/arch/mips/configs/wrppmc_defconfig index c10267d61cc9..3e4b16b39827 100644 --- a/trunk/arch/mips/configs/wrppmc_defconfig +++ b/trunk/arch/mips/configs/wrppmc_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -155,8 +156,6 @@ CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -831,7 +830,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/configs/yosemite_defconfig b/trunk/arch/mips/configs/yosemite_defconfig index 4d3c1329f3cf..3a68d8a25b66 100644 --- a/trunk/arch/mips/configs/yosemite_defconfig +++ b/trunk/arch/mips/configs/yosemite_defconfig @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -152,8 +153,6 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_PREEMPT_BKL=y -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -762,7 +761,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/defconfig b/trunk/arch/mips/defconfig index 21d53e0c9ee8..fff6fcc96212 100644 --- a/trunk/arch/mips/defconfig +++ b/trunk/arch/mips/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.18-rc1 -# Thu Jul 6 10:04:10 2006 +# Thu Jul 6 09:49:33 2006 # CONFIG_MIPS=y @@ -25,6 +25,7 @@ CONFIG_MIPS=y # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set # CONFIG_MIPS_IVR is not set # CONFIG_MIPS_ITE8172 is not set # CONFIG_MACH_JAZZ is not set @@ -153,8 +154,6 @@ CONFIG_HZ=1000 # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -1014,7 +1013,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -CONFIG_TMPFS=y +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set @@ -1149,7 +1148,6 @@ CONFIG_NLS_UTF8=m # # Kernel hacking # -CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set diff --git a/trunk/arch/mips/galileo-boards/ev96100/Makefile b/trunk/arch/mips/galileo-boards/ev96100/Makefile new file mode 100644 index 000000000000..cd868ec78cbc --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/Makefile @@ -0,0 +1,9 @@ +# +# Copyright 2000 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# ppopov@mvista.com or source@mvista.com +# +# Makefile for the Galileo EV96100 board. +# + +obj-y += init.o irq.o puts.o reset.o time.o setup.o diff --git a/trunk/arch/mips/galileo-boards/ev96100/init.c b/trunk/arch/mips/galileo-boards/ev96100/init.c new file mode 100644 index 000000000000..a01fe9b36f2c --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/init.c @@ -0,0 +1,173 @@ +/* + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/generic/generic.c + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +/* Environment variable */ + +typedef struct { + char *name; + char *val; +} t_env_var; + +int prom_argc; +char **prom_argv, **prom_envp; + +int init_debug = 0; + +char * __init prom_getcmdline(void) +{ + return &(arcs_cmdline[0]); +} + +unsigned long __init prom_free_prom_memory(void) +{ + return 0; +} + +void __init prom_init_cmdline(void) +{ + char *cp; + int actr; + + actr = 1; /* Always ignore argv[0] */ + + cp = &(arcs_cmdline[0]); + while(actr < prom_argc) { + strcpy(cp, prom_argv[actr]); + cp += strlen(prom_argv[actr]); + *cp++ = ' '; + actr++; + } + if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ + --cp; + *cp = '\0'; +} + +char *prom_getenv(char *envname) +{ + /* + * Return a pointer to the given environment variable. + */ + + t_env_var *env = (t_env_var *) prom_envp; + int i; + + i = strlen(envname); + + while (env->name) { + if (strncmp(envname, env->name, i) == 0) { + return (env->val); + } + env++; + } + return (NULL); +} + +static inline unsigned char str2hexnum(unsigned char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 0; /* foo */ +} + +static inline void str2eaddr(unsigned char *ea, unsigned char *str) +{ + int i; + + for (i = 0; i < 6; i++) { + unsigned char num; + + if ((*str == '.') || (*str == ':')) + str++; + num = str2hexnum(*str++) << 4; + num |= (str2hexnum(*str++)); + ea[i] = num; + } +} + +int get_ethernet_addr(char *ethernet_addr) +{ + char *ethaddr_str; + + ethaddr_str = prom_getenv("ethaddr"); + if (!ethaddr_str) { + printk("ethaddr not set in boot prom\n"); + return -1; + } + str2eaddr(ethernet_addr, ethaddr_str); + + if (init_debug > 1) { + int i; + printk("get_ethernet_addr: "); + for (i = 0; i < 5; i++) + printk("%02x:", + (unsigned char) *(ethernet_addr + i)); + printk("%02x\n", *(ethernet_addr + i)); + } + + return 0; +} + +const char *get_system_type(void) +{ + return "Galileo EV96100"; +} + +void __init prom_init(void) +{ + volatile unsigned char *uart; + char ppbuf[8]; + + prom_argc = fw_arg0; + prom_argv = (char **) fw_arg1; + prom_envp = (char **) fw_arg2; + + mips_machgroup = MACH_GROUP_GALILEO; + mips_machtype = MACH_EV96100; + + prom_init_cmdline(); + + /* 32 MB upgradable */ + add_memory_region(0, 32 << 20, BOOT_MEM_RAM); +} diff --git a/trunk/arch/mips/galileo-boards/ev96100/irq.c b/trunk/arch/mips/galileo-boards/ev96100/irq.c new file mode 100644 index 000000000000..ee5d6720f23b --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/irq.c @@ -0,0 +1,77 @@ +/* + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/atlas/atlas_int.c. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static inline unsigned int ffz8(unsigned int word) +{ + unsigned long k; + + k = 7; + if (word & 0x0fUL) { k -= 4; word <<= 4; } + if (word & 0x30UL) { k -= 2; word <<= 2; } + if (word & 0x40UL) { k -= 1; } + + return k; +} + +extern void mips_timer_interrupt(struct pt_regs *regs); + +asmlinkage void ev96100_cpu_irq(unsigned int pending, struct pt_regs *regs) +{ + do_IRQ(ffz8(pending >> 8), regs); +} + +asmlinkage void plat_irq_dispatch(struct pt_regs *regs) +{ + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; + + if (pending & CAUSEF_IP7) + mips_timer_interrupt(regs); + else if (pending) + ev96100_cpu_irq(pending, regs); + else + spurious_interrupt(regs); +} + +void __init arch_init_irq(void) +{ + mips_cpu_irq_init(0); +} diff --git a/trunk/arch/mips/galileo-boards/ev96100/puts.c b/trunk/arch/mips/galileo-boards/ev96100/puts.c new file mode 100644 index 000000000000..49dc6d137b9c --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/puts.c @@ -0,0 +1,138 @@ + +/* + * Debug routines which directly access the uart. + */ + +#include +#include + + +//#define SERIAL_BASE EV96100_UART0_REGS_BASE +#define SERIAL_BASE 0xBD000020 +#define NS16550_BASE SERIAL_BASE + +#define SERA_CMD 0x0D +#define SERA_DATA 0x08 +//#define SERB_CMD 0x05 +#define SERB_CMD 20 +#define SERB_DATA 0x00 +#define TX_BUSY 0x20 + +#define TIMEOUT 0xffff +#undef SLOW_DOWN + +static const char digits[16] = "0123456789abcdef"; +static volatile unsigned char *const com1 = (unsigned char *) SERIAL_BASE; + + +#ifdef SLOW_DOWN +static inline void slow_down() +{ + int k; + for (k = 0; k < 10000; k++); +} +#else +#define slow_down() +#endif + +void putch(const unsigned char c) +{ + unsigned char ch; + int i = 0; + + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = c; +} + +void putchar(const unsigned char c) +{ + unsigned char ch; + int i = 0; + + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = c; +} + +void puts(unsigned char *cp) +{ + unsigned char ch; + int i = 0; + + while (*cp) { + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = *cp++; + } + putch('\r'); + putch('\n'); +} + +void fputs(unsigned char *cp) +{ + unsigned char ch; + int i = 0; + + while (*cp) { + + do { + ch = com1[SERB_CMD]; + slow_down(); + i++; + if (i > TIMEOUT) { + break; + } + } while (0 == (ch & TX_BUSY)); + com1[SERB_DATA] = *cp++; + } +} + + +void put64(uint64_t ul) +{ + int cnt; + unsigned ch; + + cnt = 16; /* 16 nibbles in a 64 bit long */ + putch('0'); + putch('x'); + do { + cnt--; + ch = (unsigned char) (ul >> cnt * 4) & 0x0F; + putch(digits[ch]); + } while (cnt > 0); +} + +void put32(unsigned u) +{ + int cnt; + unsigned ch; + + cnt = 8; /* 8 nibbles in a 32 bit long */ + putch('0'); + putch('x'); + do { + cnt--; + ch = (unsigned char) (u >> cnt * 4) & 0x0F; + putch(digits[ch]); + } while (cnt > 0); +} diff --git a/trunk/arch/mips/galileo-boards/ev96100/reset.c b/trunk/arch/mips/galileo-boards/ev96100/reset.c new file mode 100644 index 000000000000..5ef9b7f896e6 --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/reset.c @@ -0,0 +1,70 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 reset routines. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/generic/reset.c + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +static void mips_machine_restart(char *command); +static void mips_machine_halt(void); + +static void mips_machine_restart(char *command) +{ + set_c0_status(ST0_BEV | ST0_ERL); + change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); + flush_cache_all(); + write_c0_wired(0); + __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000)); + while (1); +} + +static void mips_machine_halt(void) +{ + printk(KERN_NOTICE "You can safely turn off the power\n"); + while (1) + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); +} + +void mips_reboot_setup(void) +{ + _machine_restart = mips_machine_restart; + _machine_halt = mips_machine_halt; +} diff --git a/trunk/arch/mips/galileo-boards/ev96100/setup.c b/trunk/arch/mips/galileo-boards/ev96100/setup.c new file mode 100644 index 000000000000..639ad5562c63 --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/setup.c @@ -0,0 +1,159 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 setup. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/atlas/atlas_setup.c. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +extern char *__init prom_getcmdline(void); + +extern void mips_reboot_setup(void); + +unsigned char mac_0_1[12]; + +void __init plat_mem_setup(void) +{ + unsigned int config = read_c0_config(); + unsigned int status = read_c0_status(); + unsigned int info = read_c0_info(); + u32 tmp; + + char *argptr; + + clear_c0_status(ST0_FR); + + if (config & 0x8) + printk("Secondary cache is enabled\n"); + else + printk("Secondary cache is disabled\n"); + + if (status & (1 << 27)) + printk("User-mode cache ops enabled\n"); + else + printk("User-mode cache ops disabled\n"); + + printk("CP0 info reg: %x\n", (unsigned) info); + if (info & (1 << 28)) + printk("burst mode Scache RAMS\n"); + else + printk("pipelined Scache RAMS\n"); + + if (info & 0x1) + printk("Atomic Enable is set\n"); + + argptr = prom_getcmdline(); +#ifdef CONFIG_SERIAL_CONSOLE + if (strstr(argptr, "console=") == NULL) { + argptr = prom_getcmdline(); + strcat(argptr, " console=ttyS0,115200"); + } +#endif + + mips_reboot_setup(); + + set_io_port_base(KSEG1); + ioport_resource.start = GT_PCI_IO_BASE; + ioport_resource.end = GT_PCI_IO_BASE + 0x01ffffff; + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); +#endif + + + /* + * Setup GT controller master bit so we can do config cycles + */ + + /* Clear cause register bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + udelay(2); + tmp = GT_READ(GT_PCI0_CFGDATA_OFS); + + tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SERR); + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + udelay(2); + GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp); + + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + udelay(2); + tmp = GT_READ(GT_PCI0_CFGDATA_OFS); +} + +unsigned short get_gt_devid(void) +{ + u32 gt_devid; + + /* Figure out if this is a gt96100 or gt96100A */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((PCI_VENDOR_ID / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + + udelay(4); + gt_devid = GT_READ(GT_PCI0_CFGDATA_OFS); + + return gt_devid >> 16; +} diff --git a/trunk/arch/mips/galileo-boards/ev96100/time.c b/trunk/arch/mips/galileo-boards/ev96100/time.c new file mode 100644 index 000000000000..8cbe8426491a --- /dev/null +++ b/trunk/arch/mips/galileo-boards/ev96100/time.c @@ -0,0 +1,88 @@ +/* + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 rtc routines. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/atlas/atlas_rtc.c. + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) + +extern volatile unsigned long wall_jiffies; +unsigned long missed_heart_beats = 0; + +static unsigned long r4k_offset; /* Amount to increment compare reg each time */ +static unsigned long r4k_cur; /* What counter should be at next timer irq */ + +static inline void ack_r4ktimer(unsigned long newval) +{ + write_c0_compare(newval); +} + +/* + * There are a lot of conceptually broken versions of the MIPS timer interrupt + * handler floating around. This one is rather different, but the algorithm + * is probably more robust. + */ +void mips_timer_interrupt(struct pt_regs *regs) +{ + int irq = 7; /* FIX ME */ + + if (r4k_offset == 0) { + goto null; + } + + do { + kstat_this_cpu.irqs[irq]++; + do_timer(regs); +#ifndef CONFIG_SMP + update_process_times(user_mode(regs)); +#endif + r4k_cur += r4k_offset; + ack_r4ktimer(r4k_cur); + + } while (((unsigned long)read_c0_count() + - r4k_cur) < 0x7fffffff); + return; + +null: + ack_r4ktimer(0); +} diff --git a/trunk/arch/mips/gt64120/common/time.c b/trunk/arch/mips/gt64120/common/time.c index 7feca49350d1..d837b26fbe51 100644 --- a/trunk/arch/mips/gt64120/common/time.c +++ b/trunk/arch/mips/gt64120/common/time.c @@ -34,7 +34,7 @@ static void gt64120_irq(int irq, void *dev_id, struct pt_regs *regs) if (irq_src & 0x00000800) { /* Check for timer interrupt */ handled = 1; irq_src &= ~0x00000800; - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif diff --git a/trunk/arch/mips/kernel/Makefile b/trunk/arch/mips/kernel/Makefile index cd9cec9e39e9..881c467c6982 100644 --- a/trunk/arch/mips/kernel/Makefile +++ b/trunk/arch/mips/kernel/Makefile @@ -11,7 +11,6 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ irix5sys.o sysirix.o -obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_MODULES) += mips_ksyms.o module.o obj-$(CONFIG_APM) += apm.o diff --git a/trunk/arch/mips/kernel/cpu-probe.c b/trunk/arch/mips/kernel/cpu-probe.c index 9fbf8430c849..aa2caa67299a 100644 --- a/trunk/arch/mips/kernel/cpu-probe.c +++ b/trunk/arch/mips/kernel/cpu-probe.c @@ -38,40 +38,15 @@ static void r3081_wait(void) static void r39xx_wait(void) { - local_irq_disable(); - if (!need_resched()) - write_c0_conf(read_c0_conf() | TX39_CONF_HALT); - local_irq_enable(); + unsigned long cfg = read_c0_conf(); + write_c0_conf(cfg | TX39_CONF_HALT); } -/* - * There is a race when WAIT instruction executed with interrupt - * enabled. - * But it is implementation-dependent wheter the pipelie restarts when - * a non-enabled interrupt is requested. - */ static void r4k_wait(void) { - __asm__(" .set mips3 \n" - " wait \n" - " .set mips0 \n"); -} - -/* - * This variant is preferable as it allows testing need_resched and going to - * sleep depending on the outcome atomically. Unfortunately the "It is - * implementation-dependent whether the pipeline restarts when a non-enabled - * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes - * using this version a gamble. - */ -static void r4k_wait_irqoff(void) -{ - local_irq_disable(); - if (!need_resched()) - __asm__(" .set mips3 \n" - " wait \n" - " .set mips0 \n"); - local_irq_enable(); + __asm__(".set\tmips3\n\t" + "wait\n\t" + ".set\tmips0"); } /* The Au1xxx wait is available only if using 32khz counter or @@ -81,17 +56,17 @@ int allow_au1k_wait; static void au1k_wait(void) { /* using the wait instruction makes CP0 counter unusable */ - __asm__(" .set mips3 \n" - " cache 0x14, 0(%0) \n" - " cache 0x14, 32(%0) \n" - " sync \n" - " nop \n" - " wait \n" - " nop \n" - " nop \n" - " nop \n" - " nop \n" - " .set mips0 \n" + __asm__(".set mips3\n\t" + "cache 0x14, 0(%0)\n\t" + "cache 0x14, 32(%0)\n\t" + "sync\n\t" + "nop\n\t" + "wait\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + "nop\n\t" + ".set mips0\n\t" : : "r" (au1k_wait)); } @@ -136,6 +111,7 @@ static inline void check_wait(void) case CPU_NEVADA: case CPU_RM7000: case CPU_RM9000: + case CPU_TX49XX: case CPU_4KC: case CPU_4KEC: case CPU_4KSC: @@ -149,10 +125,6 @@ static inline void check_wait(void) cpu_wait = r4k_wait; printk(" available.\n"); break; - case CPU_TX49XX: - cpu_wait = r4k_wait_irqoff; - printk(" available.\n"); - break; case CPU_AU1000: case CPU_AU1100: case CPU_AU1500: diff --git a/trunk/arch/mips/kernel/genex.S b/trunk/arch/mips/kernel/genex.S index af6ef2fd8300..37fda3dcdfc5 100644 --- a/trunk/arch/mips/kernel/genex.S +++ b/trunk/arch/mips/kernel/genex.S @@ -220,8 +220,8 @@ NESTED(except_vec_vi_handler, 0, sp) CLI TRACE_IRQS_OFF move a0, sp - PTR_LA ra, ret_from_irq - jr v0 + jalr v0 + j ret_from_irq END(except_vec_vi_handler) /* @@ -349,8 +349,8 @@ NESTED(nmi_handler, PT_SIZE, sp) .set at __BUILD_\verbose \exception move a0, sp - PTR_LA ra, ret_from_exception - j do_\handler + jal do_\handler + j ret_from_exception END(handle_\exception) .endm diff --git a/trunk/arch/mips/kernel/i8259.c b/trunk/arch/mips/kernel/i8259.c index 48e3418c217b..ea36c8e8852c 100644 --- a/trunk/arch/mips/kernel/i8259.c +++ b/trunk/arch/mips/kernel/i8259.c @@ -302,11 +302,11 @@ static struct irqaction irq2 = { }; static struct resource pic1_io_resource = { - .name = "pic1", .start = 0x20, .end = 0x21, .flags = IORESOURCE_BUSY + .name = "pic1", .start = 0x20, .end = 0x3f, .flags = IORESOURCE_BUSY }; static struct resource pic2_io_resource = { - .name = "pic2", .start = 0xa0, .end = 0xa1, .flags = IORESOURCE_BUSY + .name = "pic2", .start = 0xa0, .end = 0xbf, .flags = IORESOURCE_BUSY }; /* diff --git a/trunk/arch/mips/kernel/irixsig.c b/trunk/arch/mips/kernel/irixsig.c index 2132485caa74..676e868d26fb 100644 --- a/trunk/arch/mips/kernel/irixsig.c +++ b/trunk/arch/mips/kernel/irixsig.c @@ -17,7 +17,6 @@ #include #include -#include #undef DEBUG_SIG @@ -173,12 +172,11 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info, return ret; } -void do_irix_signal(struct pt_regs *regs) +asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) { struct k_sigaction ka; siginfo_t info; int signr; - sigset_t *oldset; /* * We want the common case to go fast, which is why we may in certain @@ -186,28 +184,19 @@ void do_irix_signal(struct pt_regs *regs) * if so. */ if (!user_mode(regs)) - return; + return 1; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else + if (try_to_freeze()) + goto no_signal; + + if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); - if (signr > 0) { - /* Whee! Actually deliver the signal. */ - if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - } - - return; - } + if (signr > 0) + return handle_signal(signr, &info, &ka, oldset, regs); +no_signal: /* * Who's code doesn't conform to the restartable syscall convention * dies here!!! The li instruction, a single machine instruction, @@ -219,22 +208,8 @@ void do_irix_signal(struct pt_regs *regs) regs->regs[2] == ERESTARTNOINTR) { regs->cp0_epc -= 8; } - if (regs->regs[2] == ERESTART_RESTARTBLOCK) { - regs->regs[2] = __NR_restart_syscall; - regs->regs[7] = regs->regs[26]; - regs->cp0_epc -= 4; - } - regs->regs[0] = 0; /* Don't deal with this again. */ - } - - /* - * If there's no signal to deliver, we just put the saved sigmask - * back - */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } + return 0; } asmlinkage void @@ -323,9 +298,6 @@ struct sigact_irix5 { int _unused0[2]; }; -#define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility: - set only the low 32 bit of the sigset. */ - #ifdef DEBUG_SIG static inline void dump_sigact_irix5(struct sigact_irix5 *p) { @@ -441,7 +413,7 @@ asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new, asmlinkage int irix_sigsuspend(struct pt_regs *regs) { - sigset_t newset; + sigset_t saveset, newset; sigset_t __user *uset; uset = (sigset_t __user *) regs->regs[4]; @@ -450,15 +422,18 @@ asmlinkage int irix_sigsuspend(struct pt_regs *regs) sigdelsetmask(&newset, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); - current->saved_sigmask = current->blocked; + saveset = current->blocked; current->blocked = newset; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - current->state = TASK_INTERRUPTIBLE; - schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); - return -ERESTARTNOHAND; + regs->regs[2] = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_irix_signal(&saveset, regs)) + return -EINTR; + } } /* hate hate hate... */ diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c index 52cada45b353..450ac592da57 100644 --- a/trunk/arch/mips/kernel/linux32.c +++ b/trunk/arch/mips/kernel/linux32.c @@ -991,7 +991,7 @@ struct sysctl_args32 unsigned int __unused[4]; }; -#ifdef CONFIG_SYSCTL_SYSCALL +#ifdef CONFIG_SYSCTL asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args) { @@ -1032,14 +1032,14 @@ asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args) return error; } -#endif /* CONFIG_SYSCTL_SYSCALL */ +#endif /* CONFIG_SYSCTL */ asmlinkage long sys32_newuname(struct new_utsname __user * name) { int ret = 0; down_read(&uts_sem); - if (copy_to_user(name, utsname(), sizeof *name)) + if (copy_to_user(name,&system_utsname,sizeof *name)) ret = -EFAULT; up_read(&uts_sem); @@ -1296,3 +1296,9 @@ _sys32_clone(nabi_no_regargs struct pt_regs regs) return do_fork(clone_flags, newsp, ®s, 0, parent_tidptr, child_tidptr); } + +extern asmlinkage void sys_set_thread_area(u32 addr); +asmlinkage void sys32_set_thread_area(u32 addr) +{ + sys_set_thread_area(AA(addr)); +} diff --git a/trunk/arch/mips/kernel/process.c b/trunk/arch/mips/kernel/process.c index 045d987bc683..7ab67f786bfe 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -40,7 +40,6 @@ #include #include #include -#include #ifdef CONFIG_MIPS_MT_SMTC #include extern void smtc_idle_loop_hook(void); @@ -274,107 +273,104 @@ long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } -/* - * - */ -struct mips_frame_info { - void *func; - unsigned long func_size; - int frame_size; - int pc_offset; -}; - -static inline int is_ra_save_ins(union mips_instruction *ip) -{ - /* sw / sd $ra, offset($sp) */ - return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) && - ip->i_format.rs == 29 && - ip->i_format.rt == 31; -} - -static inline int is_jal_jalr_jr_ins(union mips_instruction *ip) -{ - if (ip->j_format.opcode == jal_op) - return 1; - if (ip->r_format.opcode != spec_op) - return 0; - return ip->r_format.func == jalr_op || ip->r_format.func == jr_op; -} - -static inline int is_sp_move_ins(union mips_instruction *ip) -{ - /* addiu/daddiu sp,sp,-imm */ - if (ip->i_format.rs != 29 || ip->i_format.rt != 29) - return 0; - if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op) - return 1; - return 0; -} +static struct mips_frame_info { + void *func; + unsigned long func_size; + int frame_size; + int pc_offset; +} *schedule_frame, mfinfo[64]; +static int mfinfo_num; -static int get_frame_info(struct mips_frame_info *info) +static int __init get_frame_info(struct mips_frame_info *info) { - union mips_instruction *ip = info->func; - unsigned max_insns = info->func_size / sizeof(union mips_instruction); - unsigned i; - + int i; + void *func = info->func; + union mips_instruction *ip = (union mips_instruction *)func; info->pc_offset = -1; info->frame_size = 0; + for (i = 0; i < 128; i++, ip++) { + /* if jal, jalr, jr, stop. */ + if (ip->j_format.opcode == jal_op || + (ip->r_format.opcode == spec_op && + (ip->r_format.func == jalr_op || + ip->r_format.func == jr_op))) + break; - if (!ip) - goto err; - - if (max_insns == 0) - max_insns = 128U; /* unknown function size */ - max_insns = min(128U, max_insns); - - for (i = 0; i < max_insns; i++, ip++) { - - if (is_jal_jalr_jr_ins(ip)) + if (info->func_size && i >= info->func_size / 4) break; - if (!info->frame_size) { - if (is_sp_move_ins(ip)) - info->frame_size = - ip->i_format.simmediate; - continue; + if ( +#ifdef CONFIG_32BIT + ip->i_format.opcode == addiu_op && +#endif +#ifdef CONFIG_64BIT + ip->i_format.opcode == daddiu_op && +#endif + ip->i_format.rs == 29 && + ip->i_format.rt == 29) { + /* addiu/daddiu sp,sp,-imm */ + if (info->frame_size) + continue; + info->frame_size = - ip->i_format.simmediate; } - if (info->pc_offset == -1 && is_ra_save_ins(ip)) { + + if ( +#ifdef CONFIG_32BIT + ip->i_format.opcode == sw_op && +#endif +#ifdef CONFIG_64BIT + ip->i_format.opcode == sd_op && +#endif + ip->i_format.rs == 29 && + ip->i_format.rt == 31) { + /* sw / sd $ra, offset($sp) */ + if (info->pc_offset != -1) + continue; info->pc_offset = ip->i_format.simmediate / sizeof(long); - break; } } - if (info->frame_size && info->pc_offset >= 0) /* nested */ - return 0; - if (info->pc_offset < 0) /* leaf */ - return 1; - /* prologue seems boggus... */ -err: - return -1; -} + if (info->pc_offset == -1 || info->frame_size == 0) { + if (func == schedule) + printk("Can't analyze prologue code at %p\n", func); + info->pc_offset = -1; + info->frame_size = 0; + } -static struct mips_frame_info schedule_mfi __read_mostly; + return 0; +} static int __init frame_info_init(void) { - unsigned long size = 0; + int i; #ifdef CONFIG_KALLSYMS - unsigned long ofs; char *modname; char namebuf[KSYM_NAME_LEN + 1]; - - kallsyms_lookup((unsigned long)schedule, &size, &ofs, &modname, namebuf); + unsigned long start, size, ofs; + extern char __sched_text_start[], __sched_text_end[]; + extern char __lock_text_start[], __lock_text_end[]; + + start = (unsigned long)__sched_text_start; + for (i = 0; i < ARRAY_SIZE(mfinfo); i++) { + if (start == (unsigned long)schedule) + schedule_frame = &mfinfo[i]; + if (!kallsyms_lookup(start, &size, &ofs, &modname, namebuf)) + break; + mfinfo[i].func = (void *)(start + ofs); + mfinfo[i].func_size = size; + start += size - ofs; + if (start >= (unsigned long)__lock_text_end) + break; + if (start == (unsigned long)__sched_text_end) + start = (unsigned long)__lock_text_start; + } +#else + mfinfo[0].func = schedule; + schedule_frame = &mfinfo[0]; #endif - schedule_mfi.func = schedule; - schedule_mfi.func_size = size; - - get_frame_info(&schedule_mfi); - - /* - * Without schedule() frame info, result given by - * thread_saved_pc() and get_wchan() are not reliable. - */ - if (schedule_mfi.pc_offset < 0) - printk("Can't analyze schedule() prologue at %p\n", schedule); + for (i = 0; i < ARRAY_SIZE(mfinfo) && mfinfo[i].func; i++) + get_frame_info(&mfinfo[i]); + mfinfo_num = i; return 0; } @@ -390,112 +386,54 @@ unsigned long thread_saved_pc(struct task_struct *tsk) /* New born processes are a special case */ if (t->reg31 == (unsigned long) ret_from_fork) return t->reg31; - if (schedule_mfi.pc_offset < 0) + + if (!schedule_frame || schedule_frame->pc_offset < 0) return 0; - return ((unsigned long *)t->reg29)[schedule_mfi.pc_offset]; + return ((unsigned long *)t->reg29)[schedule_frame->pc_offset]; } - -#ifdef CONFIG_KALLSYMS -/* used by show_backtrace() */ -unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, - unsigned long pc, unsigned long *ra) +/* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ +unsigned long get_wchan(struct task_struct *p) { unsigned long stack_page; - struct mips_frame_info info; - char *modname; - char namebuf[KSYM_NAME_LEN + 1]; - unsigned long size, ofs; - int leaf; - extern void ret_from_irq(void); - extern void ret_from_exception(void); - - stack_page = (unsigned long)task_stack_page(task); - if (!stack_page) - return 0; - - /* - * If we reached the bottom of interrupt context, - * return saved pc in pt_regs. - */ - if (pc == (unsigned long)ret_from_irq || - pc == (unsigned long)ret_from_exception) { - struct pt_regs *regs; - if (*sp >= stack_page && - *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) { - regs = (struct pt_regs *)*sp; - pc = regs->cp0_epc; - if (__kernel_text_address(pc)) { - *sp = regs->regs[29]; - *ra = regs->regs[31]; - return pc; - } - } - return 0; - } - if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf)) - return 0; - /* - * Return ra if an exception occured at the first instruction - */ - if (unlikely(ofs == 0)) { - pc = *ra; - *ra = 0; - return pc; - } + unsigned long pc; +#ifdef CONFIG_KALLSYMS + unsigned long frame; +#endif - info.func = (void *)(pc - ofs); - info.func_size = ofs; /* analyze from start to ofs */ - leaf = get_frame_info(&info); - if (leaf < 0) + if (!p || p == current || p->state == TASK_RUNNING) return 0; - if (*sp < stack_page || - *sp + info.frame_size > stack_page + THREAD_SIZE - 32) + stack_page = (unsigned long)task_stack_page(p); + if (!stack_page || !mfinfo_num) return 0; - if (leaf) - /* - * For some extreme cases, get_frame_info() can - * consider wrongly a nested function as a leaf - * one. In that cases avoid to return always the - * same value. - */ - pc = pc != *ra ? *ra : 0; - else - pc = ((unsigned long *)(*sp))[info.pc_offset]; - - *sp += info.frame_size; - *ra = 0; - return __kernel_text_address(pc) ? pc : 0; -} -#endif - -/* - * get_wchan - a maintenance nightmare^W^Wpain in the ass ... - */ -unsigned long get_wchan(struct task_struct *task) -{ - unsigned long pc = 0; + pc = thread_saved_pc(p); #ifdef CONFIG_KALLSYMS - unsigned long sp; - unsigned long ra = 0; -#endif + if (!in_sched_functions(pc)) + return pc; - if (!task || task == current || task->state == TASK_RUNNING) - goto out; - if (!task_stack_page(task)) - goto out; + frame = p->thread.reg29 + schedule_frame->frame_size; + do { + int i; - pc = thread_saved_pc(task); + if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32) + return 0; -#ifdef CONFIG_KALLSYMS - sp = task->thread.reg29 + schedule_mfi.frame_size; + for (i = mfinfo_num - 1; i >= 0; i--) { + if (pc >= (unsigned long) mfinfo[i].func) + break; + } + if (i < 0) + break; - while (in_sched_functions(pc)) - pc = unwind_stack(task, &sp, pc, &ra); + pc = ((unsigned long *)frame)[mfinfo[i].pc_offset]; + if (!mfinfo[i].frame_size) + break; + frame += mfinfo[i].frame_size; + } while (in_sched_functions(pc)); #endif -out: return pc; } + diff --git a/trunk/arch/mips/kernel/scall32-o32.S b/trunk/arch/mips/kernel/scall32-o32.S index 61362e6fa9ec..ba1bcd83c7d3 100644 --- a/trunk/arch/mips/kernel/scall32-o32.S +++ b/trunk/arch/mips/kernel/scall32-o32.S @@ -28,7 +28,18 @@ NESTED(handle_sys, PT_SIZE, sp) .set noat SAVE_SOME - TRACE_IRQS_ON_RELOAD +#ifdef CONFIG_TRACE_IRQFLAGS + TRACE_IRQS_ON +#ifdef CONFIG_64BIT + LONG_L $8, PT_R8(sp) + LONG_L $9, PT_R9(sp) +#endif + LONG_L $7, PT_R7(sp) + LONG_L $6, PT_R6(sp) + LONG_L $5, PT_R5(sp) + LONG_L $4, PT_R4(sp) + LONG_L $2, PT_R2(sp) +#endif STI .set at @@ -651,8 +662,6 @@ einval: li v0, -EINVAL sys sys_tee 4 sys sys_vmsplice 4 sys sys_move_pages 6 - sys sys_set_robust_list 2 - sys sys_get_robust_list 3 .endm /* We pre-compute the number of _instruction_ bytes needed to diff --git a/trunk/arch/mips/kernel/scall64-64.S b/trunk/arch/mips/kernel/scall64-64.S index 6c7b5ed0ea6e..939e172db953 100644 --- a/trunk/arch/mips/kernel/scall64-64.S +++ b/trunk/arch/mips/kernel/scall64-64.S @@ -34,7 +34,7 @@ NESTED(handle_sys64, PT_SIZE, sp) */ .set noat SAVE_SOME - TRACE_IRQS_ON_RELOAD + TRACE_IRQS_ON STI .set at #endif @@ -466,5 +466,3 @@ sys_call_table: PTR sys_tee /* 5265 */ PTR sys_vmsplice PTR sys_move_pages - PTR sys_set_robust_list - PTR sys_get_robust_list diff --git a/trunk/arch/mips/kernel/scall64-n32.S b/trunk/arch/mips/kernel/scall64-n32.S index 6d9f18727ac5..98abbc5a9f13 100644 --- a/trunk/arch/mips/kernel/scall64-n32.S +++ b/trunk/arch/mips/kernel/scall64-n32.S @@ -33,7 +33,7 @@ NESTED(handle_sysn32, PT_SIZE, sp) #ifndef CONFIG_MIPS32_O32 .set noat SAVE_SOME - TRACE_IRQS_ON_RELOAD + TRACE_IRQS_ON STI .set at #endif @@ -247,7 +247,7 @@ EXPORT(sysn32_call_table) PTR sys_capset PTR sys32_rt_sigpending /* 6125 */ PTR compat_sys_rt_sigtimedwait - PTR sys32_rt_sigqueueinfo + PTR sys_rt_sigqueueinfo PTR sysn32_rt_sigsuspend PTR sys32_sigaltstack PTR compat_sys_utime /* 6130 */ @@ -390,7 +390,5 @@ EXPORT(sysn32_call_table) PTR sys_splice PTR sys_sync_file_range PTR sys_tee - PTR sys_vmsplice /* 6270 */ + PTR sys_vmsplice /* 6271 */ PTR sys_move_pages - PTR compat_sys_set_robust_list - PTR compat_sys_get_robust_list diff --git a/trunk/arch/mips/kernel/scall64-o32.S b/trunk/arch/mips/kernel/scall64-o32.S index 2e6d0673163e..505c9ee54009 100644 --- a/trunk/arch/mips/kernel/scall64-o32.S +++ b/trunk/arch/mips/kernel/scall64-o32.S @@ -28,7 +28,7 @@ NESTED(handle_sys, PT_SIZE, sp) .set noat SAVE_SOME - TRACE_IRQS_ON_RELOAD + TRACE_IRQS_ON STI .set at ld t1, PT_EPC(sp) # skip syscall on return @@ -498,7 +498,7 @@ sys_call_table: PTR sys_mknodat /* 4290 */ PTR sys_fchownat PTR compat_sys_futimesat - PTR sys_newfstatat + PTR compat_sys_newfstatat PTR sys_unlinkat PTR sys_renameat /* 4295 */ PTR sys_linkat @@ -514,6 +514,4 @@ sys_call_table: PTR sys_tee PTR sys_vmsplice PTR compat_sys_move_pages - PTR compat_sys_set_robust_list - PTR compat_sys_get_robust_list /* 4310 */ .size sys_call_table,.-sys_call_table diff --git a/trunk/arch/mips/kernel/setup.c b/trunk/arch/mips/kernel/setup.c index fdbb508661c5..8c2b596a136f 100644 --- a/trunk/arch/mips/kernel/setup.c +++ b/trunk/arch/mips/kernel/setup.c @@ -10,15 +10,29 @@ * Copyright (C) 1999 Silicon Graphics, Inc. * Copyright (C) 2000 2001, 2002 Maciej W. Rozycki */ +#include #include #include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include #include #include #include +#include #include #include @@ -82,12 +96,6 @@ void __init add_memory_region(phys_t start, phys_t size, long type) int x = boot_mem_map.nr_map; struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1; - /* Sanity check */ - if (start + size < start) { - printk("Trying to add an invalid memory region, skipped\n"); - return; - } - /* * Try to merge with previous entry if any. This is far less than * perfect but is sufficient for most real world cases. @@ -135,132 +143,167 @@ static void __init print_memory_map(void) } } -/* - * Manage initrd - */ -#ifdef CONFIG_BLK_DEV_INITRD - -static int __init rd_start_early(char *p) +static inline void parse_cmdline_early(void) { - unsigned long start = memparse(p, &p); - -#ifdef CONFIG_64BIT - /* HACK: Guess if the sign extension was forgotten */ - if (start > 0x0000000080000000 && start < 0x00000000ffffffff) - start |= 0xffffffff00000000UL; -#endif - initrd_start = start; - initrd_end += start; + char c = ' ', *to = command_line, *from = saved_command_line; + unsigned long start_at, mem_size; + int len = 0; + int usermem = 0; - return 0; -} -early_param("rd_start", rd_start_early); + printk("Determined physical RAM map:\n"); + print_memory_map(); -static int __init rd_size_early(char *p) -{ - initrd_end += memparse(p, &p); + for (;;) { + /* + * "mem=XXX[kKmM]" defines a memory region from + * 0 to , overriding the determined size. + * "mem=XXX[KkmM]@YYY[KkmM]" defines a memory region from + * to +, overriding the determined size. + */ + if (c == ' ' && !memcmp(from, "mem=", 4)) { + if (to != command_line) + to--; + /* + * If a user specifies memory size, we + * blow away any automatically generated + * size. + */ + if (usermem == 0) { + boot_mem_map.nr_map = 0; + usermem = 1; + } + mem_size = memparse(from + 4, &from); + if (*from == '@') + start_at = memparse(from + 1, &from); + else + start_at = 0; + add_memory_region(start_at, mem_size, BOOT_MEM_RAM); + } + c = *(from++); + if (!c) + break; + if (CL_SIZE <= ++len) + break; + *(to++) = c; + } + *to = '\0'; - return 0; + if (usermem) { + printk("User-defined physical RAM map:\n"); + print_memory_map(); + } } -early_param("rd_size", rd_size_early); -static unsigned long __init init_initrd(void) +static inline int parse_rd_cmdline(unsigned long* rd_start, unsigned long* rd_end) { - unsigned long tmp, end, size; - u32 *initrd_header; - - ROOT_DEV = Root_RAM0; - /* - * Board specific code or command line parser should have - * already set up initrd_start and initrd_end. In these cases - * perfom sanity checks and use them if all looks good. + * "rd_start=0xNNNNNNNN" defines the memory address of an initrd + * "rd_size=0xNN" it's size */ - size = initrd_end - initrd_start; - if (initrd_end == 0 || size == 0) { - initrd_start = 0; - initrd_end = 0; - } else - return initrd_end; - - end = (unsigned long)&_end; - tmp = PAGE_ALIGN(end) - sizeof(u32) * 2; - if (tmp < end) - tmp += PAGE_SIZE; - - initrd_header = (u32 *)tmp; - if (initrd_header[0] == 0x494E5244) { - initrd_start = (unsigned long)&initrd_header[2]; - initrd_end = initrd_start + initrd_header[1]; + unsigned long start = 0; + unsigned long size = 0; + unsigned long end; + char cmd_line[CL_SIZE]; + char *start_str; + char *size_str; + char *tmp; + + strcpy(cmd_line, command_line); + *command_line = 0; + tmp = cmd_line; + /* Ignore "rd_start=" strings in other parameters. */ + start_str = strstr(cmd_line, "rd_start="); + if (start_str && start_str != cmd_line && *(start_str - 1) != ' ') + start_str = strstr(start_str, " rd_start="); + while (start_str) { + if (start_str != cmd_line) + strncat(command_line, tmp, start_str - tmp); + start = memparse(start_str + 9, &start_str); + tmp = start_str + 1; + start_str = strstr(start_str, " rd_start="); } - return initrd_end; -} - -static void __init finalize_initrd(void) -{ - unsigned long size = initrd_end - initrd_start; - - if (size == 0) { - printk(KERN_INFO "Initrd not found or empty"); - goto disable; - } - if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { - printk("Initrd extends beyond end of memory"); - goto disable; + if (*tmp) + strcat(command_line, tmp); + + strcpy(cmd_line, command_line); + *command_line = 0; + tmp = cmd_line; + /* Ignore "rd_size" strings in other parameters. */ + size_str = strstr(cmd_line, "rd_size="); + if (size_str && size_str != cmd_line && *(size_str - 1) != ' ') + size_str = strstr(size_str, " rd_size="); + while (size_str) { + if (size_str != cmd_line) + strncat(command_line, tmp, size_str - tmp); + size = memparse(size_str + 8, &size_str); + tmp = size_str + 1; + size_str = strstr(size_str, " rd_size="); } + if (*tmp) + strcat(command_line, tmp); - reserve_bootmem(CPHYSADDR(initrd_start), size); - initrd_below_start_ok = 1; - - printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n", - initrd_start, size); - return; -disable: - printk(" - disabling initrd\n"); - initrd_start = 0; - initrd_end = 0; -} - -#else /* !CONFIG_BLK_DEV_INITRD */ - -#define init_initrd() 0 -#define finalize_initrd() do {} while (0) - +#ifdef CONFIG_64BIT + /* HACK: Guess if the sign extension was forgotten */ + if (start > 0x0000000080000000 && start < 0x00000000ffffffff) + start |= 0xffffffff00000000UL; #endif -/* - * Initialize the bootmem allocator. It also setup initrd related data - * if needed. - */ -#ifdef CONFIG_SGI_IP27 - -static void __init bootmem_init(void) -{ - init_initrd(); - finalize_initrd(); + end = start + size; + if (start && end) { + *rd_start = start; + *rd_end = end; + return 1; + } + return 0; } -#else /* !CONFIG_SGI_IP27 */ +#define MAXMEM HIGHMEM_START +#define MAXMEM_PFN PFN_DOWN(MAXMEM) -static void __init bootmem_init(void) +static inline void bootmem_init(void) { - unsigned long reserved_end; - unsigned long highest = 0; - unsigned long mapstart = -1UL; + unsigned long start_pfn; + unsigned long reserved_end = (unsigned long)&_end; +#ifndef CONFIG_SGI_IP27 + unsigned long first_usable_pfn; unsigned long bootmap_size; int i; +#endif +#ifdef CONFIG_BLK_DEV_INITRD + int initrd_reserve_bootmem = 0; + + /* Board specific code should have set up initrd_start and initrd_end */ + ROOT_DEV = Root_RAM0; + if (parse_rd_cmdline(&initrd_start, &initrd_end)) { + reserved_end = max(reserved_end, initrd_end); + initrd_reserve_bootmem = 1; + } else { + unsigned long tmp; + u32 *initrd_header; + + tmp = ((reserved_end + PAGE_SIZE-1) & PAGE_MASK) - sizeof(u32) * 2; + if (tmp < reserved_end) + tmp += PAGE_SIZE; + initrd_header = (u32 *)tmp; + if (initrd_header[0] == 0x494E5244) { + initrd_start = (unsigned long)&initrd_header[2]; + initrd_end = initrd_start + initrd_header[1]; + reserved_end = max(reserved_end, initrd_end); + initrd_reserve_bootmem = 1; + } + } +#endif /* CONFIG_BLK_DEV_INITRD */ /* - * Init any data related to initrd. It's a nop if INITRD is - * not selected. Once that done we can determine the low bound - * of usable memory. + * Partially used pages are not usable - thus + * we are rounding upwards. */ - reserved_end = init_initrd(); - reserved_end = PFN_UP(CPHYSADDR(max(reserved_end, (unsigned long)&_end))); + start_pfn = PFN_UP(CPHYSADDR(reserved_end)); - /* - * Find the highest page frame number we have available. - */ +#ifndef CONFIG_SGI_IP27 + /* Find the highest page frame number we have available. */ + max_pfn = 0; + first_usable_pfn = -1UL; for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end; @@ -269,38 +312,56 @@ static void __init bootmem_init(void) start = PFN_UP(boot_mem_map.map[i].addr); end = PFN_DOWN(boot_mem_map.map[i].addr - + boot_mem_map.map[i].size); + + boot_mem_map.map[i].size); - if (end > highest) - highest = end; - if (end <= reserved_end) - continue; - if (start >= mapstart) + if (start >= end) continue; - mapstart = max(reserved_end, start); + if (end > max_pfn) + max_pfn = end; + if (start < first_usable_pfn) { + if (start > start_pfn) { + first_usable_pfn = start; + } else if (end > start_pfn) { + first_usable_pfn = start_pfn; + } + } } /* * Determine low and high memory ranges */ - if (highest > PFN_DOWN(HIGHMEM_START)) { -#ifdef CONFIG_HIGHMEM - highstart_pfn = PFN_DOWN(HIGHMEM_START); - highend_pfn = highest; + max_low_pfn = max_pfn; + if (max_low_pfn > MAXMEM_PFN) { + max_low_pfn = MAXMEM_PFN; +#ifndef CONFIG_HIGHMEM + /* Maximum memory usable is what is directly addressable */ + printk(KERN_WARNING "Warning only %ldMB will be used.\n", + MAXMEM >> 20); + printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n"); #endif - highest = PFN_DOWN(HIGHMEM_START); } +#ifdef CONFIG_HIGHMEM /* - * Initialize the boot-time allocator with low memory only. + * Crude, we really should make a better attempt at detecting + * highstart_pfn */ - bootmap_size = init_bootmem(mapstart, highest); + highstart_pfn = highend_pfn = max_pfn; + if (max_pfn > MAXMEM_PFN) { + highstart_pfn = MAXMEM_PFN; + printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", + (highend_pfn - highstart_pfn) >> (20 - PAGE_SHIFT)); + } +#endif + + /* Initialize the boot-time allocator with low memory only. */ + bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn); /* * Register fully available low RAM pages with the bootmem allocator. */ for (i = 0; i < boot_mem_map.nr_map; i++) { - unsigned long start, end, size; + unsigned long curr_pfn, last_pfn, size; /* * Reserve usable memory. @@ -308,50 +369,85 @@ static void __init bootmem_init(void) if (boot_mem_map.map[i].type != BOOT_MEM_RAM) continue; - start = PFN_UP(boot_mem_map.map[i].addr); - end = PFN_DOWN(boot_mem_map.map[i].addr + /* + * We are rounding up the start address of usable memory: + */ + curr_pfn = PFN_UP(boot_mem_map.map[i].addr); + if (curr_pfn >= max_low_pfn) + continue; + if (curr_pfn < start_pfn) + curr_pfn = start_pfn; + + /* + * ... and at the end of the usable range downwards: + */ + last_pfn = PFN_DOWN(boot_mem_map.map[i].addr + boot_mem_map.map[i].size); + + if (last_pfn > max_low_pfn) + last_pfn = max_low_pfn; + /* - * We are rounding up the start address of usable memory - * and at the end of the usable range downwards. + * Only register lowmem part of lowmem segment with bootmem. */ - if (start >= max_low_pfn) + size = last_pfn - curr_pfn; + if (curr_pfn > PFN_DOWN(HIGHMEM_START)) + continue; + if (curr_pfn + size - 1 > PFN_DOWN(HIGHMEM_START)) + size = PFN_DOWN(HIGHMEM_START) - curr_pfn; + if (!size) continue; - if (start < reserved_end) - start = reserved_end; - if (end > max_low_pfn) - end = max_low_pfn; /* - * ... finally, is the area going away? + * ... finally, did all the rounding and playing + * around just make the area go away? */ - if (end <= start) + if (last_pfn <= curr_pfn) continue; - size = end - start; /* Register lowmem ranges */ - free_bootmem(PFN_PHYS(start), size << PAGE_SHIFT); - memory_present(0, start, end); + free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); + memory_present(0, curr_pfn, curr_pfn + size - 1); } - /* - * Reserve the bootmap memory. - */ - reserve_bootmem(PFN_PHYS(mapstart), bootmap_size); + /* Reserve the bootmap memory. */ + reserve_bootmem(PFN_PHYS(first_usable_pfn), bootmap_size); +#endif /* CONFIG_SGI_IP27 */ - /* - * Reserve initrd memory if needed. - */ - finalize_initrd(); -} +#ifdef CONFIG_BLK_DEV_INITRD + initrd_below_start_ok = 1; + if (initrd_start) { + unsigned long initrd_size = ((unsigned char *)initrd_end) - + ((unsigned char *)initrd_start); + const int width = sizeof(long) * 2; + + printk("Initial ramdisk at: 0x%p (%lu bytes)\n", + (void *)initrd_start, initrd_size); + + if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { + printk("initrd extends beyond end of memory " + "(0x%0*Lx > 0x%0*Lx)\ndisabling initrd\n", + width, + (unsigned long long) CPHYSADDR(initrd_end), + width, + (unsigned long long) PFN_PHYS(max_low_pfn)); + initrd_start = initrd_end = 0; + initrd_reserve_bootmem = 0; + } -#endif /* CONFIG_SGI_IP27 */ + if (initrd_reserve_bootmem) + reserve_bootmem(CPHYSADDR(initrd_start), initrd_size); + } +#endif /* CONFIG_BLK_DEV_INITRD */ +} /* * arch_mem_init - initialize memory managment subsystem * * o plat_mem_setup() detects the memory configuration and will record detected * memory areas using add_memory_region. + * o parse_cmdline_early() parses the command line for mem= options which, + * iff detected, will override the results of the automatic detection. * * At this stage the memory configuration of the system is known to the * kernel but generic memory managment system is still entirely uninitialized. @@ -369,59 +465,25 @@ static void __init bootmem_init(void) * initialization hook for anything else was introduced. */ -static int usermem __initdata = 0; - -static int __init early_parse_mem(char *p) -{ - unsigned long start, size; - - /* - * If a user specifies memory size, we - * blow away any automatically generated - * size. - */ - if (usermem == 0) { - boot_mem_map.nr_map = 0; - usermem = 1; - } - start = 0; - size = memparse(p, &p); - if (*p == '@') - start = memparse(p + 1, &p); - - add_memory_region(start, size, BOOT_MEM_RAM); - return 0; -} -early_param("mem", early_parse_mem); +extern void plat_mem_setup(void); static void __init arch_mem_init(char **cmdline_p) { - extern void plat_mem_setup(void); - /* call board setup routine */ plat_mem_setup(); - printk("Determined physical RAM map:\n"); - print_memory_map(); - strlcpy(command_line, arcs_cmdline, sizeof(command_line)); strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; - parse_early_param(); - - if (usermem) { - printk("User-defined physical RAM map:\n"); - print_memory_map(); - } - + parse_cmdline_early(); bootmem_init(); sparse_init(); paging_init(); } -static void __init resource_init(void) +static inline void resource_init(void) { int i; @@ -442,10 +504,10 @@ static void __init resource_init(void) start = boot_mem_map.map[i].addr; end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1; - if (start >= HIGHMEM_START) + if (start >= MAXMEM) continue; - if (end >= HIGHMEM_START) - end = HIGHMEM_START - 1; + if (end >= MAXMEM) + end = MAXMEM - 1; res = alloc_bootmem(sizeof(struct resource)); switch (boot_mem_map.map[i].type) { @@ -474,6 +536,9 @@ static void __init resource_init(void) } } +#undef MAXMEM +#undef MAXMEM_PFN + void __init setup_arch(char **cmdline_p) { cpu_probe(); diff --git a/trunk/arch/mips/kernel/signal.c b/trunk/arch/mips/kernel/signal.c index b9d358e05214..6b4d9be31615 100644 --- a/trunk/arch/mips/kernel/signal.c +++ b/trunk/arch/mips/kernel/signal.c @@ -424,11 +424,15 @@ void do_signal(struct pt_regs *regs) if (!user_mode(regs)) return; + if (try_to_freeze()) + goto no_signal; + if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else oldset = ¤t->blocked; + signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ @@ -442,10 +446,9 @@ void do_signal(struct pt_regs *regs) if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); } - - return; } +no_signal: /* * Who's code doesn't conform to the restartable syscall convention * dies here!!! The li instruction, a single machine instruction, @@ -463,7 +466,6 @@ void do_signal(struct pt_regs *regs) regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 4; } - regs->regs[0] = 0; /* Don't deal with this again. */ } /* diff --git a/trunk/arch/mips/kernel/signal32.c b/trunk/arch/mips/kernel/signal32.c index c86a5ddff050..f32a22997c3d 100644 --- a/trunk/arch/mips/kernel/signal32.c +++ b/trunk/arch/mips/kernel/signal32.c @@ -815,6 +815,9 @@ void do_signal32(struct pt_regs *regs) if (!user_mode(regs)) return; + if (try_to_freeze()) + goto no_signal; + if (test_thread_flag(TIF_RESTORE_SIGMASK)) oldset = ¤t->saved_sigmask; else @@ -833,10 +836,9 @@ void do_signal32(struct pt_regs *regs) if (test_thread_flag(TIF_RESTORE_SIGMASK)) clear_thread_flag(TIF_RESTORE_SIGMASK); } - - return; } +no_signal: /* * Who's code doesn't conform to the restartable syscall convention * dies here!!! The li instruction, a single machine instruction, @@ -854,7 +856,6 @@ void do_signal32(struct pt_regs *regs) regs->regs[7] = regs->regs[26]; regs->cp0_epc -= 4; } - regs->regs[0] = 0; /* Don't deal with this again. */ } /* diff --git a/trunk/arch/mips/kernel/smp-mt.c b/trunk/arch/mips/kernel/smp-mt.c index 766253c44f3f..93429a4d3012 100644 --- a/trunk/arch/mips/kernel/smp-mt.c +++ b/trunk/arch/mips/kernel/smp-mt.c @@ -203,7 +203,7 @@ void plat_smp_setup(void) write_vpe_c0_config( read_c0_config()); /* make sure there are no software interrupts pending */ - write_vpe_c0_cause(0); + write_vpe_c0_cause(read_vpe_c0_cause() & ~(C_SW1|C_SW0)); /* Propagate Config7 */ write_vpe_c0_config7(read_c0_config7()); diff --git a/trunk/arch/mips/kernel/smtc-asm.S b/trunk/arch/mips/kernel/smtc-asm.S index 76cb31d57482..4cc3dea36612 100644 --- a/trunk/arch/mips/kernel/smtc-asm.S +++ b/trunk/arch/mips/kernel/smtc-asm.S @@ -8,7 +8,7 @@ #include #include #include -#include +#include /* * "Software Interrupt" linkage. diff --git a/trunk/arch/mips/kernel/stacktrace.c b/trunk/arch/mips/kernel/stacktrace.c deleted file mode 100644 index 4aabe526a68e..000000000000 --- a/trunk/arch/mips/kernel/stacktrace.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * arch/mips/kernel/stacktrace.c - * - * Stack trace management functions - * - * Copyright (C) 2006 Atsushi Nemoto - */ -#include -#include -#include - -/* - * Save stack-backtrace addresses into a stack_trace buffer: - */ -static void save_raw_context_stack(struct stack_trace *trace, - unsigned long reg29) -{ - unsigned long *sp = (unsigned long *)reg29; - unsigned long addr; - - while (!kstack_end(sp)) { - addr = *sp++; - if (__kernel_text_address(addr)) { - if (trace->skip > 0) - trace->skip--; - else - trace->entries[trace->nr_entries++] = addr; - if (trace->nr_entries >= trace->max_entries) - break; - } - } -} - -static void save_context_stack(struct stack_trace *trace, - struct task_struct *task, struct pt_regs *regs) -{ - unsigned long sp = regs->regs[29]; -#ifdef CONFIG_KALLSYMS - unsigned long ra = regs->regs[31]; - unsigned long pc = regs->cp0_epc; - - if (raw_show_trace || !__kernel_text_address(pc)) { - unsigned long stack_page = - (unsigned long)task_stack_page(task); - if (stack_page && sp >= stack_page && - sp <= stack_page + THREAD_SIZE - 32) - save_raw_context_stack(trace, sp); - return; - } - do { - if (trace->skip > 0) - trace->skip--; - else - trace->entries[trace->nr_entries++] = pc; - if (trace->nr_entries >= trace->max_entries) - break; - pc = unwind_stack(task, &sp, pc, &ra); - } while (pc); -#else - save_raw_context_stack(sp); -#endif -} - -/* - * Save stack-backtrace addresses into a stack_trace buffer. - */ -void save_stack_trace(struct stack_trace *trace, struct task_struct *task) -{ - struct pt_regs dummyregs; - struct pt_regs *regs = &dummyregs; - - WARN_ON(trace->nr_entries || !trace->max_entries); - - if (task && task != current) { - regs->regs[29] = task->thread.reg29; - regs->regs[31] = 0; - regs->cp0_epc = task->thread.reg31; - } else { - if (!task) - task = current; - prepare_frametrace(regs); - } - - save_context_stack(trace, task, regs); -} diff --git a/trunk/arch/mips/kernel/syscall.c b/trunk/arch/mips/kernel/syscall.c index 26e1a7e78d13..0721314db657 100644 --- a/trunk/arch/mips/kernel/syscall.c +++ b/trunk/arch/mips/kernel/syscall.c @@ -231,7 +231,7 @@ asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs) */ asmlinkage int sys_uname(struct old_utsname __user * name) { - if (name && !copy_to_user(name, utsname(), sizeof (*name))) + if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) return 0; return -EFAULT; } @@ -248,27 +248,22 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name) if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; - error = __copy_to_user(&name->sysname, &utsname()->sysname, - __OLD_UTS_LEN); - error -= __put_user(0, name->sysname + __OLD_UTS_LEN); - error -= __copy_to_user(&name->nodename, &utsname()->nodename, - __OLD_UTS_LEN); - error -= __put_user(0, name->nodename + __OLD_UTS_LEN); - error -= __copy_to_user(&name->release, &utsname()->release, - __OLD_UTS_LEN); - error -= __put_user(0, name->release + __OLD_UTS_LEN); - error -= __copy_to_user(&name->version, &utsname()->version, - __OLD_UTS_LEN); - error -= __put_user(0, name->version + __OLD_UTS_LEN); - error -= __copy_to_user(&name->machine, &utsname()->machine, - __OLD_UTS_LEN); - error = __put_user(0, name->machine + __OLD_UTS_LEN); + error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); + error -= __put_user(0,name->sysname+__OLD_UTS_LEN); + error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); + error -= __put_user(0,name->nodename+__OLD_UTS_LEN); + error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); + error -= __put_user(0,name->release+__OLD_UTS_LEN); + error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); + error -= __put_user(0,name->version+__OLD_UTS_LEN); + error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); + error = __put_user(0,name->machine+__OLD_UTS_LEN); error = error ? -EFAULT : 0; return error; } -asmlinkage int sys_set_thread_area(unsigned long addr) +void sys_set_thread_area(unsigned long addr) { struct thread_info *ti = task_thread_info(current); @@ -276,8 +271,6 @@ asmlinkage int sys_set_thread_area(unsigned long addr) /* If some future MIPS implementation has this register in hardware, * we will need to update it here (and in context switches). */ - - return 0; } asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) @@ -406,32 +399,3 @@ asmlinkage void bad_stack(void) { do_exit(SIGSEGV); } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register unsigned long __a0 asm("$4") = (unsigned long) filename; - register unsigned long __a1 asm("$5") = (unsigned long) argv; - register unsigned long __a2 asm("$6") = (unsigned long) envp; - register unsigned long __a3 asm("$7"); - unsigned long __v0; - - __asm__ volatile (" \n" - " .set noreorder \n" - " li $2, %5 # __NR_execve \n" - " syscall \n" - " move %0, $2 \n" - " .set reorder \n" - : "=&r" (__v0), "=r" (__a3) - : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_execve) - : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", - "memory"); - - if (__a3 == 0) - return __v0; - - return -__v0; -} diff --git a/trunk/arch/mips/kernel/sysirix.c b/trunk/arch/mips/kernel/sysirix.c index 11bb97174972..1137dd6ea7aa 100644 --- a/trunk/arch/mips/kernel/sysirix.c +++ b/trunk/arch/mips/kernel/sysirix.c @@ -884,7 +884,7 @@ asmlinkage int irix_getdomainname(char __user *name, int len) down_read(&uts_sem); if (len > __NEW_UTS_LEN) len = __NEW_UTS_LEN; - err = copy_to_user(name, utsname()->domainname, len) ? -EFAULT : 0; + err = copy_to_user(name, system_utsname.domainname, len) ? -EFAULT : 0; up_read(&uts_sem); return err; @@ -1127,11 +1127,11 @@ struct iuname { asmlinkage int irix_uname(struct iuname __user *buf) { down_read(&uts_sem); - if (copy_from_user(utsname()->sysname, buf->sysname, 65) - || copy_from_user(utsname()->nodename, buf->nodename, 65) - || copy_from_user(utsname()->release, buf->release, 65) - || copy_from_user(utsname()->version, buf->version, 65) - || copy_from_user(utsname()->machine, buf->machine, 65)) { + if (copy_from_user(system_utsname.sysname, buf->sysname, 65) + || copy_from_user(system_utsname.nodename, buf->nodename, 65) + || copy_from_user(system_utsname.release, buf->release, 65) + || copy_from_user(system_utsname.version, buf->version, 65) + || copy_from_user(system_utsname.machine, buf->machine, 65)) { return -EFAULT; } up_read(&uts_sem); diff --git a/trunk/arch/mips/kernel/time.c b/trunk/arch/mips/kernel/time.c index 845c7e55505d..170cb67f4ede 100644 --- a/trunk/arch/mips/kernel/time.c +++ b/trunk/arch/mips/kernel/time.c @@ -47,6 +47,8 @@ /* * forward reference */ +extern volatile unsigned long wall_jiffies; + DEFINE_SPINLOCK(rtc_lock); /* @@ -157,6 +159,7 @@ void (*mips_hpt_init)(unsigned int); void do_gettimeofday(struct timeval *tv) { unsigned long seq; + unsigned long lost; unsigned long usec, sec; unsigned long max_ntp_tick; @@ -165,6 +168,8 @@ void do_gettimeofday(struct timeval *tv) usec = do_gettimeoffset(); + lost = jiffies - wall_jiffies; + /* * If time_adjust is negative then NTP is slowing the clock * so make sure not to go into next possible interval. @@ -173,7 +178,11 @@ void do_gettimeofday(struct timeval *tv) if (unlikely(time_adjust < 0)) { max_ntp_tick = (USEC_PER_SEC / HZ) - tickadj; usec = min(usec, max_ntp_tick); - } + + if (lost) + usec += lost * max_ntp_tick; + } else if (unlikely(lost)) + usec += lost * (USEC_PER_SEC / HZ); sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); @@ -208,6 +217,7 @@ int do_settimeofday(struct timespec *tv) * made, and then undo it! */ nsec -= do_gettimeoffset() * NSEC_PER_USEC; + nsec -= (jiffies - wall_jiffies) * tick_nsec; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -424,7 +434,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* * call the generic timer interrupt handling */ - do_timer(1); + do_timer(regs); /* * If we have an externally synchronized Linux clock, then update diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index b7292a56d4cd..954a198494ef 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -41,7 +40,6 @@ #include #include #include -#include extern asmlinkage void handle_int(void); extern asmlinkage void handle_tlbm(void); @@ -74,62 +72,28 @@ void (*board_nmi_handler_setup)(void); void (*board_ejtag_handler_setup)(void); void (*board_bind_eic_interrupt)(int irq, int regset); - -static void show_raw_backtrace(unsigned long reg29) -{ - unsigned long *sp = (unsigned long *)reg29; - unsigned long addr; - - printk("Call Trace:"); -#ifdef CONFIG_KALLSYMS - printk("\n"); -#endif - while (!kstack_end(sp)) { - addr = *sp++; - if (__kernel_text_address(addr)) - print_ip_sym(addr); - } - printk("\n"); -} - -#ifdef CONFIG_KALLSYMS -int raw_show_trace; -static int __init set_raw_show_trace(char *str) -{ - raw_show_trace = 1; - return 1; -} -__setup("raw_show_trace", set_raw_show_trace); -#endif - -static void show_backtrace(struct task_struct *task, struct pt_regs *regs) -{ - unsigned long sp = regs->regs[29]; - unsigned long ra = regs->regs[31]; - unsigned long pc = regs->cp0_epc; - - if (raw_show_trace || !__kernel_text_address(pc)) { - show_raw_backtrace(sp); - return; - } - printk("Call Trace:\n"); - do { - print_ip_sym(pc); - pc = unwind_stack(task, &sp, pc, &ra); - } while (pc); - printk("\n"); -} +/* + * These constant is for searching for possible module text segments. + * MODULE_RANGE is a guess of how much space is likely to be vmalloced. + */ +#define MODULE_RANGE (8*1024*1024) /* * This routine abuses get_user()/put_user() to reference pointers * with at least a bit of error checking ... */ -static void show_stacktrace(struct task_struct *task, struct pt_regs *regs) +void show_stack(struct task_struct *task, unsigned long *sp) { const int field = 2 * sizeof(unsigned long); long stackdata; int i; - unsigned long *sp = (unsigned long *)regs->regs[29]; + + if (!sp) { + if (task && task != current) + sp = (unsigned long *) task->thread.reg29; + else + sp = (unsigned long *) &sp; + } printk("Stack :"); i = 0; @@ -150,26 +114,32 @@ static void show_stacktrace(struct task_struct *task, struct pt_regs *regs) i++; } printk("\n"); - show_backtrace(task, regs); } -void show_stack(struct task_struct *task, unsigned long *sp) +void show_trace(struct task_struct *task, unsigned long *stack) { - struct pt_regs regs; - if (sp) { - regs.regs[29] = (unsigned long)sp; - regs.regs[31] = 0; - regs.cp0_epc = 0; - } else { - if (task && task != current) { - regs.regs[29] = task->thread.reg29; - regs.regs[31] = 0; - regs.cp0_epc = task->thread.reg31; - } else { - prepare_frametrace(®s); + const int field = 2 * sizeof(unsigned long); + unsigned long addr; + + if (!stack) { + if (task && task != current) + stack = (unsigned long *) task->thread.reg29; + else + stack = (unsigned long *) &stack; + } + + printk("Call Trace:"); +#ifdef CONFIG_KALLSYMS + printk("\n"); +#endif + while (!kstack_end(stack)) { + addr = *stack++; + if (__kernel_text_address(addr)) { + printk(" [<%0*lx>] ", field, addr); + print_symbol("%s\n", addr); } } - show_stacktrace(task, ®s); + printk("\n"); } /* @@ -177,10 +147,9 @@ void show_stack(struct task_struct *task, unsigned long *sp) */ void dump_stack(void) { - struct pt_regs regs; + unsigned long stack; - prepare_frametrace(®s); - show_backtrace(current, ®s); + show_trace(current, &stack); } EXPORT_SYMBOL(dump_stack); @@ -299,7 +268,8 @@ void show_registers(struct pt_regs *regs) print_modules(); printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n", current->comm, current->pid, current_thread_info(), current); - show_stacktrace(current, regs); + show_stack(current, (long *) regs->regs[29]); + show_trace(current, (long *) regs->regs[29]); show_code((unsigned int *) regs->cp0_epc); printk("\n"); } @@ -322,16 +292,6 @@ NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs) printk("%s[#%d]:\n", str, ++die_counter); show_registers(regs); spin_unlock_irq(&die_lock); - - if (in_interrupt()) - panic("Fatal exception in interrupt"); - - if (panic_on_oops) { - printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n"); - ssleep(5); - panic("Fatal exception"); - } - do_exit(SIGSEGV); } diff --git a/trunk/arch/mips/kernel/vpe.c b/trunk/arch/mips/kernel/vpe.c index 51ddd2166898..9ee0ec2cd067 100644 --- a/trunk/arch/mips/kernel/vpe.c +++ b/trunk/arch/mips/kernel/vpe.c @@ -768,16 +768,10 @@ int vpe_run(struct vpe * v) */ write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | v->minor); - write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~(VPECONF0_VPA)); - - back_to_back_c0_hazard(); - /* Set up the XTC bit in vpeconf0 to point at our tc */ write_vpe_c0_vpeconf0( (read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC)) | (t->index << VPECONF0_XTC_SHIFT)); - back_to_back_c0_hazard(); - /* enable this VPE */ write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA); diff --git a/trunk/arch/mips/mips-boards/atlas/atlas_int.c b/trunk/arch/mips/mips-boards/atlas/atlas_int.c index a020a3cb4f4b..fb25e0377f11 100644 --- a/trunk/arch/mips/mips-boards/atlas/atlas_int.c +++ b/trunk/arch/mips/mips-boards/atlas/atlas_int.c @@ -1,8 +1,6 @@ /* - * Copyright (C) 1999, 2000, 2006 MIPS Technologies, Inc. - * All rights reserved. - * Authors: Carsten Langgaard - * Maciej W. Rozycki + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. * * ######################################################################## * @@ -27,20 +25,17 @@ */ #include #include -#include #include #include #include #include -#include +#include #include -#include -#include - #include #include -#include +#include + static struct atlas_ictrl_regs *atlas_hw0_icregs; @@ -52,13 +47,13 @@ static struct atlas_ictrl_regs *atlas_hw0_icregs; void disable_atlas_irq(unsigned int irq_nr) { - atlas_hw0_icregs->intrsten = 1 << (irq_nr - ATLAS_INT_BASE); + atlas_hw0_icregs->intrsten = (1 << (irq_nr-ATLASINT_BASE)); iob(); } void enable_atlas_irq(unsigned int irq_nr) { - atlas_hw0_icregs->intseten = 1 << (irq_nr - ATLAS_INT_BASE); + atlas_hw0_icregs->intseten = (1 << (irq_nr-ATLASINT_BASE)); iob(); } @@ -112,7 +107,7 @@ static inline void atlas_hw0_irqdispatch(struct pt_regs *regs) if (unlikely(int_status == 0)) return; - irq = ATLAS_INT_BASE + ls1bit32(int_status); + irq = ATLASINT_BASE + ls1bit32(int_status); DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq); @@ -166,14 +161,15 @@ static inline unsigned int irq_ffs(unsigned int pending) } /* - * IRQs on the Atlas board look basically like (all external interrupt - * sources are combined together on hardware interrupt 0 (MIPS IRQ 2)): + * IRQs on the Atlas board look basically (barring software IRQs which we + * don't use at all and all external interrupt sources are combined together + * on hardware interrupt 0 (MIPS IRQ 2)) like: * - * MIPS IRQ Source + * MIPS IRQ Source * -------- ------ - * 0 Software 0 (reschedule IPI on MT) - * 1 Software 1 (remote call IPI on MT) - * 2 Combined Atlas hardware interrupt (hw0) + * 0 Software (ignored) + * 1 Software (ignored) + * 2 Combined hardware interrupt (hw0) * 3 Hardware (ignored) * 4 Hardware (ignored) * 5 Hardware (ignored) @@ -183,7 +179,7 @@ static inline unsigned int irq_ffs(unsigned int pending) * We handle the IRQ according to _our_ priority which is: * * Highest ---- R4k Timer - * Lowest ---- Software 0 + * Lowest ---- Combined hardware interrupt * * then we just return, if multiple IRQs are pending then we will just take * another exception, big deal. @@ -197,19 +193,17 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs) if (irq == MIPSCPU_INT_ATLAS) atlas_hw0_irqdispatch(regs); - else if (irq >= 0) + else if (irq > 0) do_IRQ(MIPSCPU_INT_BASE + irq, regs); else spurious_interrupt(regs); } -static inline void init_atlas_irqs (int base) +void __init arch_init_irq(void) { int i; - atlas_hw0_icregs = (struct atlas_ictrl_regs *) - ioremap(ATLAS_ICTRL_REGS_BASE, - sizeof(struct atlas_ictrl_regs *)); + atlas_hw0_icregs = (struct atlas_ictrl_regs *)ioremap (ATLAS_ICTRL_REGS_BASE, sizeof(struct atlas_ictrl_regs *)); /* * Mask out all interrupt by writing "1" to all bit position in @@ -217,7 +211,7 @@ static inline void init_atlas_irqs (int base) */ atlas_hw0_icregs->intrsten = 0xffffffff; - for (i = ATLAS_INT_BASE; i <= ATLAS_INT_END; i++) { + for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; @@ -225,62 +219,3 @@ static inline void init_atlas_irqs (int base) spin_lock_init(&irq_desc[i].lock); } } - -static struct irqaction atlasirq = { - .handler = no_action, - .name = "Atlas cascade" -}; - -msc_irqmap_t __initdata msc_irqmap[] = { - {MSC01C_INT_TMR, MSC01_IRQ_EDGE, 0}, - {MSC01C_INT_PCI, MSC01_IRQ_LEVEL, 0}, -}; -int __initdata msc_nr_irqs = sizeof(msc_irqmap) / sizeof(*msc_irqmap); - -msc_irqmap_t __initdata msc_eicirqmap[] = { - {MSC01E_INT_SW0, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_SW1, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_ATLAS, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_TMR, MSC01_IRQ_EDGE, 0}, - {MSC01E_INT_PCI, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_PERFCTR, MSC01_IRQ_LEVEL, 0}, - {MSC01E_INT_CPUCTR, MSC01_IRQ_LEVEL, 0} -}; -int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap) / sizeof(*msc_eicirqmap); - -void __init arch_init_irq(void) -{ - init_atlas_irqs(ATLAS_INT_BASE); - - if (!cpu_has_veic) - mips_cpu_irq_init(MIPSCPU_INT_BASE); - - switch(mips_revision_corid) { - case MIPS_REVISION_CORID_CORE_MSC: - case MIPS_REVISION_CORID_CORE_FPGA2: - case MIPS_REVISION_CORID_CORE_FPGA3: - case MIPS_REVISION_CORID_CORE_24K: - case MIPS_REVISION_CORID_CORE_EMUL_MSC: - if (cpu_has_veic) - init_msc_irqs (MSC01E_INT_BASE, - msc_eicirqmap, msc_nr_eicirqs); - else - init_msc_irqs (MSC01C_INT_BASE, - msc_irqmap, msc_nr_irqs); - } - - - if (cpu_has_veic) { - set_vi_handler (MSC01E_INT_ATLAS, atlas_hw0_irqdispatch); - setup_irq (MSC01E_INT_BASE + MSC01E_INT_ATLAS, &atlasirq); - } else if (cpu_has_vint) { - set_vi_handler (MIPSCPU_INT_ATLAS, atlas_hw0_irqdispatch); -#ifdef CONFIG_MIPS_MT_SMTC - setup_irq_smtc (MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, - &atlasirq, (0x100 << MIPSCPU_INT_ATLAS)); -#else /* Not SMTC */ - setup_irq(MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, &atlasirq); -#endif /* CONFIG_MIPS_MT_SMTC */ - } else - setup_irq(MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, &atlasirq); -} diff --git a/trunk/arch/mips/mips-boards/atlas/atlas_setup.c b/trunk/arch/mips/mips-boards/atlas/atlas_setup.c index 0c6b0ce15028..9871a91fdb07 100644 --- a/trunk/arch/mips/mips-boards/atlas/atlas_setup.c +++ b/trunk/arch/mips/mips-boards/atlas/atlas_setup.c @@ -77,7 +77,7 @@ static void __init serial_init(void) #else s.iobase = ATLAS_UART_REGS_BASE+3; #endif - s.irq = ATLAS_INT_UART; + s.irq = ATLASINT_UART; s.uartclk = ATLAS_BASE_BAUD * 16; s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; s.iotype = UPIO_PORT; diff --git a/trunk/arch/mips/mips-boards/generic/time.c b/trunk/arch/mips/mips-boards/generic/time.c index 8d15861fce61..557bf961f36a 100644 --- a/trunk/arch/mips/mips-boards/generic/time.c +++ b/trunk/arch/mips/mips-boards/generic/time.c @@ -41,13 +41,8 @@ #include #include - -#ifdef CONFIG_MIPS_ATLAS -#include -#endif -#ifdef CONFIG_MIPS_MALTA #include -#endif +#include unsigned long cpu_khz; @@ -97,9 +92,10 @@ extern int (*perf_irq)(struct pt_regs *regs); irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { int cpu = smp_processor_id(); + int r2 = cpu_has_mips_r2; #ifdef CONFIG_MIPS_MT_SMTC - /* + /* * In an SMTC system, one Count/Compare set exists per VPE. * Which TC within a VPE gets the interrupt is essentially * random - we only know that it shouldn't be one with @@ -112,46 +108,29 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * the general MIPS timer_interrupt routine. */ - int vpflags; - /* - * We could be here due to timer interrupt, - * perf counter overflow, or both. + * DVPE is necessary so long as cross-VPE interrupts + * are done via read-modify-write of Cause register. */ - if (read_c0_cause() & (1 << 26)) - perf_irq(regs); + int vpflags = dvpe(); + write_c0_compare (read_c0_count() - 1); + clear_c0_cause(CPUCTR_IMASKBIT); + evpe(vpflags); - if (read_c0_cause() & (1 << 30)) { - /* If timer interrupt, make it de-assert */ - write_c0_compare (read_c0_count() - 1); - /* - * DVPE is necessary so long as cross-VPE interrupts - * are done via read-modify-write of Cause register. - */ - vpflags = dvpe(); - clear_c0_cause(CPUCTR_IMASKBIT); - evpe(vpflags); + if (cpu_data[cpu].vpe_id == 0) { + timer_interrupt(irq, dev_id, regs); + scroll_display_message(); + } else + write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ)); + smtc_timer_broadcast(cpu_data[cpu].vpe_id); + + if (cpu != 0) /* - * There are things we only want to do once per tick - * in an "MP" system. One TC of each VPE will take - * the actual timer interrupt. The others will get - * timer broadcast IPIs. We use whoever it is that takes - * the tick on VPE 0 to run the full timer_interrupt(). + * Other CPUs should do profiling and process accounting */ - if (cpu_data[cpu].vpe_id == 0) { - timer_interrupt(irq, NULL, regs); - smtc_timer_broadcast(cpu_data[cpu].vpe_id); - scroll_display_message(); - } else { - write_c0_compare(read_c0_count() + - (mips_hpt_frequency/HZ)); - local_timer_interrupt(irq, dev_id, regs); - smtc_timer_broadcast(cpu_data[cpu].vpe_id); - } - } -#else /* CONFIG_MIPS_MT_SMTC */ - int r2 = cpu_has_mips_r2; + local_timer_interrupt(irq, dev_id, regs); +#else /* CONFIG_MIPS_MT_SMTC */ if (cpu == 0) { /* * CPU 0 handles the global timer interrupt job and process @@ -182,8 +161,9 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) */ local_timer_interrupt(irq, dev_id, regs); } -out: #endif /* CONFIG_MIPS_MT_SMTC */ + +out: return IRQ_HANDLED; } diff --git a/trunk/arch/mips/mm/c-r3k.c b/trunk/arch/mips/mm/c-r3k.c index d1af42c2a52e..bb041a22f20a 100644 --- a/trunk/arch/mips/mm/c-r3k.c +++ b/trunk/arch/mips/mm/c-r3k.c @@ -268,6 +268,26 @@ static void r3k_flush_data_cache_page(unsigned long addr) { } +static void r3k_flush_icache_page(struct vm_area_struct *vma, struct page *page) +{ + struct mm_struct *mm = vma->vm_mm; + unsigned long physpage; + + if (cpu_context(smp_processor_id(), mm) == 0) + return; + + if (!(vma->vm_flags & VM_EXEC)) + return; + +#ifdef DEBUG_CACHE + printk("cpage[%d,%08lx]", cpu_context(smp_processor_id(), mm), page); +#endif + + physpage = (unsigned long) page_address(page); + if (physpage) + r3k_flush_icache_range(physpage, physpage + PAGE_SIZE); +} + static void r3k_flush_cache_sigtramp(unsigned long addr) { unsigned long flags; @@ -315,6 +335,7 @@ void __init r3k_cache_init(void) flush_cache_mm = r3k_flush_cache_mm; flush_cache_range = r3k_flush_cache_range; flush_cache_page = r3k_flush_cache_page; + flush_icache_page = r3k_flush_icache_page; flush_icache_range = r3k_flush_icache_range; flush_cache_sigtramp = r3k_flush_cache_sigtramp; diff --git a/trunk/arch/mips/mm/c-r4k.c b/trunk/arch/mips/mm/c-r4k.c index cc895dad71d2..069803f58f3b 100644 --- a/trunk/arch/mips/mm/c-r4k.c +++ b/trunk/arch/mips/mm/c-r4k.c @@ -89,7 +89,7 @@ static inline void r4k_blast_dcache_page_dc32(unsigned long addr) blast_dcache32_page(addr); } -static void __init r4k_blast_dcache_page_setup(void) +static inline void r4k_blast_dcache_page_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); @@ -103,7 +103,7 @@ static void __init r4k_blast_dcache_page_setup(void) static void (* r4k_blast_dcache_page_indexed)(unsigned long addr); -static void __init r4k_blast_dcache_page_indexed_setup(void) +static inline void r4k_blast_dcache_page_indexed_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); @@ -117,7 +117,7 @@ static void __init r4k_blast_dcache_page_indexed_setup(void) static void (* r4k_blast_dcache)(void); -static void __init r4k_blast_dcache_setup(void) +static inline void r4k_blast_dcache_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); @@ -202,7 +202,7 @@ static inline void tx49_blast_icache32_page_indexed(unsigned long page) static void (* r4k_blast_icache_page)(unsigned long addr); -static void __init r4k_blast_icache_page_setup(void) +static inline void r4k_blast_icache_page_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); @@ -219,7 +219,7 @@ static void __init r4k_blast_icache_page_setup(void) static void (* r4k_blast_icache_page_indexed)(unsigned long addr); -static void __init r4k_blast_icache_page_indexed_setup(void) +static inline void r4k_blast_icache_page_indexed_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); @@ -243,7 +243,7 @@ static void __init r4k_blast_icache_page_indexed_setup(void) static void (* r4k_blast_icache)(void); -static void __init r4k_blast_icache_setup(void) +static inline void r4k_blast_icache_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); @@ -264,7 +264,7 @@ static void __init r4k_blast_icache_setup(void) static void (* r4k_blast_scache_page)(unsigned long addr); -static void __init r4k_blast_scache_page_setup(void) +static inline void r4k_blast_scache_page_setup(void) { unsigned long sc_lsize = cpu_scache_line_size(); @@ -282,7 +282,7 @@ static void __init r4k_blast_scache_page_setup(void) static void (* r4k_blast_scache_page_indexed)(unsigned long addr); -static void __init r4k_blast_scache_page_indexed_setup(void) +static inline void r4k_blast_scache_page_indexed_setup(void) { unsigned long sc_lsize = cpu_scache_line_size(); @@ -300,7 +300,7 @@ static void __init r4k_blast_scache_page_indexed_setup(void) static void (* r4k_blast_scache)(void); -static void __init r4k_blast_scache_setup(void) +static inline void r4k_blast_scache_setup(void) { unsigned long sc_lsize = cpu_scache_line_size(); @@ -475,7 +475,7 @@ static inline void local_r4k_flush_cache_page(void *args) } } if (exec) { - if (cpu_has_vtag_icache && mm == current->active_mm) { + if (cpu_has_vtag_icache) { int cpu = smp_processor_id(); if (cpu_context(cpu, mm) != 0) @@ -551,6 +551,82 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) instruction_hazard(); } +/* + * Ok, this seriously sucks. We use them to flush a user page but don't + * know the virtual address, so we have to blast away the whole icache + * which is significantly more expensive than the real thing. Otoh we at + * least know the kernel address of the page so we can flush it + * selectivly. + */ + +struct flush_icache_page_args { + struct vm_area_struct *vma; + struct page *page; +}; + +static inline void local_r4k_flush_icache_page(void *args) +{ + struct flush_icache_page_args *fip_args = args; + struct vm_area_struct *vma = fip_args->vma; + struct page *page = fip_args->page; + + /* + * Tricky ... Because we don't know the virtual address we've got the + * choice of either invalidating the entire primary and secondary + * caches or invalidating the secondary caches also. With the subset + * enforcment on R4000SC, R4400SC, R10000 and R12000 invalidating the + * secondary cache will result in any entries in the primary caches + * also getting invalidated which hopefully is a bit more economical. + */ + if (cpu_has_inclusive_pcaches) { + unsigned long addr = (unsigned long) page_address(page); + + r4k_blast_scache_page(addr); + ClearPageDcacheDirty(page); + + return; + } + + if (!cpu_has_ic_fills_f_dc) { + unsigned long addr = (unsigned long) page_address(page); + r4k_blast_dcache_page(addr); + if (!cpu_icache_snoops_remote_store) + r4k_blast_scache_page(addr); + ClearPageDcacheDirty(page); + } + + /* + * We're not sure of the virtual address(es) involved here, so + * we have to flush the entire I-cache. + */ + if (cpu_has_vtag_icache) { + int cpu = smp_processor_id(); + + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); + } else + r4k_blast_icache(); +} + +static void r4k_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + struct flush_icache_page_args args; + + /* + * If there's no context yet, or the page isn't executable, no I-cache + * flush is needed. + */ + if (!(vma->vm_flags & VM_EXEC)) + return; + + args.vma = vma; + args.page = page; + + r4k_on_each_cpu(local_r4k_flush_icache_page, &args, 1, 1); +} + + #ifdef CONFIG_DMA_NONCOHERENT static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) @@ -1145,7 +1221,7 @@ void au1x00_fixup_config_od(void) } } -static void __init coherency_setup(void) +static inline void coherency_setup(void) { change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); @@ -1166,7 +1242,7 @@ static void __init coherency_setup(void) clear_c0_config(CONF_CU); break; /* - * We need to catch the early Alchemy SOCs with + * We need to catch the ealry Alchemy SOCs with * the write-only co_config.od bit and set it back to one... */ case CPU_AU1000: /* rev. DA, HA, HB */ @@ -1215,6 +1291,7 @@ void __init r4k_cache_init(void) __flush_cache_all = r4k___flush_cache_all; flush_cache_mm = r4k_flush_cache_mm; flush_cache_page = r4k_flush_cache_page; + flush_icache_page = r4k_flush_icache_page; flush_cache_range = r4k_flush_cache_range; flush_cache_sigtramp = r4k_flush_cache_sigtramp; diff --git a/trunk/arch/mips/mm/c-sb1.c b/trunk/arch/mips/mm/c-sb1.c index 5537558f19f7..2d71efb82ac5 100644 --- a/trunk/arch/mips/mm/c-sb1.c +++ b/trunk/arch/mips/mm/c-sb1.c @@ -154,26 +154,6 @@ static inline void __sb1_flush_icache_all(void) } } -/* - * Invalidate a range of the icache. The addresses are virtual, and - * the cache is virtually indexed and tagged. However, we don't - * necessarily have the right ASID context, so use index ops instead - * of hit ops. - */ -static inline void __sb1_flush_icache_range(unsigned long start, - unsigned long end) -{ - start &= ~(icache_line_size - 1); - end = (end + icache_line_size - 1) & ~(icache_line_size - 1); - - while (start != end) { - cache_set_op(Index_Invalidate_I, start & icache_index_mask); - start += icache_line_size; - } - mispredict(); - sync(); -} - /* * Flush the icache for a given physical page. Need to writeback the * dcache first, then invalidate the icache. If the page isn't @@ -193,11 +173,8 @@ static void local_sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long /* * Bumping the ASID is probably cheaper than the flush ... */ - if (vma->vm_mm == current->active_mm) { - if (cpu_context(cpu, vma->vm_mm) != 0) - drop_mmu_context(vma->vm_mm, cpu); - } else - __sb1_flush_icache_range(addr, addr + PAGE_SIZE); + if (cpu_context(cpu, vma->vm_mm) != 0) + drop_mmu_context(vma->vm_mm, cpu); } #ifdef CONFIG_SMP @@ -233,6 +210,26 @@ void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsign __attribute__((alias("local_sb1_flush_cache_page"))); #endif +/* + * Invalidate a range of the icache. The addresses are virtual, and + * the cache is virtually indexed and tagged. However, we don't + * necessarily have the right ASID context, so use index ops instead + * of hit ops. + */ +static inline void __sb1_flush_icache_range(unsigned long start, + unsigned long end) +{ + start &= ~(icache_line_size - 1); + end = (end + icache_line_size - 1) & ~(icache_line_size - 1); + + while (start != end) { + cache_set_op(Index_Invalidate_I, start & icache_index_mask); + start += icache_line_size; + } + mispredict(); + sync(); +} + /* * Invalidate all caches on this CPU @@ -306,6 +303,63 @@ void sb1_flush_icache_range(unsigned long start, unsigned long end) __attribute__((alias("local_sb1_flush_icache_range"))); #endif +/* + * Flush the icache for a given physical page. Need to writeback the + * dcache first, then invalidate the icache. If the page isn't + * executable, nothing is required. + */ +static void local_sb1_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + unsigned long start; + int cpu = smp_processor_id(); + +#ifndef CONFIG_SMP + if (!(vma->vm_flags & VM_EXEC)) + return; +#endif + + /* Need to writeback any dirty data for that page, we have the PA */ + start = (unsigned long)(page-mem_map) << PAGE_SHIFT; + __sb1_writeback_inv_dcache_phys_range(start, start + PAGE_SIZE); + /* + * If there's a context, bump the ASID (cheaper than a flush, + * since we don't know VAs!) + */ + if (cpu_context(cpu, vma->vm_mm) != 0) { + drop_mmu_context(vma->vm_mm, cpu); + } +} + +#ifdef CONFIG_SMP +struct flush_icache_page_args { + struct vm_area_struct *vma; + struct page *page; +}; + +static void sb1_flush_icache_page_ipi(void *info) +{ + struct flush_icache_page_args *args = info; + local_sb1_flush_icache_page(args->vma, args->page); +} + +/* Dirty dcache could be on another CPU, so do the IPIs */ +static void sb1_flush_icache_page(struct vm_area_struct *vma, + struct page *page) +{ + struct flush_icache_page_args args; + + if (!(vma->vm_flags & VM_EXEC)) + return; + args.vma = vma; + args.page = page; + on_each_cpu(sb1_flush_icache_page_ipi, (void *) &args, 1, 1); +} +#else +void sb1_flush_icache_page(struct vm_area_struct *vma, struct page *page) + __attribute__((alias("local_sb1_flush_icache_page"))); +#endif + /* * A signal trampoline must fit into a single cacheline. */ @@ -466,6 +520,7 @@ void sb1_cache_init(void) /* These routines are for Icache coherence with the Dcache */ flush_icache_range = sb1_flush_icache_range; + flush_icache_page = sb1_flush_icache_page; flush_icache_all = __sb1_flush_icache_all; /* local only */ /* This implies an Icache flush too, so can't be nop'ed */ diff --git a/trunk/arch/mips/mm/c-tx39.c b/trunk/arch/mips/mm/c-tx39.c index f32ebde30ccf..5dfc9b1901f6 100644 --- a/trunk/arch/mips/mm/c-tx39.c +++ b/trunk/arch/mips/mm/c-tx39.c @@ -248,6 +248,33 @@ static void tx39_flush_icache_range(unsigned long start, unsigned long end) } } +/* + * Ok, this seriously sucks. We use them to flush a user page but don't + * know the virtual address, so we have to blast away the whole icache + * which is significantly more expensive than the real thing. Otoh we at + * least know the kernel address of the page so we can flush it + * selectivly. + */ +static void tx39_flush_icache_page(struct vm_area_struct *vma, struct page *page) +{ + unsigned long addr; + /* + * If there's no context yet, or the page isn't executable, no icache + * flush is needed. + */ + if (!(vma->vm_flags & VM_EXEC)) + return; + + addr = (unsigned long) page_address(page); + tx39_blast_dcache_page(addr); + + /* + * We're not sure of the virtual address(es) involved here, so + * we have to flush the entire I-cache. + */ + tx39_blast_icache(); +} + static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) { unsigned long end; @@ -355,6 +382,7 @@ void __init tx39_cache_init(void) flush_cache_mm = (void *) tx39h_flush_icache_all; flush_cache_range = (void *) tx39h_flush_icache_all; flush_cache_page = (void *) tx39h_flush_icache_all; + flush_icache_page = (void *) tx39h_flush_icache_all; flush_icache_range = (void *) tx39h_flush_icache_all; flush_cache_sigtramp = (void *) tx39h_flush_icache_all; @@ -380,6 +408,7 @@ void __init tx39_cache_init(void) flush_cache_mm = tx39_flush_cache_mm; flush_cache_range = tx39_flush_cache_range; flush_cache_page = tx39_flush_cache_page; + flush_icache_page = tx39_flush_icache_page; flush_icache_range = tx39_flush_icache_range; flush_cache_sigtramp = tx39_flush_cache_sigtramp; diff --git a/trunk/arch/mips/mm/cache.c b/trunk/arch/mips/mm/cache.c index caf807ded514..ddd3a2de1d73 100644 --- a/trunk/arch/mips/mm/cache.c +++ b/trunk/arch/mips/mm/cache.c @@ -25,6 +25,7 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start, void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); void (*flush_icache_range)(unsigned long start, unsigned long end); +void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); /* MIPS specific cache operations */ void (*flush_cache_sigtramp)(unsigned long addr); @@ -69,8 +70,6 @@ void __flush_dcache_page(struct page *page) struct address_space *mapping = page_mapping(page); unsigned long addr; - if (PageHighMem(page)) - return; if (mapping && !mapping_mapped(mapping)) { SetPageDcacheDirty(page); return; @@ -92,16 +91,16 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address, { struct page *page; unsigned long pfn, addr; - int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc; pfn = pte_pfn(pte); - if (unlikely(!pfn_valid(pfn))) - return; - page = pfn_to_page(pfn); - if (page_mapping(page) && Page_dcache_dirty(page)) { - addr = (unsigned long) page_address(page); - if (exec || pages_do_alias(addr, address & PAGE_MASK)) + if (pfn_valid(pfn) && (page = pfn_to_page(pfn), page_mapping(page)) && + Page_dcache_dirty(page)) { + if (pages_do_alias((unsigned long)page_address(page), + address & PAGE_MASK)) { + addr = (unsigned long) page_address(page); flush_data_cache_page(addr); + } + ClearPageDcacheDirty(page); } } diff --git a/trunk/arch/mips/mm/fault.c b/trunk/arch/mips/mm/fault.c index 8423d8590779..e3a617224868 100644 --- a/trunk/arch/mips/mm/fault.c +++ b/trunk/arch/mips/mm/fault.c @@ -89,7 +89,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, if (!(vma->vm_flags & VM_WRITE)) goto bad_area; } else { - if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } @@ -171,7 +171,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_init(tsk)) { + if (tsk->pid == 1) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/mips/mm/tlb-r4k.c b/trunk/arch/mips/mm/tlb-r4k.c index 2e0e21ef433e..2cde1b772443 100644 --- a/trunk/arch/mips/mm/tlb-r4k.c +++ b/trunk/arch/mips/mm/tlb-r4k.c @@ -26,6 +26,11 @@ extern void build_tlb_refill_handler(void); */ #define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) +/* CP0 hazard avoidance. */ +#define BARRIER __asm__ __volatile__(".set noreorder\n\t" \ + "nop; nop; nop; nop; nop; nop;\n\t" \ + ".set reorder\n\t") + /* Atomicity and interruptability */ #ifdef CONFIG_MIPS_MT_SMTC @@ -121,7 +126,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, start += (PAGE_SIZE << 1); mtc0_tlbw_hazard(); tlb_probe(); - tlb_probe_hazard(); + BARRIER; idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); @@ -163,7 +168,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) start += (PAGE_SIZE << 1); mtc0_tlbw_hazard(); tlb_probe(); - tlb_probe_hazard(); + BARRIER; idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); @@ -197,7 +202,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) write_c0_entryhi(page | newpid); mtc0_tlbw_hazard(); tlb_probe(); - tlb_probe_hazard(); + BARRIER; idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); @@ -230,7 +235,7 @@ void local_flush_tlb_one(unsigned long page) write_c0_entryhi(page); mtc0_tlbw_hazard(); tlb_probe(); - tlb_probe_hazard(); + BARRIER; idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); @@ -274,7 +279,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) pgdp = pgd_offset(vma->vm_mm, address); mtc0_tlbw_hazard(); tlb_probe(); - tlb_probe_hazard(); + BARRIER; pudp = pud_offset(pgdp, address); pmdp = pmd_offset(pudp, address); idx = read_c0_index(); @@ -315,7 +320,7 @@ static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, pgdp = pgd_offset(vma->vm_mm, address); mtc0_tlbw_hazard(); tlb_probe(); - tlb_probe_hazard(); + BARRIER; pmdp = pmd_offset(pgdp, address); idx = read_c0_index(); ptep = pte_offset_map(pmdp, address); @@ -346,7 +351,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, wired = read_c0_wired(); write_c0_wired(wired + 1); write_c0_index(wired); - tlbw_use_hazard(); /* What is the hazard here? */ + BARRIER; write_c0_pagemask(pagemask); write_c0_entryhi(entryhi); write_c0_entrylo0(entrylo0); @@ -356,7 +361,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, tlbw_use_hazard(); write_c0_entryhi(old_ctx); - tlbw_use_hazard(); /* What is the hazard here? */ + BARRIER; write_c0_pagemask(old_pagemask); local_flush_tlb_all(); EXIT_CRITICAL(flags); diff --git a/trunk/arch/mips/mm/tlbex-fault.S b/trunk/arch/mips/mm/tlbex-fault.S index e99eaa1fbedc..9e7f4175b493 100644 --- a/trunk/arch/mips/mm/tlbex-fault.S +++ b/trunk/arch/mips/mm/tlbex-fault.S @@ -19,8 +19,8 @@ move a0, sp REG_S a2, PT_BVADDR(sp) li a1, \write - PTR_LA ra, ret_from_exception - j do_page_fault + jal do_page_fault + j ret_from_exception END(tlb_do_page_fault_\write) .endm diff --git a/trunk/arch/mips/momentum/ocelot_g/gt-irq.c b/trunk/arch/mips/momentum/ocelot_g/gt-irq.c index 6cd87cf0195a..9fb2493fff02 100644 --- a/trunk/arch/mips/momentum/ocelot_g/gt-irq.c +++ b/trunk/arch/mips/momentum/ocelot_g/gt-irq.c @@ -133,7 +133,7 @@ static irqreturn_t gt64240_p0int_irq(int irq, void *dev, struct pt_regs *regs) MV_WRITE(TIMER_COUNTER_0_3_INTERRUPT_CAUSE, 0x0); /* handle the timer call */ - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif diff --git a/trunk/arch/mips/pci/Makefile b/trunk/arch/mips/pci/Makefile index edefa97b2330..35d5927706ea 100644 --- a/trunk/arch/mips/pci/Makefile +++ b/trunk/arch/mips/pci/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_ITE_BOARD_GEN) += ops-it8172.o obj-$(CONFIG_MIPS_BONITO64) += ops-bonito64.o obj-$(CONFIG_MIPS_GT64111) += ops-gt64111.o obj-$(CONFIG_MIPS_GT64120) += ops-gt64120.o +obj-$(CONFIG_MIPS_GT96100) += ops-gt96100.o obj-$(CONFIG_PCI_MARVELL) += ops-marvell.o obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o @@ -27,7 +28,8 @@ obj-$(CONFIG_DDB5477) += fixup-ddb5477.o pci-ddb5477.o ops-ddb5477.o obj-$(CONFIG_LASAT) += pci-lasat.o obj-$(CONFIG_MIPS_ATLAS) += fixup-atlas.o obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o -obj-$(CONFIG_MIPS_EV64120) += fixup-ev64120.o +obj-$(CONFIG_MIPS_EV96100) += fixup-ev64120.o +obj-$(CONFIG_MIPS_EV96100) += fixup-ev96100.o pci-ev96100.o obj-$(CONFIG_MIPS_ITE8172) += fixup-ite8172g.o obj-$(CONFIG_MIPS_IVR) += fixup-ivr.o obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o diff --git a/trunk/arch/mips/pci/fixup-atlas.c b/trunk/arch/mips/pci/fixup-atlas.c index c6cd6e9cdfbc..439510af3037 100644 --- a/trunk/arch/mips/pci/fixup-atlas.c +++ b/trunk/arch/mips/pci/fixup-atlas.c @@ -21,16 +21,16 @@ #include -#define PCIA ATLAS_INT_PCIA -#define PCIB ATLAS_INT_PCIB -#define PCIC ATLAS_INT_PCIC -#define PCID ATLAS_INT_PCID -#define INTA ATLAS_INT_INTA -#define INTB ATLAS_INT_INTB -#define ETH ATLAS_INT_ETH -#define INTC ATLAS_INT_INTC -#define SCSI ATLAS_INT_SCSI -#define INTD ATLAS_INT_INTD +#define PCIA ATLASINT_PCIA +#define PCIB ATLASINT_PCIB +#define PCIC ATLASINT_PCIC +#define PCID ATLASINT_PCID +#define INTA ATLASINT_INTA +#define INTB ATLASINT_INTB +#define ETH ATLASINT_ETH +#define INTC ATLASINT_INTC +#define SCSI ATLASINT_SCSI +#define INTD ATLASINT_INTD static char irq_tab[][5] __initdata = { /* INTA INTB INTC INTD */ diff --git a/trunk/arch/mips/pci/fixup-ev96100.c b/trunk/arch/mips/pci/fixup-ev96100.c new file mode 100644 index 000000000000..e2bc977b6d58 --- /dev/null +++ b/trunk/arch/mips/pci/fixup-ev96100.c @@ -0,0 +1,48 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * EV96100 Board specific pci fixups. + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include + +static char irq_tab_ev96100[][5] __initdata = { + [8] = { 0, 5, 5, 5, 5 }, + [9] = { 0, 2, 2, 2, 2 } +}; + +int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + return irq_tab_ev96100[slot][pin]; +} + +/* Do platform specific device initialization at pci_enable_device() time */ +int pcibios_plat_dev_init(struct pci_dev *dev) +{ + return 0; +} diff --git a/trunk/arch/mips/pci/ops-au1000.c b/trunk/arch/mips/pci/ops-au1000.c index 8ae46481fcb7..0c0c1e6519f9 100644 --- a/trunk/arch/mips/pci/ops-au1000.c +++ b/trunk/arch/mips/pci/ops-au1000.c @@ -110,7 +110,7 @@ static int config_access(unsigned char access_type, struct pci_bus *bus, if (first_cfg) { /* reserve a wired entry for pci config accesses */ first_cfg = 0; - pci_cfg_vm = get_vm_area(0x2000, VM_IOREMAP); + pci_cfg_vm = get_vm_area(0x2000, 0); if (!pci_cfg_vm) panic (KERN_ERR "PCI unable to get vm area\n"); pci_cfg_wired_entry = read_c0_wired(); diff --git a/trunk/arch/mips/pci/ops-gt96100.c b/trunk/arch/mips/pci/ops-gt96100.c new file mode 100644 index 000000000000..9e4ea6627e21 --- /dev/null +++ b/trunk/arch/mips/pci/ops-gt96100.c @@ -0,0 +1,169 @@ +/* + * + * BRIEF MODULE DESCRIPTION + * Galileo EV96100 board specific pci support. + * + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * This file was derived from Carsten Langgaard's + * arch/mips/mips-boards/generic/pci.c + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +#include +#include +#include + +#define PCI_ACCESS_READ 0 +#define PCI_ACCESS_WRITE 1 + +static int static gt96100_config_access(unsigned char access_type, + struct pci_bus *bus, unsigned int devfn, int where, u32 * data) +{ + unsigned char bus = bus->number; + u32 intr; + + /* + * Because of a bug in the galileo (for slot 31). + */ + if (bus == 0 && devfn >= PCI_DEVFN(31, 0)) + return PCIBIOS_DEVICE_NOT_FOUND; + + /* Clear cause register bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + + /* Setup address */ + GT_WRITE(GT_PCI0_CFGADDR_OFS, + (bus << GT_PCI0_CFGADDR_BUSNUM_SHF) | + (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | + ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) | + GT_PCI0_CFGADDR_CONFIGEN_BIT); + udelay(2); + + + if (access_type == PCI_ACCESS_WRITE) { + if (devfn != 0) + *data = le32_to_cpu(*data); + GT_WRITE(GT_PCI0_CFGDATA_OFS, *data); + } else { + *data = GT_READ(GT_PCI0_CFGDATA_OFS); + if (devfn != 0) + *data = le32_to_cpu(*data); + } + + udelay(2); + + /* Check for master or target abort */ + intr = GT_READ(GT_INTRCAUSE_OFS); + + if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) { + /* Error occured */ + + /* Clear bits */ + GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT | + GT_INTRCAUSE_TARABORT0_BIT)); + return -1; + } + return 0; +} + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int gt96100_pcibios_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 * val) +{ + u32 data = 0; + + if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return PCIBIOS_DEVICE_NOT_FOUND; + + switch (size) { + case 1: + *val = (data >> ((where & 3) << 3)) & 0xff; + break; + + case 2: + *val = (data >> ((where & 3) << 3)) & 0xffff; + break; + + case 4: + *val = data; + break; + } + return PCIBIOS_SUCCESSFUL; +} + +static int gt96100_pcibios_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + u32 data = 0; + + switch (size) { + case 1: + if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return -1; + + data = (data & ~(0xff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (gt96100_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data)) + return -1; + + return PCIBIOS_SUCCESSFUL; + + case 2: + if (gt96100_config_access(PCI_ACCESS_READ, bus, devfn, where, &data)) + return -1; + + data = (data & ~(0xffff << ((where & 3) << 3))) | + (val << ((where & 3) << 3)); + + if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &data)) + return -1; + + + return PCIBIOS_SUCCESSFUL; + + case 4: + if (gt96100_config_access(PCI_ACCESS_WRITE, dev, where, &val)) + return -1; + + return PCIBIOS_SUCCESSFUL; + } +} + +struct pci_ops gt96100_pci_ops = { + .read = gt96100_pcibios_read, + .write = gt96100_pcibios_write +}; diff --git a/trunk/arch/mips/pci/pci-ev96100.c b/trunk/arch/mips/pci/pci-ev96100.c new file mode 100644 index 000000000000..f9457ea00def --- /dev/null +++ b/trunk/arch/mips/pci/pci-ev96100.c @@ -0,0 +1,63 @@ +/* + * Copyright 2000 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * + * Carsten Langgaard, carstenl@mips.com + * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * + * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org) + * + * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include +#include +#include +#include + +static struct resource pci_io_resource = { + .name = "io pci IO space", + .start = 0x10000000, + .end = 0x11ffffff, + .flags = IORESOURCE_IO +}; + +static struct resource pci_mem_resource = { + .name = "ext pci memory space", + .start = 0x12000000, + .end = 0x13ffffff, + .flags = IORESOURCE_MEM +}; + +extern struct pci_ops gt96100_pci_ops; + +struct pci_controller ev96100_controller = { + .pci_ops = >96100_pci_ops, + .io_resource = &pci_io_resource, + .mem_resource = &pci_mem_resource, +}; + +static void ev96100_pci_init(void) +{ + register_pci_controller(&ev96100_controller); +} + +arch_initcall(ev96100_pci_init); diff --git a/trunk/arch/mips/pci/pci-ip27.c b/trunk/arch/mips/pci/pci-ip27.c index 405ce0152739..80eb9af9ecdf 100644 --- a/trunk/arch/mips/pci/pci-ip27.c +++ b/trunk/arch/mips/pci/pci-ip27.c @@ -16,6 +16,8 @@ #include #include +extern unsigned int allocate_irqno(void); + /* * Max #PCI busses we can handle; ie, max #PCI bridges. */ diff --git a/trunk/arch/mips/sgi-ip22/ip22-reset.c b/trunk/arch/mips/sgi-ip22/ip22-reset.c index 7a941ecff3bb..8134220ed600 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-reset.c +++ b/trunk/arch/mips/sgi-ip22/ip22-reset.c @@ -123,8 +123,7 @@ static inline void power_button(void) if (machine_state & MACHINE_PANICED) return; - if ((machine_state & MACHINE_SHUTTING_DOWN) || - kill_cad_pid(SIGINT, 1)) { + if ((machine_state & MACHINE_SHUTTING_DOWN) || kill_proc(1,SIGINT,1)) { /* No init process or button pressed twice. */ sgi_machine_power_off(); } diff --git a/trunk/arch/mips/sgi-ip27/ip27-timer.c b/trunk/arch/mips/sgi-ip27/ip27-timer.c index 257ce118e380..b029ba79c27a 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-timer.c +++ b/trunk/arch/mips/sgi-ip27/ip27-timer.c @@ -42,6 +42,8 @@ static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */ static long last_rtc_update; /* Last time the rtc clock got updated */ +extern volatile unsigned long wall_jiffies; + #if 0 static int set_rtc_mmss(unsigned long nowtime) { @@ -109,7 +111,7 @@ void ip27_rt_timer_interrupt(struct pt_regs *regs) kstat_this_cpu.irqs[irq]++; /* kstat only for bootcpu? */ if (cpu == 0) - do_timer(1); + do_timer(regs); update_process_times(user_mode(regs)); diff --git a/trunk/arch/mips/sgi-ip32/ip32-reset.c b/trunk/arch/mips/sgi-ip32/ip32-reset.c index fd0932b2d521..79ddb4605659 100644 --- a/trunk/arch/mips/sgi-ip32/ip32-reset.c +++ b/trunk/arch/mips/sgi-ip32/ip32-reset.c @@ -120,7 +120,7 @@ static inline void ip32_power_button(void) if (has_panicked) return; - if (shuting_down || kill_cad_pid(SIGINT, 1)) { + if (shuting_down || kill_proc(1, SIGINT, 1)) { /* No init process or button pressed twice. */ ip32_machine_power_off(); } diff --git a/trunk/arch/mips/sibyte/bcm1480/irq.c b/trunk/arch/mips/sibyte/bcm1480/irq.c index a0222fa4416c..ed325f0ab28a 100644 --- a/trunk/arch/mips/sibyte/bcm1480/irq.c +++ b/trunk/arch/mips/sibyte/bcm1480/irq.c @@ -469,6 +469,21 @@ void bcm1480_kgdb_interrupt(struct pt_regs *regs) #endif /* CONFIG_KGDB */ +static inline int dclz(unsigned long long x) +{ + int lz; + + __asm__ ( + " .set push \n" + " .set mips64 \n" + " dclz %0, %1 \n" + " .set pop \n" + : "=r" (lz) + : "r" (x)); + + return lz; +} + extern void bcm1480_timer_interrupt(struct pt_regs *regs); extern void bcm1480_mailbox_interrupt(struct pt_regs *regs); extern void bcm1480_kgdb_interrupt(struct pt_regs *regs); @@ -521,9 +536,9 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs) if (mask_h) { if (mask_h ^ 1) - do_IRQ(fls64(mask_h) - 1, regs); + do_IRQ(63 - dclz(mask_h), regs); else - do_IRQ(63 + fls64(mask_l), regs); + do_IRQ(127 - dclz(mask_l), regs); } } } diff --git a/trunk/arch/mips/sibyte/sb1250/irq.c b/trunk/arch/mips/sibyte/sb1250/irq.c index a451b4c7732d..1de71adec6c6 100644 --- a/trunk/arch/mips/sibyte/sb1250/irq.c +++ b/trunk/arch/mips/sibyte/sb1250/irq.c @@ -419,6 +419,21 @@ static void sb1250_kgdb_interrupt(struct pt_regs *regs) #endif /* CONFIG_KGDB */ +static inline int dclz(unsigned long long x) +{ + int lz; + + __asm__ ( + " .set push \n" + " .set mips64 \n" + " dclz %0, %1 \n" + " .set pop \n" + : "=r" (lz) + : "r" (x)); + + return lz; +} + extern void sb1250_timer_interrupt(struct pt_regs *regs); extern void sb1250_mailbox_interrupt(struct pt_regs *regs); extern void sb1250_kgdb_interrupt(struct pt_regs *regs); @@ -475,6 +490,6 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs) mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(), R_IMR_INTERRUPT_STATUS_BASE))); if (mask) - do_IRQ(fls64(mask) - 1, regs); + do_IRQ(63 - dclz(mask), regs); } } diff --git a/trunk/arch/parisc/hpux/sys_hpux.c b/trunk/arch/parisc/hpux/sys_hpux.c index 2e2dc4f2c853..cb69727027ae 100644 --- a/trunk/arch/parisc/hpux/sys_hpux.c +++ b/trunk/arch/parisc/hpux/sys_hpux.c @@ -266,21 +266,16 @@ static int hpux_uname(struct hpux_utsname *name) down_read(&uts_sem); - error = __copy_to_user(&name->sysname, &utsname()->sysname, - HPUX_UTSLEN - 1); - error |= __put_user(0, name->sysname + HPUX_UTSLEN - 1); - error |= __copy_to_user(&name->nodename, &utsname()->nodename, - HPUX_UTSLEN - 1); - error |= __put_user(0, name->nodename + HPUX_UTSLEN - 1); - error |= __copy_to_user(&name->release, &utsname()->release, - HPUX_UTSLEN - 1); - error |= __put_user(0, name->release + HPUX_UTSLEN - 1); - error |= __copy_to_user(&name->version, &utsname()->version, - HPUX_UTSLEN - 1); - error |= __put_user(0, name->version + HPUX_UTSLEN - 1); - error |= __copy_to_user(&name->machine, &utsname()->machine, - HPUX_UTSLEN - 1); - error |= __put_user(0, name->machine + HPUX_UTSLEN - 1); + error = __copy_to_user(&name->sysname,&system_utsname.sysname,HPUX_UTSLEN-1); + error |= __put_user(0,name->sysname+HPUX_UTSLEN-1); + error |= __copy_to_user(&name->nodename,&system_utsname.nodename,HPUX_UTSLEN-1); + error |= __put_user(0,name->nodename+HPUX_UTSLEN-1); + error |= __copy_to_user(&name->release,&system_utsname.release,HPUX_UTSLEN-1); + error |= __put_user(0,name->release+HPUX_UTSLEN-1); + error |= __copy_to_user(&name->version,&system_utsname.version,HPUX_UTSLEN-1); + error |= __put_user(0,name->version+HPUX_UTSLEN-1); + error |= __copy_to_user(&name->machine,&system_utsname.machine,HPUX_UTSLEN-1); + error |= __put_user(0,name->machine+HPUX_UTSLEN-1); up_read(&uts_sem); @@ -378,8 +373,8 @@ int hpux_utssys(char *ubuf, int n, int type) /* TODO: print a warning about using this? */ down_write(&uts_sem); error = -EFAULT; - if (!copy_from_user(utsname()->sysname, ubuf, len)) { - utsname()->sysname[len] = 0; + if (!copy_from_user(system_utsname.sysname, ubuf, len)) { + system_utsname.sysname[len] = 0; error = 0; } up_write(&uts_sem); @@ -405,8 +400,8 @@ int hpux_utssys(char *ubuf, int n, int type) /* TODO: print a warning about this? */ down_write(&uts_sem); error = -EFAULT; - if (!copy_from_user(utsname()->release, ubuf, len)) { - utsname()->release[len] = 0; + if (!copy_from_user(system_utsname.release, ubuf, len)) { + system_utsname.release[len] = 0; error = 0; } up_write(&uts_sem); @@ -427,13 +422,13 @@ int hpux_getdomainname(char *name, int len) down_read(&uts_sem); - nlen = strlen(utsname()->domainname) + 1; + nlen = strlen(system_utsname.domainname) + 1; if (nlen < len) len = nlen; if(len > __NEW_UTS_LEN) goto done; - if(copy_to_user(name, utsname()->domainname, len)) + if(copy_to_user(name, system_utsname.domainname, len)) goto done; err = 0; done: diff --git a/trunk/arch/parisc/kernel/firmware.c b/trunk/arch/parisc/kernel/firmware.c index c2531ae032cf..4398d2a95789 100644 --- a/trunk/arch/parisc/kernel/firmware.c +++ b/trunk/arch/parisc/kernel/firmware.c @@ -1049,7 +1049,7 @@ void pdc_iodc_putc(unsigned char c) static int __attribute__((aligned(8))) iodc_retbuf[32]; static char __attribute__((aligned(64))) iodc_dbuf[4096]; unsigned int n; - unsigned long flags; + unsigned int flags; switch (c) { case '\n': @@ -1088,8 +1088,7 @@ void pdc_iodc_putc(unsigned char c) */ void pdc_iodc_outc(unsigned char c) { - unsigned int n; - unsigned long flags; + unsigned int n, flags; /* fill buffer with one caracter and print it */ static int __attribute__((aligned(8))) iodc_retbuf[32]; @@ -1114,7 +1113,7 @@ void pdc_iodc_outc(unsigned char c) */ int pdc_iodc_getc(void) { - unsigned long flags; + unsigned int flags; static int __attribute__((aligned(8))) iodc_retbuf[32]; static char __attribute__((aligned(64))) iodc_dbuf[4096]; int ch; diff --git a/trunk/arch/parisc/kernel/module.c b/trunk/arch/parisc/kernel/module.c index f50b982b0834..aee311884f3f 100644 --- a/trunk/arch/parisc/kernel/module.c +++ b/trunk/arch/parisc/kernel/module.c @@ -27,7 +27,7 @@ * - SEGREL32 handling * We are not doing SEGREL32 handling correctly. According to the ABI, we * should do a value offset, like this: - * if (in_init(me, (void *)val)) + * if (is_init(me, (void *)val)) * val -= (uint32_t)me->module_init; * else * val -= (uint32_t)me->module_core; @@ -72,27 +72,27 @@ /* three functions to determine where in the module core * or init pieces the location is */ -static inline int in_init(struct module *me, void *loc) +static inline int is_init(struct module *me, void *loc) { return (loc >= me->module_init && loc <= (me->module_init + me->init_size)); } -static inline int in_core(struct module *me, void *loc) +static inline int is_core(struct module *me, void *loc) { return (loc >= me->module_core && loc <= (me->module_core + me->core_size)); } -static inline int in_local(struct module *me, void *loc) +static inline int is_local(struct module *me, void *loc) { - return in_init(me, loc) || in_core(me, loc); + return is_init(me, loc) || is_core(me, loc); } -static inline int in_local_section(struct module *me, void *loc, void *dot) +static inline int is_local_section(struct module *me, void *loc, void *dot) { - return (in_init(me, loc) && in_init(me, dot)) || - (in_core(me, loc) && in_core(me, dot)); + return (is_init(me, loc) && is_init(me, dot)) || + (is_core(me, loc) && is_core(me, dot)); } @@ -566,14 +566,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs, break; case R_PARISC_PCREL17F: /* 17-bit PC relative address */ - val = get_stub(me, val, addend, ELF_STUB_GOT, in_init(me, loc)); + val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); val = (val - dot - 8)/4; CHECK_RELOC(val, 17) *loc = (*loc & ~0x1f1ffd) | reassemble_17(val); break; case R_PARISC_PCREL22F: /* 22-bit PC relative address; only defined for pa20 */ - val = get_stub(me, val, addend, ELF_STUB_GOT, in_init(me, loc)); + val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n", strtab + sym->st_name, (unsigned long)loc, addend, val) @@ -670,9 +670,9 @@ int apply_relocate_add(Elf_Shdr *sechdrs, strtab + sym->st_name, loc, val); /* can we reach it locally? */ - if(!in_local_section(me, (void *)val, (void *)dot)) { + if(!is_local_section(me, (void *)val, (void *)dot)) { - if (in_local(me, (void *)val)) + if (is_local(me, (void *)val)) /* this is the case where the * symbol is local to the * module, but in a different @@ -680,14 +680,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs, * in case it's more than 22 * bits away */ val = get_stub(me, val, addend, ELF_STUB_DIRECT, - in_init(me, loc)); + is_init(me, loc)); else if (strncmp(strtab + sym->st_name, "$$", 2) == 0) val = get_stub(me, val, addend, ELF_STUB_MILLI, - in_init(me, loc)); + is_init(me, loc)); else val = get_stub(me, val, addend, ELF_STUB_GOT, - in_init(me, loc)); + is_init(me, loc)); } DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n", strtab + sym->st_name, loc, sym->st_value, @@ -720,7 +720,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, break; case R_PARISC_FPTR64: /* 64-bit function address */ - if(in_local(me, (void *)(val + addend))) { + if(is_local(me, (void *)(val + addend))) { *loc64 = get_fdesc(me, val+addend); DEBUGP("FDESC for %s at %p points to %lx\n", strtab + sym->st_name, *loc64, diff --git a/trunk/arch/parisc/kernel/process.c b/trunk/arch/parisc/kernel/process.c index 2f9f9dfa66f7..0b485ef4be89 100644 --- a/trunk/arch/parisc/kernel/process.c +++ b/trunk/arch/parisc/kernel/process.c @@ -368,14 +368,7 @@ asmlinkage int sys_execve(struct pt_regs *regs) return error; } -extern int __execve(const char *filename, char *const argv[], - char *const envp[], struct task_struct *task); -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - return __execve(filename, argv, envp, current); -} - -unsigned long +unsigned long get_wchan(struct task_struct *p) { struct unwind_frame_info info; diff --git a/trunk/arch/parisc/kernel/time.c b/trunk/arch/parisc/kernel/time.c index ab641d67f551..5facc9bff4ef 100644 --- a/trunk/arch/parisc/kernel/time.c +++ b/trunk/arch/parisc/kernel/time.c @@ -32,6 +32,9 @@ #include +/* xtime and wall_jiffies keep wall-clock time */ +extern unsigned long wall_jiffies; + static long clocktick __read_mostly; /* timer cycles per tick */ static long halftick __read_mostly; @@ -76,7 +79,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) #endif if (cpu == 0) { write_seqlock(&xtime_lock); - do_timer(1); + do_timer(regs); write_sequnlock(&xtime_lock); } } @@ -109,7 +112,7 @@ EXPORT_SYMBOL(profile_pc); /*** converted from ia64 ***/ /* * Return the number of micro-seconds that elapsed since the last - * update to wall time (aka xtime). The xtime_lock + * update to wall time (aka xtime aka wall_jiffies). The xtime_lock * must be at least read-locked when calling this routine. */ static inline unsigned long diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 032e6ab5d3c4..de1ef2fa1a20 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -731,11 +731,12 @@ config ARCH_SPARSEMEM_DEFAULT def_bool y depends on SMP && PPC_PSERIES -config ARCH_POPULATES_NODE_MAP - def_bool y - source "mm/Kconfig" +config HAVE_ARCH_EARLY_PFN_TO_NID + def_bool y + depends on NEED_MULTIPLE_NODES + config ARCH_MEMORY_PROBE def_bool y depends on MEMORY_HOTPLUG @@ -1069,7 +1070,7 @@ source "arch/powerpc/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on PPC64 && KALLSYMS && EXPERIMENTAL && MODULES + depends on PPC64 && EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/trunk/arch/powerpc/kernel/kprobes.c b/trunk/arch/powerpc/kernel/kprobes.c index 7b8d12b9026c..cd65c367b8b6 100644 --- a/trunk/arch/powerpc/kernel/kprobes.c +++ b/trunk/arch/powerpc/kernel/kprobes.c @@ -259,15 +259,14 @@ void kretprobe_trampoline_holder(void) */ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *node, *tmp; + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; - INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); - head = kretprobe_inst_table_head(current); + head = kretprobe_inst_table_head(current); /* * It is possible to have multiple instances associated with a given @@ -278,20 +277,20 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) * We can handle this because: * - instances are always inserted at the head of the list * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the + * function, the first instance's ret_addr will point to the * real return address, and all the rest will point to * kretprobe_trampoline */ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { - if (ri->task != current) + if (ri->task != current) /* another task is sharing our hash bucket */ - continue; + continue; if (ri->rp && ri->rp->handler) ri->rp->handler(ri, regs); orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); + recycle_rp_inst(ri); if (orig_ret_address != trampoline_address) /* @@ -309,16 +308,12 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); preempt_enable_no_resched(); - hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } - /* - * By returning a non-zero value, we are telling - * kprobe_handler() that we don't want the post_handler - * to run (and have re-enabled preemption) - */ - return 1; + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we don't want the post_handler + * to run (and have re-enabled preemption) + */ + return 1; } /* diff --git a/trunk/arch/powerpc/kernel/misc_32.S b/trunk/arch/powerpc/kernel/misc_32.S index 88fd73fdf048..58758d883361 100644 --- a/trunk/arch/powerpc/kernel/misc_32.S +++ b/trunk/arch/powerpc/kernel/misc_32.S @@ -843,7 +843,7 @@ _GLOBAL(kernel_thread) addi r1,r1,16 blr -_GLOBAL(kernel_execve) +_GLOBAL(execve) li r0,__NR_execve sc bnslr diff --git a/trunk/arch/powerpc/kernel/misc_64.S b/trunk/arch/powerpc/kernel/misc_64.S index 9c54eccad993..e3ed21cd3d94 100644 --- a/trunk/arch/powerpc/kernel/misc_64.S +++ b/trunk/arch/powerpc/kernel/misc_64.S @@ -556,7 +556,7 @@ _GLOBAL(giveup_altivec) #endif /* CONFIG_ALTIVEC */ -_GLOBAL(kernel_execve) +_GLOBAL(execve) li r0,__NR_execve sc bnslr diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 7b2f6452ba72..a127a1e3c097 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -424,7 +424,7 @@ void show_regs(struct pt_regs * regs) printk("NIP: "REG" LR: "REG" CTR: "REG"\n", regs->nip, regs->link, regs->ctr); printk("REGS: %p TRAP: %04lx %s (%s)\n", - regs, regs->trap, print_tainted(), init_utsname()->release); + regs, regs->trap, print_tainted(), system_utsname.release); printk("MSR: "REG" ", regs->msr); printbits(regs->msr, msr_bits); printk(" CR: %08lX XER: %08lX\n", regs->ccr, regs->xer); diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index 79a17795d17b..e0df2ba1ab9f 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -67,6 +67,10 @@ int have_of = 1; dev_t boot_dev; #endif /* CONFIG_PPC_MULTIPLATFORM */ +#ifdef CONFIG_MAGIC_SYSRQ +unsigned long SYSRQ_KEY = 0x54; +#endif /* CONFIG_MAGIC_SYSRQ */ + #ifdef CONFIG_VGA_CONSOLE unsigned long vgacon_remap_base; #endif diff --git a/trunk/arch/powerpc/kernel/setup_64.c b/trunk/arch/powerpc/kernel/setup_64.c index cda2dbe70a76..00d6b8addd78 100644 --- a/trunk/arch/powerpc/kernel/setup_64.c +++ b/trunk/arch/powerpc/kernel/setup_64.c @@ -93,6 +93,11 @@ int dcache_bsize; int icache_bsize; int ucache_bsize; +#ifdef CONFIG_MAGIC_SYSRQ +unsigned long SYSRQ_KEY; +#endif /* CONFIG_MAGIC_SYSRQ */ + + #ifdef CONFIG_SMP static int smt_enabled_cmdline; @@ -414,7 +419,7 @@ void __init setup_system(void) smp_release_cpus(); #endif - printk("Starting Linux PPC64 %s\n", init_utsname()->version); + printk("Starting Linux PPC64 %s\n", system_utsname.version); printk("-----------------------------------------------------\n"); printk("ppc64_pft_size = 0x%lx\n", ppc64_pft_size); diff --git a/trunk/arch/powerpc/kernel/sys_ppc32.c b/trunk/arch/powerpc/kernel/sys_ppc32.c index 5e391fc25340..2e292863e982 100644 --- a/trunk/arch/powerpc/kernel/sys_ppc32.c +++ b/trunk/arch/powerpc/kernel/sys_ppc32.c @@ -740,7 +740,7 @@ asmlinkage long compat_sys_umask(u32 mask) return sys_umask((int)mask); } -#ifdef CONFIG_SYSCTL_SYSCALL +#ifdef CONFIG_SYSCTL struct __sysctl_args32 { u32 name; int nlen; diff --git a/trunk/arch/powerpc/kernel/syscalls.c b/trunk/arch/powerpc/kernel/syscalls.c index d358866b880f..9b69d99a9103 100644 --- a/trunk/arch/powerpc/kernel/syscalls.c +++ b/trunk/arch/powerpc/kernel/syscalls.c @@ -260,7 +260,7 @@ long ppc_newuname(struct new_utsname __user * name) int err = 0; down_read(&uts_sem); - if (copy_to_user(name, utsname(), sizeof(*name))) + if (copy_to_user(name, &system_utsname, sizeof(*name))) err = -EFAULT; up_read(&uts_sem); if (!err) @@ -273,7 +273,7 @@ int sys_uname(struct old_utsname __user *name) int err = 0; down_read(&uts_sem); - if (copy_to_user(name, utsname(), sizeof(*name))) + if (copy_to_user(name, &system_utsname, sizeof(*name))) err = -EFAULT; up_read(&uts_sem); if (!err) @@ -289,19 +289,19 @@ int sys_olduname(struct oldold_utsname __user *name) return -EFAULT; down_read(&uts_sem); - error = __copy_to_user(&name->sysname, &utsname()->sysname, + error = __copy_to_user(&name->sysname, &system_utsname.sysname, __OLD_UTS_LEN); error |= __put_user(0, name->sysname + __OLD_UTS_LEN); - error |= __copy_to_user(&name->nodename, &utsname()->nodename, + error |= __copy_to_user(&name->nodename, &system_utsname.nodename, __OLD_UTS_LEN); error |= __put_user(0, name->nodename + __OLD_UTS_LEN); - error |= __copy_to_user(&name->release, &utsname()->release, + error |= __copy_to_user(&name->release, &system_utsname.release, __OLD_UTS_LEN); error |= __put_user(0, name->release + __OLD_UTS_LEN); - error |= __copy_to_user(&name->version, &utsname()->version, + error |= __copy_to_user(&name->version, &system_utsname.version, __OLD_UTS_LEN); error |= __put_user(0, name->version + __OLD_UTS_LEN); - error |= __copy_to_user(&name->machine, &utsname()->machine, + error |= __copy_to_user(&name->machine, &system_utsname.machine, __OLD_UTS_LEN); error |= override_machine(name->machine); up_read(&uts_sem); diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index 8b278d85ca4e..7a3c3f791ade 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -117,6 +117,8 @@ unsigned tb_to_ns_shift; struct gettimeofday_struct do_gtod; +extern unsigned long wall_jiffies; + extern struct timezone sys_tz; static long timezone_offset; @@ -691,7 +693,7 @@ void timer_interrupt(struct pt_regs * regs) tb_next_jiffy = tb_last_jiffy + tb_ticks_per_jiffy; if (per_cpu(last_jiffy, cpu) >= tb_next_jiffy) { tb_last_jiffy = tb_next_jiffy; - do_timer(1); + do_timer(regs); timer_recalc_offset(tb_last_jiffy); timer_check_rtc(); } @@ -814,6 +816,11 @@ int do_settimeofday(struct timespec *tv) /* * Subtract off the number of nanoseconds since the * beginning of the last tick. + * Note that since we don't increment jiffies_64 anywhere other + * than in do_timer (since we don't have a lost tick problem), + * wall_jiffies will always be the same as jiffies, + * and therefore the (jiffies - wall_jiffies) computation + * has been removed. */ tb_delta = tb_ticks_since(tb_last_jiffy); tb_delta = mulhdu(tb_delta, do_gtod.varp->tb_to_xs); /* in xsec */ diff --git a/trunk/arch/powerpc/mm/fault.c b/trunk/arch/powerpc/mm/fault.c index e8fa50624b70..78a0d59903ee 100644 --- a/trunk/arch/powerpc/mm/fault.c +++ b/trunk/arch/powerpc/mm/fault.c @@ -333,7 +333,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, /* protection fault */ if (error_code & 0x08000000) goto bad_area; - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } @@ -386,7 +386,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_init(current)) { + if (current->pid == 1) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 16fe027bbc12..eebd8b83a6b0 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -256,22 +256,20 @@ void __init do_init_bootmem(void) boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages); - /* Add active regions with valid PFNs */ - for (i = 0; i < lmb.memory.cnt; i++) { - unsigned long start_pfn, end_pfn; - start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT; - end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i); - add_active_range(0, start_pfn, end_pfn); - } - /* Add all physical memory to the bootmem map, mark each area * present. */ + for (i = 0; i < lmb.memory.cnt; i++) { + unsigned long base = lmb.memory.region[i].base; + unsigned long size = lmb_size_bytes(&lmb.memory, i); #ifdef CONFIG_HIGHMEM - free_bootmem_with_active_regions(0, total_lowmem >> PAGE_SHIFT); -#else - free_bootmem_with_active_regions(0, max_pfn); + if (base >= total_lowmem) + continue; + if (base + size > total_lowmem) + size = total_lowmem - base; #endif + free_bootmem(base, size); + } /* reserve the sections we're already using */ for (i = 0; i < lmb.reserved.cnt; i++) @@ -279,8 +277,9 @@ void __init do_init_bootmem(void) lmb_size_bytes(&lmb.reserved, i)); /* XXX need to clip this if using highmem? */ - sparse_memory_present_with_active_regions(0); - + for (i = 0; i < lmb.memory.cnt; i++) + memory_present(0, lmb_start_pfn(&lmb.memory, i), + lmb_end_pfn(&lmb.memory, i)); init_bootmem_done = 1; } @@ -289,9 +288,10 @@ void __init do_init_bootmem(void) */ void __init paging_init(void) { + unsigned long zones_size[MAX_NR_ZONES]; + unsigned long zholes_size[MAX_NR_ZONES]; unsigned long total_ram = lmb_phys_mem_size(); unsigned long top_of_ram = lmb_end_of_DRAM(); - unsigned long max_zone_pfns[MAX_NR_ZONES]; #ifdef CONFIG_HIGHMEM map_page(PKMAP_BASE, 0, 0); /* XXX gross */ @@ -307,13 +307,26 @@ void __init paging_init(void) top_of_ram, total_ram); printk(KERN_DEBUG "Memory hole size: %ldMB\n", (top_of_ram - total_ram) >> 20); + /* + * All pages are DMA-able so we put them all in the DMA zone. + */ + memset(zones_size, 0, sizeof(zones_size)); + memset(zholes_size, 0, sizeof(zholes_size)); + + zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; + zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; + #ifdef CONFIG_HIGHMEM - max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT; - max_zone_pfns[1] = top_of_ram >> PAGE_SHIFT; + zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT; + zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT; + zholes_size[ZONE_HIGHMEM] = (top_of_ram - total_ram) >> PAGE_SHIFT; #else - max_zone_pfns[0] = top_of_ram >> PAGE_SHIFT; -#endif - free_area_init_nodes(max_zone_pfns); + zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; + zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; +#endif /* CONFIG_HIGHMEM */ + + free_area_init_node(0, NODE_DATA(0), zones_size, + __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); } #endif /* ! CONFIG_NEED_MULTIPLE_NODES */ diff --git a/trunk/arch/powerpc/mm/numa.c b/trunk/arch/powerpc/mm/numa.c index 43c272075e1a..6c0f1c7d83e5 100644 --- a/trunk/arch/powerpc/mm/numa.c +++ b/trunk/arch/powerpc/mm/numa.c @@ -39,6 +39,96 @@ static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES]; static int min_common_depth; static int n_mem_addr_cells, n_mem_size_cells; +/* + * We need somewhere to store start/end/node for each region until we have + * allocated the real node_data structures. + */ +#define MAX_REGIONS (MAX_LMB_REGIONS*2) +static struct { + unsigned long start_pfn; + unsigned long end_pfn; + int nid; +} init_node_data[MAX_REGIONS] __initdata; + +int __init early_pfn_to_nid(unsigned long pfn) +{ + unsigned int i; + + for (i = 0; init_node_data[i].end_pfn; i++) { + unsigned long start_pfn = init_node_data[i].start_pfn; + unsigned long end_pfn = init_node_data[i].end_pfn; + + if ((start_pfn <= pfn) && (pfn < end_pfn)) + return init_node_data[i].nid; + } + + return -1; +} + +void __init add_region(unsigned int nid, unsigned long start_pfn, + unsigned long pages) +{ + unsigned int i; + + dbg("add_region nid %d start_pfn 0x%lx pages 0x%lx\n", + nid, start_pfn, pages); + + for (i = 0; init_node_data[i].end_pfn; i++) { + if (init_node_data[i].nid != nid) + continue; + if (init_node_data[i].end_pfn == start_pfn) { + init_node_data[i].end_pfn += pages; + return; + } + if (init_node_data[i].start_pfn == (start_pfn + pages)) { + init_node_data[i].start_pfn -= pages; + return; + } + } + + /* + * Leave last entry NULL so we dont iterate off the end (we use + * entry.end_pfn to terminate the walk). + */ + if (i >= (MAX_REGIONS - 1)) { + printk(KERN_ERR "WARNING: too many memory regions in " + "numa code, truncating\n"); + return; + } + + init_node_data[i].start_pfn = start_pfn; + init_node_data[i].end_pfn = start_pfn + pages; + init_node_data[i].nid = nid; +} + +/* We assume init_node_data has no overlapping regions */ +void __init get_region(unsigned int nid, unsigned long *start_pfn, + unsigned long *end_pfn, unsigned long *pages_present) +{ + unsigned int i; + + *start_pfn = -1UL; + *end_pfn = *pages_present = 0; + + for (i = 0; init_node_data[i].end_pfn; i++) { + if (init_node_data[i].nid != nid) + continue; + + *pages_present += init_node_data[i].end_pfn - + init_node_data[i].start_pfn; + + if (init_node_data[i].start_pfn < *start_pfn) + *start_pfn = init_node_data[i].start_pfn; + + if (init_node_data[i].end_pfn > *end_pfn) + *end_pfn = init_node_data[i].end_pfn; + } + + /* We didnt find a matching region, return start/end as 0 */ + if (*start_pfn == -1UL) + *start_pfn = 0; +} + static void __cpuinit map_cpu_to_node(int cpu, int node) { numa_cpu_lookup_table[cpu] = node; @@ -378,8 +468,8 @@ static int __init parse_numa_properties(void) continue; } - add_active_range(nid, start >> PAGE_SHIFT, - (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT)); + add_region(nid, start >> PAGE_SHIFT, + size >> PAGE_SHIFT); if (--ranges) goto new_range; @@ -392,7 +482,6 @@ static void __init setup_nonnuma(void) { unsigned long top_of_ram = lmb_end_of_DRAM(); unsigned long total_ram = lmb_phys_mem_size(); - unsigned long start_pfn, end_pfn; unsigned int i; printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", @@ -400,11 +489,9 @@ static void __init setup_nonnuma(void) printk(KERN_DEBUG "Memory hole size: %ldMB\n", (top_of_ram - total_ram) >> 20); - for (i = 0; i < lmb.memory.cnt; ++i) { - start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT; - end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i); - add_active_range(0, start_pfn, end_pfn); - } + for (i = 0; i < lmb.memory.cnt; ++i) + add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT, + lmb_size_pages(&lmb.memory, i)); node_set_online(0); } @@ -543,11 +630,11 @@ void __init do_init_bootmem(void) (void *)(unsigned long)boot_cpuid); for_each_online_node(nid) { - unsigned long start_pfn, end_pfn; + unsigned long start_pfn, end_pfn, pages_present; unsigned long bootmem_paddr; unsigned long bootmap_pages; - get_pfn_range_for_nid(nid, &start_pfn, &end_pfn); + get_region(nid, &start_pfn, &end_pfn, &pages_present); /* Allocate the node structure node local if possible */ NODE_DATA(nid) = careful_allocation(nid, @@ -580,7 +667,19 @@ void __init do_init_bootmem(void) init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT, start_pfn, end_pfn); - free_bootmem_with_active_regions(nid, end_pfn); + /* Add free regions on this node */ + for (i = 0; init_node_data[i].end_pfn; i++) { + unsigned long start, end; + + if (init_node_data[i].nid != nid) + continue; + + start = init_node_data[i].start_pfn << PAGE_SHIFT; + end = init_node_data[i].end_pfn << PAGE_SHIFT; + + dbg("free_bootmem %lx %lx\n", start, end - start); + free_bootmem_node(NODE_DATA(nid), start, end - start); + } /* Mark reserved regions on this node */ for (i = 0; i < lmb.reserved.cnt; i++) { @@ -611,16 +710,44 @@ void __init do_init_bootmem(void) } } - sparse_memory_present_with_active_regions(nid); + /* Add regions into sparsemem */ + for (i = 0; init_node_data[i].end_pfn; i++) { + unsigned long start, end; + + if (init_node_data[i].nid != nid) + continue; + + start = init_node_data[i].start_pfn; + end = init_node_data[i].end_pfn; + + memory_present(nid, start, end); + } } } void __init paging_init(void) { - unsigned long max_zone_pfns[MAX_NR_ZONES] = { - lmb_end_of_DRAM() >> PAGE_SHIFT - }; - free_area_init_nodes(max_zone_pfns); + unsigned long zones_size[MAX_NR_ZONES]; + unsigned long zholes_size[MAX_NR_ZONES]; + int nid; + + memset(zones_size, 0, sizeof(zones_size)); + memset(zholes_size, 0, sizeof(zholes_size)); + + for_each_online_node(nid) { + unsigned long start_pfn, end_pfn, pages_present; + + get_region(nid, &start_pfn, &end_pfn, &pages_present); + + zones_size[ZONE_DMA] = end_pfn - start_pfn; + zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] - pages_present; + + dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid, + zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]); + + free_area_init_node(nid, NODE_DATA(nid), zones_size, start_pfn, + zholes_size); + } } static int __init early_numa(char *p) diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c index 3950ddccb2c8..7b4572805db9 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -82,6 +82,7 @@ spufs_new_inode(struct super_block *sb, int mode) inode->i_mode = mode; inode->i_uid = current->fsuid; inode->i_gid = current->fsgid; + inode->i_blksize = PAGE_CACHE_SIZE; inode->i_blocks = 0; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; out: @@ -119,7 +120,7 @@ spufs_new_file(struct super_block *sb, struct dentry *dentry, ret = 0; inode->i_op = &spufs_file_iops; inode->i_fop = fops; - inode->i_private = SPUFS_I(inode)->i_ctx = get_spu_context(ctx); + inode->u.generic_ip = SPUFS_I(inode)->i_ctx = get_spu_context(ctx); d_add(dentry, inode); out: return ret; diff --git a/trunk/arch/powerpc/platforms/iseries/mf.c b/trunk/arch/powerpc/platforms/iseries/mf.c index 1983b640bac1..1a2c2a50f922 100644 --- a/trunk/arch/powerpc/platforms/iseries/mf.c +++ b/trunk/arch/powerpc/platforms/iseries/mf.c @@ -357,7 +357,7 @@ static int dma_and_signal_ce_msg(char *ce_msg, */ static int shutdown(void) { - int rc = kill_cad_pid(SIGINT, 1); + int rc = kill_proc(1, SIGINT, 1); if (rc) { printk(KERN_ALERT "mf.c: SIGINT to init failed (%d), " diff --git a/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c b/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c index 9d22361a26d6..d30466d74194 100644 --- a/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c +++ b/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c @@ -104,7 +104,7 @@ static void g5_smu_switch_volt(int speed_mode) { struct smu_simple_cmd cmd; - DECLARE_COMPLETION_ONSTACK(comp); + DECLARE_COMPLETION(comp); smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 8, smu_done_complete, &comp, 'V', 'S', 'L', 'E', 'W', 0xff, g5_fvt_cur+1, speed_mode); diff --git a/trunk/arch/powerpc/platforms/powermac/nvram.c b/trunk/arch/powerpc/platforms/powermac/nvram.c index 692945c14919..6a36ea9bf673 100644 --- a/trunk/arch/powerpc/platforms/powermac/nvram.c +++ b/trunk/arch/powerpc/platforms/powermac/nvram.c @@ -195,7 +195,7 @@ static void pmu_nvram_complete(struct adb_request *req) static unsigned char pmu_nvram_read_byte(int addr) { struct adb_request req; - DECLARE_COMPLETION_ONSTACK(req_complete); + DECLARE_COMPLETION(req_complete); req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL; if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM, @@ -211,7 +211,7 @@ static unsigned char pmu_nvram_read_byte(int addr) static void pmu_nvram_write_byte(int addr, unsigned char val) { struct adb_request req; - DECLARE_COMPLETION_ONSTACK(req_complete); + DECLARE_COMPLETION(req_complete); req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL; if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM, diff --git a/trunk/arch/powerpc/platforms/pseries/hvCall_inst.c b/trunk/arch/powerpc/platforms/pseries/hvCall_inst.c index 446e17d162a5..641e6511cf06 100644 --- a/trunk/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/trunk/arch/powerpc/platforms/pseries/hvCall_inst.c @@ -85,7 +85,7 @@ static int hcall_inst_seq_open(struct inode *inode, struct file *file) rc = seq_open(file, &hcall_inst_seq_ops); seq = file->private_data; - seq->private = file->f_dentry->d_inode->i_private; + seq->private = file->f_dentry->d_inode->u.generic_ip; return rc; } diff --git a/trunk/arch/powerpc/platforms/pseries/ras.c b/trunk/arch/powerpc/platforms/pseries/ras.c index 311ed1993fc0..903115d67fdc 100644 --- a/trunk/arch/powerpc/platforms/pseries/ras.c +++ b/trunk/arch/powerpc/platforms/pseries/ras.c @@ -337,7 +337,7 @@ static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err) err->disposition == RTAS_DISP_NOT_RECOVERED && err->target == RTAS_TARGET_MEMORY && err->type == RTAS_TYPE_ECC_UNCORR && - !(current->pid == 0 || is_init(current))) { + !(current->pid == 0 || current->pid == 1)) { /* Kill off a user process with an ECC error */ printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n", current->pid); diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index 98189d8efaca..a6398fbe530d 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -342,7 +342,7 @@ static int __init pSeries_init_panel(void) { /* Manually leave the kernel version on the panel. */ ppc_md.progress("Linux ppc64\n", 0); - ppc_md.progress(init_utsname()->version, 0); + ppc_md.progress(system_utsname.release, 0); return 0; } @@ -415,12 +415,6 @@ static int pSeries_check_legacy_ioport(unsigned int baseport) return -ENODEV; of_node_put(np); break; - case PARALLEL_BASE: - np = of_find_node_by_type(NULL, "parallel"); - if (np == NULL) - return -ENODEV; - of_node_put(np); - break; } return 0; } diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index 723972bb5bd9..b604926401f5 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -339,7 +339,7 @@ static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase, for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0; pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) { u8 id = readb(devbase + pos + PCI_CAP_LIST_ID); - if (id == PCI_CAP_ID_HT) { + if (id == PCI_CAP_ID_HT_IRQCONF) { id = readb(devbase + pos + 3); if (id == 0x80) break; diff --git a/trunk/arch/ppc/4xx_io/serial_sicc.c b/trunk/arch/ppc/4xx_io/serial_sicc.c index 87fe9a89dba7..b81a367dc278 100644 --- a/trunk/arch/ppc/4xx_io/serial_sicc.c +++ b/trunk/arch/ppc/4xx_io/serial_sicc.c @@ -1720,7 +1720,7 @@ static int siccuart_open(struct tty_struct *tty, struct file *filp) return 0; } -static const struct tty_operations sicc_ops = { +static struct tty_operations sicc_ops = { .open = siccuart_open, .close = siccuart_close, .write = siccuart_write, diff --git a/trunk/arch/ppc/Kconfig b/trunk/arch/ppc/Kconfig index fdd9e7b66244..8fa10cf661a8 100644 --- a/trunk/arch/ppc/Kconfig +++ b/trunk/arch/ppc/Kconfig @@ -953,9 +953,6 @@ config NR_CPUS config HIGHMEM bool "High memory support" -config ARCH_POPULATES_NODE_MAP - def_bool y - source kernel/Kconfig.hz source kernel/Kconfig.preempt source "mm/Kconfig" diff --git a/trunk/arch/ppc/kernel/misc.S b/trunk/arch/ppc/kernel/misc.S index 5f6684012ded..50b4bbd06804 100644 --- a/trunk/arch/ppc/kernel/misc.S +++ b/trunk/arch/ppc/kernel/misc.S @@ -942,16 +942,20 @@ _GLOBAL(kernel_thread) addi r1,r1,16 blr -_GLOBAL(kernel_execve) - li r0,__NR_execve - sc - bnslr - neg r3,r3 - blr - /* * This routine is just here to keep GCC happy - sigh... */ _GLOBAL(__main) blr +#define SYSCALL(name) \ +_GLOBAL(name) \ + li r0,__NR_##name; \ + sc; \ + bnslr; \ + lis r4,errno@ha; \ + stw r3,errno@l(r4); \ + li r3,-1; \ + blr + +SYSCALL(execve) diff --git a/trunk/arch/ppc/kernel/setup.c b/trunk/arch/ppc/kernel/setup.c index 75fe13815be2..5458ac5da7c3 100644 --- a/trunk/arch/ppc/kernel/setup.c +++ b/trunk/arch/ppc/kernel/setup.c @@ -86,6 +86,10 @@ int ppc_do_canonicalize_irqs; EXPORT_SYMBOL(ppc_do_canonicalize_irqs); #endif +#ifdef CONFIG_MAGIC_SYSRQ +unsigned long SYSRQ_KEY = 0x54; +#endif /* CONFIG_MAGIC_SYSRQ */ + #ifdef CONFIG_VGA_CONSOLE unsigned long vgacon_remap_base; #endif diff --git a/trunk/arch/ppc/kernel/time.c b/trunk/arch/ppc/kernel/time.c index 187388625a76..6ab8cc7226ab 100644 --- a/trunk/arch/ppc/kernel/time.c +++ b/trunk/arch/ppc/kernel/time.c @@ -80,6 +80,8 @@ unsigned tb_to_us; unsigned tb_last_stamp; unsigned long tb_to_ns_scale; +extern unsigned long wall_jiffies; + /* used for timezone offset */ static long timezone_offset; @@ -151,7 +153,7 @@ void timer_interrupt(struct pt_regs * regs) /* We are in an interrupt, no need to save/restore flags */ write_seqlock(&xtime_lock); tb_last_stamp = jiffy_stamp; - do_timer(1); + do_timer(regs); /* * update the rtc when needed, this should be performed on the @@ -171,7 +173,8 @@ void timer_interrupt(struct pt_regs * regs) */ if ( ppc_md.set_rtc_time && ntp_synced() && xtime.tv_sec - last_rtc_update >= 659 && - abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ) { + abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ && + jiffies - wall_jiffies == 1) { if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0) last_rtc_update = xtime.tv_sec+1; else @@ -197,7 +200,7 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; unsigned long seq; - unsigned delta, usec, sec; + unsigned delta, lost_ticks, usec, sec; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); @@ -211,9 +214,10 @@ void do_gettimeofday(struct timeval *tv) if (!smp_tb_synchronized) delta = 0; #endif /* CONFIG_SMP */ + lost_ticks = jiffies - wall_jiffies; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - usec += mulhwu(tb_to_us, delta); + usec += mulhwu(tb_to_us, tb_ticks_per_jiffy * lost_ticks + delta); while (usec >= 1000000) { sec++; usec -= 1000000; @@ -254,6 +258,7 @@ int do_settimeofday(struct timespec *tv) * still reasonable when gettimeofday resolution is 1 jiffy. */ tb_delta = tb_ticks_since(last_jiffy_stamp(smp_processor_id())); + tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy; new_nsec -= 1000 * mulhwu(tb_to_us, tb_delta); diff --git a/trunk/arch/ppc/kernel/traps.c b/trunk/arch/ppc/kernel/traps.c index aafc8e8893d1..d7a433049b48 100644 --- a/trunk/arch/ppc/kernel/traps.c +++ b/trunk/arch/ppc/kernel/traps.c @@ -119,7 +119,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) * generate the same exception over and over again and we get * nowhere. Better to kill it and let the kernel panic. */ - if (is_init(current)) { + if (current->pid == 1) { __sighandler_t handler; spin_lock_irq(¤t->sighand->siglock); diff --git a/trunk/arch/ppc/mm/fault.c b/trunk/arch/ppc/mm/fault.c index 465f451f3bc3..5cdfb71fcb07 100644 --- a/trunk/arch/ppc/mm/fault.c +++ b/trunk/arch/ppc/mm/fault.c @@ -239,7 +239,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, /* protection fault */ if (error_code & 0x08000000) goto bad_area; - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } @@ -291,7 +291,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_init(current)) { + if (current->pid == 1) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/ppc/mm/init.c b/trunk/arch/ppc/mm/init.c index 410200046af1..523392d460fa 100644 --- a/trunk/arch/ppc/mm/init.c +++ b/trunk/arch/ppc/mm/init.c @@ -358,8 +358,8 @@ void __init do_init_bootmem(void) */ void __init paging_init(void) { - unsigned long start_pfn, end_pfn; - unsigned long max_zone_pfns[MAX_NR_ZONES]; + unsigned long zones_size[MAX_NR_ZONES], i; + #ifdef CONFIG_HIGHMEM map_page(PKMAP_BASE, 0, 0); /* XXX gross */ pkmap_page_table = pte_offset_kernel(pmd_offset(pgd_offset_k @@ -369,18 +369,19 @@ void __init paging_init(void) (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN); kmap_prot = PAGE_KERNEL; #endif /* CONFIG_HIGHMEM */ - /* All pages are DMA-able so we put them all in the DMA zone. */ - start_pfn = __pa(PAGE_OFFSET) >> PAGE_SHIFT; - end_pfn = start_pfn + (total_memory >> PAGE_SHIFT); - add_active_range(0, start_pfn, end_pfn); + + /* + * All pages are DMA-able so we put them all in the DMA zone. + */ + zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT; + for (i = 1; i < MAX_NR_ZONES; i++) + zones_size[i] = 0; #ifdef CONFIG_HIGHMEM - max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT; - max_zone_pfns[1] = total_memory >> PAGE_SHIFT; -#else - max_zone_pfns[0] = total_memory >> PAGE_SHIFT; + zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT; #endif /* CONFIG_HIGHMEM */ - free_area_init_nodes(max_zone_pfns); + + free_area_init(zones_size); } void __init mem_init(void) diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index f900a516f099..b216ca659cdf 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -51,10 +51,6 @@ config 64BIT Select this option if you have a 64 bit IBM zSeries machine and want to use the 64 bit addressing mode. -config 32BIT - bool - default y if !64BIT - config SMP bool "Symmetric multi-processing support" ---help--- @@ -153,14 +149,6 @@ config MARCH_Z990 This will be slightly faster but does not work on older machines such as the z900. -config MARCH_Z9_109 - bool "IBM System z9" - help - Select this to enable optimizations for IBM System z9-109, IBM - System z9 Enterprise Class (z9 EC), and IBM System z9 Business - Class (z9 BC). The kernel will be slightly faster but will not - work on older machines such as the z990, z890, z900, and z800. - endchoice config PACK_STACK diff --git a/trunk/arch/s390/Makefile b/trunk/arch/s390/Makefile index 5deb9f7544a1..74ef57dcfa60 100644 --- a/trunk/arch/s390/Makefile +++ b/trunk/arch/s390/Makefile @@ -33,7 +33,6 @@ endif cflags-$(CONFIG_MARCH_G5) += $(call cc-option,-march=g5) cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900) cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990) -cflags-$(CONFIG_MARCH_Z9_109) += $(call cc-option,-march=z9-109) # # Prevent tail-call optimizations, to get clearer backtraces: diff --git a/trunk/arch/s390/appldata/appldata_base.c b/trunk/arch/s390/appldata/appldata_base.c index 2b1e6c9a6e0e..b69ed742f981 100644 --- a/trunk/arch/s390/appldata/appldata_base.c +++ b/trunk/arch/s390/appldata/appldata_base.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -157,12 +157,12 @@ int appldata_diag(char record_nr, u16 function, unsigned long buffer, .prod_nr = {0xD3, 0xC9, 0xD5, 0xE4, 0xE7, 0xD2, 0xD9}, /* "LINUXKR" */ .prod_fn = 0xD5D3, /* "NL" */ + .record_nr = record_nr, .version_nr = 0xF2F6, /* "26" */ .release_nr = 0xF0F1, /* "01" */ + .mod_lvl = (mod_lvl[0]) << 8 | mod_lvl[1], }; - id.record_nr = record_nr; - id.mod_lvl = (mod_lvl[0]) << 8 | mod_lvl[1]; return appldata_asm(&id, function, (void *) buffer, length); } /************************ timer, work, DIAG ****************************/ diff --git a/trunk/arch/s390/crypto/crypt_s390.h b/trunk/arch/s390/crypto/crypt_s390.h index 2b137089f625..efd836c2e4a6 100644 --- a/trunk/arch/s390/crypto/crypt_s390.h +++ b/trunk/arch/s390/crypto/crypt_s390.h @@ -104,6 +104,63 @@ struct crypt_s390_query_status { u64 low; }; +/* + * Standard fixup and ex_table sections for crypt_s390 inline functions. + * label 0: the s390 crypto operation + * label 1: just after 1 to catch illegal operation exception + * (unsupported model) + * label 6: the return point after fixup + * label 7: set error value if exception _in_ crypto operation + * label 8: set error value if illegal operation exception + * [ret] is the variable to receive the error code + * [ERR] is the error code value + */ +#ifndef CONFIG_64BIT +#define __crypt_s390_fixup \ + ".section .fixup,\"ax\" \n" \ + "7: lhi %0,%h[e1] \n" \ + " bras 1,9f \n" \ + " .long 6b \n" \ + "8: lhi %0,%h[e2] \n" \ + " bras 1,9f \n" \ + " .long 6b \n" \ + "9: l 1,0(1) \n" \ + " br 1 \n" \ + ".previous \n" \ + ".section __ex_table,\"a\" \n" \ + " .align 4 \n" \ + " .long 0b,7b \n" \ + " .long 1b,8b \n" \ + ".previous" +#else /* CONFIG_64BIT */ +#define __crypt_s390_fixup \ + ".section .fixup,\"ax\" \n" \ + "7: lhi %0,%h[e1] \n" \ + " jg 6b \n" \ + "8: lhi %0,%h[e2] \n" \ + " jg 6b \n" \ + ".previous\n" \ + ".section __ex_table,\"a\" \n" \ + " .align 8 \n" \ + " .quad 0b,7b \n" \ + " .quad 1b,8b \n" \ + ".previous" +#endif /* CONFIG_64BIT */ + +/* + * Standard code for setting the result of s390 crypto instructions. + * %0: the register which will receive the result + * [result]: the register containing the result (e.g. second operand length + * to compute number of processed bytes]. + */ +#ifndef CONFIG_64BIT +#define __crypt_s390_set_result \ + " lr %0,%[result] \n" +#else /* CONFIG_64BIT */ +#define __crypt_s390_set_result \ + " lgr %0,%[result] \n" +#endif + /* * Executes the KM (CIPHER MESSAGE) operation of the CPU. * @param func: the function code passed to KM; see crypt_s390_km_func @@ -119,24 +176,28 @@ crypt_s390_km(long func, void* param, u8* dest, const u8* src, long src_len) { register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; register void* __param asm("1") = param; + register u8* __dest asm("4") = dest; register const u8* __src asm("2") = src; register long __src_len asm("3") = src_len; - register u8* __dest asm("4") = dest; int ret; - asm volatile( - "0: .insn rre,0xb92e0000,%3,%1 \n" /* KM opcode */ + ret = 0; + __asm__ __volatile__ ( + "0: .insn rre,0xB92E0000,%1,%2 \n" /* KM opcode */ "1: brc 1,0b \n" /* handle partial completion */ - " ahi %0,%h7\n" - "2: ahi %0,%h8\n" - "3:\n" - EX_TABLE(0b,3b) EX_TABLE(1b,2b) - : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) - : "d" (__func), "a" (__param), "0" (-EFAULT), - "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory"); - if (ret < 0) - return ret; - return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; + __crypt_s390_set_result + "6: \n" + __crypt_s390_fixup + : "+d" (ret), "+a" (__dest), "+a" (__src), + [result] "+d" (__src_len) + : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), + "a" (__param) + : "cc", "memory" + ); + if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){ + ret = src_len - ret; + } + return ret; } /* @@ -154,24 +215,28 @@ crypt_s390_kmc(long func, void* param, u8* dest, const u8* src, long src_len) { register long __func asm("0") = func & CRYPT_S390_FUNC_MASK; register void* __param asm("1") = param; + register u8* __dest asm("4") = dest; register const u8* __src asm("2") = src; register long __src_len asm("3") = src_len; - register u8* __dest asm("4") = dest; int ret; - asm volatile( - "0: .insn rre,0xb92f0000,%3,%1 \n" /* KMC opcode */ + ret = 0; + __asm__ __volatile__ ( + "0: .insn rre,0xB92F0000,%1,%2 \n" /* KMC opcode */ "1: brc 1,0b \n" /* handle partial completion */ - " ahi %0,%h7\n" - "2: ahi %0,%h8\n" - "3:\n" - EX_TABLE(0b,3b) EX_TABLE(1b,2b) - : "=d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest) - : "d" (__func), "a" (__param), "0" (-EFAULT), - "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory"); - if (ret < 0) - return ret; - return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; + __crypt_s390_set_result + "6: \n" + __crypt_s390_fixup + : "+d" (ret), "+a" (__dest), "+a" (__src), + [result] "+d" (__src_len) + : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), + "a" (__param) + : "cc", "memory" + ); + if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){ + ret = src_len - ret; + } + return ret; } /* @@ -193,19 +258,22 @@ crypt_s390_kimd(long func, void* param, const u8* src, long src_len) register long __src_len asm("3") = src_len; int ret; - asm volatile( - "0: .insn rre,0xb93e0000,%1,%1 \n" /* KIMD opcode */ - "1: brc 1,0b \n" /* handle partial completion */ - " ahi %0,%h6\n" - "2: ahi %0,%h7\n" - "3:\n" - EX_TABLE(0b,3b) EX_TABLE(1b,2b) - : "=d" (ret), "+a" (__src), "+d" (__src_len) - : "d" (__func), "a" (__param), "0" (-EFAULT), - "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory"); - if (ret < 0) - return ret; - return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; + ret = 0; + __asm__ __volatile__ ( + "0: .insn rre,0xB93E0000,%1,%1 \n" /* KIMD opcode */ + "1: brc 1,0b \n" /* handle partical completion */ + __crypt_s390_set_result + "6: \n" + __crypt_s390_fixup + : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) + : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), + "a" (__param) + : "cc", "memory" + ); + if (ret >= 0 && (func & CRYPT_S390_FUNC_MASK)){ + ret = src_len - ret; + } + return ret; } /* @@ -226,19 +294,22 @@ crypt_s390_klmd(long func, void* param, const u8* src, long src_len) register long __src_len asm("3") = src_len; int ret; - asm volatile( - "0: .insn rre,0xb93f0000,%1,%1 \n" /* KLMD opcode */ - "1: brc 1,0b \n" /* handle partial completion */ - " ahi %0,%h6\n" - "2: ahi %0,%h7\n" - "3:\n" - EX_TABLE(0b,3b) EX_TABLE(1b,2b) - : "=d" (ret), "+a" (__src), "+d" (__src_len) - : "d" (__func), "a" (__param), "0" (-EFAULT), - "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory"); - if (ret < 0) - return ret; - return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; + ret = 0; + __asm__ __volatile__ ( + "0: .insn rre,0xB93F0000,%1,%1 \n" /* KLMD opcode */ + "1: brc 1,0b \n" /* handle partical completion */ + __crypt_s390_set_result + "6: \n" + __crypt_s390_fixup + : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) + : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), + "a" (__param) + : "cc", "memory" + ); + if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){ + ret = src_len - ret; + } + return ret; } /* @@ -260,19 +331,22 @@ crypt_s390_kmac(long func, void* param, const u8* src, long src_len) register long __src_len asm("3") = src_len; int ret; - asm volatile( - "0: .insn rre,0xb91e0000,%1,%1 \n" /* KLAC opcode */ - "1: brc 1,0b \n" /* handle partial completion */ - " ahi %0,%h6\n" - "2: ahi %0,%h7\n" - "3:\n" - EX_TABLE(0b,3b) EX_TABLE(1b,2b) - : "=d" (ret), "+a" (__src), "+d" (__src_len) - : "d" (__func), "a" (__param), "0" (-EFAULT), - "K" (ENOSYS), "K" (-ENOSYS + EFAULT) : "cc", "memory"); - if (ret < 0) - return ret; - return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len; + ret = 0; + __asm__ __volatile__ ( + "0: .insn rre,0xB91E0000,%5,%5 \n" /* KMAC opcode */ + "1: brc 1,0b \n" /* handle partical completion */ + __crypt_s390_set_result + "6: \n" + __crypt_s390_fixup + : "+d" (ret), "+a" (__src), [result] "+d" (__src_len) + : [e1] "K" (-EFAULT), [e2] "K" (-ENOSYS), "d" (__func), + "a" (__param) + : "cc", "memory" + ); + if (ret >= 0 && func & CRYPT_S390_FUNC_MASK){ + ret = src_len - ret; + } + return ret; } /** diff --git a/trunk/arch/s390/hypfs/hypfs_diag.c b/trunk/arch/s390/hypfs/hypfs_diag.c index 443fa377d9ff..75144efbb92b 100644 --- a/trunk/arch/s390/hypfs/hypfs_diag.c +++ b/trunk/arch/s390/hypfs/hypfs_diag.c @@ -333,14 +333,22 @@ static int diag204(unsigned long subcode, unsigned long size, void *addr) register unsigned long _subcode asm("0") = subcode; register unsigned long _size asm("1") = size; - asm volatile( - " diag %2,%0,0x204\n" - "0:\n" - EX_TABLE(0b,0b) - : "+d" (_subcode), "+d" (_size) : "d" (addr) : "memory"); + asm volatile (" diag %2,%0,0x204\n" + "0: \n" ".section __ex_table,\"a\"\n" +#ifndef __s390x__ + " .align 4\n" + " .long 0b,0b\n" +#else + " .align 8\n" + " .quad 0b,0b\n" +#endif + ".previous":"+d" (_subcode), "+d"(_size) + :"d"(addr) + :"memory"); if (_subcode) return -1; - return _size; + else + return _size; } /* @@ -395,8 +403,7 @@ static void *diag204_get_buffer(enum diag204_format fmt, int *pages) *pages = 1; return diag204_alloc_rbuf(); } else {/* INFO_EXT */ - *pages = diag204((unsigned long)SUBC_RSI | - (unsigned long)INFO_EXT, 0, NULL); + *pages = diag204(SUBC_RSI | INFO_EXT, 0, NULL); if (*pages <= 0) return ERR_PTR(-ENOSYS); else @@ -483,7 +490,8 @@ static void *diag204_store(void) static void diag224(void *ptr) { - asm volatile("diag %0,%1,0x224" : :"d" (0), "d"(ptr) : "memory"); + asm volatile(" diag %0,%1,0x224\n" + : :"d" (0), "d"(ptr) : "memory"); } static int diag224_get_name_table(void) diff --git a/trunk/arch/s390/hypfs/inode.c b/trunk/arch/s390/hypfs/inode.c index cd702ae45d6d..bdade5f2e325 100644 --- a/trunk/arch/s390/hypfs/inode.c +++ b/trunk/arch/s390/hypfs/inode.c @@ -91,6 +91,7 @@ static struct inode *hypfs_make_inode(struct super_block *sb, int mode) ret->i_mode = mode; ret->i_uid = hypfs_info->uid; ret->i_gid = hypfs_info->gid; + ret->i_blksize = PAGE_CACHE_SIZE; ret->i_blocks = 0; ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME; if (mode & S_IFDIR) @@ -103,13 +104,13 @@ static struct inode *hypfs_make_inode(struct super_block *sb, int mode) static void hypfs_drop_inode(struct inode *inode) { - kfree(inode->i_private); + kfree(inode->u.generic_ip); generic_delete_inode(inode); } static int hypfs_open(struct inode *inode, struct file *filp) { - char *data = filp->f_dentry->d_inode->i_private; + char *data = filp->f_dentry->d_inode->u.generic_ip; struct hypfs_sb_info *fs_info; if (filp->f_mode & FMODE_WRITE) { @@ -134,20 +135,12 @@ static int hypfs_open(struct inode *inode, struct file *filp) return 0; } -static ssize_t hypfs_aio_read(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t offset) +static ssize_t hypfs_aio_read(struct kiocb *iocb, __user char *buf, + size_t count, loff_t offset) { char *data; size_t len; struct file *filp = iocb->ki_filp; - /* XXX: temporary */ - char __user *buf = iov[0].iov_base; - size_t count = iov[0].iov_len; - - if (nr_segs != 1) { - count = -EINVAL; - goto out; - } data = filp->private_data; len = strlen(data); @@ -166,13 +159,12 @@ static ssize_t hypfs_aio_read(struct kiocb *iocb, const struct iovec *iov, out: return count; } -static ssize_t hypfs_aio_write(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t offset) +static ssize_t hypfs_aio_write(struct kiocb *iocb, const char __user *buf, + size_t count, loff_t pos) { int rc; struct super_block *sb; struct hypfs_sb_info *fs_info; - size_t count = iov_length(iov, nr_segs); sb = iocb->ki_filp->f_dentry->d_inode->i_sb; fs_info = sb->s_fs_info; @@ -360,7 +352,7 @@ static struct dentry *hypfs_create_file(struct super_block *sb, parent->d_inode->i_nlink++; } else BUG(); - inode->i_private = data; + inode->u.generic_ip = data; d_instantiate(dentry, inode); dget(dentry); return dentry; diff --git a/trunk/arch/s390/kernel/compat_linux.c b/trunk/arch/s390/kernel/compat_linux.c index c46e3d48e410..785c9f70ac98 100644 --- a/trunk/arch/s390/kernel/compat_linux.c +++ b/trunk/arch/s390/kernel/compat_linux.c @@ -544,7 +544,10 @@ sys32_execve(struct pt_regs regs) current->ptrace &= ~PT_DTRACE; task_unlock(current); current->thread.fp_regs.fpc=0; - asm volatile("sfpc %0,0" : : "d" (0)); + __asm__ __volatile__ + ("sr 0,0\n\t" + "sfpc 0,0\n\t" + : : :"0"); } putname(filename); out: @@ -705,7 +708,7 @@ asmlinkage long sys32_sendfile64(int out_fd, int in_fd, return ret; } -#ifdef CONFIG_SYSCTL_SYSCALL +#ifdef CONFIG_SYSCTL struct __sysctl_args32 { u32 name; int nlen; diff --git a/trunk/arch/s390/kernel/compat_wrapper.S b/trunk/arch/s390/kernel/compat_wrapper.S index 4aabeeaa7cf7..4d53b2739357 100644 --- a/trunk/arch/s390/kernel/compat_wrapper.S +++ b/trunk/arch/s390/kernel/compat_wrapper.S @@ -4,97 +4,97 @@ * * Copyright (C) IBM Corp. 2000,2006 * Author(s): Gerhard Tonn (ton@de.ibm.com), -* Thomas Spatzier (tspat@de.ibm.com) -*/ +* Thomas Spatzier (tspat@de.ibm.com) +*/ - .globl sys32_exit_wrapper + .globl sys32_exit_wrapper sys32_exit_wrapper: lgfr %r2,%r2 # int jg sys_exit # branch to sys_exit - - .globl sys32_read_wrapper + + .globl sys32_read_wrapper sys32_read_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # char * llgfr %r4,%r4 # size_t jg sys32_read # branch to sys_read - .globl sys32_write_wrapper + .globl sys32_write_wrapper sys32_write_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # const char * llgfr %r4,%r4 # size_t jg sys32_write # branch to system call - .globl sys32_open_wrapper + .globl sys32_open_wrapper sys32_open_wrapper: llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int lgfr %r4,%r4 # int jg sys_open # branch to system call - .globl sys32_close_wrapper + .globl sys32_close_wrapper sys32_close_wrapper: llgfr %r2,%r2 # unsigned int jg sys_close # branch to system call - .globl sys32_creat_wrapper + .globl sys32_creat_wrapper sys32_creat_wrapper: llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int jg sys_creat # branch to system call - .globl sys32_link_wrapper + .globl sys32_link_wrapper sys32_link_wrapper: llgtr %r2,%r2 # const char * llgtr %r3,%r3 # const char * jg sys_link # branch to system call - .globl sys32_unlink_wrapper + .globl sys32_unlink_wrapper sys32_unlink_wrapper: llgtr %r2,%r2 # const char * jg sys_unlink # branch to system call - .globl sys32_chdir_wrapper + .globl sys32_chdir_wrapper sys32_chdir_wrapper: llgtr %r2,%r2 # const char * jg sys_chdir # branch to system call - .globl sys32_time_wrapper + .globl sys32_time_wrapper sys32_time_wrapper: llgtr %r2,%r2 # int * jg compat_sys_time # branch to system call - .globl sys32_mknod_wrapper + .globl sys32_mknod_wrapper sys32_mknod_wrapper: llgtr %r2,%r2 # const char * - lgfr %r3,%r3 # int + lgfr %r3,%r3 # int llgfr %r4,%r4 # dev jg sys_mknod # branch to system call - .globl sys32_chmod_wrapper + .globl sys32_chmod_wrapper sys32_chmod_wrapper: llgtr %r2,%r2 # const char * llgfr %r3,%r3 # mode_t jg sys_chmod # branch to system call - .globl sys32_lchown16_wrapper + .globl sys32_lchown16_wrapper sys32_lchown16_wrapper: llgtr %r2,%r2 # const char * - llgfr %r3,%r3 # __kernel_old_uid_emu31_t - llgfr %r4,%r4 # __kernel_old_uid_emu31_t + llgfr %r3,%r3 # __kernel_old_uid_emu31_t + llgfr %r4,%r4 # __kernel_old_uid_emu31_t jg sys32_lchown16 # branch to system call - .globl sys32_lseek_wrapper + .globl sys32_lseek_wrapper sys32_lseek_wrapper: llgfr %r2,%r2 # unsigned int lgfr %r3,%r3 # off_t llgfr %r4,%r4 # unsigned int jg sys_lseek # branch to system call -#sys32_getpid_wrapper # void +#sys32_getpid_wrapper # void - .globl sys32_mount_wrapper + .globl sys32_mount_wrapper sys32_mount_wrapper: llgtr %r2,%r2 # char * llgtr %r3,%r3 # char * @@ -103,19 +103,19 @@ sys32_mount_wrapper: llgtr %r6,%r6 # void * jg compat_sys_mount # branch to system call - .globl sys32_oldumount_wrapper + .globl sys32_oldumount_wrapper sys32_oldumount_wrapper: llgtr %r2,%r2 # char * jg sys_oldumount # branch to system call - .globl sys32_setuid16_wrapper + .globl sys32_setuid16_wrapper sys32_setuid16_wrapper: - llgfr %r2,%r2 # __kernel_old_uid_emu31_t + llgfr %r2,%r2 # __kernel_old_uid_emu31_t jg sys32_setuid16 # branch to system call -#sys32_getuid16_wrapper # void +#sys32_getuid16_wrapper # void - .globl sys32_ptrace_wrapper + .globl sys32_ptrace_wrapper sys32_ptrace_wrapper: lgfr %r2,%r2 # long lgfr %r3,%r3 # long @@ -123,168 +123,168 @@ sys32_ptrace_wrapper: llgfr %r5,%r5 # long jg sys_ptrace # branch to system call - .globl sys32_alarm_wrapper + .globl sys32_alarm_wrapper sys32_alarm_wrapper: llgfr %r2,%r2 # unsigned int jg sys_alarm # branch to system call -#sys32_pause_wrapper # void +#sys32_pause_wrapper # void - .globl compat_sys_utime_wrapper + .globl compat_sys_utime_wrapper compat_sys_utime_wrapper: llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct compat_utimbuf * jg compat_sys_utime # branch to system call - .globl sys32_access_wrapper + .globl sys32_access_wrapper sys32_access_wrapper: llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int jg sys_access # branch to system call - .globl sys32_nice_wrapper + .globl sys32_nice_wrapper sys32_nice_wrapper: lgfr %r2,%r2 # int jg sys_nice # branch to system call -#sys32_sync_wrapper # void +#sys32_sync_wrapper # void - .globl sys32_kill_wrapper + .globl sys32_kill_wrapper sys32_kill_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int jg sys_kill # branch to system call - .globl sys32_rename_wrapper + .globl sys32_rename_wrapper sys32_rename_wrapper: llgtr %r2,%r2 # const char * llgtr %r3,%r3 # const char * jg sys_rename # branch to system call - .globl sys32_mkdir_wrapper + .globl sys32_mkdir_wrapper sys32_mkdir_wrapper: llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int jg sys_mkdir # branch to system call - .globl sys32_rmdir_wrapper + .globl sys32_rmdir_wrapper sys32_rmdir_wrapper: llgtr %r2,%r2 # const char * jg sys_rmdir # branch to system call - .globl sys32_dup_wrapper + .globl sys32_dup_wrapper sys32_dup_wrapper: llgfr %r2,%r2 # unsigned int jg sys_dup # branch to system call - .globl sys32_pipe_wrapper + .globl sys32_pipe_wrapper sys32_pipe_wrapper: llgtr %r2,%r2 # u32 * jg sys_pipe # branch to system call - .globl compat_sys_times_wrapper + .globl compat_sys_times_wrapper compat_sys_times_wrapper: llgtr %r2,%r2 # struct compat_tms * jg compat_sys_times # branch to system call - .globl sys32_brk_wrapper + .globl sys32_brk_wrapper sys32_brk_wrapper: llgtr %r2,%r2 # unsigned long jg sys_brk # branch to system call - .globl sys32_setgid16_wrapper + .globl sys32_setgid16_wrapper sys32_setgid16_wrapper: - llgfr %r2,%r2 # __kernel_old_gid_emu31_t + llgfr %r2,%r2 # __kernel_old_gid_emu31_t jg sys32_setgid16 # branch to system call -#sys32_getgid16_wrapper # void +#sys32_getgid16_wrapper # void .globl sys32_signal_wrapper sys32_signal_wrapper: - lgfr %r2,%r2 # int + lgfr %r2,%r2 # int llgtr %r3,%r3 # __sighandler_t jg sys_signal -#sys32_geteuid16_wrapper # void +#sys32_geteuid16_wrapper # void -#sys32_getegid16_wrapper # void +#sys32_getegid16_wrapper # void - .globl sys32_acct_wrapper + .globl sys32_acct_wrapper sys32_acct_wrapper: llgtr %r2,%r2 # char * jg sys_acct # branch to system call - .globl sys32_umount_wrapper + .globl sys32_umount_wrapper sys32_umount_wrapper: llgtr %r2,%r2 # char * lgfr %r3,%r3 # int jg sys_umount # branch to system call - .globl compat_sys_ioctl_wrapper + .globl compat_sys_ioctl_wrapper compat_sys_ioctl_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned int llgfr %r4,%r4 # unsigned int jg compat_sys_ioctl # branch to system call - .globl compat_sys_fcntl_wrapper + .globl compat_sys_fcntl_wrapper compat_sys_fcntl_wrapper: llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # unsigned int + llgfr %r3,%r3 # unsigned int llgfr %r4,%r4 # unsigned long jg compat_sys_fcntl # branch to system call - .globl sys32_setpgid_wrapper + .globl sys32_setpgid_wrapper sys32_setpgid_wrapper: lgfr %r2,%r2 # pid_t lgfr %r3,%r3 # pid_t jg sys_setpgid # branch to system call - .globl sys32_umask_wrapper + .globl sys32_umask_wrapper sys32_umask_wrapper: lgfr %r2,%r2 # int jg sys_umask # branch to system call - .globl sys32_chroot_wrapper + .globl sys32_chroot_wrapper sys32_chroot_wrapper: llgtr %r2,%r2 # char * jg sys_chroot # branch to system call .globl sys32_ustat_wrapper sys32_ustat_wrapper: - llgfr %r2,%r2 # dev_t + llgfr %r2,%r2 # dev_t llgtr %r3,%r3 # struct ustat * jg sys_ustat - .globl sys32_dup2_wrapper + .globl sys32_dup2_wrapper sys32_dup2_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned int jg sys_dup2 # branch to system call -#sys32_getppid_wrapper # void +#sys32_getppid_wrapper # void -#sys32_getpgrp_wrapper # void +#sys32_getpgrp_wrapper # void -#sys32_setsid_wrapper # void +#sys32_setsid_wrapper # void - .globl sys32_sigaction_wrapper + .globl sys32_sigaction_wrapper sys32_sigaction_wrapper: - lgfr %r2,%r2 # int + lgfr %r2,%r2 # int llgtr %r3,%r3 # const struct old_sigaction * llgtr %r4,%r4 # struct old_sigaction32 * jg sys32_sigaction # branch to system call - .globl sys32_setreuid16_wrapper + .globl sys32_setreuid16_wrapper sys32_setreuid16_wrapper: - llgfr %r2,%r2 # __kernel_old_uid_emu31_t - llgfr %r3,%r3 # __kernel_old_uid_emu31_t + llgfr %r2,%r2 # __kernel_old_uid_emu31_t + llgfr %r3,%r3 # __kernel_old_uid_emu31_t jg sys32_setreuid16 # branch to system call - .globl sys32_setregid16_wrapper + .globl sys32_setregid16_wrapper sys32_setregid16_wrapper: - llgfr %r2,%r2 # __kernel_old_gid_emu31_t - llgfr %r3,%r3 # __kernel_old_gid_emu31_t + llgfr %r2,%r2 # __kernel_old_gid_emu31_t + llgfr %r3,%r3 # __kernel_old_gid_emu31_t jg sys32_setregid16 # branch to system call .globl sys_sigsuspend_wrapper @@ -294,95 +294,95 @@ sys_sigsuspend_wrapper: llgfr %r4,%r4 # old_sigset_t jg sys_sigsuspend - .globl compat_sys_sigpending_wrapper + .globl compat_sys_sigpending_wrapper compat_sys_sigpending_wrapper: llgtr %r2,%r2 # compat_old_sigset_t * jg compat_sys_sigpending # branch to system call - .globl sys32_sethostname_wrapper + .globl sys32_sethostname_wrapper sys32_sethostname_wrapper: llgtr %r2,%r2 # char * lgfr %r3,%r3 # int jg sys_sethostname # branch to system call - .globl compat_sys_setrlimit_wrapper + .globl compat_sys_setrlimit_wrapper compat_sys_setrlimit_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # struct rlimit_emu31 * jg compat_sys_setrlimit # branch to system call - .globl compat_sys_old_getrlimit_wrapper + .globl compat_sys_old_getrlimit_wrapper compat_sys_old_getrlimit_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # struct rlimit_emu31 * jg compat_sys_old_getrlimit # branch to system call - .globl compat_sys_getrlimit_wrapper + .globl compat_sys_getrlimit_wrapper compat_sys_getrlimit_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # struct rlimit_emu31 * jg compat_sys_getrlimit # branch to system call - .globl sys32_mmap2_wrapper + .globl sys32_mmap2_wrapper sys32_mmap2_wrapper: llgtr %r2,%r2 # struct mmap_arg_struct_emu31 * jg sys32_mmap2 # branch to system call - .globl compat_sys_getrusage_wrapper + .globl compat_sys_getrusage_wrapper compat_sys_getrusage_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # struct rusage_emu31 * jg compat_sys_getrusage # branch to system call - .globl sys32_gettimeofday_wrapper + .globl sys32_gettimeofday_wrapper sys32_gettimeofday_wrapper: llgtr %r2,%r2 # struct timeval_emu31 * llgtr %r3,%r3 # struct timezone * jg sys32_gettimeofday # branch to system call - .globl sys32_settimeofday_wrapper + .globl sys32_settimeofday_wrapper sys32_settimeofday_wrapper: llgtr %r2,%r2 # struct timeval_emu31 * llgtr %r3,%r3 # struct timezone * jg sys32_settimeofday # branch to system call - .globl sys32_getgroups16_wrapper + .globl sys32_getgroups16_wrapper sys32_getgroups16_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # __kernel_old_gid_emu31_t * jg sys32_getgroups16 # branch to system call - .globl sys32_setgroups16_wrapper + .globl sys32_setgroups16_wrapper sys32_setgroups16_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # __kernel_old_gid_emu31_t * jg sys32_setgroups16 # branch to system call - .globl sys32_symlink_wrapper + .globl sys32_symlink_wrapper sys32_symlink_wrapper: llgtr %r2,%r2 # const char * llgtr %r3,%r3 # const char * jg sys_symlink # branch to system call - .globl sys32_readlink_wrapper + .globl sys32_readlink_wrapper sys32_readlink_wrapper: llgtr %r2,%r2 # const char * llgtr %r3,%r3 # char * lgfr %r4,%r4 # int jg sys_readlink # branch to system call - .globl sys32_uselib_wrapper + .globl sys32_uselib_wrapper sys32_uselib_wrapper: llgtr %r2,%r2 # const char * jg sys_uselib # branch to system call - .globl sys32_swapon_wrapper + .globl sys32_swapon_wrapper sys32_swapon_wrapper: llgtr %r2,%r2 # const char * lgfr %r3,%r3 # int jg sys_swapon # branch to system call - .globl sys32_reboot_wrapper + .globl sys32_reboot_wrapper sys32_reboot_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int @@ -390,121 +390,121 @@ sys32_reboot_wrapper: llgtr %r5,%r5 # void * jg sys_reboot # branch to system call - .globl old32_readdir_wrapper + .globl old32_readdir_wrapper old32_readdir_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # void * llgfr %r4,%r4 # unsigned int jg compat_sys_old_readdir # branch to system call - .globl old32_mmap_wrapper + .globl old32_mmap_wrapper old32_mmap_wrapper: llgtr %r2,%r2 # struct mmap_arg_struct_emu31 * jg old32_mmap # branch to system call - .globl sys32_munmap_wrapper + .globl sys32_munmap_wrapper sys32_munmap_wrapper: llgfr %r2,%r2 # unsigned long - llgfr %r3,%r3 # size_t + llgfr %r3,%r3 # size_t jg sys_munmap # branch to system call - .globl sys32_truncate_wrapper + .globl sys32_truncate_wrapper sys32_truncate_wrapper: llgtr %r2,%r2 # const char * llgfr %r3,%r3 # unsigned long jg sys_truncate # branch to system call - .globl sys32_ftruncate_wrapper + .globl sys32_ftruncate_wrapper sys32_ftruncate_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned long jg sys_ftruncate # branch to system call - .globl sys32_fchmod_wrapper + .globl sys32_fchmod_wrapper sys32_fchmod_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # mode_t jg sys_fchmod # branch to system call - .globl sys32_fchown16_wrapper + .globl sys32_fchown16_wrapper sys32_fchown16_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # compat_uid_t llgfr %r4,%r4 # compat_uid_t jg sys32_fchown16 # branch to system call - .globl sys32_getpriority_wrapper + .globl sys32_getpriority_wrapper sys32_getpriority_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int jg sys_getpriority # branch to system call - .globl sys32_setpriority_wrapper + .globl sys32_setpriority_wrapper sys32_setpriority_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int lgfr %r4,%r4 # int jg sys_setpriority # branch to system call - .globl compat_sys_statfs_wrapper + .globl compat_sys_statfs_wrapper compat_sys_statfs_wrapper: llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct compat_statfs * jg compat_sys_statfs # branch to system call - .globl compat_sys_fstatfs_wrapper + .globl compat_sys_fstatfs_wrapper compat_sys_fstatfs_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # struct compat_statfs * jg compat_sys_fstatfs # branch to system call - .globl compat_sys_socketcall_wrapper + .globl compat_sys_socketcall_wrapper compat_sys_socketcall_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # u32 * jg compat_sys_socketcall # branch to system call - .globl sys32_syslog_wrapper + .globl sys32_syslog_wrapper sys32_syslog_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # char * lgfr %r4,%r4 # int jg sys_syslog # branch to system call - .globl compat_sys_setitimer_wrapper + .globl compat_sys_setitimer_wrapper compat_sys_setitimer_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # struct itimerval_emu31 * llgtr %r4,%r4 # struct itimerval_emu31 * jg compat_sys_setitimer # branch to system call - .globl compat_sys_getitimer_wrapper + .globl compat_sys_getitimer_wrapper compat_sys_getitimer_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # struct itimerval_emu31 * jg compat_sys_getitimer # branch to system call - .globl compat_sys_newstat_wrapper + .globl compat_sys_newstat_wrapper compat_sys_newstat_wrapper: llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct stat_emu31 * jg compat_sys_newstat # branch to system call - .globl compat_sys_newlstat_wrapper + .globl compat_sys_newlstat_wrapper compat_sys_newlstat_wrapper: llgtr %r2,%r2 # char * llgtr %r3,%r3 # struct stat_emu31 * jg compat_sys_newlstat # branch to system call - .globl compat_sys_newfstat_wrapper + .globl compat_sys_newfstat_wrapper compat_sys_newfstat_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # struct stat_emu31 * jg compat_sys_newfstat # branch to system call -#sys32_vhangup_wrapper # void +#sys32_vhangup_wrapper # void - .globl compat_sys_wait4_wrapper + .globl compat_sys_wait4_wrapper compat_sys_wait4_wrapper: lgfr %r2,%r2 # pid_t llgtr %r3,%r3 # unsigned int * @@ -512,17 +512,17 @@ compat_sys_wait4_wrapper: llgtr %r5,%r5 # struct rusage * jg compat_sys_wait4 # branch to system call - .globl sys32_swapoff_wrapper + .globl sys32_swapoff_wrapper sys32_swapoff_wrapper: llgtr %r2,%r2 # const char * jg sys_swapoff # branch to system call - .globl sys32_sysinfo_wrapper + .globl sys32_sysinfo_wrapper sys32_sysinfo_wrapper: llgtr %r2,%r2 # struct sysinfo_emu31 * jg sys32_sysinfo # branch to system call - .globl sys32_ipc_wrapper + .globl sys32_ipc_wrapper sys32_ipc_wrapper: llgfr %r2,%r2 # uint lgfr %r3,%r3 # int @@ -531,59 +531,59 @@ sys32_ipc_wrapper: llgfr %r6,%r6 # u32 jg sys32_ipc # branch to system call - .globl sys32_fsync_wrapper + .globl sys32_fsync_wrapper sys32_fsync_wrapper: llgfr %r2,%r2 # unsigned int jg sys_fsync # branch to system call -#sys32_sigreturn_wrapper # done in sigreturn_glue +#sys32_sigreturn_wrapper # done in sigreturn_glue -#sys32_clone_wrapper # done in clone_glue +#sys32_clone_wrapper # done in clone_glue - .globl sys32_setdomainname_wrapper + .globl sys32_setdomainname_wrapper sys32_setdomainname_wrapper: llgtr %r2,%r2 # char * lgfr %r3,%r3 # int jg sys_setdomainname # branch to system call - .globl sys32_newuname_wrapper + .globl sys32_newuname_wrapper sys32_newuname_wrapper: llgtr %r2,%r2 # struct new_utsname * jg s390x_newuname # branch to system call - .globl compat_sys_adjtimex_wrapper + .globl compat_sys_adjtimex_wrapper compat_sys_adjtimex_wrapper: llgtr %r2,%r2 # struct compat_timex * jg compat_sys_adjtimex # branch to system call - .globl sys32_mprotect_wrapper + .globl sys32_mprotect_wrapper sys32_mprotect_wrapper: llgtr %r2,%r2 # unsigned long (actually pointer llgfr %r3,%r3 # size_t llgfr %r4,%r4 # unsigned long jg sys_mprotect # branch to system call - .globl compat_sys_sigprocmask_wrapper + .globl compat_sys_sigprocmask_wrapper compat_sys_sigprocmask_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # compat_old_sigset_t * llgtr %r4,%r4 # compat_old_sigset_t * jg compat_sys_sigprocmask # branch to system call - .globl sys32_init_module_wrapper + .globl sys32_init_module_wrapper sys32_init_module_wrapper: llgtr %r2,%r2 # void * llgfr %r3,%r3 # unsigned long llgtr %r4,%r4 # char * jg sys32_init_module # branch to system call - .globl sys32_delete_module_wrapper + .globl sys32_delete_module_wrapper sys32_delete_module_wrapper: llgtr %r2,%r2 # const char * llgfr %r3,%r3 # unsigned int jg sys32_delete_module # branch to system call - .globl sys32_quotactl_wrapper + .globl sys32_quotactl_wrapper sys32_quotactl_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # const char * @@ -591,45 +591,45 @@ sys32_quotactl_wrapper: llgtr %r5,%r5 # caddr_t jg sys_quotactl # branch to system call - .globl sys32_getpgid_wrapper + .globl sys32_getpgid_wrapper sys32_getpgid_wrapper: lgfr %r2,%r2 # pid_t jg sys_getpgid # branch to system call - .globl sys32_fchdir_wrapper + .globl sys32_fchdir_wrapper sys32_fchdir_wrapper: llgfr %r2,%r2 # unsigned int jg sys_fchdir # branch to system call - .globl sys32_bdflush_wrapper + .globl sys32_bdflush_wrapper sys32_bdflush_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # long jg sys_bdflush # branch to system call - .globl sys32_sysfs_wrapper + .globl sys32_sysfs_wrapper sys32_sysfs_wrapper: lgfr %r2,%r2 # int llgfr %r3,%r3 # unsigned long llgfr %r4,%r4 # unsigned long jg sys_sysfs # branch to system call - .globl sys32_personality_wrapper + .globl sys32_personality_wrapper sys32_personality_wrapper: llgfr %r2,%r2 # unsigned long jg s390x_personality # branch to system call - .globl sys32_setfsuid16_wrapper + .globl sys32_setfsuid16_wrapper sys32_setfsuid16_wrapper: - llgfr %r2,%r2 # __kernel_old_uid_emu31_t + llgfr %r2,%r2 # __kernel_old_uid_emu31_t jg sys32_setfsuid16 # branch to system call - .globl sys32_setfsgid16_wrapper + .globl sys32_setfsgid16_wrapper sys32_setfsgid16_wrapper: - llgfr %r2,%r2 # __kernel_old_gid_emu31_t + llgfr %r2,%r2 # __kernel_old_gid_emu31_t jg sys32_setfsgid16 # branch to system call - .globl sys32_llseek_wrapper + .globl sys32_llseek_wrapper sys32_llseek_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned long @@ -638,14 +638,14 @@ sys32_llseek_wrapper: llgfr %r6,%r6 # unsigned int jg sys_llseek # branch to system call - .globl sys32_getdents_wrapper + .globl sys32_getdents_wrapper sys32_getdents_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # void * llgfr %r4,%r4 # unsigned int jg compat_sys_getdents # branch to system call - .globl compat_sys_select_wrapper + .globl compat_sys_select_wrapper compat_sys_select_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # compat_fd_set * @@ -654,113 +654,113 @@ compat_sys_select_wrapper: llgtr %r6,%r6 # struct compat_timeval * jg compat_sys_select # branch to system call - .globl sys32_flock_wrapper + .globl sys32_flock_wrapper sys32_flock_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned int jg sys_flock # branch to system call - .globl sys32_msync_wrapper + .globl sys32_msync_wrapper sys32_msync_wrapper: llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # size_t lgfr %r4,%r4 # int jg sys_msync # branch to system call - .globl compat_sys_readv_wrapper + .globl compat_sys_readv_wrapper compat_sys_readv_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # const struct compat_iovec * llgfr %r4,%r4 # unsigned long jg compat_sys_readv # branch to system call - .globl compat_sys_writev_wrapper + .globl compat_sys_writev_wrapper compat_sys_writev_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # const struct compat_iovec * llgfr %r4,%r4 # unsigned long jg compat_sys_writev # branch to system call - .globl sys32_getsid_wrapper + .globl sys32_getsid_wrapper sys32_getsid_wrapper: lgfr %r2,%r2 # pid_t jg sys_getsid # branch to system call - .globl sys32_fdatasync_wrapper + .globl sys32_fdatasync_wrapper sys32_fdatasync_wrapper: llgfr %r2,%r2 # unsigned int jg sys_fdatasync # branch to system call -#sys32_sysctl_wrapper # tbd +#sys32_sysctl_wrapper # tbd - .globl sys32_mlock_wrapper + .globl sys32_mlock_wrapper sys32_mlock_wrapper: llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # size_t jg sys_mlock # branch to system call - .globl sys32_munlock_wrapper + .globl sys32_munlock_wrapper sys32_munlock_wrapper: llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # size_t jg sys_munlock # branch to system call - .globl sys32_mlockall_wrapper + .globl sys32_mlockall_wrapper sys32_mlockall_wrapper: lgfr %r2,%r2 # int jg sys_mlockall # branch to system call -#sys32_munlockall_wrapper # void +#sys32_munlockall_wrapper # void - .globl sys32_sched_setparam_wrapper + .globl sys32_sched_setparam_wrapper sys32_sched_setparam_wrapper: lgfr %r2,%r2 # pid_t llgtr %r3,%r3 # struct sched_param * jg sys_sched_setparam # branch to system call - .globl sys32_sched_getparam_wrapper + .globl sys32_sched_getparam_wrapper sys32_sched_getparam_wrapper: lgfr %r2,%r2 # pid_t llgtr %r3,%r3 # struct sched_param * jg sys_sched_getparam # branch to system call - .globl sys32_sched_setscheduler_wrapper + .globl sys32_sched_setscheduler_wrapper sys32_sched_setscheduler_wrapper: lgfr %r2,%r2 # pid_t lgfr %r3,%r3 # int llgtr %r4,%r4 # struct sched_param * jg sys_sched_setscheduler # branch to system call - .globl sys32_sched_getscheduler_wrapper + .globl sys32_sched_getscheduler_wrapper sys32_sched_getscheduler_wrapper: lgfr %r2,%r2 # pid_t jg sys_sched_getscheduler # branch to system call -#sys32_sched_yield_wrapper # void +#sys32_sched_yield_wrapper # void - .globl sys32_sched_get_priority_max_wrapper + .globl sys32_sched_get_priority_max_wrapper sys32_sched_get_priority_max_wrapper: lgfr %r2,%r2 # int jg sys_sched_get_priority_max # branch to system call - .globl sys32_sched_get_priority_min_wrapper + .globl sys32_sched_get_priority_min_wrapper sys32_sched_get_priority_min_wrapper: lgfr %r2,%r2 # int jg sys_sched_get_priority_min # branch to system call - .globl sys32_sched_rr_get_interval_wrapper + .globl sys32_sched_rr_get_interval_wrapper sys32_sched_rr_get_interval_wrapper: lgfr %r2,%r2 # pid_t llgtr %r3,%r3 # struct compat_timespec * jg sys32_sched_rr_get_interval # branch to system call - .globl compat_sys_nanosleep_wrapper + .globl compat_sys_nanosleep_wrapper compat_sys_nanosleep_wrapper: llgtr %r2,%r2 # struct compat_timespec * llgtr %r3,%r3 # struct compat_timespec * jg compat_sys_nanosleep # branch to system call - .globl sys32_mremap_wrapper + .globl sys32_mremap_wrapper sys32_mremap_wrapper: llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # unsigned long @@ -769,49 +769,49 @@ sys32_mremap_wrapper: llgfr %r6,%r6 # unsigned long jg sys_mremap # branch to system call - .globl sys32_setresuid16_wrapper + .globl sys32_setresuid16_wrapper sys32_setresuid16_wrapper: - llgfr %r2,%r2 # __kernel_old_uid_emu31_t - llgfr %r3,%r3 # __kernel_old_uid_emu31_t - llgfr %r4,%r4 # __kernel_old_uid_emu31_t + llgfr %r2,%r2 # __kernel_old_uid_emu31_t + llgfr %r3,%r3 # __kernel_old_uid_emu31_t + llgfr %r4,%r4 # __kernel_old_uid_emu31_t jg sys32_setresuid16 # branch to system call - .globl sys32_getresuid16_wrapper + .globl sys32_getresuid16_wrapper sys32_getresuid16_wrapper: llgtr %r2,%r2 # __kernel_old_uid_emu31_t * llgtr %r3,%r3 # __kernel_old_uid_emu31_t * llgtr %r4,%r4 # __kernel_old_uid_emu31_t * jg sys32_getresuid16 # branch to system call - .globl sys32_poll_wrapper + .globl sys32_poll_wrapper sys32_poll_wrapper: - llgtr %r2,%r2 # struct pollfd * - llgfr %r3,%r3 # unsigned int - lgfr %r4,%r4 # long + llgtr %r2,%r2 # struct pollfd * + llgfr %r3,%r3 # unsigned int + lgfr %r4,%r4 # long jg sys_poll # branch to system call - .globl compat_sys_nfsservctl_wrapper + .globl compat_sys_nfsservctl_wrapper compat_sys_nfsservctl_wrapper: - lgfr %r2,%r2 # int + lgfr %r2,%r2 # int llgtr %r3,%r3 # struct compat_nfsctl_arg* llgtr %r4,%r4 # union compat_nfsctl_res* jg compat_sys_nfsservctl # branch to system call - .globl sys32_setresgid16_wrapper + .globl sys32_setresgid16_wrapper sys32_setresgid16_wrapper: - llgfr %r2,%r2 # __kernel_old_gid_emu31_t - llgfr %r3,%r3 # __kernel_old_gid_emu31_t - llgfr %r4,%r4 # __kernel_old_gid_emu31_t + llgfr %r2,%r2 # __kernel_old_gid_emu31_t + llgfr %r3,%r3 # __kernel_old_gid_emu31_t + llgfr %r4,%r4 # __kernel_old_gid_emu31_t jg sys32_setresgid16 # branch to system call - .globl sys32_getresgid16_wrapper + .globl sys32_getresgid16_wrapper sys32_getresgid16_wrapper: llgtr %r2,%r2 # __kernel_old_gid_emu31_t * llgtr %r3,%r3 # __kernel_old_gid_emu31_t * llgtr %r4,%r4 # __kernel_old_gid_emu31_t * jg sys32_getresgid16 # branch to system call - .globl sys32_prctl_wrapper + .globl sys32_prctl_wrapper sys32_prctl_wrapper: lgfr %r2,%r2 # int llgfr %r3,%r3 # unsigned long @@ -820,9 +820,9 @@ sys32_prctl_wrapper: llgfr %r6,%r6 # unsigned long jg sys_prctl # branch to system call -#sys32_rt_sigreturn_wrapper # done in rt_sigreturn_glue +#sys32_rt_sigreturn_wrapper # done in rt_sigreturn_glue - .globl sys32_rt_sigaction_wrapper + .globl sys32_rt_sigaction_wrapper sys32_rt_sigaction_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # const struct sigaction_emu31 * @@ -830,7 +830,7 @@ sys32_rt_sigaction_wrapper: llgfr %r5,%r5 # size_t jg sys32_rt_sigaction # branch to system call - .globl sys32_rt_sigprocmask_wrapper + .globl sys32_rt_sigprocmask_wrapper sys32_rt_sigprocmask_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # old_sigset_emu31 * @@ -838,13 +838,13 @@ sys32_rt_sigprocmask_wrapper: llgfr %r5,%r5 # size_t jg sys32_rt_sigprocmask # branch to system call - .globl sys32_rt_sigpending_wrapper + .globl sys32_rt_sigpending_wrapper sys32_rt_sigpending_wrapper: llgtr %r2,%r2 # sigset_emu31 * llgfr %r3,%r3 # size_t jg sys32_rt_sigpending # branch to system call - .globl compat_sys_rt_sigtimedwait_wrapper + .globl compat_sys_rt_sigtimedwait_wrapper compat_sys_rt_sigtimedwait_wrapper: llgtr %r2,%r2 # const sigset_emu31_t * llgtr %r3,%r3 # siginfo_emu31_t * @@ -852,7 +852,7 @@ compat_sys_rt_sigtimedwait_wrapper: llgfr %r5,%r5 # size_t jg compat_sys_rt_sigtimedwait # branch to system call - .globl sys32_rt_sigqueueinfo_wrapper + .globl sys32_rt_sigqueueinfo_wrapper sys32_rt_sigqueueinfo_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int @@ -865,7 +865,7 @@ compat_sys_rt_sigsuspend_wrapper: llgfr %r3,%r3 # compat_size_t jg compat_sys_rt_sigsuspend - .globl sys32_pread64_wrapper + .globl sys32_pread64_wrapper sys32_pread64_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # char * @@ -874,7 +874,7 @@ sys32_pread64_wrapper: llgfr %r6,%r6 # u32 jg sys32_pread64 # branch to system call - .globl sys32_pwrite64_wrapper + .globl sys32_pwrite64_wrapper sys32_pwrite64_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # const char * @@ -883,26 +883,26 @@ sys32_pwrite64_wrapper: llgfr %r6,%r6 # u32 jg sys32_pwrite64 # branch to system call - .globl sys32_chown16_wrapper + .globl sys32_chown16_wrapper sys32_chown16_wrapper: llgtr %r2,%r2 # const char * - llgfr %r3,%r3 # __kernel_old_uid_emu31_t - llgfr %r4,%r4 # __kernel_old_gid_emu31_t + llgfr %r3,%r3 # __kernel_old_uid_emu31_t + llgfr %r4,%r4 # __kernel_old_gid_emu31_t jg sys32_chown16 # branch to system call - .globl sys32_getcwd_wrapper + .globl sys32_getcwd_wrapper sys32_getcwd_wrapper: llgtr %r2,%r2 # char * llgfr %r3,%r3 # unsigned long jg sys_getcwd # branch to system call - .globl sys32_capget_wrapper + .globl sys32_capget_wrapper sys32_capget_wrapper: llgtr %r2,%r2 # cap_user_header_t llgtr %r3,%r3 # cap_user_data_t jg sys_capget # branch to system call - .globl sys32_capset_wrapper + .globl sys32_capset_wrapper sys32_capset_wrapper: llgtr %r2,%r2 # cap_user_header_t llgtr %r3,%r3 # const cap_user_data_t @@ -910,11 +910,11 @@ sys32_capset_wrapper: .globl sys32_sigaltstack_wrapper sys32_sigaltstack_wrapper: - llgtr %r2,%r2 # const stack_emu31_t * - llgtr %r3,%r3 # stack_emu31_t * + llgtr %r2,%r2 # const stack_emu31_t * + llgtr %r3,%r3 # stack_emu31_t * jg sys32_sigaltstack - .globl sys32_sendfile_wrapper + .globl sys32_sendfile_wrapper sys32_sendfile_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int @@ -922,33 +922,33 @@ sys32_sendfile_wrapper: llgfr %r5,%r5 # size_t jg sys32_sendfile # branch to system call -#sys32_vfork_wrapper # done in vfork_glue +#sys32_vfork_wrapper # done in vfork_glue - .globl sys32_truncate64_wrapper + .globl sys32_truncate64_wrapper sys32_truncate64_wrapper: llgtr %r2,%r2 # const char * llgfr %r3,%r3 # unsigned long llgfr %r4,%r4 # unsigned long jg sys32_truncate64 # branch to system call - .globl sys32_ftruncate64_wrapper + .globl sys32_ftruncate64_wrapper sys32_ftruncate64_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # unsigned long llgfr %r4,%r4 # unsigned long jg sys32_ftruncate64 # branch to system call - .globl sys32_lchown_wrapper + .globl sys32_lchown_wrapper sys32_lchown_wrapper: llgtr %r2,%r2 # const char * llgfr %r3,%r3 # uid_t llgfr %r4,%r4 # gid_t jg sys_lchown # branch to system call -#sys32_getuid_wrapper # void -#sys32_getgid_wrapper # void -#sys32_geteuid_wrapper # void -#sys32_getegid_wrapper # void +#sys32_getuid_wrapper # void +#sys32_getgid_wrapper # void +#sys32_geteuid_wrapper # void +#sys32_getegid_wrapper # void .globl sys32_setreuid_wrapper sys32_setreuid_wrapper: @@ -962,111 +962,111 @@ sys32_setregid_wrapper: llgfr %r3,%r3 # gid_t jg sys_setregid # branch to system call - .globl sys32_getgroups_wrapper + .globl sys32_getgroups_wrapper sys32_getgroups_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # gid_t * jg sys_getgroups # branch to system call - .globl sys32_setgroups_wrapper + .globl sys32_setgroups_wrapper sys32_setgroups_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # gid_t * jg sys_setgroups # branch to system call - .globl sys32_fchown_wrapper + .globl sys32_fchown_wrapper sys32_fchown_wrapper: llgfr %r2,%r2 # unsigned int llgfr %r3,%r3 # uid_t llgfr %r4,%r4 # gid_t jg sys_fchown # branch to system call - .globl sys32_setresuid_wrapper + .globl sys32_setresuid_wrapper sys32_setresuid_wrapper: llgfr %r2,%r2 # uid_t llgfr %r3,%r3 # uid_t llgfr %r4,%r4 # uid_t jg sys_setresuid # branch to system call - .globl sys32_getresuid_wrapper + .globl sys32_getresuid_wrapper sys32_getresuid_wrapper: llgtr %r2,%r2 # uid_t * llgtr %r3,%r3 # uid_t * llgtr %r4,%r4 # uid_t * jg sys_getresuid # branch to system call - .globl sys32_setresgid_wrapper + .globl sys32_setresgid_wrapper sys32_setresgid_wrapper: llgfr %r2,%r2 # gid_t llgfr %r3,%r3 # gid_t llgfr %r4,%r4 # gid_t jg sys_setresgid # branch to system call - .globl sys32_getresgid_wrapper + .globl sys32_getresgid_wrapper sys32_getresgid_wrapper: llgtr %r2,%r2 # gid_t * llgtr %r3,%r3 # gid_t * llgtr %r4,%r4 # gid_t * jg sys_getresgid # branch to system call - .globl sys32_chown_wrapper + .globl sys32_chown_wrapper sys32_chown_wrapper: llgtr %r2,%r2 # const char * llgfr %r3,%r3 # uid_t llgfr %r4,%r4 # gid_t jg sys_chown # branch to system call - .globl sys32_setuid_wrapper + .globl sys32_setuid_wrapper sys32_setuid_wrapper: llgfr %r2,%r2 # uid_t jg sys_setuid # branch to system call - .globl sys32_setgid_wrapper + .globl sys32_setgid_wrapper sys32_setgid_wrapper: llgfr %r2,%r2 # gid_t jg sys_setgid # branch to system call - .globl sys32_setfsuid_wrapper + .globl sys32_setfsuid_wrapper sys32_setfsuid_wrapper: llgfr %r2,%r2 # uid_t jg sys_setfsuid # branch to system call - .globl sys32_setfsgid_wrapper + .globl sys32_setfsgid_wrapper sys32_setfsgid_wrapper: llgfr %r2,%r2 # gid_t jg sys_setfsgid # branch to system call - .globl sys32_pivot_root_wrapper + .globl sys32_pivot_root_wrapper sys32_pivot_root_wrapper: llgtr %r2,%r2 # const char * llgtr %r3,%r3 # const char * jg sys_pivot_root # branch to system call - .globl sys32_mincore_wrapper + .globl sys32_mincore_wrapper sys32_mincore_wrapper: llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # size_t llgtr %r4,%r4 # unsigned char * jg sys_mincore # branch to system call - .globl sys32_madvise_wrapper + .globl sys32_madvise_wrapper sys32_madvise_wrapper: llgfr %r2,%r2 # unsigned long llgfr %r3,%r3 # size_t lgfr %r4,%r4 # int jg sys_madvise # branch to system call - .globl sys32_getdents64_wrapper + .globl sys32_getdents64_wrapper sys32_getdents64_wrapper: llgfr %r2,%r2 # unsigned int llgtr %r3,%r3 # void * llgfr %r4,%r4 # unsigned int jg sys_getdents64 # branch to system call - .globl compat_sys_fcntl64_wrapper + .globl compat_sys_fcntl64_wrapper compat_sys_fcntl64_wrapper: llgfr %r2,%r2 # unsigned int - llgfr %r3,%r3 # unsigned int + llgfr %r3,%r3 # unsigned int llgfr %r4,%r4 # unsigned long jg compat_sys_fcntl64 # branch to system call @@ -1087,10 +1087,10 @@ sys32_stime_wrapper: llgtr %r2,%r2 # long * jg compat_sys_stime # branch to system call - .globl sys32_sysctl_wrapper + .globl sys32_sysctl_wrapper sys32_sysctl_wrapper: - llgtr %r2,%r2 # struct __sysctl_args32 * - jg sys32_sysctl + llgtr %r2,%r2 # struct __sysctl_args32 * + jg sys32_sysctl .globl sys32_fstat64_wrapper sys32_fstat64_wrapper: @@ -1098,7 +1098,7 @@ sys32_fstat64_wrapper: llgtr %r3,%r3 # struct stat64 * jg sys32_fstat64 # branch to system call - .globl compat_sys_futex_wrapper + .globl compat_sys_futex_wrapper compat_sys_futex_wrapper: llgtr %r2,%r2 # u32 * lgfr %r3,%r3 # int @@ -1213,22 +1213,22 @@ sys32_sched_getaffinity_wrapper: llgtr %r4,%r4 # unsigned long * jg compat_sys_sched_getaffinity - .globl sys32_exit_group_wrapper + .globl sys32_exit_group_wrapper sys32_exit_group_wrapper: lgfr %r2,%r2 # int jg sys_exit_group # branch to system call - .globl sys32_set_tid_address_wrapper + .globl sys32_set_tid_address_wrapper sys32_set_tid_address_wrapper: llgtr %r2,%r2 # int * jg sys_set_tid_address # branch to system call - .globl sys_epoll_create_wrapper + .globl sys_epoll_create_wrapper sys_epoll_create_wrapper: lgfr %r2,%r2 # int jg sys_epoll_create # branch to system call - .globl sys_epoll_ctl_wrapper + .globl sys_epoll_ctl_wrapper sys_epoll_ctl_wrapper: lgfr %r2,%r2 # int lgfr %r3,%r3 # int @@ -1236,7 +1236,7 @@ sys_epoll_ctl_wrapper: llgtr %r5,%r5 # struct epoll_event * jg sys_epoll_ctl # branch to system call - .globl sys_epoll_wait_wrapper + .globl sys_epoll_wait_wrapper sys_epoll_wait_wrapper: lgfr %r2,%r2 # int llgtr %r3,%r3 # struct epoll_event * diff --git a/trunk/arch/s390/kernel/cpcmd.c b/trunk/arch/s390/kernel/cpcmd.c index 1eae74e72f95..4ef44e536b2c 100644 --- a/trunk/arch/s390/kernel/cpcmd.c +++ b/trunk/arch/s390/kernel/cpcmd.c @@ -25,8 +25,11 @@ static char cpcmd_buf[241]; */ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) { - unsigned long flags, cmdlen; - int return_code, return_len; + const int mask = 0x40000000L; + unsigned long flags; + int return_code; + int return_len; + int cmdlen; spin_lock_irqsave(&cpcmd_lock, flags); cmdlen = strlen(cmd); @@ -35,44 +38,64 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) ASCEBC(cpcmd_buf, cmdlen); if (response != NULL && rlen > 0) { - register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf; - register unsigned long reg3 asm ("3") = (addr_t) response; - register unsigned long reg4 asm ("4") = cmdlen | 0x40000000L; - register unsigned long reg5 asm ("5") = rlen; - memset(response, 0, rlen); - asm volatile( #ifndef CONFIG_64BIT - " diag %2,%0,0x8\n" - " brc 8,1f\n" - " ar %1,%4\n" + asm volatile ( "lra 2,0(%2)\n" + "lr 4,%3\n" + "o 4,%6\n" + "lra 3,0(%4)\n" + "lr 5,%5\n" + "diag 2,4,0x8\n" + "brc 8, 1f\n" + "ar 5, %5\n" + "1: \n" + "lr %0,4\n" + "lr %1,5\n" + : "=d" (return_code), "=d" (return_len) + : "a" (cpcmd_buf), "d" (cmdlen), + "a" (response), "d" (rlen), "m" (mask) + : "cc", "2", "3", "4", "5" ); #else /* CONFIG_64BIT */ - " sam31\n" - " diag %2,%0,0x8\n" - " sam64\n" - " brc 8,1f\n" - " agr %1,%4\n" + asm volatile ( "lrag 2,0(%2)\n" + "lgr 4,%3\n" + "o 4,%6\n" + "lrag 3,0(%4)\n" + "lgr 5,%5\n" + "sam31\n" + "diag 2,4,0x8\n" + "sam64\n" + "brc 8, 1f\n" + "agr 5, %5\n" + "1: \n" + "lgr %0,4\n" + "lgr %1,5\n" + : "=d" (return_code), "=d" (return_len) + : "a" (cpcmd_buf), "d" (cmdlen), + "a" (response), "d" (rlen), "m" (mask) + : "cc", "2", "3", "4", "5" ); #endif /* CONFIG_64BIT */ - "1:\n" - : "+d" (reg4), "+d" (reg5) - : "d" (reg2), "d" (reg3), "d" (rlen) : "cc"); - return_code = (int) reg4; - return_len = (int) reg5; EBCASC(response, rlen); } else { - register unsigned long reg2 asm ("2") = (addr_t) cpcmd_buf; - register unsigned long reg3 asm ("3") = cmdlen; return_len = 0; - asm volatile( #ifndef CONFIG_64BIT - " diag %1,%0,0x8\n" + asm volatile ( "lra 2,0(%1)\n" + "lr 3,%2\n" + "diag 2,3,0x8\n" + "lr %0,3\n" + : "=d" (return_code) + : "a" (cpcmd_buf), "d" (cmdlen) + : "2", "3" ); #else /* CONFIG_64BIT */ - " sam31\n" - " diag %1,%0,0x8\n" - " sam64\n" + asm volatile ( "lrag 2,0(%1)\n" + "lgr 3,%2\n" + "sam31\n" + "diag 2,3,0x8\n" + "sam64\n" + "lgr %0,3\n" + : "=d" (return_code) + : "a" (cpcmd_buf), "d" (cmdlen) + : "2", "3" ); #endif /* CONFIG_64BIT */ - : "+d" (reg3) : "d" (reg2) : "cc"); - return_code = (int) reg3; } spin_unlock_irqrestore(&cpcmd_lock, flags); if (response_code != NULL) diff --git a/trunk/arch/s390/kernel/debug.c b/trunk/arch/s390/kernel/debug.c index 43f3d0c7e132..7ba20922a535 100644 --- a/trunk/arch/s390/kernel/debug.c +++ b/trunk/arch/s390/kernel/debug.c @@ -603,7 +603,7 @@ debug_open(struct inode *inode, struct file *file) debug_info_t *debug_info, *debug_info_snapshot; down(&debug_lock); - debug_info = file->f_dentry->d_inode->i_private; + debug_info = (struct debug_info*)file->f_dentry->d_inode->u.generic_ip; /* find debug view */ for (i = 0; i < DEBUG_MAX_VIEWS; i++) { if (!debug_info->views[i]) diff --git a/trunk/arch/s390/kernel/entry.S b/trunk/arch/s390/kernel/entry.S index dddc3de30401..0c712b78a7e8 100644 --- a/trunk/arch/s390/kernel/entry.S +++ b/trunk/arch/s390/kernel/entry.S @@ -4,8 +4,8 @@ * * Copyright (C) IBM Corp. 1999,2006 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - * Hartmut Penner (hp@de.ibm.com), - * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), + * Hartmut Penner (hp@de.ibm.com), + * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), * Heiko Carstens */ @@ -24,29 +24,29 @@ * Stack layout for the system_call stack entry. * The first few entries are identical to the user_regs_struct. */ -SP_PTREGS = STACK_FRAME_OVERHEAD -SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS -SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW -SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS -SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 4 -SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 -SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 12 -SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 -SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 20 -SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 -SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 28 -SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 -SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 36 -SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 -SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 44 -SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 -SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 52 -SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 -SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60 -SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 -SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC -SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP -SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE +SP_PTREGS = STACK_FRAME_OVERHEAD +SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS +SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW +SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS +SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 4 +SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 +SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 12 +SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 +SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 20 +SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 +SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 28 +SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 +SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 36 +SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 +SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 44 +SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 +SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 52 +SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 +SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60 +SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 +SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC +SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP +SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ _TIF_MCCK_PENDING | _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) @@ -81,14 +81,14 @@ STACK_SIZE = 1 << STACK_SHIFT * R15 - kernel stack pointer */ - .macro STORE_TIMER lc_offset + .macro STORE_TIMER lc_offset #ifdef CONFIG_VIRT_CPU_ACCOUNTING stpt \lc_offset #endif .endm #ifdef CONFIG_VIRT_CPU_ACCOUNTING - .macro UPDATE_VTIME lc_from,lc_to,lc_sum + .macro UPDATE_VTIME lc_from,lc_to,lc_sum lm %r10,%r11,\lc_from sl %r10,\lc_to sl %r11,\lc_to+4 @@ -147,7 +147,7 @@ STACK_SIZE = 1 << STACK_SHIFT 2: .endm - .macro CREATE_STACK_FRAME psworg,savearea + .macro CREATE_STACK_FRAME psworg,savearea s %r15,BASED(.Lc_spsize) # make room for registers & psw mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack la %r12,\psworg @@ -160,7 +160,7 @@ STACK_SIZE = 1 << STACK_SHIFT st %r12,__SF_BACKCHAIN(%r15) # clear back chain .endm - .macro RESTORE_ALL psworg,sync + .macro RESTORE_ALL psworg,sync mvc \psworg(8),SP_PSW(%r15) # move user PSW to lowcore .if !\sync ni \psworg+1,0xfd # clear wait state bit @@ -177,16 +177,16 @@ STACK_SIZE = 1 << STACK_SHIFT * Returns: * gpr2 = prev */ - .globl __switch_to + .globl __switch_to __switch_to: - basr %r1,0 + basr %r1,0 __switch_to_base: tm __THREAD_per(%r3),0xe8 # new process is using per ? bz __switch_to_noper-__switch_to_base(%r1) # if not we're fine - stctl %c9,%c11,__SF_EMPTY(%r15) # We are using per stuff - clc __THREAD_per(12,%r3),__SF_EMPTY(%r15) - be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's - lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't + stctl %c9,%c11,__SF_EMPTY(%r15) # We are using per stuff + clc __THREAD_per(12,%r3),__SF_EMPTY(%r15) + be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's + lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't __switch_to_noper: l %r4,__THREAD_info(%r2) # get thread_info of prev tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? @@ -195,13 +195,13 @@ __switch_to_noper: l %r4,__THREAD_info(%r3) # get thread_info of next oi __TI_flags+3(%r4),_TIF_MCCK_PENDING # set it in next __switch_to_no_mcck: - stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task + stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task st %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp l %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp lm %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task st %r3,__LC_CURRENT # __LC_CURRENT = current task struct lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 - l %r3,__THREAD_info(%r3) # load thread_info from task struct + l %r3,__THREAD_info(%r3) # load thread_info from task struct st %r3,__LC_THREAD_INFO ahi %r3,STACK_SIZE st %r3,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack @@ -213,7 +213,7 @@ __critical_start: * are executed with interrupts enabled. */ - .globl system_call + .globl system_call system_call: STORE_TIMER __LC_SYNC_ENTER_TIMER sysc_saveall: @@ -233,24 +233,24 @@ sysc_update: #endif sysc_do_svc: l %r9,__LC_THREAD_INFO # load pointer to thread_info struct - sla %r7,2 # *4 and test for svc 0 - bnz BASED(sysc_nr_ok) # svc number > 0 + sla %r7,2 # *4 and test for svc 0 + bnz BASED(sysc_nr_ok) # svc number > 0 # svc 0: system call number in %r1 cl %r1,BASED(.Lnr_syscalls) bnl BASED(sysc_nr_ok) - lr %r7,%r1 # copy svc number to %r7 - sla %r7,2 # *4 + lr %r7,%r1 # copy svc number to %r7 + sla %r7,2 # *4 sysc_nr_ok: mvc SP_ARGS(4,%r15),SP_R7(%r15) sysc_do_restart: l %r8,BASED(.Lsysc_table) tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) l %r8,0(%r7,%r8) # get system call addr. - bnz BASED(sysc_tracesys) - basr %r14,%r8 # call sys_xxxx - st %r2,SP_R2(%r15) # store return value (change R2 on stack) - # ATTENTION: check sys_execve_glue before - # changing anything here !! + bnz BASED(sysc_tracesys) + basr %r14,%r8 # call sys_xxxx + st %r2,SP_R2(%r15) # store return value (change R2 on stack) + # ATTENTION: check sys_execve_glue before + # changing anything here !! sysc_return: tm SP_PSW+1(%r15),0x01 # returning to user ? @@ -258,14 +258,14 @@ sysc_return: tm __TI_flags+3(%r9),_TIF_WORK_SVC bnz BASED(sysc_work) # there is work to do (signals etc.) sysc_leave: - RESTORE_ALL __LC_RETURN_PSW,1 + RESTORE_ALL __LC_RETURN_PSW,1 # # recheck if there is more work to do # sysc_work_loop: tm __TI_flags+3(%r9),_TIF_WORK_SVC - bz BASED(sysc_leave) # there is no work to do + bz BASED(sysc_leave) # there is no work to do # # One of the work bits is on. Find out which one. # @@ -284,11 +284,11 @@ sysc_work: # # _TIF_NEED_RESCHED is set, call schedule -# -sysc_reschedule: - l %r1,BASED(.Lschedule) - la %r14,BASED(sysc_work_loop) - br %r1 # call scheduler +# +sysc_reschedule: + l %r1,BASED(.Lschedule) + la %r14,BASED(sysc_work_loop) + br %r1 # call scheduler # # _TIF_MCCK_PENDING is set, call handler @@ -301,11 +301,11 @@ sysc_mcck_pending: # # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal # -sysc_sigpending: +sysc_sigpending: ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Ldo_signal) - basr %r14,%r1 # call do_signal + la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Ldo_signal) + basr %r14,%r1 # call do_signal tm __TI_flags+3(%r9),_TIF_RESTART_SVC bo BASED(sysc_restart) tm __TI_flags+3(%r9),_TIF_SINGLE_STEP @@ -317,11 +317,11 @@ sysc_sigpending: # sysc_restart: ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC - l %r7,SP_R2(%r15) # load new svc number + l %r7,SP_R2(%r15) # load new svc number sla %r7,2 mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument - lm %r2,%r6,SP_R2(%r15) # load svc arguments - b BASED(sysc_do_restart) # restart svc + lm %r2,%r6,SP_R2(%r15) # load svc arguments + b BASED(sysc_do_restart) # restart svc # # _TIF_SINGLE_STEP is set, call do_single_step @@ -338,8 +338,8 @@ sysc_singlestep: # call trace before and after sys_call # sysc_tracesys: - l %r1,BASED(.Ltrace) - la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Ltrace) + la %r2,SP_PTREGS(%r15) # load pt_regs la %r3,0 srl %r7,2 st %r7,SP_R2(%r15) @@ -347,19 +347,19 @@ sysc_tracesys: clc SP_R2(4,%r15),BASED(.Lnr_syscalls) bnl BASED(sysc_tracenogo) l %r8,BASED(.Lsysc_table) - l %r7,SP_R2(%r15) # strace might have changed the - sll %r7,2 # system call + l %r7,SP_R2(%r15) # strace might have changed the + sll %r7,2 # system call l %r8,0(%r7,%r8) sysc_tracego: lm %r3,%r6,SP_R3(%r15) l %r2,SP_ORIG_R2(%r15) - basr %r14,%r8 # call sys_xxx - st %r2,SP_R2(%r15) # store return value + basr %r14,%r8 # call sys_xxx + st %r2,SP_R2(%r15) # store return value sysc_tracenogo: tm __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) - bz BASED(sysc_return) + bz BASED(sysc_return) l %r1,BASED(.Ltrace) - la %r2,SP_PTREGS(%r15) # load pt_regs + la %r2,SP_PTREGS(%r15) # load pt_regs la %r3,1 la %r14,BASED(sysc_return) br %r1 @@ -367,17 +367,17 @@ sysc_tracenogo: # # a new process exits the kernel with ret_from_fork # - .globl ret_from_fork + .globl ret_from_fork ret_from_fork: l %r13,__LC_SVC_NEW_PSW+4 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? bo BASED(0f) st %r15,SP_R15(%r15) # store stack pointer for new kthread -0: l %r1,BASED(.Lschedtail) - basr %r14,%r1 +0: l %r1,BASED(.Lschedtail) + basr %r14,%r1 TRACE_IRQS_ON - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts b BASED(sysc_return) # @@ -386,51 +386,52 @@ ret_from_fork: # but are called with different parameter. # return-address is set up above # -sys_clone_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Lclone) - br %r1 # branch to sys_clone - -sys_fork_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Lfork) - br %r1 # branch to sys_fork - -sys_vfork_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Lvfork) - br %r1 # branch to sys_vfork - -sys_execve_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Lexecve) - lr %r12,%r14 # save return address - basr %r14,%r1 # call sys_execve - ltr %r2,%r2 # check if execve failed - bnz 0(%r12) # it did fail -> store result in gpr2 - b 4(%r12) # SKIP ST 2,SP_R2(15) after BASR 14,8 - # in system_call/sysc_tracesys - -sys_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - l %r1,BASED(.Lsigreturn) - br %r1 # branch to sys_sigreturn - -sys_rt_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - l %r1,BASED(.Lrt_sigreturn) - br %r1 # branch to sys_sigreturn +sys_clone_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Lclone) + br %r1 # branch to sys_clone + +sys_fork_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Lfork) + br %r1 # branch to sys_fork + +sys_vfork_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Lvfork) + br %r1 # branch to sys_vfork + +sys_execve_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Lexecve) + lr %r12,%r14 # save return address + basr %r14,%r1 # call sys_execve + ltr %r2,%r2 # check if execve failed + bnz 0(%r12) # it did fail -> store result in gpr2 + b 4(%r12) # SKIP ST 2,SP_R2(15) after BASR 14,8 + # in system_call/sysc_tracesys + +sys_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + l %r1,BASED(.Lsigreturn) + br %r1 # branch to sys_sigreturn + +sys_rt_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + l %r1,BASED(.Lrt_sigreturn) + br %r1 # branch to sys_sigreturn sys_sigaltstack_glue: - la %r4,SP_PTREGS(%r15) # load pt_regs as parameter - l %r1,BASED(.Lsigaltstack) - br %r1 # branch to sys_sigreturn + la %r4,SP_PTREGS(%r15) # load pt_regs as parameter + l %r1,BASED(.Lsigaltstack) + br %r1 # branch to sys_sigreturn + /* * Program check handler routine */ - .globl pgm_check_handler + .globl pgm_check_handler pgm_check_handler: /* * First we need to check for a special case: @@ -447,8 +448,8 @@ pgm_check_handler: */ STORE_TIMER __LC_SYNC_ENTER_TIMER SAVE_ALL_BASE __LC_SAVE_AREA - tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception - bnz BASED(pgm_per) # got per exception -> special case + tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception + bnz BASED(pgm_per) # got per exception -> special case SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING @@ -460,29 +461,29 @@ pgm_check_handler: pgm_no_vtime: #endif l %r9,__LC_THREAD_INFO # load pointer to thread_info struct - l %r3,__LC_PGM_ILC # load program interruption code + l %r3,__LC_PGM_ILC # load program interruption code la %r8,0x7f nr %r8,%r3 pgm_do_call: - l %r7,BASED(.Ljump_table) - sll %r8,2 - l %r7,0(%r8,%r7) # load address of handler routine - la %r2,SP_PTREGS(%r15) # address of register-save area - la %r14,BASED(sysc_return) - br %r7 # branch to interrupt-handler + l %r7,BASED(.Ljump_table) + sll %r8,2 + l %r7,0(%r8,%r7) # load address of handler routine + la %r2,SP_PTREGS(%r15) # address of register-save area + la %r14,BASED(sysc_return) + br %r7 # branch to interrupt-handler # # handle per exception # pgm_per: - tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on - bnz BASED(pgm_per_std) # ok, normal per event from user space + tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on + bnz BASED(pgm_per_std) # ok, normal per event from user space # ok its one of the special cases, now we need to find out which one - clc __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW - be BASED(pgm_svcper) + clc __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW + be BASED(pgm_svcper) # no interesting special case, ignore PER event - lm %r12,%r15,__LC_SAVE_AREA - lpsw 0x28 + lm %r12,%r15,__LC_SAVE_AREA + lpsw 0x28 # # Normal per exception @@ -506,10 +507,10 @@ pgm_no_vtime2: oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP tm SP_PSW+1(%r15),0x01 # kernel per event ? bz BASED(kernel_per) - l %r3,__LC_PGM_ILC # load program interruption code + l %r3,__LC_PGM_ILC # load program interruption code la %r8,0x7f - nr %r8,%r3 # clear per-event-bit and ilc - be BASED(sysc_return) # only per or per+check ? + nr %r8,%r3 # clear per-event-bit and ilc + be BASED(sysc_return) # only per or per+check ? b BASED(pgm_do_call) # @@ -551,7 +552,7 @@ kernel_per: * IO interrupt handler routine */ - .globl io_int_handler + .globl io_int_handler io_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK @@ -568,42 +569,42 @@ io_no_vtime: #endif l %r9,__LC_THREAD_INFO # load pointer to thread_info struct TRACE_IRQS_OFF - l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ - la %r2,SP_PTREGS(%r15) # address of register-save area - basr %r14,%r1 # branch to standard irq handler + l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ + la %r2,SP_PTREGS(%r15) # address of register-save area + basr %r14,%r1 # branch to standard irq handler TRACE_IRQS_ON io_return: - tm SP_PSW+1(%r15),0x01 # returning to user ? + tm SP_PSW+1(%r15),0x01 # returning to user ? #ifdef CONFIG_PREEMPT - bno BASED(io_preempt) # no -> check for preemptive scheduling + bno BASED(io_preempt) # no -> check for preemptive scheduling #else - bno BASED(io_leave) # no-> skip resched & signal + bno BASED(io_leave) # no-> skip resched & signal #endif tm __TI_flags+3(%r9),_TIF_WORK_INT - bnz BASED(io_work) # there is work to do (signals etc.) + bnz BASED(io_work) # there is work to do (signals etc.) io_leave: - RESTORE_ALL __LC_RETURN_PSW,0 + RESTORE_ALL __LC_RETURN_PSW,0 io_done: #ifdef CONFIG_PREEMPT io_preempt: icm %r0,15,__TI_precount(%r9) - bnz BASED(io_leave) + bnz BASED(io_leave) l %r1,SP_R15(%r15) s %r1,BASED(.Lc_spsize) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) - xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain + xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain lr %r15,%r1 io_resume_loop: tm __TI_flags+3(%r9),_TIF_NEED_RESCHED bno BASED(io_leave) - mvc __TI_precount(4,%r9),BASED(.Lc_pactive) - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - l %r1,BASED(.Lschedule) + mvc __TI_precount(4,%r9),BASED(.Lc_pactive) + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + l %r1,BASED(.Lschedule) basr %r14,%r1 # call schedule - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts - xc __TI_precount(4,%r9),__TI_precount(%r9) + stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts + xc __TI_precount(4,%r9),__TI_precount(%r9) b BASED(io_resume_loop) #endif @@ -614,16 +615,16 @@ io_work: l %r1,__LC_KERNEL_STACK s %r1,BASED(.Lc_spsize) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) - xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain + xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain lr %r15,%r1 # # One of the work bits is on. Find out which one. # Checked are: _TIF_SIGPENDING, _TIF_RESTORE_SIGMASK, _TIF_NEED_RESCHED -# and _TIF_MCCK_PENDING +# and _TIF_MCCK_PENDING # io_work_loop: tm __TI_flags+3(%r9),_TIF_MCCK_PENDING - bo BASED(io_mcck_pending) + bo BASED(io_mcck_pending) tm __TI_flags+3(%r9),_TIF_NEED_RESCHED bo BASED(io_reschedule) tm __TI_flags+3(%r9),(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK) @@ -636,36 +637,36 @@ io_work_loop: io_mcck_pending: l %r1,BASED(.Ls390_handle_mcck) la %r14,BASED(io_work_loop) - br %r1 # TIF bit will be cleared by handler + br %r1 # TIF bit will be cleared by handler # # _TIF_NEED_RESCHED is set, call schedule -# -io_reschedule: - l %r1,BASED(.Lschedule) - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - basr %r14,%r1 # call scheduler - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts +# +io_reschedule: + l %r1,BASED(.Lschedule) + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + basr %r14,%r1 # call scheduler + stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts tm __TI_flags+3(%r9),_TIF_WORK_INT - bz BASED(io_leave) # there is no work to do + bz BASED(io_leave) # there is no work to do b BASED(io_work_loop) # # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal # -io_sigpending: - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Ldo_signal) - basr %r14,%r1 # call do_signal - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts +io_sigpending: + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + la %r2,SP_PTREGS(%r15) # load pt_regs + l %r1,BASED(.Ldo_signal) + basr %r14,%r1 # call do_signal + stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts b BASED(io_work_loop) /* * External interrupt handler routine */ - .globl ext_int_handler + .globl ext_int_handler ext_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK @@ -682,8 +683,8 @@ ext_no_vtime: #endif l %r9,__LC_THREAD_INFO # load pointer to thread_info struct TRACE_IRQS_OFF - la %r2,SP_PTREGS(%r15) # address of register-save area - lh %r3,__LC_EXT_INT_CODE # get interruption code + la %r2,SP_PTREGS(%r15) # address of register-save area + lh %r3,__LC_EXT_INT_CODE # get interruption code l %r1,BASED(.Ldo_extint) basr %r14,%r1 TRACE_IRQS_ON @@ -695,13 +696,13 @@ __critical_end: * Machine check handler routines */ - .globl mcck_int_handler + .globl mcck_int_handler mcck_int_handler: spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs SAVE_ALL_BASE __LC_SAVE_AREA+32 la %r12,__LC_MCK_OLD_PSW - tm __LC_MCCK_CODE,0x80 # system damage? + tm __LC_MCCK_CODE,0x80 # system damage? bo BASED(mcck_int_main) # yes -> rest of mcck code invalid #ifdef CONFIG_VIRT_CPU_ACCOUNTING mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER @@ -740,7 +741,7 @@ mcck_int_main: l %r15,__LC_PANIC_STACK # load panic stack 0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32 #ifdef CONFIG_VIRT_CPU_ACCOUNTING - tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? + tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? bno BASED(mcck_no_vtime) # no -> skip cleanup critical tm SP_PSW+1(%r15),0x01 # interrupting from user ? bz BASED(mcck_no_vtime) @@ -751,14 +752,14 @@ mcck_no_vtime: #endif l %r9,__LC_THREAD_INFO # load pointer to thread_info struct la %r2,SP_PTREGS(%r15) # load pt_regs - l %r1,BASED(.Ls390_mcck) - basr %r14,%r1 # call machine check handler - tm SP_PSW+1(%r15),0x01 # returning to user ? + l %r1,BASED(.Ls390_mcck) + basr %r14,%r1 # call machine check handler + tm SP_PSW+1(%r15),0x01 # returning to user ? bno BASED(mcck_return) - l %r1,__LC_KERNEL_STACK # switch to kernel stack + l %r1,__LC_KERNEL_STACK # switch to kernel stack s %r1,BASED(.Lc_spsize) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) - xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain + xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain lr %r15,%r1 stosm __SF_EMPTY(%r15),0x04 # turn dat on tm __TI_flags+3(%r9),_TIF_MCCK_PENDING @@ -782,36 +783,36 @@ mcck_return: lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 lpsw __LC_RETURN_MCCK_PSW # back to caller - RESTORE_ALL __LC_RETURN_MCCK_PSW,0 + RESTORE_ALL __LC_RETURN_MCCK_PSW,0 #ifdef CONFIG_SMP /* * Restart interruption handler, kick starter for additional CPUs */ - .globl restart_int_handler + .globl restart_int_handler restart_int_handler: - l %r15,__LC_SAVE_AREA+60 # load ksp - lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs - lam %a0,%a15,__LC_AREGS_SAVE_AREA - lm %r6,%r15,__SF_GPRS(%r15) # load registers from clone - stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on - basr %r14,0 - l %r14,restart_addr-.(%r14) - br %r14 # branch to start_secondary + l %r15,__LC_SAVE_AREA+60 # load ksp + lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs + lam %a0,%a15,__LC_AREGS_SAVE_AREA + lm %r6,%r15,__SF_GPRS(%r15) # load registers from clone + stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on + basr %r14,0 + l %r14,restart_addr-.(%r14) + br %r14 # branch to start_secondary restart_addr: - .long start_secondary + .long start_secondary #else /* * If we do not run with SMP enabled, let the new CPU crash ... */ - .globl restart_int_handler + .globl restart_int_handler restart_int_handler: - basr %r1,0 + basr %r1,0 restart_base: - lpsw restart_crash-restart_base(%r1) - .align 8 + lpsw restart_crash-restart_base(%r1) + .align 8 restart_crash: - .long 0x000a0000,0x00000000 + .long 0x000a0000,0x00000000 restart_go: #endif @@ -833,11 +834,11 @@ stack_overflow: be BASED(0f) la %r1,__LC_SAVE_AREA+16 0: mvc SP_R12(16,%r15),0(%r1) # move %r12-%r15 to stack - xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear back chain + xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear back chain l %r1,BASED(1f) # branch to kernel_stack_overflow - la %r2,SP_PTREGS(%r15) # load pt_regs + la %r2,SP_PTREGS(%r15) # load pt_regs br %r1 -1: .long kernel_stack_overflow +1: .long kernel_stack_overflow #endif cleanup_table_system_call: @@ -939,10 +940,10 @@ cleanup_novtime: cleanup_system_call_insn: .long sysc_saveall + 0x80000000 #ifdef CONFIG_VIRT_CPU_ACCOUNTING - .long system_call + 0x80000000 - .long sysc_vtime + 0x80000000 - .long sysc_stime + 0x80000000 - .long sysc_update + 0x80000000 + .long system_call + 0x80000000 + .long sysc_vtime + 0x80000000 + .long sysc_stime + 0x80000000 + .long sysc_update + 0x80000000 #endif cleanup_sysc_return: @@ -1008,57 +1009,57 @@ cleanup_io_leave_insn: /* * Integer constants */ - .align 4 -.Lc_spsize: .long SP_SIZE -.Lc_overhead: .long STACK_FRAME_OVERHEAD -.Lc_pactive: .long PREEMPT_ACTIVE -.Lnr_syscalls: .long NR_syscalls -.L0x018: .short 0x018 -.L0x020: .short 0x020 -.L0x028: .short 0x028 -.L0x030: .short 0x030 -.L0x038: .short 0x038 -.Lc_1: .long 1 + .align 4 +.Lc_spsize: .long SP_SIZE +.Lc_overhead: .long STACK_FRAME_OVERHEAD +.Lc_pactive: .long PREEMPT_ACTIVE +.Lnr_syscalls: .long NR_syscalls +.L0x018: .short 0x018 +.L0x020: .short 0x020 +.L0x028: .short 0x028 +.L0x030: .short 0x030 +.L0x038: .short 0x038 +.Lc_1: .long 1 /* * Symbol constants */ -.Ls390_mcck: .long s390_do_machine_check +.Ls390_mcck: .long s390_do_machine_check .Ls390_handle_mcck: - .long s390_handle_mcck -.Lmck_old_psw: .long __LC_MCK_OLD_PSW -.Ldo_IRQ: .long do_IRQ -.Ldo_extint: .long do_extint -.Ldo_signal: .long do_signal -.Lhandle_per: .long do_single_step -.Ljump_table: .long pgm_check_table -.Lschedule: .long schedule -.Lclone: .long sys_clone -.Lexecve: .long sys_execve -.Lfork: .long sys_fork -.Lrt_sigreturn: .long sys_rt_sigreturn + .long s390_handle_mcck +.Lmck_old_psw: .long __LC_MCK_OLD_PSW +.Ldo_IRQ: .long do_IRQ +.Ldo_extint: .long do_extint +.Ldo_signal: .long do_signal +.Lhandle_per: .long do_single_step +.Ljump_table: .long pgm_check_table +.Lschedule: .long schedule +.Lclone: .long sys_clone +.Lexecve: .long sys_execve +.Lfork: .long sys_fork +.Lrt_sigreturn:.long sys_rt_sigreturn .Lrt_sigsuspend: - .long sys_rt_sigsuspend -.Lsigreturn: .long sys_sigreturn -.Lsigsuspend: .long sys_sigsuspend -.Lsigaltstack: .long sys_sigaltstack -.Ltrace: .long syscall_trace -.Lvfork: .long sys_vfork -.Lschedtail: .long schedule_tail -.Lsysc_table: .long sys_call_table + .long sys_rt_sigsuspend +.Lsigreturn: .long sys_sigreturn +.Lsigsuspend: .long sys_sigsuspend +.Lsigaltstack: .long sys_sigaltstack +.Ltrace: .long syscall_trace +.Lvfork: .long sys_vfork +.Lschedtail: .long schedule_tail +.Lsysc_table: .long sys_call_table #ifdef CONFIG_TRACE_IRQFLAGS -.Ltrace_irq_on: .long trace_hardirqs_on +.Ltrace_irq_on:.long trace_hardirqs_on .Ltrace_irq_off: - .long trace_hardirqs_off + .long trace_hardirqs_off #endif .Lcritical_start: - .long __critical_start + 0x80000000 + .long __critical_start + 0x80000000 .Lcritical_end: - .long __critical_end + 0x80000000 + .long __critical_end + 0x80000000 .Lcleanup_critical: - .long cleanup_critical + .long cleanup_critical - .section .rodata, "a" + .section .rodata, "a" #define SYSCALL(esa,esame,emu) .long esa sys_call_table: #include "syscalls.S" diff --git a/trunk/arch/s390/kernel/entry64.S b/trunk/arch/s390/kernel/entry64.S index 0f758c329a5d..29bbfbab7332 100644 --- a/trunk/arch/s390/kernel/entry64.S +++ b/trunk/arch/s390/kernel/entry64.S @@ -4,8 +4,8 @@ * * Copyright (C) IBM Corp. 1999,2006 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - * Hartmut Penner (hp@de.ibm.com), - * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), + * Hartmut Penner (hp@de.ibm.com), + * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), * Heiko Carstens */ @@ -24,29 +24,29 @@ * Stack layout for the system_call stack entry. * The first few entries are identical to the user_regs_struct. */ -SP_PTREGS = STACK_FRAME_OVERHEAD -SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS -SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW -SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS -SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 -SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 -SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 -SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 -SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 -SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 -SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 -SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 64 -SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 72 -SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 80 -SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 88 -SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 96 -SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 104 -SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 112 -SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 120 -SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 -SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC -SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP -SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE +SP_PTREGS = STACK_FRAME_OVERHEAD +SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS +SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW +SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS +SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 +SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 +SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 +SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 +SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 +SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 +SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 +SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 64 +SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 72 +SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 80 +SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 88 +SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 96 +SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 104 +SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 112 +SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 120 +SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2 +SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC +SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP +SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER STACK_SIZE = 1 << STACK_SHIFT @@ -71,14 +71,14 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ #define TRACE_IRQS_OFF #endif - .macro STORE_TIMER lc_offset + .macro STORE_TIMER lc_offset #ifdef CONFIG_VIRT_CPU_ACCOUNTING stpt \lc_offset #endif .endm #ifdef CONFIG_VIRT_CPU_ACCOUNTING - .macro UPDATE_VTIME lc_from,lc_to,lc_sum + .macro UPDATE_VTIME lc_from,lc_to,lc_sum lg %r10,\lc_from slg %r10,\lc_to alg %r10,\lc_sum @@ -94,7 +94,7 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ * R15 - kernel stack pointer */ - .macro SAVE_ALL_BASE savearea + .macro SAVE_ALL_BASE savearea stmg %r12,%r15,\savearea larl %r13,system_call .endm @@ -139,8 +139,8 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ .endm .macro CREATE_STACK_FRAME psworg,savearea - aghi %r15,-SP_SIZE # make room for registers & psw - mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack + aghi %r15,-SP_SIZE # make room for registers & psw + mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack la %r12,\psworg stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 icm %r12,12,__LC_SVC_ILC @@ -149,7 +149,7 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ mvc SP_R12(32,%r15),\savearea # move %r12-%r15 to stack la %r12,0 stg %r12,__SF_BACKCHAIN(%r15) - .endm + .endm .macro RESTORE_ALL psworg,sync mvc \psworg(16),SP_PSW(%r15) # move user PSW to lowcore @@ -168,29 +168,29 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ * Returns: * gpr2 = prev */ - .globl __switch_to + .globl __switch_to __switch_to: tm __THREAD_per+4(%r3),0xe8 # is the new process using per ? jz __switch_to_noper # if not we're fine - stctg %c9,%c11,__SF_EMPTY(%r15)# We are using per stuff - clc __THREAD_per(24,%r3),__SF_EMPTY(%r15) - je __switch_to_noper # we got away without bashing TLB's - lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't + stctg %c9,%c11,__SF_EMPTY(%r15)# We are using per stuff + clc __THREAD_per(24,%r3),__SF_EMPTY(%r15) + je __switch_to_noper # we got away without bashing TLB's + lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't __switch_to_noper: - lg %r4,__THREAD_info(%r2) # get thread_info of prev + lg %r4,__THREAD_info(%r2) # get thread_info of prev tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending? jz __switch_to_no_mcck ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev lg %r4,__THREAD_info(%r3) # get thread_info of next oi __TI_flags+7(%r4),_TIF_MCCK_PENDING # set it in next __switch_to_no_mcck: - stmg %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task + stmg %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task stg %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp lg %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp - lmg %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task + lmg %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task stg %r3,__LC_CURRENT # __LC_CURRENT = current task struct lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 - lg %r3,__THREAD_info(%r3) # load thread_info from task struct + lg %r3,__THREAD_info(%r3) # load thread_info from task struct stg %r3,__LC_THREAD_INFO aghi %r3,STACK_SIZE stg %r3,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack @@ -202,14 +202,14 @@ __critical_start: * are executed with interrupts enabled. */ - .globl system_call + .globl system_call system_call: STORE_TIMER __LC_SYNC_ENTER_TIMER sysc_saveall: SAVE_ALL_BASE __LC_SAVE_AREA SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA - CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA - llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore + CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA + llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore #ifdef CONFIG_VIRT_CPU_ACCOUNTING sysc_vtime: tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -222,45 +222,45 @@ sysc_update: #endif sysc_do_svc: lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct - slag %r7,%r7,2 # *4 and test for svc 0 + slag %r7,%r7,2 # *4 and test for svc 0 jnz sysc_nr_ok # svc 0: system call number in %r1 cl %r1,BASED(.Lnr_syscalls) jnl sysc_nr_ok - lgfr %r7,%r1 # clear high word in r1 - slag %r7,%r7,2 # svc 0: system call number in %r1 + lgfr %r7,%r1 # clear high word in r1 + slag %r7,%r7,2 # svc 0: system call number in %r1 sysc_nr_ok: mvc SP_ARGS(8,%r15),SP_R7(%r15) sysc_do_restart: - larl %r10,sys_call_table + larl %r10,sys_call_table #ifdef CONFIG_COMPAT tm __TI_flags+5(%r9),(_TIF_31BIT>>16) # running in 31 bit mode ? jno sysc_noemu - larl %r10,sys_call_table_emu # use 31 bit emulation system calls + larl %r10,sys_call_table_emu # use 31 bit emulation system calls sysc_noemu: #endif tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) - lgf %r8,0(%r7,%r10) # load address of system call routine - jnz sysc_tracesys - basr %r14,%r8 # call sys_xxxx - stg %r2,SP_R2(%r15) # store return value (change R2 on stack) - # ATTENTION: check sys_execve_glue before - # changing anything here !! + lgf %r8,0(%r7,%r10) # load address of system call routine + jnz sysc_tracesys + basr %r14,%r8 # call sys_xxxx + stg %r2,SP_R2(%r15) # store return value (change R2 on stack) + # ATTENTION: check sys_execve_glue before + # changing anything here !! sysc_return: - tm SP_PSW+1(%r15),0x01 # returning to user ? - jno sysc_leave + tm SP_PSW+1(%r15),0x01 # returning to user ? + jno sysc_leave tm __TI_flags+7(%r9),_TIF_WORK_SVC - jnz sysc_work # there is work to do (signals etc.) + jnz sysc_work # there is work to do (signals etc.) sysc_leave: - RESTORE_ALL __LC_RETURN_PSW,1 + RESTORE_ALL __LC_RETURN_PSW,1 # # recheck if there is more work to do # sysc_work_loop: tm __TI_flags+7(%r9),_TIF_WORK_SVC - jz sysc_leave # there is no work to do + jz sysc_leave # there is no work to do # # One of the work bits is on. Find out which one. # @@ -279,25 +279,25 @@ sysc_work: # # _TIF_NEED_RESCHED is set, call schedule -# -sysc_reschedule: - larl %r14,sysc_work_loop - jg schedule # return point is sysc_return +# +sysc_reschedule: + larl %r14,sysc_work_loop + jg schedule # return point is sysc_return # # _TIF_MCCK_PENDING is set, call handler # sysc_mcck_pending: larl %r14,sysc_work_loop - jg s390_handle_mcck # TIF bit will be cleared by handler + jg s390_handle_mcck # TIF bit will be cleared by handler # # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal # -sysc_sigpending: +sysc_sigpending: ni __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP - la %r2,SP_PTREGS(%r15) # load pt_regs - brasl %r14,do_signal # call do_signal + la %r2,SP_PTREGS(%r15) # load pt_regs + brasl %r14,do_signal # call do_signal tm __TI_flags+7(%r9),_TIF_RESTART_SVC jo sysc_restart tm __TI_flags+7(%r9),_TIF_SINGLE_STEP @@ -309,11 +309,11 @@ sysc_sigpending: # sysc_restart: ni __TI_flags+7(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC - lg %r7,SP_R2(%r15) # load new svc number - slag %r7,%r7,2 # *4 + lg %r7,SP_R2(%r15) # load new svc number + slag %r7,%r7,2 # *4 mvc SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument - lmg %r2,%r6,SP_R2(%r15) # load svc arguments - j sysc_do_restart # restart svc + lmg %r2,%r6,SP_R2(%r15) # load svc arguments + j sysc_do_restart # restart svc # # _TIF_SINGLE_STEP is set, call do_single_step @@ -326,48 +326,49 @@ sysc_singlestep: larl %r14,sysc_return # load adr. of system return jg do_single_step # branch to do_sigtrap + # # call syscall_trace before and after system call # special linkage: %r12 contains the return address for trace_svc # sysc_tracesys: - la %r2,SP_PTREGS(%r15) # load pt_regs + la %r2,SP_PTREGS(%r15) # load pt_regs la %r3,0 srl %r7,2 - stg %r7,SP_R2(%r15) - brasl %r14,syscall_trace + stg %r7,SP_R2(%r15) + brasl %r14,syscall_trace lghi %r0,NR_syscalls clg %r0,SP_R2(%r15) jnh sysc_tracenogo - lg %r7,SP_R2(%r15) # strace might have changed the - sll %r7,2 # system call + lg %r7,SP_R2(%r15) # strace might have changed the + sll %r7,2 # system call lgf %r8,0(%r7,%r10) sysc_tracego: - lmg %r3,%r6,SP_R3(%r15) - lg %r2,SP_ORIG_R2(%r15) - basr %r14,%r8 # call sys_xxx - stg %r2,SP_R2(%r15) # store return value + lmg %r3,%r6,SP_R3(%r15) + lg %r2,SP_ORIG_R2(%r15) + basr %r14,%r8 # call sys_xxx + stg %r2,SP_R2(%r15) # store return value sysc_tracenogo: tm __TI_flags+7(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT) - jz sysc_return - la %r2,SP_PTREGS(%r15) # load pt_regs + jz sysc_return + la %r2,SP_PTREGS(%r15) # load pt_regs la %r3,1 - larl %r14,sysc_return # return point is sysc_return + larl %r14,sysc_return # return point is sysc_return jg syscall_trace # # a new process exits the kernel with ret_from_fork # - .globl ret_from_fork + .globl ret_from_fork ret_from_fork: lg %r13,__LC_SVC_NEW_PSW+8 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? jo 0f stg %r15,SP_R15(%r15) # store stack pointer for new kthread -0: brasl %r14,schedule_tail +0: brasl %r14,schedule_tail TRACE_IRQS_ON - stosm 24(%r15),0x03 # reenable interrupts + stosm 24(%r15),0x03 # reenable interrupts j sysc_return # @@ -376,78 +377,78 @@ ret_from_fork: # but are called with different parameter. # return-address is set up above # -sys_clone_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - jg sys_clone # branch to sys_clone +sys_clone_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + jg sys_clone # branch to sys_clone #ifdef CONFIG_COMPAT -sys32_clone_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - jg sys32_clone # branch to sys32_clone +sys32_clone_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + jg sys32_clone # branch to sys32_clone #endif -sys_fork_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - jg sys_fork # branch to sys_fork - -sys_vfork_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - jg sys_vfork # branch to sys_vfork - -sys_execve_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - lgr %r12,%r14 # save return address - brasl %r14,sys_execve # call sys_execve - ltgr %r2,%r2 # check if execve failed - bnz 0(%r12) # it did fail -> store result in gpr2 - b 6(%r12) # SKIP STG 2,SP_R2(15) in - # system_call/sysc_tracesys +sys_fork_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + jg sys_fork # branch to sys_fork + +sys_vfork_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + jg sys_vfork # branch to sys_vfork + +sys_execve_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + lgr %r12,%r14 # save return address + brasl %r14,sys_execve # call sys_execve + ltgr %r2,%r2 # check if execve failed + bnz 0(%r12) # it did fail -> store result in gpr2 + b 6(%r12) # SKIP STG 2,SP_R2(15) in + # system_call/sysc_tracesys #ifdef CONFIG_COMPAT -sys32_execve_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs - lgr %r12,%r14 # save return address - brasl %r14,sys32_execve # call sys32_execve - ltgr %r2,%r2 # check if execve failed - bnz 0(%r12) # it did fail -> store result in gpr2 - b 6(%r12) # SKIP STG 2,SP_R2(15) in - # system_call/sysc_tracesys +sys32_execve_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs + lgr %r12,%r14 # save return address + brasl %r14,sys32_execve # call sys32_execve + ltgr %r2,%r2 # check if execve failed + bnz 0(%r12) # it did fail -> store result in gpr2 + b 6(%r12) # SKIP STG 2,SP_R2(15) in + # system_call/sysc_tracesys #endif -sys_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys_sigreturn # branch to sys_sigreturn +sys_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys_sigreturn # branch to sys_sigreturn #ifdef CONFIG_COMPAT -sys32_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys32_sigreturn # branch to sys32_sigreturn +sys32_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys32_sigreturn # branch to sys32_sigreturn #endif -sys_rt_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys_rt_sigreturn # branch to sys_sigreturn +sys_rt_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys_rt_sigreturn # branch to sys_sigreturn #ifdef CONFIG_COMPAT -sys32_rt_sigreturn_glue: - la %r2,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys32_rt_sigreturn # branch to sys32_sigreturn +sys32_rt_sigreturn_glue: + la %r2,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys32_rt_sigreturn # branch to sys32_sigreturn #endif sys_sigaltstack_glue: - la %r4,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys_sigaltstack # branch to sys_sigreturn + la %r4,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys_sigaltstack # branch to sys_sigreturn #ifdef CONFIG_COMPAT sys32_sigaltstack_glue: - la %r4,SP_PTREGS(%r15) # load pt_regs as parameter - jg sys32_sigaltstack_wrapper # branch to sys_sigreturn + la %r4,SP_PTREGS(%r15) # load pt_regs as parameter + jg sys32_sigaltstack_wrapper # branch to sys_sigreturn #endif /* * Program check handler routine */ - .globl pgm_check_handler + .globl pgm_check_handler pgm_check_handler: /* * First we need to check for a special case: @@ -464,8 +465,8 @@ pgm_check_handler: */ STORE_TIMER __LC_SYNC_ENTER_TIMER SAVE_ALL_BASE __LC_SAVE_AREA - tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception - jnz pgm_per # got per exception -> special case + tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception + jnz pgm_per # got per exception -> special case SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING @@ -477,29 +478,29 @@ pgm_check_handler: pgm_no_vtime: #endif lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct - lgf %r3,__LC_PGM_ILC # load program interruption code + lgf %r3,__LC_PGM_ILC # load program interruption code lghi %r8,0x7f ngr %r8,%r3 pgm_do_call: - sll %r8,3 - larl %r1,pgm_check_table - lg %r1,0(%r8,%r1) # load address of handler routine - la %r2,SP_PTREGS(%r15) # address of register-save area + sll %r8,3 + larl %r1,pgm_check_table + lg %r1,0(%r8,%r1) # load address of handler routine + la %r2,SP_PTREGS(%r15) # address of register-save area larl %r14,sysc_return - br %r1 # branch to interrupt-handler + br %r1 # branch to interrupt-handler # # handle per exception # pgm_per: - tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on - jnz pgm_per_std # ok, normal per event from user space + tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on + jnz pgm_per_std # ok, normal per event from user space # ok its one of the special cases, now we need to find out which one - clc __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW - je pgm_svcper + clc __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW + je pgm_svcper # no interesting special case, ignore PER event lmg %r12,%r15,__LC_SAVE_AREA - lpswe __LC_PGM_OLD_PSW + lpswe __LC_PGM_OLD_PSW # # Normal per exception @@ -523,9 +524,9 @@ pgm_no_vtime2: mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP - lgf %r3,__LC_PGM_ILC # load program interruption code + lgf %r3,__LC_PGM_ILC # load program interruption code lghi %r8,0x7f - ngr %r8,%r3 # clear per-event-bit and ilc + ngr %r8,%r3 # clear per-event-bit and ilc je sysc_return j pgm_do_call @@ -543,7 +544,7 @@ pgm_svcper: mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER pgm_no_vtime3: #endif - llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore + llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct lg %r1,__TI_task(%r9) mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID @@ -567,7 +568,7 @@ kernel_per: /* * IO interrupt handler routine */ - .globl io_int_handler + .globl io_int_handler io_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK @@ -584,42 +585,42 @@ io_no_vtime: #endif lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct TRACE_IRQS_OFF - la %r2,SP_PTREGS(%r15) # address of register-save area - brasl %r14,do_IRQ # call standard irq handler + la %r2,SP_PTREGS(%r15) # address of register-save area + brasl %r14,do_IRQ # call standard irq handler TRACE_IRQS_ON io_return: - tm SP_PSW+1(%r15),0x01 # returning to user ? + tm SP_PSW+1(%r15),0x01 # returning to user ? #ifdef CONFIG_PREEMPT - jno io_preempt # no -> check for preemptive scheduling + jno io_preempt # no -> check for preemptive scheduling #else - jno io_leave # no-> skip resched & signal + jno io_leave # no-> skip resched & signal #endif tm __TI_flags+7(%r9),_TIF_WORK_INT - jnz io_work # there is work to do (signals etc.) + jnz io_work # there is work to do (signals etc.) io_leave: - RESTORE_ALL __LC_RETURN_PSW,0 + RESTORE_ALL __LC_RETURN_PSW,0 io_done: #ifdef CONFIG_PREEMPT io_preempt: - icm %r0,15,__TI_precount(%r9) - jnz io_leave + icm %r0,15,__TI_precount(%r9) + jnz io_leave # switch to kernel stack lg %r1,SP_R15(%r15) aghi %r1,-SP_SIZE mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) - xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain + xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain lgr %r15,%r1 io_resume_loop: tm __TI_flags+7(%r9),_TIF_NEED_RESCHED jno io_leave - larl %r1,.Lc_pactive - mvc __TI_precount(4,%r9),0(%r1) - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - brasl %r14,schedule # call schedule - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts - xc __TI_precount(4,%r9),__TI_precount(%r9) + larl %r1,.Lc_pactive + mvc __TI_precount(4,%r9),0(%r1) + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + brasl %r14,schedule # call schedule + stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts + xc __TI_precount(4,%r9),__TI_precount(%r9) j io_resume_loop #endif @@ -630,7 +631,7 @@ io_work: lg %r1,__LC_KERNEL_STACK aghi %r1,-SP_SIZE mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) - xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain + xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain lgr %r15,%r1 # # One of the work bits is on. Find out which one. @@ -655,11 +656,11 @@ io_mcck_pending: # # _TIF_NEED_RESCHED is set, call schedule -# -io_reschedule: - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - brasl %r14,schedule # call scheduler - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts +# +io_reschedule: + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + brasl %r14,schedule # call scheduler + stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts tm __TI_flags+7(%r9),_TIF_WORK_INT jz io_leave # there is no work to do j io_work_loop @@ -667,17 +668,17 @@ io_reschedule: # # _TIF_SIGPENDING or _TIF_RESTORE_SIGMASK is set, call do_signal # -io_sigpending: - stosm __SF_EMPTY(%r15),0x03 # reenable interrupts - la %r2,SP_PTREGS(%r15) # load pt_regs +io_sigpending: + stosm __SF_EMPTY(%r15),0x03 # reenable interrupts + la %r2,SP_PTREGS(%r15) # load pt_regs brasl %r14,do_signal # call do_signal - stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts + stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts j io_work_loop /* * External interrupt handler routine */ - .globl ext_int_handler + .globl ext_int_handler ext_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK @@ -694,9 +695,9 @@ ext_no_vtime: #endif lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct TRACE_IRQS_OFF - la %r2,SP_PTREGS(%r15) # address of register-save area - llgh %r3,__LC_EXT_INT_CODE # get interruption code - brasl %r14,do_extint + la %r2,SP_PTREGS(%r15) # address of register-save area + llgh %r3,__LC_EXT_INT_CODE # get interruption code + brasl %r14,do_extint TRACE_IRQS_ON j io_return @@ -705,14 +706,14 @@ __critical_end: /* * Machine check handler routines */ - .globl mcck_int_handler + .globl mcck_int_handler mcck_int_handler: la %r1,4095 # revalidate r1 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer - lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs + lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs SAVE_ALL_BASE __LC_SAVE_AREA+64 la %r12,__LC_MCK_OLD_PSW - tm __LC_MCCK_CODE,0x80 # system damage? + tm __LC_MCCK_CODE,0x80 # system damage? jo mcck_int_main # yes -> rest of mcck code invalid #ifdef CONFIG_VIRT_CPU_ACCOUNTING la %r14,4095 @@ -736,19 +737,19 @@ mcck_int_handler: #endif tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? jno mcck_int_main # no -> skip cleanup critical - tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit + tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit jnz mcck_int_main # from user -> load kernel stack clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_end) jhe mcck_int_main - clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start) + clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start) jl mcck_int_main - brasl %r14,cleanup_critical + brasl %r14,cleanup_critical mcck_int_main: - lg %r14,__LC_PANIC_STACK # are we already on the panic stack? + lg %r14,__LC_PANIC_STACK # are we already on the panic stack? slgr %r14,%r15 srag %r14,%r14,PAGE_SHIFT jz 0f - lg %r15,__LC_PANIC_STACK # load panic stack + lg %r15,__LC_PANIC_STACK # load panic stack 0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? @@ -763,7 +764,7 @@ mcck_no_vtime: lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct la %r2,SP_PTREGS(%r15) # load pt_regs brasl %r14,s390_do_machine_check - tm SP_PSW+1(%r15),0x01 # returning to user ? + tm SP_PSW+1(%r15),0x01 # returning to user ? jno mcck_return lg %r1,__LC_KERNEL_STACK # switch to kernel stack aghi %r1,-SP_SIZE @@ -793,28 +794,28 @@ mcck_return: /* * Restart interruption handler, kick starter for additional CPUs */ - .globl restart_int_handler + .globl restart_int_handler restart_int_handler: - lg %r15,__LC_SAVE_AREA+120 # load ksp - lghi %r10,__LC_CREGS_SAVE_AREA - lctlg %c0,%c15,0(%r10) # get new ctl regs - lghi %r10,__LC_AREGS_SAVE_AREA - lam %a0,%a15,0(%r10) - lmg %r6,%r15,__SF_GPRS(%r15) # load registers from clone - stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on - jg start_secondary + lg %r15,__LC_SAVE_AREA+120 # load ksp + lghi %r10,__LC_CREGS_SAVE_AREA + lctlg %c0,%c15,0(%r10) # get new ctl regs + lghi %r10,__LC_AREGS_SAVE_AREA + lam %a0,%a15,0(%r10) + lmg %r6,%r15,__SF_GPRS(%r15) # load registers from clone + stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on + jg start_secondary #else /* * If we do not run with SMP enabled, let the new CPU crash ... */ - .globl restart_int_handler + .globl restart_int_handler restart_int_handler: - basr %r1,0 + basr %r1,0 restart_base: - lpswe restart_crash-restart_base(%r1) - .align 8 + lpswe restart_crash-restart_base(%r1) + .align 8 restart_crash: - .long 0x000a0000,0x00000000,0x00000000,0x00000000 + .long 0x000a0000,0x00000000,0x00000000,0x00000000 restart_go: #endif @@ -835,9 +836,9 @@ stack_overflow: chi %r12,__LC_PGM_OLD_PSW je 0f la %r1,__LC_SAVE_AREA+32 -0: mvc SP_R12(32,%r15),0(%r1) # move %r12-%r15 to stack - xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain - la %r2,SP_PTREGS(%r15) # load pt_regs +0: mvc SP_R12(32,%r15),0(%r1) # move %r12-%r15 to stack + xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain + la %r2,SP_PTREGS(%r15) # load pt_regs jg kernel_stack_overflow #endif @@ -940,10 +941,10 @@ cleanup_novtime: cleanup_system_call_insn: .quad sysc_saveall #ifdef CONFIG_VIRT_CPU_ACCOUNTING - .quad system_call - .quad sysc_vtime - .quad sysc_stime - .quad sysc_update + .quad system_call + .quad sysc_vtime + .quad sysc_stime + .quad sysc_update #endif cleanup_sysc_return: @@ -1009,21 +1010,21 @@ cleanup_io_leave_insn: /* * Integer constants */ - .align 4 + .align 4 .Lconst: -.Lc_pactive: .long PREEMPT_ACTIVE -.Lnr_syscalls: .long NR_syscalls -.L0x0130: .short 0x130 -.L0x0140: .short 0x140 -.L0x0150: .short 0x150 -.L0x0160: .short 0x160 -.L0x0170: .short 0x170 +.Lc_pactive: .long PREEMPT_ACTIVE +.Lnr_syscalls: .long NR_syscalls +.L0x0130: .short 0x130 +.L0x0140: .short 0x140 +.L0x0150: .short 0x150 +.L0x0160: .short 0x160 +.L0x0170: .short 0x170 .Lcritical_start: - .quad __critical_start + .quad __critical_start .Lcritical_end: - .quad __critical_end + .quad __critical_end - .section .rodata, "a" + .section .rodata, "a" #define SYSCALL(esa,esame,emu) .long esame sys_call_table: #include "syscalls.S" diff --git a/trunk/arch/s390/kernel/head.S b/trunk/arch/s390/kernel/head.S index 0cf59bb7a857..0f1db268a8a9 100644 --- a/trunk/arch/s390/kernel/head.S +++ b/trunk/arch/s390/kernel/head.S @@ -36,449 +36,449 @@ #endif #ifndef CONFIG_IPL - .org 0 - .long 0x00080000,0x80000000+startup # Just a restart PSW + .org 0 + .long 0x00080000,0x80000000+startup # Just a restart PSW #else #ifdef CONFIG_IPL_TAPE #define IPL_BS 1024 - .org 0 - .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded - .long 0x27000000,0x60000001 # by ipl to addresses 0-23. - .long 0x02000000,0x20000000+IPL_BS # (a PSW and two CCWs). - .long 0x00000000,0x00000000 # external old psw - .long 0x00000000,0x00000000 # svc old psw - .long 0x00000000,0x00000000 # program check old psw - .long 0x00000000,0x00000000 # machine check old psw - .long 0x00000000,0x00000000 # io old psw - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x000a0000,0x00000058 # external new psw - .long 0x000a0000,0x00000060 # svc new psw - .long 0x000a0000,0x00000068 # program check new psw - .long 0x000a0000,0x00000070 # machine check new psw - .long 0x00080000,0x80000000+.Lioint # io new psw + .org 0 + .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded + .long 0x27000000,0x60000001 # by ipl to addresses 0-23. + .long 0x02000000,0x20000000+IPL_BS # (a PSW and two CCWs). + .long 0x00000000,0x00000000 # external old psw + .long 0x00000000,0x00000000 # svc old psw + .long 0x00000000,0x00000000 # program check old psw + .long 0x00000000,0x00000000 # machine check old psw + .long 0x00000000,0x00000000 # io old psw + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x000a0000,0x00000058 # external new psw + .long 0x000a0000,0x00000060 # svc new psw + .long 0x000a0000,0x00000068 # program check new psw + .long 0x000a0000,0x00000070 # machine check new psw + .long 0x00080000,0x80000000+.Lioint # io new psw - .org 0x100 + .org 0x100 # # subroutine for loading from tape -# Paramters: +# Paramters: # R1 = device number # R2 = load address -.Lloader: - st %r14,.Lldret - la %r3,.Lorbread # r3 = address of orb - la %r5,.Lirb # r5 = address of irb - st %r2,.Lccwread+4 # initialize CCW data addresses - lctl %c6,%c6,.Lcr6 - slr %r2,%r2 +.Lloader: + st %r14,.Lldret + la %r3,.Lorbread # r3 = address of orb + la %r5,.Lirb # r5 = address of irb + st %r2,.Lccwread+4 # initialize CCW data addresses + lctl %c6,%c6,.Lcr6 + slr %r2,%r2 .Lldlp: - la %r6,3 # 3 retries + la %r6,3 # 3 retries .Lssch: - ssch 0(%r3) # load chunk of IPL_BS bytes - bnz .Llderr + ssch 0(%r3) # load chunk of IPL_BS bytes + bnz .Llderr .Lw4end: - bas %r14,.Lwait4io - tm 8(%r5),0x82 # do we have a problem ? - bnz .Lrecov - slr %r7,%r7 - icm %r7,3,10(%r5) # get residual count - lcr %r7,%r7 - la %r7,IPL_BS(%r7) # IPL_BS-residual=#bytes read - ar %r2,%r7 # add to total size - tm 8(%r5),0x01 # found a tape mark ? - bnz .Ldone - l %r0,.Lccwread+4 # update CCW data addresses - ar %r0,%r7 - st %r0,.Lccwread+4 - b .Lldlp + bas %r14,.Lwait4io + tm 8(%r5),0x82 # do we have a problem ? + bnz .Lrecov + slr %r7,%r7 + icm %r7,3,10(%r5) # get residual count + lcr %r7,%r7 + la %r7,IPL_BS(%r7) # IPL_BS-residual=#bytes read + ar %r2,%r7 # add to total size + tm 8(%r5),0x01 # found a tape mark ? + bnz .Ldone + l %r0,.Lccwread+4 # update CCW data addresses + ar %r0,%r7 + st %r0,.Lccwread+4 + b .Lldlp .Ldone: - l %r14,.Lldret - br %r14 # r2 contains the total size + l %r14,.Lldret + br %r14 # r2 contains the total size .Lrecov: - bas %r14,.Lsense # do the sensing - bct %r6,.Lssch # dec. retry count & branch - b .Llderr + bas %r14,.Lsense # do the sensing + bct %r6,.Lssch # dec. retry count & branch + b .Llderr # # Sense subroutine # .Lsense: - st %r14,.Lsnsret - la %r7,.Lorbsense - ssch 0(%r7) # start sense command - bnz .Llderr - bas %r14,.Lwait4io - l %r14,.Lsnsret - tm 8(%r5),0x82 # do we have a problem ? - bnz .Llderr - br %r14 + st %r14,.Lsnsret + la %r7,.Lorbsense + ssch 0(%r7) # start sense command + bnz .Llderr + bas %r14,.Lwait4io + l %r14,.Lsnsret + tm 8(%r5),0x82 # do we have a problem ? + bnz .Llderr + br %r14 # # Wait for interrupt subroutine # .Lwait4io: - lpsw .Lwaitpsw + lpsw .Lwaitpsw .Lioint: - c %r1,0xb8 # compare subchannel number - bne .Lwait4io - tsch 0(%r5) - slr %r0,%r0 - tm 8(%r5),0x82 # do we have a problem ? - bnz .Lwtexit - tm 8(%r5),0x04 # got device end ? - bz .Lwait4io + c %r1,0xb8 # compare subchannel number + bne .Lwait4io + tsch 0(%r5) + slr %r0,%r0 + tm 8(%r5),0x82 # do we have a problem ? + bnz .Lwtexit + tm 8(%r5),0x04 # got device end ? + bz .Lwait4io .Lwtexit: - br %r14 + br %r14 .Llderr: - lpsw .Lcrash + lpsw .Lcrash - .align 8 + .align 8 .Lorbread: - .long 0x00000000,0x0080ff00,.Lccwread - .align 8 + .long 0x00000000,0x0080ff00,.Lccwread + .align 8 .Lorbsense: - .long 0x00000000,0x0080ff00,.Lccwsense - .align 8 + .long 0x00000000,0x0080ff00,.Lccwsense + .align 8 .Lccwread: - .long 0x02200000+IPL_BS,0x00000000 + .long 0x02200000+IPL_BS,0x00000000 .Lccwsense: - .long 0x04200001,0x00000000 + .long 0x04200001,0x00000000 .Lwaitpsw: - .long 0x020a0000,0x80000000+.Lioint + .long 0x020a0000,0x80000000+.Lioint -.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -.Lcr6: .long 0xff000000 - .align 8 -.Lcrash:.long 0x000a0000,0x00000000 -.Lldret:.long 0 +.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.Lcr6: .long 0xff000000 + .align 8 +.Lcrash:.long 0x000a0000,0x00000000 +.Lldret:.long 0 .Lsnsret: .long 0 -#endif /* CONFIG_IPL_TAPE */ +#endif /* CONFIG_IPL_TAPE */ #ifdef CONFIG_IPL_VM -#define IPL_BS 0x730 - .org 0 - .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded - .long 0x02000018,0x60000050 # by ipl to addresses 0-23. - .long 0x02000068,0x60000050 # (a PSW and two CCWs). - .fill 80-24,1,0x40 # bytes 24-79 are discarded !! - .long 0x020000f0,0x60000050 # The next 160 byte are loaded - .long 0x02000140,0x60000050 # to addresses 0x18-0xb7 - .long 0x02000190,0x60000050 # They form the continuation - .long 0x020001e0,0x60000050 # of the CCW program started - .long 0x02000230,0x60000050 # by ipl and load the range - .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image - .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730 - .long 0x02000320,0x60000050 # in memory. At the end of - .long 0x02000370,0x60000050 # the channel program the PSW - .long 0x020003c0,0x60000050 # at location 0 is loaded. - .long 0x02000410,0x60000050 # Initial processing starts - .long 0x02000460,0x60000050 # at 0xf0 = iplstart. - .long 0x020004b0,0x60000050 - .long 0x02000500,0x60000050 - .long 0x02000550,0x60000050 - .long 0x020005a0,0x60000050 - .long 0x020005f0,0x60000050 - .long 0x02000640,0x60000050 - .long 0x02000690,0x60000050 - .long 0x020006e0,0x20000050 +#define IPL_BS 0x730 + .org 0 + .long 0x00080000,0x80000000+iplstart # The first 24 bytes are loaded + .long 0x02000018,0x60000050 # by ipl to addresses 0-23. + .long 0x02000068,0x60000050 # (a PSW and two CCWs). + .fill 80-24,1,0x40 # bytes 24-79 are discarded !! + .long 0x020000f0,0x60000050 # The next 160 byte are loaded + .long 0x02000140,0x60000050 # to addresses 0x18-0xb7 + .long 0x02000190,0x60000050 # They form the continuation + .long 0x020001e0,0x60000050 # of the CCW program started + .long 0x02000230,0x60000050 # by ipl and load the range + .long 0x02000280,0x60000050 # 0x0f0-0x730 from the image + .long 0x020002d0,0x60000050 # to the range 0x0f0-0x730 + .long 0x02000320,0x60000050 # in memory. At the end of + .long 0x02000370,0x60000050 # the channel program the PSW + .long 0x020003c0,0x60000050 # at location 0 is loaded. + .long 0x02000410,0x60000050 # Initial processing starts + .long 0x02000460,0x60000050 # at 0xf0 = iplstart. + .long 0x020004b0,0x60000050 + .long 0x02000500,0x60000050 + .long 0x02000550,0x60000050 + .long 0x020005a0,0x60000050 + .long 0x020005f0,0x60000050 + .long 0x02000640,0x60000050 + .long 0x02000690,0x60000050 + .long 0x020006e0,0x20000050 - .org 0xf0 + .org 0xf0 # # subroutine for loading cards from the reader # -.Lloader: - la %r3,.Lorb # r2 = address of orb into r2 - la %r5,.Lirb # r4 = address of irb - la %r6,.Lccws - la %r7,20 +.Lloader: + la %r3,.Lorb # r2 = address of orb into r2 + la %r5,.Lirb # r4 = address of irb + la %r6,.Lccws + la %r7,20 .Linit: - st %r2,4(%r6) # initialize CCW data addresses - la %r2,0x50(%r2) - la %r6,8(%r6) - bct 7,.Linit + st %r2,4(%r6) # initialize CCW data addresses + la %r2,0x50(%r2) + la %r6,8(%r6) + bct 7,.Linit - lctl %c6,%c6,.Lcr6 # set IO subclass mask - slr %r2,%r2 + lctl %c6,%c6,.Lcr6 # set IO subclass mask + slr %r2,%r2 .Lldlp: - ssch 0(%r3) # load chunk of 1600 bytes - bnz .Llderr + ssch 0(%r3) # load chunk of 1600 bytes + bnz .Llderr .Lwait4irq: - mvc 0x78(8),.Lnewpsw # set up IO interrupt psw - lpsw .Lwaitpsw + mvc 0x78(8),.Lnewpsw # set up IO interrupt psw + lpsw .Lwaitpsw .Lioint: - c %r1,0xb8 # compare subchannel number - bne .Lwait4irq - tsch 0(%r5) + c %r1,0xb8 # compare subchannel number + bne .Lwait4irq + tsch 0(%r5) - slr %r0,%r0 - ic %r0,8(%r5) # get device status - chi %r0,8 # channel end ? - be .Lcont - chi %r0,12 # channel end + device end ? - be .Lcont + slr %r0,%r0 + ic %r0,8(%r5) # get device status + chi %r0,8 # channel end ? + be .Lcont + chi %r0,12 # channel end + device end ? + be .Lcont - l %r0,4(%r5) - s %r0,8(%r3) # r0/8 = number of ccws executed - mhi %r0,10 # *10 = number of bytes in ccws - lh %r3,10(%r5) # get residual count - sr %r0,%r3 # #ccws*80-residual=#bytes read - ar %r2,%r0 - - br %r14 # r2 contains the total size + l %r0,4(%r5) + s %r0,8(%r3) # r0/8 = number of ccws executed + mhi %r0,10 # *10 = number of bytes in ccws + lh %r3,10(%r5) # get residual count + sr %r0,%r3 # #ccws*80-residual=#bytes read + ar %r2,%r0 + + br %r14 # r2 contains the total size .Lcont: - ahi %r2,0x640 # add 0x640 to total size - la %r6,.Lccws - la %r7,20 + ahi %r2,0x640 # add 0x640 to total size + la %r6,.Lccws + la %r7,20 .Lincr: - l %r0,4(%r6) # update CCW data addresses - ahi %r0,0x640 - st %r0,4(%r6) - ahi %r6,8 - bct 7,.Lincr + l %r0,4(%r6) # update CCW data addresses + ahi %r0,0x640 + st %r0,4(%r6) + ahi %r6,8 + bct 7,.Lincr - b .Lldlp + b .Lldlp .Llderr: - lpsw .Lcrash + lpsw .Lcrash - .align 8 -.Lorb: .long 0x00000000,0x0080ff00,.Lccws -.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -.Lcr6: .long 0xff000000 -.Lloadp:.long 0,0 - .align 8 -.Lcrash:.long 0x000a0000,0x00000000 + .align 8 +.Lorb: .long 0x00000000,0x0080ff00,.Lccws +.Lirb: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +.Lcr6: .long 0xff000000 +.Lloadp:.long 0,0 + .align 8 +.Lcrash:.long 0x000a0000,0x00000000 .Lnewpsw: - .long 0x00080000,0x80000000+.Lioint + .long 0x00080000,0x80000000+.Lioint .Lwaitpsw: - .long 0x020a0000,0x80000000+.Lioint + .long 0x020a0000,0x80000000+.Lioint - .align 8 -.Lccws: .rept 19 - .long 0x02600050,0x00000000 - .endr - .long 0x02200050,0x00000000 -#endif /* CONFIG_IPL_VM */ + .align 8 +.Lccws: .rept 19 + .long 0x02600050,0x00000000 + .endr + .long 0x02200050,0x00000000 +#endif /* CONFIG_IPL_VM */ iplstart: - lh %r1,0xb8 # test if subchannel number - bct %r1,.Lnoload # is valid - l %r1,0xb8 # load ipl subchannel number - la %r2,IPL_BS # load start address - bas %r14,.Lloader # load rest of ipl image - l %r12,.Lparm # pointer to parameter area - st %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number + lh %r1,0xb8 # test if subchannel number + bct %r1,.Lnoload # is valid + l %r1,0xb8 # load ipl subchannel number + la %r2,IPL_BS # load start address + bas %r14,.Lloader # load rest of ipl image + l %r12,.Lparm # pointer to parameter area + st %r1,IPL_DEVICE+ARCH_OFFSET-PARMAREA(%r12) # save ipl device number # # load parameter file from ipl device # .Lagain1: - l %r2,.Linitrd # ramdisk loc. is temp - bas %r14,.Lloader # load parameter file - ltr %r2,%r2 # got anything ? - bz .Lnopf - chi %r2,895 - bnh .Lnotrunc - la %r2,895 + l %r2,.Linitrd # ramdisk loc. is temp + bas %r14,.Lloader # load parameter file + ltr %r2,%r2 # got anything ? + bz .Lnopf + chi %r2,895 + bnh .Lnotrunc + la %r2,895 .Lnotrunc: - l %r4,.Linitrd - clc 0(3,%r4),.L_hdr # if it is HDRx - bz .Lagain1 # skip dataset header - clc 0(3,%r4),.L_eof # if it is EOFx - bz .Lagain1 # skip dateset trailer - la %r5,0(%r4,%r2) - lr %r3,%r2 + l %r4,.Linitrd + clc 0(3,%r4),.L_hdr # if it is HDRx + bz .Lagain1 # skip dataset header + clc 0(3,%r4),.L_eof # if it is EOFx + bz .Lagain1 # skip dateset trailer + la %r5,0(%r4,%r2) + lr %r3,%r2 .Lidebc: - tm 0(%r5),0x80 # high order bit set ? - bo .Ldocv # yes -> convert from EBCDIC - ahi %r5,-1 - bct %r3,.Lidebc - b .Lnocv + tm 0(%r5),0x80 # high order bit set ? + bo .Ldocv # yes -> convert from EBCDIC + ahi %r5,-1 + bct %r3,.Lidebc + b .Lnocv .Ldocv: - l %r3,.Lcvtab - tr 0(256,%r4),0(%r3) # convert parameters to ascii - tr 256(256,%r4),0(%r3) - tr 512(256,%r4),0(%r3) - tr 768(122,%r4),0(%r3) -.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line - mvc 0(256,%r3),0(%r4) - mvc 256(256,%r3),256(%r4) - mvc 512(256,%r3),512(%r4) - mvc 768(122,%r3),768(%r4) - slr %r0,%r0 - b .Lcntlp + l %r3,.Lcvtab + tr 0(256,%r4),0(%r3) # convert parameters to ascii + tr 256(256,%r4),0(%r3) + tr 512(256,%r4),0(%r3) + tr 768(122,%r4),0(%r3) +.Lnocv: la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line + mvc 0(256,%r3),0(%r4) + mvc 256(256,%r3),256(%r4) + mvc 512(256,%r3),512(%r4) + mvc 768(122,%r3),768(%r4) + slr %r0,%r0 + b .Lcntlp .Ldelspc: - ic %r0,0(%r2,%r3) - chi %r0,0x20 # is it a space ? - be .Lcntlp - ahi %r2,1 - b .Leolp + ic %r0,0(%r2,%r3) + chi %r0,0x20 # is it a space ? + be .Lcntlp + ahi %r2,1 + b .Leolp .Lcntlp: - brct %r2,.Ldelspc + brct %r2,.Ldelspc .Leolp: - slr %r0,%r0 - stc %r0,0(%r2,%r3) # terminate buffer + slr %r0,%r0 + stc %r0,0(%r2,%r3) # terminate buffer .Lnopf: # # load ramdisk from ipl device -# +# .Lagain2: - l %r2,.Linitrd # addr of ramdisk - st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) - bas %r14,.Lloader # load ramdisk - st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of rd - ltr %r2,%r2 - bnz .Lrdcont - st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found + l %r2,.Linitrd # addr of ramdisk + st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) + bas %r14,.Lloader # load ramdisk + st %r2,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r12) # store size of ramdisk + ltr %r2,%r2 + bnz .Lrdcont + st %r2,INITRD_START+ARCH_OFFSET-PARMAREA(%r12) # no ramdisk found .Lrdcont: - l %r2,.Linitrd + l %r2,.Linitrd - clc 0(3,%r2),.L_hdr # skip HDRx and EOFx - bz .Lagain2 - clc 0(3,%r2),.L_eof - bz .Lagain2 + clc 0(3,%r2),.L_hdr # skip HDRx and EOFx + bz .Lagain2 + clc 0(3,%r2),.L_eof + bz .Lagain2 #ifdef CONFIG_IPL_VM # # reset files in VM reader # - stidp __LC_CPUID # store cpuid - tm __LC_CPUID,0xff # running VM ? - bno .Lnoreset - la %r2,.Lreset - lhi %r3,26 - diag %r2,%r3,8 - la %r5,.Lirb - stsch 0(%r5) # check if irq is pending - tm 30(%r5),0x0f # by verifying if any of the - bnz .Lwaitforirq # activity or status control - tm 31(%r5),0xff # bits is set in the schib - bz .Lnoreset + stidp __LC_CPUID # store cpuid + tm __LC_CPUID,0xff # running VM ? + bno .Lnoreset + la %r2,.Lreset + lhi %r3,26 + diag %r2,%r3,8 + la %r5,.Lirb + stsch 0(%r5) # check if irq is pending + tm 30(%r5),0x0f # by verifying if any of the + bnz .Lwaitforirq # activity or status control + tm 31(%r5),0xff # bits is set in the schib + bz .Lnoreset .Lwaitforirq: - mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw + mvc 0x78(8),.Lrdrnewpsw # set up IO interrupt psw .Lwaitrdrirq: - lpsw .Lrdrwaitpsw + lpsw .Lrdrwaitpsw .Lrdrint: - c %r1,0xb8 # compare subchannel number - bne .Lwaitrdrirq - la %r5,.Lirb - tsch 0(%r5) + c %r1,0xb8 # compare subchannel number + bne .Lwaitrdrirq + la %r5,.Lirb + tsch 0(%r5) .Lnoreset: - b .Lnoload + b .Lnoload - .align 8 + .align 8 .Lrdrnewpsw: - .long 0x00080000,0x80000000+.Lrdrint + .long 0x00080000,0x80000000+.Lrdrint .Lrdrwaitpsw: - .long 0x020a0000,0x80000000+.Lrdrint + .long 0x020a0000,0x80000000+.Lrdrint #endif # # everything loaded, go for it # .Lnoload: - l %r1,.Lstartup - br %r1 + l %r1,.Lstartup + br %r1 -.Linitrd:.long _end + 0x400000 # default address of initrd +.Linitrd:.long _end + 0x400000 # default address of initrd .Lparm: .long PARMAREA .Lstartup: .long startup -.Lcvtab:.long _ebcasc # ebcdic to ascii table -.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40 - .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6 - .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold" -.L_eof: .long 0xc5d6c600 /* C'EOF' */ -.L_hdr: .long 0xc8c4d900 /* C'HDR' */ +.Lcvtab:.long _ebcasc # ebcdic to ascii table +.Lreset:.byte 0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40 + .byte 0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6 + .byte 0xc8,0xd6,0xd3,0xc4 # "change rdr all keep nohold" +.L_eof: .long 0xc5d6c600 /* C'EOF' */ +.L_hdr: .long 0xc8c4d900 /* C'HDR' */ -#endif /* CONFIG_IPL */ +#endif /* CONFIG_IPL */ # # SALIPL loader support. Based on a patch by Rob van der Heij. # This entry point is called directly from the SALIPL loader and # doesn't need a builtin ipl record. # - .org 0x800 - .globl start + .org 0x800 + .globl start start: - stm %r0,%r15,0x07b0 # store registers - basr %r12,%r0 + stm %r0,%r15,0x07b0 # store registers + basr %r12,%r0 .base: - l %r11,.parm - l %r8,.cmd # pointer to command buffer + l %r11,.parm + l %r8,.cmd # pointer to command buffer - ltr %r9,%r9 # do we have SALIPL parameters? - bp .sk8x8 + ltr %r9,%r9 # do we have SALIPL parameters? + bp .sk8x8 - mvc 0(64,%r8),0x00b0 # copy saved registers - xc 64(240-64,%r8),0(%r8) # remainder of buffer - tr 0(64,%r8),.lowcase - b .gotr + mvc 0(64,%r8),0x00b0 # copy saved registers + xc 64(240-64,%r8),0(%r8) # remainder of buffer + tr 0(64,%r8),.lowcase + b .gotr .sk8x8: - mvc 0(240,%r8),0(%r9) # copy iplparms into buffer + mvc 0(240,%r8),0(%r9) # copy iplparms into buffer .gotr: - l %r10,.tbl # EBCDIC to ASCII table - tr 0(240,%r8),0(%r10) - stidp __LC_CPUID # Are we running on VM maybe - cli __LC_CPUID,0xff - bnz .test - .long 0x83300060 # diag 3,0,x'0060' - storage size - b .done + l %r10,.tbl # EBCDIC to ASCII table + tr 0(240,%r8),0(%r10) + stidp __LC_CPUID # Are we running on VM maybe + cli __LC_CPUID,0xff + bnz .test + .long 0x83300060 # diag 3,0,x'0060' - storage size + b .done .test: - mvc 0x68(8),.pgmnw # set up pgm check handler - l %r2,.fourmeg - lr %r3,%r2 - bctr %r3,%r0 # 4M-1 -.loop: iske %r0,%r3 - ar %r3,%r2 + mvc 0x68(8),.pgmnw # set up pgm check handler + l %r2,.fourmeg + lr %r3,%r2 + bctr %r3,%r0 # 4M-1 +.loop: iske %r0,%r3 + ar %r3,%r2 .pgmx: - sr %r3,%r2 - la %r3,1(%r3) + sr %r3,%r2 + la %r3,1(%r3) .done: - l %r1,.memsize - st %r3,ARCH_OFFSET(%r1) - slr %r0,%r0 - st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11) - st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11) - j startup # continue with startup -.tbl: .long _ebcasc # translate table -.cmd: .long COMMAND_LINE # address of command line buffer -.parm: .long PARMAREA + l %r1,.memsize + st %r3,ARCH_OFFSET(%r1) + slr %r0,%r0 + st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11) + st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11) + j startup # continue with startup +.tbl: .long _ebcasc # translate table +.cmd: .long COMMAND_LINE # address of command line buffer +.parm: .long PARMAREA .memsize: .long memory_size .fourmeg: .long 0x00400000 # 4M -.pgmnw: .long 0x00080000,.pgmx +.pgmnw: .long 0x00080000,.pgmx .lowcase: - .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 + .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f - .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 + .byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 .byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f - .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 + .byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 .byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f - .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 + .byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 .byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f - .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47 + .byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47 .byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f - .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57 + .byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57 .byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f - .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67 + .byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67 .byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f - .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77 + .byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77 .byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f - .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87 + .byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87 .byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f - .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97 + .byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97 .byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f - .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 + .byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 .byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf - .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7 + .byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7 .byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf - .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg + .byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87 # .abcdefg .byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf # hi - .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop + .byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 # .jklmnop .byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf # qr .byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 # ..stuvwx .byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef # yz - .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 + .byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 .byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff #ifdef CONFIG_64BIT diff --git a/trunk/arch/s390/kernel/head31.S b/trunk/arch/s390/kernel/head31.S index 1b952a3664e2..1fa9fa1ca740 100644 --- a/trunk/arch/s390/kernel/head31.S +++ b/trunk/arch/s390/kernel/head31.S @@ -254,16 +254,6 @@ startup_continue: oi 3(%r12),0x80 # set IDTE flag .Lchkidte: -# -# find out if the diag 0x9c is available -# - mvc __LC_PGM_NEW_PSW(8),.Lpcdiag9c-.LPG1(%r13) - stap __LC_CPUID+4 # store cpu address - lh %r1,__LC_CPUID+4 - diag %r1,0,0x9c # test diag 0x9c - oi 2(%r12),1 # set diag9c flag -.Lchkdiag9c: - lpsw .Lentry-.LPG1(13) # jump to _stext in primary-space, # virtual and never return ... .align 8 @@ -291,7 +281,6 @@ startup_continue: .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp .Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg .Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte -.Lpcdiag9c:.long 0x00080000,0x80000000 + .Lchkdiag9c .Lmemsize:.long memory_size .Lmchunk:.long memory_chunk .Lmflags:.long machine_flags diff --git a/trunk/arch/s390/kernel/head64.S b/trunk/arch/s390/kernel/head64.S index b30e5897cdf7..a8bdd96494c7 100644 --- a/trunk/arch/s390/kernel/head64.S +++ b/trunk/arch/s390/kernel/head64.S @@ -15,232 +15,232 @@ # this is called either by the ipl loader or directly by PSW restart # or linload or SALIPL # - .org 0x10000 -startup:basr %r13,0 # get base -.LPG0: l %r13,0f-.LPG0(%r13) - b 0(%r13) -0: .long startup_continue + .org 0x10000 +startup:basr %r13,0 # get base +.LPG0: l %r13,0f-.LPG0(%r13) + b 0(%r13) +0: .long startup_continue # # params at 10400 (setup.h) # - .org PARMAREA - .quad 0 # IPL_DEVICE - .quad 0 # INITRD_START - .quad 0 # INITRD_SIZE + .org PARMAREA + .quad 0 # IPL_DEVICE + .quad 0 # INITRD_START + .quad 0 # INITRD_SIZE - .org COMMAND_LINE - .byte "root=/dev/ram0 ro" - .byte 0 + .org COMMAND_LINE + .byte "root=/dev/ram0 ro" + .byte 0 - .org 0x11000 + .org 0x11000 startup_continue: - basr %r13,0 # get base -.LPG1: sll %r13,1 # remove high order bit - srl %r13,1 - lhi %r1,1 # mode 1 = esame - mvi __LC_AR_MODE_ID,1 # set esame flag - slr %r0,%r0 # set cpuid to zero - sigp %r1,%r0,0x12 # switch to esame mode - sam64 # switch to 64 bit mode - lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers - lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area - # move IPL device to lowcore - mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) + basr %r13,0 # get base +.LPG1: sll %r13,1 # remove high order bit + srl %r13,1 + lhi %r1,1 # mode 1 = esame + mvi __LC_AR_MODE_ID,1 # set esame flag + slr %r0,%r0 # set cpuid to zero + sigp %r1,%r0,0x12 # switch to esame mode + sam64 # switch to 64 bit mode + lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers + lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area + # move IPL device to lowcore + mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) # # Setup stack # - larl %r15,init_thread_union - lg %r14,__TI_task(%r15) # cache current in lowcore - stg %r14,__LC_CURRENT - aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE - stg %r15,__LC_KERNEL_STACK # set end of kernel stack - aghi %r15,-160 - xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain + larl %r15,init_thread_union + lg %r14,__TI_task(%r15) # cache current in lowcore + stg %r14,__LC_CURRENT + aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE + stg %r15,__LC_KERNEL_STACK # set end of kernel stack + aghi %r15,-160 + xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain - brasl %r14,ipl_save_parameters + brasl %r14,ipl_save_parameters # # clear bss memory # - larl %r2,__bss_start # start of bss segment - larl %r3,_end # end of bss segment - sgr %r3,%r2 # length of bss - sgr %r4,%r4 # - sgr %r5,%r5 # set src,length and pad to zero - mvcle %r2,%r4,0 # clear mem - jo .-4 # branch back, if not finish + larl %r2,__bss_start # start of bss segment + larl %r3,_end # end of bss segment + sgr %r3,%r2 # length of bss + sgr %r4,%r4 # + sgr %r5,%r5 # set src,length and pad to zero + mvcle %r2,%r4,0 # clear mem + jo .-4 # branch back, if not finish - l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word + l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word .Lservicecall: - stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts + stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts - stctg %r0,%r0,.Lcr-.LPG1(%r13) # get cr0 - la %r1,0x200 # set bit 22 - og %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1 - stg %r1,.Lcr-.LPG1(%r13) - lctlg %r0,%r0,.Lcr-.LPG1(%r13) # load modified cr0 + stctg %r0,%r0,.Lcr-.LPG1(%r13) # get cr0 + la %r1,0x200 # set bit 22 + og %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1 + stg %r1,.Lcr-.LPG1(%r13) + lctlg %r0,%r0,.Lcr-.LPG1(%r13) # load modified cr0 - mvc __LC_EXT_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # set postcall psw - larl %r1,.Lsclph - stg %r1,__LC_EXT_NEW_PSW+8 # set handler + mvc __LC_EXT_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # set postcall psw + larl %r1,.Lsclph + stg %r1,__LC_EXT_NEW_PSW+8 # set handler - larl %r4,.Lsccb # %r4 is our index for sccb stuff - lgr %r1,%r4 # our sccb - .insn rre,0xb2200000,%r2,%r1 # service call - ipm %r1 - srl %r1,28 # get cc code - xr %r3,%r3 - chi %r1,3 - be .Lfchunk-.LPG1(%r13) # leave - chi %r1,2 - be .Lservicecall-.LPG1(%r13) - lpswe .Lwaitsclp-.LPG1(%r13) + larl %r4,.Lsccb # %r4 is our index for sccb stuff + lgr %r1,%r4 # our sccb + .insn rre,0xb2200000,%r2,%r1 # service call + ipm %r1 + srl %r1,28 # get cc code + xr %r3,%r3 + chi %r1,3 + be .Lfchunk-.LPG1(%r13) # leave + chi %r1,2 + be .Lservicecall-.LPG1(%r13) + lpswe .Lwaitsclp-.LPG1(%r13) .Lsclph: - lh %r1,.Lsccbr-.Lsccb(%r4) - chi %r1,0x10 # 0x0010 is the sucess code - je .Lprocsccb # let's process the sccb - chi %r1,0x1f0 - bne .Lfchunk-.LPG1(%r13) # unhandled error code - c %r2,.Lrcp-.LPG1(%r13) # Did we try Read SCP forced - bne .Lfchunk-.LPG1(%r13) # if no, give up - l %r2,.Lrcp2-.LPG1(%r13) # try with Read SCP - b .Lservicecall-.LPG1(%r13) + lh %r1,.Lsccbr-.Lsccb(%r4) + chi %r1,0x10 # 0x0010 is the sucess code + je .Lprocsccb # let's process the sccb + chi %r1,0x1f0 + bne .Lfchunk-.LPG1(%r13) # unhandled error code + c %r2,.Lrcp-.LPG1(%r13) # Did we try Read SCP forced + bne .Lfchunk-.LPG1(%r13) # if no, give up + l %r2,.Lrcp2-.LPG1(%r13) # try with Read SCP + b .Lservicecall-.LPG1(%r13) .Lprocsccb: - lghi %r1,0 - icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 - jnz .Lscnd - lg %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one + lghi %r1,0 + icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 + jnz .Lscnd + lg %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one .Lscnd: - xr %r3,%r3 # same logic - ic %r3,.Lscpa1-.Lsccb(%r4) - chi %r3,0x00 - jne .Lcompmem - l %r3,.Lscpa2-.Lsccb(%r4) + xr %r3,%r3 # same logic + ic %r3,.Lscpa1-.Lsccb(%r4) + chi %r3,0x00 + jne .Lcompmem + l %r3,.Lscpa2-.Lsccb(%r4) .Lcompmem: - mlgr %r2,%r1 # mem in MB on 128-bit - l %r1,.Lonemb-.LPG1(%r13) - mlgr %r2,%r1 # mem size in bytes in %r3 - b .Lfchunk-.LPG1(%r13) + mlgr %r2,%r1 # mem in MB on 128-bit + l %r1,.Lonemb-.LPG1(%r13) + mlgr %r2,%r1 # mem size in bytes in %r3 + b .Lfchunk-.LPG1(%r13) - .align 4 + .align 4 .Lpmask: - .byte 0 - .align 8 + .byte 0 + .align 8 .Lcr: - .quad 0x00 # place holder for cr0 + .quad 0x00 # place holder for cr0 .Lwaitsclp: - .quad 0x0102000180000000,.Lsclph + .quad 0x0102000180000000,.Lsclph .Lrcp: - .int 0x00120001 # Read SCP forced code + .int 0x00120001 # Read SCP forced code .Lrcp2: - .int 0x00020001 # Read SCP code + .int 0x00020001 # Read SCP code .Lonemb: - .int 0x100000 + .int 0x100000 .Lfchunk: - # set program check new psw mask - mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) + # set program check new psw mask + mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # # find memory chunks. # - lgr %r9,%r3 # end of mem - larl %r1,.Lchkmem # set program check address - stg %r1,__LC_PGM_NEW_PSW+8 - la %r1,1 # test in increments of 128KB - sllg %r1,%r1,17 - larl %r3,memory_chunk - slgr %r4,%r4 # set start of chunk to zero - slgr %r5,%r5 # set end of chunk to zero - slr %r6,%r6 # set access code to zero - la %r10,MEMORY_CHUNKS # number of chunks + lgr %r9,%r3 # end of mem + larl %r1,.Lchkmem # set program check address + stg %r1,__LC_PGM_NEW_PSW+8 + la %r1,1 # test in increments of 128KB + sllg %r1,%r1,17 + larl %r3,memory_chunk + slgr %r4,%r4 # set start of chunk to zero + slgr %r5,%r5 # set end of chunk to zero + slr %r6,%r6 # set access code to zero + la %r10,MEMORY_CHUNKS # number of chunks .Lloop: - tprot 0(%r5),0 # test protection of first byte - ipm %r7 - srl %r7,28 - clr %r6,%r7 # compare cc with last access code - je .Lsame - j .Lchkmem + tprot 0(%r5),0 # test protection of first byte + ipm %r7 + srl %r7,28 + clr %r6,%r7 # compare cc with last access code + je .Lsame + j .Lchkmem .Lsame: - algr %r5,%r1 # add 128KB to end of chunk - # no need to check here, - brc 12,.Lloop # this is the same chunk -.Lchkmem: # > 16EB or tprot got a program check - clgr %r4,%r5 # chunk size > 0? - je .Lchkloop - stg %r4,0(%r3) # store start address of chunk - lgr %r0,%r5 - slgr %r0,%r4 - stg %r0,8(%r3) # store size of chunk - st %r6,20(%r3) # store type of chunk - la %r3,24(%r3) - larl %r8,memory_size - stg %r5,0(%r8) # store memory size - ahi %r10,-1 # update chunk number + algr %r5,%r1 # add 128KB to end of chunk + # no need to check here, + brc 12,.Lloop # this is the same chunk +.Lchkmem: # > 16EB or tprot got a program check + clgr %r4,%r5 # chunk size > 0? + je .Lchkloop + stg %r4,0(%r3) # store start address of chunk + lgr %r0,%r5 + slgr %r0,%r4 + stg %r0,8(%r3) # store size of chunk + st %r6,20(%r3) # store type of chunk + la %r3,24(%r3) + larl %r8,memory_size + stg %r5,0(%r8) # store memory size + ahi %r10,-1 # update chunk number .Lchkloop: - lr %r6,%r7 # set access code to last cc + lr %r6,%r7 # set access code to last cc # we got an exception or we're starting a new # chunk , we must check if we should # still try to find valid memory (if we detected # the amount of available storage), and if we # have chunks left - lghi %r4,1 - sllg %r4,%r4,31 - clgr %r5,%r4 - je .Lhsaskip - xr %r0, %r0 - clgr %r0, %r9 # did we detect memory? - je .Ldonemem # if not, leave - chi %r10, 0 # do we have chunks left? - je .Ldonemem + lghi %r4,1 + sllg %r4,%r4,31 + clgr %r5,%r4 + je .Lhsaskip + xr %r0, %r0 + clgr %r0, %r9 # did we detect memory? + je .Ldonemem # if not, leave + chi %r10, 0 # do we have chunks left? + je .Ldonemem .Lhsaskip: - algr %r5,%r1 # add 128KB to end of chunk - lgr %r4,%r5 # potential new chunk - clgr %r5,%r9 # should we go on? - jl .Lloop -.Ldonemem: + algr %r5,%r1 # add 128KB to end of chunk + lgr %r4,%r5 # potential new chunk + clgr %r5,%r9 # should we go on? + jl .Lloop +.Ldonemem: - larl %r12,machine_flags + larl %r12,machine_flags # # find out if we are running under VM # - stidp __LC_CPUID # store cpuid - tm __LC_CPUID,0xff # running under VM ? - bno 0f-.LPG1(%r13) - oi 7(%r12),1 # set VM flag -0: lh %r0,__LC_CPUID+4 # get cpu version - chi %r0,0x7490 # running on a P/390 ? - bne 1f-.LPG1(%r13) - oi 7(%r12),4 # set P/390 flag + stidp __LC_CPUID # store cpuid + tm __LC_CPUID,0xff # running under VM ? + bno 0f-.LPG1(%r13) + oi 7(%r12),1 # set VM flag +0: lh %r0,__LC_CPUID+4 # get cpu version + chi %r0,0x7490 # running on a P/390 ? + bne 1f-.LPG1(%r13) + oi 7(%r12),4 # set P/390 flag 1: # # find out if we have the MVPG instruction # - la %r1,0f-.LPG1(%r13) # set program check address - stg %r1,__LC_PGM_NEW_PSW+8 - sgr %r0,%r0 - lghi %r1,0 - lghi %r2,0 - mvpg %r1,%r2 # test MVPG instruction - oi 7(%r12),16 # set MVPG flag + la %r1,0f-.LPG1(%r13) # set program check address + stg %r1,__LC_PGM_NEW_PSW+8 + sgr %r0,%r0 + lghi %r1,0 + lghi %r2,0 + mvpg %r1,%r2 # test MVPG instruction + oi 7(%r12),16 # set MVPG flag 0: # # find out if the diag 0x44 works in 64 bit mode # - la %r1,0f-.LPG1(%r13) # set program check address - stg %r1,__LC_PGM_NEW_PSW+8 - diag 0,0,0x44 # test diag 0x44 - oi 7(%r12),32 # set diag44 flag -0: + la %r1,0f-.LPG1(%r13) # set program check address + stg %r1,__LC_PGM_NEW_PSW+8 + diag 0,0,0x44 # test diag 0x44 + oi 7(%r12),32 # set diag44 flag +0: # # find out if we have the IDTE instruction # - la %r1,0f-.LPG1(%r13) # set program check address - stg %r1,__LC_PGM_NEW_PSW+8 + la %r1,0f-.LPG1(%r13) # set program check address + stg %r1,__LC_PGM_NEW_PSW+8 .long 0xb2b10000 # store facility list tm 0xc8,0x08 # check bit for clearing-by-ASCE bno 0f-.LPG1(%r13) @@ -250,17 +250,6 @@ startup_continue: oi 7(%r12),0x80 # set IDTE flag 0: -# -# find out if the diag 0x9c is available -# - la %r1,0f-.LPG1(%r13) # set program check address - stg %r1,__LC_PGM_NEW_PSW+8 - stap __LC_CPUID+4 # store cpu address - lh %r1,__LC_CPUID+4 - diag %r1,0,0x9c # test diag 0x9c - oi 6(%r12),1 # set diag9c flag -0: - # # find out if we have the MVCOS instruction # @@ -274,45 +263,45 @@ startup_continue: oi 6(%r12),2 # set MVCOS flag 1: - lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space, - # virtual and never return ... - .align 16 -.Lentry:.quad 0x0000000180000000,_stext -.Lctl: .quad 0x04b50002 # cr0: various things - .quad 0 # cr1: primary space segment table - .quad .Lduct # cr2: dispatchable unit control table - .quad 0 # cr3: instruction authorization - .quad 0 # cr4: instruction authorization - .quad 0xffffffffffffffff # cr5: primary-aste origin - .quad 0 # cr6: I/O interrupts - .quad 0 # cr7: secondary space segment table - .quad 0 # cr8: access registers translation - .quad 0 # cr9: tracing off - .quad 0 # cr10: tracing off - .quad 0 # cr11: tracing off - .quad 0 # cr12: tracing off - .quad 0 # cr13: home space segment table - .quad 0xc0000000 # cr14: machine check handling off - .quad 0 # cr15: linkage stack operations -.Lduct: .long 0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0 -.Lpcmsk:.quad 0x0000000180000000 + lpswe .Lentry-.LPG1(13) # jump to _stext in primary-space, + # virtual and never return ... + .align 16 +.Lentry:.quad 0x0000000180000000,_stext +.Lctl: .quad 0x04b50002 # cr0: various things + .quad 0 # cr1: primary space segment table + .quad .Lduct # cr2: dispatchable unit control table + .quad 0 # cr3: instruction authorization + .quad 0 # cr4: instruction authorization + .quad 0xffffffffffffffff # cr5: primary-aste origin + .quad 0 # cr6: I/O interrupts + .quad 0 # cr7: secondary space segment table + .quad 0 # cr8: access registers translation + .quad 0 # cr9: tracing off + .quad 0 # cr10: tracing off + .quad 0 # cr11: tracing off + .quad 0 # cr12: tracing off + .quad 0 # cr13: home space segment table + .quad 0xc0000000 # cr14: machine check handling off + .quad 0 # cr15: linkage stack operations +.Lduct: .long 0,0,0,0,0,0,0,0 + .long 0,0,0,0,0,0,0,0 +.Lpcmsk:.quad 0x0000000180000000 .L4malign:.quad 0xffffffffffc00000 -.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 -.Lnop: .long 0x07000700 +.Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 +.Lnop: .long 0x07000700 .Lparmaddr: .quad PARMAREA - .globl ipl_schib + .globl ipl_schib ipl_schib: .rept 13 .long 0 .endr - .globl ipl_flags + .globl ipl_flags ipl_flags: - .long 0 - .globl ipl_devno + .long 0 + .globl ipl_devno ipl_devno: .word 0 @@ -320,47 +309,47 @@ ipl_devno: .globl s390_readinfo_sccb s390_readinfo_sccb: .Lsccb: - .hword 0x1000 # length, one page - .byte 0x00,0x00,0x00 - .byte 0x80 # variable response bit set + .hword 0x1000 # length, one page + .byte 0x00,0x00,0x00 + .byte 0x80 # variable response bit set .Lsccbr: - .hword 0x00 # response code + .hword 0x00 # response code .Lscpincr1: - .hword 0x00 + .hword 0x00 .Lscpa1: - .byte 0x00 - .fill 89,1,0 + .byte 0x00 + .fill 89,1,0 .Lscpa2: - .int 0x00 + .int 0x00 .Lscpincr2: - .quad 0x00 - .fill 3984,1,0 + .quad 0x00 + .fill 3984,1,0 .org 0x13000 #ifdef CONFIG_SHARED_KERNEL - .org 0x100000 + .org 0x100000 #endif - + # # startup-code, running in absolute addressing mode # - .globl _stext -_stext: basr %r13,0 # get base + .globl _stext +_stext: basr %r13,0 # get base .LPG3: # check control registers - stctg %c0,%c15,0(%r15) - oi 6(%r15),0x40 # enable sigp emergency signal - oi 4(%r15),0x10 # switch on low address proctection - lctlg %c0,%c15,0(%r15) + stctg %c0,%c15,0(%r15) + oi 6(%r15),0x40 # enable sigp emergency signal + oi 4(%r15),0x10 # switch on low address proctection + lctlg %c0,%c15,0(%r15) - lam 0,15,.Laregs-.LPG3(%r13) # load acrs needed by uaccess - brasl %r14,start_kernel # go to C code + lam 0,15,.Laregs-.LPG3(%r13) # load access regs needed by uaccess + brasl %r14,start_kernel # go to C code # # We returned from start_kernel ?!? PANIK # - basr %r13,0 - lpswe .Ldw-.(%r13) # load disabled wait psw + basr %r13,0 + lpswe .Ldw-.(%r13) # load disabled wait psw - .align 8 -.Ldw: .quad 0x0002000180000000,0x0000000000000000 -.Laregs:.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + .align 8 +.Ldw: .quad 0x0002000180000000,0x0000000000000000 +.Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 diff --git a/trunk/arch/s390/kernel/ipl.c b/trunk/arch/s390/kernel/ipl.c index 1f5e782b3d05..6555cc48e28f 100644 --- a/trunk/arch/s390/kernel/ipl.c +++ b/trunk/arch/s390/kernel/ipl.c @@ -120,15 +120,24 @@ static enum shutdown_action on_panic_action = SHUTDOWN_STOP; static int diag308(unsigned long subcode, void *addr) { - register unsigned long _addr asm("0") = (unsigned long) addr; + register unsigned long _addr asm("0") = (unsigned long)addr; register unsigned long _rc asm("1") = 0; - asm volatile( - " diag %0,%2,0x308\n" - "0:\n" - EX_TABLE(0b,0b) + asm volatile ( + " diag %0,%2,0x308\n" + "0: \n" + ".section __ex_table,\"a\"\n" +#ifdef CONFIG_64BIT + " .align 8\n" + " .quad 0b, 0b\n" +#else + " .align 4\n" + " .long 0b, 0b\n" +#endif + ".previous\n" : "+d" (_addr), "+d" (_rc) - : "d" (subcode) : "cc", "memory"); + : "d" (subcode) : "cc", "memory" ); + return _rc; } diff --git a/trunk/arch/s390/kernel/kprobes.c b/trunk/arch/s390/kernel/kprobes.c index 4d9ff5ce4cbd..ca28fb0b3790 100644 --- a/trunk/arch/s390/kernel/kprobes.c +++ b/trunk/arch/s390/kernel/kprobes.c @@ -369,12 +369,11 @@ void __kprobes kretprobe_trampoline_holder(void) int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; + struct hlist_head *head; struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; - INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); head = kretprobe_inst_table_head(current); @@ -400,7 +399,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) ri->rp->handler(ri, regs); orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); + recycle_rp_inst(ri); if (orig_ret_address != trampoline_address) { /* @@ -418,10 +417,6 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); preempt_enable_no_resched(); - hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } /* * By returning a non-zero value, we are telling * kprobe_handler() that we don't want the post_handler diff --git a/trunk/arch/s390/kernel/process.c b/trunk/arch/s390/kernel/process.c index 6603fbb41d07..d3cbfa3005ec 100644 --- a/trunk/arch/s390/kernel/process.c +++ b/trunk/arch/s390/kernel/process.c @@ -45,7 +45,7 @@ #include #include -asmlinkage void ret_from_fork(void) asm ("ret_from_fork"); +asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); /* * Return saved PC of a blocked thread. used in kernel/sched. @@ -177,8 +177,7 @@ void show_regs(struct pt_regs *regs) extern void kernel_thread_starter(void); -asm( - ".align 4\n" +__asm__(".align 4\n" "kernel_thread_starter:\n" " la 2,0(10)\n" " basr 14,9\n" diff --git a/trunk/arch/s390/kernel/reipl.S b/trunk/arch/s390/kernel/reipl.S index 0340477f3b08..4562cdbce8eb 100644 --- a/trunk/arch/s390/kernel/reipl.S +++ b/trunk/arch/s390/kernel/reipl.S @@ -32,58 +32,58 @@ do_reipl_asm: basr %r13,0 st %r13, __LC_PSW_SAVE_AREA+4 lctl %c6,%c6,.Lall-.Lpg0(%r13) - lr %r1,%r2 - mvc __LC_PGM_NEW_PSW(8),.Lpcnew-.Lpg0(%r13) - stsch .Lschib-.Lpg0(%r13) - oi .Lschib+5-.Lpg0(%r13),0x84 -.Lecs: xi .Lschib+27-.Lpg0(%r13),0x01 - msch .Lschib-.Lpg0(%r13) - lhi %r0,5 -.Lssch: ssch .Liplorb-.Lpg0(%r13) + lr %r1,%r2 + mvc __LC_PGM_NEW_PSW(8),.Lpcnew-.Lpg0(%r13) + stsch .Lschib-.Lpg0(%r13) + oi .Lschib+5-.Lpg0(%r13),0x84 +.Lecs: xi .Lschib+27-.Lpg0(%r13),0x01 + msch .Lschib-.Lpg0(%r13) + lhi %r0,5 +.Lssch: ssch .Liplorb-.Lpg0(%r13) jz .L001 - brct %r0,.Lssch + brct %r0,.Lssch bas %r14,.Ldisab-.Lpg0(%r13) -.L001: mvc __LC_IO_NEW_PSW(8),.Lionew-.Lpg0(%r13) -.Ltpi: lpsw .Lwaitpsw-.Lpg0(%r13) +.L001: mvc __LC_IO_NEW_PSW(8),.Lionew-.Lpg0(%r13) +.Ltpi: lpsw .Lwaitpsw-.Lpg0(%r13) .Lcont: c %r1,__LC_SUBCHANNEL_ID jnz .Ltpi clc __LC_IO_INT_PARM(4),.Liplorb-.Lpg0(%r13) jnz .Ltpi - tsch .Liplirb-.Lpg0(%r13) + tsch .Liplirb-.Lpg0(%r13) tm .Liplirb+9-.Lpg0(%r13),0xbf - jz .L002 - bas %r14,.Ldisab-.Lpg0(%r13) -.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 - jz .L003 - bas %r14,.Ldisab-.Lpg0(%r13) + jz .L002 + bas %r14,.Ldisab-.Lpg0(%r13) +.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 + jz .L003 + bas %r14,.Ldisab-.Lpg0(%r13) .L003: spx .Lnull-.Lpg0(%r13) - st %r1,__LC_SUBCHANNEL_ID - lpsw 0 - sigp 0,0,0(6) -.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13) + st %r1,__LC_SUBCHANNEL_ID + lpsw 0 + sigp 0,0,0(6) +.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13) lpsw .Ldispsw-.Lpg0(%r13) - .align 8 + .align 8 .Lclkcmp: .quad 0x0000000000000000 .Lall: .long 0xff000000 -.Lnull: .long 0x00000000 +.Lnull: .long 0x00000000 .Lctlsave1: .long 0x00000000 .Lctlsave2: .long 0x00000000 - .align 8 -.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1 -.Lpcnew: .long 0x00080000,0x80000000+.Lecs -.Lionew: .long 0x00080000,0x80000000+.Lcont + .align 8 +.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1 +.Lpcnew: .long 0x00080000,0x80000000+.Lecs +.Lionew: .long 0x00080000,0x80000000+.Lcont .Lwaitpsw: .long 0x020a0000,0x00000000+.Ltpi -.Ldispsw: .long 0x000a0000,0x00000000 -.Liplccws: .long 0x02000000,0x60000018 - .long 0x08000008,0x20000001 +.Ldispsw: .long 0x000a0000,0x00000000 +.Liplccws: .long 0x02000000,0x60000018 + .long 0x08000008,0x20000001 .Liplorb: .long 0x0049504c,0x0040ff80 .long 0x00000000+.Liplccws -.Lschib: .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 +.Lschib: .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 .Liplirb: .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 @@ -92,3 +92,6 @@ do_reipl_asm: basr %r13,0 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 + + + diff --git a/trunk/arch/s390/kernel/reipl64.S b/trunk/arch/s390/kernel/reipl64.S index de7435054f7c..95bd1e234f63 100644 --- a/trunk/arch/s390/kernel/reipl64.S +++ b/trunk/arch/s390/kernel/reipl64.S @@ -4,7 +4,7 @@ * S390 version * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com) - Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) + Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) */ #include @@ -32,46 +32,46 @@ do_reipl_asm: basr %r13,0 stctg %c0,%c0,.Lregsave-.Lpg0(%r13) ni .Lregsave+4-.Lpg0(%r13),0xef lctlg %c0,%c0,.Lregsave-.Lpg0(%r13) - lgr %r1,%r2 - mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) - stsch .Lschib-.Lpg0(%r13) - oi .Lschib+5-.Lpg0(%r13),0x84 -.Lecs: xi .Lschib+27-.Lpg0(%r13),0x01 - msch .Lschib-.Lpg0(%r13) - lghi %r0,5 -.Lssch: ssch .Liplorb-.Lpg0(%r13) + lgr %r1,%r2 + mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) + stsch .Lschib-.Lpg0(%r13) + oi .Lschib+5-.Lpg0(%r13),0x84 +.Lecs: xi .Lschib+27-.Lpg0(%r13),0x01 + msch .Lschib-.Lpg0(%r13) + lghi %r0,5 +.Lssch: ssch .Liplorb-.Lpg0(%r13) jz .L001 - brct %r0,.Lssch + brct %r0,.Lssch bas %r14,.Ldisab-.Lpg0(%r13) -.L001: mvc __LC_IO_NEW_PSW(16),.Lionew-.Lpg0(%r13) -.Ltpi: lpswe .Lwaitpsw-.Lpg0(%r13) +.L001: mvc __LC_IO_NEW_PSW(16),.Lionew-.Lpg0(%r13) +.Ltpi: lpswe .Lwaitpsw-.Lpg0(%r13) .Lcont: c %r1,__LC_SUBCHANNEL_ID jnz .Ltpi clc __LC_IO_INT_PARM(4),.Liplorb-.Lpg0(%r13) jnz .Ltpi - tsch .Liplirb-.Lpg0(%r13) + tsch .Liplirb-.Lpg0(%r13) tm .Liplirb+9-.Lpg0(%r13),0xbf - jz .L002 - bas %r14,.Ldisab-.Lpg0(%r13) -.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 - jz .L003 - bas %r14,.Ldisab-.Lpg0(%r13) + jz .L002 + bas %r14,.Ldisab-.Lpg0(%r13) +.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 + jz .L003 + bas %r14,.Ldisab-.Lpg0(%r13) .L003: spx .Lnull-.Lpg0(%r13) - st %r1,__LC_SUBCHANNEL_ID - lhi %r1,0 # mode 0 = esa - slr %r0,%r0 # set cpuid to zero - sigp %r1,%r0,0x12 # switch to esa mode - lpsw 0 -.Ldisab: sll %r14,1 - srl %r14,1 # need to kill hi bit to avoid specification exceptions. - st %r14,.Ldispsw+12-.Lpg0(%r13) + st %r1,__LC_SUBCHANNEL_ID + lhi %r1,0 # mode 0 = esa + slr %r0,%r0 # set cpuid to zero + sigp %r1,%r0,0x12 # switch to esa mode + lpsw 0 +.Ldisab: sll %r14,1 + srl %r14,1 # need to kill hi bit to avoid specification exceptions. + st %r14,.Ldispsw+12-.Lpg0(%r13) lpswe .Ldispsw-.Lpg0(%r13) - .align 8 + .align 8 .Lclkcmp: .quad 0x0000000000000000 .Lall: .quad 0x00000000ff000000 .Lregsave: .quad 0x0000000000000000 -.Lnull: .long 0x0000000000000000 - .align 16 +.Lnull: .long 0x0000000000000000 + .align 16 /* * These addresses have to be 31 bit otherwise * the sigp will throw a specifcation exception @@ -81,26 +81,26 @@ do_reipl_asm: basr %r13,0 * 31bit lpswe instruction a fact they appear to have * ommited from the pop. */ -.Lnewpsw: .quad 0x0000000080000000 - .quad .Lpg1 -.Lpcnew: .quad 0x0000000080000000 - .quad .Lecs -.Lionew: .quad 0x0000000080000000 - .quad .Lcont +.Lnewpsw: .quad 0x0000000080000000 + .quad .Lpg1 +.Lpcnew: .quad 0x0000000080000000 + .quad .Lecs +.Lionew: .quad 0x0000000080000000 + .quad .Lcont .Lwaitpsw: .quad 0x0202000080000000 - .quad .Ltpi -.Ldispsw: .quad 0x0002000080000000 - .quad 0x0000000000000000 -.Liplccws: .long 0x02000000,0x60000018 - .long 0x08000008,0x20000001 + .quad .Ltpi +.Ldispsw: .quad 0x0002000080000000 + .quad 0x0000000000000000 +.Liplccws: .long 0x02000000,0x60000018 + .long 0x08000008,0x20000001 .Liplorb: .long 0x0049504c,0x0040ff80 .long 0x00000000+.Liplccws -.Lschib: .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 - .long 0x00000000,0x00000000 +.Lschib: .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 + .long 0x00000000,0x00000000 .Liplirb: .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 @@ -109,3 +109,4 @@ do_reipl_asm: basr %r13,0 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 .long 0x00000000,0x00000000 + diff --git a/trunk/arch/s390/kernel/relocate_kernel.S b/trunk/arch/s390/kernel/relocate_kernel.S index f9899ff2e5b0..2a25ec7147ff 100644 --- a/trunk/arch/s390/kernel/relocate_kernel.S +++ b/trunk/arch/s390/kernel/relocate_kernel.S @@ -3,7 +3,7 @@ * * (C) Copyright IBM Corp. 2005 * - * Author(s): Rolf Adelsberger, + * Author(s): Rolf Adelsberger * Heiko Carstens * */ @@ -24,14 +24,14 @@ .text .globl relocate_kernel relocate_kernel: - basr %r13,0 # base address + basr %r13,0 #base address .base: - stnsm sys_msk-.base(%r13),0xf8 # disable DAT and IRQ (external) - spx zero64-.base(%r13) # absolute addressing mode + stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQ (external) + spx zero64-.base(%r13) #absolute addressing mode stctl %c0,%c15,ctlregs-.base(%r13) stm %r0,%r15,gprregs-.base(%r13) la %r1,load_psw-.base(%r13) - mvc 0(8,%r0),0(%r1) + mvc 0(8,%r0),0(%r1) la %r0,.back-.base(%r13) st %r0,4(%r0) oi 4(%r0),0x80 @@ -51,50 +51,50 @@ .back_pgm: lm %r0,%r15,gprregs-.base(%r13) .start_reloc: - lhi %r10,-1 # preparing the mask - sll %r10,12 # shift it such that it becomes 0xf000 + lhi %r10,-1 #preparing the mask + sll %r10,12 #shift it such that it becomes 0xf000 .top: - lhi %r7,4096 # load PAGE_SIZE in r7 - lhi %r9,4096 # load PAGE_SIZE in r9 - l %r5,0(%r2) # read another word for indirection page - ahi %r2,4 # increment pointer - tml %r5,0x1 # is it a destination page? - je .indir_check # NO, goto "indir_check" - lr %r6,%r5 # r6 = r5 - nr %r6,%r10 # mask it out and... - j .top # ...next iteration + lhi %r7,4096 #load PAGE_SIZE in r7 + lhi %r9,4096 #load PAGE_SIZE in r9 + l %r5,0(%r2) #read another word for indirection page + ahi %r2,4 #increment pointer + tml %r5,0x1 #is it a destination page? + je .indir_check #NO, goto "indir_check" + lr %r6,%r5 #r6 = r5 + nr %r6,%r10 #mask it out and... + j .top #...next iteration .indir_check: - tml %r5,0x2 # is it a indirection page? - je .done_test # NO, goto "done_test" - nr %r5,%r10 # YES, mask out, - lr %r2,%r5 # move it into the right register, - j .top # and read next... + tml %r5,0x2 #is it a indirection page? + je .done_test #NO, goto "done_test" + nr %r5,%r10 #YES, mask out, + lr %r2,%r5 #move it into the right register, + j .top #and read next... .done_test: - tml %r5,0x4 # is it the done indicator? - je .source_test # NO! Well, then it should be the source indicator... - j .done # ok, lets finish it here... + tml %r5,0x4 #is it the done indicator? + je .source_test #NO! Well, then it should be the source indicator... + j .done #ok, lets finish it here... .source_test: - tml %r5,0x8 # it should be a source indicator... - je .top # NO, ignore it... - lr %r8,%r5 # r8 = r5 - nr %r8,%r10 # masking - 0: mvcle %r6,%r8,0x0 # copy PAGE_SIZE bytes from r8 to r6 - pad with 0 + tml %r5,0x8 #it should be a source indicator... + je .top #NO, ignore it... + lr %r8,%r5 #r8 = r5 + nr %r8,%r10 #masking + 0: mvcle %r6,%r8,0x0 #copy PAGE_SIZE bytes from r8 to r6 - pad with 0 jo 0b j .top .done: - sr %r0,%r0 # clear register r0 - la %r4,load_psw-.base(%r13) # load psw-address into the register - o %r3,4(%r4) # or load address into psw + sr %r0,%r0 #clear register r0 + la %r4,load_psw-.base(%r13) #load psw-address into the register + o %r3,4(%r4) #or load address into psw st %r3,4(%r4) - mvc 0(8,%r0),0(%r4) # copy psw to absolute address 0 + mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 tm have_diag308-.base(%r13),0x01 jno .no_diag308 diag %r0,%r0,0x308 .no_diag308: - sr %r1,%r1 # clear %r1 - sr %r2,%r2 # clear %r2 - sigp %r1,%r2,0x12 # set cpuid to zero - lpsw 0 # hopefully start new kernel... + sr %r1,%r1 #clear %r1 + sr %r2,%r2 #clear %r2 + sigp %r1,%r2,0x12 #set cpuid to zero + lpsw 0 #hopefully start new kernel... .align 8 zero64: diff --git a/trunk/arch/s390/kernel/relocate_kernel64.S b/trunk/arch/s390/kernel/relocate_kernel64.S index 4fb443042d9c..8cdb86e8911f 100644 --- a/trunk/arch/s390/kernel/relocate_kernel64.S +++ b/trunk/arch/s390/kernel/relocate_kernel64.S @@ -3,7 +3,7 @@ * * (C) Copyright IBM Corp. 2005 * - * Author(s): Rolf Adelsberger, + * Author(s): Rolf Adelsberger * Heiko Carstens * */ @@ -25,10 +25,10 @@ .text .globl relocate_kernel relocate_kernel: - basr %r13,0 # base address + basr %r13,0 #base address .base: - stnsm sys_msk-.base(%r13),0xf8 # disable DAT and IRQs - spx zero64-.base(%r13) # absolute addressing mode + stnsm sys_msk-.base(%r13),0xf8 #disable DAT and IRQs + spx zero64-.base(%r13) #absolute addressing mode stctg %c0,%c15,ctlregs-.base(%r13) stmg %r0,%r15,gprregs-.base(%r13) lghi %r0,3 @@ -37,16 +37,16 @@ la %r0,.back_pgm-.base(%r13) stg %r0,0x1d8(%r0) la %r1,load_psw-.base(%r13) - mvc 0(8,%r0),0(%r1) + mvc 0(8,%r0),0(%r1) la %r0,.back-.base(%r13) st %r0,4(%r0) oi 4(%r0),0x80 lghi %r0,0 diag %r0,%r0,0x308 .back: - lhi %r1,1 # mode 1 = esame - sigp %r1,%r0,0x12 # switch to esame mode - sam64 # switch to 64 bit addressing mode + lhi %r1,1 #mode 1 = esame + sigp %r1,%r0,0x12 #switch to esame mode + sam64 #switch to 64 bit addressing mode basr %r13,0 .back_base: oi have_diag308-.back_base(%r13),0x01 @@ -56,50 +56,50 @@ .back_pgm: lmg %r0,%r15,gprregs-.base(%r13) .top: - lghi %r7,4096 # load PAGE_SIZE in r7 - lghi %r9,4096 # load PAGE_SIZE in r9 - lg %r5,0(%r2) # read another word for indirection page - aghi %r2,8 # increment pointer - tml %r5,0x1 # is it a destination page? - je .indir_check # NO, goto "indir_check" - lgr %r6,%r5 # r6 = r5 - nill %r6,0xf000 # mask it out and... - j .top # ...next iteration + lghi %r7,4096 #load PAGE_SIZE in r7 + lghi %r9,4096 #load PAGE_SIZE in r9 + lg %r5,0(%r2) #read another word for indirection page + aghi %r2,8 #increment pointer + tml %r5,0x1 #is it a destination page? + je .indir_check #NO, goto "indir_check" + lgr %r6,%r5 #r6 = r5 + nill %r6,0xf000 #mask it out and... + j .top #...next iteration .indir_check: - tml %r5,0x2 # is it a indirection page? - je .done_test # NO, goto "done_test" - nill %r5,0xf000 # YES, mask out, - lgr %r2,%r5 # move it into the right register, - j .top # and read next... + tml %r5,0x2 #is it a indirection page? + je .done_test #NO, goto "done_test" + nill %r5,0xf000 #YES, mask out, + lgr %r2,%r5 #move it into the right register, + j .top #and read next... .done_test: - tml %r5,0x4 # is it the done indicator? - je .source_test # NO! Well, then it should be the source indicator... - j .done # ok, lets finish it here... + tml %r5,0x4 #is it the done indicator? + je .source_test #NO! Well, then it should be the source indicator... + j .done #ok, lets finish it here... .source_test: - tml %r5,0x8 # it should be a source indicator... - je .top # NO, ignore it... - lgr %r8,%r5 # r8 = r5 - nill %r8,0xf000 # masking - 0: mvcle %r6,%r8,0x0 # copy PAGE_SIZE bytes from r8 to r6 - pad with 0 + tml %r5,0x8 #it should be a source indicator... + je .top #NO, ignore it... + lgr %r8,%r5 #r8 = r5 + nill %r8,0xf000 #masking + 0: mvcle %r6,%r8,0x0 #copy PAGE_SIZE bytes from r8 to r6 - pad with 0 jo 0b - j .top + j .top .done: - sgr %r0,%r0 # clear register r0 - la %r4,load_psw-.base(%r13) # load psw-address into the register - o %r3,4(%r4) # or load address into psw + sgr %r0,%r0 #clear register r0 + la %r4,load_psw-.base(%r13) #load psw-address into the register + o %r3,4(%r4) #or load address into psw st %r3,4(%r4) - mvc 0(8,%r0),0(%r4) # copy psw to absolute address 0 + mvc 0(8,%r0),0(%r4) #copy psw to absolute address 0 tm have_diag308-.base(%r13),0x01 jno .no_diag308 diag %r0,%r0,0x308 .no_diag308: - sam31 # 31 bit mode - sr %r1,%r1 # erase register r1 - sr %r2,%r2 # erase register r2 - sigp %r1,%r2,0x12 # set cpuid to zero - lpsw 0 # hopefully start new kernel... + sam31 #31 bit mode + sr %r1,%r1 #erase register r1 + sr %r2,%r2 #erase register r2 + sigp %r1,%r2,0x12 #set cpuid to zero + lpsw 0 #hopefully start new kernel... - .align 8 + .align 8 zero64: .quad 0 load_psw: diff --git a/trunk/arch/s390/kernel/semaphore.c b/trunk/arch/s390/kernel/semaphore.c index 191303f6c1d8..8dfb690c159f 100644 --- a/trunk/arch/s390/kernel/semaphore.c +++ b/trunk/arch/s390/kernel/semaphore.c @@ -26,17 +26,17 @@ static inline int __sem_update_count(struct semaphore *sem, int incr) { int old_val, new_val; - asm volatile( - " l %0,0(%3)\n" - "0: ltr %1,%0\n" - " jhe 1f\n" - " lhi %1,0\n" - "1: ar %1,%4\n" - " cs %0,%1,0(%3)\n" - " jl 0b\n" - : "=&d" (old_val), "=&d" (new_val), "=m" (sem->count) - : "a" (&sem->count), "d" (incr), "m" (sem->count) - : "cc"); + __asm__ __volatile__(" l %0,0(%3)\n" + "0: ltr %1,%0\n" + " jhe 1f\n" + " lhi %1,0\n" + "1: ar %1,%4\n" + " cs %0,%1,0(%3)\n" + " jl 0b\n" + : "=&d" (old_val), "=&d" (new_val), + "=m" (sem->count) + : "a" (&sem->count), "d" (incr), "m" (sem->count) + : "cc" ); return old_val; } diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index a21cfbb9d97e..e3d9325f6022 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -101,7 +101,7 @@ void __devinit cpu_init (void) /* * Store processor id in lowcore (used e.g. in timer_interrupt) */ - asm volatile("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id)); + asm volatile ("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id)); S390_lowcore.cpu_data.cpu_addr = addr; /* diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index a8e6199755d4..b2e6f4c8d382 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -63,7 +63,7 @@ static void smp_ext_bitcall(int, ec_bit_sig); static void smp_ext_bitcall_others(ec_bit_sig); /* -5B * Structure and data for smp_call_function(). This is designed to minimise + * Structure and data for smp_call_function(). This is designed to minimise * static memory requirements. It also looks cleaner. */ static DEFINE_SPINLOCK(call_lock); @@ -418,49 +418,59 @@ void smp_send_reschedule(int cpu) /* * parameter area for the set/clear control bit callbacks */ -struct ec_creg_mask_parms { +typedef struct +{ + __u16 start_ctl; + __u16 end_ctl; unsigned long orvals[16]; unsigned long andvals[16]; -}; +} ec_creg_mask_parms; /* * callback for setting/clearing control bits */ void smp_ctl_bit_callback(void *info) { - struct ec_creg_mask_parms *pp = info; + ec_creg_mask_parms *pp; unsigned long cregs[16]; int i; - __ctl_store(cregs, 0, 15); - for (i = 0; i <= 15; i++) + pp = (ec_creg_mask_parms *) info; + __ctl_store(cregs[pp->start_ctl], pp->start_ctl, pp->end_ctl); + for (i = pp->start_ctl; i <= pp->end_ctl; i++) cregs[i] = (cregs[i] & pp->andvals[i]) | pp->orvals[i]; - __ctl_load(cregs, 0, 15); + __ctl_load(cregs[pp->start_ctl], pp->start_ctl, pp->end_ctl); } /* * Set a bit in a control register of all cpus */ -void smp_ctl_set_bit(int cr, int bit) -{ - struct ec_creg_mask_parms parms; +void smp_ctl_set_bit(int cr, int bit) { + ec_creg_mask_parms parms; - memset(&parms.orvals, 0, sizeof(parms.orvals)); - memset(&parms.andvals, 0xff, sizeof(parms.andvals)); + parms.start_ctl = cr; + parms.end_ctl = cr; parms.orvals[cr] = 1 << bit; - on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1); + parms.andvals[cr] = -1L; + preempt_disable(); + smp_call_function(smp_ctl_bit_callback, &parms, 0, 1); + __ctl_set_bit(cr, bit); + preempt_enable(); } /* * Clear a bit in a control register of all cpus */ -void smp_ctl_clear_bit(int cr, int bit) -{ - struct ec_creg_mask_parms parms; +void smp_ctl_clear_bit(int cr, int bit) { + ec_creg_mask_parms parms; - memset(&parms.orvals, 0, sizeof(parms.orvals)); - memset(&parms.andvals, 0xff, sizeof(parms.andvals)); + parms.start_ctl = cr; + parms.end_ctl = cr; + parms.orvals[cr] = 0; parms.andvals[cr] = ~(1L << bit); - on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1); + preempt_disable(); + smp_call_function(smp_ctl_bit_callback, &parms, 0, 1); + __ctl_clear_bit(cr, bit); + preempt_enable(); } /* @@ -640,9 +650,9 @@ __cpu_up(unsigned int cpu) sf->gprs[9] = (unsigned long) sf; cpu_lowcore->save_area[15] = (unsigned long) sf; __ctl_store(cpu_lowcore->cregs_save_area[0], 0, 15); - asm volatile( - " stam 0,15,0(%0)" - : : "a" (&cpu_lowcore->access_regs_save_area) : "memory"); + __asm__ __volatile__("stam 0,15,0(%0)" + : : "a" (&cpu_lowcore->access_regs_save_area) + : "memory"); cpu_lowcore->percpu_offset = __per_cpu_offset[cpu]; cpu_lowcore->current_task = (unsigned long) idle; cpu_lowcore->cpu_data.cpu_nr = cpu; @@ -698,7 +708,7 @@ int __cpu_disable(void) { unsigned long flags; - struct ec_creg_mask_parms cr_parms; + ec_creg_mask_parms cr_parms; int cpu = smp_processor_id(); spin_lock_irqsave(&smp_reserve_lock, flags); @@ -714,21 +724,30 @@ __cpu_disable(void) pfault_fini(); #endif - memset(&cr_parms.orvals, 0, sizeof(cr_parms.orvals)); - memset(&cr_parms.andvals, 0xff, sizeof(cr_parms.andvals)); - /* disable all external interrupts */ + + cr_parms.start_ctl = 0; + cr_parms.end_ctl = 0; cr_parms.orvals[0] = 0; cr_parms.andvals[0] = ~(1<<15 | 1<<14 | 1<<13 | 1<<12 | 1<<11 | 1<<10 | 1<< 6 | 1<< 4); + smp_ctl_bit_callback(&cr_parms); + /* disable all I/O interrupts */ + + cr_parms.start_ctl = 6; + cr_parms.end_ctl = 6; cr_parms.orvals[6] = 0; cr_parms.andvals[6] = ~(1<<31 | 1<<30 | 1<<29 | 1<<28 | 1<<27 | 1<<26 | 1<<25 | 1<<24); + smp_ctl_bit_callback(&cr_parms); + /* disable most machine checks */ + + cr_parms.start_ctl = 14; + cr_parms.end_ctl = 14; cr_parms.orvals[14] = 0; cr_parms.andvals[14] = ~(1<<28 | 1<<27 | 1<<26 | 1<<25 | 1<<24); - smp_ctl_bit_callback(&cr_parms); spin_unlock_irqrestore(&smp_reserve_lock, flags); diff --git a/trunk/arch/s390/kernel/stacktrace.c b/trunk/arch/s390/kernel/stacktrace.c index d9428a0fc8fb..de83f38288d0 100644 --- a/trunk/arch/s390/kernel/stacktrace.c +++ b/trunk/arch/s390/kernel/stacktrace.c @@ -59,7 +59,9 @@ static inline unsigned long save_context_stack(struct stack_trace *trace, } } -void save_stack_trace(struct stack_trace *trace, struct task_struct *task) +void save_stack_trace(struct stack_trace *trace, + struct task_struct *task, int all_contexts, + unsigned int skip) { register unsigned long sp asm ("15"); unsigned long orig_sp; @@ -67,23 +69,22 @@ void save_stack_trace(struct stack_trace *trace, struct task_struct *task) sp &= PSW_ADDR_INSN; orig_sp = sp; - sp = save_context_stack(trace, &trace->skip, sp, + sp = save_context_stack(trace, &skip, sp, S390_lowcore.panic_stack - PAGE_SIZE, S390_lowcore.panic_stack); - if ((sp != orig_sp) && !trace->all_contexts) + if ((sp != orig_sp) && !all_contexts) return; - sp = save_context_stack(trace, &trace->skip, sp, + sp = save_context_stack(trace, &skip, sp, S390_lowcore.async_stack - ASYNC_SIZE, S390_lowcore.async_stack); - if ((sp != orig_sp) && !trace->all_contexts) + if ((sp != orig_sp) && !all_contexts) return; if (task) - save_context_stack(trace, &trace->skip, sp, + save_context_stack(trace, &skip, sp, (unsigned long) task_stack_page(task), (unsigned long) task_stack_page(task) + THREAD_SIZE); else - save_context_stack(trace, &trace->skip, sp, - S390_lowcore.thread_info, + save_context_stack(trace, &skip, sp, S390_lowcore.thread_info, S390_lowcore.thread_info + THREAD_SIZE); return; } diff --git a/trunk/arch/s390/kernel/sys_s390.c b/trunk/arch/s390/kernel/sys_s390.c index 584ed95f3380..e351780bb660 100644 --- a/trunk/arch/s390/kernel/sys_s390.c +++ b/trunk/arch/s390/kernel/sys_s390.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -267,22 +266,3 @@ s390_fadvise64_64(struct fadvise64_64_args __user *args) return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice); } -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register const char *__arg1 asm("2") = filename; - register char *const*__arg2 asm("3") = argv; - register char *const*__arg3 asm("4") = envp; - register long __svcres asm("2"); - asm volatile( - "svc %b1" - : "=d" (__svcres) - : "i" (__NR_execve), - "0" (__arg1), - "d" (__arg2), - "d" (__arg3) : "memory"); - return __svcres; -} diff --git a/trunk/arch/s390/kernel/time.c b/trunk/arch/s390/kernel/time.c index 4bf66cc4a267..74e6178fbaf2 100644 --- a/trunk/arch/s390/kernel/time.c +++ b/trunk/arch/s390/kernel/time.c @@ -53,6 +53,8 @@ static u64 init_timer_cc; static u64 jiffies_timer_cc; static u64 xtime_cc; +extern unsigned long wall_jiffies; + /* * Scheduler clock - returns current time in nanosec units. */ @@ -85,8 +87,9 @@ static inline unsigned long do_gettimeoffset(void) { __u64 now; - now = (get_clock() - jiffies_timer_cc) >> 12; - now -= (__u64) jiffies * USECS_PER_JIFFY; + now = (get_clock() - jiffies_timer_cc) >> 12; + /* We require the offset from the latest update of xtime */ + now -= (__u64) wall_jiffies*USECS_PER_JIFFY; return (unsigned long) now; } @@ -163,7 +166,7 @@ EXPORT_SYMBOL(do_settimeofday); void account_ticks(struct pt_regs *regs) { __u64 tmp; - __u32 ticks; + __u32 ticks, xticks; /* Calculate how many ticks have passed. */ if (S390_lowcore.int_clock < S390_lowcore.jiffy_timer) { @@ -201,7 +204,6 @@ void account_ticks(struct pt_regs *regs) */ write_seqlock(&xtime_lock); if (S390_lowcore.jiffy_timer > xtime_cc) { - __u32 xticks; tmp = S390_lowcore.jiffy_timer - xtime_cc; if (tmp >= 2*CLK_TICKS_PER_JIFFY) { xticks = __div(tmp, CLK_TICKS_PER_JIFFY); @@ -210,11 +212,13 @@ void account_ticks(struct pt_regs *regs) xticks = 1; xtime_cc += CLK_TICKS_PER_JIFFY; } - do_timer(xticks); + while (xticks--) + do_timer(regs); } write_sequnlock(&xtime_lock); #else - do_timer(ticks); + for (xticks = ticks; xticks > 0; xticks--) + do_timer(regs); #endif #ifdef CONFIG_VIRT_CPU_ACCOUNTING @@ -347,12 +351,10 @@ void __init time_init(void) int cc; /* kick the TOD clock */ - asm volatile( - " stck 0(%2)\n" - " ipm %0\n" - " srl %0,28" - : "=d" (cc), "=m" (init_timer_cc) - : "a" (&init_timer_cc) : "cc"); + asm volatile ("STCK 0(%1)\n\t" + "IPM %0\n\t" + "SRL %0,28" : "=r" (cc) : "a" (&init_timer_cc) + : "memory", "cc"); switch (cc) { case 0: /* clock in set state: all is fine */ break; diff --git a/trunk/arch/s390/kernel/traps.c b/trunk/arch/s390/kernel/traps.c index 3eb4fab048b8..c4982c963424 100644 --- a/trunk/arch/s390/kernel/traps.c +++ b/trunk/arch/s390/kernel/traps.c @@ -597,7 +597,8 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code) local_irq_enable(); if (MACHINE_HAS_IEEE) - asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc)); + __asm__ volatile ("stfpc %0\n\t" + : "=m" (current->thread.fp_regs.fpc)); #ifdef CONFIG_MATHEMU else if (regs->psw.mask & PSW_MASK_PSTATE) { diff --git a/trunk/arch/s390/lib/Makefile b/trunk/arch/s390/lib/Makefile index b0cfa6c4883d..c42ffedfdb49 100644 --- a/trunk/arch/s390/lib/Makefile +++ b/trunk/arch/s390/lib/Makefile @@ -5,6 +5,5 @@ EXTRA_AFLAGS := -traditional lib-y += delay.o string.o uaccess_std.o -lib-$(CONFIG_32BIT) += div64.o lib-$(CONFIG_64BIT) += uaccess_mvcos.o lib-$(CONFIG_SMP) += spinlock.o diff --git a/trunk/arch/s390/lib/delay.c b/trunk/arch/s390/lib/delay.c index 027c4742a001..468f4ea33f99 100644 --- a/trunk/arch/s390/lib/delay.c +++ b/trunk/arch/s390/lib/delay.c @@ -27,7 +27,9 @@ void __delay(unsigned long loops) * yield the megahertz number of the cpu. The important function * is udelay and that is done using the tod clock. -- martin. */ - asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1)); + __asm__ __volatile__( + "0: brct %0,0b" + : /* no outputs */ : "r" ((loops/2) + 1)); } /* @@ -36,12 +38,13 @@ void __delay(unsigned long loops) */ void __udelay(unsigned long usecs) { - uint64_t start_cc; + uint64_t start_cc, end_cc; if (usecs == 0) return; - start_cc = get_clock(); + asm volatile ("STCK %0" : "=m" (start_cc)); do { cpu_relax(); - } while (((get_clock() - start_cc)/4096) < usecs); + asm volatile ("STCK %0" : "=m" (end_cc)); + } while (((end_cc - start_cc)/4096) < usecs); } diff --git a/trunk/arch/s390/lib/div64.c b/trunk/arch/s390/lib/div64.c deleted file mode 100644 index 0481f3424a13..000000000000 --- a/trunk/arch/s390/lib/div64.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * arch/s390/lib/div64.c - * - * __div64_32 implementation for 31 bit. - * - * Copyright (C) IBM Corp. 2006 - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), - */ - -#include -#include - -#ifdef CONFIG_MARCH_G5 - -/* - * Function to divide an unsigned 64 bit integer by an unsigned - * 31 bit integer using signed 64/32 bit division. - */ -static uint32_t __div64_31(uint64_t *n, uint32_t base) -{ - register uint32_t reg2 asm("2"); - register uint32_t reg3 asm("3"); - uint32_t *words = (uint32_t *) n; - uint32_t tmp; - - /* Special case base==1, remainder = 0, quotient = n */ - if (base == 1) - return 0; - /* - * Special case base==0 will cause a fixed point divide exception - * on the dr instruction and may not happen anyway. For the - * following calculation we can assume base > 1. The first - * signed 64 / 32 bit division with an upper half of 0 will - * give the correct upper half of the 64 bit quotient. - */ - reg2 = 0UL; - reg3 = words[0]; - asm volatile( - " dr %0,%2\n" - : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" ); - words[0] = reg3; - reg3 = words[1]; - /* - * To get the lower half of the 64 bit quotient and the 32 bit - * remainder we have to use a little trick. Since we only have - * a signed division the quotient can get too big. To avoid this - * the 64 bit dividend is halved, then the signed division will - * work. Afterwards the quotient and the remainder are doubled. - * If the last bit of the dividend has been one the remainder - * is increased by one then checked against the base. If the - * remainder has overflown subtract base and increase the - * quotient. Simple, no ? - */ - asm volatile( - " nr %2,%1\n" - " srdl %0,1\n" - " dr %0,%3\n" - " alr %0,%0\n" - " alr %1,%1\n" - " alr %0,%2\n" - " clr %0,%3\n" - " jl 0f\n" - " slr %0,%3\n" - " alr %1,%2\n" - "0:\n" - : "+d" (reg2), "+d" (reg3), "=d" (tmp) - : "d" (base), "2" (1UL) : "cc" ); - words[1] = reg3; - return reg2; -} - -/* - * Function to divide an unsigned 64 bit integer by an unsigned - * 32 bit integer using the unsigned 64/31 bit division. - */ -uint32_t __div64_32(uint64_t *n, uint32_t base) -{ - uint32_t r; - - /* - * If the most significant bit of base is set, divide n by - * (base/2). That allows to use 64/31 bit division and gives a - * good approximation of the result: n = (base/2)*q + r. The - * result needs to be corrected with two simple transformations. - * If base is already < 2^31-1 __div64_31 can be used directly. - */ - r = __div64_31(n, ((signed) base < 0) ? (base/2) : base); - if ((signed) base < 0) { - uint64_t q = *n; - /* - * First transformation: - * n = (base/2)*q + r - * = ((base/2)*2)*(q/2) + ((q&1) ? (base/2) : 0) + r - * Since r < (base/2), r + (base/2) < base. - * With q1 = (q/2) and r1 = r + ((q&1) ? (base/2) : 0) - * n = ((base/2)*2)*q1 + r1 with r1 < base. - */ - if (q & 1) - r += base/2; - q >>= 1; - /* - * Second transformation. ((base/2)*2) could have lost the - * last bit. - * n = ((base/2)*2)*q1 + r1 - * = base*q1 - ((base&1) ? q1 : 0) + r1 - */ - if (base & 1) { - int64_t rx = r - q; - /* - * base is >= 2^31. The worst case for the while - * loop is n=2^64-1 base=2^31+1. That gives a - * maximum for q=(2^64-1)/2^31 = 0x1ffffffff. Since - * base >= 2^31 the loop is finished after a maximum - * of three iterations. - */ - while (rx < 0) { - rx += base; - q--; - } - r = rx; - } - *n = q; - } - return r; -} - -#else /* MARCH_G5 */ - -uint32_t __div64_32(uint64_t *n, uint32_t base) -{ - register uint32_t reg2 asm("2"); - register uint32_t reg3 asm("3"); - uint32_t *words = (uint32_t *) n; - - reg2 = 0UL; - reg3 = words[0]; - asm volatile( - " dlr %0,%2\n" - : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" ); - words[0] = reg3; - reg3 = words[1]; - asm volatile( - " dlr %0,%2\n" - : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" ); - words[1] = reg3; - return reg2; -} - -#endif /* MARCH_G5 */ - -EXPORT_SYMBOL(__div64_32); diff --git a/trunk/arch/s390/lib/spinlock.c b/trunk/arch/s390/lib/spinlock.c index 8d76403fcf89..b9b7958a226a 100644 --- a/trunk/arch/s390/lib/spinlock.c +++ b/trunk/arch/s390/lib/spinlock.c @@ -24,76 +24,57 @@ static int __init spin_retry_setup(char *str) } __setup("spin_retry=", spin_retry_setup); -static inline void _raw_yield(void) +static inline void +_diag44(void) { +#ifdef CONFIG_64BIT if (MACHINE_HAS_DIAG44) +#endif asm volatile("diag 0,0,0x44"); } -static inline void _raw_yield_cpu(int cpu) -{ - if (MACHINE_HAS_DIAG9C) - asm volatile("diag %0,0,0x9c" - : : "d" (__cpu_logical_map[cpu])); - else - _raw_yield(); -} - -void _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc) +void +_raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc) { int count = spin_retry; - unsigned int cpu = ~smp_processor_id(); while (1) { if (count-- <= 0) { - unsigned int owner = lp->owner_cpu; - if (owner != 0) - _raw_yield_cpu(~owner); + _diag44(); count = spin_retry; } if (__raw_spin_is_locked(lp)) continue; - if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) { - lp->owner_pc = pc; + if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) return; - } } } EXPORT_SYMBOL(_raw_spin_lock_wait); -int _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc) +int +_raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc) { - unsigned int cpu = ~smp_processor_id(); - int count; + int count = spin_retry; - for (count = spin_retry; count > 0; count--) { + while (count-- > 0) { if (__raw_spin_is_locked(lp)) continue; - if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) { - lp->owner_pc = pc; + if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) return 1; - } } return 0; } EXPORT_SYMBOL(_raw_spin_trylock_retry); -void _raw_spin_relax(raw_spinlock_t *lock) -{ - unsigned int cpu = lock->owner_cpu; - if (cpu != 0) - _raw_yield_cpu(~cpu); -} -EXPORT_SYMBOL(_raw_spin_relax); - -void _raw_read_lock_wait(raw_rwlock_t *rw) +void +_raw_read_lock_wait(raw_rwlock_t *rw) { unsigned int old; int count = spin_retry; while (1) { if (count-- <= 0) { - _raw_yield(); + _diag44(); count = spin_retry; } if (!__raw_read_can_lock(rw)) @@ -105,7 +86,8 @@ void _raw_read_lock_wait(raw_rwlock_t *rw) } EXPORT_SYMBOL(_raw_read_lock_wait); -int _raw_read_trylock_retry(raw_rwlock_t *rw) +int +_raw_read_trylock_retry(raw_rwlock_t *rw) { unsigned int old; int count = spin_retry; @@ -121,13 +103,14 @@ int _raw_read_trylock_retry(raw_rwlock_t *rw) } EXPORT_SYMBOL(_raw_read_trylock_retry); -void _raw_write_lock_wait(raw_rwlock_t *rw) +void +_raw_write_lock_wait(raw_rwlock_t *rw) { int count = spin_retry; while (1) { if (count-- <= 0) { - _raw_yield(); + _diag44(); count = spin_retry; } if (!__raw_write_can_lock(rw)) @@ -138,7 +121,8 @@ void _raw_write_lock_wait(raw_rwlock_t *rw) } EXPORT_SYMBOL(_raw_write_lock_wait); -int _raw_write_trylock_retry(raw_rwlock_t *rw) +int +_raw_write_trylock_retry(raw_rwlock_t *rw) { int count = spin_retry; diff --git a/trunk/arch/s390/lib/uaccess_mvcos.c b/trunk/arch/s390/lib/uaccess_mvcos.c index 121b2935a422..86c96d6c191a 100644 --- a/trunk/arch/s390/lib/uaccess_mvcos.c +++ b/trunk/arch/s390/lib/uaccess_mvcos.c @@ -35,7 +35,7 @@ size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) tmp1 = -4096UL; asm volatile( "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n" - " jz 7f\n" + " jz 4f\n" "1:"ALR" %0,%3\n" " "SLR" %1,%3\n" " "SLR" %2,%3\n" @@ -44,23 +44,13 @@ size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) " nr %4,%3\n" /* %4 = (ptr + 4095) & -4096 */ " "SLR" %4,%1\n" " "CLR" %0,%4\n" /* copy crosses next page boundary? */ - " jnh 4f\n" + " jnh 5f\n" "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n" " "SLR" %0,%4\n" - " "ALR" %2,%4\n" - "4:"LHI" %4,-1\n" - " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ - " bras %3,6f\n" /* memset loop */ - " xc 0(1,%2),0(%2)\n" - "5: xc 0(256,%2),0(%2)\n" - " la %2,256(%2)\n" - "6:"AHI" %4,-256\n" - " jnm 5b\n" - " ex %4,0(%3)\n" - " j 8f\n" - "7:"SLR" %0,%0\n" - "8: \n" - EX_TABLE(0b,2b) EX_TABLE(3b,4b) + " j 5f\n" + "4:"SLR" %0,%0\n" + "5: \n" + EX_TABLE(0b,2b) EX_TABLE(3b,5b) : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) : "d" (reg0) : "cc", "memory"); return size; diff --git a/trunk/arch/s390/lib/uaccess_std.c b/trunk/arch/s390/lib/uaccess_std.c index f44f0078b354..9a4d4a29ea79 100644 --- a/trunk/arch/s390/lib/uaccess_std.c +++ b/trunk/arch/s390/lib/uaccess_std.c @@ -35,35 +35,25 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) tmp1 = -256UL; asm volatile( "0: mvcp 0(%0,%2),0(%1),%3\n" - " jz 8f\n" + " jz 5f\n" "1:"ALR" %0,%3\n" " la %1,256(%1)\n" " la %2,256(%2)\n" "2: mvcp 0(%0,%2),0(%1),%3\n" " jnz 1b\n" - " j 8f\n" + " j 5f\n" "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ " "LHI" %3,-4096\n" " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */ " "SLR" %4,%1\n" " "CLR" %0,%4\n" /* copy crosses next page boundary? */ - " jnh 5f\n" + " jnh 6f\n" "4: mvcp 0(%4,%2),0(%1),%3\n" " "SLR" %0,%4\n" - " "ALR" %2,%4\n" - "5:"LHI" %4,-1\n" - " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ - " bras %3,7f\n" /* memset loop */ - " xc 0(1,%2),0(%2)\n" - "6: xc 0(256,%2),0(%2)\n" - " la %2,256(%2)\n" - "7:"AHI" %4,-256\n" - " jnm 6b\n" - " ex %4,0(%3)\n" - " j 9f\n" - "8:"SLR" %0,%0\n" - "9: \n" - EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,5b) + " j 6f\n" + "5:"SLR" %0,%0\n" + "6: \n" + EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b) : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) : : "cc", "memory"); return size; @@ -77,22 +67,16 @@ size_t copy_from_user_std_small(size_t size, const void __user *ptr, void *x) asm volatile( "0: mvcp 0(%0,%2),0(%1),%3\n" " "SLR" %0,%0\n" - " j 5f\n" + " j 3f\n" "1: la %4,255(%1)\n" /* %4 = ptr + 255 */ " "LHI" %3,-4096\n" " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */ " "SLR" %4,%1\n" " "CLR" %0,%4\n" /* copy crosses next page boundary? */ - " jnh 5f\n" + " jnh 3f\n" "2: mvcp 0(%4,%2),0(%1),%3\n" " "SLR" %0,%4\n" - " "ALR" %2,%4\n" - "3:"LHI" %4,-1\n" - " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ - " bras %3,4f\n" - " xc 0(1,%2),0(%2)\n" - "4: ex %4,0(%3)\n" - "5:\n" + "3:\n" EX_TABLE(0b,1b) EX_TABLE(2b,3b) : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) : : "cc", "memory"); diff --git a/trunk/arch/s390/math-emu/math.c b/trunk/arch/s390/math-emu/math.c index 6b9aec5a2c18..b4957c84e4d6 100644 --- a/trunk/arch/s390/math-emu/math.c +++ b/trunk/arch/s390/math-emu/math.c @@ -1564,52 +1564,52 @@ static int emu_tceb (struct pt_regs *regs, int rx, long val) { } static inline void emu_load_regd(int reg) { - if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ + if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ return; - asm volatile( /* load reg from fp_regs.fprs[reg] */ - " bras 1,0f\n" - " ld 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" (reg<<4),"a" (¤t->thread.fp_regs.fprs[reg].d) - : "1"); + asm volatile ( /* load reg from fp_regs.fprs[reg] */ + " bras 1,0f\n" + " ld 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" (reg<<4),"a" (¤t->thread.fp_regs.fprs[reg].d) + : "1" ); } static inline void emu_load_rege(int reg) { - if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ + if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ return; - asm volatile( /* load reg from fp_regs.fprs[reg] */ - " bras 1,0f\n" - " le 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f) - : "1"); + asm volatile ( /* load reg from fp_regs.fprs[reg] */ + " bras 1,0f\n" + " le 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f) + : "1" ); } static inline void emu_store_regd(int reg) { - if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ + if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ return; - asm volatile( /* store reg to fp_regs.fprs[reg] */ - " bras 1,0f\n" - " std 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].d) - : "1"); + asm volatile ( /* store reg to fp_regs.fprs[reg] */ + " bras 1,0f\n" + " std 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].d) + : "1" ); } static inline void emu_store_rege(int reg) { - if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ + if ((reg&9) != 0) /* test if reg in {0,2,4,6} */ return; - asm volatile( /* store reg to fp_regs.fprs[reg] */ - " bras 1,0f\n" - " ste 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f) - : "1"); + asm volatile ( /* store reg to fp_regs.fprs[reg] */ + " bras 1,0f\n" + " ste 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" (reg<<4), "a" (¤t->thread.fp_regs.fprs[reg].f) + : "1" ); } int math_emu_b3(__u8 *opcode, struct pt_regs * regs) { @@ -2089,22 +2089,23 @@ int math_emu_ldr(__u8 *opcode) { if ((opc & 0x90) == 0) { /* test if rx in {0,2,4,6} */ /* we got an exception therfore ry can't be in {0,2,4,6} */ - asm volatile( /* load rx from fp_regs.fprs[ry] */ - " bras 1,0f\n" - " ld 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" (opc & 0xf0), "a" (&fp_regs->fprs[opc & 0xf].d) - : "1"); + __asm__ __volatile ( /* load rx from fp_regs.fprs[ry] */ + " bras 1,0f\n" + " ld 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" (opc & 0xf0), + "a" (&fp_regs->fprs[opc & 0xf].d) + : "1" ); } else if ((opc & 0x9) == 0) { /* test if ry in {0,2,4,6} */ - asm volatile ( /* store ry to fp_regs.fprs[rx] */ - " bras 1,0f\n" - " std 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" ((opc & 0xf) << 4), - "a" (&fp_regs->fprs[(opc & 0xf0)>>4].d) - : "1"); + __asm__ __volatile ( /* store ry to fp_regs.fprs[rx] */ + " bras 1,0f\n" + " std 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" ((opc & 0xf) << 4), + "a" (&fp_regs->fprs[(opc & 0xf0)>>4].d) + : "1" ); } else /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */ fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf]; return 0; @@ -2119,22 +2120,23 @@ int math_emu_ler(__u8 *opcode) { if ((opc & 0x90) == 0) { /* test if rx in {0,2,4,6} */ /* we got an exception therfore ry can't be in {0,2,4,6} */ - asm volatile( /* load rx from fp_regs.fprs[ry] */ - " bras 1,0f\n" - " le 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" (opc & 0xf0), "a" (&fp_regs->fprs[opc & 0xf].f) - : "1"); + __asm__ __volatile ( /* load rx from fp_regs.fprs[ry] */ + " bras 1,0f\n" + " le 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" (opc & 0xf0), + "a" (&fp_regs->fprs[opc & 0xf].f) + : "1" ); } else if ((opc & 0x9) == 0) { /* test if ry in {0,2,4,6} */ - asm volatile( /* store ry to fp_regs.fprs[rx] */ - " bras 1,0f\n" - " ste 0,0(%1)\n" - "0: ex %0,0(1)" - : /* no output */ - : "a" ((opc & 0xf) << 4), - "a" (&fp_regs->fprs[(opc & 0xf0) >> 4].f) - : "1"); + __asm__ __volatile ( /* store ry to fp_regs.fprs[rx] */ + " bras 1,0f\n" + " ste 0,0(%1)\n" + "0: ex %0,0(1)" + : /* no output */ + : "a" ((opc & 0xf) << 4), + "a" (&fp_regs->fprs[(opc & 0xf0) >> 4].f) + : "1" ); } else /* move fp_regs.fprs[ry] to fp_regs.fprs[rx] */ fp_regs->fprs[(opc & 0xf0) >> 4] = fp_regs->fprs[opc & 0xf]; return 0; diff --git a/trunk/arch/s390/math-emu/sfp-util.h b/trunk/arch/s390/math-emu/sfp-util.h index 5b6ca4570ea4..ab556b600f73 100644 --- a/trunk/arch/s390/math-emu/sfp-util.h +++ b/trunk/arch/s390/math-emu/sfp-util.h @@ -4,51 +4,48 @@ #include #define add_ssaaaa(sh, sl, ah, al, bh, bl) ({ \ - unsigned int __sh = (ah); \ - unsigned int __sl = (al); \ - asm volatile( \ - " alr %1,%3\n" \ - " brc 12,0f\n" \ - " ahi %0,1\n" \ - "0: alr %0,%2" \ - : "+&d" (__sh), "+d" (__sl) \ - : "d" (bh), "d" (bl) : "cc"); \ - (sh) = __sh; \ - (sl) = __sl; \ + unsigned int __sh = (ah); \ + unsigned int __sl = (al); \ + __asm__ (" alr %1,%3\n" \ + " brc 12,0f\n" \ + " ahi %0,1\n" \ + "0: alr %0,%2" \ + : "+&d" (__sh), "+d" (__sl) \ + : "d" (bh), "d" (bl) : "cc" ); \ + (sh) = __sh; \ + (sl) = __sl; \ }) #define sub_ddmmss(sh, sl, ah, al, bh, bl) ({ \ - unsigned int __sh = (ah); \ - unsigned int __sl = (al); \ - asm volatile( \ - " slr %1,%3\n" \ - " brc 3,0f\n" \ - " ahi %0,-1\n" \ - "0: slr %0,%2" \ - : "+&d" (__sh), "+d" (__sl) \ - : "d" (bh), "d" (bl) : "cc"); \ - (sh) = __sh; \ - (sl) = __sl; \ + unsigned int __sh = (ah); \ + unsigned int __sl = (al); \ + __asm__ (" slr %1,%3\n" \ + " brc 3,0f\n" \ + " ahi %0,-1\n" \ + "0: slr %0,%2" \ + : "+&d" (__sh), "+d" (__sl) \ + : "d" (bh), "d" (bl) : "cc" ); \ + (sh) = __sh; \ + (sl) = __sl; \ }) /* a umul b = a mul b + (a>=2<<31) ? b<<32:0 + (b>=2<<31) ? a<<32:0 */ #define umul_ppmm(wh, wl, u, v) ({ \ - unsigned int __wh = u; \ - unsigned int __wl = v; \ - asm volatile( \ - " ltr 1,%0\n" \ - " mr 0,%1\n" \ - " jnm 0f\n" \ - " alr 0,%1\n" \ - "0: ltr %1,%1\n" \ - " jnm 1f\n" \ - " alr 0,%0\n" \ - "1: lr %0,0\n" \ - " lr %1,1\n" \ - : "+d" (__wh), "+d" (__wl) \ - : : "0", "1", "cc"); \ - wh = __wh; \ - wl = __wl; \ + unsigned int __wh = u; \ + unsigned int __wl = v; \ + __asm__ (" ltr 1,%0\n" \ + " mr 0,%1\n" \ + " jnm 0f\n" \ + " alr 0,%1\n" \ + "0: ltr %1,%1\n" \ + " jnm 1f\n" \ + " alr 0,%0\n" \ + "1: lr %0,0\n" \ + " lr %1,1\n" \ + : "+d" (__wh), "+d" (__wl) \ + : : "0", "1", "cc" ); \ + wh = __wh; \ + wl = __wl; \ }) #define udiv_qrnnd(q, r, n1, n0, d) \ diff --git a/trunk/arch/s390/mm/extmem.c b/trunk/arch/s390/mm/extmem.c index 226275d5c4f6..9b11e3e20903 100644 --- a/trunk/arch/s390/mm/extmem.c +++ b/trunk/arch/s390/mm/extmem.c @@ -142,17 +142,17 @@ dcss_diag (__u8 func, void *parameter, rx = (unsigned long) parameter; ry = (unsigned long) func; - asm volatile( + __asm__ __volatile__( #ifdef CONFIG_64BIT - " sam31\n" - " diag %0,%1,0x64\n" - " sam64\n" + " sam31\n" // switch to 31 bit + " diag %0,%1,0x64\n" + " sam64\n" // switch back to 64 bit #else - " diag %0,%1,0x64\n" + " diag %0,%1,0x64\n" #endif - " ipm %2\n" - " srl %2,28\n" - : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc"); + " ipm %2\n" + " srl %2,28\n" + : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc" ); *ret1 = rx; *ret2 = ry; return rc; diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c index 9c3c19fe62fc..44f0cda7e72e 100644 --- a/trunk/arch/s390/mm/fault.c +++ b/trunk/arch/s390/mm/fault.c @@ -353,9 +353,8 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection) */ out_of_memory: up_read(&mm->mmap_sem); - if (is_init(tsk)) { + if (tsk->pid == 1) { yield(); - down_read(&mm->mmap_sem); goto survive; } printk("VM: killing process %s\n", tsk->comm); @@ -424,13 +423,20 @@ int pfault_init(void) if (pfault_disable) return -1; - asm volatile( - " diag %1,%0,0x258\n" - "0: j 2f\n" - "1: la %0,8\n" + __asm__ __volatile__( + " diag %1,%0,0x258\n" + "0: j 2f\n" + "1: la %0,8\n" "2:\n" - EX_TABLE(0b,1b) - : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc"); + ".section __ex_table,\"a\"\n" + " .align 4\n" +#ifndef CONFIG_64BIT + " .long 0b,1b\n" +#else /* CONFIG_64BIT */ + " .quad 0b,1b\n" +#endif /* CONFIG_64BIT */ + ".previous" + : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc" ); __ctl_set_bit(0, 9); return rc; } @@ -443,11 +449,18 @@ void pfault_fini(void) if (pfault_disable) return; __ctl_clear_bit(0,9); - asm volatile( - " diag %0,0,0x258\n" + __asm__ __volatile__( + " diag %0,0,0x258\n" "0:\n" - EX_TABLE(0b,0b) - : : "a" (&refbk), "m" (refbk) : "cc"); + ".section __ex_table,\"a\"\n" + " .align 4\n" +#ifndef CONFIG_64BIT + " .long 0b,0b\n" +#else /* CONFIG_64BIT */ + " .quad 0b,0b\n" +#endif /* CONFIG_64BIT */ + ".previous" + : : "a" (&refbk), "m" (refbk) : "cc" ); } asmlinkage void diff --git a/trunk/arch/s390/mm/init.c b/trunk/arch/s390/mm/init.c index 127044e1707c..cfd9b8f7a523 100644 --- a/trunk/arch/s390/mm/init.c +++ b/trunk/arch/s390/mm/init.c @@ -45,17 +45,26 @@ void diag10(unsigned long addr) { if (addr >= 0x7ff00000) return; - asm volatile( #ifdef CONFIG_64BIT - " sam31\n" - " diag %0,%0,0x10\n" - "0: sam64\n" + asm volatile ( + " sam31\n" + " diag %0,%0,0x10\n" + "0: sam64\n" + ".section __ex_table,\"a\"\n" + " .align 8\n" + " .quad 0b, 0b\n" + ".previous\n" + : : "a" (addr)); #else - " diag %0,%0,0x10\n" + asm volatile ( + " diag %0,%0,0x10\n" "0:\n" -#endif - EX_TABLE(0b,0b) + ".section __ex_table,\"a\"\n" + " .align 4\n" + " .long 0b, 0b\n" + ".previous\n" : : "a" (addr)); +#endif } void show_mem(void) @@ -147,10 +156,11 @@ void __init paging_init(void) S390_lowcore.kernel_asce = pgdir_k; /* enable virtual mapping in kernel mode */ - __ctl_load(pgdir_k, 1, 1); - __ctl_load(pgdir_k, 7, 7); - __ctl_load(pgdir_k, 13, 13); - __raw_local_irq_ssm(ssm_mask); + __asm__ __volatile__(" LCTL 1,1,%0\n" + " LCTL 7,7,%0\n" + " LCTL 13,13,%0\n" + " SSM %1" + : : "m" (pgdir_k), "m" (ssm_mask)); local_flush_tlb(); return; @@ -231,10 +241,11 @@ void __init paging_init(void) S390_lowcore.kernel_asce = pgdir_k; /* enable virtual mapping in kernel mode */ - __ctl_load(pgdir_k, 1, 1); - __ctl_load(pgdir_k, 7, 7); - __ctl_load(pgdir_k, 13, 13); - __raw_local_irq_ssm(ssm_mask); + __asm__ __volatile__("lctlg 1,1,%0\n\t" + "lctlg 7,7,%0\n\t" + "lctlg 13,13,%0\n\t" + "ssm %1" + : :"m" (pgdir_k), "m" (ssm_mask)); local_flush_tlb(); diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index 1cc5c9b27bfd..1a0db1d4c952 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -8,7 +8,6 @@ mainmenu "Linux/SuperH Kernel Configuration" config SUPERH bool default y - select EMBEDDED help The SuperH is a RISC processor targeted for use in embedded systems and consumer electronics; it was also used in the Sega Dreamcast @@ -52,23 +51,18 @@ source "init/Kconfig" menu "System type" -config SOLUTION_ENGINE - bool - choice prompt "SuperH system type" default SH_UNKNOWN config SH_SOLUTION_ENGINE bool "SolutionEngine" - select SOLUTION_ENGINE help Select SolutionEngine if configuring for a Hitachi SH7709 or SH7750 evaluation board. config SH_7751_SOLUTION_ENGINE bool "SolutionEngine7751" - select SOLUTION_ENGINE select CPU_SUBTYPE_SH7751 help Select 7751 SolutionEngine if configuring for a Hitachi SH7751 @@ -76,27 +70,17 @@ config SH_7751_SOLUTION_ENGINE config SH_7300_SOLUTION_ENGINE bool "SolutionEngine7300" - select SOLUTION_ENGINE select CPU_SUBTYPE_SH7300 help - Select 7300 SolutionEngine if configuring for a Hitachi - SH7300(SH-Mobile V) evaluation board. - -config SH_7343_SOLUTION_ENGINE - bool "SolutionEngine7343" - select SOLUTION_ENGINE - select CPU_SUBTYPE_SH7343 - help - Select 7343 SolutionEngine if configuring for a Hitachi - SH7343 (SH-Mobile 3AS) evaluation board. + Select 7300 SolutionEngine if configuring for a Hitachi SH7300(SH-Mobile V) + evaluation board. config SH_73180_SOLUTION_ENGINE bool "SolutionEngine73180" - select SOLUTION_ENGINE - select CPU_SUBTYPE_SH73180 - help - Select 73180 SolutionEngine if configuring for a Hitachi - SH73180(SH-Mobile 3) evaluation board. + select CPU_SUBTYPE_SH73180 + help + Select 73180 SolutionEngine if configuring for a Hitachi SH73180(SH-Mobile 3) + evaluation board. config SH_7751_SYSTEMH bool "SystemH7751R" @@ -105,6 +89,12 @@ config SH_7751_SYSTEMH Select SystemH if you are configuring for a Renesas SystemH 7751R evaluation board. +config SH_STB1_HARP + bool "STB1_Harp" + +config SH_STB1_OVERDRIVE + bool "STB1_Overdrive" + config SH_HP6XX bool "HP6XX" help @@ -112,6 +102,19 @@ config SH_HP6XX More information (hardware only) at . +config SH_CQREEK + bool "CqREEK" + help + Select CqREEK if configuring for a CqREEK SH7708 or SH7750. + More information at + . + +config SH_DMIDA + bool "DMIDA" + help + Select DMIDA if configuring for a DataMyte 4000 Industrial + Digital Assistant. More information at . + config SH_EC3104 bool "EC3104" help @@ -133,9 +136,25 @@ config SH_DREAMCAST . There is a Dreamcast project is at . +config SH_CAT68701 + bool "CAT68701" + config SH_BIGSUR bool "BigSur" +config SH_SH2000 + bool "SH2000" + select CPU_SUBTYPE_SH7709 + help + SH-2000 is a single-board computer based around SH7709A chip + intended for embedded applications. + It has an Ethernet interface (CS8900A), direct connected + Compact Flash socket, three serial ports and PC-104 bus. + More information at . + +config SH_ADX + bool "ADX" + config SH_MPC1211 bool "Interface MPC1211" help @@ -165,13 +184,6 @@ config SH_HS7751RVOIP Select HS7751RVOIP if configuring for a Renesas Technology Sales VoIP board. -config SH_7710VOIPGW - bool "SH7710-VOIP-GW" - select CPU_SUBTYPE_SH7710 - help - Select this option to build a kernel for the SH7710 based - VOIP GW. - config SH_RTS7751R2D bool "RTS7751R2D" select CPU_SUBTYPE_SH7751R @@ -210,12 +222,6 @@ config SH_TITAN Select Titan if you are configuring for a Nimble Microsystems NetEngine NP51R. -config SH_SHMIN - bool "SHMIN" - select CPU_SUBTYPE_SH7706 - help - Select SHMIN if configureing for the SHMIN board - config SH_UNKNOWN bool "BareCPU" help @@ -232,9 +238,35 @@ endchoice source "arch/sh/mm/Kconfig" +config MEMORY_START + hex "Physical memory start address" + default "0x08000000" + ---help--- + Computers built with Hitachi SuperH processors always + map the ROM starting at address zero. But the processor + does not specify the range that RAM takes. + + The physical memory (RAM) start address will be automatically + set to 08000000. Other platforms, such as the Solution Engine + boards typically map RAM at 0C000000. + + Tweak this only when porting to a new machine which does not + already have a defconfig. Changing it from the known correct + value on any of the known systems will only lead to disaster. + +config MEMORY_SIZE + hex "Physical memory size" + default "0x00400000" + help + This sets the default memory size assumed by your SH kernel. It can + be overridden as normal by the 'mem=' argument on the kernel command + line. If unsure, consult your board specifications or just leave it + as 0x00400000 which was the default value before this became + configurable. + config CF_ENABLER bool "Compact Flash Enabler support" - depends on SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_SH03 + depends on SH_ADX || SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_CAT68701 || SH_SH03 ---help--- Compact Flash is a small, removable mass storage device introduced in 1994 originally as a PCMCIA device. If you say `Y' here, you @@ -262,7 +294,7 @@ config CF_AREA5 - "Area5" if CompactFlash is connected to Area 5 (0x14000000) - "Area6" if it is connected to Area 6 (0x18000000) - "Area6" will work for most boards. + "Area6" will work for most boards. For ADX, select "Area5". config CF_AREA6 bool "Area6" @@ -284,6 +316,19 @@ config CPU_LITTLE_ENDIAN endian byte order. These modes require different kernels. Say Y if your machine is little endian, N if it's a big endian machine. +# The SH7750 RTC module is disabled in the Dreamcast +config SH_RTC + bool + depends on !SH_DREAMCAST && !SH_SATURN && !SH_7300_SOLUTION_ENGINE && \ + !SH_73180_SOLUTION_ENGINE && !SH_LANDISK && \ + !SH_R7780RP + default y + help + Selecting this option will allow the Linux kernel to emulate + PC's RTC. + + If unsure, say N. + config SH_FPU bool "FPU support" depends on !CPU_SH3 @@ -294,22 +339,14 @@ config SH_FPU This option must be set in order to enable the FPU. -config SH_FPU_EMU - bool "FPU emulation support" - depends on !SH_FPU && EXPERIMENTAL - default n - help - Selecting this option will enable support for software FPU emulation. - Most SH-3 users will want to say Y here, whereas most SH-4 users will - want to say N. - config SH_DSP bool "DSP support" - default y if SH4AL_DSP || !CPU_SH4 - default n + depends on !CPU_SH4 + default y help Selecting this option will enable support for SH processors that - have DSP units (ie, SH2-DSP, SH3-DSP, and SH4AL-DSP). + have DSP units (ie, SH2-DSP and SH3-DSP). It is safe to say Y here + by default, as the existance of the DSP will be probed at runtime. This option must be set in order to enable the DSP. @@ -336,9 +373,6 @@ config CPU_HAS_INTEVT config CPU_HAS_PINT_IRQ bool -config CPU_HAS_MASKREG_IRQ - bool - config CPU_HAS_INTC2_IRQ bool @@ -366,19 +400,16 @@ config SH_TMU endmenu -source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" - -source "arch/sh/boards/renesas/rts7751r2d/Kconfig" +#source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" -source "arch/sh/boards/renesas/r7780rp/Kconfig" +#source "arch/sh/boards/renesas/rts7751r2d/Kconfig" config SH_PCLK_FREQ int "Peripheral clock frequency (in Hz)" default "50000000" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7780 default "60000000" if CPU_SUBTYPE_SH7751 - default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \ - CPU_SUBTYPE_SH7760 - default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343 + default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || CPU_SUBTYPE_SH7760 + default "27000000" if CPU_SUBTYPE_SH73180 default "66000000" if CPU_SUBTYPE_SH4_202 help This option is used to specify the peripheral clock frequency. @@ -409,8 +440,10 @@ source "arch/sh/cchips/Kconfig" config HEARTBEAT bool "Heartbeat LED" - depends on SH_MPC1211 || SH_SH03 || \ - SH_BIGSUR || SOLUTION_ENGINE || \ + depends on SH_MPC1211 || SH_SH03 || SH_CAT68701 || \ + SH_STB1_HARP || SH_STB1_OVERDRIVE || SH_BIGSUR || \ + SH_7751_SOLUTION_ENGINE || SH_7300_SOLUTION_ENGINE || \ + SH_73180_SOLUTION_ENGINE || SH_SOLUTION_ENGINE || \ SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK help Use the power-on LED on your machine as a load meter. The exact @@ -426,8 +459,6 @@ config ISA_DMA_API menu "Kernel features" -source kernel/Kconfig.hz - config KEXEC bool "kexec system call (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -445,6 +476,10 @@ config KEXEC support. As of this writing the exact hardware interface is strongly in flux, so no good recommendation can be made. +config PREEMPT + bool "Preemptible Kernel (EXPERIMENTAL)" + depends on EXPERIMENTAL + config SMP bool "Symmetric multi-processing support" ---help--- @@ -480,8 +515,6 @@ config NR_CPUS This is purely to save memory - each supported CPU adds approximately eight kilobytes to the kernel image. -source "kernel/Kconfig.preempt" - config CPU_HAS_SR_RB bool "CPU has SR.RB" depends on CPU_SH3 || CPU_SH4 @@ -603,16 +636,6 @@ source "fs/Kconfig.binfmt" endmenu -menu "Power management options (EXPERIMENTAL)" -depends on EXPERIMENTAL - -source kernel/power/Kconfig - -config APM - bool "Advanced Power Management Emulation" - depends on PM -endmenu - source "net/Kconfig" source "drivers/Kconfig" diff --git a/trunk/arch/sh/Kconfig.debug b/trunk/arch/sh/Kconfig.debug index 48479e014dac..8fb31ab2c02c 100644 --- a/trunk/arch/sh/Kconfig.debug +++ b/trunk/arch/sh/Kconfig.debug @@ -30,35 +30,8 @@ config EARLY_PRINTK when the kernel may crash or hang before the serial console is initialised. If unsure, say N. -config DEBUG_STACKOVERFLOW - bool "Check for stack overflows" - depends on DEBUG_KERNEL - help - This option will cause messages to be printed if free stack space - drops below a certain limit. - -config DEBUG_STACK_USAGE - bool "Stack utilization instrumentation" - depends on DEBUG_KERNEL - help - Enables the display of the minimum amount of free stack which each - task has ever had available in the sysrq-T and sysrq-P debug output. - - This option will slow down process creation somewhat. - -config 4KSTACKS - bool "Use 4Kb for kernel stacks instead of 8Kb" - depends on DEBUG_KERNEL - help - If you say Y here the kernel will use a 4Kb stacksize for the - kernel stack attached to each process/thread. This facilitates - running more threads on a system and also reduces the pressure - on the VM subsystem for higher order allocations. This option - will also use IRQ stacks to compensate for the reduced stackspace. - config KGDB bool "Include KGDB kernel debugger" - select FRAME_POINTER help Include in-kernel hooks for kgdb, the Linux kernel source level debugger. See for more information. @@ -139,4 +112,13 @@ endchoice endmenu +config FRAME_POINTER + bool "Compile the kernel with frame pointers" + default y if KGDB + help + If you say Y here the resulting kernel image will be slightly larger + and slower, but it will give very useful debugging information. + If you don't debug the kernel, you can say N, but we may not be able + to solve problems without frame pointers. + endmenu diff --git a/trunk/arch/sh/Makefile b/trunk/arch/sh/Makefile index 26d62ff51a64..e467a450662b 100644 --- a/trunk/arch/sh/Makefile +++ b/trunk/arch/sh/Makefile @@ -18,13 +18,11 @@ cflags-y := -mb cflags-$(CONFIG_CPU_LITTLE_ENDIAN) := -ml isa-y := any -isa-$(CONFIG_SH_DSP) := sh isa-$(CONFIG_CPU_SH2) := sh2 -isa-$(CONFIG_CPU_SH2A) := sh2a isa-$(CONFIG_CPU_SH3) := sh3 isa-$(CONFIG_CPU_SH4) := sh4 isa-$(CONFIG_CPU_SH4A) := sh4a -isa-$(CONFIG_CPU_SH4AL_DSP) := sh4al +isa-$(CONFIG_CPU_SH2A) := sh2a isa-$(CONFIG_SH_DSP) := $(isa-y)-dsp @@ -32,11 +30,9 @@ ifndef CONFIG_MMU isa-y := $(isa-y)-nommu endif -ifndef CONFIG_SH_DSP ifndef CONFIG_SH_FPU isa-y := $(isa-y)-nofpu endif -endif cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) @@ -83,19 +79,24 @@ head-y := arch/sh/kernel/head.o arch/sh/kernel/init_task.o LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) core-y += arch/sh/kernel/ arch/sh/mm/ -core-$(CONFIG_SH_FPU_EMU) += arch/sh/math-emu/ # Boards machdir-$(CONFIG_SH_SOLUTION_ENGINE) := se/770x machdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se/7751 machdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se/7300 -machdir-$(CONFIG_SH_7343_SOLUTION_ENGINE) := se/7343 machdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se/73180 +machdir-$(CONFIG_SH_STB1_HARP) := harp +machdir-$(CONFIG_SH_STB1_OVERDRIVE) := overdrive machdir-$(CONFIG_SH_HP6XX) := hp6xx +machdir-$(CONFIG_SH_CQREEK) := cqreek +machdir-$(CONFIG_SH_DMIDA) := dmida machdir-$(CONFIG_SH_EC3104) := ec3104 machdir-$(CONFIG_SH_SATURN) := saturn machdir-$(CONFIG_SH_DREAMCAST) := dreamcast +machdir-$(CONFIG_SH_CAT68701) := cat68701 machdir-$(CONFIG_SH_BIGSUR) := bigsur +machdir-$(CONFIG_SH_SH2000) := sh2000 +machdir-$(CONFIG_SH_ADX) := adx machdir-$(CONFIG_SH_MPC1211) := mpc1211 machdir-$(CONFIG_SH_SH03) := sh03 machdir-$(CONFIG_SH_SECUREEDGE5410) := snapgear @@ -103,16 +104,16 @@ machdir-$(CONFIG_SH_HS7751RVOIP) := renesas/hs7751rvoip machdir-$(CONFIG_SH_RTS7751R2D) := renesas/rts7751r2d machdir-$(CONFIG_SH_7751_SYSTEMH) := renesas/systemh machdir-$(CONFIG_SH_EDOSK7705) := renesas/edosk7705 -machdir-$(CONFIG_SH_R7780RP) := renesas/r7780rp -machdir-$(CONFIG_SH_7710VOIPGW) := renesas/sh7710voipgw machdir-$(CONFIG_SH_SH4202_MICRODEV) := superh/microdev -machdir-$(CONFIG_SH_LANDISK) := landisk -machdir-$(CONFIG_SH_TITAN) := titan -machdir-$(CONFIG_SH_SHMIN) := shmin machdir-$(CONFIG_SH_UNKNOWN) := unknown incdir-y := $(notdir $(machdir-y)) -incdir-$(CONFIG_SH_HP6XX) := hp6xx + +incdir-$(CONFIG_SH_SOLUTION_ENGINE) := se +incdir-$(CONFIG_SH_7751_SOLUTION_ENGINE) := se7751 +incdir-$(CONFIG_SH_7300_SOLUTION_ENGINE) := se7300 +incdir-$(CONFIG_SH_73180_SOLUTION_ENGINE) := se73180 +incdir-$(CONFIG_SH_HP600) := hp6xx ifneq ($(machdir-y),) core-y += arch/sh/boards/$(machdir-y)/ @@ -136,14 +137,17 @@ boot := arch/sh/boot CPPFLAGS_vmlinux.lds := -traditional +ifneq ($(KBUILD_SRC),) incdir-prefix := $(srctree)/include/asm-sh/ +else +incdir-prefix := +endif # Update machine arch and proc symlinks if something which affects # them changed. We use .arch and .mach to indicate when they were # updated last, otherwise make uses the target directory mtime. -include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) \ - include/config/auto.conf FORCE +include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/auto.conf @echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)' $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi $(Q)ln -fsn $(incdir-prefix)$(cpuincdir-y) include/asm-sh/cpu @@ -153,8 +157,7 @@ include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) \ # don't, just reference the parent directory so the semantics are # kept roughly the same. -include/asm-sh/.mach: $(wildcard include/config/sh/*.h) \ - include/config/auto.conf FORCE +include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/auto.conf @echo -n ' SYMLINK include/asm-sh/mach -> ' $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi $(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \ @@ -167,7 +170,7 @@ include/asm-sh/.mach: $(wildcard include/config/sh/*.h) \ fi @touch $@ -archprepare: include/asm-sh/.cpu include/asm-sh/.mach maketools +archprepare: maketools include/asm-sh/.cpu include/asm-sh/.mach PHONY += maketools FORCE maketools: include/linux/version.h FORCE @@ -188,3 +191,4 @@ CLEAN_FILES += include/asm-sh/machtypes.h define archhelp @echo ' zImage - Compressed kernel image (arch/sh/boot/zImage)' endef + diff --git a/trunk/arch/sh/boards/adx/Makefile b/trunk/arch/sh/boards/adx/Makefile new file mode 100644 index 000000000000..5b1c531b3991 --- /dev/null +++ b/trunk/arch/sh/boards/adx/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for ADX boards +# + +obj-y := setup.o irq.o irq_maskreq.o + diff --git a/trunk/arch/sh/boards/adx/irq.c b/trunk/arch/sh/boards/adx/irq.c new file mode 100644 index 000000000000..c6ca409dff98 --- /dev/null +++ b/trunk/arch/sh/boards/adx/irq.c @@ -0,0 +1,31 @@ +/* + * linux/arch/sh/boards/adx/irq.c + * + * Copyright (C) 2001 A&D Co., Ltd. + * + * I/O routine and setup routines for A&D ADX Board + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +#include + +void init_adx_IRQ(void) +{ + int i; + +/* printk("init_adx_IRQ()\n");*/ + /* setup irq_mask_register */ + irq_mask_register = (unsigned short *)0xa6000008; + + /* cover all external interrupt area by maskreg_irq_type + * (Actually, irq15 doesn't exist) + */ + for (i = 0; i < 16; i++) { + make_maskreg_irq(i); + disable_irq(i); + } +} diff --git a/trunk/arch/sh/kernel/cpu/irq/maskreg.c b/trunk/arch/sh/boards/adx/irq_maskreg.c similarity index 63% rename from trunk/arch/sh/kernel/cpu/irq/maskreg.c rename to trunk/arch/sh/boards/adx/irq_maskreg.c index 492db31b3cab..4b2abe5eb165 100644 --- a/trunk/arch/sh/kernel/cpu/irq/maskreg.c +++ b/trunk/arch/sh/boards/adx/irq_maskreg.c @@ -1,23 +1,30 @@ /* - * Interrupt handling for Simple external interrupt mask register + * linux/arch/sh/kernel/irq_maskreg.c * * Copyright (C) 2001 A&D Co., Ltd. * - * This is for the machine which have single 16 bit register - * for masking external IRQ individually. - * Each bit of the register is for masking each interrupt. - * * This file may be copied or modified under the terms of the GNU * General Public License. See linux/COPYING for more information. + * + * Interrupt handling for Simple external interrupt mask register + * + * This is for the machine which have single 16 bit register + * for masking external IRQ individually. + * Each bit of the register is for masking each interrupt. */ + #include #include #include + #include #include +#include -/* address of external interrupt mask register */ -unsigned long irq_mask_register; +/* address of external interrupt mask register + * address must be set prior to use these (maybe in init_XXX_irq()) + * XXX : is it better to use .config than specifying it in code? */ +unsigned short *irq_mask_register = 0; /* forward declaration */ static unsigned int startup_maskreg_irq(unsigned int irq); @@ -29,7 +36,7 @@ static void end_maskreg_irq(unsigned int irq); /* hw_interrupt_type */ static struct hw_interrupt_type maskreg_irq_type = { - .typename = "Mask Register", + .typename = " Mask Register", .startup = startup_maskreg_irq, .shutdown = shutdown_maskreg_irq, .enable = enable_maskreg_irq, @@ -40,7 +47,7 @@ static struct hw_interrupt_type maskreg_irq_type = { /* actual implementatin */ static unsigned int startup_maskreg_irq(unsigned int irq) -{ +{ enable_maskreg_irq(irq); return 0; /* never anything pending */ } @@ -52,26 +59,32 @@ static void shutdown_maskreg_irq(unsigned int irq) static void disable_maskreg_irq(unsigned int irq) { - unsigned short val, mask = 0x01 << irq; - - BUG_ON(!irq_mask_register); + if (irq_mask_register) { + unsigned long flags; + unsigned short val, mask = 0x01 << irq; - /* Set "irq"th bit */ - val = ctrl_inw(irq_mask_register); - val |= mask; - ctrl_outw(val, irq_mask_register); + /* Set "irq"th bit */ + local_irq_save(flags); + val = ctrl_inw((unsigned long)irq_mask_register); + val |= mask; + ctrl_outw(val, (unsigned long)irq_mask_register); + local_irq_restore(flags); + } } static void enable_maskreg_irq(unsigned int irq) { - unsigned short val, mask = ~(0x01 << irq); - - BUG_ON(!irq_mask_register); + if (irq_mask_register) { + unsigned long flags; + unsigned short val, mask = ~(0x01 << irq); - /* Clear "irq"th bit */ - val = ctrl_inw(irq_mask_register); - val &= mask; - ctrl_outw(val, irq_mask_register); + /* Clear "irq"th bit */ + local_irq_save(flags); + val = ctrl_inw((unsigned long)irq_mask_register); + val &= mask; + ctrl_outw(val, (unsigned long)irq_mask_register); + local_irq_restore(flags); + } } static void mask_and_ack_maskreg(unsigned int irq) @@ -88,6 +101,6 @@ static void end_maskreg_irq(unsigned int irq) void make_maskreg_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &maskreg_irq_type; + irq_desc[irq].chip = &maskreg_irq_type; disable_maskreg_irq(irq); } diff --git a/trunk/arch/sh/boards/adx/setup.c b/trunk/arch/sh/boards/adx/setup.c new file mode 100644 index 000000000000..4938d9592343 --- /dev/null +++ b/trunk/arch/sh/boards/adx/setup.c @@ -0,0 +1,56 @@ +/* + * linux/arch/sh/board/adx/setup.c + * + * Copyright (C) 2001 A&D Co., Ltd. + * + * I/O routine and setup routines for A&D ADX Board + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +#include +#include + +extern void init_adx_IRQ(void); +extern void *cf_io_base; + +const char *get_system_type(void) +{ + return "A&D ADX"; +} + +unsigned long adx_isa_port2addr(unsigned long offset) +{ + /* CompactFlash (IDE) */ + if (((offset >= 0x1f0) && (offset <= 0x1f7)) || (offset == 0x3f6)) { + return (unsigned long)cf_io_base + offset; + } + + /* eth0 */ + if ((offset >= 0x300) && (offset <= 0x30f)) { + return 0xa5000000 + offset; /* COMM BOARD (AREA1) */ + } + + return offset + 0xb0000000; /* IOBUS (AREA 4)*/ +} + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_adx __initmv = { + .mv_nr_irqs = 48, + .mv_isa_port2addr = adx_isa_port2addr, + .mv_init_irq = init_adx_IRQ, +}; +ALIAS_MV(adx) + +int __init platform_setup(void) +{ + /* Nothing to see here .. */ + return 0; +} + diff --git a/trunk/arch/sh/boards/bigsur/irq.c b/trunk/arch/sh/boards/bigsur/irq.c index 1ab04da36382..ac946a2201c7 100644 --- a/trunk/arch/sh/boards/bigsur/irq.c +++ b/trunk/arch/sh/boards/bigsur/irq.c @@ -19,7 +19,6 @@ * IRQ functions for a Hitachi Big Sur Evaluation Board. * */ -#undef DEBUG #include #include @@ -42,8 +41,10 @@ #undef BIGSUR_DEBUG #ifdef BIGSUR_DEBUG +#define DPRINTK(args...) printk(args) #define DIPRINTK(n, args...) if (BIGSUR_DEBUG>(n)) printk(args) #else +#define DPRINTK(args...) #define DIPRINTK(n, args...) #endif /* BIGSUR_DEBUG */ @@ -59,39 +60,45 @@ extern int hd64465_irq_demux(int irq); /* Level 1 IRQ routines */ static void disable_bigsur_l1irq(unsigned int irq) { + unsigned long flags; unsigned char mask; unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0; unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) ); if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { - pr_debug("Disable L1 IRQ %d\n", irq); + DPRINTK("Disable L1 IRQ %d\n", irq); DIPRINTK(2,"disable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n", mask_port, bit); + local_irq_save(flags); /* Disable IRQ - set mask bit */ mask = inb(mask_port) | bit; outb(mask, mask_port); + local_irq_restore(flags); return; } - pr_debug("disable_bigsur_l1irq: Invalid IRQ %d\n", irq); + DPRINTK("disable_bigsur_l1irq: Invalid IRQ %d\n", irq); } static void enable_bigsur_l1irq(unsigned int irq) { + unsigned long flags; unsigned char mask; unsigned int mask_port = ((irq - BIGSUR_IRQ_LOW)/8) ? BIGSUR_IRLMR1 : BIGSUR_IRLMR0; unsigned char bit = (1 << ((irq - MGATE_IRQ_LOW)%8) ); if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { - pr_debug("Enable L1 IRQ %d\n", irq); + DPRINTK("Enable L1 IRQ %d\n", irq); DIPRINTK(2,"enable_bigsur_l1irq: IMR=0x%08x mask=0x%x\n", mask_port, bit); + local_irq_save(flags); /* Enable L1 IRQ - clear mask bit */ mask = inb(mask_port) & ~bit; outb(mask, mask_port); + local_irq_restore(flags); return; } - pr_debug("enable_bigsur_l1irq: Invalid IRQ %d\n", irq); + DPRINTK("enable_bigsur_l1irq: Invalid IRQ %d\n", irq); } @@ -119,45 +126,51 @@ static const u32 imr_offset = BIGSUR_IMR0 - BIGSUR_IMR1; /* Level 2 IRQ routines */ static void disable_bigsur_l2irq(unsigned int irq) { + unsigned long flags; unsigned char mask; unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8); unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset; - if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { - pr_debug("Disable L2 IRQ %d\n", irq); + if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { + DPRINTK("Disable L2 IRQ %d\n", irq); DIPRINTK(2,"disable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n", mask_port, bit); + local_irq_save(flags); /* Disable L2 IRQ - set mask bit */ mask = inb(mask_port) | bit; outb(mask, mask_port); + local_irq_restore(flags); return; } - pr_debug("disable_bigsur_l2irq: Invalid IRQ %d\n", irq); + DPRINTK("disable_bigsur_l2irq: Invalid IRQ %d\n", irq); } static void enable_bigsur_l2irq(unsigned int irq) { + unsigned long flags; unsigned char mask; unsigned char bit = 1 << ((irq-BIGSUR_2NDLVL_IRQ_LOW)%8); unsigned int mask_port = imr_base - REG_NUM(irq)*imr_offset; - if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { - pr_debug("Enable L2 IRQ %d\n", irq); + if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { + DPRINTK("Enable L2 IRQ %d\n", irq); DIPRINTK(2,"enable_bigsur_l2irq: IMR=0x%08x mask=0x%x\n", mask_port, bit); + local_irq_save(flags); /* Enable L2 IRQ - clear mask bit */ mask = inb(mask_port) & ~bit; outb(mask, mask_port); + local_irq_restore(flags); return; } - pr_debug("enable_bigsur_l2irq: Invalid IRQ %d\n", irq); + DPRINTK("enable_bigsur_l2irq: Invalid IRQ %d\n", irq); } static void mask_and_ack_bigsur(unsigned int irq) { - pr_debug("mask_and_ack_bigsur IRQ %d\n", irq); + DPRINTK("mask_and_ack_bigsur IRQ %d\n", irq); if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) disable_bigsur_l1irq(irq); else @@ -166,7 +179,7 @@ static void mask_and_ack_bigsur(unsigned int irq) static void end_bigsur_irq(unsigned int irq) { - pr_debug("end_bigsur_irq IRQ %d\n", irq); + DPRINTK("end_bigsur_irq IRQ %d\n", irq); if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) enable_bigsur_l1irq(irq); @@ -180,7 +193,7 @@ static unsigned int startup_bigsur_irq(unsigned int irq) u8 mask; u32 reg; - pr_debug("startup_bigsur_irq IRQ %d\n", irq); + DPRINTK("startup_bigsur_irq IRQ %d\n", irq); if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { /* Enable the L1 IRQ */ @@ -205,7 +218,7 @@ static unsigned int startup_bigsur_irq(unsigned int irq) static void shutdown_bigsur_irq(unsigned int irq) { - pr_debug("shutdown_bigsur_irq IRQ %d\n", irq); + DPRINTK("shutdown_bigsur_irq IRQ %d\n", irq); if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) disable_bigsur_l1irq(irq); else @@ -247,7 +260,7 @@ static void make_bigsur_l1isr(unsigned int irq) { disable_bigsur_l1irq(irq); return; } - pr_debug("make_bigsur_l1isr: bad irq, %d\n", irq); + DPRINTK("make_bigsur_l1isr: bad irq, %d\n", irq); return; } @@ -264,7 +277,7 @@ static void make_bigsur_l2isr(unsigned int irq) { disable_bigsur_l2irq(irq); return; } - pr_debug("make_bigsur_l2isr: bad irq, %d\n", irq); + DPRINTK("make_bigsur_l2isr: bad irq, %d\n", irq); return; } diff --git a/trunk/arch/sh/boards/bigsur/setup.c b/trunk/arch/sh/boards/bigsur/setup.c index 9711c20fc9e4..dfeede9da50f 100644 --- a/trunk/arch/sh/boards/bigsur/setup.c +++ b/trunk/arch/sh/boards/bigsur/setup.c @@ -41,7 +41,31 @@ // Big Sur Init Routines /*===========================================================*/ -static void __init bigsur_setup(char **cmdline_p) +const char *get_system_type(void) +{ + return "Big Sur"; +} + +/* + * The Machine Vector + */ +extern void heartbeat_bigsur(void); +extern void init_bigsur_IRQ(void); + +struct sh_machine_vector mv_bigsur __initmv = { + .mv_nr_irqs = NR_IRQS, // Defined in + + .mv_isa_port2addr = bigsur_isa_port2addr, + .mv_irq_demux = bigsur_irq_demux, + + .mv_init_irq = init_bigsur_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_bigsur, +#endif +}; +ALIAS_MV(bigsur) + +int __init platform_setup(void) { /* Mask all 2nd level IRQ's */ outb(-1,BIGSUR_IMR0); @@ -65,24 +89,7 @@ static void __init bigsur_setup(char **cmdline_p) outw(1, BIGSUR_ETHR+0xe); /* set the IO port to BIGSUR_ETHER_IOPORT */ outw(BIGSUR_ETHER_IOPORT<<3, BIGSUR_ETHR+0x2); -} - -/* - * The Machine Vector - */ -extern void heartbeat_bigsur(void); -extern void init_bigsur_IRQ(void); - -struct sh_machine_vector mv_bigsur __initmv = { - .mv_name = "Big Sur", - .mv_setup = bigsur_setup, - .mv_isa_port2addr = bigsur_isa_port2addr, - .mv_irq_demux = bigsur_irq_demux, + return 0; +} - .mv_init_irq = init_bigsur_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_bigsur, -#endif -}; -ALIAS_MV(bigsur) diff --git a/trunk/arch/sh/boards/cat68701/Makefile b/trunk/arch/sh/boards/cat68701/Makefile new file mode 100644 index 000000000000..52c1de0a6dfd --- /dev/null +++ b/trunk/arch/sh/boards/cat68701/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the CAT-68701 specific parts of the kernel +# + +obj-y := setup.o irq.o + diff --git a/trunk/arch/sh/boards/cat68701/irq.c b/trunk/arch/sh/boards/cat68701/irq.c new file mode 100644 index 000000000000..f9a6d185fb8b --- /dev/null +++ b/trunk/arch/sh/boards/cat68701/irq.c @@ -0,0 +1,28 @@ +/* + * linux/arch/sh/boards/cat68701/irq.c + * + * Copyright (C) 2000 Niibe Yutaka + * 2001 Yutaro Ebihara + * + * Setup routines for A-ONE Corp CAT-68701 SH7708 Board + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +#include + +int cat68701_irq_demux(int irq) +{ + if(irq==13) return 14; + if(irq==7) return 10; + return irq; +} + +void init_cat68701_IRQ() +{ + make_imask_irq(10); + make_imask_irq(14); +} diff --git a/trunk/arch/sh/boards/cat68701/setup.c b/trunk/arch/sh/boards/cat68701/setup.c new file mode 100644 index 000000000000..90e5175df227 --- /dev/null +++ b/trunk/arch/sh/boards/cat68701/setup.c @@ -0,0 +1,85 @@ +/* + * linux/arch/sh/boards/cat68701/setup.c + * + * Copyright (C) 2000 Niibe Yutaka + * 2001 Yutaro Ebihara + * + * Setup routines for A-ONE Corp CAT-68701 SH7708 Board + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ + +#include +#include +#include +#include +#include +#include + +const char *get_system_type(void) +{ + return "CAT-68701"; +} + +#ifdef CONFIG_HEARTBEAT +void heartbeat_cat68701() +{ + static unsigned int cnt = 0, period = 0 , bit = 0; + cnt += 1; + if (cnt < period) { + return; + } + cnt = 0; + + /* Go through the points (roughly!): + * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110 + */ + period = 110 - ( (300<= 0x1f0) && (offset <= 0x1f7)) || (offset==0x3f6)) + return 0xba000000 + offset; + + /* INPUT PORT */ + if ((offset >= 0x3fc) && (offset <= 0x3fd)) + return 0xb4007000 + offset; + + /* OUTPUT PORT */ + if ((offset >= 0x3fe) && (offset <= 0x3ff)) + return 0xb4007400 + offset; + + return offset + 0xb4000000; /* other I/O (EREA 5)*/ +} + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_cat68701 __initmv = { + .mv_nr_irqs = 32, + .mv_isa_port2addr = cat68701_isa_port2addr, + .mv_irq_demux = cat68701_irq_demux, + + .mv_init_irq = init_cat68701_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_cat68701, +#endif +}; +ALIAS_MV(cat68701) + +int __init platform_setup(void) +{ + /* dummy read erea5 (CS8900A) */ +} + diff --git a/trunk/arch/sh/boards/cqreek/Makefile b/trunk/arch/sh/boards/cqreek/Makefile new file mode 100644 index 000000000000..1a788a85eba3 --- /dev/null +++ b/trunk/arch/sh/boards/cqreek/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the CqREEK specific parts of the kernel +# + +obj-y := setup.o irq.o + diff --git a/trunk/arch/sh/boards/cqreek/irq.c b/trunk/arch/sh/boards/cqreek/irq.c new file mode 100644 index 000000000000..2955adc52310 --- /dev/null +++ b/trunk/arch/sh/boards/cqreek/irq.c @@ -0,0 +1,128 @@ +/* $Id: irq.c,v 1.1.2.4 2002/11/04 20:33:56 lethal Exp $ + * + * arch/sh/boards/cqreek/irq.c + * + * Copyright (C) 2000 Niibe Yutaka + * + * CqREEK IDE/ISA Bridge Support. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +struct cqreek_irq_data { + unsigned short mask_port; /* Port of Interrupt Mask Register */ + unsigned short stat_port; /* Port of Interrupt Status Register */ + unsigned short bit; /* Value of the bit */ +}; +static struct cqreek_irq_data cqreek_irq_data[NR_IRQS]; + +static void disable_cqreek_irq(unsigned int irq) +{ + unsigned long flags; + unsigned short mask; + unsigned short mask_port = cqreek_irq_data[irq].mask_port; + unsigned short bit = cqreek_irq_data[irq].bit; + + local_irq_save(flags); + /* Disable IRQ */ + mask = inw(mask_port) & ~bit; + outw_p(mask, mask_port); + local_irq_restore(flags); +} + +static void enable_cqreek_irq(unsigned int irq) +{ + unsigned long flags; + unsigned short mask; + unsigned short mask_port = cqreek_irq_data[irq].mask_port; + unsigned short bit = cqreek_irq_data[irq].bit; + + local_irq_save(flags); + /* Enable IRQ */ + mask = inw(mask_port) | bit; + outw_p(mask, mask_port); + local_irq_restore(flags); +} + +static void mask_and_ack_cqreek(unsigned int irq) +{ + unsigned short stat_port = cqreek_irq_data[irq].stat_port; + unsigned short bit = cqreek_irq_data[irq].bit; + + disable_cqreek_irq(irq); + /* Clear IRQ (it might be edge IRQ) */ + inw(stat_port); + outw_p(bit, stat_port); +} + +static void end_cqreek_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_cqreek_irq(irq); +} + +static unsigned int startup_cqreek_irq(unsigned int irq) +{ + enable_cqreek_irq(irq); + return 0; +} + +static void shutdown_cqreek_irq(unsigned int irq) +{ + disable_cqreek_irq(irq); +} + +static struct hw_interrupt_type cqreek_irq_type = { + .typename = "CqREEK-IRQ", + .startup = startup_cqreek_irq, + .shutdown = shutdown_cqreek_irq, + .enable = enable_cqreek_irq, + .disable = disable_cqreek_irq, + .ack = mask_and_ack_cqreek, + .end = end_cqreek_irq +}; + +int cqreek_has_ide, cqreek_has_isa; + +/* XXX: This is just for test for my NE2000 ISA board + What we really need is virtualized IRQ and demultiplexer like HP600 port */ +void __init init_cqreek_IRQ(void) +{ + if (cqreek_has_ide) { + cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK; + cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT; + cqreek_irq_data[14].bit = 1; + + irq_desc[14].chip = &cqreek_irq_type; + irq_desc[14].status = IRQ_DISABLED; + irq_desc[14].action = 0; + irq_desc[14].depth = 1; + + disable_cqreek_irq(14); + } + + if (cqreek_has_isa) { + cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK; + cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT; + cqreek_irq_data[10].bit = (1 << 10); + + /* XXX: Err... we may need demultiplexer for ISA irq... */ + irq_desc[10].chip = &cqreek_irq_type; + irq_desc[10].status = IRQ_DISABLED; + irq_desc[10].action = 0; + irq_desc[10].depth = 1; + + disable_cqreek_irq(10); + } +} + diff --git a/trunk/arch/sh/boards/cqreek/setup.c b/trunk/arch/sh/boards/cqreek/setup.c new file mode 100644 index 000000000000..eff4ed93599f --- /dev/null +++ b/trunk/arch/sh/boards/cqreek/setup.c @@ -0,0 +1,100 @@ +/* $Id: setup.c,v 1.5 2003/08/04 01:51:58 lethal Exp $ + * + * arch/sh/kernel/setup_cqreek.c + * + * Copyright (C) 2000 Niibe Yutaka + * + * CqREEK IDE/ISA Bridge Support. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define IDE_OFFSET 0xA4000000UL +#define ISA_OFFSET 0xA4A00000UL + +const char *get_system_type(void) +{ + return "CqREEK"; +} + +static unsigned long cqreek_port2addr(unsigned long port) +{ + if (0x0000<=port && port<=0x0040) + return IDE_OFFSET + port; + if ((0x01f0<=port && port<=0x01f7) || port == 0x03f6) + return IDE_OFFSET + port; + + return ISA_OFFSET + port; +} + +/* + * The Machine Vector + */ +struct sh_machine_vector mv_cqreek __initmv = { +#if defined(CONFIG_CPU_SH4) + .mv_nr_irqs = 48, +#elif defined(CONFIG_CPU_SUBTYPE_SH7708) + .mv_nr_irqs = 32, +#elif defined(CONFIG_CPU_SUBTYPE_SH7709) + .mv_nr_irqs = 61, +#endif + + .mv_init_irq = init_cqreek_IRQ, + + .mv_isa_port2addr = cqreek_port2addr, +}; +ALIAS_MV(cqreek) + +/* + * Initialize the board + */ +void __init platform_setup(void) +{ + int i; +/* udelay is not available at setup time yet... */ +#define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0) + + if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */ + outw_p(0, BRIDGE_IDE_INTR_LVL); + outw_p(0, BRIDGE_IDE_INTR_MASK); + + outw_p(0, BRIDGE_IDE_CTRL); + DELAY(); + + outw_p(0x8000, BRIDGE_IDE_CTRL); + DELAY(); + + outw_p(0xffff, BRIDGE_IDE_INTR_STAT); /* Clear interrupt status */ + outw_p(0x0f-14, BRIDGE_IDE_INTR_LVL); /* Use 14 IPR */ + outw_p(1, BRIDGE_IDE_INTR_MASK); /* Enable interrupt */ + cqreek_has_ide=1; + } + + if ((inw (BRIDGE_FEATURE) & 2)) { /* We have ISA interface */ + outw_p(0, BRIDGE_ISA_INTR_LVL); + outw_p(0, BRIDGE_ISA_INTR_MASK); + + outw_p(0, BRIDGE_ISA_CTRL); + DELAY(); + outw_p(0x8000, BRIDGE_ISA_CTRL); + DELAY(); + + outw_p(0xffff, BRIDGE_ISA_INTR_STAT); /* Clear interrupt status */ + outw_p(0x0f-10, BRIDGE_ISA_INTR_LVL); /* Use 10 IPR */ + outw_p(0xfff8, BRIDGE_ISA_INTR_MASK); /* Enable interrupt */ + cqreek_has_isa=1; + } + + printk(KERN_INFO "CqREEK Setup (IDE=%d, ISA=%d)...done\n", cqreek_has_ide, cqreek_has_isa); +} + diff --git a/trunk/arch/sh/boards/dmida/Makefile b/trunk/arch/sh/boards/dmida/Makefile new file mode 100644 index 000000000000..75999aa0a2d9 --- /dev/null +++ b/trunk/arch/sh/boards/dmida/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the DataMyte Industrial Digital Assistant(tm) specific parts +# of the kernel +# + +obj-y := mach.o + diff --git a/trunk/arch/sh/boards/dmida/mach.c b/trunk/arch/sh/boards/dmida/mach.c new file mode 100644 index 000000000000..d03a25f989c2 --- /dev/null +++ b/trunk/arch/sh/boards/dmida/mach.c @@ -0,0 +1,59 @@ +/* + * linux/arch/sh/boards/dmida/mach.c + * + * by Greg Banks + * (c) 2000 PocketPenguins Inc + * + * Derived from mach_hp600.c, which bore the message: + * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Machine vector for the DataMyte Industrial Digital Assistant(tm). + * See http://www.dmida.com + * + */ + +#include + +#include +#include +#include + +#include +#include +#include + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_dmida __initmv = { + .mv_nr_irqs = HD64465_IRQ_BASE+HD64465_IRQ_NUM, + + .mv_inb = hd64465_inb, + .mv_inw = hd64465_inw, + .mv_inl = hd64465_inl, + .mv_outb = hd64465_outb, + .mv_outw = hd64465_outw, + .mv_outl = hd64465_outl, + + .mv_inb_p = hd64465_inb_p, + .mv_inw_p = hd64465_inw, + .mv_inl_p = hd64465_inl, + .mv_outb_p = hd64465_outb_p, + .mv_outw_p = hd64465_outw, + .mv_outl_p = hd64465_outl, + + .mv_insb = hd64465_insb, + .mv_insw = hd64465_insw, + .mv_insl = hd64465_insl, + .mv_outsb = hd64465_outsb, + .mv_outsw = hd64465_outsw, + .mv_outsl = hd64465_outsl, + + .mv_irq_demux = hd64465_irq_demux, +}; +ALIAS_MV(dmida) + diff --git a/trunk/arch/sh/boards/dreamcast/irq.c b/trunk/arch/sh/boards/dreamcast/irq.c index 5bf01f86c20c..b10a6b11c034 100644 --- a/trunk/arch/sh/boards/dreamcast/irq.c +++ b/trunk/arch/sh/boards/dreamcast/irq.c @@ -10,6 +10,7 @@ */ #include + #include #include #include @@ -25,10 +26,10 @@ event. There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908. Event - types can be found in include/asm-sh/dreamcast/sysasic.h. There are three - groups of EMRs that parallel the ESRs. Each EMR group corresponds to an - IRQ, so 0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928 - triggers IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9. + types can be found in include/asm-sh/dc_sysasic.h. There are three groups + of EMRs that parallel the ESRs. Each EMR group corresponds to an IRQ, so + 0xa05f6910 - 0xa05f6918 triggers IRQ 13, 0xa05f6920 - 0xa05f6928 triggers + IRQ 11, and 0xa05f6930 - 0xa05f6938 triggers IRQ 9. In the kernel, these events are mapped to virtual IRQs so that drivers can respond to them as they would a normal interrupt. In order to keep this @@ -56,23 +57,29 @@ /* Disable the hardware event by masking its bit in its EMR */ static inline void disable_systemasic_irq(unsigned int irq) { + unsigned long flags; __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); __u32 mask; + local_irq_save(flags); mask = inl(emr); mask &= ~(1 << EVENT_BIT(irq)); outl(mask, emr); + local_irq_restore(flags); } /* Enable the hardware event by setting its bit in its EMR */ static inline void enable_systemasic_irq(unsigned int irq) { + unsigned long flags; __u32 emr = EMR_BASE + (LEVEL(irq) << 4) + (LEVEL(irq) << 2); __u32 mask; + local_irq_save(flags); mask = inl(emr); mask |= (1 << EVENT_BIT(irq)); outl(mask, emr); + local_irq_restore(flags); } /* Acknowledge a hardware event by writing its bit back to its ESR */ diff --git a/trunk/arch/sh/boards/dreamcast/rtc.c b/trunk/arch/sh/boards/dreamcast/rtc.c index b3a876a3b859..379de1629134 100644 --- a/trunk/arch/sh/boards/dreamcast/rtc.c +++ b/trunk/arch/sh/boards/dreamcast/rtc.c @@ -1,5 +1,4 @@ -/* - * arch/sh/boards/dreamcast/rtc.c +/* arch/sh/kernel/rtc-aica.c * * Dreamcast AICA RTC routines. * @@ -11,12 +10,15 @@ */ #include -#include + #include +extern void (*rtc_get_time)(struct timespec *); +extern int (*rtc_set_time)(const time_t); + /* The AICA RTC has an Epoch of 1/1/1950, so we must subtract 20 years (in - seconds) to get the standard Unix Epoch when getting the time, and add - 20 years when setting the time. */ + seconds to get the standard Unix Epoch when getting the time, and add 20 + years when setting the time. */ #define TWENTY_YEARS ((20 * 365LU + 5) * 86400) /* The AICA RTC is represented by a 32-bit seconds counter stored in 2 16-bit @@ -30,8 +32,7 @@ * * Grabs the current RTC seconds counter and adjusts it to the Unix Epoch. */ -void aica_rtc_gettimeofday(struct timespec *ts) -{ +void aica_rtc_gettimeofday(struct timespec *ts) { unsigned long val1, val2; do { @@ -54,8 +55,7 @@ void aica_rtc_gettimeofday(struct timespec *ts) * * Adjusts the given @tv to the AICA Epoch and sets the RTC seconds counter. */ -int aica_rtc_settimeofday(const time_t secs) -{ +int aica_rtc_settimeofday(const time_t secs) { unsigned long val1, val2; unsigned long adj = secs + TWENTY_YEARS; @@ -75,7 +75,7 @@ int aica_rtc_settimeofday(const time_t secs) void aica_time_init(void) { - rtc_sh_get_time = aica_rtc_gettimeofday; - rtc_sh_set_time = aica_rtc_settimeofday; + rtc_get_time = aica_rtc_gettimeofday; + rtc_set_time = aica_rtc_settimeofday; } diff --git a/trunk/arch/sh/boards/dreamcast/setup.c b/trunk/arch/sh/boards/dreamcast/setup.c index f13017eeeb27..0027b80a2343 100644 --- a/trunk/arch/sh/boards/dreamcast/setup.c +++ b/trunk/arch/sh/boards/dreamcast/setup.c @@ -22,21 +22,41 @@ #include #include #include + #include #include -#include #include +#include #include extern struct hw_interrupt_type systemasic_int; +/* XXX: Move this into it's proper header. */ +extern void (*board_time_init)(void); extern void aica_time_init(void); extern int gapspci_init(void); extern int systemasic_irq_demux(int); -void *dreamcast_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t); +void *dreamcast_consistent_alloc(struct device *, size_t, dma_addr_t *, int); int dreamcast_consistent_free(struct device *, size_t, void *, dma_addr_t); -static void __init dreamcast_setup(char **cmdline_p) +const char *get_system_type(void) +{ + return "Sega Dreamcast"; +} + +struct sh_machine_vector mv_dreamcast __initmv = { + .mv_nr_irqs = NR_IRQS, + + .mv_irq_demux = systemasic_irq_demux, + +#ifdef CONFIG_PCI + .mv_consistent_alloc = dreamcast_consistent_alloc, + .mv_consistent_free = dreamcast_consistent_free, +#endif +}; +ALIAS_MV(dreamcast) + +int __init platform_setup(void) { int i; @@ -58,16 +78,6 @@ static void __init dreamcast_setup(char **cmdline_p) if (gapspci_init() < 0) printk(KERN_WARNING "GAPSPCI was not detected.\n"); #endif -} -struct sh_machine_vector mv_dreamcast __initmv = { - .mv_name = "Sega Dreamcast", - .mv_setup = dreamcast_setup, - .mv_irq_demux = systemasic_irq_demux, - -#ifdef CONFIG_PCI - .mv_consistent_alloc = dreamcast_consistent_alloc, - .mv_consistent_free = dreamcast_consistent_free, -#endif -}; -ALIAS_MV(dreamcast) + return 0; +} diff --git a/trunk/arch/sh/boards/ec3104/setup.c b/trunk/arch/sh/boards/ec3104/setup.c index 902bc975a13e..4b3ef16a0e96 100644 --- a/trunk/arch/sh/boards/ec3104/setup.c +++ b/trunk/arch/sh/boards/ec3104/setup.c @@ -21,36 +21,22 @@ #include #include #include + #include #include #include #include -static void __init ec3104_setup(char **cmdline_p) +const char *get_system_type(void) { - char str[8]; - int i; - - for (i=0; i<8; i++) - str[i] = ctrl_readb(EC3104_BASE + i); - - for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++) - irq_desc[i].handler = &ec3104_int; - - printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n", - str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE); - - /* mask all interrupts. this should have been done by the boot - * loader for us but we want to be sure ... */ - ctrl_writel(0xffffffff, EC3104_IMR); + return "EC3104"; } /* * The Machine Vector */ + struct sh_machine_vector mv_ec3104 __initmv = { - .mv_name = "EC3104", - .mv_setup = ec3104_setup, .mv_nr_irqs = 96, .mv_inb = ec3104_inb, @@ -62,4 +48,31 @@ struct sh_machine_vector mv_ec3104 __initmv = { .mv_irq_demux = ec3104_irq_demux, }; + ALIAS_MV(ec3104) + +int __init platform_setup(void) +{ + char str[8]; + int i; + + if (0) + return 0; + + for (i=0; i<8; i++) + str[i] = ctrl_readb(EC3104_BASE + i); + + for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++) + irq_desc[i].chip = &ec3104_int; + + printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n", + str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE); + + + /* mask all interrupts. this should have been done by the boot + * loader for us but we want to be sure ... */ + ctrl_writel(0xffffffff, EC3104_IMR); + + return 0; +} + diff --git a/trunk/arch/sh/boards/harp/Makefile b/trunk/arch/sh/boards/harp/Makefile new file mode 100644 index 000000000000..eb753d31812e --- /dev/null +++ b/trunk/arch/sh/boards/harp/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for STMicroelectronics board specific parts of the kernel +# + +obj-y := irq.o setup.o mach.o led.o + +obj-$(CONFIG_PCI) += pcidma.o + diff --git a/trunk/arch/sh/boards/harp/irq.c b/trunk/arch/sh/boards/harp/irq.c new file mode 100644 index 000000000000..96bb41c9fc55 --- /dev/null +++ b/trunk/arch/sh/boards/harp/irq.c @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Looks after interrupts on the HARP board. + * + * Bases on the IPR irq system + */ + +#include +#include + +#include +#include +#include + + +#define NUM_EXTERNAL_IRQS 16 + +// Early versions of the STB1 Overdrive required this nasty frig +//#define INVERT_INTMASK_WRITES + +static void enable_harp_irq(unsigned int irq); +static void disable_harp_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_harp_irq disable_harp_irq + +static void mask_and_ack_harp(unsigned int); +static void end_harp_irq(unsigned int irq); + +static unsigned int startup_harp_irq(unsigned int irq) +{ + enable_harp_irq(irq); + return 0; /* never anything pending */ +} + +static struct hw_interrupt_type harp_irq_type = { + .typename = "Harp-IRQ", + .startup = startup_harp_irq, + .shutdown = shutdown_harp_irq, + .enable = enable_harp_irq, + .disable = disable_harp_irq, + .ack = mask_and_ack_harp, + .end = end_harp_irq +}; + +static void disable_harp_irq(unsigned int irq) +{ + unsigned val, flags; + unsigned maskReg; + unsigned mask; + int pri; + + if (irq < 0 || irq >= NUM_EXTERNAL_IRQS) + return; + + pri = 15 - irq; + + if (pri < 8) { + maskReg = EPLD_INTMASK0; + } else { + maskReg = EPLD_INTMASK1; + pri -= 8; + } + + local_irq_save(flags); + mask = ctrl_inl(maskReg); + mask &= (~(1 << pri)); +#if defined(INVERT_INTMASK_WRITES) + mask ^= 0xff; +#endif + ctrl_outl(mask, maskReg); + local_irq_restore(flags); +} + +static void enable_harp_irq(unsigned int irq) +{ + unsigned flags; + unsigned maskReg; + unsigned mask; + int pri; + + if (irq < 0 || irq >= NUM_EXTERNAL_IRQS) + return; + + pri = 15 - irq; + + if (pri < 8) { + maskReg = EPLD_INTMASK0; + } else { + maskReg = EPLD_INTMASK1; + pri -= 8; + } + + local_irq_save(flags); + mask = ctrl_inl(maskReg); + + + mask |= (1 << pri); + +#if defined(INVERT_INTMASK_WRITES) + mask ^= 0xff; +#endif + ctrl_outl(mask, maskReg); + + local_irq_restore(flags); +} + +/* This functions sets the desired irq handler to be an overdrive type */ +static void __init make_harp_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].chip = &harp_irq_type; + disable_harp_irq(irq); +} + +static void mask_and_ack_harp(unsigned int irq) +{ + disable_harp_irq(irq); +} + +static void end_harp_irq(unsigned int irq) +{ + enable_harp_irq(irq); +} + +void __init init_harp_irq(void) +{ + int i; + +#if !defined(INVERT_INTMASK_WRITES) + // On the harp these are set to enable an interrupt + ctrl_outl(0x00, EPLD_INTMASK0); + ctrl_outl(0x00, EPLD_INTMASK1); +#else + // On the Overdrive the data is inverted before being stored in the reg + ctrl_outl(0xff, EPLD_INTMASK0); + ctrl_outl(0xff, EPLD_INTMASK1); +#endif + + for (i = 0; i < NUM_EXTERNAL_IRQS; i++) { + make_harp_irq(i); + } +} diff --git a/trunk/arch/sh/boards/harp/led.c b/trunk/arch/sh/boards/harp/led.c new file mode 100644 index 000000000000..aeb7b392b190 --- /dev/null +++ b/trunk/arch/sh/boards/harp/led.c @@ -0,0 +1,51 @@ +/* + * linux/arch/sh/stboards/led.c + * + * Copyright (C) 2000 Stuart Menefy + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains ST40STB1 HARP and compatible code. + */ + +#include +#include + +/* Harp: Flash LD10 (front pannel) connected to EPLD (IC8) */ +/* Overdrive: Flash LD1 (front panel) connected to EPLD (IC4) */ +/* Works for HARP and overdrive */ +static void mach_led(int position, int value) +{ + if (value) { + ctrl_outl(EPLD_LED_ON, EPLD_LED); + } else { + ctrl_outl(EPLD_LED_OFF, EPLD_LED); + } +} + +#ifdef CONFIG_HEARTBEAT + +#include + +/* acts like an actual heart beat -- ie thump-thump-pause... */ +void heartbeat_harp(void) +{ + static unsigned cnt = 0, period = 0, dist = 0; + + if (cnt == 0 || cnt == dist) + mach_led( -1, 1); + else if (cnt == 7 || cnt == dist+7) + mach_led( -1, 0); + + if (++cnt > period) { + cnt = 0; + /* The hyperbolic function below modifies the heartbeat period + * length in dependency of the current (5min) load. It goes + * through the points f(0)=126, f(1)=86, f(5)=51, + * f(inf)->30. */ + period = ((672< + +#include +#include +#include +#include +#include + +void setup_harp(void); +void init_harp_irq(void); +void heartbeat_harp(void); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_harp __initmv = { + .mv_nr_irqs = 89 + HD64465_IRQ_NUM, + + .mv_inb = hd64465_inb, + .mv_inw = hd64465_inw, + .mv_inl = hd64465_inl, + .mv_outb = hd64465_outb, + .mv_outw = hd64465_outw, + .mv_outl = hd64465_outl, + + .mv_inb_p = hd64465_inb_p, + .mv_inw_p = hd64465_inw, + .mv_inl_p = hd64465_inl, + .mv_outb_p = hd64465_outb_p, + .mv_outw_p = hd64465_outw, + .mv_outl_p = hd64465_outl, + + .mv_insb = hd64465_insb, + .mv_insw = hd64465_insw, + .mv_insl = hd64465_insl, + .mv_outsb = hd64465_outsb, + .mv_outsw = hd64465_outsw, + .mv_outsl = hd64465_outsl, + + .mv_isa_port2addr = hd64465_isa_port2addr, + +#ifdef CONFIG_PCI + .mv_init_irq = init_harp_irq, +#endif +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_harp, +#endif +}; + +ALIAS_MV(harp) diff --git a/trunk/arch/sh/boards/harp/pcidma.c b/trunk/arch/sh/boards/harp/pcidma.c new file mode 100644 index 000000000000..475311390fd6 --- /dev/null +++ b/trunk/arch/sh/boards/harp/pcidma.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Dynamic DMA mapping support. + */ + +#include +#include +#include +#include +#include +#include + + +void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t * dma_handle) +{ + void *ret; + int gfp = GFP_ATOMIC; + + ret = (void *) __get_free_pages(gfp, get_order(size)); + + if (ret != NULL) { + /* Is it neccessary to do the memset? */ + memset(ret, 0, size); + *dma_handle = virt_to_bus(ret); + } + /* We must flush the cache before we pass it on to the device */ + flush_cache_all(); + return P2SEGADDR(ret); +} + +void pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + unsigned long p1addr=P1SEGADDR((unsigned long)vaddr); + + free_pages(p1addr, get_order(size)); +} diff --git a/trunk/arch/sh/boards/harp/setup.c b/trunk/arch/sh/boards/harp/setup.c new file mode 100644 index 000000000000..886e450ab63e --- /dev/null +++ b/trunk/arch/sh/boards/harp/setup.c @@ -0,0 +1,90 @@ +/* + * arch/sh/stboard/setup.c + * + * Copyright (C) 2001 Stuart Menefy (stuart.menefy@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * STMicroelectronics ST40STB1 HARP and compatible support. + */ + +#include +#include +#include +#include + +const char *get_system_type(void) +{ + return "STB1 Harp"; +} + +/* + * Initialize the board + */ +int __init platform_setup(void) +{ +#ifdef CONFIG_SH_STB1_HARP + unsigned long ic8_version, ic36_version; + + ic8_version = ctrl_inl(EPLD_REVID2); + ic36_version = ctrl_inl(EPLD_REVID1); + + printk("STMicroelectronics STB1 HARP initialisaton\n"); + printk("EPLD versions: IC8: %d.%02d, IC36: %d.%02d\n", + (ic8_version >> 4) & 0xf, ic8_version & 0xf, + (ic36_version >> 4) & 0xf, ic36_version & 0xf); +#elif defined(CONFIG_SH_STB1_OVERDRIVE) + unsigned long version; + + version = ctrl_inl(EPLD_REVID); + + printk("STMicroelectronics STB1 Overdrive initialisaton\n"); + printk("EPLD version: %d.%02d\n", + (version >> 4) & 0xf, version & 0xf); +#else +#error Undefined machine +#endif + + /* Currently all STB1 chips have problems with the sleep instruction, + * so disable it here. + */ + disable_hlt(); + + return 0; +} + +/* + * pcibios_map_platform_irq + * + * This is board specific and returns the IRQ for a given PCI device. + * It is used by the PCI code (arch/sh/kernel/st40_pci*) + * + */ + +#define HARP_PCI_IRQ 1 +#define HARP_BRIDGE_IRQ 2 +#define OVERDRIVE_SLOT0_IRQ 0 + + +int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + switch (slot) { +#ifdef CONFIG_SH_STB1_HARP + case 2: /*This is the PCI slot on the */ + return HARP_PCI_IRQ; + case 1: /* this is the bridge */ + return HARP_BRIDGE_IRQ; +#elif defined(CONFIG_SH_STB1_OVERDRIVE) + case 1: + case 2: + case 3: + return slot - 1; +#else +#error Unknown board +#endif + default: + return -1; + } +} + diff --git a/trunk/arch/sh/boards/hp6xx/Makefile b/trunk/arch/sh/boards/hp6xx/Makefile index ff1b7f5b4e91..927fe0aa5dfa 100644 --- a/trunk/arch/sh/boards/hp6xx/Makefile +++ b/trunk/arch/sh/boards/hp6xx/Makefile @@ -2,6 +2,5 @@ # Makefile for the HP6xx specific parts of the kernel # -obj-y := setup.o -obj-$(CONFIG_PM) += pm.o pm_wakeup.o -obj-$(CONFIG_APM) += hp6xx_apm.o +obj-y := mach.o setup.o + diff --git a/trunk/arch/sh/boards/hp6xx/hp6xx_apm.c b/trunk/arch/sh/boards/hp6xx/hp6xx_apm.c deleted file mode 100644 index ad0e712c29f6..000000000000 --- a/trunk/arch/sh/boards/hp6xx/hp6xx_apm.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * bios-less APM driver for hp680 - * - * Copyright 2005 (c) Andriy Skulysh - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SH7709_PGDR 0xa400012c - -#define APM_CRITICAL 10 -#define APM_LOW 30 - -#define HP680_BATTERY_MAX 875 -#define HP680_BATTERY_MIN 600 -#define HP680_BATTERY_AC_ON 900 - -#define MODNAME "hp6x0_apm" - -static int hp6x0_apm_get_info(char *buf, char **start, off_t fpos, int length) -{ - u8 pgdr; - char *p; - int battery_status; - int battery_flag; - int ac_line_status; - int time_units = APM_BATTERY_LIFE_UNKNOWN; - - int battery = adc_single(ADC_CHANNEL_BATTERY); - int backup = adc_single(ADC_CHANNEL_BACKUP); - int charging = adc_single(ADC_CHANNEL_CHARGE); - int percentage; - - percentage = 100 * (battery - HP680_BATTERY_MIN) / - (HP680_BATTERY_MAX - HP680_BATTERY_MIN); - - ac_line_status = (battery > HP680_BATTERY_AC_ON) ? - APM_AC_ONLINE : APM_AC_OFFLINE; - - p = buf; - - pgdr = ctrl_inb(SH7709_PGDR); - if (pgdr & PGDR_MAIN_BATTERY_OUT) { - battery_status = APM_BATTERY_STATUS_NOT_PRESENT; - battery_flag = 0x80; - percentage = -1; - } else if (charging < 8 ) { - battery_status = APM_BATTERY_STATUS_CHARGING; - battery_flag = 0x08; - ac_line_status = 0xff; - } else if (percentage <= APM_CRITICAL) { - battery_status = APM_BATTERY_STATUS_CRITICAL; - battery_flag = 0x04; - } else if (percentage <= APM_LOW) { - battery_status = APM_BATTERY_STATUS_LOW; - battery_flag = 0x02; - } else { - battery_status = APM_BATTERY_STATUS_HIGH; - battery_flag = 0x01; - } - - p += sprintf(p, "1.0 1.2 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n", - APM_32_BIT_SUPPORT, - ac_line_status, - battery_status, - battery_flag, - percentage, - time_units, - "min"); - p += sprintf(p, "bat=%d backup=%d charge=%d\n", - battery, backup, charging); - - return p - buf; -} - -static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev, struct pt_regs *regs) -{ - if (!apm_suspended) - apm_queue_event(APM_USER_SUSPEND); - - return IRQ_HANDLED; -} - -static int __init hp6x0_apm_init(void) -{ - int ret; - - ret = request_irq(HP680_BTN_IRQ, hp6x0_apm_interrupt, - SA_INTERRUPT, MODNAME, 0); - if (unlikely(ret < 0)) { - printk(KERN_ERR MODNAME ": IRQ %d request failed\n", - HP680_BTN_IRQ); - return ret; - } - - apm_get_info = hp6x0_apm_get_info; - - return ret; -} - -static void __exit hp6x0_apm_exit(void) -{ - free_irq(HP680_BTN_IRQ, 0); - apm_get_info = 0; -} - -module_init(hp6x0_apm_init); -module_exit(hp6x0_apm_exit); - -MODULE_AUTHOR("Adriy Skulysh"); -MODULE_DESCRIPTION("hp6xx Advanced Power Management"); -MODULE_LICENSE("GPL"); diff --git a/trunk/arch/sh/boards/hp6xx/pm.c b/trunk/arch/sh/boards/hp6xx/pm.c deleted file mode 100644 index 0e501bcbd7a9..000000000000 --- a/trunk/arch/sh/boards/hp6xx/pm.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * hp6x0 Power Management Routines - * - * Copyright (c) 2006 Andriy Skulysh - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define STBCR 0xffffff82 -#define STBCR2 0xffffff88 - -static int hp6x0_pm_enter(suspend_state_t state) -{ - u8 stbcr, stbcr2; -#ifdef CONFIG_HD64461_ENABLER - u8 scr; - u16 hd64461_stbcr; -#endif - - if (state != PM_SUSPEND_MEM) - return -EINVAL; - -#ifdef CONFIG_HD64461_ENABLER - outb(0, HD64461_PCC1CSCIER); - - scr = inb(HD64461_PCC1SCR); - scr |= HD64461_PCCSCR_VCC1; - outb(scr, HD64461_PCC1SCR); - - hd64461_stbcr = inw(HD64461_STBCR); - hd64461_stbcr |= HD64461_STBCR_SPC1ST; - outw(hd64461_stbcr, HD64461_STBCR); -#endif - - ctrl_outb(0x1f, DACR); - - stbcr = ctrl_inb(STBCR); - ctrl_outb(0x01, STBCR); - - stbcr2 = ctrl_inb(STBCR2); - ctrl_outb(0x7f , STBCR2); - - outw(0xf07f, HD64461_SCPUCR); - - pm_enter(); - - outw(0, HD64461_SCPUCR); - ctrl_outb(stbcr, STBCR); - ctrl_outb(stbcr2, STBCR2); - -#ifdef CONFIG_HD64461_ENABLER - hd64461_stbcr = inw(HD64461_STBCR); - hd64461_stbcr &= ~HD64461_STBCR_SPC1ST; - outw(hd64461_stbcr, HD64461_STBCR); - - outb(0x4c, HD64461_PCC1CSCIER); - outb(0x00, HD64461_PCC1CSCR); -#endif - - return 0; -} - -/* - * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk. - */ -static struct pm_ops hp6x0_pm_ops = { - .pm_disk_mode = PM_DISK_FIRMWARE, - .enter = hp6x0_pm_enter, -}; - -static int __init hp6x0_pm_init(void) -{ - pm_set_ops(&hp6x0_pm_ops); - return 0; -} - -late_initcall(hp6x0_pm_init); diff --git a/trunk/arch/sh/boards/hp6xx/pm_wakeup.S b/trunk/arch/sh/boards/hp6xx/pm_wakeup.S deleted file mode 100644 index 45e9bf0b9115..000000000000 --- a/trunk/arch/sh/boards/hp6xx/pm_wakeup.S +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2006 Andriy Skulysh - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - */ - -#include -#include - -#define k0 r0 -#define k1 r1 -#define k2 r2 -#define k3 r3 -#define k4 r4 - -/* - * Kernel mode register usage: - * k0 scratch - * k1 scratch - * k2 scratch (Exception code) - * k3 scratch (Return address) - * k4 scratch - * k5 reserved - * k6 Global Interrupt Mask (0--15 << 4) - * k7 CURRENT_THREAD_INFO (pointer to current thread info) - */ - -ENTRY(wakeup_start) -! clear STBY bit - mov #-126, k2 - and #127, k0 - mov.b k0, @k2 -! enable refresh - mov.l 5f, k1 - mov.w 6f, k0 - mov.w k0, @k1 -! jump to handler - mov.l 2f, k2 - mov.l 3f, k3 - mov.l @k2, k2 - - mov.l 4f, k1 - jmp @k1 - nop - - .align 2 -1: .long EXPEVT -2: .long INTEVT -3: .long ret_from_irq -4: .long handle_exception -5: .long 0xffffff68 -6: .word 0x0524 - -ENTRY(wakeup_end) - nop diff --git a/trunk/arch/sh/boards/hp6xx/setup.c b/trunk/arch/sh/boards/hp6xx/setup.c index 60ab17ad6054..71f315663cc9 100644 --- a/trunk/arch/sh/boards/hp6xx/setup.c +++ b/trunk/arch/sh/boards/hp6xx/setup.c @@ -8,22 +8,22 @@ * * Setup code for an HP680 (internal peripherials only) */ -#include + #include -#include #include -#include +#include #include #include -#define SCPCR 0xa4000116 -#define SCPDR 0xa4000136 +const char *get_system_type(void) +{ + return "HP6xx"; +} -static void __init hp6xx_setup(char **cmdline_p) +int __init platform_setup(void) { u8 v8; u16 v; - v = inw(HD64461_STBCR); v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST | @@ -50,51 +50,5 @@ static void __init hp6xx_setup(char **cmdline_p) v8 &= ~DACR_DAE; ctrl_outb(v8,DACR); - v8 = ctrl_inb(SCPDR); - v8 |= SCPDR_TS_SCAN_X | SCPDR_TS_SCAN_Y; - v8 &= ~SCPDR_TS_SCAN_ENABLE; - ctrl_outb(v8, SCPDR); - - v = ctrl_inw(SCPCR); - v &= ~SCPCR_TS_MASK; - v |= SCPCR_TS_ENABLE; - ctrl_outw(v, SCPCR); + return 0; } - -/* - * XXX: This is stupid, we should have a generic machine vector for the cchips - * and just wrap the platform setup code in to this, as it's the only thing - * that ends up being different. - */ -struct sh_machine_vector mv_hp6xx __initmv = { - .mv_name = "hp6xx", - .mv_setup = hp6xx_setup, - .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM, - - .mv_inb = hd64461_inb, - .mv_inw = hd64461_inw, - .mv_inl = hd64461_inl, - .mv_outb = hd64461_outb, - .mv_outw = hd64461_outw, - .mv_outl = hd64461_outl, - - .mv_inb_p = hd64461_inb_p, - .mv_inw_p = hd64461_inw, - .mv_inl_p = hd64461_inl, - .mv_outb_p = hd64461_outb_p, - .mv_outw_p = hd64461_outw, - .mv_outl_p = hd64461_outl, - - .mv_insb = hd64461_insb, - .mv_insw = hd64461_insw, - .mv_insl = hd64461_insl, - .mv_outsb = hd64461_outsb, - .mv_outsw = hd64461_outsw, - .mv_outsl = hd64461_outsl, - - .mv_readw = hd64461_readw, - .mv_writew = hd64461_writew, - - .mv_irq_demux = hd64461_irq_demux, -}; -ALIAS_MV(hp6xx) diff --git a/trunk/arch/sh/boards/landisk/Makefile b/trunk/arch/sh/boards/landisk/Makefile deleted file mode 100644 index 89e4beb2ad47..000000000000 --- a/trunk/arch/sh/boards/landisk/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for I-O DATA DEVICE, INC. "LANDISK Series" -# - -obj-y := setup.o io.o irq.o rtc.o landisk_pwb.o diff --git a/trunk/arch/sh/boards/landisk/io.c b/trunk/arch/sh/boards/landisk/io.c deleted file mode 100644 index 92498b4947d5..000000000000 --- a/trunk/arch/sh/boards/landisk/io.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * arch/sh/boards/landisk/io.c - * - * Copyright (C) 2001 Ian da Silva, Jeremy Siegel - * Based largely on io_se.c. - * - * I/O routine for I-O Data Device, Inc. LANDISK. - * - * Initial version only to support LAN access; some - * placeholder code from io_landisk.c left in with the - * expectation of later SuperIO and PCMCIA access. - */ -/* - * modifed by kogiidena - * 2005.03.03 - */ -#include -#include -#include -#include -#include -#include - -extern void *area5_io_base; /* Area 5 I/O Base address */ -extern void *area6_io_base; /* Area 6 I/O Base address */ - -static inline unsigned long port2adr(unsigned int port) -{ - if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) - if (port == 0x3f6) - return ((unsigned long)area5_io_base + 0x2c); - else - return ((unsigned long)area5_io_base + PA_PIDE_OFFSET + - ((port - 0x1f0) << 1)); - else if ((0x170 <= port && port < 0x178) || port == 0x376) - if (port == 0x376) - return ((unsigned long)area6_io_base + 0x2c); - else - return ((unsigned long)area6_io_base + PA_SIDE_OFFSET + - ((port - 0x170) << 1)); - else - maybebadio((unsigned long)port); - - return port; -} - -/* - * General outline: remap really low stuff [eventually] to SuperIO, - * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) - * is mapped through the PCI IO window. Stuff with high bits (PXSEG) - * should be way beyond the window, and is used w/o translation for - * compatibility. - */ -u8 landisk_inb(unsigned long port) -{ - if (PXSEG(port)) - return ctrl_inb(port); - else if (is_pci_ioaddr(port)) - return ctrl_inb(pci_ioaddr(port)); - - return ctrl_inw(port2adr(port)) & 0xff; -} - -u8 landisk_inb_p(unsigned long port) -{ - u8 v; - - if (PXSEG(port)) - v = ctrl_inb(port); - else if (is_pci_ioaddr(port)) - v = ctrl_inb(pci_ioaddr(port)); - else - v = ctrl_inw(port2adr(port)) & 0xff; - - ctrl_delay(); - - return v; -} - -u16 landisk_inw(unsigned long port) -{ - if (PXSEG(port)) - return ctrl_inw(port); - else if (is_pci_ioaddr(port)) - return ctrl_inw(pci_ioaddr(port)); - else - maybebadio(port); - - return 0; -} - -u32 landisk_inl(unsigned long port) -{ - if (PXSEG(port)) - return ctrl_inl(port); - else if (is_pci_ioaddr(port)) - return ctrl_inl(pci_ioaddr(port)); - else - maybebadio(port); - - return 0; -} - -void landisk_outb(u8 value, unsigned long port) -{ - if (PXSEG(port)) - ctrl_outb(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outb(value, pci_ioaddr(port)); - else - ctrl_outw(value, port2adr(port)); -} - -void landisk_outb_p(u8 value, unsigned long port) -{ - if (PXSEG(port)) - ctrl_outb(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outb(value, pci_ioaddr(port)); - else - ctrl_outw(value, port2adr(port)); - ctrl_delay(); -} - -void landisk_outw(u16 value, unsigned long port) -{ - if (PXSEG(port)) - ctrl_outw(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outw(value, pci_ioaddr(port)); - else - maybebadio(port); -} - -void landisk_outl(u32 value, unsigned long port) -{ - if (PXSEG(port)) - ctrl_outl(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outl(value, pci_ioaddr(port)); - else - maybebadio(port); -} - -void landisk_insb(unsigned long port, void *dst, unsigned long count) -{ - volatile u16 *p; - u8 *buf = dst; - - if (PXSEG(port)) { - while (count--) - *buf++ = *(volatile u8 *)port; - } else if (is_pci_ioaddr(port)) { - volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); - - while (count--) - *buf++ = *bp; - } else { - p = (volatile u16 *)port2adr(port); - while (count--) - *buf++ = *p & 0xff; - } -} - -void landisk_insw(unsigned long port, void *dst, unsigned long count) -{ - volatile u16 *p; - u16 *buf = dst; - - if (PXSEG(port)) - p = (volatile u16 *)port; - else if (is_pci_ioaddr(port)) - p = (volatile u16 *)pci_ioaddr(port); - else - p = (volatile u16 *)port2adr(port); - while (count--) - *buf++ = *p; -} - -void landisk_insl(unsigned long port, void *dst, unsigned long count) -{ - u32 *buf = dst; - - if (is_pci_ioaddr(port)) { - volatile u32 *p = (volatile u32 *)pci_ioaddr(port); - - while (count--) - *buf++ = *p; - } else - maybebadio(port); -} - -void landisk_outsb(unsigned long port, const void *src, unsigned long count) -{ - volatile u16 *p; - const u8 *buf = src; - - if (PXSEG(port)) - while (count--) - ctrl_outb(*buf++, port); - else if (is_pci_ioaddr(port)) { - volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); - - while (count--) - *bp = *buf++; - } else { - p = (volatile u16 *)port2adr(port); - while (count--) - *p = *buf++; - } -} - -void landisk_outsw(unsigned long port, const void *src, unsigned long count) -{ - volatile u16 *p; - const u16 *buf = src; - - if (PXSEG(port)) - p = (volatile u16 *)port; - else if (is_pci_ioaddr(port)) - p = (volatile u16 *)pci_ioaddr(port); - else - p = (volatile u16 *)port2adr(port); - - while (count--) - *p = *buf++; -} - -void landisk_outsl(unsigned long port, const void *src, unsigned long count) -{ - const u32 *buf = src; - - if (is_pci_ioaddr(port)) { - volatile u32 *p = (volatile u32 *)pci_ioaddr(port); - - while (count--) - *p = *buf++; - } else - maybebadio(port); -} - -void __iomem *landisk_ioport_map(unsigned long port, unsigned int size) -{ - if (PXSEG(port)) - return (void __iomem *)port; - else if (is_pci_ioaddr(port)) - return (void __iomem *)pci_ioaddr(port); - - return (void __iomem *)port2adr(port); -} diff --git a/trunk/arch/sh/boards/landisk/irq.c b/trunk/arch/sh/boards/landisk/irq.c deleted file mode 100644 index a006d6443225..000000000000 --- a/trunk/arch/sh/boards/landisk/irq.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * arch/sh/boards/landisk/irq.c - * - * Copyright (C) 2001 Ian da Silva, Jeremy Siegel - * Based largely on io_se.c. - * - * I/O routine for I-O Data Device, Inc. LANDISK. - * - * Initial version only to support LAN access; some - * placeholder code from io_landisk.c left in with the - * expectation of later SuperIO and PCMCIA access. - */ -/* - * modified by kogiidena - * 2005.03.03 - */ - -#include -#include -#include -#include -#include -#include - -static void enable_landisk_irq(unsigned int irq); -static void disable_landisk_irq(unsigned int irq); - -/* shutdown is same as "disable" */ -#define shutdown_landisk_irq disable_landisk_irq - -static void ack_landisk_irq(unsigned int irq); -static void end_landisk_irq(unsigned int irq); - -static unsigned int startup_landisk_irq(unsigned int irq) -{ - enable_landisk_irq(irq); - return 0; /* never anything pending */ -} - -static void disable_landisk_irq(unsigned int irq) -{ - unsigned char val; - unsigned char mask = 0xff ^ (0x01 << (irq - 5)); - - /* Set the priority in IPR to 0 */ - val = ctrl_inb(PA_IMASK); - val &= mask; - ctrl_outb(val, PA_IMASK); -} - -static void enable_landisk_irq(unsigned int irq) -{ - unsigned char val; - unsigned char value = (0x01 << (irq - 5)); - - /* Set priority in IPR back to original value */ - val = ctrl_inb(PA_IMASK); - val |= value; - ctrl_outb(val, PA_IMASK); -} - -static void ack_landisk_irq(unsigned int irq) -{ - disable_landisk_irq(irq); -} - -static void end_landisk_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_landisk_irq(irq); -} - -static struct hw_interrupt_type landisk_irq_type = { - .typename = "LANDISK IRQ", - .startup = startup_landisk_irq, - .shutdown = shutdown_landisk_irq, - .enable = enable_landisk_irq, - .disable = disable_landisk_irq, - .ack = ack_landisk_irq, - .end = end_landisk_irq -}; - -static void make_landisk_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - irq_desc[irq].handler = &landisk_irq_type; - disable_landisk_irq(irq); -} - -/* - * Initialize IRQ setting - */ -void __init init_landisk_IRQ(void) -{ - int i; - - for (i = 5; i < 14; i++) - make_landisk_irq(i); -} diff --git a/trunk/arch/sh/boards/landisk/landisk_pwb.c b/trunk/arch/sh/boards/landisk/landisk_pwb.c deleted file mode 100644 index e75cb578a28b..000000000000 --- a/trunk/arch/sh/boards/landisk/landisk_pwb.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * arch/sh/boards/landisk/landisk_pwb.c -- driver for the Power control switch. - * - * This driver will also support the I-O DATA Device, Inc. LANDISK Board. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copylight (C) 2002 Atom Create Engineering Co., Ltd. - * - * LED control drive function added by kogiidena - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define SHUTDOWN_BTN_MINOR 1 /* Shutdown button device minor no. */ -#define LED_MINOR 21 /* LED minor no. */ -#define BTN_MINOR 22 /* BUTTON minor no. */ -#define GIO_MINOR 40 /* GIO minor no. */ - -static int openCnt; -static int openCntLED; -static int openCntGio; -static int openCntBtn; -static int landisk_btn; -static int landisk_btnctrlpid; -/* - * Functions prototypes - */ - -static int gio_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg); - -static int swdrv_open(struct inode *inode, struct file *filp) -{ - int minor; - - minor = MINOR(inode->i_rdev); - filp->private_data = (void *)minor; - - if (minor == SHUTDOWN_BTN_MINOR) { - if (openCnt > 0) { - return -EALREADY; - } else { - openCnt++; - return 0; - } - } else if (minor == LED_MINOR) { - if (openCntLED > 0) { - return -EALREADY; - } else { - openCntLED++; - return 0; - } - } else if (minor == BTN_MINOR) { - if (openCntBtn > 0) { - return -EALREADY; - } else { - openCntBtn++; - return 0; - } - } else if (minor == GIO_MINOR) { - if (openCntGio > 0) { - return -EALREADY; - } else { - openCntGio++; - return 0; - } - } - return -ENOENT; - -} - -static int swdrv_close(struct inode *inode, struct file *filp) -{ - int minor; - - minor = MINOR(inode->i_rdev); - if (minor == SHUTDOWN_BTN_MINOR) { - openCnt--; - } else if (minor == LED_MINOR) { - openCntLED--; - } else if (minor == BTN_MINOR) { - openCntBtn--; - } else if (minor == GIO_MINOR) { - openCntGio--; - } - return 0; -} - -static int swdrv_read(struct file *filp, char *buff, size_t count, - loff_t * ppos) -{ - int minor; - minor = (int)(filp->private_data); - - if (!access_ok(VERIFY_WRITE, (void *)buff, count)) - return -EFAULT; - - if (minor == SHUTDOWN_BTN_MINOR) { - if (landisk_btn & 0x10) { - put_user(1, buff); - return 1; - } else { - return 0; - } - } - return 0; -} - -static int swdrv_write(struct file *filp, const char *buff, size_t count, - loff_t * ppos) -{ - int minor; - minor = (int)(filp->private_data); - - if (minor == SHUTDOWN_BTN_MINOR) { - return count; - } - return count; -} - -static irqreturn_t sw_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - landisk_btn = (0x0ff & (~ctrl_inb(PA_STATUS))); - disable_irq(IRQ_BUTTON); - disable_irq(IRQ_POWER); - ctrl_outb(0x00, PA_PWRINT_CLR); - - if (landisk_btnctrlpid != 0) { - kill_proc(landisk_btnctrlpid, SIGUSR1, 1); - landisk_btnctrlpid = 0; - } - - return IRQ_HANDLED; -} - -static struct file_operations swdrv_fops = { - .read = swdrv_read, /* read */ - .write = swdrv_write, /* write */ - .open = swdrv_open, /* open */ - .release = swdrv_close, /* release */ - .ioctl = gio_ioctl, /* ioctl */ - -}; - -static char banner[] __initdata = - KERN_INFO "LANDISK and USL-5P Button, LED and GIO driver initialized\n"; - -int __init swdrv_init(void) -{ - int error; - - printk("%s", banner); - - openCnt = 0; - openCntLED = 0; - openCntBtn = 0; - openCntGio = 0; - landisk_btn = 0; - landisk_btnctrlpid = 0; - - if ((error = register_chrdev(SHUTDOWN_BTN_MAJOR, "swdrv", &swdrv_fops))) { - printk(KERN_ERR - "Button, LED and GIO driver:Couldn't register driver, error=%d\n", - error); - return 1; - } - - if (request_irq(IRQ_POWER, sw_interrupt, 0, "SHUTDOWNSWITCH", NULL)) { - printk(KERN_ERR "Unable to get IRQ 11.\n"); - return 1; - } - if (request_irq(IRQ_BUTTON, sw_interrupt, 0, "USL-5P BUTTON", NULL)) { - printk(KERN_ERR "Unable to get IRQ 12.\n"); - return 1; - } - ctrl_outb(0x00, PA_PWRINT_CLR); - - return 0; -} - -module_init(swdrv_init); - -/* - * gio driver - * - */ - -#include - -static int gio_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) -{ - int minor; - unsigned int data, mask; - static unsigned int addr = 0; - - minor = (int)(filp->private_data); - - /* access control */ - if (minor == GIO_MINOR) { - ; - } else if (minor == LED_MINOR) { - if (((cmd & 0x0ff) >= 9) && ((cmd & 0x0ff) < 20)) { - ; - } else { - return -EINVAL; - } - } else if (minor == BTN_MINOR) { - if (((cmd & 0x0ff) >= 20) && ((cmd & 0x0ff) < 30)) { - ; - } else { - return -EINVAL; - } - } else { - return -EINVAL; - } - - if (cmd & 0x01) { /* write */ - if (copy_from_user(&data, (int *)arg, sizeof(int))) { - return -EFAULT; - } - } - - switch (cmd) { - case GIODRV_IOCSGIOSETADDR: /* addres set */ - addr = data; - break; - - case GIODRV_IOCSGIODATA1: /* write byte */ - ctrl_outb((unsigned char)(0x0ff & data), addr); - break; - - case GIODRV_IOCSGIODATA2: /* write word */ - if (addr & 0x01) { - return -EFAULT; - } - ctrl_outw((unsigned short int)(0x0ffff & data), addr); - break; - - case GIODRV_IOCSGIODATA4: /* write long */ - if (addr & 0x03) { - return -EFAULT; - } - ctrl_outl(data, addr); - break; - - case GIODRV_IOCGGIODATA1: /* read byte */ - data = ctrl_inb(addr); - break; - - case GIODRV_IOCGGIODATA2: /* read word */ - if (addr & 0x01) { - return -EFAULT; - } - data = ctrl_inw(addr); - break; - - case GIODRV_IOCGGIODATA4: /* read long */ - if (addr & 0x03) { - return -EFAULT; - } - data = ctrl_inl(addr); - break; - case GIODRV_IOCSGIO_LED: /* write */ - mask = ((data & 0x00ffffff) << 8) - | ((data & 0x0000ffff) << 16) - | ((data & 0x000000ff) << 24); - landisk_ledparam = data & (~mask); - if (landisk_arch == 0) { /* arch == landisk */ - landisk_ledparam &= 0x03030303; - mask = (~(landisk_ledparam >> 22)) & 0x000c; - landisk_ledparam |= mask; - } else { /* arch == usl-5p */ - mask = (landisk_ledparam >> 24) & 0x0001; - landisk_ledparam |= mask; - landisk_ledparam &= 0x007f7f7f; - } - landisk_ledparam |= 0x80; - break; - case GIODRV_IOCGGIO_LED: /* read */ - data = landisk_ledparam; - if (landisk_arch == 0) { /* arch == landisk */ - data &= 0x03030303; - } else { /* arch == usl-5p */ - ; - } - data &= (~0x080); - break; - case GIODRV_IOCSGIO_BUZZER: /* write */ - landisk_buzzerparam = data; - landisk_ledparam |= 0x80; - break; - case GIODRV_IOCGGIO_LANDISK: /* read */ - data = landisk_arch & 0x01; - break; - case GIODRV_IOCGGIO_BTN: /* read */ - data = (0x0ff & ctrl_inb(PA_PWRINT_CLR)); - data <<= 8; - data |= (0x0ff & ctrl_inb(PA_IMASK)); - data <<= 8; - data |= (0x0ff & landisk_btn); - data <<= 8; - data |= (0x0ff & (~ctrl_inb(PA_STATUS))); - break; - case GIODRV_IOCSGIO_BTNPID: /* write */ - landisk_btnctrlpid = data; - landisk_btn = 0; - if (irq_desc[IRQ_BUTTON].depth) { - enable_irq(IRQ_BUTTON); - } - if (irq_desc[IRQ_POWER].depth) { - enable_irq(IRQ_POWER); - } - break; - case GIODRV_IOCGGIO_BTNPID: /* read */ - data = landisk_btnctrlpid; - break; - default: - return -EFAULT; - break; - } - - if ((cmd & 0x01) == 0) { /* read */ - if (copy_to_user((int *)arg, &data, sizeof(int))) { - return -EFAULT; - } - } - return 0; -} diff --git a/trunk/arch/sh/boards/landisk/rtc.c b/trunk/arch/sh/boards/landisk/rtc.c deleted file mode 100644 index 35ba726a0979..000000000000 --- a/trunk/arch/sh/boards/landisk/rtc.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * arch/sh/boards/landisk/rtc.c -- RTC support - * - * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka - */ -/* - * modifed by kogiidena - * 2005.09.16 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -extern spinlock_t rtc_lock; - -extern void -rs5c313_set_cmos_time(unsigned int BCD_yr, unsigned int BCD_mon, - unsigned int BCD_day, unsigned int BCD_hr, - unsigned int BCD_min, unsigned int BCD_sec); - -extern unsigned long -rs5c313_get_cmos_time(unsigned int *BCD_yr, unsigned int *BCD_mon, - unsigned int *BCD_day, unsigned int *BCD_hr, - unsigned int *BCD_min, unsigned int *BCD_sec); - -void landisk_rtc_gettimeofday(struct timespec *tv) -{ - unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec; - unsigned long flags; - - spin_lock_irqsave(&rtc_lock, flags); - tv->tv_sec = rs5c313_get_cmos_time - (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec); - tv->tv_nsec = 0; - spin_unlock_irqrestore(&rtc_lock, flags); -} - -int landisk_rtc_settimeofday(const time_t secs) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - unsigned long flags; - unsigned long nowtime = secs; - unsigned int BCD_yr, BCD_mon, BCD_day, BCD_hr, BCD_min, BCD_sec; - - spin_lock_irqsave(&rtc_lock, flags); - - rs5c313_get_cmos_time - (&BCD_yr, &BCD_mon, &BCD_day, &BCD_hr, &BCD_min, &BCD_sec); - cmos_minutes = BCD_min; - BCD_TO_BIN(cmos_minutes); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - BIN_TO_BCD(real_seconds); - BIN_TO_BCD(real_minutes); - rs5c313_set_cmos_time(BCD_yr, BCD_mon, BCD_day, BCD_hr, - real_minutes, real_seconds); - } else { - printk(KERN_WARNING - "set_rtc_time: can't update from %d to %d\n", - cmos_minutes, real_minutes); - retval = -1; - } - - spin_unlock_irqrestore(&rtc_lock, flags); - return retval; -} - -void landisk_time_init(void) -{ - rtc_sh_get_time = landisk_rtc_gettimeofday; - rtc_sh_set_time = landisk_rtc_settimeofday; -} diff --git a/trunk/arch/sh/boards/landisk/setup.c b/trunk/arch/sh/boards/landisk/setup.c deleted file mode 100644 index 127b9e020e00..000000000000 --- a/trunk/arch/sh/boards/landisk/setup.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * arch/sh/boards/landisk/setup.c - * - * Copyright (C) 2000 Kazumoto Kojima - * Copyright (C) 2002 Paul Mundt - * - * I-O DATA Device, Inc. LANDISK Support. - * - * Modified for LANDISK by - * Atom Create Engineering Co., Ltd. 2002. - * - * modifed by kogiidena - * 2005.09.16 - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -void landisk_time_init(void); -void init_landisk_IRQ(void); - -int landisk_ledparam; -int landisk_buzzerparam; -int landisk_arch; - -/* cycle the led's in the clasic knightrider/sun pattern */ -static void heartbeat_landisk(void) -{ - static unsigned int cnt = 0, blink = 0x00, period = 25; - volatile u8 *p = (volatile u8 *)PA_LED; - char data; - - if ((landisk_ledparam & 0x080) == 0) - return; - - cnt += 1; - - if (cnt < period) - return; - - cnt = 0; - blink++; - - data = (blink & 0x01) ? (landisk_ledparam >> 16) : 0; - data |= (blink & 0x02) ? (landisk_ledparam >> 8) : 0; - data |= landisk_ledparam; - - /* buzzer */ - if (landisk_buzzerparam & 0x1) { - data |= 0x80; - } else { - data &= 0x7f; - } - *p = data; - - if (((landisk_ledparam & 0x007f7f00) == 0) && - (landisk_buzzerparam == 0)) - landisk_ledparam &= (~0x0080); - - landisk_buzzerparam >>= 1; -} - -static void landisk_power_off(void) -{ - ctrl_outb(0x01, PA_SHUTDOWN); -} - -static void check_usl5p(void) -{ - volatile u8 *p = (volatile u8 *)PA_LED; - u8 tmp1, tmp2; - - tmp1 = *p; - *p = 0x40; - tmp2 = *p; - *p = tmp1; - - landisk_arch = (tmp2 == 0x40); - if (landisk_arch == 1) { - /* arch == usl-5p */ - landisk_ledparam = 0x00000380; - landisk_ledparam |= (tmp1 & 0x07c); - } else { - /* arch == landisk */ - landisk_ledparam = 0x02000180; - landisk_ledparam |= 0x04; - } -} - -void *area5_io_base; -void *area6_io_base; - -static int __init landisk_cf_init(void) -{ - pgprot_t prot; - unsigned long paddrbase, psize; - - /* open I/O area window */ - paddrbase = virt_to_phys((void *)PA_AREA5_IO); - psize = PAGE_SIZE; - prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16); - area5_io_base = p3_ioremap(paddrbase, psize, prot.pgprot); - if (!area5_io_base) { - printk("allocate_cf_area : can't open CF I/O window!\n"); - return -ENOMEM; - } - - paddrbase = virt_to_phys((void *)PA_AREA6_IO); - psize = PAGE_SIZE; - prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16); - area6_io_base = p3_ioremap(paddrbase, psize, prot.pgprot); - if (!area6_io_base) { - printk("allocate_cf_area : can't open HDD I/O window!\n"); - return -ENOMEM; - } - - printk(KERN_INFO "Allocate Area5/6 success.\n"); - - /* XXX : do we need attribute and common-memory area also? */ - - return 0; -} - -static void __init landisk_setup(char **cmdline_p) -{ - device_initcall(landisk_cf_init); - - landisk_buzzerparam = 0; - check_usl5p(); - - printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n"); - - board_time_init = landisk_time_init; - pm_power_off = landisk_power_off; -} - -/* - * The Machine Vector - */ -struct sh_machine_vector mv_landisk __initmv = { - .mv_name = "LANDISK", - .mv_setup = landisk_setup, - .mv_nr_irqs = 72, - .mv_inb = landisk_inb, - .mv_inw = landisk_inw, - .mv_inl = landisk_inl, - .mv_outb = landisk_outb, - .mv_outw = landisk_outw, - .mv_outl = landisk_outl, - .mv_inb_p = landisk_inb_p, - .mv_inw_p = landisk_inw, - .mv_inl_p = landisk_inl, - .mv_outb_p = landisk_outb_p, - .mv_outw_p = landisk_outw, - .mv_outl_p = landisk_outl, - .mv_insb = landisk_insb, - .mv_insw = landisk_insw, - .mv_insl = landisk_insl, - .mv_outsb = landisk_outsb, - .mv_outsw = landisk_outsw, - .mv_outsl = landisk_outsl, - .mv_ioport_map = landisk_ioport_map, - .mv_init_irq = init_landisk_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_landisk, -#endif -}; -ALIAS_MV(landisk) diff --git a/trunk/arch/sh/boards/mpc1211/rtc.c b/trunk/arch/sh/boards/mpc1211/rtc.c index 03b123a4bba4..a76c655dceee 100644 --- a/trunk/arch/sh/boards/mpc1211/rtc.c +++ b/trunk/arch/sh/boards/mpc1211/rtc.c @@ -130,7 +130,7 @@ int mpc1211_rtc_settimeofday(const struct timeval *tv) void mpc1211_time_init(void) { - rtc_sh_get_time = mpc1211_rtc_gettimeofday; - rtc_sh_set_time = mpc1211_rtc_settimeofday; + rtc_get_time = mpc1211_rtc_gettimeofday; + rtc_set_time = mpc1211_rtc_settimeofday; } diff --git a/trunk/arch/sh/boards/mpc1211/setup.c b/trunk/arch/sh/boards/mpc1211/setup.c index 8eb5d4303972..2bfb221cc35c 100644 --- a/trunk/arch/sh/boards/mpc1211/setup.c +++ b/trunk/arch/sh/boards/mpc1211/setup.c @@ -10,12 +10,14 @@ #include #include #include + #include #include #include #include #include + /* ALI15X3 SMBus address offsets */ #define SMBHSTSTS (0 + 0x3100) #define SMBHSTCNT (1 + 0x3100) @@ -48,6 +50,11 @@ #define ALI15X3_STS_TERM 0x80 /* terminated by abort */ #define ALI15X3_STS_ERR 0xE0 /* all the bad error bits */ +const char *get_system_type(void) +{ + return "Interface MPC-1211(CTP/PCI/MPC-SH02)"; +} + static void __init pci_write_config(unsigned long busNo, unsigned long devNo, unsigned long fncNo, @@ -73,6 +80,9 @@ volatile unsigned long irq_err_count; static void disable_mpc1211_irq(unsigned int irq) { + unsigned long flags; + + save_and_cli(flags); if( irq < 8) { m_irq_mask |= (1 << irq); outb(m_irq_mask,I8259_M_MR); @@ -80,11 +90,16 @@ static void disable_mpc1211_irq(unsigned int irq) s_irq_mask |= (1 << (irq - 8)); outb(s_irq_mask,I8259_S_MR); } + restore_flags(flags); } static void enable_mpc1211_irq(unsigned int irq) { + unsigned long flags; + + save_and_cli(flags); + if( irq < 8) { m_irq_mask &= ~(1 << irq); outb(m_irq_mask,I8259_M_MR); @@ -92,6 +107,7 @@ static void enable_mpc1211_irq(unsigned int irq) s_irq_mask &= ~(1 << (irq - 8)); outb(s_irq_mask,I8259_S_MR); } + restore_flags(flags); } static inline int mpc1211_irq_real(unsigned int irq) @@ -115,6 +131,10 @@ static inline int mpc1211_irq_real(unsigned int irq) static void mask_and_ack_mpc1211(unsigned int irq) { + unsigned long flags; + + save_and_cli(flags); + if(irq < 8) { if(m_irq_mask & (1< +#include +#include +#include +#include +#include +#include + + +#include +#include +#include + +#define FPGA_NotConfigHigh() (*FPGA_ControlReg) = (*FPGA_ControlReg) | ENABLE_FPGA_BIT +#define FPGA_NotConfigLow() (*FPGA_ControlReg) = (*FPGA_ControlReg) & RESET_FPGA_MASK + +/* I need to find out what (if any) the real delay factor here is */ +/* The delay is definately not critical */ +#define long_delay() {int i;for(i=0;i<10000;i++);} +#define short_delay() {int i;for(i=0;i<100;i++);} + +static void __init program_overdrive_fpga(const unsigned char *fpgacode, + int size) +{ + int timeout = 0; + int i, j; + unsigned char b; + static volatile unsigned char *FPGA_ControlReg = + (volatile unsigned char *) (OVERDRIVE_CTRL); + static volatile unsigned char *FPGA_ProgramReg = + (volatile unsigned char *) (FPGA_DCLK_ADDRESS); + + printk("FPGA: Commencing FPGA Programming\n"); + + /* The PCI reset but MUST be low when programming the FPGA !!! */ + b = (*FPGA_ControlReg) & RESET_PCI_MASK; + + (*FPGA_ControlReg) = b; + + /* Prepare FPGA to program */ + + FPGA_NotConfigHigh(); + long_delay(); + + FPGA_NotConfigLow(); + short_delay(); + + while ((*FPGA_ProgramReg & FPGA_NOT_STATUS) != 0) { + printk("FPGA: Waiting for NotStatus to go Low ... \n"); + } + + FPGA_NotConfigHigh(); + + /* Wait for FPGA "ready to be programmed" signal */ + printk("FPGA: Waiting for NotStatus to go high (FPGA ready)... \n"); + + for (timeout = 0; + (((*FPGA_ProgramReg & FPGA_NOT_STATUS) == 0) + && (timeout < FPGA_TIMEOUT)); timeout++); + + /* Check if timeout condition occured - i.e. an error */ + + if (timeout == FPGA_TIMEOUT) { + printk + ("FPGA: Failed to program - Timeout waiting for notSTATUS to go high\n"); + return; + } + + printk("FPGA: Copying data to FPGA ... %d bytes\n", size); + + /* Copy array to FPGA - bit at a time */ + + for (i = 0; i < size; i++) { + volatile unsigned w = 0; + + for (j = 0; j < 8; j++) { + *FPGA_ProgramReg = (fpgacode[i] >> j) & 0x01; + short_delay(); + } + if ((i & 0x3ff) == 0) { + printk("."); + } + } + + /* Waiting for CONFDONE to go high - means the program is complete */ + + for (timeout = 0; + (((*FPGA_ProgramReg & FPGA_CONFDONE) == 0) + && (timeout < FPGA_TIMEOUT)); timeout++) { + + *FPGA_ProgramReg = 0x0; + long_delay(); + } + + if (timeout == FPGA_TIMEOUT) { + printk + ("FPGA: Failed to program - Timeout waiting for CONFDONE to go high\n"); + return; + } else { /* Clock another 10 times - gets the device into a working state */ + for (i = 0; i < 10; i++) { + *FPGA_ProgramReg = 0x0; + short_delay(); + } + } + + printk("FPGA: Programming complete\n"); +} + + +static const unsigned char __init fpgacode[] = { +#include "./overdrive.ttf" /* Code from maxplus2 compiler */ + , 0, 0 +}; + + +int __init init_overdrive_fpga(void) +{ + program_overdrive_fpga(fpgacode, sizeof(fpgacode)); + + return 0; +} diff --git a/trunk/arch/sh/boards/overdrive/galileo.c b/trunk/arch/sh/boards/overdrive/galileo.c new file mode 100644 index 000000000000..29e48971bba0 --- /dev/null +++ b/trunk/arch/sh/boards/overdrive/galileo.c @@ -0,0 +1,587 @@ +/* + * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains the PCI routines required for the Galileo GT6411 + * PCI bridge as used on the Orion and Overdrive boards. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +/* After boot, we shift the Galileo registers so that they appear + * in BANK6, along with IO space. This means we can have one contingous + * lump of PCI address space without these registers appearing in the + * middle of them + */ + +#define GT64111_BASE_ADDRESS 0xbb000000 +#define GT64111_IO_BASE_ADDRESS 0x1000 +/* The GT64111 registers appear at this address to the SH4 after reset */ +#define RESET_GT64111_BASE_ADDRESS 0xb4000000 + +/* Macros used to access the Galileo registers */ +#define RESET_GT64111_REG(x) (RESET_GT64111_BASE_ADDRESS+x) +#define GT64111_REG(x) (GT64111_BASE_ADDRESS+x) + +#define RESET_GT_WRITE(x,v) writel((v),RESET_GT64111_REG(x)) + +#define RESET_GT_READ(x) readl(RESET_GT64111_REG(x)) + +#define GT_WRITE(x,v) writel((v),GT64111_REG(x)) +#define GT_WRITE_BYTE(x,v) writeb((v),GT64111_REG(x)) +#define GT_WRITE_SHORT(x,v) writew((v),GT64111_REG(x)) + +#define GT_READ(x) readl(GT64111_REG(x)) +#define GT_READ_BYTE(x) readb(GT64111_REG(x)) +#define GT_READ_SHORT(x) readw(GT64111_REG(x)) + + +/* Where the various SH banks start at */ +#define SH_BANK4_ADR 0xb0000000 +#define SH_BANK5_ADR 0xb4000000 +#define SH_BANK6_ADR 0xb8000000 + +/* Masks out everything but lines 28,27,26 */ +#define BANK_SELECT_MASK 0x1c000000 + +#define SH4_TO_BANK(x) ( (x) & BANK_SELECT_MASK) + +/* + * Masks used for address conversaion. Bank 6 is used for IO and + * has all the address bits zeroed by the FPGA. Special case this + */ +#define MEMORY_BANK_MASK 0x1fffffff +#define IO_BANK_MASK 0x03ffffff + +/* Mark bank 6 as the bank used for IO. You can change this in the FPGA code + * if you want + */ +#define IO_BANK_ADR PCI_GTIO_BASE + +/* Will select the correct mask to apply depending on the SH$ address */ +#define SELECT_BANK_MASK(x) \ + ( (SH4_TO_BANK(x)==SH4_TO_BANK(IO_BANK_ADR)) ? IO_BANK_MASK : MEMORY_BANK_MASK) + +/* Converts between PCI space and P2 region */ +#define SH4_TO_PCI(x) ((x)&SELECT_BANK_MASK(x)) + +/* Various macros for figuring out what to stick in the Galileo registers. + * You *really* don't want to figure this stuff out by hand, you always get + * it wrong + */ +#define GT_MEM_LO_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7ff) +#define GT_MEM_HI_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>21)&0x7f) +#define GT_MEM_SUB_ADR(x) ((((unsigned)((x)&SELECT_BANK_MASK(x)))>>20)&0xff) + +#define PROGRAM_HI_LO(block,a,s) \ + GT_WRITE(block##_LO_DEC_ADR,GT_MEM_LO_ADR(a));\ + GT_WRITE(block##_HI_DEC_ADR,GT_MEM_HI_ADR(a+s-1)) + +#define PROGRAM_SUB_HI_LO(block,a,s) \ + GT_WRITE(block##_LO_DEC_ADR,GT_MEM_SUB_ADR(a));\ + GT_WRITE(block##_HI_DEC_ADR,GT_MEM_SUB_ADR(a+s-1)) + +/* We need to set the size, and the offset register */ + +#define GT_BAR_MASK(x) ((x)&~0xfff) + +/* Macro to set up the BAR in the Galileo. Essentially used for the DRAM */ +#define PROGRAM_GT_BAR(block,a,s) \ + GT_WRITE(PCI_##block##_BANK_SIZE,GT_BAR_MASK((s-1)));\ + write_config_to_galileo(PCI_CONFIG_##block##_BASE_ADR,\ + GT_BAR_MASK(a)) + +#define DISABLE_GT_BAR(block) \ + GT_WRITE(PCI_##block##_BANK_SIZE,0),\ + GT_CONFIG_WRITE(PCI_CONFIG_##block##_BASE_ADR,\ + 0x80000000) + +/* Macros to disable things we are not going to use */ +#define DISABLE_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0x7ff);\ + GT_WRITE(x##_HI_DEC_ADR,0x00) + +#define DISABLE_SUB_DECODE(x) GT_WRITE(x##_LO_DEC_ADR,0xff);\ + GT_WRITE(x##_HI_DEC_ADR,0x00) + +static void __init reset_pci(void) +{ + /* Set RESET_PCI bit high */ + writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL); + udelay(250); + + /* Set RESET_PCI bit low */ + writeb(readb(OVERDRIVE_CTRL) & RESET_PCI_MASK, OVERDRIVE_CTRL); + udelay(250); + + writeb(readb(OVERDRIVE_CTRL) | ENABLE_PCI_BIT, OVERDRIVE_CTRL); + udelay(250); +} + +static int write_config_to_galileo(int where, u32 val); +#define GT_CONFIG_WRITE(where,val) write_config_to_galileo(where,val) + +#define ENABLE_PCI_DRAM + + +#ifdef TEST_DRAM +/* Test function to check out if the PCI DRAM is working OK */ +static int /* __init */ test_dram(unsigned *base, unsigned size) +{ + unsigned *p = base; + unsigned *end = (unsigned *) (((unsigned) base) + size); + unsigned w; + + for (p = base; p < end; p++) { + *p = 0xffffffff; + if (*p != 0xffffffff) { + printk("AAARGH -write failed!!! at %p is %x\n", p, + *p); + return 0; + } + *p = 0x0; + if (*p != 0x0) { + printk("AAARGH -write failed!!!\n"); + return 0; + } + } + + for (p = base; p < end; p++) { + *p = (unsigned) p; + if (*p != (unsigned) p) { + printk("Failed at 0x%p, actually is 0x%x\n", p, + *p); + return 0; + } + } + + for (p = base; p < end; p++) { + w = ((unsigned) p & 0xffff0000); + *p = w | (w >> 16); + } + + for (p = base; p < end; p++) { + w = ((unsigned) p & 0xffff0000); + w |= (w >> 16); + if (*p != w) { + printk + ("Failed at 0x%p, should be 0x%x actually is 0x%x\n", + p, w, *p); + return 0; + } + } + + return 1; +} +#endif + + +/* Function to set up and initialise the galileo. This sets up the BARS, + * maps the DRAM into the address space etc,etc + */ +int __init galileo_init(void) +{ + reset_pci(); + + /* Now shift the galileo regs into this block */ + RESET_GT_WRITE(INTERNAL_SPACE_DEC, + GT_MEM_LO_ADR(GT64111_BASE_ADDRESS)); + + /* Should have a sanity check here, that you can read back at the new + * address what you just wrote + */ + + /* Disable decode for all regions */ + DISABLE_DECODE(RAS10); + DISABLE_DECODE(RAS32); + DISABLE_DECODE(CS20); + DISABLE_DECODE(CS3); + DISABLE_DECODE(PCI_IO); + DISABLE_DECODE(PCI_MEM0); + DISABLE_DECODE(PCI_MEM1); + + /* Disable all BARS */ + GT_WRITE(BAR_ENABLE_ADR, 0x1ff); + DISABLE_GT_BAR(RAS10); + DISABLE_GT_BAR(RAS32); + DISABLE_GT_BAR(CS20); + DISABLE_GT_BAR(CS3); + + /* Tell the BAR where the IO registers now are */ + GT_CONFIG_WRITE(PCI_CONFIG_INT_REG_IO_ADR,GT_BAR_MASK( + (GT64111_IO_BASE_ADDRESS & + IO_BANK_MASK))); + /* set up a 112 Mb decode */ + PROGRAM_HI_LO(PCI_MEM0, SH_BANK4_ADR, 112 * 1024 * 1024); + + /* Set up a 32 MB io space decode */ + PROGRAM_HI_LO(PCI_IO, IO_BANK_ADR, 32 * 1024 * 1024); + +#ifdef ENABLE_PCI_DRAM + /* Program up the DRAM configuration - there is DRAM only in bank 0 */ + /* Now set up the DRAM decode */ + PROGRAM_HI_LO(RAS10, PCI_DRAM_BASE, PCI_DRAM_SIZE); + /* And the sub decode */ + PROGRAM_SUB_HI_LO(RAS0, PCI_DRAM_BASE, PCI_DRAM_SIZE); + + DISABLE_SUB_DECODE(RAS1); + + /* Set refresh rate */ + GT_WRITE(DRAM_BANK0_PARMS, 0x3f); + GT_WRITE(DRAM_CFG, 0x100); + + /* we have to lob off the top bits rememeber!! */ + PROGRAM_GT_BAR(RAS10, SH4_TO_PCI(PCI_DRAM_BASE), PCI_DRAM_SIZE); + +#endif + + /* We are only interested in decoding RAS10 and the Galileo's internal + * registers (as IO) on the PCI bus + */ +#ifdef ENABLE_PCI_DRAM + GT_WRITE(BAR_ENABLE_ADR, (~((1 << 8) | (1 << 3))) & 0x1ff); +#else + GT_WRITE(BAR_ENABLE_ADR, (~(1 << 3)) & 0x1ff); +#endif + + /* Change the class code to host bridge, it actually powers up + * as a memory controller + */ + GT_CONFIG_WRITE(8, 0x06000011); + + /* Allow the galileo to master the PCI bus */ + GT_CONFIG_WRITE(PCI_COMMAND, + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | + PCI_COMMAND_IO); + + +#if 0 + printk("Testing PCI DRAM - "); + if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) { + printk("Passed\n"); + }else { + printk("FAILED\n"); + } +#endif + return 0; + +} + + +#define SET_CONFIG_BITS(bus,devfn,where)\ + ((1<<31) | ((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) + +#define CONFIG_CMD(dev, where) SET_CONFIG_BITS((dev)->bus->number,(dev)->devfn,where) + +/* This write to the galileo config registers, unlike the functions below, can + * be used before the PCI subsystem has started up + */ +static int __init write_config_to_galileo(int where, u32 val) +{ + GT_WRITE(PCI_CFG_ADR, SET_CONFIG_BITS(0, 0, where)); + + GT_WRITE(PCI_CFG_DATA, val); + return 0; +} + +/* We exclude the galileo and slot 31, the galileo because I don't know how to stop + * the setup code shagging up the setup I have done on it, and 31 because the whole + * thing locks up if you try to access that slot (which doesn't exist of course anyway + */ + +#define EXCLUDED_DEV(dev) ((dev->bus->number==0) && ((PCI_SLOT(dev->devfn)==0) || (PCI_SLOT(dev->devfn) == 31))) + +static int galileo_read_config_byte(struct pci_dev *dev, int where, + u8 * val) +{ + + + /* I suspect this doesn't work because this drives a special cycle ? */ + if (EXCLUDED_DEV(dev)) { + *val = 0xff; + return PCIBIOS_SUCCESSFUL; + } + /* Start the config cycle */ + GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); + /* Read back the result */ + *val = GT_READ_BYTE(PCI_CFG_DATA + (where & 3)); + + return PCIBIOS_SUCCESSFUL; +} + + +static int galileo_read_config_word(struct pci_dev *dev, int where, + u16 * val) +{ + + if (EXCLUDED_DEV(dev)) { + *val = 0xffff; + return PCIBIOS_SUCCESSFUL; + } + + GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); + *val = GT_READ_SHORT(PCI_CFG_DATA + (where & 2)); + + return PCIBIOS_SUCCESSFUL; +} + + +static int galileo_read_config_dword(struct pci_dev *dev, int where, + u32 * val) +{ + if (EXCLUDED_DEV(dev)) { + *val = 0xffffffff; + return PCIBIOS_SUCCESSFUL; + } + + GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); + *val = GT_READ(PCI_CFG_DATA); + + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_write_config_byte(struct pci_dev *dev, int where, + u8 val) +{ + GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); + + GT_WRITE_BYTE(PCI_CFG_DATA + (where & 3), val); + + return PCIBIOS_SUCCESSFUL; +} + + +static int galileo_write_config_word(struct pci_dev *dev, int where, + u16 val) +{ + GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); + + GT_WRITE_SHORT(PCI_CFG_DATA + (where & 2), val); + + return PCIBIOS_SUCCESSFUL; +} + +static int galileo_write_config_dword(struct pci_dev *dev, int where, + u32 val) +{ + GT_WRITE(PCI_CFG_ADR, CONFIG_CMD(dev, where)); + + GT_WRITE(PCI_CFG_DATA, val); + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops pci_config_ops = { + galileo_read_config_byte, + galileo_read_config_word, + galileo_read_config_dword, + galileo_write_config_byte, + galileo_write_config_word, + galileo_write_config_dword +}; + + +/* Everything hangs off this */ +static struct pci_bus *pci_root_bus; + + +static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin) +{ + return PCI_SLOT(dev->devfn); +} + +static int __init map_od_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + /* Slot 1: Galileo + * Slot 2: PCI Slot 1 + * Slot 3: PCI Slot 2 + * Slot 4: ESS + */ + switch (slot) { + case 2: + return OVERDRIVE_PCI_IRQ1; + case 3: + /* Note this assumes you have a hacked card in slot 2 */ + return OVERDRIVE_PCI_IRQ2; + case 4: + return OVERDRIVE_ESS_IRQ; + default: + /* printk("PCI: Unexpected IRQ mapping request for slot %d\n", slot); */ + return -1; + } +} + + + +void __init +pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges) +{ + ranges->io_start -= bus->resource[0]->start; + ranges->io_end -= bus->resource[0]->start; + ranges->mem_start -= bus->resource[1]->start; + ranges->mem_end -= bus->resource[1]->start; +} + +static void __init pci_fixup_ide_bases(struct pci_dev *d) +{ + int i; + + /* + * PCI IDE controllers use non-standard I/O port decoding, respect it. + */ + if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) + return; + printk("PCI: IDE base address fixup for %s\n", pci_name(d)); + for(i=0; i<4; i++) { + struct resource *r = &d->resource[i]; + if ((r->start & ~0x80) == 0x374) { + r->start |= 2; + r->end = r->start; + } + } +} +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); + +void __init pcibios_init(void) +{ + static struct resource galio,galmem; + + /* Allocate the registers used by the Galileo */ + galio.flags = IORESOURCE_IO; + galio.name = "Galileo GT64011"; + galmem.flags = IORESOURCE_MEM|IORESOURCE_PREFETCH; + galmem.name = "Galileo GT64011 DRAM"; + + allocate_resource(&ioport_resource, &galio, 256, + GT64111_IO_BASE_ADDRESS,GT64111_IO_BASE_ADDRESS+256, 256, NULL, NULL); + allocate_resource(&iomem_resource, &galmem,PCI_DRAM_SIZE, + PHYSADDR(PCI_DRAM_BASE), PHYSADDR(PCI_DRAM_BASE)+PCI_DRAM_SIZE, + PCI_DRAM_SIZE, NULL, NULL); + + /* ok, do the scan man */ + pci_root_bus = pci_scan_bus(0, &pci_config_ops, NULL); + + pci_assign_unassigned_resources(); + pci_fixup_irqs(no_swizzle, map_od_irq); + +#ifdef TEST_DRAM + printk("Testing PCI DRAM - "); + if(test_dram(PCI_DRAM_BASE,PCI_DRAM_SIZE)) { + printk("Passed\n"); + }else { + printk("FAILED\n"); + } +#endif + +} + +char * __init pcibios_setup(char *str) +{ + return str; +} + + + +int pcibios_enable_device(struct pci_dev *dev) +{ + + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for (idx = 0; idx < 6; idx++) { + r = dev->resource + idx; + if (!r->start && r->end) { + printk(KERN_ERR + "PCI: Device %s not available because" + " of resource collisions\n", + pci_name(dev)); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + printk("PCI: enabling device %s (%04x -> %04x)\n", + pci_name(dev), old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; + +} + +/* We should do some optimisation work here I think. Ok for now though */ +void __init pcibios_fixup_bus(struct pci_bus *bus) +{ + +} + +void pcibios_align_resource(void *data, struct resource *res, + resource_size_t size) +{ +} + +void __init pcibios_update_resource(struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) +{ + + unsigned long where, size; + u32 reg; + + + printk("PCI: Assigning %3s %08lx to %s\n", + res->flags & IORESOURCE_IO ? "IO" : "MEM", + res->start, dev->name); + + where = PCI_BASE_ADDRESS_0 + resource * 4; + size = res->end - res->start; + + pci_read_config_dword(dev, where, ®); + reg = (reg & size) | (((u32) (res->start - root->start)) & ~size); + pci_write_config_dword(dev, where, reg); +} + + +void __init pcibios_update_irq(struct pci_dev *dev, int irq) +{ + printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); +} + +/* + * If we set up a device for bus mastering, we need to check the latency + * timer as certain crappy BIOSes forget to set it properly. + */ +unsigned int pcibios_max_latency = 255; + +void pcibios_set_master(struct pci_dev *dev) +{ + u8 lat; + pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); + if (lat < 16) + lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; + else if (lat > pcibios_max_latency) + lat = pcibios_max_latency; + else + return; + printk("PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); +} diff --git a/trunk/arch/sh/boards/overdrive/io.c b/trunk/arch/sh/boards/overdrive/io.c new file mode 100644 index 000000000000..4671b6b047bb --- /dev/null +++ b/trunk/arch/sh/boards/overdrive/io.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains the I/O routines for use on the overdrive board + * + */ + +#include +#include +#include +#include +#include + +#include + +/* + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the SuperH architecture, we just read/write the + * memory location directly. + */ + +#define dprintk(x...) + +/* Translates an IO address to where it is mapped in memory */ + +#define io_addr(x) (((unsigned)(x))|PCI_GTIO_BASE) + +unsigned char od_inb(unsigned long port) +{ +dprintk("od_inb(%x)\n", port); + return readb(io_addr(port)) & 0xff; +} + + +unsigned short od_inw(unsigned long port) +{ +dprintk("od_inw(%x)\n", port); + return readw(io_addr(port)) & 0xffff; +} + +unsigned int od_inl(unsigned long port) +{ +dprintk("od_inl(%x)\n", port); + return readl(io_addr(port)); +} + +void od_outb(unsigned char value, unsigned long port) +{ +dprintk("od_outb(%x, %x)\n", value, port); + writeb(value, io_addr(port)); +} + +void od_outw(unsigned short value, unsigned long port) +{ +dprintk("od_outw(%x, %x)\n", value, port); + writew(value, io_addr(port)); +} + +void od_outl(unsigned int value, unsigned long port) +{ +dprintk("od_outl(%x, %x)\n", value, port); + writel(value, io_addr(port)); +} + +/* This is horrible at the moment - needs more work to do something sensible */ +#define IO_DELAY() udelay(10) + +#define OUT_DELAY(x,type) \ +void od_out##x##_p(unsigned type value,unsigned long port){out##x(value,port);IO_DELAY();} + +#define IN_DELAY(x,type) \ +unsigned type od_in##x##_p(unsigned long port) {unsigned type tmp=in##x(port);IO_DELAY();return tmp;} + + +OUT_DELAY(b,char) +OUT_DELAY(w,short) +OUT_DELAY(l,int) + +IN_DELAY(b,char) +IN_DELAY(w,short) +IN_DELAY(l,int) + + +/* Now for the string version of these functions */ +void od_outsb(unsigned long port, const void *addr, unsigned long count) +{ + int i; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p++) { + outb(*p, port); + } +} + + +void od_insb(unsigned long port, void *addr, unsigned long count) +{ + int i; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p++) { + *p = inb(port); + } +} + +/* For the 16 and 32 bit string functions, we have to worry about alignment. + * The SH does not do unaligned accesses, so we have to read as bytes and + * then write as a word or dword. + * This can be optimised a lot more, especially in the case where the data + * is aligned + */ + +void od_outsw(unsigned long port, const void *addr, unsigned long count) +{ + int i; + unsigned short tmp; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p += 2) { + tmp = (*p) | ((*(p + 1)) << 8); + outw(tmp, port); + } +} + + +void od_insw(unsigned long port, void *addr, unsigned long count) +{ + int i; + unsigned short tmp; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p += 2) { + tmp = inw(port); + p[0] = tmp & 0xff; + p[1] = (tmp >> 8) & 0xff; + } +} + + +void od_outsl(unsigned long port, const void *addr, unsigned long count) +{ + int i; + unsigned tmp; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p += 4) { + tmp = (*p) | ((*(p + 1)) << 8) | ((*(p + 2)) << 16) | + ((*(p + 3)) << 24); + outl(tmp, port); + } +} + + +void od_insl(unsigned long port, void *addr, unsigned long count) +{ + int i; + unsigned tmp; + unsigned char *p = (unsigned char *) addr; + + for (i = 0; i < count; i++, p += 4) { + tmp = inl(port); + p[0] = tmp & 0xff; + p[1] = (tmp >> 8) & 0xff; + p[2] = (tmp >> 16) & 0xff; + p[3] = (tmp >> 24) & 0xff; + + } +} diff --git a/trunk/arch/sh/boards/overdrive/irq.c b/trunk/arch/sh/boards/overdrive/irq.c new file mode 100644 index 000000000000..5d730c70389e --- /dev/null +++ b/trunk/arch/sh/boards/overdrive/irq.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Looks after interrupts on the overdrive board. + * + * Bases on the IPR irq system + */ + +#include +#include + +#include +#include + +#include + +struct od_data { + int overdrive_irq; + int irq_mask; +}; + +#define NUM_EXTERNAL_IRQS 16 +#define EXTERNAL_IRQ_NOT_IN_USE (-1) +#define EXTERNAL_IRQ_NOT_ASSIGNED (-1) + +/* + * This table is used to determine what to program into the FPGA's CT register + * for the specified Linux IRQ. + * + * The irq_mask gives the interrupt number from the PCI board (PCI_Int(6:0)) + * but is one greater than that because the because the FPGA treats 0 + * as disabled, a value of 1 asserts PCI_Int0, and so on. + * + * The overdrive_irq specifies which of the eight interrupt sources generates + * that interrupt, and but is multiplied by four to give the bit offset into + * the CT register. + * + * The seven interrupts levels (SH4 IRL's) we have available here is hardwired + * by the EPLD. The assignments here of which PCI interrupt generates each + * level is arbitary. + */ +static struct od_data od_data_table[NUM_EXTERNAL_IRQS] = { + /* overdrive_irq , irq_mask */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 0 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 7}, /* 1 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 6}, /* 2 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 3 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 5}, /* 4 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 5 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 6 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 4}, /* 7 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 8 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 9 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 3}, /* 10 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 2}, /* 11 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 12 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, 1}, /* 13 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE}, /* 14 */ + {EXTERNAL_IRQ_NOT_ASSIGNED, EXTERNAL_IRQ_NOT_IN_USE} /* 15 */ +}; + +static void set_od_data(int overdrive_irq, int irq) +{ + if (irq >= NUM_EXTERNAL_IRQS || irq < 0) + return; + od_data_table[irq].overdrive_irq = overdrive_irq << 2; +} + +static void enable_od_irq(unsigned int irq); +void disable_od_irq(unsigned int irq); + +/* shutdown is same as "disable" */ +#define shutdown_od_irq disable_od_irq + +static void mask_and_ack_od(unsigned int); +static void end_od_irq(unsigned int irq); + +static unsigned int startup_od_irq(unsigned int irq) +{ + enable_od_irq(irq); + return 0; /* never anything pending */ +} + +static struct hw_interrupt_type od_irq_type = { + .typename = "Overdrive-IRQ", + .startup = startup_od_irq, + .shutdown = shutdown_od_irq, + .enable = enable_od_irq, + .disable = disable_od_irq, + .ack = mask_and_ack_od, + .end = end_od_irq +}; + +static void disable_od_irq(unsigned int irq) +{ + unsigned val, flags; + int overdrive_irq; + unsigned mask; + + /* Not a valid interrupt */ + if (irq < 0 || irq >= NUM_EXTERNAL_IRQS) + return; + + /* Is is necessary to use a cli here? Would a spinlock not be + * mroe efficient? + */ + local_irq_save(flags); + overdrive_irq = od_data_table[irq].overdrive_irq; + if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) { + mask = ~(0x7 << overdrive_irq); + val = ctrl_inl(OVERDRIVE_INT_CT); + val &= mask; + ctrl_outl(val, OVERDRIVE_INT_CT); + } + local_irq_restore(flags); +} + +static void enable_od_irq(unsigned int irq) +{ + unsigned val, flags; + int overdrive_irq; + unsigned mask; + + /* Not a valid interrupt */ + if (irq < 0 || irq >= NUM_EXTERNAL_IRQS) + return; + + /* Set priority in OD back to original value */ + local_irq_save(flags); + /* This one is not in use currently */ + overdrive_irq = od_data_table[irq].overdrive_irq; + if (overdrive_irq != EXTERNAL_IRQ_NOT_ASSIGNED) { + val = ctrl_inl(OVERDRIVE_INT_CT); + mask = ~(0x7 << overdrive_irq); + val &= mask; + mask = od_data_table[irq].irq_mask << overdrive_irq; + val |= mask; + ctrl_outl(val, OVERDRIVE_INT_CT); + } + local_irq_restore(flags); +} + + + +/* this functions sets the desired irq handler to be an overdrive type */ +static void __init make_od_irq(unsigned int irq) +{ + disable_irq_nosync(irq); + irq_desc[irq].chip = &od_irq_type; + disable_od_irq(irq); +} + + +static void mask_and_ack_od(unsigned int irq) +{ + disable_od_irq(irq); +} + +static void end_od_irq(unsigned int irq) +{ + enable_od_irq(irq); +} + +void __init init_overdrive_irq(void) +{ + int i; + + /* Disable all interrupts */ + ctrl_outl(0, OVERDRIVE_INT_CT); + + /* Update interrupt pin mode to use encoded interrupts */ + i = ctrl_inw(INTC_ICR); + i &= ~INTC_ICR_IRLM; + ctrl_outw(i, INTC_ICR); + + for (i = 0; i < NUM_EXTERNAL_IRQS; i++) { + if (od_data_table[i].irq_mask != EXTERNAL_IRQ_NOT_IN_USE) { + make_od_irq(i); + } else if (i != 15) { // Cannot use imask on level 15 + make_imask_irq(i); + } + } + + /* Set up the interrupts */ + set_od_data(OVERDRIVE_PCI_INTA, OVERDRIVE_PCI_IRQ1); + set_od_data(OVERDRIVE_PCI_INTB, OVERDRIVE_PCI_IRQ2); + set_od_data(OVERDRIVE_AUDIO_INT, OVERDRIVE_ESS_IRQ); +} diff --git a/trunk/arch/sh/boards/overdrive/led.c b/trunk/arch/sh/boards/overdrive/led.c new file mode 100644 index 000000000000..860d7f204a4e --- /dev/null +++ b/trunk/arch/sh/boards/overdrive/led.c @@ -0,0 +1,58 @@ +/* + * linux/arch/sh/overdrive/led.c + * + * Copyright (C) 1999 Stuart Menefy + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * This file contains an Overdrive specific LED feature. + */ + +#include +#include +#include + +static void mach_led(int position, int value) +{ + unsigned long flags; + unsigned long reg; + + local_irq_save(flags); + + reg = readl(OVERDRIVE_CTRL); + if (value) { + reg |= (1<<3); + } else { + reg &= ~(1<<3); + } + writel(reg, OVERDRIVE_CTRL); + + local_irq_restore(flags); +} + +#ifdef CONFIG_HEARTBEAT + +#include + +/* acts like an actual heart beat -- ie thump-thump-pause... */ +void heartbeat_od(void) +{ + static unsigned cnt = 0, period = 0, dist = 0; + + if (cnt == 0 || cnt == dist) + mach_led( -1, 1); + else if (cnt == 7 || cnt == dist+7) + mach_led( -1, 0); + + if (++cnt > period) { + cnt = 0; + /* The hyperbolic function below modifies the heartbeat period + * length in dependency of the current (5min) load. It goes + * through the points f(0)=126, f(1)=86, f(5)=51, + * f(inf)->30. */ + period = ((672< + +#include +#include +#include + +#include +#include +#include + +void heartbeat_od(void); +void init_overdrive_irq(void); +void galileo_pcibios_init(void); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_od __initmv = { + .mv_nr_irqs = 48, + + .mv_inb = od_inb, + .mv_inw = od_inw, + .mv_inl = od_inl, + .mv_outb = od_outb, + .mv_outw = od_outw, + .mv_outl = od_outl, + + .mv_inb_p = od_inb_p, + .mv_inw_p = od_inw_p, + .mv_inl_p = od_inl_p, + .mv_outb_p = od_outb_p, + .mv_outw_p = od_outw_p, + .mv_outl_p = od_outl_p, + + .mv_insb = od_insb, + .mv_insw = od_insw, + .mv_insl = od_insl, + .mv_outsb = od_outsb, + .mv_outsw = od_outsw, + .mv_outsl = od_outsl, + +#ifdef CONFIG_PCI + .mv_init_irq = init_overdrive_irq, +#endif +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_od, +#endif +}; + +ALIAS_MV(od) diff --git a/trunk/arch/sh/boards/overdrive/pcidma.c b/trunk/arch/sh/boards/overdrive/pcidma.c new file mode 100644 index 000000000000..1c9bfeda00b7 --- /dev/null +++ b/trunk/arch/sh/boards/overdrive/pcidma.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2000 David J. Mckay (david.mckay@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Dynamic DMA mapping support. + * + * On the overdrive, we can only DMA from memory behind the PCI bus! + * this means that all DMA'able memory must come from there. + * this restriction will not apply to later boards. + */ + +#include +#include +#include +#include +#include + +void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t * dma_handle) +{ + void *ret; + int gfp = GFP_ATOMIC; + + printk("BUG: pci_alloc_consistent() called - not yet supported\n"); + /* We ALWAYS need DMA memory on the overdrive hardware, + * due to it's extreme weirdness + * Need to flush the cache here as well, since the memory + * can still be seen through the cache! + */ + gfp |= GFP_DMA; + ret = (void *) __get_free_pages(gfp, get_order(size)); + + if (ret != NULL) { + memset(ret, 0, size); + *dma_handle = virt_to_bus(ret); + } + return ret; +} + +void pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long) vaddr, get_order(size)); +} diff --git a/trunk/arch/sh/boards/overdrive/setup.c b/trunk/arch/sh/boards/overdrive/setup.c new file mode 100644 index 000000000000..a3a7744c2047 --- /dev/null +++ b/trunk/arch/sh/boards/overdrive/setup.c @@ -0,0 +1,36 @@ +/* + * arch/sh/overdrive/setup.c + * + * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * STMicroelectronics Overdrive Support. + */ + +#include +#include +#include + +#include +#include + +const char *get_system_type(void) +{ + return "SH7750 Overdrive"; +} + +/* + * Initialize the board + */ +int __init platform_setup(void) +{ +#ifdef CONFIG_PCI + init_overdrive_fpga(); + galileo_init(); +#endif + + /* Enable RS232 receive buffers */ + writel(0x1e, OVERDRIVE_CTRL); +} diff --git a/trunk/arch/sh/boards/renesas/edosk7705/Makefile b/trunk/arch/sh/boards/renesas/edosk7705/Makefile index 14bdd531f116..7fccbf2e4a1d 100644 --- a/trunk/arch/sh/boards/renesas/edosk7705/Makefile +++ b/trunk/arch/sh/boards/renesas/edosk7705/Makefile @@ -1,6 +1,10 @@ # # Makefile for the EDOSK7705 specific parts of the kernel # +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# obj-y := setup.o io.o diff --git a/trunk/arch/sh/boards/renesas/edosk7705/setup.c b/trunk/arch/sh/boards/renesas/edosk7705/setup.c index ec5be0107719..ba143fa4afaa 100644 --- a/trunk/arch/sh/boards/renesas/edosk7705/setup.c +++ b/trunk/arch/sh/boards/renesas/edosk7705/setup.c @@ -8,21 +8,19 @@ * Modified for edosk7705 development * board by S. Dunn, 2003. */ + #include #include +#include #include -static void __init sh_edosk7705_init_irq(void) -{ - /* This is the Ethernet interrupt */ - make_imask_irq(0x09); -} +static void init_edosk7705(void); /* * The Machine Vector */ + struct sh_machine_vector mv_edosk7705 __initmv = { - .mv_name = "EDOSK7705", .mv_nr_irqs = 80, .mv_inb = sh_edosk7705_inb, @@ -39,6 +37,23 @@ struct sh_machine_vector mv_edosk7705 __initmv = { .mv_outsl = sh_edosk7705_outsl, .mv_isa_port2addr = sh_edosk7705_isa_port2addr, - .mv_init_irq = sh_edosk7705_init_irq, + .mv_init_irq = init_edosk7705, }; ALIAS_MV(edosk7705) + +static void __init init_edosk7705(void) +{ + /* This is the Ethernet interrupt */ + make_imask_irq(0x09); +} + +const char *get_system_type(void) +{ + return "EDOSK7705"; +} + +void __init platform_setup(void) +{ + /* Nothing .. */ +} + diff --git a/trunk/arch/sh/boards/renesas/hs7751rvoip/Kconfig b/trunk/arch/sh/boards/renesas/hs7751rvoip/Kconfig deleted file mode 100644 index 1743be477be5..000000000000 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -if SH_HS7751RVOIP - -menu "HS7751RVoIP options" - -config HS7751RVOIP_CODEC - bool "Support VoIP Codec section" - help - Selecting this option will support CODEC section. - -endmenu - -endif diff --git a/trunk/arch/sh/boards/renesas/hs7751rvoip/Makefile b/trunk/arch/sh/boards/renesas/hs7751rvoip/Makefile index e626377c55ee..e8b4109ace11 100644 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/Makefile +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/Makefile @@ -1,8 +1,12 @@ # # Makefile for the HS7751RVoIP specific parts of the kernel # +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# -obj-y := setup.o io.o irq.o +obj-y := mach.o setup.o io.o irq.o led.o obj-$(CONFIG_PCI) += pci.o diff --git a/trunk/arch/sh/boards/renesas/hs7751rvoip/io.c b/trunk/arch/sh/boards/renesas/hs7751rvoip/io.c index 9ea1136b219b..3a1abfa2fefb 100644 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/io.c +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/io.c @@ -10,16 +10,21 @@ * placeholder code from io_hs7751rvoip.c left in with the * expectation of later SuperIO and PCMCIA access. */ + #include #include -#include -#include #include #include #include +#include +#include +#include "../../../drivers/pci/pci-sh7751.h" + +extern void *area5_io8_base; /* Area 5 8bit I/O Base address */ extern void *area6_io8_base; /* Area 6 8bit I/O Base address */ extern void *area5_io16_base; /* Area 5 16bit I/O Base address */ +extern void *area6_io16_base; /* Area 6 16bit I/O Base address */ /* * The 7751R HS7751RVoIP uses the built-in PCI controller (PCIC) @@ -28,8 +33,25 @@ extern void *area5_io16_base; /* Area 5 16bit I/O Base address */ * like the other Solution Engine boards. */ +#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) +#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) +#define PCI_IO_AREA SH7751_PCI_IO_BASE +#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE + +#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) + +#if defined(CONFIG_HS7751RVOIP_CODEC) #define CODEC_IO_BASE 0x1000 -#define CODEC_IOMAP(a) ((unsigned long)area6_io8_base + ((a) - CODEC_IO_BASE)) +#endif + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} static inline unsigned long port2adr(unsigned int port) { @@ -37,10 +59,9 @@ static inline unsigned long port2adr(unsigned int port) if (port == 0x3f6) return ((unsigned long)area5_io16_base + 0x0c); else - return ((unsigned long)area5_io16_base + 0x800 + - ((port-0x1f0) << 1)); + return ((unsigned long)area5_io16_base + 0x800 + ((port-0x1f0) << 1)); else - maybebadio((unsigned long)port); + maybebadio(port2adr, (unsigned long)port); return port; } @@ -57,10 +78,25 @@ static inline int shifted_port(unsigned long port) } #if defined(CONFIG_HS7751RVOIP_CODEC) -#define codec_port(port) \ - ((CODEC_IO_BASE <= (port)) && ((port) < (CODEC_IO_BASE + 0x20))) +static inline int +codec_port(unsigned long port) +{ + if (CODEC_IO_BASE <= port && port < (CODEC_IO_BASE+0x20)) + return 1; + else + return 0; +} +#endif + +/* In case someone configures the kernel w/o PCI support: in that */ +/* scenario, don't ever bother to check for PCI-window addresses */ + +/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ +#if defined(CONFIG_PCI) +#define CHECK_SH7751_PCIIO(port) \ + ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) #else -#define codec_port(port) (0) +#define CHECK_SH7751_PCIIO(port) (0) #endif /* @@ -73,13 +109,15 @@ static inline int shifted_port(unsigned long port) unsigned char hs7751rvoip_inb(unsigned long port) { if (PXSEG(port)) - return ctrl_inb(port); + return *(volatile unsigned char *)port; +#if defined(CONFIG_HS7751RVOIP_CODEC) else if (codec_port(port)) - return ctrl_inb(CODEC_IOMAP(port)); - else if (is_pci_ioaddr(port) || shifted_port(port)) - return ctrl_inb(pci_ioaddr(port)); + return *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned char *)PCI_IOMAP(port); else - return ctrl_inw(port2adr(port)) & 0xff; + return (*(volatile unsigned short *)port2adr(port) & 0xff); } unsigned char hs7751rvoip_inb_p(unsigned long port) @@ -87,36 +125,38 @@ unsigned char hs7751rvoip_inb_p(unsigned long port) unsigned char v; if (PXSEG(port)) - v = ctrl_inb(port); + v = *(volatile unsigned char *)port; +#if defined(CONFIG_HS7751RVOIP_CODEC) else if (codec_port(port)) - v = ctrl_inb(CODEC_IOMAP(port)); - else if (is_pci_ioaddr(port) || shifted_port(port)) - v = ctrl_inb(pci_ioaddr(port)); + v = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + v = *(volatile unsigned char *)PCI_IOMAP(port); else - v = ctrl_inw(port2adr(port)) & 0xff; - ctrl_delay(); + v = (*(volatile unsigned short *)port2adr(port) & 0xff); + delay(); return v; } unsigned short hs7751rvoip_inw(unsigned long port) { if (PXSEG(port)) - return ctrl_inw(port); - else if (is_pci_ioaddr(port) || shifted_port(port)) - return ctrl_inw(pci_ioaddr(port)); + return *(volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned short *)PCI_IOMAP(port); else - maybebadio(port); + maybebadio(inw, port); return 0; } unsigned int hs7751rvoip_inl(unsigned long port) { if (PXSEG(port)) - return ctrl_inl(port); - else if (is_pci_ioaddr(port) || shifted_port(port)) - return ctrl_inl(pci_ioaddr(port)); + return *(volatile unsigned long *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned long *)PCI_IOMAP(port); else - maybebadio(port); + maybebadio(inl, port); return 0; } @@ -124,160 +164,146 @@ void hs7751rvoip_outb(unsigned char value, unsigned long port) { if (PXSEG(port)) - ctrl_outb(value, port); + *(volatile unsigned char *)port = value; +#if defined(CONFIG_HS7751RVOIP_CODEC) else if (codec_port(port)) - ctrl_outb(value, CODEC_IOMAP(port)); - else if (is_pci_ioaddr(port) || shifted_port(port)) - ctrl_outb(value, pci_ioaddr(port)); + *(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value; +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(unsigned char *)PCI_IOMAP(port) = value; else - ctrl_outb(value, port2adr(port)); + *(volatile unsigned short *)port2adr(port) = value; } void hs7751rvoip_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) - ctrl_outb(value, port); + *(volatile unsigned char *)port = value; +#if defined(CONFIG_HS7751RVOIP_CODEC) else if (codec_port(port)) - ctrl_outb(value, CODEC_IOMAP(port)); - else if (is_pci_ioaddr(port) || shifted_port(port)) - ctrl_outb(value, pci_ioaddr(port)); + *(volatile unsigned cjar *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = value; +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(unsigned char *)PCI_IOMAP(port) = value; else - ctrl_outw(value, port2adr(port)); - - ctrl_delay(); + *(volatile unsigned short *)port2adr(port) = value; + delay(); } void hs7751rvoip_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) - ctrl_outw(value, port); - else if (is_pci_ioaddr(port) || shifted_port(port)) - ctrl_outw(value, pci_ioaddr(port)); + *(volatile unsigned short *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(unsigned short *)PCI_IOMAP(port) = value; else - maybebadio(port); + maybebadio(outw, port); } void hs7751rvoip_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) - ctrl_outl(value, port); - else if (is_pci_ioaddr(port) || shifted_port(port)) - ctrl_outl(value, pci_ioaddr(port)); + *(volatile unsigned long *)port = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *((unsigned long *)PCI_IOMAP(port)) = value; else - maybebadio(port); + maybebadio(outl, port); } void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count) { - u8 *buf = addr; - if (PXSEG(port)) - while (count--) - *buf++ = ctrl_inb(port); + while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port; +#if defined(CONFIG_HS7751RVOIP_CODEC) else if (codec_port(port)) - while (count--) - *buf++ = ctrl_inb(CODEC_IOMAP(port)); - else if (is_pci_ioaddr(port) || shifted_port(port)) { - volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); + while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)); +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u8 *bp = (__u8 *)PCI_IOMAP(port); - while (count--) - *buf++ = *bp; + while (count--) *((volatile unsigned char *) addr)++ = *bp; } else { - volatile u16 *p = (volatile u16 *)port2adr(port); + volatile __u16 *p = (volatile unsigned short *)port2adr(port); - while (count--) - *buf++ = *p & 0xff; + while (count--) *((unsigned char *) addr)++ = *p & 0xff; } } void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count) { - volatile u16 *p; - u16 *buf = addr; + volatile __u16 *p; if (PXSEG(port)) - p = (volatile u16 *)port; - else if (is_pci_ioaddr(port) || shifted_port(port)) - p = (volatile u16 *)pci_ioaddr(port); + p = (volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + p = (volatile unsigned short *)PCI_IOMAP(port); else - p = (volatile u16 *)port2adr(port); - while (count--) - *buf++ = *p; + p = (volatile unsigned short *)port2adr(port); + while (count--) *((__u16 *) addr)++ = *p; } void hs7751rvoip_insl(unsigned long port, void *addr, unsigned long count) { + if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u32 *p = (__u32 *)PCI_IOMAP(port); - if (is_pci_ioaddr(port) || shifted_port(port)) { - volatile u32 *p = (volatile u32 *)pci_ioaddr(port); - u32 *buf = addr; - - while (count--) - *buf++ = *p; + while (count--) *((__u32 *) addr)++ = *p; } else - maybebadio(port); + maybebadio(insl, port); } void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count) { - const u8 *buf = addr; - if (PXSEG(port)) - while (count--) - ctrl_outb(*buf++, port); + while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++; +#if defined(CONFIG_HS7751RVOIP_CODEC) else if (codec_port(port)) - while (count--) - ctrl_outb(*buf++, CODEC_IOMAP(port)); - else if (is_pci_ioaddr(port) || shifted_port(port)) { - volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); + while (count--) *(volatile unsigned char *)((unsigned long)area6_io8_base+(port-CODEC_IO_BASE)) = *((unsigned char *) addr)++; +#endif + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u8 *bp = (__u8 *)PCI_IOMAP(port); - while (count--) - *bp = *buf++; + while (count--) *bp = *((volatile unsigned char *) addr)++; } else { - volatile u16 *p = (volatile u16 *)port2adr(port); + volatile __u16 *p = (volatile unsigned short *)port2adr(port); - while (count--) - *p = *buf++; + while (count--) *p = *((unsigned char *) addr)++; } } void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count) { - volatile u16 *p; - const u16 *buf = addr; + volatile __u16 *p; if (PXSEG(port)) - p = (volatile u16 *)port; - else if (is_pci_ioaddr(port) || shifted_port(port)) - p = (volatile u16 *)pci_ioaddr(port); + p = (volatile unsigned short *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + p = (volatile unsigned short *)PCI_IOMAP(port); else - p = (volatile u16 *)port2adr(port); - - while (count--) - *p = *buf++; + p = (volatile unsigned short *)port2adr(port); + while (count--) *p = *((__u16 *) addr)++; } void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count) { - const u32 *buf = addr; + if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u32 *p = (__u32 *)PCI_IOMAP(port); - if (is_pci_ioaddr(port) || shifted_port(port)) { - volatile u32 *p = (volatile u32 *)pci_ioaddr(port); - - while (count--) - *p = *buf++; + while (count--) *p = *((__u32 *) addr)++; } else - maybebadio(port); + maybebadio(outsl, port); } -void __iomem *hs7751rvoip_ioport_map(unsigned long port, unsigned int size) +void *hs7751rvoip_ioremap(unsigned long offset, unsigned long size) { - if (PXSEG(port)) - return (void __iomem *)port; - else if (unlikely(codec_port(port) && (size == 1))) - return (void __iomem *)CODEC_IOMAP(port); - else if (is_pci_ioaddr(port)) - return (void __iomem *)pci_ioaddr(port); + if (offset >= 0xfd000000) + return (void *)offset; + else + return (void *)P2SEGADDR(offset); +} +EXPORT_SYMBOL(hs7751rvoip_ioremap); - return (void __iomem *)port2adr(port); +unsigned long hs7751rvoip_isa_port2addr(unsigned long offset) +{ + return port2adr(offset); } diff --git a/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c b/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c index c617b188258a..705b7ddcb0d2 100644 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c @@ -35,24 +35,30 @@ static unsigned int startup_hs7751rvoip_irq(unsigned int irq) static void disable_hs7751rvoip_irq(unsigned int irq) { + unsigned long flags; unsigned short val; unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); /* Set the priority in IPR to 0 */ + local_irq_save(flags); val = ctrl_inw(IRLCNTR3); val &= mask; ctrl_outw(val, IRLCNTR3); + local_irq_restore(flags); } static void enable_hs7751rvoip_irq(unsigned int irq) { + unsigned long flags; unsigned short val; unsigned short value = (0x0001 << mask_pos[irq]); /* Set priority in IPR back to original value */ + local_irq_save(flags); val = ctrl_inw(IRLCNTR3); val |= value; ctrl_outw(val, IRLCNTR3); + local_irq_restore(flags); } static void ack_hs7751rvoip_irq(unsigned int irq) diff --git a/trunk/arch/sh/boards/renesas/hs7751rvoip/led.c b/trunk/arch/sh/boards/renesas/hs7751rvoip/led.c new file mode 100644 index 000000000000..b6608fff9f38 --- /dev/null +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/led.c @@ -0,0 +1,26 @@ +/* + * linux/arch/sh/kernel/setup_hs7751rvoip.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Renesas Technology Sales HS7751RVoIP Support. + * + * Modified for HS7751RVoIP by + * Atom Create Engineering Co., Ltd. 2002. + * Lineo uSolutions, Inc. 2003. + */ + +#include +#include + +extern unsigned int debug_counter; + +void debug_led_disp(void) +{ + unsigned short value; + + value = (unsigned char)debug_counter++; + ctrl_outb((0xf0|value), PA_OUTPORTR); + if (value == 0x0f) + debug_counter = 0; +} diff --git a/trunk/arch/sh/boards/renesas/hs7751rvoip/mach.c b/trunk/arch/sh/boards/renesas/hs7751rvoip/mach.c new file mode 100644 index 000000000000..caf967f77c61 --- /dev/null +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/mach.c @@ -0,0 +1,54 @@ +/* + * linux/arch/sh/kernel/mach_hs7751rvoip.c + * + * Minor tweak of mach_se.c file to reference hs7751rvoip-specific items. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Machine vector for the Renesas Technology sales HS7751RVoIP + */ + +#include + +#include +#include +#include +#include + +extern void init_hs7751rvoip_IRQ(void); +extern void *hs7751rvoip_ioremap(unsigned long, unsigned long); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_hs7751rvoip __initmv = { + .mv_nr_irqs = 72, + + .mv_inb = hs7751rvoip_inb, + .mv_inw = hs7751rvoip_inw, + .mv_inl = hs7751rvoip_inl, + .mv_outb = hs7751rvoip_outb, + .mv_outw = hs7751rvoip_outw, + .mv_outl = hs7751rvoip_outl, + + .mv_inb_p = hs7751rvoip_inb_p, + .mv_inw_p = hs7751rvoip_inw, + .mv_inl_p = hs7751rvoip_inl, + .mv_outb_p = hs7751rvoip_outb_p, + .mv_outw_p = hs7751rvoip_outw, + .mv_outl_p = hs7751rvoip_outl, + + .mv_insb = hs7751rvoip_insb, + .mv_insw = hs7751rvoip_insw, + .mv_insl = hs7751rvoip_insl, + .mv_outsb = hs7751rvoip_outsb, + .mv_outsw = hs7751rvoip_outsw, + .mv_outsl = hs7751rvoip_outsl, + + .mv_ioremap = hs7751rvoip_ioremap, + .mv_isa_port2addr = hs7751rvoip_isa_port2addr, + .mv_init_irq = init_hs7751rvoip_IRQ, +}; +ALIAS_MV(hs7751rvoip) diff --git a/trunk/arch/sh/boards/renesas/hs7751rvoip/setup.c b/trunk/arch/sh/boards/renesas/hs7751rvoip/setup.c index 0414c15c3458..29fb5ff70fb5 100644 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/setup.c +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/setup.c @@ -1,38 +1,44 @@ /* - * Renesas Technology Sales HS7751RVoIP Support. + * linux/arch/sh/kernel/setup_hs7751rvoip.c * * Copyright (C) 2000 Kazumoto Kojima * + * Renesas Technology Sales HS7751RVoIP Support. + * * Modified for HS7751RVoIP by * Atom Create Engineering Co., Ltd. 2002. * Lineo uSolutions, Inc. 2003. */ + #include #include -#include -#include + #include #include -#include #include #include -#include -#include -#include -static void __init hs7751rvoip_init_irq(void) -{ -#if defined(CONFIG_HS7751RVOIP_CODEC) - make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); - make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); -#endif +#include +#include + +/* defined in mm/ioremap.c */ +extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags); - init_hs7751rvoip_IRQ(); +unsigned int debug_counter; + +const char *get_system_type(void) +{ + return "HS7751RVoIP"; } -static void hs7751rvoip_power_off(void) +/* + * Initialize the board + */ +void __init platform_setup(void) { - ctrl_outw(ctrl_inw(PA_OUTPORTR) & 0xffdf, PA_OUTPORTR); + printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n"); + ctrl_outb(0xf0, PA_OUTPORTR); + debug_counter = 0; } void *area5_io8_base; @@ -40,15 +46,16 @@ void *area6_io8_base; void *area5_io16_base; void *area6_io16_base; -static int __init hs7751rvoip_cf_init(void) +int __init cf_init(void) { pgprot_t prot; - unsigned long paddrbase; + unsigned long paddrbase, psize; /* open I/O area window */ paddrbase = virt_to_phys((void *)(PA_AREA5_IO+0x00000800)); + psize = PAGE_SIZE; prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_COM16); - area5_io16_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot); + area5_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot); if (!area5_io16_base) { printk("allocate_cf_area : can't open CF I/O window!\n"); return -ENOMEM; @@ -57,18 +64,19 @@ static int __init hs7751rvoip_cf_init(void) /* XXX : do we need attribute and common-memory area also? */ paddrbase = virt_to_phys((void *)PA_AREA6_IO); + psize = PAGE_SIZE; #if defined(CONFIG_HS7751RVOIP_CODEC) prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_COM8); #else prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO8); #endif - area6_io8_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot); + area6_io8_base = p3_ioremap(paddrbase, psize, prot.pgprot); if (!area6_io8_base) { printk("allocate_cf_area : can't open CODEC I/O 8bit window!\n"); return -ENOMEM; } prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16); - area6_io16_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot); + area6_io16_base = p3_ioremap(paddrbase, psize, prot.pgprot); if (!area6_io16_base) { printk("allocate_cf_area : can't open CODEC I/O 16bit window!\n"); return -ENOMEM; @@ -77,46 +85,4 @@ static int __init hs7751rvoip_cf_init(void) return 0; } -/* - * Initialize the board - */ -static void __init hs7751rvoip_setup(char **cmdline_p) -{ - device_initcall(hs7751rvoip_cf_init); - - ctrl_outb(0xf0, PA_OUTPORTR); - pm_power_off = hs7751rvoip_power_off; - - printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n"); -} - -struct sh_machine_vector mv_hs7751rvoip __initmv = { - .mv_name = "HS7751RVoIP", - .mv_setup = hs7751rvoip_setup, - .mv_nr_irqs = 72, - - .mv_inb = hs7751rvoip_inb, - .mv_inw = hs7751rvoip_inw, - .mv_inl = hs7751rvoip_inl, - .mv_outb = hs7751rvoip_outb, - .mv_outw = hs7751rvoip_outw, - .mv_outl = hs7751rvoip_outl, - - .mv_inb_p = hs7751rvoip_inb_p, - .mv_inw_p = hs7751rvoip_inw, - .mv_inl_p = hs7751rvoip_inl, - .mv_outb_p = hs7751rvoip_outb_p, - .mv_outw_p = hs7751rvoip_outw, - .mv_outl_p = hs7751rvoip_outl, - - .mv_insb = hs7751rvoip_insb, - .mv_insw = hs7751rvoip_insw, - .mv_insl = hs7751rvoip_insl, - .mv_outsb = hs7751rvoip_outsb, - .mv_outsw = hs7751rvoip_outsw, - .mv_outsl = hs7751rvoip_outsl, - - .mv_init_irq = hs7751rvoip_init_irq, - .mv_ioport_map = hs7751rvoip_ioport_map, -}; -ALIAS_MV(hs7751rvoip) +__initcall (cf_init); diff --git a/trunk/arch/sh/boards/renesas/r7780rp/Kconfig b/trunk/arch/sh/boards/renesas/r7780rp/Kconfig deleted file mode 100644 index c26d9813d239..000000000000 --- a/trunk/arch/sh/boards/renesas/r7780rp/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -if SH_R7780RP - -menu "R7780RP options" - -config SH_R7780MP - bool "R7780MP board support" - default y - help - Selecting this option will enable support for the mass-production - version of the R7780RP. If in doubt, say Y. - -endmenu - -endif diff --git a/trunk/arch/sh/boards/renesas/r7780rp/Makefile b/trunk/arch/sh/boards/renesas/r7780rp/Makefile deleted file mode 100644 index f1776d027978..000000000000 --- a/trunk/arch/sh/boards/renesas/r7780rp/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for the R7780RP-1 specific parts of the kernel -# - -obj-y := setup.o io.o irq.o -obj-$(CONFIG_HEARTBEAT) += led.o diff --git a/trunk/arch/sh/boards/renesas/r7780rp/io.c b/trunk/arch/sh/boards/renesas/r7780rp/io.c deleted file mode 100644 index db92d6e6ae99..000000000000 --- a/trunk/arch/sh/boards/renesas/r7780rp/io.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (C) 2001 Ian da Silva, Jeremy Siegel - * Based largely on io_se.c. - * - * I/O routine for Renesas Solutions Highlander R7780RP-1 - * - * Initial version only to support LAN access; some - * placeholder code from io_r7780rp.c left in with the - * expectation of later SuperIO and PCMCIA access. - */ -#include -#include -#include -#include -#include -#include - -static inline unsigned long port2adr(unsigned int port) -{ - if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) - if (port == 0x3f6) - return (PA_AREA5_IO + 0x80c); - else - return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1)); - else - maybebadio((unsigned long)port); - - return port; -} - -static inline unsigned long port88796l(unsigned int port, int flag) -{ - unsigned long addr; - - if (flag) - addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1); - else - addr = PA_AX88796L + ((port - AX88796L_IO_BASE) << 1) + 0x1000; - - return addr; -} - -/* The 7780 R7780RP-1 seems to have everything hooked */ -/* up pretty normally (nothing on high-bytes only...) so this */ -/* shouldn't be needed */ -static inline int shifted_port(unsigned long port) -{ - /* For IDE registers, value is not shifted */ - if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) - return 0; - else - return 1; -} - -#if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE) -#define CHECK_AX88796L_PORT(port) \ - ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20))) -#else -#define CHECK_AX88796L_PORT(port) (0) -#endif - -/* - * General outline: remap really low stuff [eventually] to SuperIO, - * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) - * is mapped through the PCI IO window. Stuff with high bits (PXSEG) - * should be way beyond the window, and is used w/o translation for - * compatibility. - */ -u8 r7780rp_inb(unsigned long port) -{ - if (CHECK_AX88796L_PORT(port)) - return ctrl_inw(port88796l(port, 0)) & 0xff; - else if (PXSEG(port)) - return ctrl_inb(port); - else if (is_pci_ioaddr(port) || shifted_port(port)) - return ctrl_inb(pci_ioaddr(port)); - - return ctrl_inw(port2adr(port)) & 0xff; -} - -u8 r7780rp_inb_p(unsigned long port) -{ - u8 v; - - if (CHECK_AX88796L_PORT(port)) - v = ctrl_inw(port88796l(port, 0)) & 0xff; - else if (PXSEG(port)) - v = ctrl_inb(port); - else if (is_pci_ioaddr(port) || shifted_port(port)) - v = ctrl_inb(pci_ioaddr(port)); - else - v = ctrl_inw(port2adr(port)) & 0xff; - - ctrl_delay(); - - return v; -} - -u16 r7780rp_inw(unsigned long port) -{ - if (CHECK_AX88796L_PORT(port)) - maybebadio(port); - else if (PXSEG(port)) - return ctrl_inw(port); - else if (is_pci_ioaddr(port) || shifted_port(port)) - return ctrl_inw(pci_ioaddr(port)); - else - maybebadio(port); - - return 0; -} - -u32 r7780rp_inl(unsigned long port) -{ - if (CHECK_AX88796L_PORT(port)) - maybebadio(port); - else if (PXSEG(port)) - return ctrl_inl(port); - else if (is_pci_ioaddr(port) || shifted_port(port)) - return ctrl_inl(pci_ioaddr(port)); - else - maybebadio(port); - - return 0; -} - -void r7780rp_outb(u8 value, unsigned long port) -{ - if (CHECK_AX88796L_PORT(port)) - ctrl_outw(value, port88796l(port, 0)); - else if (PXSEG(port)) - ctrl_outb(value, port); - else if (is_pci_ioaddr(port) || shifted_port(port)) - ctrl_outb(value, pci_ioaddr(port)); - else - ctrl_outw(value, port2adr(port)); -} - -void r7780rp_outb_p(u8 value, unsigned long port) -{ - if (CHECK_AX88796L_PORT(port)) - ctrl_outw(value, port88796l(port, 0)); - else if (PXSEG(port)) - ctrl_outb(value, port); - else if (is_pci_ioaddr(port) || shifted_port(port)) - ctrl_outb(value, pci_ioaddr(port)); - else - ctrl_outw(value, port2adr(port)); - - ctrl_delay(); -} - -void r7780rp_outw(u16 value, unsigned long port) -{ - if (CHECK_AX88796L_PORT(port)) - maybebadio(port); - else if (PXSEG(port)) - ctrl_outw(value, port); - else if (is_pci_ioaddr(port) || shifted_port(port)) - ctrl_outw(value, pci_ioaddr(port)); - else - maybebadio(port); -} - -void r7780rp_outl(u32 value, unsigned long port) -{ - if (CHECK_AX88796L_PORT(port)) - maybebadio(port); - else if (PXSEG(port)) - ctrl_outl(value, port); - else if (is_pci_ioaddr(port) || shifted_port(port)) - ctrl_outl(value, pci_ioaddr(port)); - else - maybebadio(port); -} - -void r7780rp_insb(unsigned long port, void *dst, unsigned long count) -{ - volatile u16 *p; - u8 *buf = dst; - - if (CHECK_AX88796L_PORT(port)) { - p = (volatile u16 *)port88796l(port, 0); - while (count--) - *buf++ = *p & 0xff; - } else if (PXSEG(port)) { - while (count--) - *buf++ = *(volatile u8 *)port; - } else if (is_pci_ioaddr(port) || shifted_port(port)) { - volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); - - while (count--) - *buf++ = *bp; - } else { - p = (volatile u16 *)port2adr(port); - while (count--) - *buf++ = *p & 0xff; - } -} - -void r7780rp_insw(unsigned long port, void *dst, unsigned long count) -{ - volatile u16 *p; - u16 *buf = dst; - - if (CHECK_AX88796L_PORT(port)) - p = (volatile u16 *)port88796l(port, 1); - else if (PXSEG(port)) - p = (volatile u16 *)port; - else if (is_pci_ioaddr(port) || shifted_port(port)) - p = (volatile u16 *)pci_ioaddr(port); - else - p = (volatile u16 *)port2adr(port); - - while (count--) - *buf++ = *p; -} - -void r7780rp_insl(unsigned long port, void *dst, unsigned long count) -{ - u32 *buf = dst; - - if (CHECK_AX88796L_PORT(port)) - maybebadio(port); - else if (is_pci_ioaddr(port) || shifted_port(port)) { - volatile u32 *p = (volatile u32 *)pci_ioaddr(port); - - while (count--) - *buf++ = *p; - } else - maybebadio(port); -} - -void r7780rp_outsb(unsigned long port, const void *src, unsigned long count) -{ - volatile u16 *p; - const u8 *buf = src; - - if (CHECK_AX88796L_PORT(port)) { - p = (volatile u16 *)port88796l(port, 0); - while (count--) - *p = *buf++; - } else if (PXSEG(port)) - while (count--) - ctrl_outb(*buf++, port); - else if (is_pci_ioaddr(port) || shifted_port(port)) { - volatile u8 *bp = (volatile u8 *)pci_ioaddr(port); - - while (count--) - *bp = *buf++; - } else { - p = (volatile u16 *)port2adr(port); - while (count--) - *p = *buf++; - } -} - -void r7780rp_outsw(unsigned long port, const void *src, unsigned long count) -{ - volatile u16 *p; - const u16 *buf = src; - - if (CHECK_AX88796L_PORT(port)) - p = (volatile u16 *)port88796l(port, 1); - else if (PXSEG(port)) - p = (volatile u16 *)port; - else if (is_pci_ioaddr(port) || shifted_port(port)) - p = (volatile u16 *)pci_ioaddr(port); - else - p = (volatile u16 *)port2adr(port); - - while (count--) - *p = *buf++; -} - -void r7780rp_outsl(unsigned long port, const void *src, unsigned long count) -{ - const u32 *buf = src; - - if (CHECK_AX88796L_PORT(port)) - maybebadio(port); - else if (is_pci_ioaddr(port) || shifted_port(port)) { - volatile u32 *p = (volatile u32 *)pci_ioaddr(port); - - while (count--) - *p = *buf++; - } else - maybebadio(port); -} - -void __iomem *r7780rp_ioport_map(unsigned long port, unsigned int size) -{ - if (CHECK_AX88796L_PORT(port)) - return (void __iomem *)port88796l(port, size > 1); - else if (PXSEG(port)) - return (void __iomem *)port; - else if (is_pci_ioaddr(port) || shifted_port(port)) - return (void __iomem *)pci_ioaddr(port); - - return (void __iomem *)port2adr(port); -} diff --git a/trunk/arch/sh/boards/renesas/r7780rp/irq.c b/trunk/arch/sh/boards/renesas/r7780rp/irq.c deleted file mode 100644 index 61d5e5d3c294..000000000000 --- a/trunk/arch/sh/boards/renesas/r7780rp/irq.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * linux/arch/sh/boards/renesas/r7780rp/irq.c - * - * Copyright (C) 2000 Kazumoto Kojima - * - * Renesas Solutions Highlander R7780RP-1 Support. - * - * Modified for R7780RP-1 by - * Atom Create Engineering Co., Ltd. 2002. - */ - -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_SH_R7780MP -static int mask_pos[] = {12, 11, 9, 14, 15, 8, 13, 6, 5, 4, 3, 2, 0, 0, 1, 0}; -#else -static int mask_pos[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 5, 6, 4, 0, 1, 2, 0}; -#endif - -static void enable_r7780rp_irq(unsigned int irq); -static void disable_r7780rp_irq(unsigned int irq); - -/* shutdown is same as "disable" */ -#define shutdown_r7780rp_irq disable_r7780rp_irq - -static void ack_r7780rp_irq(unsigned int irq); -static void end_r7780rp_irq(unsigned int irq); - -static unsigned int startup_r7780rp_irq(unsigned int irq) -{ - enable_r7780rp_irq(irq); - return 0; /* never anything pending */ -} - -static void disable_r7780rp_irq(unsigned int irq) -{ - unsigned short val; - unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); - - /* Set the priority in IPR to 0 */ - val = ctrl_inw(IRLCNTR1); - val &= mask; - ctrl_outw(val, IRLCNTR1); -} - -static void enable_r7780rp_irq(unsigned int irq) -{ - unsigned short val; - unsigned short value = (0x0001 << mask_pos[irq]); - - /* Set priority in IPR back to original value */ - val = ctrl_inw(IRLCNTR1); - val |= value; - ctrl_outw(val, IRLCNTR1); -} - -static void ack_r7780rp_irq(unsigned int irq) -{ - disable_r7780rp_irq(irq); -} - -static void end_r7780rp_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) - enable_r7780rp_irq(irq); -} - -static struct hw_interrupt_type r7780rp_irq_type = { - .typename = "R7780RP-IRQ", - .startup = startup_r7780rp_irq, - .shutdown = shutdown_r7780rp_irq, - .enable = enable_r7780rp_irq, - .disable = disable_r7780rp_irq, - .ack = ack_r7780rp_irq, - .end = end_r7780rp_irq, -}; - -static void make_r7780rp_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - irq_desc[irq].handler = &r7780rp_irq_type; - disable_r7780rp_irq(irq); -} - -/* - * Initialize IRQ setting - */ -void __init init_r7780rp_IRQ(void) -{ - int i; - - /* IRL0=PCI Slot #A - * IRL1=PCI Slot #B - * IRL2=PCI Slot #C - * IRL3=PCI Slot #D - * IRL4=CF Card - * IRL5=CF Card Insert - * IRL6=M66596 - * IRL7=SD Card - * IRL8=Touch Panel - * IRL9=SCI - * IRL10=Serial - * IRL11=Extention #A - * IRL11=Extention #B - * IRL12=Debug LAN - * IRL13=Push Switch - * IRL14=ZiggBee IO - */ - - for (i=0; i<15; i++) - make_r7780rp_irq(i); -} diff --git a/trunk/arch/sh/boards/renesas/r7780rp/led.c b/trunk/arch/sh/boards/renesas/r7780rp/led.c deleted file mode 100644 index 9f02766b6f53..000000000000 --- a/trunk/arch/sh/boards/renesas/r7780rp/led.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) Atom Create Engineering Co., Ltd. - * - * May be copied or modified under the terms of GNU General Public - * License. See linux/COPYING for more information. - * - * This file contains Renesas Solutions HIGHLANDER R7780RP-1 specific LED code. - */ - -#include -#include -#include -#include - -/* Cycle the LED's in the clasic Knightriger/Sun pattern */ -void heartbeat_r7780rp(void) -{ - static unsigned int cnt = 0, period = 0; - volatile unsigned short *p = (volatile unsigned short *)PA_OBLED; - static unsigned bit = 0, up = 1; - unsigned bit_pos[] = {2, 1, 0, 3, 6, 5, 4, 7}; - - cnt += 1; - if (cnt < period) - return; - - cnt = 0; - - /* Go through the points (roughly!): - * f(0)=10, f(1)=16, f(2)=20, f(5)=35, f(int)->110 - */ - period = 110 - ((300 << FSHIFT)/((avenrun[0]/5) + (3< -#include -#include -#include -#include -#include - -extern void heartbeat_r7780rp(void); -extern void init_r7780rp_IRQ(void); - -static struct resource m66596_usb_host_resources[] = { - [0] = { - .start = 0xa4800000, - .end = 0xa4ffffff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 6, /* irq number */ - .end = 6, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device m66596_usb_host_device = { - .name = "m66596-hcd", - .id = 0, - .dev = { - .dma_mask = NULL, /* don't use dma */ - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(m66596_usb_host_resources), - .resource = m66596_usb_host_resources, -}; - -static struct platform_device *r7780rp_devices[] __initdata = { - &m66596_usb_host_device, -}; - -static int __init r7780rp_devices_setup(void) -{ - return platform_add_devices(r7780rp_devices, - ARRAY_SIZE(r7780rp_devices)); -} - -/* - * Platform specific clocks - */ -static void ivdr_clk_enable(struct clk *clk) -{ - ctrl_outw(ctrl_inw(PA_IVDRCTL) | (1 << 8), PA_IVDRCTL); -} - -static void ivdr_clk_disable(struct clk *clk) -{ - ctrl_outw(ctrl_inw(PA_IVDRCTL) & ~(1 << 8), PA_IVDRCTL); -} - -static struct clk_ops ivdr_clk_ops = { - .enable = ivdr_clk_enable, - .disable = ivdr_clk_disable, -}; - -static struct clk ivdr_clk = { - .name = "ivdr_clk", - .ops = &ivdr_clk_ops, -}; - -static struct clk *r7780rp_clocks[] = { - &ivdr_clk, -}; - -static void r7780rp_power_off(void) -{ -#ifdef CONFIG_SH_R7780MP - ctrl_outw(0x0001, PA_POFF); -#endif -} - -/* - * Initialize the board - */ -static void __init r7780rp_setup(char **cmdline_p) -{ - u16 ver = ctrl_inw(PA_VERREG); - int i; - - device_initcall(r7780rp_devices_setup); - - printk(KERN_INFO "Renesas Solutions Highlander R7780RP-1 support.\n"); - - printk(KERN_INFO "Board version: %d (revision %d), " - "FPGA version: %d (revision %d)\n", - (ver >> 12) & 0xf, (ver >> 8) & 0xf, - (ver >> 4) & 0xf, ver & 0xf); - - /* - * Enable the important clocks right away.. - */ - for (i = 0; i < ARRAY_SIZE(r7780rp_clocks); i++) { - struct clk *clk = r7780rp_clocks[i]; - - clk_register(clk); - clk_enable(clk); - } - - ctrl_outw(0x0000, PA_OBLED); /* Clear LED. */ -#ifndef CONFIG_SH_R7780MP - ctrl_outw(0x0001, PA_SDPOW); /* SD Power ON */ -#endif - ctrl_outw(ctrl_inw(PA_IVDRCTL) | 0x0100, PA_IVDRCTL); /* Si13112 */ - - pm_power_off = r7780rp_power_off; -} - -/* - * The Machine Vector - */ -struct sh_machine_vector mv_r7780rp __initmv = { - .mv_name = "Highlander R7780RP-1", - .mv_setup = r7780rp_setup, - - .mv_nr_irqs = 109, - - .mv_inb = r7780rp_inb, - .mv_inw = r7780rp_inw, - .mv_inl = r7780rp_inl, - .mv_outb = r7780rp_outb, - .mv_outw = r7780rp_outw, - .mv_outl = r7780rp_outl, - - .mv_inb_p = r7780rp_inb_p, - .mv_inw_p = r7780rp_inw, - .mv_inl_p = r7780rp_inl, - .mv_outb_p = r7780rp_outb_p, - .mv_outw_p = r7780rp_outw, - .mv_outl_p = r7780rp_outl, - - .mv_insb = r7780rp_insb, - .mv_insw = r7780rp_insw, - .mv_insl = r7780rp_insl, - .mv_outsb = r7780rp_outsb, - .mv_outsw = r7780rp_outsw, - .mv_outsl = r7780rp_outsl, - - .mv_ioport_map = r7780rp_ioport_map, - .mv_init_irq = init_r7780rp_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_r7780rp, -#endif -}; -ALIAS_MV(r7780rp) diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/Kconfig b/trunk/arch/sh/boards/renesas/rts7751r2d/Kconfig deleted file mode 100644 index 7780d1fb13ff..000000000000 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -if SH_RTS7751R2D - -menu "RTS7751R2D options" - -config RTS7751R2D_REV11 - bool "RTS7751R2D Rev. 1.1 board support" - help - Selecting this option will support version rev. 1.1. -endmenu - -endif - diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/Makefile b/trunk/arch/sh/boards/renesas/rts7751r2d/Makefile index 686fc9ea5989..daa53334bdc3 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/Makefile +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/Makefile @@ -1,6 +1,10 @@ # # Makefile for the RTS7751R2D specific parts of the kernel # +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +obj-y := mach.o setup.o io.o irq.o led.o -obj-y := setup.o io.o irq.o -obj-$(CONFIG_HEARTBEAT) += led.o diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/io.c b/trunk/arch/sh/boards/renesas/rts7751r2d/io.c index 135aa0b5e62d..123abbbc91e0 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/io.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/io.c @@ -1,4 +1,6 @@ /* + * linux/arch/sh/kernel/io_rts7751r2d.c + * * Copyright (C) 2001 Ian da Silva, Jeremy Siegel * Based largely on io_se.c. * @@ -8,13 +10,17 @@ * placeholder code from io_rts7751r2d.c left in with the * expectation of later SuperIO and PCMCIA access. */ + #include #include -#include -#include #include +#include #include +#include +#include +#include "../../../drivers/pci/pci-sh7751.h" + /* * The 7751R RTS7751R2D uses the built-in PCI controller (PCIC) * of the 7751R processor, and has a SuperIO accessible via the PCI. @@ -22,6 +28,22 @@ * like the other Solution Engine boards. */ +#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) +#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) +#define PCI_IO_AREA SH7751_PCI_IO_BASE +#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE + +#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + static inline unsigned long port2adr(unsigned int port) { if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) @@ -30,7 +52,7 @@ static inline unsigned long port2adr(unsigned int port) else return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1)); else - maybebadio((unsigned long)port); + maybebadio(port2adr, (unsigned long)port); return port; } @@ -59,6 +81,17 @@ static inline int shifted_port(unsigned long port) return 1; } +/* In case someone configures the kernel w/o PCI support: in that */ +/* scenario, don't ever bother to check for PCI-window addresses */ + +/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ +#if defined(CONFIG_PCI) +#define CHECK_SH7751_PCIIO(port) \ + ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) +#else +#define CHECK_SH7751_PCIIO(port) (0) +#endif + #if defined(CONFIG_NE2000) || defined(CONFIG_NE2000_MODULE) #define CHECK_AX88796L_PORT(port) \ ((port >= AX88796L_IO_BASE) && (port < (AX88796L_IO_BASE+0x20))) @@ -79,8 +112,8 @@ unsigned char rts7751r2d_inb(unsigned long port) return (*(volatile unsigned short *)port88796l(port, 0)) & 0xff; else if (PXSEG(port)) return *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port) || shifted_port(port)) - return *(volatile unsigned char *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned char *)PCI_IOMAP(port); else return (*(volatile unsigned short *)port2adr(port) & 0xff); } @@ -93,12 +126,11 @@ unsigned char rts7751r2d_inb_p(unsigned long port) v = (*(volatile unsigned short *)port88796l(port, 0)) & 0xff; else if (PXSEG(port)) v = *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port) || shifted_port(port)) - v = *(volatile unsigned char *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + v = *(volatile unsigned char *)PCI_IOMAP(port); else v = (*(volatile unsigned short *)port2adr(port) & 0xff); - - ctrl_delay(); + delay(); return v; } @@ -106,13 +138,13 @@ unsigned char rts7751r2d_inb_p(unsigned long port) unsigned short rts7751r2d_inw(unsigned long port) { if (CHECK_AX88796L_PORT(port)) - maybebadio(port); + maybebadio(inw, port); else if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (is_pci_ioaddr(port) || shifted_port(port)) - return *(volatile unsigned short *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned short *)PCI_IOMAP(port); else - maybebadio(port); + maybebadio(inw, port); return 0; } @@ -120,13 +152,13 @@ unsigned short rts7751r2d_inw(unsigned long port) unsigned int rts7751r2d_inl(unsigned long port) { if (CHECK_AX88796L_PORT(port)) - maybebadio(port); + maybebadio(inl, port); else if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (is_pci_ioaddr(port) || shifted_port(port)) - return *(volatile unsigned long *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + return *(volatile unsigned long *)PCI_IOMAP(port); else - maybebadio(port); + maybebadio(inl, port); return 0; } @@ -137,8 +169,8 @@ void rts7751r2d_outb(unsigned char value, unsigned long port) *((volatile unsigned short *)port88796l(port, 0)) = value; else if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port) || shifted_port(port)) - *(volatile unsigned char *)pci_ioaddr(port) = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(volatile unsigned char *)PCI_IOMAP(port) = value; else *(volatile unsigned short *)port2adr(port) = value; } @@ -149,152 +181,143 @@ void rts7751r2d_outb_p(unsigned char value, unsigned long port) *((volatile unsigned short *)port88796l(port, 0)) = value; else if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port) || shifted_port(port)) - *(volatile unsigned char *)pci_ioaddr(port) = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(volatile unsigned char *)PCI_IOMAP(port) = value; else *(volatile unsigned short *)port2adr(port) = value; - - ctrl_delay(); + delay(); } void rts7751r2d_outw(unsigned short value, unsigned long port) { if (CHECK_AX88796L_PORT(port)) - maybebadio(port); + maybebadio(outw, port); else if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (is_pci_ioaddr(port) || shifted_port(port)) - *(volatile unsigned short *)pci_ioaddr(port) = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(volatile unsigned short *)PCI_IOMAP(port) = value; else - maybebadio(port); + maybebadio(outw, port); } void rts7751r2d_outl(unsigned int value, unsigned long port) { if (CHECK_AX88796L_PORT(port)) - maybebadio(port); + maybebadio(outl, port); else if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (is_pci_ioaddr(port) || shifted_port(port)) - *(volatile unsigned long *)pci_ioaddr(port) = value; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + *(volatile unsigned long *)PCI_IOMAP(port) = value; else - maybebadio(port); + maybebadio(outl, port); } void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count) { - unsigned long a = (unsigned long)addr; volatile __u8 *bp; volatile __u16 *p; + unsigned char *s = addr; if (CHECK_AX88796L_PORT(port)) { p = (volatile unsigned short *)port88796l(port, 0); - while (count--) - ctrl_outb(*p & 0xff, a++); + while (count--) *s++ = *p & 0xff; } else if (PXSEG(port)) - while (count--) - ctrl_outb(ctrl_inb(port), a++); - else if (is_pci_ioaddr(port) || shifted_port(port)) { - bp = (__u8 *)pci_ioaddr(port); - while (count--) - ctrl_outb(*bp, a++); + while (count--) *s++ = *(volatile unsigned char *)port; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + bp = (__u8 *)PCI_IOMAP(port); + while (count--) *s++ = *bp; } else { p = (volatile unsigned short *)port2adr(port); - while (count--) - ctrl_outb(*p & 0xff, a++); + while (count--) *s++ = *p & 0xff; } } void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count) { - unsigned long a = (unsigned long)addr; volatile __u16 *p; + __u16 *s = addr; if (CHECK_AX88796L_PORT(port)) p = (volatile unsigned short *)port88796l(port, 1); else if (PXSEG(port)) p = (volatile unsigned short *)port; - else if (is_pci_ioaddr(port) || shifted_port(port)) - p = (volatile unsigned short *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + p = (volatile unsigned short *)PCI_IOMAP(port); else p = (volatile unsigned short *)port2adr(port); - while (count--) - ctrl_outw(*p, a++); + while (count--) *s++ = *p; } void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count) { if (CHECK_AX88796L_PORT(port)) - maybebadio(port); - else if (is_pci_ioaddr(port) || shifted_port(port)) { - unsigned long a = (unsigned long)addr; - - while (count--) { - ctrl_outl(ctrl_inl(pci_ioaddr(port)), a); - a += 4; - } + maybebadio(insl, port); + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + __u32 *s = addr; + + while (count--) *s++ = *p; } else - maybebadio(port); + maybebadio(insl, port); } void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count) { - unsigned long a = (unsigned long)addr; volatile __u8 *bp; volatile __u16 *p; + const __u8 *s = addr; if (CHECK_AX88796L_PORT(port)) { p = (volatile unsigned short *)port88796l(port, 0); - while (count--) - *p = ctrl_inb(a++); + while (count--) *p = *s++; } else if (PXSEG(port)) - while (count--) - ctrl_outb(a++, port); - else if (is_pci_ioaddr(port) || shifted_port(port)) { - bp = (__u8 *)pci_ioaddr(port); - while (count--) - *bp = ctrl_inb(a++); + while (count--) *(volatile unsigned char *)port = *s++; + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + bp = (__u8 *)PCI_IOMAP(port); + while (count--) *bp = *s++; } else { p = (volatile unsigned short *)port2adr(port); - while (count--) - *p = ctrl_inb(a++); + while (count--) *p = *s++; } } void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count) { - unsigned long a = (unsigned long)addr; volatile __u16 *p; + const __u16 *s = addr; if (CHECK_AX88796L_PORT(port)) p = (volatile unsigned short *)port88796l(port, 1); else if (PXSEG(port)) p = (volatile unsigned short *)port; - else if (is_pci_ioaddr(port) || shifted_port(port)) - p = (volatile unsigned short *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) + p = (volatile unsigned short *)PCI_IOMAP(port); else p = (volatile unsigned short *)port2adr(port); - - while (count--) { - ctrl_outw(*p, a); - a += 2; - } + while (count--) *p = *s++; } void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count) { if (CHECK_AX88796L_PORT(port)) - maybebadio(port); - else if (is_pci_ioaddr(port) || shifted_port(port)) { - unsigned long a = (unsigned long)addr; - - while (count--) { - ctrl_outl(ctrl_inl(a), pci_ioaddr(port)); - a += 4; - } + maybebadio(outsl, port); + else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { + volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + const __u32 *s = addr; + + while (count--) *p = *s++; } else - maybebadio(port); + maybebadio(outsl, port); +} + +void *rts7751r2d_ioremap(unsigned long offset, unsigned long size) +{ + if (offset >= 0xfd000000) + return (void *)offset; + else + return (void *)P2SEGADDR(offset); } +EXPORT_SYMBOL(rts7751r2d_ioremap); unsigned long rts7751r2d_isa_port2addr(unsigned long offset) { diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c b/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c index c915e7a3693a..154535440bbf 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c @@ -41,24 +41,30 @@ static unsigned int startup_rts7751r2d_irq(unsigned int irq) static void disable_rts7751r2d_irq(unsigned int irq) { + unsigned long flags; unsigned short val; unsigned short mask = 0xffff ^ (0x0001 << mask_pos[irq]); /* Set the priority in IPR to 0 */ + local_irq_save(flags); val = ctrl_inw(IRLCNTR1); val &= mask; ctrl_outw(val, IRLCNTR1); + local_irq_restore(flags); } static void enable_rts7751r2d_irq(unsigned int irq) { + unsigned long flags; unsigned short val; unsigned short value = (0x0001 << mask_pos[irq]); /* Set priority in IPR back to original value */ + local_irq_save(flags); val = ctrl_inw(IRLCNTR1); val |= value; ctrl_outw(val, IRLCNTR1); + local_irq_restore(flags); } int rts7751r2d_irq_demux(int irq) diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/led.c b/trunk/arch/sh/boards/renesas/rts7751r2d/led.c index e14a13d12d4a..4d16de71fac1 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/led.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/led.c @@ -12,6 +12,8 @@ #include #include +extern unsigned int debug_counter; + #ifdef CONFIG_HEARTBEAT #include @@ -53,3 +55,12 @@ void rts7751r2d_led(unsigned short value) ctrl_outw(value, PA_OUTPORT); } +void debug_led_disp(void) +{ + unsigned short value; + + value = (unsigned short)debug_counter++; + rts7751r2d_led(value); + if (value == 0xff) + debug_counter = 0; +} diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/mach.c b/trunk/arch/sh/boards/renesas/rts7751r2d/mach.c new file mode 100644 index 000000000000..5ed9e97ea197 --- /dev/null +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/mach.c @@ -0,0 +1,69 @@ +/* + * linux/arch/sh/kernel/mach_rts7751r2d.c + * + * Minor tweak of mach_se.c file to reference rts7751r2d-specific items. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Machine vector for the Renesas Technology sales RTS7751R2D + */ + +#include +#include + +#include +#include +#include +#include + +extern void heartbeat_rts7751r2d(void); +extern void init_rts7751r2d_IRQ(void); +extern void *rts7751r2d_ioremap(unsigned long, unsigned long); +extern int rts7751r2d_irq_demux(int irq); + +extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t); +extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_rts7751r2d __initmv = { + .mv_nr_irqs = 72, + + .mv_inb = rts7751r2d_inb, + .mv_inw = rts7751r2d_inw, + .mv_inl = rts7751r2d_inl, + .mv_outb = rts7751r2d_outb, + .mv_outw = rts7751r2d_outw, + .mv_outl = rts7751r2d_outl, + + .mv_inb_p = rts7751r2d_inb_p, + .mv_inw_p = rts7751r2d_inw, + .mv_inl_p = rts7751r2d_inl, + .mv_outb_p = rts7751r2d_outb_p, + .mv_outw_p = rts7751r2d_outw, + .mv_outl_p = rts7751r2d_outl, + + .mv_insb = rts7751r2d_insb, + .mv_insw = rts7751r2d_insw, + .mv_insl = rts7751r2d_insl, + .mv_outsb = rts7751r2d_outsb, + .mv_outsw = rts7751r2d_outsw, + .mv_outsl = rts7751r2d_outsl, + + .mv_ioremap = rts7751r2d_ioremap, + .mv_isa_port2addr = rts7751r2d_isa_port2addr, + .mv_init_irq = init_rts7751r2d_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_rts7751r2d, +#endif + .mv_irq_demux = rts7751r2d_irq_demux, + +#ifdef CONFIG_USB_OHCI_HCD + .mv_consistent_alloc = voyagergx_consistent_alloc, + .mv_consistent_free = voyagergx_consistent_free, +#endif +}; +ALIAS_MV(rts7751r2d) diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c b/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c index 20597a6e6702..2587fd1a0240 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c @@ -1,142 +1,31 @@ /* - * Renesas Technology Sales RTS7751R2D Support. + * linux/arch/sh/kernel/setup_rts7751r2d.c + * + * Copyright (C) 2000 Kazumoto Kojima * - * Copyright (C) 2002 Atom Create Engineering Co., Ltd. - * Copyright (C) 2004 - 2006 Paul Mundt + * Renesas Technology Sales RTS7751R2D Support. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. + * Modified for RTS7751R2D by + * Atom Create Engineering Co., Ltd. 2002. */ + #include -#include -#include -#include #include -#include -#include -#include - -extern void heartbeat_rts7751r2d(void); -extern void init_rts7751r2d_IRQ(void); -extern int rts7751r2d_irq_demux(int irq); - -extern void *voyagergx_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t); -extern int voyagergx_consistent_free(struct device *, size_t, void *, dma_addr_t); - -static struct plat_serial8250_port uart_platform_data[] = { - { - .membase = (void *)VOYAGER_UART_BASE, - .mapbase = VOYAGER_UART_BASE, - .iotype = UPIO_MEM, - .irq = VOYAGER_UART0_IRQ, - .flags = UPF_BOOT_AUTOCONF, - .regshift = 2, - .uartclk = (9600 * 16), - }, { - .flags = 0, - }, -}; - -static void __init voyagergx_serial_init(void) -{ - unsigned long val; - - /* - * GPIO Control - */ - val = inl(GPIO_MUX_HIGH); - val |= 0x00001fe0; - outl(val, GPIO_MUX_HIGH); - - /* - * Power Mode Gate - */ - val = inl(POWER_MODE0_GATE); - val |= (POWER_MODE0_GATE_U0 | POWER_MODE0_GATE_U1); - outl(val, POWER_MODE0_GATE); - - val = inl(POWER_MODE1_GATE); - val |= (POWER_MODE1_GATE_U0 | POWER_MODE1_GATE_U1); - outl(val, POWER_MODE1_GATE); -} - -static struct platform_device uart_device = { - .name = "serial8250", - .id = -1, - .dev = { - .platform_data = uart_platform_data, - }, -}; - -static struct platform_device *rts7751r2d_devices[] __initdata = { - &uart_device, -}; +#include -static int __init rts7751r2d_devices_setup(void) -{ - return platform_add_devices(rts7751r2d_devices, - ARRAY_SIZE(rts7751r2d_devices)); -} +unsigned int debug_counter; -static void rts7751r2d_power_off(void) +const char *get_system_type(void) { - ctrl_outw(0x0001, PA_POWOFF); + return "RTS7751R2D"; } /* * Initialize the board */ -static void __init rts7751r2d_setup(char **cmdline_p) +void __init platform_setup(void) { - device_initcall(rts7751r2d_devices_setup); - - ctrl_outw(0x0000, PA_OUTPORT); - pm_power_off = rts7751r2d_power_off; - - voyagergx_serial_init(); - printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n"); + ctrl_outw(0x0000, PA_OUTPORT); + debug_counter = 0; } - -/* - * The Machine Vector - */ -struct sh_machine_vector mv_rts7751r2d __initmv = { - .mv_name = "RTS7751R2D", - .mv_setup = rts7751r2d_setup, - .mv_nr_irqs = 72, - - .mv_inb = rts7751r2d_inb, - .mv_inw = rts7751r2d_inw, - .mv_inl = rts7751r2d_inl, - .mv_outb = rts7751r2d_outb, - .mv_outw = rts7751r2d_outw, - .mv_outl = rts7751r2d_outl, - - .mv_inb_p = rts7751r2d_inb_p, - .mv_inw_p = rts7751r2d_inw, - .mv_inl_p = rts7751r2d_inl, - .mv_outb_p = rts7751r2d_outb_p, - .mv_outw_p = rts7751r2d_outw, - .mv_outl_p = rts7751r2d_outl, - - .mv_insb = rts7751r2d_insb, - .mv_insw = rts7751r2d_insw, - .mv_insl = rts7751r2d_insl, - .mv_outsb = rts7751r2d_outsb, - .mv_outsw = rts7751r2d_outsw, - .mv_outsl = rts7751r2d_outsl, - - .mv_init_irq = init_rts7751r2d_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_rts7751r2d, -#endif - .mv_irq_demux = rts7751r2d_irq_demux, - -#ifdef CONFIG_USB_SM501 - .mv_consistent_alloc = voyagergx_consistent_alloc, - .mv_consistent_free = voyagergx_consistent_free, -#endif -}; -ALIAS_MV(rts7751r2d) diff --git a/trunk/arch/sh/boards/renesas/sh7710voipgw/Makefile b/trunk/arch/sh/boards/renesas/sh7710voipgw/Makefile deleted file mode 100644 index 77037567633b..000000000000 --- a/trunk/arch/sh/boards/renesas/sh7710voipgw/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y := setup.o diff --git a/trunk/arch/sh/boards/renesas/sh7710voipgw/setup.c b/trunk/arch/sh/boards/renesas/sh7710voipgw/setup.c deleted file mode 100644 index e57e7afab8c6..000000000000 --- a/trunk/arch/sh/boards/renesas/sh7710voipgw/setup.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Renesas Technology SH7710 VoIP Gateway - * - * Copyright (C) 2006 Ranjit Deshpande - * Kenati Technologies Inc. - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - */ -#include -#include -#include -#include -#include - -/* - * Initialize IRQ setting - */ -static void __init sh7710voipgw_init_irq(void) -{ - /* Disable all interrupts in IPR registers */ - ctrl_outw(0x0, INTC_IPRA); - ctrl_outw(0x0, INTC_IPRB); - ctrl_outw(0x0, INTC_IPRC); - ctrl_outw(0x0, INTC_IPRD); - ctrl_outw(0x0, INTC_IPRE); - ctrl_outw(0x0, INTC_IPRF); - ctrl_outw(0x0, INTC_IPRG); - ctrl_outw(0x0, INTC_IPRH); - ctrl_outw(0x0, INTC_IPRI); - - /* Ack all interrupt sources in the IRR0 register */ - ctrl_outb(0x3f, INTC_IRR0); - - /* Use IRQ0 - IRQ3 as active low interrupt lines i.e. disable - * IRL mode. - */ - ctrl_outw(0x2aa, INTC_ICR1); - - /* Now make IPR interrupts */ - make_ipr_irq(TIMER2_IRQ, TIMER2_IPR_ADDR, - TIMER2_IPR_POS, TIMER2_PRIORITY); - make_ipr_irq(WDT_IRQ, WDT_IPR_ADDR, WDT_IPR_POS, WDT_PRIORITY); - - /* SCIF0 */ - make_ipr_irq(SCIF0_ERI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, - SCIF0_PRIORITY); - make_ipr_irq(SCIF0_RXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, - SCIF0_PRIORITY); - make_ipr_irq(SCIF0_BRI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, - SCIF0_PRIORITY); - make_ipr_irq(SCIF0_TXI_IRQ, SCIF0_IPR_ADDR, SCIF0_IPR_POS, - SCIF0_PRIORITY); - - /* DMAC-1 */ - make_ipr_irq(DMTE0_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); - make_ipr_irq(DMTE1_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); - make_ipr_irq(DMTE2_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); - make_ipr_irq(DMTE3_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); - - /* DMAC-2 */ - make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); - make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); - - /* IPSEC */ - make_ipr_irq(IPSEC_IRQ, IPSEC_IPR_ADDR, IPSEC_IPR_POS, IPSEC_PRIORITY); - - /* EDMAC */ - make_ipr_irq(EDMAC0_IRQ, EDMAC0_IPR_ADDR, EDMAC0_IPR_POS, - EDMAC0_PRIORITY); - make_ipr_irq(EDMAC1_IRQ, EDMAC1_IPR_ADDR, EDMAC1_IPR_POS, - EDMAC1_PRIORITY); - make_ipr_irq(EDMAC2_IRQ, EDMAC2_IPR_ADDR, EDMAC2_IPR_POS, - EDMAC2_PRIORITY); - - /* SIOF0 */ - make_ipr_irq(SIOF0_ERI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, - SIOF0_PRIORITY); - make_ipr_irq(SIOF0_TXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, - SIOF0_PRIORITY); - make_ipr_irq(SIOF0_RXI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, - SIOF0_PRIORITY); - make_ipr_irq(SIOF0_CCI_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, - SIOF0_PRIORITY); - - /* SIOF1 */ - make_ipr_irq(SIOF1_ERI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, - SIOF1_PRIORITY); - make_ipr_irq(SIOF1_TXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, - SIOF1_PRIORITY); - make_ipr_irq(SIOF1_RXI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, - SIOF1_PRIORITY); - make_ipr_irq(SIOF1_CCI_IRQ, SIOF1_IPR_ADDR, SIOF1_IPR_POS, - SIOF1_PRIORITY); - - /* SLIC IRQ's */ - make_ipr_irq(IRQ1_IRQ, IRQ1_IPR_ADDR, IRQ1_IPR_POS, IRQ1_PRIORITY); - make_ipr_irq(IRQ2_IRQ, IRQ2_IPR_ADDR, IRQ2_IPR_POS, IRQ2_PRIORITY); -} - -/* - * The Machine Vector - */ -struct sh_machine_vector mv_sh7710voipgw __initmv = { - .mv_name = "SH7710 VoIP Gateway", - .mv_nr_irqs = 104, - .mv_init_irq = sh7710voipgw_init_irq, -}; -ALIAS_MV(sh7710voipgw) diff --git a/trunk/arch/sh/boards/renesas/systemh/io.c b/trunk/arch/sh/boards/renesas/systemh/io.c index cde6e5d192c4..cf979011aa94 100644 --- a/trunk/arch/sh/boards/renesas/systemh/io.c +++ b/trunk/arch/sh/boards/renesas/systemh/io.c @@ -5,25 +5,66 @@ * Based largely on io_se.c. * * I/O routine for Hitachi 7751 Systemh. + * */ + #include #include -#include -#include +#include #include #include +#include +#include "../../drivers/pci/pci-sh7751.h" + +/* + * The 7751 SystemH Engine uses the built-in PCI controller (PCIC) + * of the 7751 processor, and has a SuperIO accessible on its memory + * bus. + */ + +#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) +#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) +#define PCI_IO_AREA SH7751_PCI_IO_BASE +#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE + +#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) #define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area of smc lan chip*/ + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + static inline volatile __u16 * port2adr(unsigned int port) { if (port >= 0x2000) return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); - maybebadio((unsigned long)port); +#if 0 + else + return (volatile __u16 *) (PA_SUPERIO + (port << 1)); +#endif + maybebadio(name,(unsigned long)port); return (volatile __u16*)port; } +/* In case someone configures the kernel w/o PCI support: in that */ +/* scenario, don't ever bother to check for PCI-window addresses */ + +/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ +#if defined(CONFIG_PCI) +#define CHECK_SH7751_PCIIO(port) \ + ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) +#else +#define CHECK_SH7751_PCIIO(port) (0) +#endif + /* * General outline: remap really low stuff [eventually] to SuperIO, * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) @@ -35,8 +76,8 @@ unsigned char sh7751systemh_inb(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned char *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned char *)PCI_IOMAP(port); else if (port <= 0x3F1) return *(volatile unsigned char *)ETHER_IOMAP(port); else @@ -49,13 +90,13 @@ unsigned char sh7751systemh_inb_p(unsigned long port) if (PXSEG(port)) v = *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port)) - v = *(volatile unsigned char *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port)) + v = *(volatile unsigned char *)PCI_IOMAP(port); else if (port <= 0x3F1) v = *(volatile unsigned char *)ETHER_IOMAP(port); else v = (*port2adr(port))&0xff; - ctrl_delay(); + delay(); return v; } @@ -63,14 +104,14 @@ unsigned short sh7751systemh_inw(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned short *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned short *)PCI_IOMAP(port); else if (port >= 0x2000) return *port2adr(port); else if (port <= 0x3F1) return *(volatile unsigned int *)ETHER_IOMAP(port); else - maybebadio(port); + maybebadio(inw, port); return 0; } @@ -78,14 +119,14 @@ unsigned int sh7751systemh_inl(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned int *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned int *)PCI_IOMAP(port); else if (port >= 0x2000) return *port2adr(port); else if (port <= 0x3F1) return *(volatile unsigned int *)ETHER_IOMAP(port); else - maybebadio(port); + maybebadio(inl, port); return 0; } @@ -94,8 +135,8 @@ void sh7751systemh_outb(unsigned char value, unsigned long port) if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned char*)pci_ioaddr(port)) = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned char*)PCI_IOMAP(port)) = value; else if (port <= 0x3F1) *(volatile unsigned char *)ETHER_IOMAP(port) = value; else @@ -106,37 +147,37 @@ void sh7751systemh_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned char*)pci_ioaddr(port)) = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned char*)PCI_IOMAP(port)) = value; else if (port <= 0x3F1) *(volatile unsigned char *)ETHER_IOMAP(port) = value; else *(port2adr(port)) = value; - ctrl_delay(); + delay(); } void sh7751systemh_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned short *)pci_ioaddr(port)) = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned short *)PCI_IOMAP(port)) = value; else if (port >= 0x2000) *port2adr(port) = value; else if (port <= 0x3F1) *(volatile unsigned short *)ETHER_IOMAP(port) = value; else - maybebadio(port); + maybebadio(outw, port); } void sh7751systemh_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned long*)pci_ioaddr(port)) = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned long*)PCI_IOMAP(port)) = value; else - maybebadio(port); + maybebadio(outl, port); } void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count) @@ -153,7 +194,7 @@ void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count) void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count) { - maybebadio(port); + maybebadio(insl, port); } void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count) @@ -170,5 +211,73 @@ void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long cou void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count) { - maybebadio(port); + maybebadio(outsw, port); +} + +/* For read/write calls, just copy generic (pass-thru); PCIMBR is */ +/* already set up. For a larger memory space, these would need to */ +/* reset PCIMBR as needed on a per-call basis... */ + +unsigned char sh7751systemh_readb(unsigned long addr) +{ + return *(volatile unsigned char*)addr; +} + +unsigned short sh7751systemh_readw(unsigned long addr) +{ + return *(volatile unsigned short*)addr; +} + +unsigned int sh7751systemh_readl(unsigned long addr) +{ + return *(volatile unsigned long*)addr; +} + +void sh7751systemh_writeb(unsigned char b, unsigned long addr) +{ + *(volatile unsigned char*)addr = b; +} + +void sh7751systemh_writew(unsigned short b, unsigned long addr) +{ + *(volatile unsigned short*)addr = b; +} + +void sh7751systemh_writel(unsigned int b, unsigned long addr) +{ + *(volatile unsigned long*)addr = b; +} + + + +/* Map ISA bus address to the real address. Only for PCMCIA. */ + +/* ISA page descriptor. */ +static __u32 sh_isa_memmap[256]; + +#if 0 +static int +sh_isa_mmap(__u32 start, __u32 length, __u32 offset) +{ + int idx; + + if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) + return -1; + + idx = start >> 12; + sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); + printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", + start, length, offset, idx, sh_isa_memmap[idx]); + return 0; +} +#endif + +unsigned long +sh7751systemh_isa_port2addr(unsigned long offset) +{ + int idx; + + idx = (offset >> 12) & 0xff; + offset &= 0xfff; + return sh_isa_memmap[idx] + offset; } diff --git a/trunk/arch/sh/boards/renesas/systemh/irq.c b/trunk/arch/sh/boards/renesas/systemh/irq.c index 8d016dae2333..8372d967f601 100644 --- a/trunk/arch/sh/boards/renesas/systemh/irq.c +++ b/trunk/arch/sh/boards/renesas/systemh/irq.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include /* address of external interrupt mask register @@ -57,9 +57,12 @@ static void shutdown_systemh_irq(unsigned int irq) static void disable_systemh_irq(unsigned int irq) { if (systemh_irq_mask_register) { + unsigned long flags; unsigned long val, mask = 0x01 << 1; /* Clear the "irq"th bit in the mask and set it in the request */ + local_irq_save(flags); + val = ctrl_inl((unsigned long)systemh_irq_mask_register); val &= ~mask; ctrl_outl(val, (unsigned long)systemh_irq_mask_register); @@ -67,18 +70,23 @@ static void disable_systemh_irq(unsigned int irq) val = ctrl_inl((unsigned long)systemh_irq_request_register); val |= mask; ctrl_outl(val, (unsigned long)systemh_irq_request_register); + + local_irq_restore(flags); } } static void enable_systemh_irq(unsigned int irq) { if (systemh_irq_mask_register) { + unsigned long flags; unsigned long val, mask = 0x01 << 1; /* Set "irq"th bit in the mask register */ + local_irq_save(flags); val = ctrl_inl((unsigned long)systemh_irq_mask_register); val |= mask; ctrl_outl(val, (unsigned long)systemh_irq_mask_register); + local_irq_restore(flags); } } diff --git a/trunk/arch/sh/boards/renesas/systemh/setup.c b/trunk/arch/sh/boards/renesas/systemh/setup.c index a8467bf90c25..826fa3d7669c 100644 --- a/trunk/arch/sh/boards/renesas/systemh/setup.c +++ b/trunk/arch/sh/boards/renesas/systemh/setup.c @@ -15,21 +15,28 @@ * for more details. */ #include +#include +#include #include -#include extern void make_systemh_irq(unsigned int irq); +const char *get_system_type(void) +{ + return "7751 SystemH"; +} + /* * Initialize IRQ setting */ -static void __init sh7751systemh_init_irq(void) +void __init init_7751systemh_IRQ(void) { +/* make_ipr_irq(10, BCR_ILCRD, 1, 0x0f-10); LAN */ +/* make_ipr_irq(14, BCR_ILCRA, 2, 0x0f-4); */ make_systemh_irq(0xb); /* Ethernet interrupt */ } struct sh_machine_vector mv_7751systemh __initmv = { - .mv_name = "7751 SystemH", .mv_nr_irqs = 72, .mv_inb = sh7751systemh_inb, @@ -53,6 +60,21 @@ struct sh_machine_vector mv_7751systemh __initmv = { .mv_outsw = sh7751systemh_outsw, .mv_outsl = sh7751systemh_outsl, - .mv_init_irq = sh7751system_init_irq, + .mv_readb = sh7751systemh_readb, + .mv_readw = sh7751systemh_readw, + .mv_readl = sh7751systemh_readl, + .mv_writeb = sh7751systemh_writeb, + .mv_writew = sh7751systemh_writew, + .mv_writel = sh7751systemh_writel, + + .mv_isa_port2addr = sh7751systemh_isa_port2addr, + + .mv_init_irq = init_7751systemh_IRQ, }; ALIAS_MV(7751systemh) + +int __init platform_setup(void) +{ + return 0; +} + diff --git a/trunk/arch/sh/boards/saturn/setup.c b/trunk/arch/sh/boards/saturn/setup.c index a3a37c9aad2e..bea6c572ad82 100644 --- a/trunk/arch/sh/boards/saturn/setup.c +++ b/trunk/arch/sh/boards/saturn/setup.c @@ -9,17 +9,22 @@ */ #include #include + #include #include #include extern int saturn_irq_demux(int irq_nr); +const char *get_system_type(void) +{ + return "Sega Saturn"; +} + /* * The Machine Vector */ struct sh_machine_vector mv_saturn __initmv = { - .mv_name = "Sega Saturn", .mv_nr_irqs = 80, /* Fix this later */ .mv_isa_port2addr = saturn_isa_port2addr, @@ -28,4 +33,11 @@ struct sh_machine_vector mv_saturn __initmv = { .mv_ioremap = saturn_ioremap, .mv_iounmap = saturn_iounmap, }; + ALIAS_MV(saturn) + +int __init platform_setup(void) +{ + return 0; +} + diff --git a/trunk/arch/sh/boards/se/7300/io.c b/trunk/arch/sh/boards/se/7300/io.c index 8a03d7a52a7c..f449a94ddffd 100644 --- a/trunk/arch/sh/boards/se/7300/io.c +++ b/trunk/arch/sh/boards/se/7300/io.c @@ -9,8 +9,8 @@ */ #include +#include #include -#include #define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a) @@ -99,7 +99,6 @@ bad_outb(struct iop *p, unsigned char value, unsigned long port) badio(inw, port); } -#ifdef CONFIG_SMC91X /* MSTLANEX01 LAN at 0xb400:0000 */ static struct iop laniop = { .start = 0x300, @@ -111,7 +110,6 @@ static struct iop laniop = { .outb = simple_outb, .outw = simple_outw, }; -#endif /* NE2000 pc card NIC */ static struct iop neiop = { @@ -125,7 +123,6 @@ static struct iop neiop = { .outw = simple_outw, }; -#ifdef CONFIG_IDE /* CF in CF slot */ static struct iop cfiop = { .base = 0xb0600000, @@ -135,13 +132,12 @@ static struct iop cfiop = { .outb = pcc_outb, .outw = simple_outw, }; -#endif static __inline__ struct iop * port2iop(unsigned long port) { if (0) ; -#if defined(CONFIG_SMC91X) +#if defined(CONFIG_SMC91111) else if (laniop.check(&laniop, port)) return &laniop; #endif diff --git a/trunk/arch/sh/boards/se/7300/irq.c b/trunk/arch/sh/boards/se/7300/irq.c index ad1034f98a29..216a78d1a108 100644 --- a/trunk/arch/sh/boards/se/7300/irq.c +++ b/trunk/arch/sh/boards/se/7300/irq.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include /* * Initialize IRQ setting diff --git a/trunk/arch/sh/boards/se/7300/led.c b/trunk/arch/sh/boards/se/7300/led.c index 4d03bb7774be..ad51f0a9c1e3 100644 --- a/trunk/arch/sh/boards/se/7300/led.c +++ b/trunk/arch/sh/boards/se/7300/led.c @@ -12,10 +12,24 @@ */ #include -#include +#include + +static void +mach_led(int position, int value) +{ + volatile unsigned short *p = (volatile unsigned short *) PA_LED; + + if (value) { + *p |= (1 << 8); + } else { + *p &= ~(1 << 8); + } +} + /* Cycle the LED's in the clasic Knightrider/Sun pattern */ -void heartbeat_7300se(void) +void +heartbeat_7300se(void) { static unsigned int cnt = 0, period = 0; volatile unsigned short *p = (volatile unsigned short *) PA_LED; diff --git a/trunk/arch/sh/boards/se/7300/setup.c b/trunk/arch/sh/boards/se/7300/setup.c index 6f082a722d42..ebcd98d4c081 100644 --- a/trunk/arch/sh/boards/se/7300/setup.c +++ b/trunk/arch/sh/boards/se/7300/setup.c @@ -9,16 +9,23 @@ #include #include -#include +#include +#include void heartbeat_7300se(void); void init_7300se_IRQ(void); +const char * +get_system_type(void) +{ + return "SolutionEngine 7300"; +} + /* * The Machine Vector */ + struct sh_machine_vector mv_7300se __initmv = { - .mv_name = "SolutionEngine 7300", .mv_nr_irqs = 109, .mv_inb = sh7300se_inb, .mv_inw = sh7300se_inw, @@ -46,4 +53,13 @@ struct sh_machine_vector mv_7300se __initmv = { .mv_heartbeat = heartbeat_7300se, #endif }; + ALIAS_MV(7300se) +/* + * Initialize the board + */ +void __init +platform_setup(void) +{ + +} diff --git a/trunk/arch/sh/boards/se/73180/io.c b/trunk/arch/sh/boards/se/73180/io.c index 72715575458b..755df5ac4a4e 100644 --- a/trunk/arch/sh/boards/se/73180/io.c +++ b/trunk/arch/sh/boards/se/73180/io.c @@ -99,7 +99,6 @@ bad_outb(struct iop *p, unsigned char value, unsigned long port) badio(inw, port); } -#ifdef CONFIG_SMC91X /* MSTLANEX01 LAN at 0xb400:0000 */ static struct iop laniop = { .start = 0x300, @@ -111,7 +110,6 @@ static struct iop laniop = { .outb = simple_outb, .outw = simple_outw, }; -#endif /* NE2000 pc card NIC */ static struct iop neiop = { @@ -125,7 +123,6 @@ static struct iop neiop = { .outw = simple_outw, }; -#ifdef CONFIG_IDE /* CF in CF slot */ static struct iop cfiop = { .base = 0xb0600000, @@ -135,13 +132,12 @@ static struct iop cfiop = { .outb = pcc_outb, .outw = simple_outw, }; -#endif static __inline__ struct iop * port2iop(unsigned long port) { if (0) ; -#if defined(CONFIG_SMC91X) +#if defined(CONFIG_SMC91111) else if (laniop.check(&laniop, port)) return &laniop; #endif diff --git a/trunk/arch/sh/boards/se/73180/irq.c b/trunk/arch/sh/boards/se/73180/irq.c index 2c62b8ea350e..4344d0ef24aa 100644 --- a/trunk/arch/sh/boards/se/73180/irq.c +++ b/trunk/arch/sh/boards/se/73180/irq.c @@ -7,6 +7,7 @@ * Modified for SH-Mobile SolutionEngine 73180 Support * by YOSHII Takashi * + * */ #include @@ -15,6 +16,14 @@ #include #include +static int +intreq2irq(int i) +{ + if (i == 5) + return 10; + return 32 + 7 - i; +} + static int irq2intreq(int irq) { diff --git a/trunk/arch/sh/boards/se/73180/led.c b/trunk/arch/sh/boards/se/73180/led.c index 4b72e9a3ead9..610439fde6ee 100644 --- a/trunk/arch/sh/boards/se/73180/led.c +++ b/trunk/arch/sh/boards/se/73180/led.c @@ -14,8 +14,21 @@ #include #include +static void +mach_led(int position, int value) +{ + volatile unsigned short *p = (volatile unsigned short *) PA_LED; + + if (value) { + *p |= (1 << LED_SHIFT); + } else { + *p &= ~(1 << LED_SHIFT); + } +} + /* Cycle the LED's in the clasic Knightrider/Sun pattern */ -void heartbeat_73180se(void) +void +heartbeat_73180se(void) { static unsigned int cnt = 0, period = 0; volatile unsigned short *p = (volatile unsigned short *) PA_LED; diff --git a/trunk/arch/sh/boards/se/73180/setup.c b/trunk/arch/sh/boards/se/73180/setup.c index b38ef50a160a..cdb7b5f8d942 100644 --- a/trunk/arch/sh/boards/se/73180/setup.c +++ b/trunk/arch/sh/boards/se/73180/setup.c @@ -11,17 +11,23 @@ #include #include -#include -#include +#include +#include void heartbeat_73180se(void); void init_73180se_IRQ(void); +const char * +get_system_type(void) +{ + return "SolutionEngine 73180"; +} + /* * The Machine Vector */ + struct sh_machine_vector mv_73180se __initmv = { - .mv_name = "SolutionEngine 73180", .mv_nr_irqs = 108, .mv_inb = sh73180se_inb, .mv_inw = sh73180se_inw, @@ -45,9 +51,17 @@ struct sh_machine_vector mv_73180se __initmv = { .mv_outsl = sh73180se_outsl, .mv_init_irq = init_73180se_IRQ, - .mv_irq_demux = shmse_irq_demux, #ifdef CONFIG_HEARTBEAT .mv_heartbeat = heartbeat_73180se, #endif }; + ALIAS_MV(73180se) +/* + * Initialize the board + */ +void __init +platform_setup(void) +{ + +} diff --git a/trunk/arch/sh/boards/se/7343/Makefile b/trunk/arch/sh/boards/se/7343/Makefile deleted file mode 100644 index 4291069c0b4f..000000000000 --- a/trunk/arch/sh/boards/se/7343/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# Makefile for the 7343 SolutionEngine specific parts of the kernel -# - -obj-y := setup.o io.o irq.o - -obj-$(CONFIG_HEARTBEAT) += led.o diff --git a/trunk/arch/sh/boards/se/7343/io.c b/trunk/arch/sh/boards/se/7343/io.c deleted file mode 100644 index 646661a146ad..000000000000 --- a/trunk/arch/sh/boards/se/7343/io.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * arch/sh/boards/se/7343/io.c - * - * I/O routine for SH-Mobile3AS 7343 SolutionEngine. - * - */ - -#include -#include -#include -#include - -#define badio(fn, a) panic("bad i/o operation %s for %08lx.", #fn, a) - -struct iop { - unsigned long start, end; - unsigned long base; - struct iop *(*check) (struct iop * p, unsigned long port); - unsigned char (*inb) (struct iop * p, unsigned long port); - unsigned short (*inw) (struct iop * p, unsigned long port); - void (*outb) (struct iop * p, unsigned char value, unsigned long port); - void (*outw) (struct iop * p, unsigned short value, unsigned long port); -}; - -struct iop * -simple_check(struct iop *p, unsigned long port) -{ - static int count; - - if (count < 100) - count++; - - port &= 0xFFFF; - - if ((p->start <= port) && (port <= p->end)) - return p; - else - badio(check, port); -} - -struct iop * -ide_check(struct iop *p, unsigned long port) -{ - if (((0x1f0 <= port) && (port <= 0x1f7)) || (port == 0x3f7)) - return p; - return NULL; -} - -unsigned char -simple_inb(struct iop *p, unsigned long port) -{ - return *(unsigned char *) (p->base + port); -} - -unsigned short -simple_inw(struct iop *p, unsigned long port) -{ - return *(unsigned short *) (p->base + port); -} - -void -simple_outb(struct iop *p, unsigned char value, unsigned long port) -{ - *(unsigned char *) (p->base + port) = value; -} - -void -simple_outw(struct iop *p, unsigned short value, unsigned long port) -{ - *(unsigned short *) (p->base + port) = value; -} - -unsigned char -pcc_inb(struct iop *p, unsigned long port) -{ - unsigned long addr = p->base + port + 0x40000; - unsigned long v; - - if (port & 1) - addr += 0x00400000; - v = *(volatile unsigned char *) addr; - return v; -} - -void -pcc_outb(struct iop *p, unsigned char value, unsigned long port) -{ - unsigned long addr = p->base + port + 0x40000; - - if (port & 1) - addr += 0x00400000; - *(volatile unsigned char *) addr = value; -} - -unsigned char -bad_inb(struct iop *p, unsigned long port) -{ - badio(inb, port); -} - -void -bad_outb(struct iop *p, unsigned char value, unsigned long port) -{ - badio(inw, port); -} - -#ifdef CONFIG_SMC91X -/* MSTLANEX01 LAN at 0xb400:0000 */ -static struct iop laniop = { - .start = 0x00, - .end = 0x0F, - .base = 0x04000000, - .check = simple_check, - .inb = simple_inb, - .inw = simple_inw, - .outb = simple_outb, - .outw = simple_outw, -}; -#endif - -#ifdef CONFIG_NE2000 -/* NE2000 pc card NIC */ -static struct iop neiop = { - .start = 0x280, - .end = 0x29f, - .base = 0xb0600000 + 0x80, /* soft 0x280 -> hard 0x300 */ - .check = simple_check, - .inb = pcc_inb, - .inw = simple_inw, - .outb = pcc_outb, - .outw = simple_outw, -}; -#endif - -#ifdef CONFIG_IDE -/* CF in CF slot */ -static struct iop cfiop = { - .base = 0xb0600000, - .check = ide_check, - .inb = pcc_inb, - .inw = simple_inw, - .outb = pcc_outb, - .outw = simple_outw, -}; -#endif - -static __inline__ struct iop * -port2iop(unsigned long port) -{ - if (0) ; -#if defined(CONFIG_SMC91X) - else if (laniop.check(&laniop, port)) - return &laniop; -#endif -#if defined(CONFIG_NE2000) - else if (neiop.check(&neiop, port)) - return &neiop; -#endif -#if defined(CONFIG_IDE) - else if (cfiop.check(&cfiop, port)) - return &cfiop; -#endif - else - return NULL; -} - -static inline void -delay(void) -{ - ctrl_inw(0xac000000); - ctrl_inw(0xac000000); -} - -unsigned char -sh7343se_inb(unsigned long port) -{ - struct iop *p = port2iop(port); - return (p->inb) (p, port); -} - -unsigned char -sh7343se_inb_p(unsigned long port) -{ - unsigned char v = sh7343se_inb(port); - delay(); - return v; -} - -unsigned short -sh7343se_inw(unsigned long port) -{ - struct iop *p = port2iop(port); - return (p->inw) (p, port); -} - -unsigned int -sh7343se_inl(unsigned long port) -{ - badio(inl, port); -} - -void -sh7343se_outb(unsigned char value, unsigned long port) -{ - struct iop *p = port2iop(port); - (p->outb) (p, value, port); -} - -void -sh7343se_outb_p(unsigned char value, unsigned long port) -{ - sh7343se_outb(value, port); - delay(); -} - -void -sh7343se_outw(unsigned short value, unsigned long port) -{ - struct iop *p = port2iop(port); - (p->outw) (p, value, port); -} - -void -sh7343se_outl(unsigned int value, unsigned long port) -{ - badio(outl, port); -} - -void -sh7343se_insb(unsigned long port, void *addr, unsigned long count) -{ - unsigned char *a = addr; - struct iop *p = port2iop(port); - while (count--) - *a++ = (p->inb) (p, port); -} - -void -sh7343se_insw(unsigned long port, void *addr, unsigned long count) -{ - unsigned short *a = addr; - struct iop *p = port2iop(port); - while (count--) - *a++ = (p->inw) (p, port); -} - -void -sh7343se_insl(unsigned long port, void *addr, unsigned long count) -{ - badio(insl, port); -} - -void -sh7343se_outsb(unsigned long port, const void *addr, unsigned long count) -{ - unsigned char *a = (unsigned char *) addr; - struct iop *p = port2iop(port); - while (count--) - (p->outb) (p, *a++, port); -} - -void -sh7343se_outsw(unsigned long port, const void *addr, unsigned long count) -{ - unsigned short *a = (unsigned short *) addr; - struct iop *p = port2iop(port); - while (count--) - (p->outw) (p, *a++, port); -} - -void -sh7343se_outsl(unsigned long port, const void *addr, unsigned long count) -{ - badio(outsw, port); -} diff --git a/trunk/arch/sh/boards/se/7343/irq.c b/trunk/arch/sh/boards/se/7343/irq.c deleted file mode 100644 index b41e3d4ea37c..000000000000 --- a/trunk/arch/sh/boards/se/7343/irq.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * arch/sh/boards/se/7343/irq.c - * - */ - -#include -#include -#include -#include -#include -#include -#include - -static void -disable_intreq_irq(unsigned int irq) -{ - int bit = irq - OFFCHIP_IRQ_BASE; - u16 val; - - val = ctrl_inw(PA_CPLD_IMSK); - val |= 1 << bit; - ctrl_outw(val, PA_CPLD_IMSK); -} - -static void -enable_intreq_irq(unsigned int irq) -{ - int bit = irq - OFFCHIP_IRQ_BASE; - u16 val; - - val = ctrl_inw(PA_CPLD_IMSK); - val &= ~(1 << bit); - ctrl_outw(val, PA_CPLD_IMSK); -} - -static void -mask_and_ack_intreq_irq(unsigned int irq) -{ - disable_intreq_irq(irq); -} - -static unsigned int -startup_intreq_irq(unsigned int irq) -{ - enable_intreq_irq(irq); - return 0; -} - -static void -shutdown_intreq_irq(unsigned int irq) -{ - disable_intreq_irq(irq); -} - -static void -end_intreq_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_intreq_irq(irq); -} - -static struct hw_interrupt_type intreq_irq_type = { - .typename = "FPGA-IRQ", - .startup = startup_intreq_irq, - .shutdown = shutdown_intreq_irq, - .enable = enable_intreq_irq, - .disable = disable_intreq_irq, - .ack = mask_and_ack_intreq_irq, - .end = end_intreq_irq -}; - -static void -make_intreq_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - irq_desc[irq].handler = &intreq_irq_type; - disable_intreq_irq(irq); -} - -int -shmse_irq_demux(int irq) -{ - int bit; - volatile u16 val; - - if (irq == IRQ5_IRQ) { - /* Read status Register */ - val = ctrl_inw(PA_CPLD_ST); - bit = ffs(val); - if (bit != 0) - return OFFCHIP_IRQ_BASE + bit - 1; - } - return irq; -} - -/* IRQ5 is multiplexed between the following sources: - * 1. PC Card socket - * 2. Extension slot - * 3. USB Controller - * 4. Serial Controller - * - * We configure IRQ5 as a cascade IRQ. - */ -static struct irqaction irq5 = { no_action, 0, CPU_MASK_NONE, "IRQ5-cascade", - NULL, NULL}; - -/* - * Initialize IRQ setting - */ -void __init -init_7343se_IRQ(void) -{ - /* Setup Multiplexed interrupts */ - ctrl_outw(8, PA_CPLD_MODESET); /* Set all CPLD interrupts to active - * low. - */ - /* Mask all CPLD controller interrupts */ - ctrl_outw(0x0fff, PA_CPLD_IMSK); - - /* PC Card interrupts */ - make_intreq_irq(PC_IRQ0); - make_intreq_irq(PC_IRQ1); - make_intreq_irq(PC_IRQ2); - make_intreq_irq(PC_IRQ3); - - /* Extension Slot Interrupts */ - make_intreq_irq(EXT_IRQ0); - make_intreq_irq(EXT_IRQ1); - make_intreq_irq(EXT_IRQ2); - make_intreq_irq(EXT_IRQ3); - - /* USB Controller interrupts */ - make_intreq_irq(USB_IRQ0); - make_intreq_irq(USB_IRQ1); - - /* Serial Controller interrupts */ - make_intreq_irq(UART_IRQ0); - make_intreq_irq(UART_IRQ1); - - /* Setup all external interrupts to be active low */ - ctrl_outw(0xaaaa, INTC_ICR1); - - make_ipr_irq(IRQ5_IRQ, IRQ5_IPR_ADDR+2, IRQ5_IPR_POS, IRQ5_PRIORITY); - setup_irq(IRQ5_IRQ, &irq5); - /* Set port control to use IRQ5 */ - *(u16 *)0xA4050108 &= ~0xc; - - make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); - make_ipr_irq(VPU_IRQ, VPU_IPR_ADDR, VPU_IPR_POS, 8); - - ctrl_outb(0x0f, INTC_IMCR5); /* enable SCIF IRQ */ - - make_ipr_irq(DMTE0_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(DMTE1_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(DMTE2_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(DMTE3_IRQ, DMA1_IPR_ADDR, DMA1_IPR_POS, DMA1_PRIORITY); - make_ipr_irq(DMTE4_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); - make_ipr_irq(DMTE5_IRQ, DMA2_IPR_ADDR, DMA2_IPR_POS, DMA2_PRIORITY); - - /* I2C block */ - make_ipr_irq(IIC0_ALI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); - make_ipr_irq(IIC0_TACKI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, - IIC0_PRIORITY); - make_ipr_irq(IIC0_WAITI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, - IIC0_PRIORITY); - make_ipr_irq(IIC0_DTEI_IRQ, IIC0_IPR_ADDR, IIC0_IPR_POS, IIC0_PRIORITY); - - make_ipr_irq(IIC1_ALI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY); - make_ipr_irq(IIC1_TACKI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, - IIC1_PRIORITY); - make_ipr_irq(IIC1_WAITI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, - IIC1_PRIORITY); - make_ipr_irq(IIC1_DTEI_IRQ, IIC1_IPR_ADDR, IIC1_IPR_POS, IIC1_PRIORITY); - - /* SIOF */ - make_ipr_irq(SIOF0_IRQ, SIOF0_IPR_ADDR, SIOF0_IPR_POS, SIOF0_PRIORITY); - - /* SIU */ - make_ipr_irq(SIU_IRQ, SIU_IPR_ADDR, SIU_IPR_POS, SIU_PRIORITY); - - /* VIO interrupt */ - make_ipr_irq(CEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); - make_ipr_irq(BEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); - make_ipr_irq(VEU_IRQ, VIO_IPR_ADDR, VIO_IPR_POS, VIO_PRIORITY); - - /*MFI interrupt*/ - - make_ipr_irq(MFI_IRQ, MFI_IPR_ADDR, MFI_IPR_POS, MFI_PRIORITY); - - /* LCD controller */ - make_ipr_irq(LCDC_IRQ, LCDC_IPR_ADDR, LCDC_IPR_POS, LCDC_PRIORITY); - ctrl_outw(0x2000, PA_MRSHPC + 0x0c); /* mrshpc irq enable */ -} diff --git a/trunk/arch/sh/boards/se/7343/led.c b/trunk/arch/sh/boards/se/7343/led.c deleted file mode 100644 index 6a439cf83e46..000000000000 --- a/trunk/arch/sh/boards/se/7343/led.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * arch/sh/boards/se/7343/led.c - * - */ - -#include -#include -#include - -/* Cycle the LED's in the clasic Knightrider/Sun pattern */ -void heartbeat_7343se(void) -{ - static unsigned int cnt = 0, period = 0; - volatile unsigned short *p = (volatile unsigned short *) PA_LED; - static unsigned bit = 0, up = 1; - - cnt += 1; - if (cnt < period) { - return; - } - - cnt = 0; - - /* Go through the points (roughly!): - * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110 - */ - period = 110 - ((300 << FSHIFT) / ((avenrun[0] / 5) + (3 << FSHIFT))); - - if (up) { - if (bit == 7) { - bit--; - up = 0; - } else { - bit++; - } - } else { - if (bit == 0) { - bit++; - up = 1; - } else { - bit--; - } - } - *p = 1 << (bit + LED_SHIFT); - -} diff --git a/trunk/arch/sh/boards/se/7343/setup.c b/trunk/arch/sh/boards/se/7343/setup.c deleted file mode 100644 index 787322291fb3..000000000000 --- a/trunk/arch/sh/boards/se/7343/setup.c +++ /dev/null @@ -1,84 +0,0 @@ -#include -#include -#include -#include -#include -#include - -void heartbeat_7343se(void); -void init_7343se_IRQ(void); - -static struct resource smc91x_resources[] = { - [0] = { - .start = 0x10000000, - .end = 0x1000000F, - .flags = IORESOURCE_MEM, - }, - [1] = { - /* - * shared with other devices via externel - * interrupt controller in FPGA... - */ - .start = EXT_IRQ2, - .end = EXT_IRQ2, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device smc91x_device = { - .name = "smc91x", - .id = 0, - .num_resources = ARRAY_SIZE(smc91x_resources), - .resource = smc91x_resources, -}; - -static struct platform_device *smc91x_platform_devices[] __initdata = { - &smc91x_device, -}; - -static int __init sh7343se_devices_setup(void) -{ - return platform_add_devices(smc91x_platform_devices, - ARRAY_SIZE(smc91x_platform_devices)); -} - -static void __init sh7343se_setup(char **cmdline_p) -{ - device_initcall(sh7343se_devices_setup); -} - -/* - * The Machine Vector - */ -struct sh_machine_vector mv_7343se __initmv = { - .mv_name = "SolutionEngine 7343", - .mv_setup = sh7343se_setup, - .mv_nr_irqs = 108, - .mv_inb = sh7343se_inb, - .mv_inw = sh7343se_inw, - .mv_inl = sh7343se_inl, - .mv_outb = sh7343se_outb, - .mv_outw = sh7343se_outw, - .mv_outl = sh7343se_outl, - - .mv_inb_p = sh7343se_inb_p, - .mv_inw_p = sh7343se_inw, - .mv_inl_p = sh7343se_inl, - .mv_outb_p = sh7343se_outb_p, - .mv_outw_p = sh7343se_outw, - .mv_outl_p = sh7343se_outl, - - .mv_insb = sh7343se_insb, - .mv_insw = sh7343se_insw, - .mv_insl = sh7343se_insl, - .mv_outsb = sh7343se_outsb, - .mv_outsw = sh7343se_outsw, - .mv_outsl = sh7343se_outsl, - - .mv_init_irq = init_7343se_IRQ, - .mv_irq_demux = shmse_irq_demux, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_7343se, -#endif -}; -ALIAS_MV(7343se) diff --git a/trunk/arch/sh/boards/se/770x/Makefile b/trunk/arch/sh/boards/se/770x/Makefile index 9a5035f80ec0..be89a73cc418 100644 --- a/trunk/arch/sh/boards/se/770x/Makefile +++ b/trunk/arch/sh/boards/se/770x/Makefile @@ -2,5 +2,5 @@ # Makefile for the 770x SolutionEngine specific parts of the kernel # -obj-y := setup.o io.o irq.o -obj-$(CONFIG_HEARTBEAT) += led.o +obj-y := mach.o setup.o io.o irq.o led.o + diff --git a/trunk/arch/sh/boards/se/770x/io.c b/trunk/arch/sh/boards/se/770x/io.c index 9941949331ab..9a39ee963143 100644 --- a/trunk/arch/sh/boards/se/770x/io.c +++ b/trunk/arch/sh/boards/se/770x/io.c @@ -1,4 +1,4 @@ -/* $Id: io.c,v 1.7 2006/02/05 21:55:29 lethal Exp $ +/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $ * * linux/arch/sh/kernel/io_se.c * @@ -11,7 +11,7 @@ #include #include #include -#include +#include /* SH pcmcia io window base, start and end. */ int sh_pcic_io_wbase = 0xb8400000; @@ -20,6 +20,11 @@ int sh_pcic_io_stop; int sh_pcic_io_type; int sh_pcic_io_dummy; +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + /* MS7750 requires special versions of in*, out* routines, since PC-like io ports are located at upper half byte of 16-bit word which can be accessed only with 16-bit wide. */ @@ -47,6 +52,10 @@ shifted_port(unsigned long port) return 1; } +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + unsigned char se_inb(unsigned long port) { if (sh_pcic_io_start <= port && port <= sh_pcic_io_stop) @@ -67,7 +76,7 @@ unsigned char se_inb_p(unsigned long port) v = (*port2adr(port) >> 8); else v = (*port2adr(port))&0xff; - ctrl_delay(); + delay(); return v; } @@ -77,13 +86,13 @@ unsigned short se_inw(unsigned long port) (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) return *port2adr(port); else - maybebadio(port); + maybebadio(inw, port); return 0; } unsigned int se_inl(unsigned long port) { - maybebadio(port); + maybebadio(inl, port); return 0; } @@ -105,7 +114,7 @@ void se_outb_p(unsigned char value, unsigned long port) *(port2adr(port)) = value << 8; else *(port2adr(port)) = value; - ctrl_delay(); + delay(); } void se_outw(unsigned short value, unsigned long port) @@ -114,12 +123,12 @@ void se_outw(unsigned short value, unsigned long port) (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) *port2adr(port) = value; else - maybebadio(port); + maybebadio(outw, port); } void se_outl(unsigned int value, unsigned long port) { - maybebadio(port); + maybebadio(outl, port); } void se_insb(unsigned long port, void *addr, unsigned long count) @@ -150,7 +159,7 @@ void se_insw(unsigned long port, void *addr, unsigned long count) void se_insl(unsigned long port, void *addr, unsigned long count) { - maybebadio(port); + maybebadio(insl, port); } void se_outsb(unsigned long port, const void *addr, unsigned long count) @@ -181,5 +190,37 @@ void se_outsw(unsigned long port, const void *addr, unsigned long count) void se_outsl(unsigned long port, const void *addr, unsigned long count) { - maybebadio(port); + maybebadio(outsw, port); +} + +/* Map ISA bus address to the real address. Only for PCMCIA. */ + +/* ISA page descriptor. */ +static __u32 sh_isa_memmap[256]; + +static int +sh_isa_mmap(__u32 start, __u32 length, __u32 offset) +{ + int idx; + + if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) + return -1; + + idx = start >> 12; + sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); +#if 0 + printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", + start, length, offset, idx, sh_isa_memmap[idx]); +#endif + return 0; +} + +unsigned long +se_isa_port2addr(unsigned long offset) +{ + int idx; + + idx = (offset >> 12) & 0xff; + offset &= 0xfff; + return sh_isa_memmap[idx] + offset; } diff --git a/trunk/arch/sh/boards/se/770x/irq.c b/trunk/arch/sh/boards/se/770x/irq.c index cff6700bbafd..3e558716ce10 100644 --- a/trunk/arch/sh/boards/se/770x/irq.c +++ b/trunk/arch/sh/boards/se/770x/irq.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include /* * Initialize IRQ setting diff --git a/trunk/arch/sh/boards/se/770x/led.c b/trunk/arch/sh/boards/se/770x/led.c index daf7b1ee786a..3cddbda025fc 100644 --- a/trunk/arch/sh/boards/se/770x/led.c +++ b/trunk/arch/sh/boards/se/770x/led.c @@ -9,8 +9,22 @@ * This file contains Solution Engine specific LED code. */ +#include + +static void mach_led(int position, int value) +{ + volatile unsigned short* p = (volatile unsigned short*)PA_LED; + + if (value) { + *p |= (1<<8); + } else { + *p &= ~(1<<8); + } +} + +#ifdef CONFIG_HEARTBEAT + #include -#include /* Cycle the LED's in the clasic Knightrider/Sun pattern */ void heartbeat_se(void) @@ -50,3 +64,4 @@ void heartbeat_se(void) *p = 1<<(bit+8); } +#endif /* CONFIG_HEARTBEAT */ diff --git a/trunk/arch/sh/boards/se/770x/mach.c b/trunk/arch/sh/boards/se/770x/mach.c new file mode 100644 index 000000000000..6ec07bd3dcf1 --- /dev/null +++ b/trunk/arch/sh/boards/se/770x/mach.c @@ -0,0 +1,67 @@ +/* + * linux/arch/sh/kernel/mach_se.c + * + * Copyright (C) 2000 Stuart Menefy (stuart.menefy@st.com) + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Machine vector for the Hitachi SolutionEngine + */ + +#include + +#include +#include +#include + +#include + +void heartbeat_se(void); +void setup_se(void); +void init_se_IRQ(void); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_se __initmv = { +#if defined(CONFIG_CPU_SH4) + .mv_nr_irqs = 48, +#elif defined(CONFIG_CPU_SUBTYPE_SH7708) + .mv_nr_irqs = 32, +#elif defined(CONFIG_CPU_SUBTYPE_SH7709) + .mv_nr_irqs = 61, +#elif defined(CONFIG_CPU_SUBTYPE_SH7705) + .mv_nr_irqs = 86, +#endif + + .mv_inb = se_inb, + .mv_inw = se_inw, + .mv_inl = se_inl, + .mv_outb = se_outb, + .mv_outw = se_outw, + .mv_outl = se_outl, + + .mv_inb_p = se_inb_p, + .mv_inw_p = se_inw, + .mv_inl_p = se_inl, + .mv_outb_p = se_outb_p, + .mv_outw_p = se_outw, + .mv_outl_p = se_outl, + + .mv_insb = se_insb, + .mv_insw = se_insw, + .mv_insl = se_insl, + .mv_outsb = se_outsb, + .mv_outsw = se_outsw, + .mv_outsl = se_outsl, + + .mv_isa_port2addr = se_isa_port2addr, + + .mv_init_irq = init_se_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_se, +#endif +}; +ALIAS_MV(se) diff --git a/trunk/arch/sh/boards/se/770x/setup.c b/trunk/arch/sh/boards/se/770x/setup.c index f3f82b7c8217..7d1a071727cc 100644 --- a/trunk/arch/sh/boards/se/770x/setup.c +++ b/trunk/arch/sh/boards/se/770x/setup.c @@ -7,17 +7,15 @@ * Hitachi SolutionEngine Support. * */ + #include #include + #include #include #include -#include -#include -#include - -void heartbeat_se(void); -void init_se_IRQ(void); +#include +#include /* * Configure the Super I/O chip @@ -28,8 +26,7 @@ static void __init smsc_config(int index, int data) outb_p(data, DATA_PORT); } -/* XXX: Another candidate for a more generic cchip machine vector */ -static void __init smsc_setup(char **cmdline_p) +static void __init init_smsc(void) { outb_p(CONFIG_ENTER, CONFIG_PORT); outb_p(CONFIG_ENTER, CONFIG_PORT); @@ -72,46 +69,16 @@ static void __init smsc_setup(char **cmdline_p) outb_p(CONFIG_EXIT, CONFIG_PORT); } +const char *get_system_type(void) +{ + return "SolutionEngine"; +} + /* - * The Machine Vector + * Initialize the board */ -struct sh_machine_vector mv_se __initmv = { - .mv_name = "SolutionEngine", - .mv_setup = smsc_setup, -#if defined(CONFIG_CPU_SH4) - .mv_nr_irqs = 48, -#elif defined(CONFIG_CPU_SUBTYPE_SH7708) - .mv_nr_irqs = 32, -#elif defined(CONFIG_CPU_SUBTYPE_SH7709) - .mv_nr_irqs = 61, -#elif defined(CONFIG_CPU_SUBTYPE_SH7705) - .mv_nr_irqs = 86, -#endif - - .mv_inb = se_inb, - .mv_inw = se_inw, - .mv_inl = se_inl, - .mv_outb = se_outb, - .mv_outw = se_outw, - .mv_outl = se_outl, - - .mv_inb_p = se_inb_p, - .mv_inw_p = se_inw, - .mv_inl_p = se_inl, - .mv_outb_p = se_outb_p, - .mv_outw_p = se_outw, - .mv_outl_p = se_outl, - - .mv_insb = se_insb, - .mv_insw = se_insw, - .mv_insl = se_insl, - .mv_outsb = se_outsb, - .mv_outsw = se_outsw, - .mv_outsl = se_outsl, - - .mv_init_irq = init_se_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_se, -#endif -}; -ALIAS_MV(se) +void __init platform_setup(void) +{ + init_smsc(); + /* XXX: RTC setting comes here */ +} diff --git a/trunk/arch/sh/boards/se/7751/Makefile b/trunk/arch/sh/boards/se/7751/Makefile index 188900c48321..ce7ca247f84d 100644 --- a/trunk/arch/sh/boards/se/7751/Makefile +++ b/trunk/arch/sh/boards/se/7751/Makefile @@ -2,7 +2,7 @@ # Makefile for the 7751 SolutionEngine specific parts of the kernel # -obj-y := setup.o io.o irq.o +obj-y := mach.o setup.o io.o irq.o led.o obj-$(CONFIG_PCI) += pci.o -obj-$(CONFIG_HEARTBEAT) += led.o + diff --git a/trunk/arch/sh/boards/se/7751/io.c b/trunk/arch/sh/boards/se/7751/io.c index e8d846cec89d..99041b269261 100644 --- a/trunk/arch/sh/boards/se/7751/io.c +++ b/trunk/arch/sh/boards/se/7751/io.c @@ -1,4 +1,6 @@ -/* +/* + * linux/arch/sh/kernel/io_7751se.c + * * Copyright (C) 2001 Ian da Silva, Jeremy Siegel * Based largely on io_se.c. * @@ -8,21 +10,96 @@ * placeholder code from io_se.c left in with the * expectation of later SuperIO and PCMCIA access. */ + #include #include -#include #include -#include +#include #include -static inline volatile u16 *port2adr(unsigned int port) +#include +#include "../../../drivers/pci/pci-sh7751.h" + +#if 0 +/****************************************************************** + * Variables from io_se.c, related to PCMCIA (not PCI); we're not + * compiling them in, and have removed references from functions + * which follow. [Many checked for IO ports in the range bounded + * by sh_pcic_io_start/stop, and used sh_pcic_io_wbase as offset. + * As start/stop are uninitialized, only port 0x0 would match?] + * When used, remember to adjust names to avoid clash with io_se? + *****************************************************************/ +/* SH pcmcia io window base, start and end. */ +int sh_pcic_io_wbase = 0xb8400000; +int sh_pcic_io_start; +int sh_pcic_io_stop; +int sh_pcic_io_type; +int sh_pcic_io_dummy; +/*************************************************************/ +#endif + +/* + * The 7751 Solution Engine uses the built-in PCI controller (PCIC) + * of the 7751 processor, and has a SuperIO accessible via the PCI. + * The board also includes a PCMCIA controller on its memory bus, + * like the other Solution Engine boards. + */ + +#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) +#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) +#define PCI_IO_AREA SH7751_PCI_IO_BASE +#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE + +#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + +static inline volatile __u16 * +port2adr(unsigned int port) { if (port >= 0x2000) return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); - maybebadio((unsigned long)port); +#if 0 + else + return (volatile __u16 *) (PA_SUPERIO + (port << 1)); +#endif + maybebadio(name,(unsigned long)port); return (volatile __u16*)port; } +#if 0 +/* The 7751 Solution Engine seems to have everything hooked */ +/* up pretty normally (nothing on high-bytes only...) so this */ +/* shouldn't be needed */ +static inline int +shifted_port(unsigned long port) +{ + /* For IDE registers, value is not shifted */ + if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) + return 0; + else + return 1; +} +#endif + +/* In case someone configures the kernel w/o PCI support: in that */ +/* scenario, don't ever bother to check for PCI-window addresses */ + +/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ +#if defined(CONFIG_PCI) +#define CHECK_SH7751_PCIIO(port) \ + ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) +#else +#define CHECK_SH7751_PCIIO(port) (0) +#endif + /* * General outline: remap really low stuff [eventually] to SuperIO, * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) @@ -34,10 +111,10 @@ unsigned char sh7751se_inb(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned char *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned char *)PCI_IOMAP(port); else - return (*port2adr(port)) & 0xff; + return (*port2adr(port))&0xff; } unsigned char sh7751se_inb_p(unsigned long port) @@ -46,11 +123,11 @@ unsigned char sh7751se_inb_p(unsigned long port) if (PXSEG(port)) v = *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port)) - v = *(volatile unsigned char *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port)) + v = *(volatile unsigned char *)PCI_IOMAP(port); else - v = (*port2adr(port)) & 0xff; - ctrl_delay(); + v = (*port2adr(port))&0xff; + delay(); return v; } @@ -58,12 +135,12 @@ unsigned short sh7751se_inw(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned short *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned short *)PCI_IOMAP(port); else if (port >= 0x2000) return *port2adr(port); else - maybebadio(port); + maybebadio(inw, port); return 0; } @@ -71,12 +148,12 @@ unsigned int sh7751se_inl(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned int *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned int *)PCI_IOMAP(port); else if (port >= 0x2000) return *port2adr(port); else - maybebadio(port); + maybebadio(inl, port); return 0; } @@ -85,8 +162,8 @@ void sh7751se_outb(unsigned char value, unsigned long port) if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned char*)pci_ioaddr(port)) = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned char*)PCI_IOMAP(port)) = value; else *(port2adr(port)) = value; } @@ -95,41 +172,73 @@ void sh7751se_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned char*)pci_ioaddr(port)) = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned char*)PCI_IOMAP(port)) = value; else *(port2adr(port)) = value; - ctrl_delay(); + delay(); } void sh7751se_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned short *)pci_ioaddr(port)) = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned short *)PCI_IOMAP(port)) = value; else if (port >= 0x2000) *port2adr(port) = value; else - maybebadio(port); + maybebadio(outw, port); } void sh7751se_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned long*)pci_ioaddr(port)) = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned long*)PCI_IOMAP(port)) = value; else - maybebadio(port); + maybebadio(outl, port); } void sh7751se_insl(unsigned long port, void *addr, unsigned long count) { - maybebadio(port); + maybebadio(insl, port); } void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count) { - maybebadio(port); + maybebadio(outsw, port); +} + +/* Map ISA bus address to the real address. Only for PCMCIA. */ + +/* ISA page descriptor. */ +static __u32 sh_isa_memmap[256]; + +#if 0 +static int +sh_isa_mmap(__u32 start, __u32 length, __u32 offset) +{ + int idx; + + if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) + return -1; + + idx = start >> 12; + sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); + printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", + start, length, offset, idx, sh_isa_memmap[idx]); + return 0; +} +#endif + +unsigned long +sh7751se_isa_port2addr(unsigned long offset) +{ + int idx; + + idx = (offset >> 12) & 0xff; + offset &= 0xfff; + return sh_isa_memmap[idx] + offset; } diff --git a/trunk/arch/sh/boards/se/7751/irq.c b/trunk/arch/sh/boards/se/7751/irq.c index c607b0a48479..bf6c023615df 100644 --- a/trunk/arch/sh/boards/se/7751/irq.c +++ b/trunk/arch/sh/boards/se/7751/irq.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include /* * Initialize IRQ setting diff --git a/trunk/arch/sh/boards/se/7751/led.c b/trunk/arch/sh/boards/se/7751/led.c index ff0355dea81b..a878726d3c7c 100644 --- a/trunk/arch/sh/boards/se/7751/led.c +++ b/trunk/arch/sh/boards/se/7751/led.c @@ -8,8 +8,23 @@ * * This file contains Solution Engine specific LED code. */ + +#include + +static void mach_led(int position, int value) +{ + volatile unsigned short* p = (volatile unsigned short*)PA_LED; + + if (value) { + *p |= (1<<8); + } else { + *p &= ~(1<<8); + } +} + +#ifdef CONFIG_HEARTBEAT + #include -#include /* Cycle the LED's in the clasic Knightrider/Sun pattern */ void heartbeat_7751se(void) @@ -49,3 +64,4 @@ void heartbeat_7751se(void) *p = 1<<(bit+8); } +#endif /* CONFIG_HEARTBEAT */ diff --git a/trunk/arch/sh/boards/se/7751/mach.c b/trunk/arch/sh/boards/se/7751/mach.c new file mode 100644 index 000000000000..62d8d3e62590 --- /dev/null +++ b/trunk/arch/sh/boards/se/7751/mach.c @@ -0,0 +1,54 @@ +/* + * linux/arch/sh/kernel/mach_7751se.c + * + * Minor tweak of mach_se.c file to reference 7751se-specific items. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * Machine vector for the Hitachi 7751 SolutionEngine + */ + +#include + +#include +#include +#include + +#include + +void heartbeat_7751se(void); +void init_7751se_IRQ(void); + +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_7751se __initmv = { + .mv_nr_irqs = 72, + + .mv_inb = sh7751se_inb, + .mv_inw = sh7751se_inw, + .mv_inl = sh7751se_inl, + .mv_outb = sh7751se_outb, + .mv_outw = sh7751se_outw, + .mv_outl = sh7751se_outl, + + .mv_inb_p = sh7751se_inb_p, + .mv_inw_p = sh7751se_inw, + .mv_inl_p = sh7751se_inl, + .mv_outb_p = sh7751se_outb_p, + .mv_outw_p = sh7751se_outw, + .mv_outl_p = sh7751se_outl, + + .mv_insl = sh7751se_insl, + .mv_outsl = sh7751se_outsl, + + .mv_isa_port2addr = sh7751se_isa_port2addr, + + .mv_init_irq = init_7751se_IRQ, +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = heartbeat_7751se, +#endif +}; +ALIAS_MV(7751se) diff --git a/trunk/arch/sh/boards/se/7751/setup.c b/trunk/arch/sh/boards/se/7751/setup.c index 73e826310ba8..48dc5aee67d4 100644 --- a/trunk/arch/sh/boards/se/7751/setup.c +++ b/trunk/arch/sh/boards/se/7751/setup.c @@ -1,4 +1,4 @@ -/* +/* * linux/arch/sh/kernel/setup_7751se.c * * Copyright (C) 2000 Kazumoto Kojima @@ -11,15 +11,78 @@ #include #include + +#include #include #include -#include - -void heartbeat_7751se(void); -void init_7751se_IRQ(void); +#include #ifdef CONFIG_SH_KGDB #include +#endif + +/* + * Configure the Super I/O chip + */ +#if 0 +/* Leftover code from regular Solution Engine, for reference. */ +/* The SH7751 Solution Engine has a different SuperIO. */ +static void __init smsc_config(int index, int data) +{ + outb_p(index, INDEX_PORT); + outb_p(data, DATA_PORT); +} + +static void __init init_smsc(void) +{ + outb_p(CONFIG_ENTER, CONFIG_PORT); + outb_p(CONFIG_ENTER, CONFIG_PORT); + + /* FDC */ + smsc_config(CURRENT_LDN_INDEX, LDN_FDC); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IRQ_SELECT_INDEX, 6); /* IRQ6 */ + + /* IDE1 */ + smsc_config(CURRENT_LDN_INDEX, LDN_IDE1); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IRQ_SELECT_INDEX, 14); /* IRQ14 */ + + /* AUXIO (GPIO): to use IDE1 */ + smsc_config(CURRENT_LDN_INDEX, LDN_AUXIO); + smsc_config(GPIO46_INDEX, 0x00); /* nIOROP */ + smsc_config(GPIO47_INDEX, 0x00); /* nIOWOP */ + + /* COM1 */ + smsc_config(CURRENT_LDN_INDEX, LDN_COM1); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IO_BASE_HI_INDEX, 0x03); + smsc_config(IO_BASE_LO_INDEX, 0xf8); + smsc_config(IRQ_SELECT_INDEX, 4); /* IRQ4 */ + + /* COM2 */ + smsc_config(CURRENT_LDN_INDEX, LDN_COM2); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IO_BASE_HI_INDEX, 0x02); + smsc_config(IO_BASE_LO_INDEX, 0xf8); + smsc_config(IRQ_SELECT_INDEX, 3); /* IRQ3 */ + + /* RTC */ + smsc_config(CURRENT_LDN_INDEX, LDN_RTC); + smsc_config(ACTIVATE_INDEX, 0x01); + smsc_config(IRQ_SELECT_INDEX, 8); /* IRQ8 */ + + /* XXX: PARPORT, KBD, and MOUSE will come here... */ + outb_p(CONFIG_EXIT, CONFIG_PORT); +} +#endif + +const char *get_system_type(void) +{ + return "7751 SolutionEngine"; +} + +#ifdef CONFIG_SH_KGDB static int kgdb_uart_setup(void); static struct kgdb_sermap kgdb_uart_sermap = { "ttyS", 0, kgdb_uart_setup, NULL }; @@ -28,7 +91,7 @@ static struct kgdb_sermap kgdb_uart_sermap = /* * Initialize the board */ -static void __init sh7751se_setup(char **cmdline_p) +void __init platform_setup(void) { /* Call init_smsc() replacement to set up SuperIO. */ /* XXX: RTC setting comes here */ @@ -162,37 +225,3 @@ static int kgdb_uart_setup(void) return 0; } #endif /* CONFIG_SH_KGDB */ - - -/* - * The Machine Vector - */ - -struct sh_machine_vector mv_7751se __initmv = { - .mv_name = "7751 SolutionEngine", - .mv_setup = sh7751se_setup, - .mv_nr_irqs = 72, - - .mv_inb = sh7751se_inb, - .mv_inw = sh7751se_inw, - .mv_inl = sh7751se_inl, - .mv_outb = sh7751se_outb, - .mv_outw = sh7751se_outw, - .mv_outl = sh7751se_outl, - - .mv_inb_p = sh7751se_inb_p, - .mv_inw_p = sh7751se_inw, - .mv_inl_p = sh7751se_inl, - .mv_outb_p = sh7751se_outb_p, - .mv_outw_p = sh7751se_outw, - .mv_outl_p = sh7751se_outl, - - .mv_insl = sh7751se_insl, - .mv_outsl = sh7751se_outsl, - - .mv_init_irq = init_7751se_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_7751se, -#endif -}; -ALIAS_MV(7751se) diff --git a/trunk/arch/sh/boards/sh03/rtc.c b/trunk/arch/sh/boards/sh03/rtc.c index 0a9266bb51c5..d609863cfe53 100644 --- a/trunk/arch/sh/boards/sh03/rtc.c +++ b/trunk/arch/sh/boards/sh03/rtc.c @@ -10,10 +10,9 @@ #include #include #include +#include #include #include -#include -#include #define RTC_BASE 0xb0000000 #define RTC_SEC1 (RTC_BASE + 0) @@ -35,6 +34,8 @@ #define RTC_BUSY 1 #define RTC_STOP 2 +extern void (*rtc_get_time)(struct timespec *); +extern int (*rtc_set_time)(const time_t); extern spinlock_t rtc_lock; unsigned long get_cmos_time(void) @@ -127,6 +128,6 @@ int sh03_rtc_settimeofday(const time_t secs) void sh03_time_init(void) { - rtc_sh_get_time = sh03_rtc_gettimeofday; - rtc_sh_set_time = sh03_rtc_settimeofday; + rtc_get_time = sh03_rtc_gettimeofday; + rtc_set_time = sh03_rtc_settimeofday; } diff --git a/trunk/arch/sh/boards/sh03/setup.c b/trunk/arch/sh/boards/sh03/setup.c index 6c310587ddfe..60290f8f289c 100644 --- a/trunk/arch/sh/boards/sh03/setup.c +++ b/trunk/arch/sh/boards/sh03/setup.c @@ -7,13 +7,22 @@ #include #include +#include +#include #include -#include #include #include #include +#include "../../drivers/pci/pci-sh7751.h" -static void __init init_sh03_IRQ(void) +extern void (*board_time_init)(void); + +const char *get_system_type(void) +{ + return "Interface CTP/PCI-SH03)"; +} + +void init_sh03_IRQ(void) { ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); @@ -25,34 +34,38 @@ static void __init init_sh03_IRQ(void) extern void *cf_io_base; -static void __iomem *sh03_ioport_map(unsigned long port, unsigned int size) +unsigned long sh03_isa_port2addr(unsigned long port) { if (PXSEG(port)) - return (void __iomem *)port; + return port; /* CompactFlash (IDE) */ - if (((port >= 0x1f0) && (port <= 0x1f7)) || (port == 0x3f6)) - return (void __iomem *)((unsigned long)cf_io_base + port); - - return (void __iomem *)(port + PCI_IO_BASE); + if (((port >= 0x1f0) && (port <= 0x1f7)) || (port == 0x3f6)) { + return (unsigned long)cf_io_base + port; + } + return port + SH7751_PCI_IO_BASE; } -/* arch/sh/boards/sh03/rtc.c */ -void sh03_time_init(void); - -static void __init sh03_setup(char **cmdline_p) -{ - board_time_init = sh03_time_init; -} +/* + * The Machine Vector + */ struct sh_machine_vector mv_sh03 __initmv = { - .mv_name = "Interface (CTP/PCI-SH03)", - .mv_setup = sh03_setup, .mv_nr_irqs = 48, - .mv_ioport_map = sh03_ioport_map, + .mv_isa_port2addr = sh03_isa_port2addr, .mv_init_irq = init_sh03_IRQ, #ifdef CONFIG_HEARTBEAT .mv_heartbeat = heartbeat_sh03, #endif }; + ALIAS_MV(sh03) + +/* arch/sh/boards/sh03/rtc.c */ +void sh03_time_init(void); + +int __init platform_setup(void) +{ + board_time_init = sh03_time_init; + return 0; +} diff --git a/trunk/arch/sh/boards/sh2000/Makefile b/trunk/arch/sh/boards/sh2000/Makefile new file mode 100644 index 000000000000..05d390c3599c --- /dev/null +++ b/trunk/arch/sh/boards/sh2000/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the SH2000 specific parts of the kernel +# + +obj-y := setup.o + diff --git a/trunk/arch/sh/boards/sh2000/setup.c b/trunk/arch/sh/boards/sh2000/setup.c new file mode 100644 index 000000000000..2fe6a11765e9 --- /dev/null +++ b/trunk/arch/sh/boards/sh2000/setup.c @@ -0,0 +1,70 @@ +/* + * linux/arch/sh/kernel/setup_sh2000.c + * + * Copyright (C) 2001 SUGIOKA Tochinobu + * + * SH-2000 Support. + * + */ + +#include +#include + +#include +#include +#include + +#define CF_CIS_BASE 0xb4200000 + +#define PORT_PECR 0xa4000108 +#define PORT_PHCR 0xa400010E +#define PORT_ICR1 0xa4000010 +#define PORT_IRR0 0xa4000004 + +#define IDE_OFFSET 0xb6200000 +#define NIC_OFFSET 0xb6000000 +#define EXTBUS_OFFSET 0xba000000 + + +const char *get_system_type(void) +{ + return "sh2000"; +} + +static unsigned long sh2000_isa_port2addr(unsigned long offset) +{ + if((offset & ~7) == 0x1f0 || offset == 0x3f6) + return IDE_OFFSET + offset; + else if((offset & ~0x1f) == 0x300) + return NIC_OFFSET + offset; + return EXTBUS_OFFSET + offset; +} + +/* + * The Machine Vector + */ +struct sh_machine_vector mv_sh2000 __initmv = { + .mv_nr_irqs = 80, + .mv_isa_port2addr = sh2000_isa_port2addr, +}; +ALIAS_MV(sh2000) + +/* + * Initialize the board + */ +int __init platform_setup(void) +{ + /* XXX: RTC setting comes here */ + + /* These should be done by BIOS/IPL ... */ + /* Enable nCE2A, nCE2B output */ + ctrl_outw(ctrl_inw(PORT_PECR) & ~0xf00, PORT_PECR); + /* Enable the Compact Flash card, and set the level interrupt */ + ctrl_outw(0x0042, CF_CIS_BASE+0x0200); + /* Enable interrupt */ + ctrl_outw(ctrl_inw(PORT_PHCR) & ~0x03f3, PORT_PHCR); + ctrl_outw(1, PORT_ICR1); + ctrl_outw(ctrl_inw(PORT_IRR0) & ~0xff3f, PORT_IRR0); + printk(KERN_INFO "SH-2000 Setup...done\n"); + return 0; +} diff --git a/trunk/arch/sh/boards/shmin/Makefile b/trunk/arch/sh/boards/shmin/Makefile deleted file mode 100644 index 3190cc72430e..000000000000 --- a/trunk/arch/sh/boards/shmin/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the SHMIN board. -# - -obj-y := setup.o diff --git a/trunk/arch/sh/boards/shmin/setup.c b/trunk/arch/sh/boards/shmin/setup.c deleted file mode 100644 index 2f0c19706cf9..000000000000 --- a/trunk/arch/sh/boards/shmin/setup.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * arch/sh/boards/shmin/setup.c - * - * Copyright (C) 2006 Takashi YOSHII - * - * SHMIN Support. - */ -#include -#include -#include -#include -#include -#include - -#define PFC_PHCR 0xa400010e - -static void __init init_shmin_irq(void) -{ - ctrl_outw(0x2a00, PFC_PHCR); // IRQ0-3=IRQ - ctrl_outw(0x0aaa, INTC_ICR1); // IRQ0-3=IRQ-mode,Low-active. -} - -static void __iomem *shmin_ioport_map(unsigned long port, unsigned int size) -{ - static int dummy; - - if ((port & ~0x1f) == SHMIN_NE_BASE) - return (void __iomem *)(SHMIN_IO_BASE + port); - - dummy = 0; - - return &dummy; - -} - -struct sh_machine_vector mv_shmin __initmv = { - .mv_name = "SHMIN", - .mv_init_irq = init_shmin_irq, - .mv_ioport_map = shmin_ioport_map, -}; -ALIAS_MV(shmin) diff --git a/trunk/arch/sh/boards/snapgear/io.c b/trunk/arch/sh/boards/snapgear/io.c index 0f4824264557..e2eb78fc381d 100644 --- a/trunk/arch/sh/boards/snapgear/io.c +++ b/trunk/arch/sh/boards/snapgear/io.c @@ -1,4 +1,6 @@ -/* +/* + * linux/arch/sh/kernel/io_7751se.c + * * Copyright (C) 2002 David McCullough * Copyright (C) 2001 Ian da Silva, Jeremy Siegel * Based largely on io_se.c. @@ -9,22 +11,67 @@ * placeholder code from io_se.c left in with the * expectation of later SuperIO and PCMCIA access. */ + #include #include #include #include #include +#include +#include "../../drivers/pci/pci-sh7751.h" + #ifdef CONFIG_SH_SECUREEDGE5410 unsigned short secureedge5410_ioport; #endif +/* + * The SnapGear uses the built-in PCI controller (PCIC) + * of the 7751 processor + */ + +#define PCIIOBR (volatile long *)PCI_REG(SH7751_PCIIOBR) +#define PCIMBR (volatile long *)PCI_REG(SH7751_PCIMBR) +#define PCI_IO_AREA SH7751_PCI_IO_BASE +#define PCI_MEM_AREA SH7751_PCI_CONFIG_BASE + + +#define PCI_IOMAP(adr) (PCI_IO_AREA + (adr & ~SH7751_PCIIOBR_MASK)) + + +#define maybebadio(name,port) \ + printk("bad PC-like io %s for port 0x%lx at 0x%08x\n", \ + #name, (port), (__u32) __builtin_return_address(0)) + + +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + + static inline volatile __u16 *port2adr(unsigned int port) { - maybebadio((unsigned long)port); +#if 0 + if (port >= 0x2000) + return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); +#endif + maybebadio(name,(unsigned long)port); return (volatile __u16*)port; } + +/* In case someone configures the kernel w/o PCI support: in that */ +/* scenario, don't ever bother to check for PCI-window addresses */ + +/* NOTE: WINDOW CHECK MAY BE A BIT OFF, HIGH PCIBIOS_MIN_IO WRAPS? */ +#if defined(CONFIG_PCI) +#define CHECK_SH7751_PCIIO(port) \ + ((port >= PCIBIOS_MIN_IO) && (port < (PCIBIOS_MIN_IO + SH7751_PCI_IO_SIZE))) +#else +#define CHECK_SH7751_PCIIO(port) (0) +#endif + /* * General outline: remap really low stuff [eventually] to SuperIO, * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) @@ -32,106 +79,148 @@ static inline volatile __u16 *port2adr(unsigned int port) * should be way beyond the window, and is used w/o translation for * compatibility. */ + unsigned char snapgear_inb(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned char *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned char *)PCI_IOMAP(port); else - return (*port2adr(port)) & 0xff; + return (*port2adr(port))&0xff; } + unsigned char snapgear_inb_p(unsigned long port) { unsigned char v; if (PXSEG(port)) v = *(volatile unsigned char *)port; - else if (is_pci_ioaddr(port)) - v = *(volatile unsigned char *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port)) + v = *(volatile unsigned char *)PCI_IOMAP(port); else - v = (*port2adr(port))&0xff; - ctrl_delay(); + v = (*port2adr(port))&0xff; + delay(); return v; } + unsigned short snapgear_inw(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned short *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned short *)PCI_IOMAP(port); else if (port >= 0x2000) return *port2adr(port); else - maybebadio(port); + maybebadio(inw, port); return 0; } + unsigned int snapgear_inl(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (is_pci_ioaddr(port)) - return *(volatile unsigned int *)pci_ioaddr(port); + else if (CHECK_SH7751_PCIIO(port)) + return *(volatile unsigned int *)PCI_IOMAP(port); else if (port >= 0x2000) return *port2adr(port); else - maybebadio(port); + maybebadio(inl, port); return 0; } + void snapgear_outb(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned char*)pci_ioaddr(port)) = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned char*)PCI_IOMAP(port)) = value; else *(port2adr(port)) = value; } + void snapgear_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned char*)pci_ioaddr(port)) = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned char*)PCI_IOMAP(port)) = value; else *(port2adr(port)) = value; - ctrl_delay(); + delay(); } + void snapgear_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned short *)pci_ioaddr(port)) = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned short *)PCI_IOMAP(port)) = value; else if (port >= 0x2000) *port2adr(port) = value; else - maybebadio(port); + maybebadio(outw, port); } + void snapgear_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (is_pci_ioaddr(port)) - *((unsigned long*)pci_ioaddr(port)) = value; + else if (CHECK_SH7751_PCIIO(port)) + *((unsigned long*)PCI_IOMAP(port)) = value; else - maybebadio(port); + maybebadio(outl, port); } void snapgear_insl(unsigned long port, void *addr, unsigned long count) { - maybebadio(port); + maybebadio(insl, port); } void snapgear_outsl(unsigned long port, const void *addr, unsigned long count) { - maybebadio(port); + maybebadio(outsw, port); +} + +/* Map ISA bus address to the real address. Only for PCMCIA. */ + + +/* ISA page descriptor. */ +static __u32 sh_isa_memmap[256]; + + +#if 0 +static int sh_isa_mmap(__u32 start, __u32 length, __u32 offset) +{ + int idx; + + if (start >= 0x100000 || (start & 0xfff) || (length != 0x1000)) + return -1; + + idx = start >> 12; + sh_isa_memmap[idx] = 0xb8000000 + (offset &~ 0xfff); +#if 0 + printk("sh_isa_mmap: start %x len %x offset %x (idx %x paddr %x)\n", + start, length, offset, idx, sh_isa_memmap[idx]); +#endif + return 0; +} +#endif + +unsigned long snapgear_isa_port2addr(unsigned long offset) +{ + int idx; + + idx = (offset >> 12) & 0xff; + offset &= 0xfff; + return sh_isa_memmap[idx] + offset; } diff --git a/trunk/arch/sh/boards/snapgear/rtc.c b/trunk/arch/sh/boards/snapgear/rtc.c index 1659fdd6695a..b71e009da35c 100644 --- a/trunk/arch/sh/boards/snapgear/rtc.c +++ b/trunk/arch/sh/boards/snapgear/rtc.c @@ -17,9 +17,14 @@ #include #include #include + #include +#include +#include + +/****************************************************************************/ -static int use_ds1302; +static int use_ds1302 = 0; /****************************************************************************/ /* @@ -77,6 +82,10 @@ static unsigned int ds1302_readbyte(unsigned int addr) unsigned int val; unsigned long flags; +#if 0 + printk("SnapGear RTC: ds1302_readbyte(addr=%x)\n", addr); +#endif + local_irq_save(flags); set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK); set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); @@ -95,6 +104,10 @@ static void ds1302_writebyte(unsigned int addr, unsigned int val) { unsigned long flags; +#if 0 + printk("SnapGear RTC: ds1302_writebyte(addr=%x)\n", addr); +#endif + local_irq_save(flags); set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK); set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); @@ -155,8 +168,11 @@ void __init secureedge5410_rtc_init(void) } if (use_ds1302) { - rtc_sh_get_time = snapgear_rtc_gettimeofday; - rtc_sh_set_time = snapgear_rtc_settimeofday; + rtc_get_time = snapgear_rtc_gettimeofday; + rtc_set_time = snapgear_rtc_settimeofday; + } else { + rtc_get_time = sh_rtc_gettimeofday; + rtc_set_time = sh_rtc_settimeofday; } printk("SnapGear RTC: using %s rtc.\n", use_ds1302 ? "ds1302" : "internal"); @@ -171,8 +187,10 @@ void snapgear_rtc_gettimeofday(struct timespec *ts) { unsigned int sec, min, hr, day, mon, yr; - if (!use_ds1302) + if (!use_ds1302) { + sh_rtc_gettimeofday(ts); return; + } sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC)); min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN)); @@ -213,7 +231,7 @@ int snapgear_rtc_settimeofday(const time_t secs) unsigned long nowtime; if (!use_ds1302) - return 0; + return sh_rtc_settimeofday(secs); /* * This is called direct from the kernel timer handling code. @@ -222,6 +240,10 @@ int snapgear_rtc_settimeofday(const time_t secs) nowtime = secs; +#if 1 + printk("SnapGear RTC: snapgear_rtc_settimeofday(nowtime=%ld)\n", nowtime); +#endif + /* STOP RTC */ ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); @@ -307,3 +329,5 @@ void secureedge5410_cmos_write(unsigned char val, int addr) default: break; } } + +/****************************************************************************/ diff --git a/trunk/arch/sh/boards/snapgear/setup.c b/trunk/arch/sh/boards/snapgear/setup.c index f5e98c56b530..f1f7c70c9402 100644 --- a/trunk/arch/sh/boards/snapgear/setup.c +++ b/trunk/arch/sh/boards/snapgear/setup.c @@ -1,4 +1,5 @@ -/* +/****************************************************************************/ +/* * linux/arch/sh/boards/snapgear/setup.c * * Copyright (C) 2002 David McCullough @@ -11,6 +12,8 @@ * Modified for 7751 Solution Engine by * Ian da Silva and Jeremy Siegel, 2001. */ +/****************************************************************************/ + #include #include #include @@ -18,13 +21,14 @@ #include #include #include + #include -#include +#include #include #include -#include #include +extern void (*board_time_init)(void); extern void secureedge5410_rtc_init(void); extern void pcibios_init(void); @@ -81,20 +85,101 @@ static void __init init_snapgear_IRQ(void) make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); } +/****************************************************************************/ +/* + * Fast poll interrupt simulator. + */ + /* - * Initialize the board + * Leave all of the fast timer/fast poll stuff commented out for now, since + * it's not clear whether it actually works or not. Since it wasn't being used + * at all in 2.4, we'll assume it's not sane for 2.6 either.. -- PFM */ -static void __init snapgear_setup(char **cmdline_p) +#if 0 +#define FAST_POLL 1000 +//#define FAST_POLL_INTR + +#define FASTTIMER_IRQ 17 +#define FASTTIMER_IPR_ADDR INTC_IPRA +#define FASTTIMER_IPR_POS 2 +#define FASTTIMER_PRIORITY 3 + +#ifdef FAST_POLL_INTR +#define TMU1_TCR_INIT 0x0020 +#else +#define TMU1_TCR_INIT 0 +#endif +#define TMU_TSTR_INIT 1 +#define TMU1_TCR_CALIB 0x0000 + + +#ifdef FAST_POLL_INTR +static void fast_timer_irq(int irq, void *dev_instance, struct pt_regs *regs) { - board_time_init = secureedge5410_rtc_init; + unsigned long timer_status; + timer_status = ctrl_inw(TMU1_TCR); + timer_status &= ~0x100; + ctrl_outw(timer_status, TMU1_TCR); +} +#endif + +/* + * return the current ticks on the fast timer + */ + +unsigned long fast_timer_count(void) +{ + return(ctrl_inl(TMU1_TCNT)); +} + +/* + * setup a fast timer for profiling etc etc + */ + +static void setup_fast_timer() +{ + unsigned long interval; + +#ifdef FAST_POLL_INTR + interval = (current_cpu_data.module_clock/4 + FAST_POLL/2) / FAST_POLL; + + make_ipr_irq(FASTTIMER_IRQ, FASTTIMER_IPR_ADDR, FASTTIMER_IPR_POS, + FASTTIMER_PRIORITY); + + printk("SnapGear: %dHz fast timer on IRQ %d\n",FAST_POLL,FASTTIMER_IRQ); + + if (request_irq(FASTTIMER_IRQ, fast_timer_irq, 0, "SnapGear fast timer", + NULL) != 0) + printk("%s(%d): request_irq() failed?\n", __FILE__, __LINE__); +#else + printk("SnapGear: fast timer running\n",FAST_POLL,FASTTIMER_IRQ); + interval = 0xffffffff; +#endif + + ctrl_outb(ctrl_inb(TMU_TSTR) & ~0x2, TMU_TSTR); /* disable timer 1 */ + ctrl_outw(TMU1_TCR_INIT, TMU1_TCR); + ctrl_outl(interval, TMU1_TCOR); + ctrl_outl(interval, TMU1_TCNT); + ctrl_outb(ctrl_inb(TMU_TSTR) | 0x2, TMU_TSTR); /* enable timer 1 */ + + printk("Timer count 1 = 0x%x\n", fast_timer_count()); + udelay(1000); + printk("Timer count 2 = 0x%x\n", fast_timer_count()); +} +#endif + +/****************************************************************************/ + +const char *get_system_type(void) +{ + return "SnapGear SecureEdge5410"; } /* * The Machine Vector */ + struct sh_machine_vector mv_snapgear __initmv = { - .mv_name = "SnapGear SecureEdge5410", - .mv_setup = snapgear_setup, .mv_nr_irqs = 72, .mv_inb = snapgear_inb, @@ -111,6 +196,20 @@ struct sh_machine_vector mv_snapgear __initmv = { .mv_outw_p = snapgear_outw, .mv_outl_p = snapgear_outl, + .mv_isa_port2addr = snapgear_isa_port2addr, + .mv_init_irq = init_snapgear_IRQ, }; ALIAS_MV(snapgear) + +/* + * Initialize the board + */ + +int __init platform_setup(void) +{ + board_time_init = secureedge5410_rtc_init; + + return 0; +} + diff --git a/trunk/arch/sh/boards/superh/microdev/irq.c b/trunk/arch/sh/boards/superh/microdev/irq.c index 8c64baa30364..236398fbc083 100644 --- a/trunk/arch/sh/boards/superh/microdev/irq.c +++ b/trunk/arch/sh/boards/superh/microdev/irq.c @@ -11,12 +11,14 @@ #include #include + #include #include #include #define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */ + static const struct { unsigned char fpgaIrq; unsigned char mapped; @@ -91,42 +93,53 @@ static struct hw_interrupt_type microdev_irq_type = { static void disable_microdev_irq(unsigned int irq) { + unsigned int flags; unsigned int fpgaIrq; - if (irq >= NUM_EXTERNAL_IRQS) - return; - if (!fpgaIrqTable[irq].mapped) - return; + if (irq >= NUM_EXTERNAL_IRQS) return; + if (!fpgaIrqTable[irq].mapped) return; fpgaIrq = fpgaIrqTable[irq].fpgaIrq; - /* disable interupts on the FPGA INTC register */ + /* disable interrupts */ + local_irq_save(flags); + + /* disable interupts on the FPGA INTC register */ ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG); + + /* restore interrupts */ + local_irq_restore(flags); } static void enable_microdev_irq(unsigned int irq) { unsigned long priorityReg, priorities, pri; + unsigned int flags; unsigned int fpgaIrq; - if (unlikely(irq >= NUM_EXTERNAL_IRQS)) - return; - if (unlikely(!fpgaIrqTable[irq].mapped)) - return; + + if (irq >= NUM_EXTERNAL_IRQS) return; + if (!fpgaIrqTable[irq].mapped) return; pri = 15 - irq; fpgaIrq = fpgaIrqTable[irq].fpgaIrq; priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq); - /* set priority for the interrupt */ + /* disable interrupts */ + local_irq_save(flags); + + /* set priority for the interrupt */ priorities = ctrl_inl(priorityReg); priorities &= ~MICRODEV_FPGA_INTPRI_MASK(fpgaIrq); priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri); ctrl_outl(priorities, priorityReg); - /* enable interupts on the FPGA INTC register */ + /* enable interupts on the FPGA INTC register */ ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG); + + /* restore interrupts */ + local_irq_restore(flags); } /* This functions sets the desired irq handler to be a MicroDev type */ @@ -145,7 +158,9 @@ static void mask_and_ack_microdev(unsigned int irq) static void end_microdev_irq(unsigned int irq) { if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + { enable_microdev_irq(irq); + } } extern void __init init_microdev_irq(void) @@ -156,7 +171,9 @@ extern void __init init_microdev_irq(void) ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG); for (i = 0; i < NUM_EXTERNAL_IRQS; i++) + { make_microdev_irq(i); + } } extern void microdev_print_fpga_intc_status(void) diff --git a/trunk/arch/sh/boards/superh/microdev/setup.c b/trunk/arch/sh/boards/superh/microdev/setup.c index 031c814e6e76..61b402a3f5d7 100644 --- a/trunk/arch/sh/boards/superh/microdev/setup.c +++ b/trunk/arch/sh/boards/superh/microdev/setup.c @@ -10,6 +10,7 @@ * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. */ + #include #include #include @@ -20,6 +21,41 @@ extern void microdev_heartbeat(void); +/* + * The Machine Vector + */ + +struct sh_machine_vector mv_sh4202_microdev __initmv = { + .mv_nr_irqs = 72, /* QQQ need to check this - use the MACRO */ + + .mv_inb = microdev_inb, + .mv_inw = microdev_inw, + .mv_inl = microdev_inl, + .mv_outb = microdev_outb, + .mv_outw = microdev_outw, + .mv_outl = microdev_outl, + + .mv_inb_p = microdev_inb_p, + .mv_inw_p = microdev_inw_p, + .mv_inl_p = microdev_inl_p, + .mv_outb_p = microdev_outb_p, + .mv_outw_p = microdev_outw_p, + .mv_outl_p = microdev_outl_p, + + .mv_insb = microdev_insb, + .mv_insw = microdev_insw, + .mv_insl = microdev_insl, + .mv_outsb = microdev_outsb, + .mv_outsw = microdev_outsw, + .mv_outsl = microdev_outsl, + + .mv_init_irq = init_microdev_irq, + +#ifdef CONFIG_HEARTBEAT + .mv_heartbeat = microdev_heartbeat, +#endif +}; +ALIAS_MV(sh4202_microdev) /****************************************************************************/ @@ -77,6 +113,11 @@ extern void microdev_heartbeat(void); /* assume a Keyboard Controller is present */ int microdev_kbd_controller_present = 1; +const char *get_system_type(void) +{ + return "SH4-202 MicroDev"; +} + static struct resource smc91x_resources[] = { [0] = { .start = 0x300, @@ -250,9 +291,25 @@ static int __init microdev_devices_setup(void) return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices)); } -/* - * Setup for the SMSC FDC37C93xAPM - */ +__initcall(microdev_devices_setup); + +void __init platform_setup(void) +{ + int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul); + const int fpgaRevision = *fpgaRevisionRegister; + int * const CacheControlRegister = (int*)CCR; + + printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n", + get_system_type(), fpgaRevision, *CacheControlRegister); +} + + +/****************************************************************************/ + + + /* + * Setup for the SMSC FDC37C93xAPM + */ static int __init smsc_superio_setup(void) { @@ -355,52 +412,8 @@ static int __init smsc_superio_setup(void) return 0; } -static void __init microdev_setup(char **cmdline_p) -{ - int * const fpgaRevisionRegister = (int*)(MICRODEV_FPGA_GP_BASE + 0x8ul); - const int fpgaRevision = *fpgaRevisionRegister; - int * const CacheControlRegister = (int*)CCR; - - device_initcall(microdev_devices_setup); - device_initcall(smsc_superio_setup); - printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n", - get_system_type(), fpgaRevision, *CacheControlRegister); -} - -/* - * The Machine Vector +/* This is grotty, but, because kernel is always referenced on the link line + * before any devices, this is safe. */ -struct sh_machine_vector mv_sh4202_microdev __initmv = { - .mv_name = "SH4-202 MicroDev", - .mv_setup = microdev_setup, - .mv_nr_irqs = 72, /* QQQ need to check this - use the MACRO */ - - .mv_inb = microdev_inb, - .mv_inw = microdev_inw, - .mv_inl = microdev_inl, - .mv_outb = microdev_outb, - .mv_outw = microdev_outw, - .mv_outl = microdev_outl, - - .mv_inb_p = microdev_inb_p, - .mv_inw_p = microdev_inw_p, - .mv_inl_p = microdev_inl_p, - .mv_outb_p = microdev_outb_p, - .mv_outw_p = microdev_outw_p, - .mv_outl_p = microdev_outl_p, - - .mv_insb = microdev_insb, - .mv_insw = microdev_insw, - .mv_insl = microdev_insl, - .mv_outsb = microdev_outsb, - .mv_outsw = microdev_outsw, - .mv_outsl = microdev_outsl, - - .mv_init_irq = init_microdev_irq, - -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = microdev_heartbeat, -#endif -}; -ALIAS_MV(sh4202_microdev) +__initcall(smsc_superio_setup); diff --git a/trunk/arch/sh/boards/titan/Makefile b/trunk/arch/sh/boards/titan/Makefile deleted file mode 100644 index 08d753700062..000000000000 --- a/trunk/arch/sh/boards/titan/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the Nimble Microsystems TITAN specific parts of the kernel -# - -obj-y := setup.o io.o diff --git a/trunk/arch/sh/boards/titan/io.c b/trunk/arch/sh/boards/titan/io.c deleted file mode 100644 index 4730c1dd697d..000000000000 --- a/trunk/arch/sh/boards/titan/io.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * I/O routines for Titan - */ -#include -#include -#include -#include -#include - -static inline unsigned int port2adr(unsigned int port) -{ - maybebadio((unsigned long)port); - return port; -} - -u8 titan_inb(unsigned long port) -{ - if (PXSEG(port)) - return ctrl_inb(port); - else if (is_pci_ioaddr(port)) - return ctrl_inb(pci_ioaddr(port)); - return ctrl_inw(port2adr(port)) & 0xff; -} - -u8 titan_inb_p(unsigned long port) -{ - u8 v; - - if (PXSEG(port)) - v = ctrl_inb(port); - else if (is_pci_ioaddr(port)) - v = ctrl_inb(pci_ioaddr(port)); - else - v = ctrl_inw(port2adr(port)) & 0xff; - ctrl_delay(); - return v; -} - -u16 titan_inw(unsigned long port) -{ - if (PXSEG(port)) - return ctrl_inw(port); - else if (is_pci_ioaddr(port)) - return ctrl_inw(pci_ioaddr(port)); - else if (port >= 0x2000) - return ctrl_inw(port2adr(port)); - else - maybebadio(port); - return 0; -} - -u32 titan_inl(unsigned long port) -{ - if (PXSEG(port)) - return ctrl_inl(port); - else if (is_pci_ioaddr(port)) - return ctrl_inl(pci_ioaddr(port)); - else if (port >= 0x2000) - return ctrl_inw(port2adr(port)); - else - maybebadio(port); - return 0; -} - -void titan_outb(u8 value, unsigned long port) -{ - if (PXSEG(port)) - ctrl_outb(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outb(value, pci_ioaddr(port)); - else - ctrl_outw(value, port2adr(port)); -} - -void titan_outb_p(u8 value, unsigned long port) -{ - if (PXSEG(port)) - ctrl_outb(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outb(value, pci_ioaddr(port)); - else - ctrl_outw(value, port2adr(port)); - ctrl_delay(); -} - -void titan_outw(u16 value, unsigned long port) -{ - if (PXSEG(port)) - ctrl_outw(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outw(value, pci_ioaddr(port)); - else if (port >= 0x2000) - ctrl_outw(value, port2adr(port)); - else - maybebadio(port); -} - -void titan_outl(u32 value, unsigned long port) -{ - if (PXSEG(port)) - ctrl_outl(value, port); - else if (is_pci_ioaddr(port)) - ctrl_outl(value, pci_ioaddr(port)); - else - maybebadio(port); -} - -void titan_insl(unsigned long port, void *dst, unsigned long count) -{ - maybebadio(port); -} - -void titan_outsl(unsigned long port, const void *src, unsigned long count) -{ - maybebadio(port); -} - -void __iomem *titan_ioport_map(unsigned long port, unsigned int size) -{ - if (PXSEG(port) || is_pci_memaddr(port)) - return (void __iomem *)port; - else if (is_pci_ioaddr(port)) - return (void __iomem *)pci_ioaddr(port); - - return (void __iomem *)port2adr(port); -} diff --git a/trunk/arch/sh/boards/titan/setup.c b/trunk/arch/sh/boards/titan/setup.c deleted file mode 100644 index 52b66d8b8d2a..000000000000 --- a/trunk/arch/sh/boards/titan/setup.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Setup for Titan - */ - -#include -#include -#include -#include - -extern void __init pcibios_init_platform(void); - -static void __init init_titan_irq(void) -{ - /* enable individual interrupt mode for externals */ - ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); - - make_ipr_irq( TITAN_IRQ_WAN, IRL0_IPR_ADDR, IRL0_IPR_POS, IRL0_PRIORITY); /* PCIRQ0 */ - make_ipr_irq( TITAN_IRQ_LAN, IRL1_IPR_ADDR, IRL1_IPR_POS, IRL1_PRIORITY); /* PCIRQ1 */ - make_ipr_irq( TITAN_IRQ_MPCIA, IRL2_IPR_ADDR, IRL2_IPR_POS, IRL2_PRIORITY); /* PCIRQ2 */ - make_ipr_irq( TITAN_IRQ_USB, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); /* PCIRQ3 */ -} - -struct sh_machine_vector mv_titan __initmv = { - .mv_name = "Titan", - - .mv_inb = titan_inb, - .mv_inw = titan_inw, - .mv_inl = titan_inl, - .mv_outb = titan_outb, - .mv_outw = titan_outw, - .mv_outl = titan_outl, - - .mv_inb_p = titan_inb_p, - .mv_inw_p = titan_inw, - .mv_inl_p = titan_inl, - .mv_outb_p = titan_outb_p, - .mv_outw_p = titan_outw, - .mv_outl_p = titan_outl, - - .mv_insl = titan_insl, - .mv_outsl = titan_outsl, - - .mv_ioport_map = titan_ioport_map, - - .mv_init_irq = init_titan_irq, - .mv_init_pci = pcibios_init_platform, -}; -ALIAS_MV(titan) diff --git a/trunk/arch/sh/boards/unknown/setup.c b/trunk/arch/sh/boards/unknown/setup.c index 1c941370a2e3..c5e4ed10876b 100644 --- a/trunk/arch/sh/boards/unknown/setup.c +++ b/trunk/arch/sh/boards/unknown/setup.c @@ -14,8 +14,19 @@ */ #include #include +#include struct sh_machine_vector mv_unknown __initmv = { - .mv_name = "Unknown", + .mv_nr_irqs = NR_IRQS, }; ALIAS_MV(unknown) + +const char *get_system_type(void) +{ + return "Unknown"; +} + +void __init platform_setup(void) +{ +} + diff --git a/trunk/arch/sh/boot/compressed/Makefile b/trunk/arch/sh/boot/compressed/Makefile index e5f443790079..75a6876bf6c6 100644 --- a/trunk/arch/sh/boot/compressed/Makefile +++ b/trunk/arch/sh/boot/compressed/Makefile @@ -18,20 +18,13 @@ endif # Assign dummy values if these 2 variables are not defined, # in order to suppress error message. # -CONFIG_PAGE_OFFSET ?= 0x80000000 CONFIG_MEMORY_START ?= 0x0c000000 CONFIG_BOOT_LINK_OFFSET ?= 0x00800000 - -IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_PAGE_OFFSET) + \ - $(CONFIG_MEMORY_START) + \ - $(CONFIG_BOOT_LINK_OFFSET)]) - -LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) +IMAGE_OFFSET := $(shell printf "0x%8x" $$[0x80000000+$(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)]) LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup -T $(obj)/../../kernel/vmlinux.lds - -$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE +$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE $(call if_changed,ld) @: diff --git a/trunk/arch/sh/cchips/Kconfig b/trunk/arch/sh/cchips/Kconfig index 0582ca8346b6..155d139884c3 100644 --- a/trunk/arch/sh/cchips/Kconfig +++ b/trunk/arch/sh/cchips/Kconfig @@ -65,11 +65,6 @@ config HD64461_IRQ Do not change this unless you know what you are doing. -config HD64461_IOBASE - hex "HD64461 start address" - depends on HD64461 - default "0xb0000000" - config HD64461_ENABLER bool "HD64461 PCMCIA enabler" depends on HD64461 @@ -78,6 +73,7 @@ config HD64461_ENABLER via the HD64461 companion chip. Otherwise, say N. + config HD64465_IOBASE hex "HD64465 start address" depends on HD64465 diff --git a/trunk/arch/sh/cchips/hd6446x/hd64461/io.c b/trunk/arch/sh/cchips/hd6446x/hd64461/io.c index 7909a1b7b512..ac3062671db7 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64461/io.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64461/io.c @@ -1,10 +1,11 @@ /* + * $Id: io.c,v 1.6 2004/03/16 00:07:50 lethal Exp $ * Copyright (C) 2000 YAEGASHI Takeshi * Typical I/O routines for HD64461 system. */ #include -#include +#include #define MEM_BASE (CONFIG_HD64461_IOBASE - HD64461_STBCR) @@ -53,6 +54,11 @@ static __inline__ unsigned long PORT2ADDR(unsigned long port) return 0xa0000000 + (port & 0x1fffffff); } +static inline void delay(void) +{ + ctrl_inw(0xa0000000); +} + unsigned char hd64461_inb(unsigned long port) { return *(volatile unsigned char*)PORT2ADDR(port); @@ -61,7 +67,7 @@ unsigned char hd64461_inb(unsigned long port) unsigned char hd64461_inb_p(unsigned long port) { unsigned long v = *(volatile unsigned char*)PORT2ADDR(port); - ctrl_delay(); + delay(); return v; } @@ -83,7 +89,7 @@ void hd64461_outb(unsigned char b, unsigned long port) void hd64461_outb_p(unsigned char b, unsigned long port) { *(volatile unsigned char*)PORT2ADDR(port) = b; - ctrl_delay(); + delay(); } void hd64461_outw(unsigned short b, unsigned long port) @@ -138,13 +144,13 @@ void hd64461_outsl(unsigned long port, const void *buffer, unsigned long count) while(count--) *addr=*buf++; } -unsigned short hd64461_readw(void __iomem *addr) +unsigned short hd64461_readw(unsigned long addr) { - return ctrl_inw(MEM_BASE+(unsigned long __force)addr); + return *(volatile unsigned short*)(MEM_BASE+addr); } -void hd64461_writew(unsigned short b, void __iomem *addr) +void hd64461_writew(unsigned short b, unsigned long addr) { - ctrl_outw(b, MEM_BASE+(unsigned long __force)addr); + *(volatile unsigned short*)(MEM_BASE+addr) = b; } diff --git a/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c b/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c index 38f1e8171a3a..ad126016720f 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c @@ -11,28 +11,36 @@ #include #include #include + #include #include -#include + +#include static void disable_hd64461_irq(unsigned int irq) { + unsigned long flags; unsigned short nimr; unsigned short mask = 1 << (irq - HD64461_IRQBASE); + local_irq_save(flags); nimr = inw(HD64461_NIMR); nimr |= mask; outw(nimr, HD64461_NIMR); + local_irq_restore(flags); } static void enable_hd64461_irq(unsigned int irq) { + unsigned long flags; unsigned short nimr; unsigned short mask = 1 << (irq - HD64461_IRQBASE); + local_irq_save(flags); nimr = inw(HD64461_NIMR); nimr &= ~mask; outw(nimr, HD64461_NIMR); + local_irq_restore(flags); } static void mask_and_ack_hd64461(unsigned int irq) diff --git a/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c b/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c index 30573d3e1966..d2b2851bc44b 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c @@ -25,25 +25,31 @@ static void disable_hd64465_irq(unsigned int irq) { + unsigned long flags; unsigned short nimr; unsigned short mask = 1 << (irq - HD64465_IRQ_BASE); pr_debug("disable_hd64465_irq(%d): mask=%x\n", irq, mask); + local_irq_save(flags); nimr = inw(HD64465_REG_NIMR); nimr |= mask; outw(nimr, HD64465_REG_NIMR); + local_irq_restore(flags); } static void enable_hd64465_irq(unsigned int irq) { + unsigned long flags; unsigned short nimr; unsigned short mask = 1 << (irq - HD64465_IRQ_BASE); pr_debug("enable_hd64465_irq(%d): mask=%x\n", irq, mask); + local_irq_save(flags); nimr = inw(HD64465_REG_NIMR); nimr &= ~mask; outw(nimr, HD64465_REG_NIMR); + local_irq_restore(flags); } diff --git a/trunk/arch/sh/cchips/voyagergx/irq.c b/trunk/arch/sh/cchips/voyagergx/irq.c index 392c8b12ce36..0dc1fb8f9687 100644 --- a/trunk/arch/sh/cchips/voyagergx/irq.c +++ b/trunk/arch/sh/cchips/voyagergx/irq.c @@ -32,30 +32,37 @@ #include #include -#include +#include +#include static void disable_voyagergx_irq(unsigned int irq) { - unsigned long val; - unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); + unsigned long flags, val; + unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); + local_irq_save(flags); val = inl(VOYAGER_INT_MASK); val &= ~mask; outl(val, VOYAGER_INT_MASK); + local_irq_restore(flags); } + static void enable_voyagergx_irq(unsigned int irq) { - unsigned long val; - unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); + unsigned long flags, val; + unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); + local_irq_save(flags); val = inl(VOYAGER_INT_MASK); val |= mask; outl(val, VOYAGER_INT_MASK); + local_irq_restore(flags); } + static void mask_and_ack_voyagergx(unsigned int irq) { disable_voyagergx_irq(irq); @@ -88,8 +95,7 @@ static struct hw_interrupt_type voyagergx_irq_type = { .end = end_voyagergx_irq, }; -static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, struct pt_regs *regs) { printk(KERN_INFO "VoyagerGX: spurious interrupt, status: 0x%x\n", @@ -97,6 +103,9 @@ static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, return IRQ_HANDLED; } + +/*====================================================*/ + static struct { int (*func)(int, void *); void *dev; diff --git a/trunk/arch/sh/cchips/voyagergx/setup.c b/trunk/arch/sh/cchips/voyagergx/setup.c index 66b2fedd7ad9..139ca88ac9e6 100644 --- a/trunk/arch/sh/cchips/voyagergx/setup.c +++ b/trunk/arch/sh/cchips/voyagergx/setup.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include static int __init setup_voyagergx(void) { diff --git a/trunk/arch/sh/configs/landisk_defconfig b/trunk/arch/sh/configs/landisk_defconfig deleted file mode 100644 index 6b43316d03cf..000000000000 --- a/trunk/arch/sh/configs/landisk_defconfig +++ /dev/null @@ -1,1373 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.13-sh -# Sun Sep 11 13:00:46 2005 -# -CONFIG_SUPERH=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -CONFIG_HOTPLUG=y -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_EXTRA_PASS=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# System type -# -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_STB1_HARP is not set -# CONFIG_SH_STB1_OVERDRIVE is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_CQREEK is not set -# CONFIG_SH_DMIDA is not set -# CONFIG_SH_EC3104 is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_CAT68701 is not set -# CONFIG_SH_BIGSUR is not set -# CONFIG_SH_SH2000 is not set -# CONFIG_SH_ADX is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -CONFIG_SH_LANDISK=y -# CONFIG_SH_TITAN is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# -CONFIG_CPU_SH4=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set - -# -# SH-4 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -CONFIG_CPU_SUBTYPE_SH7751=y -CONFIG_CPU_SUBTYPE_SH7751R=y -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set -# CONFIG_CPU_SUBTYPE_SH7770 is not set -# CONFIG_CPU_SUBTYPE_SH7780 is not set - -# -# Memory management options -# -CONFIG_MMU=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set -CONFIG_MEMORY_START=0x0c000000 -CONFIG_MEMORY_SIZE=0x04000000 - -# -# Processor features -# -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_SH_FPU=y -# CONFIG_SH_STORE_QUEUES is not set - -# -# Timer support -# -CONFIG_SH_TMU=y -CONFIG_SH_PCLK_FREQ_BOOL=y -CONFIG_SH_PCLK_FREQ=33333333 - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# DMA support -# -CONFIG_SH_DMA=y -CONFIG_NR_ONCHIP_DMA_CHANNELS=4 -# CONFIG_NR_DMA_CHANNELS_BOOL is not set - -# -# Companion Chips -# -# CONFIG_HD6446X_SERIES is not set -CONFIG_HEARTBEAT=y - -# -# Kernel features -# -CONFIG_KEXEC=y -# CONFIG_PREEMPT is not set -# CONFIG_SMP is not set - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x00800000 -# CONFIG_UBC_WAKEUP is not set -# CONFIG_CMDLINE_BOOL is not set - -# -# Bus options -# -CONFIG_ISA=y -CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y -CONFIG_PCI_LEGACY_PROC=y - -# -# PCCARD (PCMCIA/CardBus) support -# -CONFIG_PCCARD=y -# CONFIG_PCMCIA_DEBUG is not set -CONFIG_PCMCIA=y -CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y -CONFIG_CARDBUS=y - -# -# PC-card bridges -# -CONFIG_YENTA=y -# CONFIG_PD6729 is not set -# CONFIG_I82092 is not set -# CONFIG_I82365 is not set -# CONFIG_TCIC is not set -CONFIG_PCMCIA_PROBE=y -CONFIG_PCCARD_NONSTATIC=y - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_MULTIPLE_TABLES is not set -# CONFIG_IP_ROUTE_MULTIPATH is not set -# CONFIG_IP_ROUTE_VERBOSE is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -# CONFIG_NETFILTER_NETLINK is not set - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -CONFIG_IP_NF_CT_ACCT=y -CONFIG_IP_NF_CONNTRACK_MARK=y -# CONFIG_IP_NF_CONNTRACK_EVENTS is not set -# CONFIG_IP_NF_CT_PROTO_SCTP is not set -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_IRC=m -# CONFIG_IP_NF_NETBIOS_NS is not set -CONFIG_IP_NF_TFTP=m -CONFIG_IP_NF_AMANDA=m -# CONFIG_IP_NF_PPTP is not set -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_LENGTH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_MATCH_ADDRTYPE=m -CONFIG_IP_NF_MATCH_REALM=m -CONFIG_IP_NF_MATCH_SCTP=m -# CONFIG_IP_NF_MATCH_DCCP is not set -CONFIG_IP_NF_MATCH_COMMENT=m -CONFIG_IP_NF_MATCH_CONNMARK=m -# CONFIG_IP_NF_MATCH_CONNBYTES is not set -CONFIG_IP_NF_MATCH_HASHLIMIT=m -# CONFIG_IP_NF_MATCH_STRING is not set -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m -# CONFIG_IP_NF_TARGET_NFQUEUE is not set -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_SAME=m -# CONFIG_IP_NF_NAT_SNMP_BASIC is not set -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_NAT_TFTP=m -CONFIG_IP_NF_NAT_AMANDA=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_DSCP=m -CONFIG_IP_NF_TARGET_MARK=m -CONFIG_IP_NF_TARGET_CLASSIFY=m -# CONFIG_IP_NF_TARGET_TTL is not set -CONFIG_IP_NF_TARGET_CONNMARK=m -# CONFIG_IP_NF_TARGET_CLUSTERIP is not set -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_TARGET_NOTRACK=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -CONFIG_LLC=m -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -CONFIG_ATALK=m -# CONFIG_DEV_APPLETALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set -CONFIG_NET_CLS_ROUTE=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNP is not set - -# -# Block devices -# -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_LBD is not set -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_IDE_MAX_HWIFS=4 -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECS is not set -CONFIG_BLK_DEV_IDECD=y -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -CONFIG_BLK_DEV_IDESCSI=y -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_OFFBOARD=y -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -CONFIG_IDEDMA_ONLYDISK=y -CONFIG_BLK_DEV_AEC62XX=y -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -CONFIG_IDE_SH=y -# CONFIG_IDE_ARM is not set -# CONFIG_IDE_CHIPSETS is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI Transport Attributes -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLA2XXX=y -# CONFIG_SCSI_QLA21XX is not set -# CONFIG_SCSI_QLA22XX is not set -# CONFIG_SCSI_QLA2300 is not set -# CONFIG_SCSI_QLA2322 is not set -# CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA24XX is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set - -# -# PCMCIA SCSI adapter support -# -# CONFIG_PCMCIA_AHA152X is not set -# CONFIG_PCMCIA_FDOMAIN is not set -# CONFIG_PCMCIA_NINJA_SCSI is not set -# CONFIG_PCMCIA_QLOGIC is not set -# CONFIG_PCMCIA_SYM53C500 is not set - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -# CONFIG_MD_RAID10 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_RAID6 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_MD_FAULTY is not set -# CONFIG_BLK_DEV_DM is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=m - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_STNIC is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_SMC91X is not set -# CONFIG_NET_VENDOR_RACAL is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -# CONFIG_NE2000 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_CS89x0 is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -CONFIG_8139CP=y -# CONFIG_8139TOO is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# PCMCIA network device support -# -# CONFIG_NET_PCMCIA is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_RTC is not set -CONFIG_RS5C313_RTC=y -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set - -# -# PCMCIA character devices -# -# CONFIG_SYNCLINK_CS is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# Multimedia Capabilities Port drivers -# - -# -# Multimedia devices -# -CONFIG_VIDEO_DEV=m - -# -# Video For Linux -# - -# -# Video Adapters -# -# CONFIG_VIDEO_PMS is not set -# CONFIG_VIDEO_CPIA is not set -# CONFIG_VIDEO_STRADIS is not set -# CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_DPC is not set -# CONFIG_VIDEO_HEXIUM_ORION is not set -# CONFIG_VIDEO_HEXIUM_GEMINI is not set - -# -# Radio Adapters -# -# CONFIG_RADIO_CADET is not set -# CONFIG_RADIO_RTRACK is not set -# CONFIG_RADIO_RTRACK2 is not set -# CONFIG_RADIO_AZTECH is not set -# CONFIG_RADIO_GEMTEK is not set -# CONFIG_RADIO_GEMTEK_PCI is not set -# CONFIG_RADIO_MAXIRADIO is not set -# CONFIG_RADIO_MAESTRO is not set -# CONFIG_RADIO_SF16FMI is not set -# CONFIG_RADIO_SF16FMR2 is not set -# CONFIG_RADIO_TERRATEC is not set -# CONFIG_RADIO_TRUST is not set -# CONFIG_RADIO_TYPHOON is not set -# CONFIG_RADIO_ZOLTRIX is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Console display driver support -# -# CONFIG_MDA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_FONT_8x16=y - -# -# Sound -# -CONFIG_SOUND=m - -# -# Advanced Linux Sound Architecture -# -# CONFIG_SND is not set - -# -# Open Sound System -# -CONFIG_SOUND_PRIME=m -# CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_CMPCI is not set -# CONFIG_SOUND_EMU10K1 is not set -# CONFIG_SOUND_FUSION is not set -# CONFIG_SOUND_CS4281 is not set -# CONFIG_SOUND_ES1370 is not set -# CONFIG_SOUND_ES1371 is not set -# CONFIG_SOUND_ESSSOLO1 is not set -# CONFIG_SOUND_MAESTRO is not set -# CONFIG_SOUND_MAESTRO3 is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set -# CONFIG_SOUND_ALI5455 is not set -# CONFIG_SOUND_FORTE is not set -# CONFIG_SOUND_RME96XX is not set -# CONFIG_SOUND_AD1980 is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -CONFIG_USB_EHCI_HCD=y -# CONFIG_USB_EHCI_SPLIT_ISO is not set -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -CONFIG_OBSOLETE_OSS_USB_DRIVER=y -CONFIG_USB_AUDIO=m -# CONFIG_USB_BLUETOOTH_TTY is not set -CONFIG_USB_MIDI=m -# CONFIG_USB_ACM is not set -CONFIG_USB_PRINTER=m - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=m -# CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_STORAGE_FREECOM=y -CONFIG_USB_STORAGE_ISD200=y -CONFIG_USB_STORAGE_DPCM=y -# CONFIG_USB_STORAGE_USBAT is not set -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_USB_STORAGE_JUMPSHOT=y - -# -# USB Input Devices -# -CONFIG_USB_HID=m -CONFIG_USB_HIDINPUT=y -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_MTOUCH is not set -# CONFIG_USB_ITMTOUCH is not set -# CONFIG_USB_EGALAX is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Multimedia devices -# -CONFIG_USB_DABUSB=m -CONFIG_USB_VICAM=m -CONFIG_USB_DSBR=m -CONFIG_USB_IBMCAM=m -CONFIG_USB_KONICAWC=m -CONFIG_USB_OV511=m -CONFIG_USB_SE401=m -CONFIG_USB_SN9C102=m -CONFIG_USB_STV680=m -CONFIG_USB_PWC=m - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -CONFIG_USB_PEGASUS=m -CONFIG_USB_RTL8150=m -# CONFIG_USB_USBNET is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -CONFIG_USB_SERIAL=m -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_AIRPRIME is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_CP2101 is not set -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_EMPEG is not set -CONFIG_USB_SERIAL_FTDI_SIO=m -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_GARMIN is not set -# CONFIG_USB_SERIAL_IPW is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -CONFIG_USB_SERIAL_PL2303=m -# CONFIG_USB_SERIAL_HP4X is not set -# CONFIG_USB_SERIAL_SAFE is not set -# CONFIG_USB_SERIAL_TI is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OPTION is not set -# CONFIG_USB_SERIAL_OMNINET is not set - -# -# USB Miscellaneous drivers -# -CONFIG_USB_EMI62=m -CONFIG_USB_EMI26=m -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGETKIT is not set -# CONFIG_USB_PHIDGETSERVO is not set -# CONFIG_USB_IDMOUSE is not set -CONFIG_USB_SISUSBVGA=m -CONFIG_USB_SISUSBVGA_CON=y -# CONFIG_USB_LD is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# SN Devices -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -CONFIG_REISERFS_FS=y -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_REISERFS_FS_XATTR is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -CONFIG_ROMFS_FS=y -CONFIG_INOTIFY=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -CONFIG_NTFS_FS=m -# CONFIG_NTFS_DEBUG is not set -CONFIG_NTFS_RW=y - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLBFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -CONFIG_UFS_FS=m -CONFIG_UFS_FS_WRITE=y - -# -# Network File Systems -# -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -# CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=m -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -CONFIG_NLS_CODEPAGE_932=y -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_FRAME_POINTER is not set -CONFIG_SH_STANDARD_BIOS=y -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_EARLY_PRINTK is not set -# CONFIG_KGDB is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set diff --git a/trunk/arch/sh/configs/r7780rp_defconfig b/trunk/arch/sh/configs/r7780rp_defconfig deleted file mode 100644 index d597fc571549..000000000000 --- a/trunk/arch/sh/configs/r7780rp_defconfig +++ /dev/null @@ -1,1099 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.15-sh -# Sat Jan 7 19:47:53 2006 -# -CONFIG_SUPERH=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -CONFIG_HOTPLUG=y -CONFIG_KOBJECT_UEVENT=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_EMBEDDED=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_BASE_FULL=y -# CONFIG_FUTEX is not set -# CONFIG_EPOLL is not set -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -# CONFIG_LBD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" - -# -# System type -# -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_STB1_HARP is not set -# CONFIG_SH_STB1_OVERDRIVE is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_CQREEK is not set -# CONFIG_SH_DMIDA is not set -# CONFIG_SH_EC3104 is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_CAT68701 is not set -# CONFIG_SH_BIGSUR is not set -# CONFIG_SH_SH2000 is not set -# CONFIG_SH_ADX is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_R77703DRP is not set -CONFIG_SH_R7780RP=y -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# -CONFIG_CPU_SH4=y -CONFIG_CPU_SH4A=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set - -# -# SH-4 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -# CONFIG_CPU_SUBTYPE_SH7751 is not set -# CONFIG_CPU_SUBTYPE_SH7751R is not set -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set -# CONFIG_CPU_SUBTYPE_SH7770 is not set -CONFIG_CPU_SUBTYPE_SH7780=y - -# -# Memory management options -# -CONFIG_MMU=y -CONFIG_32BIT=y -CONFIG_HUGETLB_PAGE_SIZE_64K=y -# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set -CONFIG_MEMORY_START=0x08000000 -CONFIG_MEMORY_SIZE=0x08000000 - -# -# Processor features -# -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_SH_FPU=y -CONFIG_SH_STORE_QUEUES=y - -# -# Timer support -# -CONFIG_SH_TMU=y -CONFIG_SH_PCLK_FREQ_BOOL=y -CONFIG_SH_PCLK_FREQ=32000000 - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# DMA support -# -CONFIG_SH_DMA=y -CONFIG_NR_ONCHIP_DMA_CHANNELS=6 -# CONFIG_NR_DMA_CHANNELS_BOOL is not set - -# -# Companion Chips -# -# CONFIG_HD6446X_SERIES is not set - -# -# Kernel features -# -# CONFIG_KEXEC is not set -CONFIG_PREEMPT=y -# CONFIG_SMP is not set -CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_INTC2_IRQ=y - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x00800000 -# CONFIG_UBC_WAKEUP is not set -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="mem=128M console=ttySC0,115200 root=/dev/hda1" - -# -# Bus options -# -CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y -CONFIG_PCI_LEGACY_PROC=y -# CONFIG_PCI_DEBUG is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -CONFIG_HOTPLUG_PCI=y -# CONFIG_HOTPLUG_PCI_FAKE is not set -# CONFIG_HOTPLUG_PCI_CPCI is not set -# CONFIG_HOTPLUG_PCI_SHPC is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_MULTIPLE_TABLES is not set -# CONFIG_IP_ROUTE_MULTIPATH is not set -# CONFIG_IP_ROUTE_VERBOSE is not set -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -CONFIG_BRIDGE=m -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# CONFIG_DEBUG_DRIVER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=m -CONFIG_IDE_MAX_HWIFS=4 -CONFIG_BLK_DEV_IDE=m - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -CONFIG_BLK_DEV_IDE_SATA=y -CONFIG_BLK_DEV_IDEDISK=m -CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -CONFIG_BLK_DEV_IDESCSI=m -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=m -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=m -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_AEC62XX=m -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -CONFIG_BLK_DEV_PDC202XX_NEW=m -# CONFIG_PDC202XX_FORCE is not set -# CONFIG_BLK_DEV_SVWKS is not set -CONFIG_BLK_DEV_SIIMAGE=m -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -CONFIG_IDE_SH=y -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=m -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=m -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_BLK_DEV_SR is not set -CONFIG_CHR_DEV_SG=m -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI Transport Attributes -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLA2XXX=m -# CONFIG_SCSI_QLA21XX is not set -# CONFIG_SCSI_QLA22XX is not set -# CONFIG_SCSI_QLA2300 is not set -# CONFIG_SCSI_QLA2322 is not set -# CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA24XX is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_STNIC is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_SMC91X is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NE2000=y -CONFIG_NET_PCI=y -CONFIG_PCNET32=m -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -CONFIG_8139CP=m -CONFIG_8139TOO=m -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -CONFIG_8139TOO_8129=y -# CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -CONFIG_VIA_RHINE=m -CONFIG_VIA_RHINE_MMIO=y - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -CONFIG_E1000=m -# CONFIG_E1000_NAPI is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -CONFIG_R8169=y -# CONFIG_R8169_NAPI is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y - -# -# Obsolete Wireless cards support (pre-802.11) -# -# CONFIG_STRIP is not set - -# -# Wireless 802.11b ISA/PCI cards support -# -CONFIG_HERMES=m -# CONFIG_PLX_HERMES is not set -# CONFIG_TMD_HERMES is not set -# CONFIG_NORTEL_HERMES is not set -# CONFIG_PCI_HERMES is not set -# CONFIG_ATMEL is not set - -# -# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support -# -CONFIG_PRISM54=m -# CONFIG_HOSTAP is not set -CONFIG_NET_WIRELESS=y - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# Multimedia Capabilities Port drivers -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Sound -# -CONFIG_SOUND=m - -# -# Advanced Linux Sound Architecture -# -# CONFIG_SND is not set - -# -# Open Sound System -# -CONFIG_SOUND_PRIME=m -# CONFIG_OBSOLETE_OSS_DRIVER is not set -# CONFIG_SOUND_FUSION is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# SN Devices -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -CONFIG_MINIX_FS=y -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -CONFIG_NTFS_FS=y -# CONFIG_NTFS_DEBUG is not set -CONFIG_NTFS_RW=y - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -# CONFIG_TMPFS is not set -CONFIG_HUGETLBFS=y -CONFIG_HUGETLB_PAGE=y -CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -CONFIG_NFSD_V4=y -CONFIG_NFSD_TCP=y -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -CONFIG_SUNRPC_GSS=y -CONFIG_RPCSEC_GSS_KRB5=y -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -CONFIG_NLS_CODEPAGE_932=y -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_MAGIC_SYSRQ is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_PREEMPT=y -CONFIG_DEBUG_SPINLOCK=y -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_INFO is not set -CONFIG_DEBUG_FS=y -# CONFIG_DEBUG_VM is not set -CONFIG_FRAME_POINTER=y -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_KGDB is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -CONFIG_CRYPTO_DES=y -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set diff --git a/trunk/arch/sh/configs/se73180_defconfig b/trunk/arch/sh/configs/se73180_defconfig index fe19feb95ca9..d217e44c89a6 100644 --- a/trunk/arch/sh/configs/se73180_defconfig +++ b/trunk/arch/sh/configs/se73180_defconfig @@ -78,7 +78,6 @@ CONFIG_SH_73180_SOLUTION_ENGINE=y # CONFIG_SH_SECUREEDGE5410 is not set # CONFIG_SH_HS7751RVOIP is not set # CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_R7780RP is not set # CONFIG_SH_EDOSK7705 is not set # CONFIG_SH_SH4202_MICRODEV is not set # CONFIG_SH_UNKNOWN is not set diff --git a/trunk/arch/sh/configs/se7343_defconfig b/trunk/arch/sh/configs/se7343_defconfig deleted file mode 100644 index 948e507b52be..000000000000 --- a/trunk/arch/sh/configs/se7343_defconfig +++ /dev/null @@ -1,997 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.17 -# Mon Aug 7 20:14:44 2006 -# -CONFIG_SUPERH=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_EMBEDDED=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -# CONFIG_FUTEX is not set -# CONFIG_EPOLL is not set -# CONFIG_SHMEM is not set -CONFIG_SLAB=y -CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set -CONFIG_OBSOLETE_INTERMODULE=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set - -# -# Block layer -# -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -CONFIG_IOSCHED_DEADLINE=y -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -CONFIG_DEFAULT_DEADLINE=y -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="deadline" - -# -# System type -# -CONFIG_SOLUTION_ENGINE=y -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -CONFIG_SH_7343_SOLUTION_ENGINE=y -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_EC3104 is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_BIGSUR is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_7710VOIPGW is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_R7780RP is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# -CONFIG_CPU_SH4=y -CONFIG_CPU_SH4A=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7706 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set -# CONFIG_CPU_SUBTYPE_SH7710 is not set - -# -# SH-4 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -# CONFIG_CPU_SUBTYPE_SH7751 is not set -# CONFIG_CPU_SUBTYPE_SH7751R is not set -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set -CONFIG_CPU_SUBTYPE_SH7343=y -# CONFIG_CPU_SUBTYPE_SH7770 is not set -# CONFIG_CPU_SUBTYPE_SH7780 is not set - -# -# Memory management options -# -CONFIG_MMU=y -CONFIG_PAGE_OFFSET=0x80000000 -CONFIG_MEMORY_START=0x0c000000 -CONFIG_MEMORY_SIZE=0x01000000 -CONFIG_32BIT=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set - -# -# Processor features -# -CONFIG_CPU_LITTLE_ENDIAN=y -# CONFIG_SH_FPU is not set -# CONFIG_SH_FPU_EMU is not set -CONFIG_SH_DSP=y -# CONFIG_SH_STORE_QUEUES is not set -CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_SR_RB=y - -# -# Timer support -# -CONFIG_SH_TMU=y -CONFIG_SH_PCLK_FREQ=27000000 - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# DMA support -# -# CONFIG_SH_DMA is not set - -# -# Companion Chips -# -# CONFIG_HD6446X_SERIES is not set -CONFIG_HEARTBEAT=y - -# -# Kernel features -# -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -# CONFIG_KEXEC is not set -# CONFIG_SMP is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x00800000 -# CONFIG_UBC_WAKEUP is not set -# CONFIG_CMDLINE_BOOL is not set - -# -# Bus options -# -# CONFIG_PCI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -CONFIG_MTD_RAM=y -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_SOLUTIONENGINE is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_STNIC is not set -CONFIG_SMC91X=y -# CONFIG_NE2000 is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_NR_UARTS=2 -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_UNIX98_PTYS is not set -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_PCA_ISA is not set -CONFIG_I2C_SH7343=y - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -CONFIG_VIDEO_DEV=y -CONFIG_VIDEO_V4L1=y -CONFIG_VIDEO_V4L1_COMPAT=y -CONFIG_VIDEO_V4L2=y - -# -# Video Capture Adapters -# - -# -# Video Capture Adapters -# -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_VIVI is not set -# CONFIG_VIDEO_CPIA is not set -# CONFIG_VIDEO_SAA5246A is not set -# CONFIG_VIDEO_SAA5249 is not set -# CONFIG_TUNER_3036 is not set -# CONFIG_VIDEO_OVCAMCHIP is not set - -# -# Encoders and Decoders -# -# CONFIG_VIDEO_MSP3400 is not set -# CONFIG_VIDEO_CS53L32A is not set -# CONFIG_VIDEO_WM8775 is not set -# CONFIG_VIDEO_WM8739 is not set -# CONFIG_VIDEO_CX25840 is not set -# CONFIG_VIDEO_SAA711X is not set -# CONFIG_VIDEO_SAA7127 is not set -# CONFIG_VIDEO_UPD64031A is not set -# CONFIG_VIDEO_UPD64083 is not set - -# -# Radio Adapters -# -# CONFIG_RADIO_MAESTRO is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FB=y -# CONFIG_FB_CFB_FILLRECT is not set -# CONFIG_FB_CFB_COPYAREA is not set -# CONFIG_FB_CFB_IMAGEBLIT is not set -# CONFIG_FB_MACMODES is not set -CONFIG_FB_FIRMWARE_EDID=y -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set -# CONFIG_FB_EPSON1355 is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -CONFIG_DUMMY_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE is not set - -# -# Logo configuration -# -# CONFIG_LOGO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -CONFIG_SOUND=y - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=y -CONFIG_SND_TIMER=y -CONFIG_SND_PCM=y -CONFIG_SND_SEQUENCER=y -# CONFIG_SND_SEQ_DUMMY is not set -CONFIG_SND_OSSEMUL=y -# CONFIG_SND_MIXER_OSS is not set -CONFIG_SND_PCM_OSS=y -CONFIG_SND_PCM_OSS_PLUGINS=y -# CONFIG_SND_SEQUENCER_OSS is not set -# CONFIG_SND_DYNAMIC_MINORS is not set -CONFIG_SND_SUPPORT_OLD_API=y -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set - -# -# Generic devices -# -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_VIRMIDI is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - -# -# SuperH devices -# -CONFIG_SH7343_SIU=m -CONFIG_AK4537_CODEC=y - -# -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_INOTIFY is not set -# CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLBFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -# CONFIG_NFSD_V3 is not set -# CONFIG_NFSD_TCP is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set -# CONFIG_KGDB is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/trunk/arch/sh/configs/sh7710voipgw_defconfig b/trunk/arch/sh/configs/sh7710voipgw_defconfig deleted file mode 100644 index ec9a3034daa5..000000000000 --- a/trunk/arch/sh/configs/sh7710voipgw_defconfig +++ /dev/null @@ -1,913 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.17 -# Mon Aug 7 17:07:06 2006 -# -CONFIG_SUPERH=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_EMBEDDED=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_BASE_FULL=y -# CONFIG_FUTEX is not set -# CONFIG_EPOLL is not set -# CONFIG_SHMEM is not set -CONFIG_SLAB=y -CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set -CONFIG_OBSOLETE_INTERMODULE=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set - -# -# Block layer -# -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -CONFIG_IOSCHED_DEADLINE=y -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -CONFIG_DEFAULT_DEADLINE=y -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="deadline" - -# -# System type -# -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_EC3104 is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_BIGSUR is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -CONFIG_SH_7710VOIPGW=y -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_R7780RP is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_TITAN is not set -# CONFIG_SH_SHMIN is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# -CONFIG_CPU_SH3=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7706 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set -CONFIG_CPU_SUBTYPE_SH7710=y - -# -# SH-4 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -# CONFIG_CPU_SUBTYPE_SH7751 is not set -# CONFIG_CPU_SUBTYPE_SH7751R is not set -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set -# CONFIG_CPU_SUBTYPE_SH7770 is not set -# CONFIG_CPU_SUBTYPE_SH7780 is not set - -# -# Memory management options -# -CONFIG_MMU=y -CONFIG_PAGE_OFFSET=0x80000000 -CONFIG_MEMORY_START=0x0c000000 -CONFIG_MEMORY_SIZE=0x00800000 -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set - -# -# Processor features -# -CONFIG_CPU_LITTLE_ENDIAN=y -# CONFIG_SH_FPU_EMU is not set -CONFIG_SH_DSP=y -# CONFIG_SH_ADC is not set -CONFIG_CPU_HAS_INTEVT=y -CONFIG_CPU_HAS_SR_RB=y - -# -# Timer support -# -CONFIG_SH_TMU=y -CONFIG_SH_PCLK_FREQ=32768000 - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# DMA support -# -# CONFIG_SH_DMA is not set - -# -# Companion Chips -# -# CONFIG_HD6446X_SERIES is not set - -# -# Kernel features -# -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -# CONFIG_KEXEC is not set -# CONFIG_PREEMPT is not set -# CONFIG_SMP is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x00800000 -# CONFIG_UBC_WAKEUP is not set -# CONFIG_CMDLINE_BOOL is not set - -# -# Bus options -# -# CONFIG_PCI is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Power management options (EXPERIMENTAL) -# -# CONFIG_PM is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_NETDEBUG is not set -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set - -# -# Core Netfilter Configuration -# -# CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NETFILTER_XTABLES is not set - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=y -# CONFIG_IP_NF_CT_ACCT is not set -# CONFIG_IP_NF_CONNTRACK_MARK is not set -# CONFIG_IP_NF_CONNTRACK_EVENTS is not set -# CONFIG_IP_NF_CT_PROTO_SCTP is not set -CONFIG_IP_NF_FTP=m -# CONFIG_IP_NF_IRC is not set -# CONFIG_IP_NF_NETBIOS_NS is not set -# CONFIG_IP_NF_TFTP is not set -# CONFIG_IP_NF_AMANDA is not set -CONFIG_IP_NF_PPTP=m -# CONFIG_IP_NF_H323 is not set -# CONFIG_IP_NF_QUEUE is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CLK_JIFFIES=y -# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set -# CONFIG_NET_SCH_CLK_CPU is not set - -# -# Queueing/Scheduling -# -CONFIG_NET_SCH_CBQ=y -# CONFIG_NET_SCH_HTB is not set -# CONFIG_NET_SCH_HFSC is not set -# CONFIG_NET_SCH_PRIO is not set -# CONFIG_NET_SCH_RED is not set -# CONFIG_NET_SCH_SFQ is not set -# CONFIG_NET_SCH_TEQL is not set -# CONFIG_NET_SCH_TBF is not set -# CONFIG_NET_SCH_GRED is not set -# CONFIG_NET_SCH_DSMARK is not set -# CONFIG_NET_SCH_NETEM is not set -CONFIG_NET_SCH_INGRESS=y - -# -# Classification -# -CONFIG_NET_CLS=y -CONFIG_NET_CLS_BASIC=y -CONFIG_NET_CLS_TCINDEX=y -CONFIG_NET_CLS_ROUTE4=y -CONFIG_NET_CLS_ROUTE=y -# CONFIG_NET_CLS_FW is not set -CONFIG_NET_CLS_U32=y -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CLS_U32_MARK is not set -# CONFIG_NET_CLS_RSVP is not set -# CONFIG_NET_CLS_RSVP6 is not set -# CONFIG_NET_EMATCH is not set -# CONFIG_NET_CLS_ACT is not set -CONFIG_NET_CLS_POLICE=y -# CONFIG_NET_CLS_IND is not set -CONFIG_NET_ESTIMATOR=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -CONFIG_MTD_RAM=y -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_SOLUTIONENGINE is not set -CONFIG_MTD_SH7710VOIPGW=y -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_STNIC is not set -# CONFIG_SMC91X is not set -# CONFIG_NE2000 is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -CONFIG_PHONE=y -# CONFIG_PHONE_IXJ is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_NR_UARTS=2 -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_UNIX98_PTYS is not set -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB_ARCH_HAS_HCD is not set -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - -# -# InfiniBand support -# - -# -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) -# - -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_INOTIFY is not set -# CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLBFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_KGDB is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/trunk/arch/sh/configs/titan_defconfig b/trunk/arch/sh/configs/titan_defconfig deleted file mode 100644 index 1db2904de9e5..000000000000 --- a/trunk/arch/sh/configs/titan_defconfig +++ /dev/null @@ -1,1367 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.14-sh -# Wed Nov 9 00:35:56 2005 -# -CONFIG_SUPERH=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -CONFIG_HOTPLUG=y -CONFIG_KOBJECT_UEVENT=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# System type -# -# CONFIG_SH_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SOLUTION_ENGINE is not set -# CONFIG_SH_7300_SOLUTION_ENGINE is not set -# CONFIG_SH_73180_SOLUTION_ENGINE is not set -# CONFIG_SH_7751_SYSTEMH is not set -CONFIG_SH_TITAN=y -# CONFIG_SH_STB1_HARP is not set -# CONFIG_SH_STB1_OVERDRIVE is not set -# CONFIG_SH_HP6XX is not set -# CONFIG_SH_CQREEK is not set -# CONFIG_SH_DMIDA is not set -# CONFIG_SH_EC3104 is not set -# CONFIG_SH_SATURN is not set -# CONFIG_SH_DREAMCAST is not set -# CONFIG_SH_CAT68701 is not set -# CONFIG_SH_BIGSUR is not set -# CONFIG_SH_SH2000 is not set -# CONFIG_SH_ADX is not set -# CONFIG_SH_MPC1211 is not set -# CONFIG_SH_SH03 is not set -# CONFIG_SH_SECUREEDGE5410 is not set -# CONFIG_SH_HS7751RVOIP is not set -# CONFIG_SH_RTS7751R2D is not set -# CONFIG_SH_EDOSK7705 is not set -# CONFIG_SH_SH4202_MICRODEV is not set -# CONFIG_SH_LANDISK is not set -# CONFIG_SH_UNKNOWN is not set - -# -# Processor selection -# -CONFIG_CPU_SH4=y - -# -# SH-2 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7604 is not set - -# -# SH-3 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7300 is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set - -# -# SH-4 Processor Support -# -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -CONFIG_CPU_SUBTYPE_SH7751=y -CONFIG_CPU_SUBTYPE_SH7751R=y -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set - -# -# ST40 Processor Support -# -# CONFIG_CPU_SUBTYPE_ST40STB1 is not set -# CONFIG_CPU_SUBTYPE_ST40GX1 is not set - -# -# SH-4A Processor Support -# -# CONFIG_CPU_SUBTYPE_SH73180 is not set -# CONFIG_CPU_SUBTYPE_SH7770 is not set -# CONFIG_CPU_SUBTYPE_SH7780 is not set - -# -# Memory management options -# -CONFIG_MMU=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -# CONFIG_SH_WRITETHROUGH is not set -# CONFIG_SH_OCRAM is not set -CONFIG_MEMORY_START=0x08030000 -CONFIG_MEMORY_SIZE=0x7fd0000 - -# -# Processor features -# -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_SH_RTC=y -CONFIG_SH_FPU=y -# CONFIG_SH_STORE_QUEUES is not set - -# -# Timer support -# -CONFIG_SH_TMU=y -CONFIG_SH_PCLK_FREQ_BOOL=y -CONFIG_SH_PCLK_FREQ=30000000 - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# DMA support -# -CONFIG_SH_DMA=y -CONFIG_NR_ONCHIP_DMA_CHANNELS=8 -# CONFIG_NR_DMA_CHANNELS_BOOL is not set - -# -# Companion Chips -# -# CONFIG_HD6446X_SERIES is not set - -# -# Kernel features -# -# CONFIG_KEXEC is not set -# CONFIG_PREEMPT is not set -# CONFIG_SMP is not set - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x009e0000 -# CONFIG_UBC_WAKEUP is not set -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf" - -# -# Bus options -# -CONFIG_PCI=y -CONFIG_SH_PCIDMA_NONCOHERENT=y -CONFIG_PCI_AUTO=y -CONFIG_PCI_AUTO_UPDATE_RESOURCES=y -CONFIG_PCI_LEGACY_PROC=y -#CONFIG_PCI_DEBUG is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# PCI Hotplug Support -# -CONFIG_HOTPLUG_PCI=y -# CONFIG_HOTPLUG_PCI_FAKE is not set -# CONFIG_HOTPLUG_PCI_CPCI is not set -# CONFIG_HOTPLUG_PCI_SHPC is not set - -# -# Executable file formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_FLAT is not set -# CONFIG_BINFMT_MISC is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -CONFIG_NET_KEY=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_MULTIPLE_TABLES=y -# CONFIG_IP_ROUTE_FWMARK is not set -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_MULTIPATH_CACHED=y -CONFIG_IP_ROUTE_MULTIPATH_RR=m -CONFIG_IP_ROUTE_MULTIPATH_RANDOM=m -CONFIG_IP_ROUTE_MULTIPATH_WRANDOM=m -CONFIG_IP_ROUTE_MULTIPATH_DRR=m -# CONFIG_IP_ROUTE_VERBOSE is not set -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -CONFIG_INET_AH=m -CONFIG_INET_ESP=m -CONFIG_INET_IPCOMP=m -CONFIG_INET_TUNNEL=m -CONFIG_INET_DIAG=m -CONFIG_INET_TCP_DIAG=m -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -CONFIG_IPV6=m -CONFIG_IPV6_PRIVACY=y -CONFIG_INET6_AH=m -CONFIG_INET6_ESP=m -CONFIG_INET6_IPCOMP=m -CONFIG_INET6_TUNNEL=m -CONFIG_IPV6_TUNNEL=m -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_BRIDGE_NETFILTER=y -CONFIG_NETFILTER_NETLINK=m -CONFIG_NETFILTER_NETLINK_QUEUE=m -CONFIG_NETFILTER_NETLINK_LOG=m - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -CONFIG_IP_NF_CT_ACCT=y -CONFIG_IP_NF_CONNTRACK_MARK=y -CONFIG_IP_NF_CONNTRACK_EVENTS=y -CONFIG_IP_NF_CONNTRACK_NETLINK=m -# CONFIG_IP_NF_CT_PROTO_SCTP is not set -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_IRC=m -CONFIG_IP_NF_NETBIOS_NS=m -CONFIG_IP_NF_TFTP=m -# CONFIG_IP_NF_AMANDA is not set -CONFIG_IP_NF_PPTP=m -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_LENGTH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_OWNER=m -# CONFIG_IP_NF_MATCH_PHYSDEV is not set -CONFIG_IP_NF_MATCH_ADDRTYPE=m -CONFIG_IP_NF_MATCH_REALM=m -# CONFIG_IP_NF_MATCH_SCTP is not set -# CONFIG_IP_NF_MATCH_DCCP is not set -CONFIG_IP_NF_MATCH_COMMENT=m -CONFIG_IP_NF_MATCH_CONNMARK=m -CONFIG_IP_NF_MATCH_CONNBYTES=m -CONFIG_IP_NF_MATCH_HASHLIMIT=m -CONFIG_IP_NF_MATCH_STRING=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m -CONFIG_IP_NF_TARGET_NFQUEUE=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_NAT_TFTP=m -CONFIG_IP_NF_NAT_PPTP=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_DSCP=m -CONFIG_IP_NF_TARGET_MARK=m -CONFIG_IP_NF_TARGET_CLASSIFY=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_TARGET_CONNMARK=m -CONFIG_IP_NF_TARGET_CLUSTERIP=m -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_TARGET_NOTRACK=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m - -# -# IPv6: Netfilter Configuration (EXPERIMENTAL) -# -CONFIG_IP6_NF_QUEUE=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_LIMIT=m -CONFIG_IP6_NF_MATCH_MAC=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_MULTIPORT=m -CONFIG_IP6_NF_MATCH_OWNER=m -CONFIG_IP6_NF_MATCH_MARK=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_AHESP=m -CONFIG_IP6_NF_MATCH_LENGTH=m -CONFIG_IP6_NF_MATCH_EUI64=m -# CONFIG_IP6_NF_MATCH_PHYSDEV is not set -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_LOG=m -CONFIG_IP6_NF_TARGET_REJECT=m -CONFIG_IP6_NF_TARGET_NFQUEUE=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_TARGET_MARK=m -CONFIG_IP6_NF_TARGET_HL=m -CONFIG_IP6_NF_RAW=m - -# -# Bridge: Netfilter Configuration -# -# CONFIG_BRIDGE_NF_EBTABLES is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -CONFIG_BRIDGE=m -CONFIG_VLAN_8021Q=m -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CLK_JIFFIES=y -# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set -# CONFIG_NET_SCH_CLK_CPU is not set -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_NETEM=m -CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_QOS=y -CONFIG_NET_ESTIMATOR=y -CONFIG_NET_CLS=y -CONFIG_NET_CLS_BASIC=m -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_CLS_U32_PERF=y -CONFIG_NET_CLS_IND=y -CONFIG_CLS_U32_MARK=y -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_EMATCH=y -CONFIG_NET_EMATCH_STACK=32 -CONFIG_NET_EMATCH_CMP=m -CONFIG_NET_EMATCH_NBYTE=m -CONFIG_NET_EMATCH_U32=m -CONFIG_NET_EMATCH_META=m -CONFIG_NET_EMATCH_TEXT=m -CONFIG_NET_CLS_ACT=y -CONFIG_NET_ACT_POLICE=m -CONFIG_NET_ACT_GACT=m -CONFIG_GACT_PROB=y -CONFIG_NET_ACT_MIRRED=m -CONFIG_NET_ACT_IPT=m -CONFIG_NET_ACT_PEDIT=m -# CONFIG_NET_ACT_SIMP is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# CONFIG_DEBUG_DRIVER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -CONFIG_CONNECTOR=m - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -CONFIG_BLK_SSFDC=y -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=m -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_UB is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_LBD is not set -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=m -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=m -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=m -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=m -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI Transport Attributes -# -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLA2XXX=m -# CONFIG_SCSI_QLA21XX is not set -# CONFIG_SCSI_QLA22XX is not set -# CONFIG_SCSI_QLA2300 is not set -# CONFIG_SCSI_QLA2322 is not set -# CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA24XX is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=m - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=m -CONFIG_PHYCONTROL=y - -# -# MII PHY device drivers -# -CONFIG_MARVELL_PHY=m -CONFIG_DAVICOM_PHY=m -CONFIG_QSEMI_PHY=m -CONFIG_LXT_PHY=m -CONFIG_CICADA_PHY=m - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_STNIC is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -CONFIG_CASSINI=m -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_SMC91X is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -# CONFIG_NE2000 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -CONFIG_8139TOO=y -# CONFIG_8139TOO_PIO is not set -CONFIG_8139TOO_TUNE_TWISTER=y -# CONFIG_8139TOO_8129 is not set -CONFIG_8139_OLD_RX_RESET=y -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y - -# -# Obsolete Wireless cards support (pre-802.11) -# -# CONFIG_STRIP is not set - -# -# Wireless 802.11b ISA/PCI cards support -# -# CONFIG_HERMES is not set -# CONFIG_ATMEL is not set - -# -# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support -# -CONFIG_PRISM54=m -# CONFIG_HOSTAP is not set -CONFIG_NET_WIRELESS=y - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPPOE=m -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_RTC is not set -# CONFIG_GEN_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# Multimedia Capabilities Port drivers -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Console display driver support -# -CONFIG_DUMMY_CONSOLE=y - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB=m -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -CONFIG_USB_EHCI_HCD=m -# CONFIG_USB_EHCI_SPLIT_ISO is not set -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=m -# CONFIG_USB_OHCI_BIG_ENDIAN is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_USB_BLUETOOTH_TTY is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# -CONFIG_USB_STORAGE=m -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set - -# -# USB Input Devices -# -# CONFIG_USB_HID is not set - -# -# USB HID Boot Protocol drivers -# -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_MTOUCH is not set -# CONFIG_USB_ITMTOUCH is not set -# CONFIG_USB_EGALAX is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_APPLETOUCH is not set - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Multimedia devices -# -# CONFIG_USB_DABUSB is not set - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_USB_ZD1201 is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -CONFIG_USB_SERIAL=m -CONFIG_USB_SERIAL_GENERIC=y -# CONFIG_USB_SERIAL_AIRPRIME is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_CP2101 is not set -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_GARMIN is not set -# CONFIG_USB_SERIAL_IPW is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -CONFIG_USB_SERIAL_PL2303=m -# CONFIG_USB_SERIAL_HP4X is not set -# CONFIG_USB_SERIAL_SAFE is not set -# CONFIG_USB_SERIAL_TI is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OMNINET is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGETKIT is not set -# CONFIG_USB_PHIDGETSERVO is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# SN Devices -# - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_REISERFS_FS_XATTR is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=m - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=m -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_ZISOFS_FS=m -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLBFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -CONFIG_RELAYFS_FS=m - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -# CONFIG_NFSD_V4 is not set -CONFIG_NFSD_TCP=y -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -CONFIG_9P_FS=m - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -CONFIG_NLS=m -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=m -CONFIG_NLS_ISO8859_1=m -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=m - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_DEBUG_KERNEL=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_LOG_BUF_SHIFT=16 -# CONFIG_DETECT_SOFTLOCKUP is not set -# CONFIG_SCHEDSTATS is not set -CONFIG_DEBUG_SLAB=y -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_FRAME_POINTER is not set -# CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y -# CONFIG_EARLY_PRINTK is not set -# CONFIG_KGDB is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_NULL is not set -CONFIG_CRYPTO_MD4=m -CONFIG_CRYPTO_MD5=m -CONFIG_CRYPTO_SHA1=m -CONFIG_CRYPTO_SHA256=m -CONFIG_CRYPTO_SHA512=m -CONFIG_CRYPTO_WP512=m -CONFIG_CRYPTO_TGR192=m -CONFIG_CRYPTO_DES=m -CONFIG_CRYPTO_BLOWFISH=m -CONFIG_CRYPTO_TWOFISH=m -CONFIG_CRYPTO_SERPENT=m -CONFIG_CRYPTO_AES=m -CONFIG_CRYPTO_CAST5=m -CONFIG_CRYPTO_CAST6=m -CONFIG_CRYPTO_TEA=m -CONFIG_CRYPTO_ARC4=m -CONFIG_CRYPTO_KHAZAD=m -CONFIG_CRYPTO_ANUBIS=m -CONFIG_CRYPTO_DEFLATE=m -CONFIG_CRYPTO_MICHAEL_MIC=m -CONFIG_CRYPTO_CRC32C=m -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_CRC_CCITT=m -CONFIG_CRC16=m -CONFIG_CRC32=y -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m diff --git a/trunk/arch/sh/drivers/dma/Kconfig b/trunk/arch/sh/drivers/dma/Kconfig index defc13c37d48..0f15216cd39d 100644 --- a/trunk/arch/sh/drivers/dma/Kconfig +++ b/trunk/arch/sh/drivers/dma/Kconfig @@ -11,8 +11,6 @@ config SH_DMA config NR_ONCHIP_DMA_CHANNELS depends on SH_DMA int "Number of on-chip DMAC channels" - default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R - default "12" if CPU_SUBTYPE_SH7780 default "4" help This allows you to specify the number of channels that the on-chip @@ -54,3 +52,4 @@ config DMA_PAGE_OPS_CHANNEL are dual-address capable. endmenu + diff --git a/trunk/arch/sh/drivers/dma/dma-g2.c b/trunk/arch/sh/drivers/dma/dma-g2.c index 9cb070924180..0f866f8789f0 100644 --- a/trunk/arch/sh/drivers/dma/dma-g2.c +++ b/trunk/arch/sh/drivers/dma/dma-g2.c @@ -3,7 +3,7 @@ * * G2 bus DMA support * - * Copyright (C) 2003 - 2006 Paul Mundt + * Copyright (C) 2003, 2004 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -13,7 +13,7 @@ #include #include #include -#include + #include #include #include @@ -47,32 +47,18 @@ struct g2_dma_info { static volatile struct g2_dma_info *g2_dma = (volatile struct g2_dma_info *)0xa05f7800; -#define g2_bytes_remaining(i) \ - ((g2_dma->channel[i].size - \ - g2_dma->status[i].size) & 0x0fffffff) - static irqreturn_t g2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - int i; - - for (i = 0; i < G2_NR_DMA_CHANNELS; i++) { - if (g2_dma->status[i].status & 0x20000000) { - unsigned int bytes = g2_bytes_remaining(i); - - if (likely(bytes == 0)) { - struct dma_info *info = dev_id; - struct dma_channel *chan = info->channels + i; - - wake_up(&chan->wait_queue); - - return IRQ_HANDLED; - } - } - } - - return IRQ_NONE; + /* FIXME: Do some meaningful completion work here.. */ + return IRQ_HANDLED; } +static struct irqaction g2_dma_irq = { + .name = "g2 DMA handler", + .handler = g2_dma_interrupt, + .flags = IRQF_DISABLED, +}; + static int g2_enable_dma(struct dma_channel *chan) { unsigned int chan_nr = chan->chan; @@ -149,14 +135,8 @@ static int g2_xfer_dma(struct dma_channel *chan) return 0; } -static int g2_get_residue(struct dma_channel *chan) -{ - return g2_bytes_remaining(chan->chan); -} - static struct dma_ops g2_dma_ops = { .xfer = g2_xfer_dma, - .get_residue = g2_get_residue, }; static struct dma_info g2_dma_info = { @@ -168,22 +148,13 @@ static struct dma_info g2_dma_info = { static int __init g2_dma_init(void) { - int ret; - - ret = request_irq(HW_EVENT_G2_DMA, g2_dma_interrupt, IRQF_DISABLED, - "g2 DMA handler", &g2_dma_info); - if (unlikely(ret)) - return -EINVAL; + setup_irq(HW_EVENT_G2_DMA, &g2_dma_irq); /* Magic */ g2_dma->wait_state = 27; g2_dma->magic = 0x4659404f; - ret = register_dmac(&g2_dma_info); - if (unlikely(ret != 0)) - free_irq(HW_EVENT_G2_DMA, 0); - - return ret; + return register_dmac(&g2_dma_info); } static void __exit g2_dma_exit(void) @@ -198,3 +169,4 @@ module_exit(g2_dma_exit); MODULE_AUTHOR("Paul Mundt "); MODULE_DESCRIPTION("G2 bus DMA driver"); MODULE_LICENSE("GPL"); + diff --git a/trunk/arch/sh/drivers/dma/dma-pvr2.c b/trunk/arch/sh/drivers/dma/dma-pvr2.c index 3b0b0f60bb3c..30a580aa7cbd 100644 --- a/trunk/arch/sh/drivers/dma/dma-pvr2.c +++ b/trunk/arch/sh/drivers/dma/dma-pvr2.c @@ -18,8 +18,8 @@ #include #include -static unsigned int xfer_complete; -static int count; +static unsigned int xfer_complete = 0; +static int count = 0; static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) { @@ -107,3 +107,4 @@ module_exit(pvr2_dma_exit); MODULE_AUTHOR("Paul Mundt "); MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver"); MODULE_LICENSE("GPL"); + diff --git a/trunk/arch/sh/drivers/dma/dma-sh.c b/trunk/arch/sh/drivers/dma/dma-sh.c index cbbe8bce3d67..e028a2d2a4ea 100644 --- a/trunk/arch/sh/drivers/dma/dma-sh.c +++ b/trunk/arch/sh/drivers/dma/dma-sh.c @@ -11,10 +11,14 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ + #include +#include #include #include #include +#include +#include #include #include #include "dma-sh.h" @@ -80,23 +84,18 @@ static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs) static int sh_dmac_request_dma(struct dma_channel *chan) { - if (unlikely(!chan->flags & DMA_TEI_CAPABLE)) - return 0; + char name[32]; - chan->name = kzalloc(32, GFP_KERNEL); - if (unlikely(chan->name == NULL)) - return -ENOMEM; - snprintf(chan->name, 32, "DMAC Transfer End (Channel %d)", + snprintf(name, sizeof(name), "DMAC Transfer End (Channel %d)", chan->chan); return request_irq(get_dmte_irq(chan->chan), dma_tei, - IRQF_DISABLED, chan->name, chan); + IRQF_DISABLED, name, chan); } static void sh_dmac_free_dma(struct dma_channel *chan) { free_irq(get_dmte_irq(chan->chan), chan); - kfree(chan->name); } static void @@ -260,7 +259,7 @@ static int __init sh_dmac_init(void) #ifdef CONFIG_CPU_SH4 make_ipr_irq(DMAE_IRQ, DMA_IPR_ADDR, DMA_IPR_POS, DMA_PRIORITY); i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0); - if (unlikely(i < 0)) + if (i < 0) return i; #endif @@ -275,7 +274,7 @@ static int __init sh_dmac_init(void) * been set. */ i = dmaor_reset(); - if (unlikely(i != 0)) + if (i < 0) return i; return register_dmac(info); diff --git a/trunk/arch/sh/drivers/pci/Makefile b/trunk/arch/sh/drivers/pci/Makefile index 9e00cb8a39e9..365bc16a4a83 100644 --- a/trunk/arch/sh/drivers/pci/Makefile +++ b/trunk/arch/sh/drivers/pci/Makefile @@ -6,8 +6,7 @@ obj-y += pci.o obj-$(CONFIG_PCI_AUTO) += pci-auto.o obj-$(CONFIG_CPU_SUBTYPE_ST40STB1) += pci-st40.o -obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o -obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o +obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ dma-dreamcast.o @@ -15,6 +14,3 @@ obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o -obj-$(CONFIG_SH_R7780RP) += ops-r7780rp.o fixups-r7780rp.o -obj-$(CONFIG_SH_TITAN) += ops-titan.o -obj-$(CONFIG_SH_LANDISK) += ops-landisk.o diff --git a/trunk/arch/sh/drivers/pci/fixups-dreamcast.c b/trunk/arch/sh/drivers/pci/fixups-dreamcast.c index c0af5f7ef414..63b1c6f4b8d2 100644 --- a/trunk/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/trunk/arch/sh/drivers/pci/fixups-dreamcast.c @@ -4,7 +4,7 @@ * PCI fixups for the Sega Dreamcast * * Copyright (C) 2001, 2002 M. R. Brown - * Copyright (C) 2002, 2003, 2006 Paul Mundt + * Copyright (C) 2002, 2003 Paul Mundt * * This file originally bore the message (with enclosed-$): * Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp @@ -45,16 +45,36 @@ static void __init gapspci_fixup_resources(struct pci_dev *dev) printk("PCI: Failed resource fixup\n"); } } + DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources); -int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) +void __init pcibios_fixup_bus(struct pci_bus *bus) { - /* - * The interrupt routing semantics here are quite trivial. - * - * We basically only support one interrupt, so we only bother - * updating a device's interrupt line with this single shared - * interrupt. Keeps routing quite simple, doesn't it? + /* + * We don't have any sub bus to fix up, and this is a rather + * stupid place to put general device fixups. Don't do it. + * Use the pcibios_fixups table or suffer the consequences. */ - return GAPSPCI_IRQ; } + +void __init pcibios_fixup_irqs(void) +{ + struct pci_dev *dev = 0; + + for_each_pci_dev(dev) { + /* + * The interrupt routing semantics here are quite trivial. + * + * We basically only support one interrupt, so we only bother + * updating a device's interrupt line with this single shared + * interrupt. Keeps routing quite simple, doesn't it? + */ + printk(KERN_NOTICE "PCI: Fixing up IRQ routing for device %s\n", + pci_name(dev)); + + dev->irq = GAPSPCI_IRQ; + + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + diff --git a/trunk/arch/sh/drivers/pci/fixups-r7780rp.c b/trunk/arch/sh/drivers/pci/fixups-r7780rp.c deleted file mode 100644 index 3e321df65d22..000000000000 --- a/trunk/arch/sh/drivers/pci/fixups-r7780rp.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * arch/sh/drivers/pci/fixups-r7780rp.c - * - * Highlander R7780RP-1 PCI fixups - * - * Copyright (C) 2003 Lineo uSolutions, Inc. - * Copyright (C) 2004 - 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include "pci-sh4.h" -#include - -int pci_fixup_pcic(void) -{ - pci_write_reg(0x000043ff, SH4_PCIINTM); - pci_write_reg(0x0000380f, SH4_PCIAINTM); - - pci_write_reg(0xfbb00047, SH7780_PCICMD); - pci_write_reg(0x00000000, SH7780_PCIIBAR); - - pci_write_reg(0x00011912, SH7780_PCISVID); - pci_write_reg(0x08000000, SH7780_PCICSCR0); - pci_write_reg(0x0000001b, SH7780_PCICSAR0); - pci_write_reg(0xfd000000, SH7780_PCICSCR1); - pci_write_reg(0x0000000f, SH7780_PCICSAR1); - - pci_write_reg(0xfd000000, SH7780_PCIMBR0); - pci_write_reg(0x00fc0000, SH7780_PCIMBMR0); - -#ifdef CONFIG_32BIT - pci_write_reg(0xc0000000, SH7780_PCIMBR2); - pci_write_reg(0x20000000 - SH7780_PCI_IO_SIZE, SH7780_PCIMBMR2); -#endif - - /* Set IOBR for windows containing area specified in pci.h */ - pci_write_reg((PCIBIOS_MIN_IO & ~(SH7780_PCI_IO_SIZE - 1)), - SH7780_PCIIOBR); - pci_write_reg(((SH7780_PCI_IO_SIZE-1) & (7<<18)), SH7780_PCIIOBMR); - - return 0; -} diff --git a/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c b/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c index e72ceb560d5b..0c590fc7a081 100644 --- a/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -10,7 +10,8 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ -#include "pci-sh4.h" +#include "pci-sh7751.h" +#include #define PCIMCR_MRSET_OFF 0xBFFFFFFF #define PCIMCR_RFSH_OFF 0xFFFFFFFB @@ -21,23 +22,22 @@ int pci_fixup_pcic(void) bcr1 = inl(SH7751_BCR1); bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ - pci_write_reg(bcr1, SH4_PCIBCR1); + outl(bcr1, PCI_REG(SH7751_PCIBCR1)); /* Enable all interrupts, so we known what to fix */ - pci_write_reg(0x0000c3ff, SH4_PCIINTM); - pci_write_reg(0x0000380f, SH4_PCIAINTM); + outl(0x0000c3ff, PCI_REG(SH7751_PCIINTM)); + outl(0x0000380f, PCI_REG(SH7751_PCIAINTM)); - pci_write_reg(0xfb900047, SH7751_PCICONF1); - pci_write_reg(0xab000001, SH7751_PCICONF4); + outl(0xfb900047, PCI_REG(SH7751_PCICONF1)); + outl(0xab000001, PCI_REG(SH7751_PCICONF4)); mcr = inl(SH7751_MCR); mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; - pci_write_reg(mcr, SH4_PCIMCR); - - pci_write_reg(0x0c000000, SH7751_PCICONF5); - pci_write_reg(0xd0000000, SH7751_PCICONF6); - pci_write_reg(0x0c000000, SH4_PCILAR0); - pci_write_reg(0x00000000, SH4_PCILAR1); + outl(mcr, PCI_REG(SH7751_PCIMCR)); + outl(0x0c000000, PCI_REG(SH7751_PCICONF5)); + outl(0xd0000000, PCI_REG(SH7751_PCICONF6)); + outl(0x0c000000, PCI_REG(SH7751_PCILAR0)); + outl(0x00000000, PCI_REG(SH7751_PCILAR1)); return 0; } diff --git a/trunk/arch/sh/drivers/pci/fixups-sh03.c b/trunk/arch/sh/drivers/pci/fixups-sh03.c index 2e8a18b7ee53..57ac26c2171f 100644 --- a/trunk/arch/sh/drivers/pci/fixups-sh03.c +++ b/trunk/arch/sh/drivers/pci/fixups-sh03.c @@ -3,7 +3,11 @@ #include #include -int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) +/* + * IRQ functions + */ + +int __init pcibios_map_platform_irq(u8 slot, u8 pin, struct pci_dev *dev) { int irq; @@ -13,9 +17,8 @@ int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) case 8: return 5; /* eth1 */ case 6: return 2; /* PCI bridge */ default: - printk(KERN_ERR "PCI: Bad IRQ mapping request " - "for slot %d\n", slot); - return 2; + printk("PCI: Bad IRQ mapping request for slot %d\n", slot); + return 2; } } else { switch (pin) { @@ -29,3 +32,30 @@ int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) } return irq; } + +static u8 __init sh03_no_swizzle(struct pci_dev *dev, u8 *pin) +{ + /* no swizzling */ + return PCI_SLOT(dev->devfn); +} + +static int sh03_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq = -1; + + /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */ + irq = pcibios_map_platform_irq(slot, pin, dev); + if( irq < 0 ) { + pr_debug("PCI: Error mapping IRQ on device %s\n", pci_name(dev)); + return irq; + } + + pr_debug("Setting IRQ for slot %s to %d\n", pci_name(dev), irq); + + return irq; +} + +void __init pcibios_fixup_irqs(void) +{ + pci_fixup_irqs(sh03_no_swizzle, sh03_pci_lookup_irq); +} diff --git a/trunk/arch/sh/drivers/pci/ops-bigsur.c b/trunk/arch/sh/drivers/pci/ops-bigsur.c index 5da501bd77b5..ae82c6ca05e5 100644 --- a/trunk/arch/sh/drivers/pci/ops-bigsur.c +++ b/trunk/arch/sh/drivers/pci/ops-bigsur.c @@ -10,12 +10,15 @@ * * PCI initialization for the Hitachi Big Sur Evaluation Board */ + #include #include #include +#include #include + #include -#include "pci-sh4.h" +#include "pci-sh7751.h" #include #define BIGSUR_PCI_IO 0x4000 @@ -38,11 +41,11 @@ static struct resource sh7751_mem_resource = { extern struct pci_ops sh7751_pci_ops; struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, { 0, } }; -static struct sh4_pci_address_map sh7751_pci_map = { +static struct sh7751_pci_address_map sh7751_pci_map = { .window0 = { .base = SH7751_CS3_BASE_ADDR, .size = BIGSUR_LSR0_SIZE, @@ -55,7 +58,7 @@ static struct sh4_pci_address_map sh7751_pci_map = { }; /* - * Initialize the Big Sur PCI interface + * Initialize the Big Sur PCI interface * Setup hardware to be Central Funtion * Copy the BSR regs to the PCI interface * Setup PCI windows into local RAM @@ -65,15 +68,15 @@ int __init pcibios_init_platform(void) return sh7751_pcic_init(&sh7751_pci_map); } -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int pcibios_map_platform_irq(u8 slot, u8 pin) { - /* + /* * The Big Sur can be used in a CPCI chassis, but the SH7751 PCI * interface is on the wrong end of the board so that it can also * support a V320 CPI interface chip... Therefor the IRQ mapping is * somewhat use dependent... I'l assume a linear map for now, i.e. * INTA=slot0,pin0... INTD=slot3,pin0... - */ + */ int irq = (slot + pin-1) % 4 + BIGSUR_SH7751_PCI_IRQ_BASE; PCIDBG(2, "PCI: Mapping Big Sur IRQ for slot %d, pin %c to irq %d\n", @@ -81,3 +84,4 @@ int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) return irq; } + diff --git a/trunk/arch/sh/drivers/pci/ops-landisk.c b/trunk/arch/sh/drivers/pci/ops-landisk.c deleted file mode 100644 index ada301c21fe7..000000000000 --- a/trunk/arch/sh/drivers/pci/ops-landisk.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * arch/sh/drivers/pci/ops-landisk.c - * - * PCI initialization for the I-O DATA Device, Inc. LANDISK board - * - * Copyright (C) 2006 kogiidena - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - */ -#include -#include -#include -#include -#include -#include -#include "pci-sh4.h" - -static struct resource sh7751_io_resource = { - .name = "SH7751 IO", - .start = 0x4000, - .end = 0x4000 + SH7751_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7751_mem_resource = { - .name = "SH7751 mem", - .start = SH7751_PCI_MEMORY_BASE, - .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -struct pci_channel board_pci_channels[] = { - {&sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0x3ff}, - {NULL, NULL, NULL, 0, 0}, -}; - -static struct sh4_pci_address_map sh7751_pci_map = { - .window0 = { - .base = SH7751_CS3_BASE_ADDR, - .size = (64 << 20), /* 64MB */ - }, - - .flags = SH4_PCIC_NO_RESET, -}; - -int __init pcibios_init_platform(void) -{ - return sh7751_pcic_init(&sh7751_pci_map); -} - -int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) -{ - /* - * slot0: pin1-4 = irq5,6,7,8 - * slot1: pin1-4 = irq6,7,8,5 - * slot2: pin1-4 = irq7,8,5,6 - * slot3: pin1-4 = irq8,5,6,7 - */ - int irq = ((slot + pin - 1) & 0x3) + 5; - - if ((slot | (pin - 1)) > 0x3) { - printk("PCI: Bad IRQ mapping request for slot %d pin %c\n", - slot, pin - 1 + 'A'); - return -1; - } - return irq; -} diff --git a/trunk/arch/sh/drivers/pci/ops-r7780rp.c b/trunk/arch/sh/drivers/pci/ops-r7780rp.c deleted file mode 100644 index 554d5ed2c586..000000000000 --- a/trunk/arch/sh/drivers/pci/ops-r7780rp.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Author: Ian DaSilva (idasilva@mvista.com) - * - * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * PCI initialization for the Renesas SH7780 Highlander R7780RP-1 board - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "pci-sh4.h" - -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) -{ - switch (slot) { - case 0: return IRQ_PCISLOT1; /* PCI Interrupt #1 */ - case 1: return IRQ_PCISLOT2; /* PCI Interrupt #2 */ - case 2: return IRQ_PCISLOT3; /* PCI Interrupt #3 */ - case 3: return IRQ_PCISLOT4; /* PCI Interrupt E4 */ - default: - printk(KERN_ERR "PCI: Bad IRQ mapping " - "request for slot %d, func %d\n", slot, pin-1); - return -1; - } -} - -static struct resource sh7780_io_resource = { - .name = "SH7780_IO", - .start = 0x2000, - .end = 0x2000 + SH7780_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7780_mem_resource = { - .name = "SH7780_mem", - .start = SH7780_PCI_MEMORY_BASE, - .end = SH7780_PCI_MEMORY_BASE + SH7780_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -extern struct pci_ops sh7780_pci_ops; - -struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sh7780_io_resource, &sh7780_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; -EXPORT_SYMBOL(board_pci_channels); - -static struct sh4_pci_address_map sh7780_pci_map = { - .window0 = { - .base = SH7780_CS2_BASE_ADDR, - .size = 0x04000000, - }, - - .window1 = { - .base = SH7780_CS3_BASE_ADDR, - .size = 0x04000000, - }, - - .flags = SH4_PCIC_NO_RESET, -}; - -int __init pcibios_init_platform(void) -{ - return sh7780_pcic_init(&sh7780_pci_map); -} diff --git a/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c b/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c index 88f44e245424..83171d10141a 100644 --- a/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c @@ -17,11 +17,12 @@ #include #include #include -#include + #include -#include "pci-sh4.h" +#include "pci-sh7751.h" +#include -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(u8 slot, u8 pin) { switch (slot) { case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */ @@ -51,12 +52,12 @@ static struct resource sh7751_mem_resource = { extern struct pci_ops sh7751_pci_ops; struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; EXPORT_SYMBOL(board_pci_channels); -static struct sh4_pci_address_map sh7751_pci_map = { +static struct sh7751_pci_address_map sh7751_pci_map = { .window0 = { .base = SH7751_CS3_BASE_ADDR, .size = 0x04000000, @@ -67,7 +68,7 @@ static struct sh4_pci_address_map sh7751_pci_map = { .size = 0x00000000, /* Unused */ }, - .flags = SH4_PCIC_NO_RESET, + .flags = SH7751_PCIC_NO_RESET, }; int __init pcibios_init_platform(void) diff --git a/trunk/arch/sh/drivers/pci/ops-sh4.c b/trunk/arch/sh/drivers/pci/ops-sh4.c deleted file mode 100644 index 2d4371009a5e..000000000000 --- a/trunk/arch/sh/drivers/pci/ops-sh4.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Generic SH-4 / SH-4A PCIC operations (SH7751, SH7780). - * - * Copyright (C) 2002 - 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License v2. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include "pci-sh4.h" - -/* - * Direct access to PCI hardware... - */ -#define CONFIG_CMD(bus, devfn, where) \ - P1SEGADDR((bus->number << 16) | (devfn << 8) | (where & ~3)) - -static DEFINE_SPINLOCK(sh4_pci_lock); - -/* - * Functions for accessing PCI configuration space with type 1 accesses - */ -static int sh4_pci_read(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 *val) -{ - unsigned long flags; - u32 data; - - /* - * PCIPDR may only be accessed as 32 bit words, - * so we must do byte alignment by hand - */ - spin_lock_irqsave(&sh4_pci_lock, flags); - pci_write_reg(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); - data = pci_read_reg(SH4_PCIPDR); - spin_unlock_irqrestore(&sh4_pci_lock, flags); - - switch (size) { - case 1: - *val = (data >> ((where & 3) << 3)) & 0xff; - break; - case 2: - *val = (data >> ((where & 2) << 3)) & 0xffff; - break; - case 4: - *val = data; - break; - default: - return PCIBIOS_FUNC_NOT_SUPPORTED; - } - - return PCIBIOS_SUCCESSFUL; -} - -/* - * Since SH4 only does 32bit access we'll have to do a read, - * mask,write operation. - * We'll allow an odd byte offset, though it should be illegal. - */ -static int sh4_pci_write(struct pci_bus *bus, unsigned int devfn, - int where, int size, u32 val) -{ - unsigned long flags; - int shift; - u32 data; - - spin_lock_irqsave(&sh4_pci_lock, flags); - pci_write_reg(CONFIG_CMD(bus, devfn, where), SH4_PCIPAR); - data = pci_read_reg(SH4_PCIPDR); - spin_unlock_irqrestore(&sh4_pci_lock, flags); - - switch (size) { - case 1: - shift = (where & 3) << 3; - data &= ~(0xff << shift); - data |= ((val & 0xff) << shift); - break; - case 2: - shift = (where & 2) << 3; - data &= ~(0xffff << shift); - data |= ((val & 0xffff) << shift); - break; - case 4: - data = val; - break; - default: - return PCIBIOS_FUNC_NOT_SUPPORTED; - } - - pci_write_reg(data, SH4_PCIPDR); - - return PCIBIOS_SUCCESSFUL; -} - -struct pci_ops sh4_pci_ops = { - .read = sh4_pci_read, - .write = sh4_pci_write, -}; - -/* - * Not really related to pci_ops, but it's common and not worth shoving - * somewhere else for now.. - */ -static unsigned int pci_probe = PCI_PROBE_CONF1; - -int __init sh4_pci_check_direct(void) -{ - /* - * Check if configuration works. - */ - if (pci_probe & PCI_PROBE_CONF1) { - unsigned int tmp = pci_read_reg(SH4_PCIPAR); - - pci_write_reg(P1SEG, SH4_PCIPAR); - - if (pci_read_reg(SH4_PCIPAR) == P1SEG) { - pci_write_reg(tmp, SH4_PCIPAR); - printk(KERN_INFO "PCI: Using configuration type 1\n"); - request_region(PCI_REG(SH4_PCIPAR), 8, "PCI conf1"); - - return 0; - } - - pci_write_reg(tmp, SH4_PCIPAR); - } - - pr_debug("PCI: pci_check_direct failed\n"); - return -EINVAL; -} - -/* Handle generic fixups */ -static void __init pci_fixup_ide_bases(struct pci_dev *d) -{ - int i; - - /* - * PCI IDE controllers use non-standard I/O port decoding, respect it. - */ - if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) - return; - pr_debug("PCI: IDE base address fixup for %s\n", pci_name(d)); - for(i = 0; i < 4; i++) { - struct resource *r = &d->resource[i]; - - if ((r->start & ~0x80) == 0x374) { - r->start |= 2; - r->end = r->start; - } - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); - -char * __init pcibios_setup(char *str) -{ - if (!strcmp(str, "off")) { - pci_probe = 0; - return NULL; - } - - return str; -} diff --git a/trunk/arch/sh/drivers/pci/ops-snapgear.c b/trunk/arch/sh/drivers/pci/ops-snapgear.c index 53dd893d4e54..3cbd14dd28fe 100644 --- a/trunk/arch/sh/drivers/pci/ops-snapgear.c +++ b/trunk/arch/sh/drivers/pci/ops-snapgear.c @@ -2,7 +2,7 @@ * arch/sh/drivers/pci/ops-snapgear.c * * Author: David McCullough - * + * * Ported to new API by Paul Mundt * * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. @@ -12,11 +12,15 @@ * * PCI initialization for the SnapGear boards */ + #include #include #include +#include #include -#include "pci-sh4.h" + +#include +#include "pci-sh7751.h" #define SNAPGEAR_PCI_IO 0x4000 #define SNAPGEAR_PCI_MEM 0xfd000000 @@ -39,12 +43,14 @@ static struct resource sh7751_mem_resource = { .flags = IORESOURCE_MEM, }; +extern struct pci_ops sh7751_pci_ops; + struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, { 0, } }; -static struct sh4_pci_address_map sh7751_pci_map = { +static struct sh7751_pci_address_map sh7751_pci_map = { .window0 = { .base = SH7751_CS2_BASE_ADDR, .size = SNAPGEAR_LSR0_SIZE, @@ -55,11 +61,11 @@ static struct sh4_pci_address_map sh7751_pci_map = { .size = SNAPGEAR_LSR1_SIZE, }, - .flags = SH4_PCIC_NO_RESET, + .flags = SH7751_PCIC_NO_RESET, }; /* - * Initialize the SnapGear PCI interface + * Initialize the SnapGear PCI interface * Setup hardware to be Central Funtion * Copy the BSR regs to the PCI interface * Setup PCI windows into local RAM @@ -69,7 +75,7 @@ int __init pcibios_init_platform(void) return sh7751_pcic_init(&sh7751_pci_map); } -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(u8 slot, u8 pin) { int irq = -1; @@ -92,3 +98,4 @@ void __init pcibios_fixup(void) { /* Nothing to fixup .. */ } + diff --git a/trunk/arch/sh/drivers/pci/ops-titan.c b/trunk/arch/sh/drivers/pci/ops-titan.c deleted file mode 100644 index c6097bcd97fd..000000000000 --- a/trunk/arch/sh/drivers/pci/ops-titan.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * arch/sh/drivers/pci/ops-titan.c - * - * Ported to new API by Paul Mundt - * - * Modified from ops-snapgear.c written by David McCullough - * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - * PCI initialization for the Titan boards - */ - -#include -#include -#include -#include -#include -#include -#include -#include "pci-sh4.h" - -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) -{ - int irq = -1; - - switch (slot) { - case 0: irq = TITAN_IRQ_WAN; break; /* eth0 (WAN) */ - case 1: irq = TITAN_IRQ_LAN; break; /* eth1 (LAN) */ - case 2: irq = TITAN_IRQ_MPCIA; break; /* mPCI A */ - case 3: irq = TITAN_IRQ_MPCIB; break; /* mPCI B */ - case 4: irq = TITAN_IRQ_USB; break; /* USB */ - default: - printk(KERN_INFO "PCI: Bad IRQ mapping " - "request for slot %d\n", slot); - return -1; - } - - printk("PCI: Mapping TITAN IRQ for slot %d, pin %c to irq %d\n", - slot, pin - 1 + 'A', irq); - - return irq; -} - -static struct resource sh7751_io_resource = { - .name = "SH7751_IO", - .start = SH7751_PCI_IO_BASE, - .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, - .flags = IORESOURCE_IO -}; - -static struct resource sh7751_mem_resource = { - .name = "SH7751_mem", - .start = SH7751_PCI_MEMORY_BASE, - .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, - .flags = IORESOURCE_MEM -}; - -struct pci_channel board_pci_channels[] = { - { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, - { NULL, NULL, NULL, 0, 0 }, -}; -EXPORT_SYMBOL(board_pci_channels); - -static struct sh4_pci_address_map sh7751_pci_map = { - .window0 = { - .base = SH7751_CS2_BASE_ADDR, - .size = SH7751_MEM_REGION_SIZE*2, /* cs2 and cs3 */ - }, - - .window1 = { - .base = SH7751_CS2_BASE_ADDR, - .size = SH7751_MEM_REGION_SIZE*2, - }, - - .flags = SH4_PCIC_NO_RESET, -}; - -int __init pcibios_init_platform(void) -{ - return sh7751_pcic_init(&sh7751_pci_map); -} diff --git a/trunk/arch/sh/drivers/pci/pci-auto.c b/trunk/arch/sh/drivers/pci/pci-auto.c index ecf16344f94a..4cef4d1d8c84 100644 --- a/trunk/arch/sh/drivers/pci/pci-auto.c +++ b/trunk/arch/sh/drivers/pci/pci-auto.c @@ -45,11 +45,11 @@ #include #include -#define DEBUG -#ifdef DEBUG +#undef DEBUG +#ifdef DEBUG #define DBG(x...) printk(x) #else -#define DBG(x...) +#define DBG(x...) #endif /* @@ -102,7 +102,7 @@ static u32 pciauto_upper_iospc; static u32 pciauto_lower_memspc; static u32 pciauto_upper_memspc; -static void __init +static void __init pciauto_setup_bars(struct pci_channel *hose, int top_bus, int current_bus, @@ -116,6 +116,7 @@ pciauto_setup_bars(struct pci_channel *hose, int found_mem64 = 0; for (bar = PCI_BASE_ADDRESS_0; bar <= bar_limit; bar+=4) { +#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D) u32 bar_addr; /* Read the old BAR value */ @@ -124,6 +125,7 @@ pciauto_setup_bars(struct pci_channel *hose, pci_devfn, bar, &bar_addr); +#endif /* Tickle the BAR and get the response */ early_write_config_dword(hose, top_bus, @@ -138,7 +140,8 @@ pciauto_setup_bars(struct pci_channel *hose, bar, &bar_response); - /* +#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D) + /* * Write the old BAR value back out, only update the BAR * if we implicitly want resources to be updated, which * is done by the generic code further down. -- PFM. @@ -148,6 +151,7 @@ pciauto_setup_bars(struct pci_channel *hose, pci_devfn, bar, bar_addr); +#endif /* If BAR is not implemented go to the next BAR */ if (!bar_response) @@ -173,7 +177,7 @@ pciauto_setup_bars(struct pci_channel *hose, PCI_BASE_ADDRESS_MEM_TYPE_64) found_mem64 = 1; - addr_mask = PCI_BASE_ADDRESS_MEM_MASK; + addr_mask = PCI_BASE_ADDRESS_MEM_MASK; upper_limit = &pciauto_upper_memspc; lower_limit = &pciauto_lower_memspc; DBG(" Mem"); @@ -189,22 +193,22 @@ pciauto_setup_bars(struct pci_channel *hose, if ((bar_value + bar_size) > *upper_limit) { if (bar_response & PCI_BASE_ADDRESS_SPACE) { if (io_resource_inuse->child) { - io_resource_inuse = + io_resource_inuse = io_resource_inuse->child; - pciauto_lower_iospc = + pciauto_lower_iospc = io_resource_inuse->start; - pciauto_upper_iospc = + pciauto_upper_iospc = io_resource_inuse->end + 1; goto retry; } } else { if (mem_resource_inuse->child) { - mem_resource_inuse = + mem_resource_inuse = mem_resource_inuse->child; - pciauto_lower_memspc = + pciauto_lower_memspc = mem_resource_inuse->start; - pciauto_upper_memspc = + pciauto_upper_memspc = mem_resource_inuse->end + 1; goto retry; } @@ -226,7 +230,7 @@ pciauto_setup_bars(struct pci_channel *hose, * If we are a 64-bit decoder then increment to the * upper 32 bits of the bar and force it to locate * in the lower 4GB of memory. - */ + */ if (found_mem64) { bar += 4; early_write_config_dword(hose, top_bus, @@ -358,6 +362,7 @@ pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose, { u32 temp; +#if !defined(CONFIG_SH_HS7751RVOIP) && !defined(CONFIG_SH_RTS7751R2D) /* * [jsun] we always bump up baselines a little, so that if there * nothing behind P2P bridge, we don't wind up overlapping IO/MEM @@ -365,6 +370,7 @@ pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose, */ pciauto_lower_memspc += 1; pciauto_lower_iospc += 1; +#endif /* * Configure subordinate bus number. The PCI subsystem @@ -390,6 +396,11 @@ pciauto_postscan_setup_cardbus_bridge(struct pci_channel *hose, * configured by this routine to happily live behind a * P2P bridge in a system. */ +#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D) + pciauto_lower_memspc += 0x00400000; + pciauto_lower_iospc += 0x00004000; +#endif + /* Align memory and I/O to 4KB and 4 byte boundaries. */ pciauto_lower_memspc = (pciauto_lower_memspc + (0x1000 - 1)) & ~(0x1000 - 1); @@ -422,12 +433,12 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus) int devfn_stop = 0xff; sub_bus = current_bus; - + if (hose->first_devfn) devfn_start = hose->first_devfn; if (hose->last_devfn) devfn_stop = hose->last_devfn; - + for (pci_devfn=devfn_start; pci_devfn> 16) == PCI_CLASS_BRIDGE_PCI) { DBG(" Bridge: primary=%.2x, secondary=%.2x\n", current_bus, sub_bus + 1); +#if defined(CONFIG_SH_HS7751RVOIP) || defined(CONFIG_SH_RTS7751R2D) + pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_1); +#endif pciauto_prescan_setup_bridge(hose, top_bus, current_bus, pci_devfn, sub_bus); DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", @@ -476,10 +490,10 @@ pciauto_bus_scan(struct pci_channel *hose, int top_bus, int current_bus) DBG("PCI Autoconfig: Found CardBus bridge, device %d function %d\n", PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn)); /* Place CardBus Socket/ExCA registers */ pciauto_setup_bars(hose, top_bus, current_bus, pci_devfn, PCI_BASE_ADDRESS_0); - + pciauto_prescan_setup_cardbus_bridge(hose, top_bus, current_bus, pci_devfn, sub_bus); - + DBG("Scanning sub bus %.2x, I/O 0x%.8x, Mem 0x%.8x\n", sub_bus + 1, pciauto_lower_iospc, pciauto_lower_memspc); diff --git a/trunk/arch/sh/drivers/pci/pci-sh4.h b/trunk/arch/sh/drivers/pci/pci-sh4.h deleted file mode 100644 index 5a61d6041f2c..000000000000 --- a/trunk/arch/sh/drivers/pci/pci-sh4.h +++ /dev/null @@ -1,180 +0,0 @@ -#ifndef __PCI_SH4_H -#define __PCI_SH4_H - -#ifdef CONFIG_CPU_SUBTYPE_SH7780 -#include "pci-sh7780.h" -#else -#include "pci-sh7751.h" -#endif - -#include - -/* startup values */ -#define PCI_PROBE_BIOS 1 -#define PCI_PROBE_CONF1 2 -#define PCI_PROBE_CONF2 4 -#define PCI_NO_SORT 0x100 -#define PCI_BIOS_SORT 0x200 -#define PCI_NO_CHECKS 0x400 -#define PCI_ASSIGN_ROMS 0x1000 -#define PCI_BIOS_IRQ_SCAN 0x2000 - -#define SH4_PCICR 0x100 /* PCI Control Register */ - #define SH4_PCICR_PREFIX 0xA5000000 /* CR prefix for write */ - #define SH4_PCICR_FTO 0x00000400 /* TRDY/IRDY Enable */ - #define SH4_PCICR_TRSB 0x00000200 /* Target Read Single */ - #define SH4_PCICR_BSWP 0x00000100 /* Target Byte Swap */ - #define SH4_PCICR_PLUP 0x00000080 /* Enable PCI Pullup */ - #define SH4_PCICR_ARBM 0x00000040 /* PCI Arbitration Mode */ - #define SH4_PCICR_MD 0x00000030 /* MD9 and MD10 status */ - #define SH4_PCICR_SERR 0x00000008 /* SERR output assert */ - #define SH4_PCICR_INTA 0x00000004 /* INTA output assert */ - #define SH4_PCICR_PRST 0x00000002 /* PCI Reset Assert */ - #define SH4_PCICR_CFIN 0x00000001 /* Central Fun. Init Done */ -#define SH4_PCILSR0 0x104 /* PCI Local Space Register0 */ -#define SH4_PCILSR1 0x108 /* PCI Local Space Register1 */ -#define SH4_PCILAR0 0x10C /* PCI Local Addr Register1 */ -#define SH4_PCILAR1 0x110 /* PCI Local Addr Register1 */ -#define SH4_PCIINT 0x114 /* PCI Interrupt Register */ - #define SH4_PCIINT_MLCK 0x00008000 /* Master Lock Error */ - #define SH4_PCIINT_TABT 0x00004000 /* Target Abort Error */ - #define SH4_PCIINT_TRET 0x00000200 /* Target Retry Error */ - #define SH4_PCIINT_MFDE 0x00000100 /* Master Func. Disable Error */ - #define SH4_PCIINT_PRTY 0x00000080 /* Address Parity Error */ - #define SH4_PCIINT_SERR 0x00000040 /* SERR Detection Error */ - #define SH4_PCIINT_TWDP 0x00000020 /* Tgt. Write Parity Error */ - #define SH4_PCIINT_TRDP 0x00000010 /* Tgt. Read Parity Err Det. */ - #define SH4_PCIINT_MTABT 0x00000008 /* Master-Tgt. Abort Error */ - #define SH4_PCIINT_MMABT 0x00000004 /* Master-Master Abort Error */ - #define SH4_PCIINT_MWPD 0x00000002 /* Master Write PERR Detect */ - #define SH4_PCIINT_MRPD 0x00000001 /* Master Read PERR Detect */ -#define SH4_PCIINTM 0x118 /* PCI Interrupt Mask */ -#define SH4_PCIALR 0x11C /* Error Address Register */ -#define SH4_PCICLR 0x120 /* Error Command/Data */ - #define SH4_PCICLR_MPIO 0x80000000 - #define SH4_PCICLR_MDMA0 0x40000000 /* DMA0 Transfer Error */ - #define SH4_PCICLR_MDMA1 0x20000000 /* DMA1 Transfer Error */ - #define SH4_PCICLR_MDMA2 0x10000000 /* DMA2 Transfer Error */ - #define SH4_PCICLR_MDMA3 0x08000000 /* DMA3 Transfer Error */ - #define SH4_PCICLR_TGT 0x04000000 /* Target Transfer Error */ - #define SH4_PCICLR_CMDL 0x0000000F /* PCI Command at Error */ -#define SH4_PCIAINT 0x130 /* Arbiter Interrupt Register */ - #define SH4_PCIAINT_MBKN 0x00002000 /* Master Broken Interrupt */ - #define SH4_PCIAINT_TBTO 0x00001000 /* Target Bus Time Out */ - #define SH4_PCIAINT_MBTO 0x00001000 /* Master Bus Time Out */ - #define SH4_PCIAINT_TABT 0x00000008 /* Target Abort */ - #define SH4_PCIAINT_MABT 0x00000004 /* Master Abort */ - #define SH4_PCIAINT_RDPE 0x00000002 /* Read Data Parity Error */ - #define SH4_PCIAINT_WDPE 0x00000001 /* Write Data Parity Error */ -#define SH4_PCIAINTM 0x134 /* Arbiter Int. Mask Register */ -#define SH4_PCIBMLR 0x138 /* Error Bus Master Register */ - #define SH4_PCIBMLR_REQ4 0x00000010 /* REQ4 bus master at error */ - #define SH4_PCIBMLR_REQ3 0x00000008 /* REQ3 bus master at error */ - #define SH4_PCIBMLR_REQ2 0x00000004 /* REQ2 bus master at error */ - #define SH4_PCIBMLR_REQ1 0x00000002 /* REQ1 bus master at error */ - #define SH4_PCIBMLR_REQ0 0x00000001 /* REQ0 bus master at error */ -#define SH4_PCIDMABT 0x140 /* DMA Transfer Arb. Register */ - #define SH4_PCIDMABT_RRBN 0x00000001 /* DMA Arbitor Round-Robin */ -#define SH4_PCIDPA0 0x180 /* DMA0 Transfer Addr. */ -#define SH4_PCIDLA0 0x184 /* DMA0 Local Addr. */ -#define SH4_PCIDTC0 0x188 /* DMA0 Transfer Cnt. */ -#define SH4_PCIDCR0 0x18C /* DMA0 Control Register */ - #define SH4_PCIDCR_ALGN 0x00000600 /* DMA Alignment Mode */ - #define SH4_PCIDCR_MAST 0x00000100 /* DMA Termination Type */ - #define SH4_PCIDCR_INTM 0x00000080 /* DMA Interrupt Done Mask*/ - #define SH4_PCIDCR_INTS 0x00000040 /* DMA Interrupt Done Status */ - #define SH4_PCIDCR_LHLD 0x00000020 /* Local Address Control */ - #define SH4_PCIDCR_PHLD 0x00000010 /* PCI Address Control*/ - #define SH4_PCIDCR_IOSEL 0x00000008 /* PCI Address Space Type */ - #define SH4_PCIDCR_DIR 0x00000004 /* DMA Transfer Direction */ - #define SH4_PCIDCR_STOP 0x00000002 /* Force DMA Stop */ - #define SH4_PCIDCR_STRT 0x00000001 /* DMA Start */ -#define SH4_PCIDPA1 0x190 /* DMA1 Transfer Addr. */ -#define SH4_PCIDLA1 0x194 /* DMA1 Local Addr. */ -#define SH4_PCIDTC1 0x198 /* DMA1 Transfer Cnt. */ -#define SH4_PCIDCR1 0x19C /* DMA1 Control Register */ -#define SH4_PCIDPA2 0x1A0 /* DMA2 Transfer Addr. */ -#define SH4_PCIDLA2 0x1A4 /* DMA2 Local Addr. */ -#define SH4_PCIDTC2 0x1A8 /* DMA2 Transfer Cnt. */ -#define SH4_PCIDCR2 0x1AC /* DMA2 Control Register */ -#define SH4_PCIDPA3 0x1B0 /* DMA3 Transfer Addr. */ -#define SH4_PCIDLA3 0x1B4 /* DMA3 Local Addr. */ -#define SH4_PCIDTC3 0x1B8 /* DMA3 Transfer Cnt. */ -#define SH4_PCIDCR3 0x1BC /* DMA3 Control Register */ -#define SH4_PCIPAR 0x1C0 /* PIO Address Register */ - #define SH4_PCIPAR_CFGEN 0x80000000 /* Configuration Enable */ - #define SH4_PCIPAR_BUSNO 0x00FF0000 /* Config. Bus Number */ - #define SH4_PCIPAR_DEVNO 0x0000FF00 /* Config. Device Number */ - #define SH4_PCIPAR_REGAD 0x000000FC /* Register Address Number */ -#define SH4_PCIMBR 0x1C4 /* Memory Base Address */ - #define SH4_PCIMBR_MASK 0xFF000000 /* Memory Space Mask */ - #define SH4_PCIMBR_LOCK 0x00000001 /* Lock Memory Space */ -#define SH4_PCIIOBR 0x1C8 /* I/O Base Address Register */ - #define SH4_PCIIOBR_MASK 0xFFFC0000 /* IO Space Mask */ - #define SH4_PCIIOBR_LOCK 0x00000001 /* Lock IO Space */ -#define SH4_PCIPINT 0x1CC /* Power Mgmnt Int. Register */ - #define SH4_PCIPINT_D3 0x00000002 /* D3 Pwr Mgmt. Interrupt */ - #define SH4_PCIPINT_D0 0x00000001 /* D0 Pwr Mgmt. Interrupt */ -#define SH4_PCIPINTM 0x1D0 /* Power Mgmnt Mask Register */ -#define SH4_PCICLKR 0x1D4 /* Clock Ctrl. Register */ - #define SH4_PCICLKR_PCSTP 0x00000002 /* PCI Clock Stop */ - #define SH4_PCICLKR_BCSTP 0x00000001 /* BCLK Clock Stop */ -/* For definitions of BCR, MCR see ... */ -#define SH4_PCIBCR1 0x1E0 /* Memory BCR1 Register */ - #define SH4_PCIMBR0 SH4_PCIBCR1 -#define SH4_PCIBCR2 0x1E4 /* Memory BCR2 Register */ - #define SH4_PCIMBMR0 SH4_PCIBCR2 -#define SH4_PCIWCR1 0x1E8 /* Wait Control 1 Register */ -#define SH4_PCIWCR2 0x1EC /* Wait Control 2 Register */ -#define SH4_PCIWCR3 0x1F0 /* Wait Control 3 Register */ - #define SH4_PCIMBR2 SH4_PCIWCR3 -#define SH4_PCIMCR 0x1F4 /* Memory Control Register */ -#define SH4_PCIBCR3 0x1f8 /* Memory BCR3 Register */ -#define SH4_PCIPCTR 0x200 /* Port Control Register */ - #define SH4_PCIPCTR_P2EN 0x000400000 /* Port 2 Enable */ - #define SH4_PCIPCTR_P1EN 0x000200000 /* Port 1 Enable */ - #define SH4_PCIPCTR_P0EN 0x000100000 /* Port 0 Enable */ - #define SH4_PCIPCTR_P2UP 0x000000020 /* Port2 Pull Up Enable */ - #define SH4_PCIPCTR_P2IO 0x000000010 /* Port2 Output Enable */ - #define SH4_PCIPCTR_P1UP 0x000000008 /* Port1 Pull Up Enable */ - #define SH4_PCIPCTR_P1IO 0x000000004 /* Port1 Output Enable */ - #define SH4_PCIPCTR_P0UP 0x000000002 /* Port0 Pull Up Enable */ - #define SH4_PCIPCTR_P0IO 0x000000001 /* Port0 Output Enable */ -#define SH4_PCIPDTR 0x204 /* Port Data Register */ - #define SH4_PCIPDTR_PB5 0x000000020 /* Port 5 Enable */ - #define SH4_PCIPDTR_PB4 0x000000010 /* Port 4 Enable */ - #define SH4_PCIPDTR_PB3 0x000000008 /* Port 3 Enable */ - #define SH4_PCIPDTR_PB2 0x000000004 /* Port 2 Enable */ - #define SH4_PCIPDTR_PB1 0x000000002 /* Port 1 Enable */ - #define SH4_PCIPDTR_PB0 0x000000001 /* Port 0 Enable */ -#define SH4_PCIPDR 0x220 /* Port IO Data Register */ - -/* Flags */ -#define SH4_PCIC_NO_RESET 0x0001 - -/* arch/sh/kernel/drivers/pci/ops-sh4.c */ -extern struct pci_ops sh4_pci_ops; -int sh4_pci_check_direct(void); -int pci_fixup_pcic(void); - -struct sh4_pci_address_space { - unsigned long base; - unsigned long size; -}; - -struct sh4_pci_address_map { - struct sh4_pci_address_space window0; - struct sh4_pci_address_space window1; - unsigned long flags; -}; - -static inline void pci_write_reg(unsigned long val, unsigned long reg) -{ - outl(val, PCI_REG(reg)); -} - -static inline unsigned long pci_read_reg(unsigned long reg) -{ - return inl(PCI_REG(reg)); -} -#endif /* __PCI_SH4_H */ diff --git a/trunk/arch/sh/drivers/pci/pci-sh7751.c b/trunk/arch/sh/drivers/pci/pci-sh7751.c index dbe837884983..682f3dae305d 100644 --- a/trunk/arch/sh/drivers/pci/pci-sh7751.c +++ b/trunk/arch/sh/drivers/pci/pci-sh7751.c @@ -15,44 +15,206 @@ #undef DEBUG +#include +#include #include #include -#include +#include +#include #include +#include #include -#include "pci-sh4.h" -#include + +#include #include +#include "pci-sh7751.h" + +static unsigned int pci_probe = PCI_PROBE_CONF1; +extern int pci_fixup_pcic(void); + +void pcibios_fixup_irqs(void) __attribute__ ((weak)); /* - * Initialization. Try all known PCI access methods. Note that we support - * using both PCI BIOS and direct access: in such cases, we use I/O ports - * to access config space. - * - * Note that the platform specific initialization (BSC registers, and memory - * space mapping) will be called via the platform defined function - * pcibios_init_platform(). + * Direct access to PCI hardware... */ -static int __init sh7751_pci_init(void) + +#define CONFIG_CMD(bus, devfn, where) (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) + +/* + * Functions for accessing PCI configuration space with type 1 accesses + */ +static int sh7751_pci_read(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *val) { - unsigned int id; - int ret; + unsigned long flags; + u32 data; - pr_debug("PCI: Starting intialization.\n"); + /* + * PCIPDR may only be accessed as 32 bit words, + * so we must do byte alignment by hand + */ + local_irq_save(flags); + outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR)); + data = inl(PCI_REG(SH7751_PCIPDR)); + local_irq_restore(flags); + + switch (size) { + case 1: + *val = (data >> ((where & 3) << 3)) & 0xff; + break; + case 2: + *val = (data >> ((where & 2) << 3)) & 0xffff; + break; + case 4: + *val = data; + break; + default: + return PCIBIOS_FUNC_NOT_SUPPORTED; + } + + return PCIBIOS_SUCCESSFUL; +} + +/* + * Since SH7751 only does 32bit access we'll have to do a read, + * mask,write operation. + * We'll allow an odd byte offset, though it should be illegal. + */ +static int sh7751_pci_write(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 val) +{ + unsigned long flags; + int shift; + u32 data; + + local_irq_save(flags); + outl(CONFIG_CMD(bus,devfn,where), PCI_REG(SH7751_PCIPAR)); + data = inl(PCI_REG(SH7751_PCIPDR)); + local_irq_restore(flags); + + switch (size) { + case 1: + shift = (where & 3) << 3; + data &= ~(0xff << shift); + data |= ((val & 0xff) << shift); + break; + case 2: + shift = (where & 2) << 3; + data &= ~(0xffff << shift); + data |= ((val & 0xffff) << shift); + break; + case 4: + data = val; + break; + default: + return PCIBIOS_FUNC_NOT_SUPPORTED; + } + + outl(data, PCI_REG(SH7751_PCIPDR)); + + return PCIBIOS_SUCCESSFUL; +} + +#undef CONFIG_CMD + +struct pci_ops sh7751_pci_ops = { + .read = sh7751_pci_read, + .write = sh7751_pci_write, +}; + +static int __init pci_check_direct(void) +{ + unsigned int tmp, id; /* check for SH7751/SH7751R hardware */ - id = pci_read_reg(SH7751_PCICONF0); + id = inl(SH7751_PCIREG_BASE+SH7751_PCICONF0); if (id != ((SH7751_DEVICE_ID << 16) | SH7751_VENDOR_ID) && id != ((SH7751R_DEVICE_ID << 16) | SH7751_VENDOR_ID)) { pr_debug("PCI: This is not an SH7751(R) (%x)\n", id); return -ENODEV; } - if ((ret = sh4_pci_check_direct()) != 0) + /* + * Check if configuration works. + */ + if (pci_probe & PCI_PROBE_CONF1) { + tmp = inl (PCI_REG(SH7751_PCIPAR)); + outl (0x80000000, PCI_REG(SH7751_PCIPAR)); + if (inl (PCI_REG(SH7751_PCIPAR)) == 0x80000000) { + outl (tmp, PCI_REG(SH7751_PCIPAR)); + printk(KERN_INFO "PCI: Using configuration type 1\n"); + request_region(PCI_REG(SH7751_PCIPAR), 8, "PCI conf1"); + return 0; + } + outl (tmp, PCI_REG(SH7751_PCIPAR)); + } + + pr_debug("PCI: pci_check_direct failed\n"); + return -EINVAL; +} + +/***************************************************************************************/ + +/* + * Handle bus scanning and fixups .... + */ + +static void __init pci_fixup_ide_bases(struct pci_dev *d) +{ + int i; + + /* + * PCI IDE controllers use non-standard I/O port decoding, respect it. + */ + if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE) + return; + pr_debug("PCI: IDE base address fixup for %s\n", pci_name(d)); + for(i=0; i<4; i++) { + struct resource *r = &d->resource[i]; + if ((r->start & ~0x80) == 0x374) { + r->start |= 2; + r->end = r->start; + } + } +} + +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); + +/* + * Called after each bus is probed, but before its children + * are examined. + */ + +void __init pcibios_fixup_bus(struct pci_bus *b) +{ + pci_read_bridge_bases(b); +} + +/* + * Initialization. Try all known PCI access methods. Note that we support + * using both PCI BIOS and direct access: in such cases, we use I/O ports + * to access config space. + * + * Note that the platform specific initialization (BSC registers, and memory + * space mapping) will be called via the machine vectors (sh_mv.mv_pci_init()) if it + * exitst and via the platform defined function pcibios_init_platform(). + * See pci_bigsur.c for implementation; + * + * The BIOS version of the pci functions is not yet implemented but it is left + * in for completeness. Currently an error will be genereated at compile time. + */ + +static int __init sh7751_pci_init(void) +{ + int ret; + + pr_debug("PCI: Starting intialization.\n"); + if ((ret = pci_check_direct()) != 0) return ret; return pcibios_init_platform(); } + subsys_initcall(sh7751_pci_init); static int __init __area_sdram_check(unsigned int area) @@ -61,26 +223,26 @@ static int __init __area_sdram_check(unsigned int area) word = inl(SH7751_BCR1); /* check BCR for SDRAM in area */ - if (((word >> area) & 1) == 0) { + if(((word >> area) & 1) == 0) { printk("PCI: Area %d is not configured for SDRAM. BCR1=0x%x\n", area, word); return 0; } - pci_write_reg(word, SH4_PCIBCR1); + outl(word, PCI_REG(SH7751_PCIBCR1)); word = (u16)inw(SH7751_BCR2); /* check BCR2 for 32bit SDRAM interface*/ - if (((word >> (area << 1)) & 0x3) != 0x3) { + if(((word >> (area << 1)) & 0x3) != 0x3) { printk("PCI: Area %d is not 32 bit SDRAM. BCR2=0x%x\n", area, word); return 0; } - pci_write_reg(word, SH4_PCIBCR2); + outl(word, PCI_REG(SH7751_PCIBCR2)); return 1; } -int __init sh7751_pcic_init(struct sh4_pci_address_map *map) +int __init sh7751_pcic_init(struct sh7751_pci_address_map *map) { u32 reg; u32 word; @@ -89,39 +251,39 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) reg = inl(SH7751_BCR1); reg |= 0x80000; outl(reg, SH7751_BCR1); - + /* Turn the clocks back on (not done in reset)*/ - pci_write_reg(0, SH4_PCICLKR); + outl(0, PCI_REG(SH7751_PCICLKR)); /* Clear Powerdown IRQ's (not done in reset) */ - word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0; - pci_write_reg(word, SH4_PCIPINT); + word = SH7751_PCIPINT_D3 | SH7751_PCIPINT_D0; + outl(word, PCI_REG(SH7751_PCIPINT)); /* * This code is unused for some boards as it is done in the * bootloader and doing it here means the MAC addresses loaded * by the bootloader get lost. */ - if (!(map->flags & SH4_PCIC_NO_RESET)) { + if (!(map->flags & SH7751_PCIC_NO_RESET)) { /* toggle PCI reset pin */ - word = SH4_PCICR_PREFIX | SH4_PCICR_PRST; - pci_write_reg(word, SH4_PCICR); + word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST; + outl(word,PCI_REG(SH7751_PCICR)); /* Wait for a long time... not 1 sec. but long enough */ mdelay(100); - word = SH4_PCICR_PREFIX; - pci_write_reg(word, SH4_PCICR); + word = SH7751_PCICR_PREFIX; + outl(word,PCI_REG(SH7751_PCICR)); } - + /* set the command/status bits to: * Wait Cycle Control + Parity Enable + Bus Master + * Mem space enable */ word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES; - pci_write_reg(word, SH7751_PCICONF1); + outl(word, PCI_REG(SH7751_PCICONF1)); /* define this host as the host bridge */ - word = PCI_BASE_CLASS_BRIDGE << 24; - pci_write_reg(word, SH7751_PCICONF2); + word = SH7751_PCI_HOST_BRIDGE << 24; + outl(word, PCI_REG(SH7751_PCICONF2)); /* Set IO and Mem windows to local address * Make PCI and local address the same for easy 1 to 1 mapping @@ -129,49 +291,46 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) * Window1 = map->window1.size @ cached area base = SDRAM */ word = map->window0.size - 1; - pci_write_reg(word, SH4_PCILSR0); + outl(word, PCI_REG(SH7751_PCILSR0)); word = map->window1.size - 1; - pci_write_reg(word, SH4_PCILSR1); + outl(word, PCI_REG(SH7751_PCILSR1)); /* Set the values on window 0 PCI config registers */ word = P2SEGADDR(map->window0.base); - pci_write_reg(word, SH4_PCILAR0); - pci_write_reg(word, SH7751_PCICONF5); + outl(word, PCI_REG(SH7751_PCILAR0)); + outl(word, PCI_REG(SH7751_PCICONF5)); /* Set the values on window 1 PCI config registers */ word = PHYSADDR(map->window1.base); - pci_write_reg(word, SH4_PCILAR1); - pci_write_reg(word, SH7751_PCICONF6); + outl(word, PCI_REG(SH7751_PCILAR1)); + outl(word, PCI_REG(SH7751_PCICONF6)); - /* Set the local 16MB PCI memory space window to + /* Set the local 16MB PCI memory space window to * the lowest PCI mapped address */ - word = PCIBIOS_MIN_MEM & SH4_PCIMBR_MASK; - pr_debug("PCI: Setting upper bits of Memory window to 0x%x\n", word); - pci_write_reg(word , SH4_PCIMBR); + word = PCIBIOS_MIN_MEM & SH7751_PCIMBR_MASK; + PCIDBG(2,"PCI: Setting upper bits of Memory window to 0x%x\n", word); + outl(word , PCI_REG(SH7751_PCIMBR)); /* Map IO space into PCI IO window * The IO window is 64K-PCIBIOS_MIN_IO in size - * IO addresses will be translated to the + * IO addresses will be translated to the * PCI IO window base address */ - pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", - PCIBIOS_MIN_IO, (64 << 10), - SH4_PCI_IO_BASE + PCIBIOS_MIN_IO); + PCIDBG(3,"PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", PCIBIOS_MIN_IO, + (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO); - /* + /* * XXX: For now, leave this board-specific. In the event we have other * boards that need to do similar work, this can be wrapped. */ #ifdef CONFIG_SH_BIGSUR - bigsur_port_map(PCIBIOS_MIN_IO, (64 << 10), - SH4_PCI_IO_BASE + PCIBIOS_MIN_IO, 0); + bigsur_port_map(PCIBIOS_MIN_IO, (64*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO,0); #endif - /* Make sure the MSB's of IO window are set to access PCI space - * correctly */ - word = PCIBIOS_MIN_IO & SH4_PCIIOBR_MASK; - pr_debug("PCI: Setting upper bits of IO window to 0x%x\n", word); - pci_write_reg(word, SH4_PCIIOBR); - + /* Make sure the MSB's of IO window are set to access PCI space correctly */ + word = PCIBIOS_MIN_IO & SH7751_PCIIOBR_MASK; + PCIDBG(2,"PCI: Setting upper bits of IO window to 0x%x\n", word); + outl(word, PCI_REG(SH7751_PCIIOBR)); + /* Set PCI WCRx, BCRx's, copy from BSC locations */ /* check BCR for SDRAM in specified area */ @@ -190,13 +349,13 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) /* configure the wait control registers */ word = inl(SH7751_WCR1); - pci_write_reg(word, SH4_PCIWCR1); + outl(word, PCI_REG(SH7751_PCIWCR1)); word = inl(SH7751_WCR2); - pci_write_reg(word, SH4_PCIWCR2); + outl(word, PCI_REG(SH7751_PCIWCR2)); word = inl(SH7751_WCR3); - pci_write_reg(word, SH4_PCIWCR3); + outl(word, PCI_REG(SH7751_PCIWCR3)); word = inl(SH7751_MCR); - pci_write_reg(word, SH4_PCIMCR); + outl(word, PCI_REG(SH7751_PCIMCR)); /* NOTE: I'm ignoring the PCI error IRQs for now.. * TODO: add support for the internal error interrupts and @@ -209,8 +368,49 @@ int __init sh7751_pcic_init(struct sh4_pci_address_map *map) /* SH7751 init done, set central function init complete */ /* use round robin mode to stop a device starving/overruning */ - word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; - pci_write_reg(word, SH4_PCICR); + word = SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN | SH7751_PCICR_ARBM; + outl(word,PCI_REG(SH7751_PCICR)); return 1; } + +char * __init pcibios_setup(char *str) +{ + if (!strcmp(str, "off")) { + pci_probe = 0; + return NULL; + } + + return str; +} + +/* + * IRQ functions + */ +static u8 __init sh7751_no_swizzle(struct pci_dev *dev, u8 *pin) +{ + /* no swizzling */ + return PCI_SLOT(dev->devfn); +} + +static int sh7751_pci_lookup_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq = -1; + + /* now lookup the actual IRQ on a platform specific basis (pci-'platform'.c) */ + irq = pcibios_map_platform_irq(slot,pin); + if( irq < 0 ) { + pr_debug("PCI: Error mapping IRQ on device %s\n", pci_name(dev)); + return irq; + } + + pr_debug("Setting IRQ for slot %s to %d\n", pci_name(dev), irq); + + return irq; +} + +void __init pcibios_fixup_irqs(void) +{ + pci_fixup_irqs(sh7751_no_swizzle, sh7751_pci_lookup_irq); +} + diff --git a/trunk/arch/sh/drivers/pci/pci-sh7751.h b/trunk/arch/sh/drivers/pci/pci-sh7751.h index 68e3cb5e6bec..1fee5cae10d1 100644 --- a/trunk/arch/sh/drivers/pci/pci-sh7751.h +++ b/trunk/arch/sh/drivers/pci/pci-sh7751.h @@ -3,7 +3,7 @@ * * Dustin McIntire (dustin@sensoria.com) (c) 2001 * Paul Mundt (lethal@linux-sh.org) (c) 2003 - * + * * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. * @@ -12,6 +12,28 @@ #ifndef _PCI_SH7751_H_ #define _PCI_SH7751_H_ +#include + +/* set debug level 4=verbose...1=terse */ +//#define DEBUG_PCI 3 +#undef DEBUG_PCI + +#ifdef DEBUG_PCI +#define PCIDBG(n, x...) { if(DEBUG_PCI>=n) printk(x); } +#else +#define PCIDBG(n, x...) +#endif + +/* startup values */ +#define PCI_PROBE_BIOS 1 +#define PCI_PROBE_CONF1 2 +#define PCI_PROBE_CONF2 4 +#define PCI_NO_SORT 0x100 +#define PCI_BIOS_SORT 0x200 +#define PCI_NO_CHECKS 0x400 +#define PCI_ASSIGN_ROMS 0x1000 +#define PCI_BIOS_IRQ_SCAN 0x2000 + /* Platform Specific Values */ #define SH7751_VENDOR_ID 0x1054 #define SH7751_DEVICE_ID 0x3505 @@ -106,6 +128,131 @@ #define SH7751_PCICONF17_PMEN 0x00010000 /* PME Enable */ #define SH7751_PCICONF17_PWST 0x00000003 /* Power State */ /* SH7715 Internal PCI Registers */ +#define SH7751_PCICR 0x100 /* PCI Control Register */ + #define SH7751_PCICR_PREFIX 0xA5000000 /* CR prefix for write */ + #define SH7751_PCICR_TRSB 0x00000200 /* Target Read Single */ + #define SH7751_PCICR_BSWP 0x00000100 /* Target Byte Swap */ + #define SH7751_PCICR_PLUP 0x00000080 /* Enable PCI Pullup */ + #define SH7751_PCICR_ARBM 0x00000040 /* PCI Arbitration Mode */ + #define SH7751_PCICR_MD 0x00000030 /* MD9 and MD10 status */ + #define SH7751_PCICR_SERR 0x00000008 /* SERR output assert */ + #define SH7751_PCICR_INTA 0x00000004 /* INTA output assert */ + #define SH7751_PCICR_PRST 0x00000002 /* PCI Reset Assert */ + #define SH7751_PCICR_CFIN 0x00000001 /* Central Fun. Init Done */ +#define SH7751_PCILSR0 0x104 /* PCI Local Space Register0 */ +#define SH7751_PCILSR1 0x108 /* PCI Local Space Register1 */ +#define SH7751_PCILAR0 0x10C /* PCI Local Address Register1 */ +#define SH7751_PCILAR1 0x110 /* PCI Local Address Register1 */ +#define SH7751_PCIINT 0x114 /* PCI Interrupt Register */ + #define SH7751_PCIINT_MLCK 0x00008000 /* Master Lock Error */ + #define SH7751_PCIINT_TABT 0x00004000 /* Target Abort Error */ + #define SH7751_PCIINT_TRET 0x00000200 /* Target Retry Error */ + #define SH7751_PCIINT_MFDE 0x00000100 /* Master Func. Disable Error */ + #define SH7751_PCIINT_PRTY 0x00000080 /* Address Parity Error */ + #define SH7751_PCIINT_SERR 0x00000040 /* SERR Detection Error */ + #define SH7751_PCIINT_TWDP 0x00000020 /* Tgt. Write Parity Error */ + #define SH7751_PCIINT_TRDP 0x00000010 /* Tgt. Read Parity Error Det. */ + #define SH7751_PCIINT_MTABT 0x00000008 /* Master-Tgt. Abort Error */ + #define SH7751_PCIINT_MMABT 0x00000004 /* Master-Master Abort Error */ + #define SH7751_PCIINT_MWPD 0x00000002 /* Master Write PERR Detect */ + #define SH7751_PCIINT_MRPD 0x00000002 /* Master Read PERR Detect */ +#define SH7751_PCIINTM 0x118 /* PCI Interrupt Mask Register */ +#define SH7751_PCIALR 0x11C /* Error Address Register */ +#define SH7751_PCICLR 0x120 /* Error Command/Data Register */ + #define SH7751_PCICLR_MPIO 0x80000000 /* Error Command/Data Register */ + #define SH7751_PCICLR_MDMA0 0x40000000 /* DMA0 Transfer Error */ + #define SH7751_PCICLR_MDMA1 0x20000000 /* DMA1 Transfer Error */ + #define SH7751_PCICLR_MDMA2 0x10000000 /* DMA2 Transfer Error */ + #define SH7751_PCICLR_MDMA3 0x08000000 /* DMA3 Transfer Error */ + #define SH7751_PCICLR_TGT 0x04000000 /* Target Transfer Error */ + #define SH7751_PCICLR_CMDL 0x0000000F /* PCI Command at Error */ +#define SH7751_PCIAINT 0x130 /* Arbiter Interrupt Register */ + #define SH7751_PCIAINT_MBKN 0x00002000 /* Master Broken Interrupt */ + #define SH7751_PCIAINT_TBTO 0x00001000 /* Target Bus Time Out */ + #define SH7751_PCIAINT_MBTO 0x00001000 /* Master Bus Time Out */ + #define SH7751_PCIAINT_TABT 0x00000008 /* Target Abort */ + #define SH7751_PCIAINT_MABT 0x00000004 /* Master Abort */ + #define SH7751_PCIAINT_RDPE 0x00000002 /* Read Data Parity Error */ + #define SH7751_PCIAINT_WDPE 0x00000002 /* Write Data Parity Error */ +#define SH7751_PCIAINTM 0x134 /* Arbiter Int. Mask Register */ +#define SH7751_PCIBMLR 0x138 /* Error Bus Master Register */ + #define SH7751_PCIBMLR_REQ4 0x00000010 /* REQ4 bus master at error */ + #define SH7751_PCIBMLR_REQ3 0x00000008 /* REQ3 bus master at error */ + #define SH7751_PCIBMLR_REQ2 0x00000004 /* REQ2 bus master at error */ + #define SH7751_PCIBMLR_REQ1 0x00000002 /* REQ1 bus master at error */ + #define SH7751_PCIBMLR_REQ0 0x00000001 /* REQ0 bus master at error */ +#define SH7751_PCIDMABT 0x140 /* DMA Transfer Arb. Register */ + #define SH7751_PCIDMABT_RRBN 0x00000001 /* DMA Arbitor Round-Robin */ +#define SH7751_PCIDPA0 0x180 /* DMA0 Transfer Addr. Register */ +#define SH7751_PCIDLA0 0x184 /* DMA0 Local Addr. Register */ +#define SH7751_PCIDTC0 0x188 /* DMA0 Transfer Cnt. Register */ +#define SH7751_PCIDCR0 0x18C /* DMA0 Control Register */ + #define SH7751_PCIDCR_ALGN 0x00000600 /* DMA Alignment Mode */ + #define SH7751_PCIDCR_MAST 0x00000100 /* DMA Termination Type */ + #define SH7751_PCIDCR_INTM 0x00000080 /* DMA Interrupt Done Mask*/ + #define SH7751_PCIDCR_INTS 0x00000040 /* DMA Interrupt Done Status */ + #define SH7751_PCIDCR_LHLD 0x00000020 /* Local Address Control */ + #define SH7751_PCIDCR_PHLD 0x00000010 /* PCI Address Control*/ + #define SH7751_PCIDCR_IOSEL 0x00000008 /* PCI Address Space Type */ + #define SH7751_PCIDCR_DIR 0x00000004 /* DMA Transfer Direction */ + #define SH7751_PCIDCR_STOP 0x00000002 /* Force DMA Stop */ + #define SH7751_PCIDCR_STRT 0x00000001 /* DMA Start */ +#define SH7751_PCIDPA1 0x190 /* DMA1 Transfer Addr. Register */ +#define SH7751_PCIDLA1 0x194 /* DMA1 Local Addr. Register */ +#define SH7751_PCIDTC1 0x198 /* DMA1 Transfer Cnt. Register */ +#define SH7751_PCIDCR1 0x19C /* DMA1 Control Register */ +#define SH7751_PCIDPA2 0x1A0 /* DMA2 Transfer Addr. Register */ +#define SH7751_PCIDLA2 0x1A4 /* DMA2 Local Addr. Register */ +#define SH7751_PCIDTC2 0x1A8 /* DMA2 Transfer Cnt. Register */ +#define SH7751_PCIDCR2 0x1AC /* DMA2 Control Register */ +#define SH7751_PCIDPA3 0x1B0 /* DMA3 Transfer Addr. Register */ +#define SH7751_PCIDLA3 0x1B4 /* DMA3 Local Addr. Register */ +#define SH7751_PCIDTC3 0x1B8 /* DMA3 Transfer Cnt. Register */ +#define SH7751_PCIDCR3 0x1BC /* DMA3 Control Register */ +#define SH7751_PCIPAR 0x1C0 /* PIO Address Register */ + #define SH7751_PCIPAR_CFGEN 0x80000000 /* Configuration Enable */ + #define SH7751_PCIPAR_BUSNO 0x00FF0000 /* Config. Bus Number */ + #define SH7751_PCIPAR_DEVNO 0x0000FF00 /* Config. Device Number */ + #define SH7751_PCIPAR_REGAD 0x000000FC /* Register Address Number */ +#define SH7751_PCIMBR 0x1C4 /* Memory Base Address Register */ + #define SH7751_PCIMBR_MASK 0xFF000000 /* Memory Space Mask */ + #define SH7751_PCIMBR_LOCK 0x00000001 /* Lock Memory Space */ +#define SH7751_PCIIOBR 0x1C8 /* I/O Base Address Register */ + #define SH7751_PCIIOBR_MASK 0xFFFC0000 /* IO Space Mask */ + #define SH7751_PCIIOBR_LOCK 0x00000001 /* Lock IO Space */ +#define SH7751_PCIPINT 0x1CC /* Power Mgmnt Int. Register */ + #define SH7751_PCIPINT_D3 0x00000002 /* D3 Pwr Mgmt. Interrupt */ + #define SH7751_PCIPINT_D0 0x00000001 /* D0 Pwr Mgmt. Interrupt */ +#define SH7751_PCIPINTM 0x1D0 /* Power Mgmnt Mask Register */ +#define SH7751_PCICLKR 0x1D4 /* Clock Ctrl. Register */ + #define SH7751_PCICLKR_PCSTP 0x00000002 /* PCI Clock Stop */ + #define SH7751_PCICLKR_BCSTP 0x00000002 /* BCLK Clock Stop */ +/* For definitions of BCR, MCR see ... */ +#define SH7751_PCIBCR1 0x1E0 /* Memory BCR1 Register */ +#define SH7751_PCIBCR2 0x1E4 /* Memory BCR2 Register */ +#define SH7751_PCIWCR1 0x1E8 /* Wait Control 1 Register */ +#define SH7751_PCIWCR2 0x1EC /* Wait Control 2 Register */ +#define SH7751_PCIWCR3 0x1F0 /* Wait Control 3 Register */ +#define SH7751_PCIMCR 0x1F4 /* Memory Control Register */ +#define SH7751_PCIBCR3 0x1f8 /* Memory BCR3 Register */ +#define SH7751_PCIPCTR 0x200 /* Port Control Register */ + #define SH7751_PCIPCTR_P2EN 0x000400000 /* Port 2 Enable */ + #define SH7751_PCIPCTR_P1EN 0x000200000 /* Port 1 Enable */ + #define SH7751_PCIPCTR_P0EN 0x000100000 /* Port 0 Enable */ + #define SH7751_PCIPCTR_P2UP 0x000000020 /* Port2 Pull Up Enable */ + #define SH7751_PCIPCTR_P2IO 0x000000010 /* Port2 Output Enable */ + #define SH7751_PCIPCTR_P1UP 0x000000008 /* Port1 Pull Up Enable */ + #define SH7751_PCIPCTR_P1IO 0x000000004 /* Port1 Output Enable */ + #define SH7751_PCIPCTR_P0UP 0x000000002 /* Port0 Pull Up Enable */ + #define SH7751_PCIPCTR_P0IO 0x000000001 /* Port0 Output Enable */ +#define SH7751_PCIPDTR 0x204 /* Port Data Register */ + #define SH7751_PCIPDTR_PB5 0x000000020 /* Port 5 Enable */ + #define SH7751_PCIPDTR_PB4 0x000000010 /* Port 4 Enable */ + #define SH7751_PCIPDTR_PB3 0x000000008 /* Port 3 Enable */ + #define SH7751_PCIPDTR_PB2 0x000000004 /* Port 2 Enable */ + #define SH7751_PCIPDTR_PB1 0x000000002 /* Port 1 Enable */ + #define SH7751_PCIPDTR_PB0 0x000000001 /* Port 0 Enable */ +#define SH7751_PCIPDR 0x220 /* Port IO Data Register */ /* Memory Control Registers */ #define SH7751_BCR1 0xFF800000 /* Memory BCR1 Register */ @@ -127,9 +274,30 @@ #define SH7751_CS5_BASE_ADDR (SH7751_CS4_BASE_ADDR + SH7751_MEM_REGION_SIZE) #define SH7751_CS6_BASE_ADDR (SH7751_CS5_BASE_ADDR + SH7751_MEM_REGION_SIZE) -struct sh4_pci_address_map; +/* General PCI values */ +#define SH7751_PCI_HOST_BRIDGE 0x6 + +/* Flags */ +#define SH7751_PCIC_NO_RESET 0x0001 + +/* External functions defined per platform i.e. Big Sur, SE... (these could be routed + * through the machine vectors... */ +extern int pcibios_init_platform(void); +extern int pcibios_map_platform_irq(u8 slot, u8 pin); + +struct sh7751_pci_address_space { + unsigned long base; + unsigned long size; +}; + +struct sh7751_pci_address_map { + struct sh7751_pci_address_space window0; + struct sh7751_pci_address_space window1; + unsigned long flags; +}; /* arch/sh/drivers/pci/pci-sh7751.c */ -int sh7751_pcic_init(struct sh4_pci_address_map *map); +extern int sh7751_pcic_init(struct sh7751_pci_address_map *map); #endif /* _PCI_SH7751_H_ */ + diff --git a/trunk/arch/sh/drivers/pci/pci-sh7780.c b/trunk/arch/sh/drivers/pci/pci-sh7780.c deleted file mode 100644 index bd3064a82087..000000000000 --- a/trunk/arch/sh/drivers/pci/pci-sh7780.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Low-Level PCI Support for the SH7780 - * - * Dustin McIntire (dustin@sensoria.com) - * Derived from arch/i386/kernel/pci-*.c which bore the message: - * (c) 1999--2000 Martin Mares - * - * Ported to the new API by Paul Mundt - * With cleanup by Paul van Gool - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include "pci-sh4.h" - -/* - * Initialization. Try all known PCI access methods. Note that we support - * using both PCI BIOS and direct access: in such cases, we use I/O ports - * to access config space. - * - * Note that the platform specific initialization (BSC registers, and memory - * space mapping) will be called via the platform defined function - * pcibios_init_platform(). - */ -static int __init sh7780_pci_init(void) -{ - unsigned int id; - int ret; - - pr_debug("PCI: Starting intialization.\n"); - - outl(0x00000001, SH7780_PCI_VCR2); /* Enable PCIC */ - - /* check for SH7780/SH7780R hardware */ - id = pci_read_reg(SH7780_PCIVID); - if ((id != ((SH7780_DEVICE_ID << 16) | SH7780_VENDOR_ID)) && - (id != ((SH7781_DEVICE_ID << 16) | SH7780_VENDOR_ID))) { - printk(KERN_ERR "PCI: This is not an SH7780 (%x)\n", id); - return -ENODEV; - } - - /* Setup the INTC */ - ctrl_outl(0x00200000, INTC_ICR0); /* INTC SH-4 Mode */ - ctrl_outl(0x00078000, INTC_INT2MSKCR); /* enable PCIINTA - PCIINTD */ - ctrl_outl(0x40000000, INTC_INTMSK1); /* disable IRL4-7 Interrupt */ - ctrl_outl(0x0000fffe, INTC_INTMSK2); /* disable IRL4-7 Interrupt */ - ctrl_outl(0x80000000, INTC_INTMSKCLR1); /* enable IRL0-3 Interrupt */ - ctrl_outl(0xfffe0000, INTC_INTMSKCLR2); /* enable IRL0-3 Interrupt */ - - if ((ret = sh4_pci_check_direct()) != 0) - return ret; - - return pcibios_init_platform(); -} -core_initcall(sh7780_pci_init); - -int __init sh7780_pcic_init(struct sh4_pci_address_map *map) -{ - u32 word; - - /* - * This code is unused for some boards as it is done in the - * bootloader and doing it here means the MAC addresses loaded - * by the bootloader get lost. - */ - if (!(map->flags & SH4_PCIC_NO_RESET)) { - /* toggle PCI reset pin */ - word = SH4_PCICR_PREFIX | SH4_PCICR_PRST; - pci_write_reg(word, SH4_PCICR); - /* Wait for a long time... not 1 sec. but long enough */ - mdelay(100); - word = SH4_PCICR_PREFIX; - pci_write_reg(word, SH4_PCICR); - } - - /* set the command/status bits to: - * Wait Cycle Control + Parity Enable + Bus Master + - * Mem space enable - */ - pci_write_reg(0x00000046, SH7780_PCICMD); - - /* define this host as the host bridge */ - word = PCI_BASE_CLASS_BRIDGE << 24; - pci_write_reg(word, SH7780_PCIRID); - - /* Set IO and Mem windows to local address - * Make PCI and local address the same for easy 1 to 1 mapping - * Window0 = map->window0.size @ non-cached area base = SDRAM - * Window1 = map->window1.size @ cached area base = SDRAM - */ - word = ((map->window0.size - 1) & 0x1ff00001) | 0x01; - pci_write_reg(0x07f00001, SH4_PCILSR0); - word = ((map->window1.size - 1) & 0x1ff00001) | 0x01; - pci_write_reg(0x00000001, SH4_PCILSR1); - /* Set the values on window 0 PCI config registers */ - word = P2SEGADDR(map->window0.base); - pci_write_reg(0xa8000000, SH4_PCILAR0); - pci_write_reg(0x08000000, SH7780_PCIMBAR0); - /* Set the values on window 1 PCI config registers */ - word = P2SEGADDR(map->window1.base); - pci_write_reg(0x00000000, SH4_PCILAR1); - pci_write_reg(0x00000000, SH7780_PCIMBAR1); - - /* Map IO space into PCI IO window - * The IO window is 64K-PCIBIOS_MIN_IO in size - * IO addresses will be translated to the - * PCI IO window base address - */ - pr_debug("PCI: Mapping IO address 0x%x - 0x%x to base 0x%x\n", - PCIBIOS_MIN_IO, (64 << 10), - SH7780_PCI_IO_BASE + PCIBIOS_MIN_IO); - - /* NOTE: I'm ignoring the PCI error IRQs for now.. - * TODO: add support for the internal error interrupts and - * DMA interrupts... - */ - -#ifdef CONFIG_SH_R7780RP - pci_fixup_pcic(); -#endif - - /* SH7780 init done, set central function init complete */ - /* use round robin mode to stop a device starving/overruning */ - word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO; - pci_write_reg(word, SH4_PCICR); - - return 1; -} diff --git a/trunk/arch/sh/drivers/pci/pci-sh7780.h b/trunk/arch/sh/drivers/pci/pci-sh7780.h deleted file mode 100644 index f02d2180a4bc..000000000000 --- a/trunk/arch/sh/drivers/pci/pci-sh7780.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Low-Level PCI Support for SH7780 targets - * - * Dustin McIntire (dustin@sensoria.com) (c) 2001 - * Paul Mundt (lethal@linux-sh.org) (c) 2003 - * - * May be copied or modified under the terms of the GNU General Public - * License. See linux/COPYING for more information. - * - */ - -#ifndef _PCI_SH7780_H_ -#define _PCI_SH7780_H_ - -/* Platform Specific Values */ -#define SH7780_VENDOR_ID 0x1912 -#define SH7780_DEVICE_ID 0x0002 -#define SH7781_DEVICE_ID 0x0001 - -/* SH7780 Control Registers */ -#define SH7780_PCI_VCR0 0xFE000000 -#define SH7780_PCI_VCR1 0xFE000004 -#define SH7780_PCI_VCR2 0xFE000008 - -/* SH7780 Specific Values */ -#define SH7780_PCI_CONFIG_BASE 0xFD000000 /* Config space base addr */ -#define SH7780_PCI_CONFIG_SIZE 0x01000000 /* Config space size */ - -#define SH7780_PCI_MEMORY_BASE 0xFD000000 /* Memory space base addr */ -#define SH7780_PCI_MEM_SIZE 0x01000000 /* Size of Memory window */ - -#define SH7780_PCI_IO_BASE 0xFE400000 /* IO space base address */ -#define SH7780_PCI_IO_SIZE 0x00400000 /* Size of IO window */ - -#define SH7780_PCIREG_BASE 0xFE040000 /* PCI regs base address */ -#define PCI_REG(n) (SH7780_PCIREG_BASE+n) - -/* SH7780 PCI Config Registers */ -#define SH7780_PCIVID 0x000 /* Vendor ID */ -#define SH7780_PCIDID 0x002 /* Device ID */ -#define SH7780_PCICMD 0x004 /* Command */ -#define SH7780_PCISTATUS 0x006 /* Status */ -#define SH7780_PCIRID 0x008 /* Revision ID */ -#define SH7780_PCIPIF 0x009 /* Program Interface */ -#define SH7780_PCISUB 0x00a /* Sub class code */ -#define SH7780_PCIBCC 0x00b /* Base class code */ -#define SH7780_PCICLS 0x00c /* Cache line size */ -#define SH7780_PCILTM 0x00d /* latency timer */ -#define SH7780_PCIHDR 0x00e /* Header type */ -#define SH7780_PCIBIST 0x00f /* BIST */ -#define SH7780_PCIIBAR 0x010 /* IO Base address */ -#define SH7780_PCIMBAR0 0x014 /* Memory base address0 */ -#define SH7780_PCIMBAR1 0x018 /* Memory base address1 */ -#define SH7780_PCISVID 0x02c /* Sub system vendor ID */ -#define SH7780_PCISID 0x02e /* Sub system ID */ -#define SH7780_PCICP 0x034 -#define SH7780_PCIINTLINE 0x03c /* Interrupt line */ -#define SH7780_PCIINTPIN 0x03d /* Interrupt pin */ -#define SH7780_PCIMINGNT 0x03e /* Minumum grand */ -#define SH7780_PCIMAXLAT 0x03f /* Maxmum latency */ -#define SH7780_PCICID 0x040 -#define SH7780_PCINIP 0x041 -#define SH7780_PCIPMC 0x042 -#define SH7780_PCIPMCSR 0x044 -#define SH7780_PCIPMCSR_BSE 0x046 -#define SH7780_PCICDD 0x047 - -#define SH7780_PCIMBR0 0x1E0 -#define SH7780_PCIMBMR0 0x1E4 -#define SH7780_PCIMBR2 0x1F0 -#define SH7780_PCIMBMR2 0x1F4 -#define SH7780_PCIIOBR 0x1F8 -#define SH7780_PCIIOBMR 0x1FC -#define SH7780_PCICSCR0 0x210 /* Cache Snoop1 Cnt. Register */ -#define SH7780_PCICSCR1 0x214 /* Cache Snoop2 Cnt. Register */ -#define SH7780_PCICSAR0 0x218 /* Cache Snoop1 Addr. Register */ -#define SH7780_PCICSAR1 0x21C /* Cache Snoop2 Addr. Register */ - -/* General Memory Config Addresses */ -#define SH7780_CS0_BASE_ADDR 0x0 -#define SH7780_MEM_REGION_SIZE 0x04000000 -#define SH7780_CS1_BASE_ADDR (SH7780_CS0_BASE_ADDR + SH7780_MEM_REGION_SIZE) -#define SH7780_CS2_BASE_ADDR (SH7780_CS1_BASE_ADDR + SH7780_MEM_REGION_SIZE) -#define SH7780_CS3_BASE_ADDR (SH7780_CS2_BASE_ADDR + SH7780_MEM_REGION_SIZE) -#define SH7780_CS4_BASE_ADDR (SH7780_CS3_BASE_ADDR + SH7780_MEM_REGION_SIZE) -#define SH7780_CS5_BASE_ADDR (SH7780_CS4_BASE_ADDR + SH7780_MEM_REGION_SIZE) -#define SH7780_CS6_BASE_ADDR (SH7780_CS5_BASE_ADDR + SH7780_MEM_REGION_SIZE) - -struct sh4_pci_address_map; - -/* arch/sh/drivers/pci/pci-sh7780.c */ -int sh7780_pcic_init(struct sh4_pci_address_map *map); - -#endif /* _PCI_SH7780_H_ */ diff --git a/trunk/arch/sh/drivers/pci/pci-st40.c b/trunk/arch/sh/drivers/pci/pci-st40.c index 4ab5ea6b35fb..7c81b8b65bb5 100644 --- a/trunk/arch/sh/drivers/pci/pci-st40.c +++ b/trunk/arch/sh/drivers/pci/pci-st40.c @@ -70,6 +70,12 @@ static void pci_set_rbar_region(unsigned int region, unsigned long localAddr, unsigned long pciOffset, unsigned long regionSize); +/* + * The pcibios_map_platform_irq function is defined in the appropriate + * board specific code and referenced here + */ +extern int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin); + static __init void SetPCIPLL(void) { { @@ -416,6 +422,13 @@ struct pci_ops st40pci_config_ops = { /* Everything hangs off this */ static struct pci_bus *pci_root_bus; + +static u8 __init no_swizzle(struct pci_dev *dev, u8 * pin) +{ + return PCI_SLOT(dev->devfn); +} + + static int __init pcibios_init(void) { extern unsigned long memory_start, memory_end; @@ -452,11 +465,17 @@ static int __init pcibios_init(void) /* ok, do the scan man */ pci_root_bus = pci_scan_bus(0, &st40pci_config_ops, NULL); pci_assign_unassigned_resources(); + pci_fixup_irqs(no_swizzle, pcibios_map_platform_irq); return 0; } + subsys_initcall(pcibios_init); +void __init pcibios_fixup_bus(struct pci_bus *bus) +{ +} + /* * Publish a region of local address space over the PCI bus * to other devices. diff --git a/trunk/arch/sh/drivers/pci/pci.c b/trunk/arch/sh/drivers/pci/pci.c index d439336d2e18..3d546ba329cf 100644 --- a/trunk/arch/sh/drivers/pci/pci.c +++ b/trunk/arch/sh/drivers/pci/pci.c @@ -1,45 +1,21 @@ -/* - * arch/sh/drivers/pci/pci.c +/* arch/sh/kernel/pci.c + * $Id: pci.c,v 1.1 2003/08/24 19:15:45 lethal Exp $ * * Copyright (c) 2002 M. R. Brown - * Copyright (c) 2004 - 2006 Paul Mundt - * + * + * * These functions are collected here to reduce duplication of common * code amongst the many platform-specific PCI support code files. - * + * * These routines require the following board-specific routines: * void pcibios_fixup_irqs(); * * See include/asm-sh/pci.h for more information. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. */ + #include #include #include -#include - -static inline u8 bridge_swizzle(u8 pin, u8 slot) -{ - return (((pin - 1) + slot) % 4) + 1; -} - -static u8 __init simple_swizzle(struct pci_dev *dev, u8 *pinp) -{ - u8 pin = *pinp; - - while (dev->bus->parent) { - pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); - /* Move up the chain of bridges. */ - dev = dev->bus->self; - } - *pinp = pin; - - /* The slot is the slot of the last bridge. */ - return PCI_SLOT(dev->devfn); -} static int __init pcibios_init(void) { @@ -50,31 +26,25 @@ static int __init pcibios_init(void) #ifdef CONFIG_PCI_AUTO /* assign resources */ busno = 0; - for (p = board_pci_channels; p->pci_ops != NULL; p++) + for (p = board_pci_channels; p->pci_ops != NULL; p++) { busno = pciauto_assign_resources(busno, p) + 1; + } #endif /* scan the buses */ busno = 0; - for (p = board_pci_channels; p->pci_ops != NULL; p++) { + for (p= board_pci_channels; p->pci_ops != NULL; p++) { bus = pci_scan_bus(busno, p->pci_ops, p); - busno = bus->subordinate + 1; + busno = bus->subordinate+1; } - pci_fixup_irqs(simple_swizzle, pcibios_map_platform_irq); + /* board-specific fixups */ + pcibios_fixup_irqs(); return 0; } -subsys_initcall(pcibios_init); -/* - * Called after each bus is probed, but before its children - * are examined. - */ -void __init pcibios_fixup_bus(struct pci_bus *bus) -{ - pci_read_bridge_bases(bus); -} +subsys_initcall(pcibios_init); void pcibios_update_resource(struct pci_dev *dev, struct resource *root, @@ -91,17 +61,13 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, new |= PCI_ROM_ADDRESS_ENABLE; reg = dev->rom_base_reg; } else { - /* - * Somebody might have asked allocation of a non-standard - * resource - */ + /* Somebody might have asked allocation of a non-standard resource */ return; } - + pci_write_config_dword(dev, reg, new); pci_read_config_dword(dev, reg, &check); - if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? - PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { + if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { printk(KERN_ERR "PCI: Error while updating region " "%s/%d (%08x != %08x)\n", pci_name(dev), resource, new, check); @@ -179,8 +145,7 @@ void pcibios_set_master(struct pci_dev *dev) lat = pcibios_max_latency; else return; - printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", - pci_name(dev), lat); + printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); } @@ -188,39 +153,3 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) { pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } - -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - unsigned long start = pci_resource_start(dev, bar); - unsigned long len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (unlikely(!len || !start)) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - - /* - * Presently the IORESOURCE_MEM case is a bit special, most - * SH7751 style PCI controllers have PCI memory at a fixed - * location in the address space where no remapping is desired - * (typically at 0xfd000000, but is_pci_memaddr() will know - * best). With the IORESOURCE_MEM case more care has to be taken - * to inhibit page table mapping for legacy cores, but this is - * punted off to __ioremap(). - * -- PFM. - */ - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) - return ioremap(start, len); - - return NULL; -} -EXPORT_SYMBOL(pci_iomap); - -void pci_iounmap(struct pci_dev *dev, void __iomem *addr) -{ - iounmap(addr); -} -EXPORT_SYMBOL(pci_iounmap); diff --git a/trunk/arch/sh/kernel/Makefile b/trunk/arch/sh/kernel/Makefile index 5da88a43d350..f05cd96f8867 100644 --- a/trunk/arch/sh/kernel/Makefile +++ b/trunk/arch/sh/kernel/Makefile @@ -6,10 +6,9 @@ extra-y := head.o init_task.o vmlinux.lds obj-y := process.o signal.o entry.o traps.o irq.o \ ptrace.o setup.o time.o sys_sh.o semaphore.o \ - io.o io_generic.o sh_ksyms.o syscalls.o + io.o io_generic.o sh_ksyms.o obj-y += cpu/ timers/ -obj-$(CONFIG_VSYSCALL) += vsyscall/ obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_CF_ENABLER) += cf-enabler.o @@ -19,5 +18,3 @@ obj-$(CONFIG_SH_CPU_FREQ) += cpufreq.o obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o -obj-$(CONFIG_APM) += apm.o -obj-$(CONFIG_PM) += pm.o diff --git a/trunk/arch/sh/kernel/apm.c b/trunk/arch/sh/kernel/apm.c deleted file mode 100644 index 871e7d640002..000000000000 --- a/trunk/arch/sh/kernel/apm.c +++ /dev/null @@ -1,539 +0,0 @@ -/* - * bios-less APM driver for hp680 - * - * Copyright 2005 (c) Andriy Skulysh - * - * based on ARM APM driver by - * Jamey Hicks - * - * adapted from the APM BIOS driver for Linux by - * Stephen Rothwell (sfr@linuxcare.com) - * - * APM 1.2 Reference: - * Intel Corporation, Microsoft Corporation. Advanced Power Management - * (APM) BIOS Interface Specification, Revision 1.2, February 1996. - * - * [This document is available from Microsoft at: - * http://www.microsoft.com/hwdev/busbios/amp_12.htm] - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MODNAME "apm" - -/* - * The apm_bios device is one of the misc char devices. - * This is its minor number. - */ -#define APM_MINOR_DEV 134 - -/* - * Maximum number of events stored - */ -#define APM_MAX_EVENTS 16 - -struct apm_queue { - unsigned int event_head; - unsigned int event_tail; - apm_event_t events[APM_MAX_EVENTS]; -}; - -/* - * The per-file APM data - */ -struct apm_user { - struct list_head list; - - unsigned int suser: 1; - unsigned int writer: 1; - unsigned int reader: 1; - - int suspend_result; - unsigned int suspend_state; -#define SUSPEND_NONE 0 /* no suspend pending */ -#define SUSPEND_PENDING 1 /* suspend pending read */ -#define SUSPEND_READ 2 /* suspend read, pending ack */ -#define SUSPEND_ACKED 3 /* suspend acked */ -#define SUSPEND_DONE 4 /* suspend completed */ - - struct apm_queue queue; -}; - -/* - * Local variables - */ -static int suspends_pending; - -static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); -static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); - -/* - * This is a list of everyone who has opened /dev/apm_bios - */ -static DECLARE_RWSEM(user_list_lock); -static LIST_HEAD(apm_user_list); - -/* - * kapmd info. kapmd provides us a process context to handle - * "APM" events within - specifically necessary if we're going - * to be suspending the system. - */ -static DECLARE_WAIT_QUEUE_HEAD(kapmd_wait); -static DECLARE_COMPLETION(kapmd_exit); -static DEFINE_SPINLOCK(kapmd_queue_lock); -static struct apm_queue kapmd_queue; - -int apm_suspended; -EXPORT_SYMBOL(apm_suspended); - -/* Platform-specific apm_read_proc(). */ -int (*apm_get_info)(char *buf, char **start, off_t fpos, int length); -EXPORT_SYMBOL(apm_get_info); - -/* - * APM event queue management. - */ -static inline int queue_empty(struct apm_queue *q) -{ - return q->event_head == q->event_tail; -} - -static inline apm_event_t queue_get_event(struct apm_queue *q) -{ - q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS; - return q->events[q->event_tail]; -} - -static void queue_add_event(struct apm_queue *q, apm_event_t event) -{ - q->event_head = (q->event_head + 1) % APM_MAX_EVENTS; - if (q->event_head == q->event_tail) { - static int notified; - - if (notified++ == 0) - printk(KERN_ERR "apm: an event queue overflowed\n"); - - q->event_tail = (q->event_tail + 1) % APM_MAX_EVENTS; - } - q->events[q->event_head] = event; -} - -static void queue_event_one_user(struct apm_user *as, apm_event_t event) -{ - if (as->suser && as->writer) { - switch (event) { - case APM_SYS_SUSPEND: - case APM_USER_SUSPEND: - /* - * If this user already has a suspend pending, - * don't queue another one. - */ - if (as->suspend_state != SUSPEND_NONE) - return; - - as->suspend_state = SUSPEND_PENDING; - suspends_pending++; - break; - } - } - queue_add_event(&as->queue, event); -} - -static void queue_event(apm_event_t event, struct apm_user *sender) -{ - struct apm_user *as; - - down_read(&user_list_lock); - - list_for_each_entry(as, &apm_user_list, list) - if (as != sender && as->reader) - queue_event_one_user(as, event); - - up_read(&user_list_lock); - wake_up_interruptible(&apm_waitqueue); -} - -/** - * apm_queue_event - queue an APM event for kapmd - * @event: APM event - * - * Queue an APM event for kapmd to process and ultimately take the - * appropriate action. Only a subset of events are handled: - * %APM_LOW_BATTERY - * %APM_POWER_STATUS_CHANGE - * %APM_USER_SUSPEND - * %APM_SYS_SUSPEND - * %APM_CRITICAL_SUSPEND - */ -void apm_queue_event(apm_event_t event) -{ - spin_lock_irq(&kapmd_queue_lock); - queue_add_event(&kapmd_queue, event); - spin_unlock_irq(&kapmd_queue_lock); - - wake_up_interruptible(&kapmd_wait); -} -EXPORT_SYMBOL(apm_queue_event); - -static void apm_suspend(void) -{ - struct apm_user *as; - int err; - - apm_suspended = 1; - err = pm_suspend(PM_SUSPEND_MEM); - - /* - * Anyone on the APM queues will think we're still suspended. - * Send a message so everyone knows we're now awake again. - */ - queue_event(APM_NORMAL_RESUME, NULL); - - /* - * Finally, wake up anyone who is sleeping on the suspend. - */ - down_read(&user_list_lock); - list_for_each_entry(as, &apm_user_list, list) { - as->suspend_result = err; - as->suspend_state = SUSPEND_DONE; - } - up_read(&user_list_lock); - - wake_up(&apm_suspend_waitqueue); - apm_suspended = 0; -} - -static ssize_t apm_read(struct file *fp, char __user *buf, - size_t count, loff_t *ppos) -{ - struct apm_user *as = fp->private_data; - apm_event_t event; - int i = count, ret = 0; - - if (count < sizeof(apm_event_t)) - return -EINVAL; - - if (queue_empty(&as->queue) && fp->f_flags & O_NONBLOCK) - return -EAGAIN; - - wait_event_interruptible(apm_waitqueue, !queue_empty(&as->queue)); - - while ((i >= sizeof(event)) && !queue_empty(&as->queue)) { - event = queue_get_event(&as->queue); - - ret = -EFAULT; - if (copy_to_user(buf, &event, sizeof(event))) - break; - - if (event == APM_SYS_SUSPEND || event == APM_USER_SUSPEND) - as->suspend_state = SUSPEND_READ; - - buf += sizeof(event); - i -= sizeof(event); - } - - if (i < count) - ret = count - i; - - return ret; -} - -static unsigned int apm_poll(struct file *fp, poll_table * wait) -{ - struct apm_user *as = fp->private_data; - - poll_wait(fp, &apm_waitqueue, wait); - return queue_empty(&as->queue) ? 0 : POLLIN | POLLRDNORM; -} - -/* - * apm_ioctl - handle APM ioctl - * - * APM_IOC_SUSPEND - * This IOCTL is overloaded, and performs two functions. It is used to: - * - initiate a suspend - * - acknowledge a suspend read from /dev/apm_bios. - * Only when everyone who has opened /dev/apm_bios with write permission - * has acknowledge does the actual suspend happen. - */ -static int -apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg) -{ - struct apm_user *as = filp->private_data; - unsigned long flags; - int err = -EINVAL; - - if (!as->suser || !as->writer) - return -EPERM; - - switch (cmd) { - case APM_IOC_SUSPEND: - as->suspend_result = -EINTR; - - if (as->suspend_state == SUSPEND_READ) { - /* - * If we read a suspend command from /dev/apm_bios, - * then the corresponding APM_IOC_SUSPEND ioctl is - * interpreted as an acknowledge. - */ - as->suspend_state = SUSPEND_ACKED; - suspends_pending--; - } else { - /* - * Otherwise it is a request to suspend the system. - * Queue an event for all readers, and expect an - * acknowledge from all writers who haven't already - * acknowledged. - */ - queue_event(APM_USER_SUSPEND, as); - } - - /* - * If there are no further acknowledges required, suspend - * the system. - */ - if (suspends_pending == 0) - apm_suspend(); - - /* - * Wait for the suspend/resume to complete. If there are - * pending acknowledges, we wait here for them. - * - * Note that we need to ensure that the PM subsystem does - * not kick us out of the wait when it suspends the threads. - */ - flags = current->flags; - current->flags |= PF_NOFREEZE; - - /* - * Note: do not allow a thread which is acking the suspend - * to escape until the resume is complete. - */ - if (as->suspend_state == SUSPEND_ACKED) - wait_event(apm_suspend_waitqueue, - as->suspend_state == SUSPEND_DONE); - else - wait_event_interruptible(apm_suspend_waitqueue, - as->suspend_state == SUSPEND_DONE); - - current->flags = flags; - err = as->suspend_result; - as->suspend_state = SUSPEND_NONE; - break; - } - - return err; -} - -static int apm_release(struct inode * inode, struct file * filp) -{ - struct apm_user *as = filp->private_data; - filp->private_data = NULL; - - down_write(&user_list_lock); - list_del(&as->list); - up_write(&user_list_lock); - - /* - * We are now unhooked from the chain. As far as new - * events are concerned, we no longer exist. However, we - * need to balance suspends_pending, which means the - * possibility of sleeping. - */ - if (as->suspend_state != SUSPEND_NONE) { - suspends_pending -= 1; - if (suspends_pending == 0) - apm_suspend(); - } - - kfree(as); - return 0; -} - -static int apm_open(struct inode * inode, struct file * filp) -{ - struct apm_user *as; - - as = kzalloc(sizeof(*as), GFP_KERNEL); - if (as) { - /* - * XXX - this is a tiny bit broken, when we consider BSD - * process accounting. If the device is opened by root, we - * instantly flag that we used superuser privs. Who knows, - * we might close the device immediately without doing a - * privileged operation -- cevans - */ - as->suser = capable(CAP_SYS_ADMIN); - as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE; - as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ; - - down_write(&user_list_lock); - list_add(&as->list, &apm_user_list); - up_write(&user_list_lock); - - filp->private_data = as; - } - - return as ? 0 : -ENOMEM; -} - -static struct file_operations apm_bios_fops = { - .owner = THIS_MODULE, - .read = apm_read, - .poll = apm_poll, - .ioctl = apm_ioctl, - .open = apm_open, - .release = apm_release, -}; - -static struct miscdevice apm_device = { - .minor = APM_MINOR_DEV, - .name = "apm_bios", - .fops = &apm_bios_fops -}; - - -#ifdef CONFIG_PROC_FS -/* - * Arguments, with symbols from linux/apm_bios.h. - * - * 0) Linux driver version (this will change if format changes) - * 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2. - * 2) APM flags from APM Installation Check (0x00): - * bit 0: APM_16_BIT_SUPPORT - * bit 1: APM_32_BIT_SUPPORT - * bit 2: APM_IDLE_SLOWS_CLOCK - * bit 3: APM_BIOS_DISABLED - * bit 4: APM_BIOS_DISENGAGED - * 3) AC line status - * 0x00: Off-line - * 0x01: On-line - * 0x02: On backup power (BIOS >= 1.1 only) - * 0xff: Unknown - * 4) Battery status - * 0x00: High - * 0x01: Low - * 0x02: Critical - * 0x03: Charging - * 0x04: Selected battery not present (BIOS >= 1.2 only) - * 0xff: Unknown - * 5) Battery flag - * bit 0: High - * bit 1: Low - * bit 2: Critical - * bit 3: Charging - * bit 7: No system battery - * 0xff: Unknown - * 6) Remaining battery life (percentage of charge): - * 0-100: valid - * -1: Unknown - * 7) Remaining battery life (time units): - * Number of remaining minutes or seconds - * -1: Unknown - * 8) min = minutes; sec = seconds - */ -static int apm_read_proc(char *buf, char **start, off_t fpos, int length) -{ - if (likely(apm_get_info)) - return apm_get_info(buf, start, fpos, length); - - return -EINVAL; -} -#endif - -static int kapmd(void *arg) -{ - daemonize("kapmd"); - current->flags |= PF_NOFREEZE; - - do { - apm_event_t event; - - wait_event_interruptible(kapmd_wait, - !queue_empty(&kapmd_queue) || !pm_active); - - if (!pm_active) - break; - - spin_lock_irq(&kapmd_queue_lock); - event = 0; - if (!queue_empty(&kapmd_queue)) - event = queue_get_event(&kapmd_queue); - spin_unlock_irq(&kapmd_queue_lock); - - switch (event) { - case 0: - break; - - case APM_LOW_BATTERY: - case APM_POWER_STATUS_CHANGE: - queue_event(event, NULL); - break; - - case APM_USER_SUSPEND: - case APM_SYS_SUSPEND: - queue_event(event, NULL); - if (suspends_pending == 0) - apm_suspend(); - break; - - case APM_CRITICAL_SUSPEND: - apm_suspend(); - break; - } - } while (1); - - complete_and_exit(&kapmd_exit, 0); -} - -static int __init apm_init(void) -{ - int ret; - - pm_active = 1; - - ret = kernel_thread(kapmd, NULL, CLONE_KERNEL); - if (unlikely(ret < 0)) { - pm_active = 0; - return ret; - } - - create_proc_info_entry("apm", 0, NULL, apm_read_proc); - - ret = misc_register(&apm_device); - if (unlikely(ret != 0)) { - remove_proc_entry("apm", NULL); - - pm_active = 0; - wake_up(&kapmd_wait); - wait_for_completion(&kapmd_exit); - } - - return ret; -} - -static void __exit apm_exit(void) -{ - misc_deregister(&apm_device); - remove_proc_entry("apm", NULL); - - pm_active = 0; - wake_up(&kapmd_wait); - wait_for_completion(&kapmd_exit); -} - -module_init(apm_init); -module_exit(apm_exit); - -MODULE_AUTHOR("Stephen Rothwell, Andriy Skulysh"); -MODULE_DESCRIPTION("Advanced Power Management"); -MODULE_LICENSE("GPL"); diff --git a/trunk/arch/sh/kernel/cf-enabler.c b/trunk/arch/sh/kernel/cf-enabler.c index 3e5fa1e24df0..f1f9ab87f0b0 100644 --- a/trunk/arch/sh/kernel/cf-enabler.c +++ b/trunk/arch/sh/kernel/cf-enabler.c @@ -10,8 +10,7 @@ */ #include -#include -#include + #include #include @@ -33,6 +32,8 @@ /* SH4 can't access PCMCIA interface through P2 area. * we must remap it with appropreate attribute bit of the page set. * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */ +#include +#include #if defined(CONFIG_CF_AREA6) #define slot_no 0 @@ -40,6 +41,9 @@ #define slot_no 1 #endif +/* defined in mm/ioremap.c */ +extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags); + /* use this pointer to access to directly connected compact flash io area*/ void *cf_io_base; @@ -58,7 +62,7 @@ static int __init allocate_cf_area(void) return -ENOMEM; } /* printk("p3_ioremap(paddr=0x%08lx, psize=0x%08lx, prot=0x%08lx)=0x%08lx\n", - paddrbase, psize, prot.pgprot, cf_io_base);*/ + paddrbase, psize, prot.pgprot, cf_io_base);*/ /* XXX : do we need attribute and common-memory area also? */ @@ -83,7 +87,7 @@ static int __init cf_init_default(void) } #if defined(CONFIG_SH_SOLUTION_ENGINE) -#include +#include /* * SolutionEngine diff --git a/trunk/arch/sh/kernel/cpu/Makefile b/trunk/arch/sh/kernel/cpu/Makefile index fb5dac069382..59d5b748752f 100644 --- a/trunk/arch/sh/kernel/cpu/Makefile +++ b/trunk/arch/sh/kernel/cpu/Makefile @@ -8,5 +8,6 @@ obj-$(CONFIG_CPU_SH2) += sh2/ obj-$(CONFIG_CPU_SH3) += sh3/ obj-$(CONFIG_CPU_SH4) += sh4/ +obj-$(CONFIG_SH_RTC) += rtc.o obj-$(CONFIG_UBC_WAKEUP) += ubc.o obj-$(CONFIG_SH_ADC) += adc.o diff --git a/trunk/arch/sh/kernel/cpu/clock.c b/trunk/arch/sh/kernel/cpu/clock.c index 51ec64cdf348..97fa37f42b84 100644 --- a/trunk/arch/sh/kernel/cpu/clock.c +++ b/trunk/arch/sh/kernel/cpu/clock.c @@ -1,7 +1,7 @@ /* * arch/sh/kernel/cpu/clock.c - SuperH clock framework * - * Copyright (C) 2005, 2006 Paul Mundt + * Copyright (C) 2005 Paul Mundt * * This clock framework is derived from the OMAP version by: * @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -25,7 +24,7 @@ static LIST_HEAD(clock_list); static DEFINE_SPINLOCK(clock_lock); -static DEFINE_MUTEX(clock_list_sem); +static DECLARE_MUTEX(clock_list_sem); /* * Each subtype is expected to define the init routines for these clocks, @@ -141,21 +140,21 @@ void clk_disable(struct clk *clk) int clk_register(struct clk *clk) { - mutex_lock(&clock_list_sem); + down(&clock_list_sem); list_add(&clk->node, &clock_list); kref_init(&clk->kref); - mutex_unlock(&clock_list_sem); + up(&clock_list_sem); return 0; } void clk_unregister(struct clk *clk) { - mutex_lock(&clock_list_sem); + down(&clock_list_sem); list_del(&clk->node); - mutex_unlock(&clock_list_sem); + up(&clock_list_sem); } inline unsigned long clk_get_rate(struct clk *clk) @@ -199,14 +198,14 @@ struct clk *clk_get(const char *id) { struct clk *p, *clk = ERR_PTR(-ENOENT); - mutex_lock(&clock_list_sem); + down(&clock_list_sem); list_for_each_entry(p, &clock_list, node) { if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) { clk = p; break; } } - mutex_unlock(&clock_list_sem); + up(&clock_list_sem); return clk; } @@ -226,7 +225,7 @@ int __init clk_init(void) { int i, ret = 0; - BUG_ON(!master_clk.rate); + BUG_ON(unlikely(!master_clk.rate)); for (i = 0; i < ARRAY_SIZE(onchip_clocks); i++) { struct clk *clk = onchip_clocks[i]; diff --git a/trunk/arch/sh/kernel/cpu/init.c b/trunk/arch/sh/kernel/cpu/init.c index bfb90eb0b7a6..868e68b28880 100644 --- a/trunk/arch/sh/kernel/cpu/init.c +++ b/trunk/arch/sh/kernel/cpu/init.c @@ -4,7 +4,6 @@ * CPU init code * * Copyright (C) 2002, 2003 Paul Mundt - * Copyright (C) 2003 Richard Curnow * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -14,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -53,15 +51,7 @@ static void __init cache_init(void) ccr = ctrl_inl(CCR); /* - * At this point we don't know whether the cache is enabled or not - a - * bootloader may have enabled it. There are at least 2 things that - * could be dirty in the cache at this point: - * 1. kernel command line set up by boot loader - * 2. spilled registers from the prolog of this function - * => before re-initialising the cache, we must do a purge of the whole - * cache out to memory for safety. As long as nothing is spilled - * during the loop to lines that have already been done, this is safe. - * - RPC + * If the cache is already enabled .. flush it. */ if (ccr & CCR_CACHE_ENABLE) { unsigned long ways, waysize, addrstart; @@ -108,8 +98,6 @@ static void __init cache_init(void) /* Force EMODE if possible */ if (cpu_data->dcache.ways > 1) flags |= CCR_CACHE_EMODE; - else - flags &= ~CCR_CACHE_EMODE; #endif #ifdef CONFIG_SH_WRITETHROUGH @@ -124,9 +112,6 @@ static void __init cache_init(void) /* Turn on OCRAM -- halve the OC */ flags |= CCR_CACHE_ORA; cpu_data->dcache.sets >>= 1; - - cpu_data->dcache.way_size = cpu_data->dcache.sets * - cpu_data->dcache.linesz; #endif ctrl_outl(flags, CCR); @@ -199,10 +184,6 @@ asmlinkage void __init sh_cpu_init(void) /* Init the cache */ cache_init(); - shm_align_mask = max_t(unsigned long, - cpu_data->dcache.way_size - 1, - PAGE_SIZE - 1); - /* Disable the FPU */ if (fpu_disabled) { printk("FPU Disabled\n"); diff --git a/trunk/arch/sh/kernel/cpu/irq/Makefile b/trunk/arch/sh/kernel/cpu/irq/Makefile index 1c034c283f59..e3cccea15e1d 100644 --- a/trunk/arch/sh/kernel/cpu/irq/Makefile +++ b/trunk/arch/sh/kernel/cpu/irq/Makefile @@ -3,6 +3,5 @@ # obj-y += ipr.o imask.o -obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o -obj-$(CONFIG_CPU_HAS_MASKREG_IRQ) += maskreg.o -obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o +obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o +obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.o diff --git a/trunk/arch/sh/kernel/cpu/irq/intc2.c b/trunk/arch/sh/kernel/cpu/irq/intc2.c index e30e4b7aa70e..30064bf6e154 100644 --- a/trunk/arch/sh/kernel/cpu/irq/intc2.c +++ b/trunk/arch/sh/kernel/cpu/irq/intc2.c @@ -241,9 +241,9 @@ static struct intc2_init { /* 110-111 reserved/unused */ #elif defined(CONFIG_CPU_SUBTYPE_SH7780) { TIMER_IRQ, 0, 24, 0, INTC_TMU0_MSK, 2}, - { 21, 1, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, - { 22, 1, 1, 0, INTC_RTC_MSK, TIMER_PRIORITY }, - { 23, 1, 2, 0, INTC_RTC_MSK, TIMER_PRIORITY }, +#ifdef CONFIG_SH_RTC + { RTC_IRQ, 4, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, +#endif { SCIF0_ERI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, { SCIF0_RXI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, { SCIF0_BRI_IRQ, 8, 24, 0, INTC_SCIF0_MSK, SCIF0_PRIORITY }, diff --git a/trunk/arch/sh/kernel/cpu/irq/ipr.c b/trunk/arch/sh/kernel/cpu/irq/ipr.c index f785822cd5de..0f545941fb4f 100644 --- a/trunk/arch/sh/kernel/cpu/irq/ipr.c +++ b/trunk/arch/sh/kernel/cpu/irq/ipr.c @@ -57,27 +57,31 @@ static struct hw_interrupt_type ipr_irq_type = { static void disable_ipr_irq(unsigned int irq) { - unsigned long val; + unsigned long val, flags; unsigned int addr = ipr_data[irq].addr; unsigned short mask = 0xffff ^ (0x0f << ipr_data[irq].shift); /* Set the priority in IPR to 0 */ + local_irq_save(flags); val = ctrl_inw(addr); val &= mask; ctrl_outw(val, addr); + local_irq_restore(flags); } static void enable_ipr_irq(unsigned int irq) { - unsigned long val; + unsigned long val, flags; unsigned int addr = ipr_data[irq].addr; int priority = ipr_data[irq].priority; unsigned short value = (priority << ipr_data[irq].shift); /* Set priority in IPR back to original value */ + local_irq_save(flags); val = ctrl_inw(addr); val |= value; ctrl_outw(val, addr); + local_irq_restore(flags); } static void mask_and_ack_ipr(unsigned int irq) @@ -85,7 +89,6 @@ static void mask_and_ack_ipr(unsigned int irq) disable_ipr_irq(irq); #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ - defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) /* This is needed when we use edge triggered setting */ /* XXX: Is it really needed? */ @@ -120,7 +123,7 @@ void __init init_IRQ(void) #ifndef CONFIG_CPU_SUBTYPE_SH7780 make_ipr_irq(TIMER_IRQ, TIMER_IPR_ADDR, TIMER_IPR_POS, TIMER_PRIORITY); make_ipr_irq(TIMER1_IRQ, TIMER1_IPR_ADDR, TIMER1_IPR_POS, TIMER1_PRIORITY); -#ifdef RTC_IRQ +#if defined(CONFIG_SH_RTC) make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); #endif @@ -159,7 +162,6 @@ void __init init_IRQ(void) #endif #if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ - defined(CONFIG_CPU_SUBTYPE_SH7706) || \ defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) /* * Initialize the Interrupt Controller (INTC) @@ -190,8 +192,6 @@ void __init init_IRQ(void) /* Perform the machine specific initialisation */ if (sh_mv.mv_init_irq != NULL) sh_mv.mv_init_irq(); - - irq_ctx_init(smp_processor_id()); } #if !defined(CONFIG_CPU_HAS_PINT_IRQ) diff --git a/trunk/arch/sh/kernel/cpu/irq/pint.c b/trunk/arch/sh/kernel/cpu/irq/pint.c index 17f47b373d6e..80cd8108d36a 100644 --- a/trunk/arch/sh/kernel/cpu/irq/pint.c +++ b/trunk/arch/sh/kernel/cpu/irq/pint.c @@ -48,22 +48,26 @@ static struct hw_interrupt_type pint_irq_type = { static void disable_pint_irq(unsigned int irq) { - unsigned long val; + unsigned long val, flags; + local_irq_save(flags); val = ctrl_inw(INTC_INTER); val &= ~(1 << (irq - PINT_IRQ_BASE)); ctrl_outw(val, INTC_INTER); /* disable PINTn */ portcr_mask &= ~(3 << (irq - PINT_IRQ_BASE)*2); + local_irq_restore(flags); } static void enable_pint_irq(unsigned int irq) { - unsigned long val; + unsigned long val, flags; + local_irq_save(flags); val = ctrl_inw(INTC_INTER); val |= 1 << (irq - PINT_IRQ_BASE); ctrl_outw(val, INTC_INTER); /* enable PINTn */ portcr_mask |= 3 << (irq - PINT_IRQ_BASE)*2; + local_irq_restore(flags); } static void mask_and_ack_pint(unsigned int irq) diff --git a/trunk/arch/sh/kernel/cpu/rtc.c b/trunk/arch/sh/kernel/cpu/rtc.c new file mode 100644 index 000000000000..4304cf75cfa2 --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/rtc.c @@ -0,0 +1,128 @@ +/* + * linux/arch/sh/kernel/rtc.c -- SH3 / SH4 on-chip RTC support + * + * Copyright (C) 2000 Philipp Rumpf + * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka + */ + +#include +#include +#include +#include +#include +#include +#include + +void sh_rtc_gettimeofday(struct timespec *ts) +{ + unsigned int sec128, sec, sec2, min, hr, wk, day, mon, yr, yr100, cf_bit; + unsigned long flags; + + again: + do { + local_irq_save(flags); + ctrl_outb(0, RCR1); /* Clear CF-bit */ + sec128 = ctrl_inb(R64CNT); + sec = ctrl_inb(RSECCNT); + min = ctrl_inb(RMINCNT); + hr = ctrl_inb(RHRCNT); + wk = ctrl_inb(RWKCNT); + day = ctrl_inb(RDAYCNT); + mon = ctrl_inb(RMONCNT); +#if defined(CONFIG_CPU_SH4) + yr = ctrl_inw(RYRCNT); + yr100 = (yr >> 8); + yr &= 0xff; +#else + yr = ctrl_inb(RYRCNT); + yr100 = (yr == 0x99) ? 0x19 : 0x20; +#endif + sec2 = ctrl_inb(R64CNT); + cf_bit = ctrl_inb(RCR1) & RCR1_CF; + local_irq_restore(flags); + } while (cf_bit != 0 || ((sec128 ^ sec2) & RTC_BIT_INVERTED) != 0); + + BCD_TO_BIN(yr100); + BCD_TO_BIN(yr); + BCD_TO_BIN(mon); + BCD_TO_BIN(day); + BCD_TO_BIN(hr); + BCD_TO_BIN(min); + BCD_TO_BIN(sec); + + if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 || + hr > 23 || min > 59 || sec > 59) { + printk(KERN_ERR + "SH RTC: invalid value, resetting to 1 Jan 2000\n"); + local_irq_save(flags); + ctrl_outb(RCR2_RESET, RCR2); /* Reset & Stop */ + ctrl_outb(0, RSECCNT); + ctrl_outb(0, RMINCNT); + ctrl_outb(0, RHRCNT); + ctrl_outb(6, RWKCNT); + ctrl_outb(1, RDAYCNT); + ctrl_outb(1, RMONCNT); +#if defined(CONFIG_CPU_SH4) + ctrl_outw(0x2000, RYRCNT); +#else + ctrl_outb(0, RYRCNT); +#endif + ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start */ + goto again; + } + +#if RTC_BIT_INVERTED != 0 + if ((sec128 & RTC_BIT_INVERTED)) + sec--; +#endif + + ts->tv_sec = mktime(yr100 * 100 + yr, mon, day, hr, min, sec); + ts->tv_nsec = ((sec128 * 1000000) / 128) * 1000; +} + +/* + * Changed to only care about tv_sec, and not the full timespec struct + * (i.e. tv_nsec). It can easily be switched to timespec for future cpus + * that support setting usec or nsec RTC values. + */ +int sh_rtc_settimeofday(const time_t secs) +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + unsigned long flags; + + local_irq_save(flags); + ctrl_outb(RCR2_RESET, RCR2); /* Reset pre-scaler & stop RTC */ + + cmos_minutes = ctrl_inb(RMINCNT); + BCD_TO_BIN(cmos_minutes); + + /* + * since we're only adjusting minutes and seconds, + * don't interfere with hour overflow. This avoids + * messing with unknown time zones but requires your + * RTC not to be off by more than 15 minutes + */ + real_seconds = secs % 60; + real_minutes = secs / 60; + if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + BIN_TO_BCD(real_seconds); + BIN_TO_BCD(real_minutes); + ctrl_outb(real_seconds, RSECCNT); + ctrl_outb(real_minutes, RMINCNT); + } else { + printk(KERN_WARNING + "set_rtc_time: can't update from %d to %d\n", + cmos_minutes, real_minutes); + retval = -1; + } + + ctrl_outb(RCR2_RTCEN|RCR2_START, RCR2); /* Start RTC */ + local_irq_restore(flags); + + return retval; +} diff --git a/trunk/arch/sh/kernel/cpu/sh3/Makefile b/trunk/arch/sh/kernel/cpu/sh3/Makefile index 58d3815695ff..b54dbb9a0c86 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/Makefile +++ b/trunk/arch/sh/kernel/cpu/sh3/Makefile @@ -4,21 +4,10 @@ obj-y := ex.o probe.o -# CPU subtype setup -obj-$(CONFIG_CPU_SUBTYPE_SH7705) += setup-sh7705.o -obj-$(CONFIG_CPU_SUBTYPE_SH7706) += setup-sh7709.o -obj-$(CONFIG_CPU_SUBTYPE_SH7707) += setup-sh7709.o -obj-$(CONFIG_CPU_SUBTYPE_SH7708) += setup-sh7708.o -obj-$(CONFIG_CPU_SUBTYPE_SH7709) += setup-sh7709.o -obj-$(CONFIG_CPU_SUBTYPE_SH7300) += setup-sh7300.o -obj-$(CONFIG_CPU_SUBTYPE_SH7710) += setup-sh7710.o - -# Primary on-chip clocks (common) clock-$(CONFIG_CPU_SH3) := clock-sh3.o clock-$(CONFIG_CPU_SUBTYPE_SH7300) := clock-sh7300.o clock-$(CONFIG_CPU_SUBTYPE_SH7705) := clock-sh7705.o -clock-$(CONFIG_CPU_SUBTYPE_SH7706) := clock-sh7706.o clock-$(CONFIG_CPU_SUBTYPE_SH7709) := clock-sh7709.o -clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7300.o obj-y += $(clock-y) + diff --git a/trunk/arch/sh/kernel/cpu/sh3/clock-sh7706.c b/trunk/arch/sh/kernel/cpu/sh3/clock-sh7706.c deleted file mode 100644 index 0cf96f9833bc..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh3/clock-sh7706.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * arch/sh/kernel/cpu/sh3/clock-sh7706.c - * - * SH7706 support for the clock framework - * - * Copyright (C) 2006 Takashi YOSHII - * - * Based on arch/sh/kernel/cpu/sh3/clock-sh7709.c - * Copyright (C) 2005 Andriy Skulysh - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include - -static int stc_multipliers[] = { 1, 2, 4, 1, 3, 6, 1, 1 }; -static int ifc_divisors[] = { 1, 2, 4, 1, 3, 1, 1, 1 }; -static int pfc_divisors[] = { 1, 2, 4, 1, 3, 6, 1, 1 }; - -static void master_clk_init(struct clk *clk) -{ - int frqcr = ctrl_inw(FRQCR); - int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); - - clk->rate *= pfc_divisors[idx]; -} - -static struct clk_ops sh7706_master_clk_ops = { - .init = master_clk_init, -}; - -static void module_clk_recalc(struct clk *clk) -{ - int frqcr = ctrl_inw(FRQCR); - int idx = ((frqcr & 0x2000) >> 11) | (frqcr & 0x0003); - - clk->rate = clk->parent->rate / pfc_divisors[idx]; -} - -static struct clk_ops sh7706_module_clk_ops = { - .recalc = module_clk_recalc, -}; - -static void bus_clk_recalc(struct clk *clk) -{ - int frqcr = ctrl_inw(FRQCR); - int idx = ((frqcr & 0x8000) >> 13) | ((frqcr & 0x0030) >> 4); - - clk->rate = clk->parent->rate / stc_multipliers[idx]; -} - -static struct clk_ops sh7706_bus_clk_ops = { - .recalc = bus_clk_recalc, -}; - -static void cpu_clk_recalc(struct clk *clk) -{ - int frqcr = ctrl_inw(FRQCR); - int idx = ((frqcr & 0x4000) >> 12) | ((frqcr & 0x000c) >> 2); - - clk->rate = clk->parent->rate / ifc_divisors[idx]; -} - -static struct clk_ops sh7706_cpu_clk_ops = { - .recalc = cpu_clk_recalc, -}; - -static struct clk_ops *sh7706_clk_ops[] = { - &sh7706_master_clk_ops, - &sh7706_module_clk_ops, - &sh7706_bus_clk_ops, - &sh7706_cpu_clk_ops, -}; - -void __init arch_init_clk_ops(struct clk_ops **ops, int idx) -{ - if (idx < ARRAY_SIZE(sh7706_clk_ops)) - *ops = sh7706_clk_ops[idx]; -} diff --git a/trunk/arch/sh/kernel/cpu/sh3/ex.S b/trunk/arch/sh/kernel/cpu/sh3/ex.S index 44daf44833f9..cc04e9e239ff 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/ex.S +++ b/trunk/arch/sh/kernel/cpu/sh3/ex.S @@ -84,12 +84,8 @@ ENTRY(interrupt_table) .long do_IRQ ! rovi .long do_IRQ .long do_IRQ /* 5E0 */ -#if defined(CONFIG_CPU_SUBTYPE_SH7707) || \ - defined(CONFIG_CPU_SUBTYPE_SH7709) || \ - defined(CONFIG_CPU_SUBTYPE_SH7706) || \ - defined(CONFIG_CPU_SUBTYPE_SH7300) || \ - defined(CONFIG_CPU_SUBTYPE_SH7705) || \ - defined(CONFIG_CPU_SUBTYPE_SH7710) +#if defined(CONFIG_CPU_SUBTYPE_SH7707) || defined(CONFIG_CPU_SUBTYPE_SH7709) || \ + defined(CONFIG_CPU_SUBTYPE_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) .long do_IRQ ! 32 IRQ irq0 /* 600 */ .long do_IRQ ! 33 irq1 .long do_IRQ ! 34 irq2 @@ -151,51 +147,6 @@ ENTRY(interrupt_table) .long do_IRQ ! 62 PCC pcc0i .long do_IRQ ! 63 pcc1i /* 9E0 */ #endif -#if defined(CONFIG_CPU_SUBTYPE_SH7710) - .long exception_none ! 61 /* 9A0 */ - .long exception_none ! 62 - .long exception_none ! 63 - .long exception_none ! 64 /* A00 */ - .long exception_none ! 65 - .long exception_none ! 66 - .long exception_none ! 67 - .long exception_none ! 68 - .long exception_none ! 69 - .long exception_none ! 70 - .long exception_none ! 71 - .long exception_none ! 72 /* B00 */ - .long exception_none ! 73 - .long exception_none ! 74 - .long exception_none ! 75 - .long do_IRQ ! 76 DMAC2 dei4 /* B80 */ - .long do_IRQ ! 77 DMAC2 dei5 - .long exception_none ! 78 - .long do_IRQ ! 79 IPSEC ipseci /* BE0 */ - .long do_IRQ ! 80 EDMAC eint0 /* C00 */ - .long do_IRQ ! 81 EDMAC eint1 - .long do_IRQ ! 82 EDMAC eint2 - .long exception_none ! 83 /* C60 */ - .long exception_none ! 84 - .long exception_none ! 85 - .long exception_none ! 86 - .long exception_none ! 87 - .long exception_none ! 88 /* D00 */ - .long exception_none ! 89 - .long exception_none ! 90 - .long exception_none ! 91 - .long exception_none ! 92 - .long exception_none ! 93 - .long exception_none ! 94 - .long exception_none ! 95 - .long do_IRQ ! 96 SIOF eri0 /* E00 */ - .long do_IRQ ! 97 txi0 - .long do_IRQ ! 98 rxi0 - .long do_IRQ ! 99 cci0 - .long do_IRQ ! 100 eri1 /* E80 */ - .long do_IRQ ! 101 txi1 - .long do_IRQ ! 102 rxi2 - .long do_IRQ ! 103 cci3 -#endif #if defined(CONFIG_CPU_SUBTYPE_SH7300) .long do_IRQ ! 64 .long do_IRQ ! 65 @@ -244,3 +195,4 @@ ENTRY(interrupt_table) .long do_IRQ ! 108 #endif #endif + diff --git a/trunk/arch/sh/kernel/cpu/sh3/probe.c b/trunk/arch/sh/kernel/cpu/sh3/probe.c index e67098836290..5cdc88638601 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/probe.c +++ b/trunk/arch/sh/kernel/cpu/sh3/probe.c @@ -72,12 +72,6 @@ int __init detect_cpu_and_cache_system(void) cpu_data->dcache.sets = 256; cpu_data->type = CPU_SH7729; -#if defined(CONFIG_CPU_SUBTYPE_SH7706) - cpu_data->type = CPU_SH7706; -#endif -#if defined(CONFIG_CPU_SUBTYPE_SH7710) - cpu_data->type = CPU_SH7710; -#endif #if defined(CONFIG_CPU_SUBTYPE_SH7705) cpu_data->type = CPU_SH7705; diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7300.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7300.c deleted file mode 100644 index ab4d204bfba5..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7300.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SH7300 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xa4430000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCI, - .irqs = { 80, 80, 80, 80 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7300_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7300_devices_setup(void) -{ - return platform_add_devices(sh7300_devices, - ARRAY_SIZE(sh7300_devices)); -} -__initcall(sh7300_devices_setup); diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c deleted file mode 100644 index a8e41c5241fa..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SH7705 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xa4400000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 52, 53, 55, 54 }, - }, { - .mapbase = 0xa4410000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 56, 57, 59, 58 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7705_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7705_devices_setup(void) -{ - return platform_add_devices(sh7705_devices, - ARRAY_SIZE(sh7705_devices)); -} -__initcall(sh7705_devices_setup); diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7708.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7708.c deleted file mode 100644 index f933723911ca..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7708.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SH7708 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xfffffe80, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCI, - .irqs = { 23, 24, 25, 0 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7708_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7708_devices_setup(void) -{ - return platform_add_devices(sh7708_devices, - ARRAY_SIZE(sh7708_devices)); -} -__initcall(sh7708_devices_setup); diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7709.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7709.c deleted file mode 100644 index ff43ef2a1f0c..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7709.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SH7707/SH7709 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xfffffe80, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCI, - .irqs = { 23, 24, 25, 0 }, - }, { - .mapbase = 0xa4000150, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 56, 57, 59, 58 }, - }, { - .mapbase = 0xa4000140, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_IRDA, - .irqs = { 52, 53, 55, 54 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7709_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7709_devices_setup(void) -{ - return platform_add_devices(sh7709_devices, - ARRAY_SIZE(sh7709_devices)); -} -__initcall(sh7709_devices_setup); diff --git a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c deleted file mode 100644 index 895f99ee6a95..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SH7710 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xa4400000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 52, 53, 55, 54 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7710_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7710_devices_setup(void) -{ - return platform_add_devices(sh7710_devices, - ARRAY_SIZE(sh7710_devices)); -} -__initcall(sh7710_devices_setup); diff --git a/trunk/arch/sh/kernel/cpu/sh4/Makefile b/trunk/arch/sh/kernel/cpu/sh4/Makefile index 8dbf3895ece7..3d5cafc71ae3 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/Makefile +++ b/trunk/arch/sh/kernel/cpu/sh4/Makefile @@ -7,16 +7,6 @@ obj-y := ex.o probe.o obj-$(CONFIG_SH_FPU) += fpu.o obj-$(CONFIG_SH_STORE_QUEUES) += sq.o -# CPU subtype setup -obj-$(CONFIG_CPU_SUBTYPE_SH7750) += setup-sh7750.o -obj-$(CONFIG_CPU_SUBTYPE_SH7751) += setup-sh7750.o -obj-$(CONFIG_CPU_SUBTYPE_SH7760) += setup-sh7760.o -obj-$(CONFIG_CPU_SUBTYPE_SH7770) += setup-sh7770.o -obj-$(CONFIG_CPU_SUBTYPE_SH7780) += setup-sh7780.o -obj-$(CONFIG_CPU_SUBTYPE_SH73180) += setup-sh73180.o -obj-$(CONFIG_CPU_SUBTYPE_SH7343) += setup-sh7343.o -obj-$(CONFIG_CPU_SUBTYPE_SH4_202) += setup-sh4-202.o - # Primary on-chip clocks (common) clock-$(CONFIG_CPU_SH4) := clock-sh4.o clock-$(CONFIG_CPU_SUBTYPE_SH73180) := clock-sh73180.o diff --git a/trunk/arch/sh/kernel/cpu/sh4/ex.S b/trunk/arch/sh/kernel/cpu/sh4/ex.S index 7146893a6cca..26a27df06505 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/ex.S +++ b/trunk/arch/sh/kernel/cpu/sh4/ex.S @@ -72,7 +72,6 @@ ENTRY(interrupt_table) .long do_IRQ ! 1110 .long exception_error ! Internal hardware -#ifndef CONFIG_CPU_SUBTYPE_SH7780 .long do_IRQ ! TMU0 tuni0 /* 400 */ .long do_IRQ ! TMU1 tuni1 .long do_IRQ ! TMU2 tuni2 @@ -123,13 +122,6 @@ ENTRY(interrupt_table) .long do_IRQ ! 45 dmte5 .long do_IRQ ! 46 dmte6 .long do_IRQ ! 47 dmte7 /* 7E0 */ -#elif defined(CONFIG_CPU_SUBTYPE_SH7343) - .long do_IRQ ! 44 IIC1 ali /* 780 */ - .long do_IRQ ! 45 tacki - .long do_IRQ ! 46 waiti - .long do_IRQ ! 47 dtei /* 7E0 */ - .long do_IRQ ! 48 DMAC dei0 /* 800 */ - .long do_IRQ ! 49 dei1 /* 820 */ #else .long exception_error ! 44 /* 780 */ .long exception_error ! 45 @@ -139,8 +131,7 @@ ENTRY(interrupt_table) #if defined(CONFIG_SH_FPU) .long do_fpu_state_restore ! 48 /* 800 */ .long do_fpu_state_restore ! 49 /* 820 */ -#elif !defined(CONFIG_CPU_SUBTYPE_SH7343) && \ - !defined(CONFIG_CPU_SUBTYPE_SH73180) +#else .long exception_error .long exception_error #endif @@ -233,7 +224,7 @@ ENTRY(interrupt_table) .long exception_error .long do_IRQ ! ADC adi .long do_IRQ ! CMT cmti /* FA0 */ -#elif defined(CONFIG_CPU_SUBTYPE_SH73180) || defined(CONFIG_CPU_SUBTYPE_SH7343) +#elif defined(CONFIG_CPU_SUBTYPE_SH73180) .long do_IRQ ! 50 0x840 .long do_IRQ ! 51 0x860 .long do_IRQ ! 52 0x880 @@ -388,168 +379,5 @@ ENTRY(interrupt_table) .long exception_error ! 141 0x13a0 .long exception_error ! 142 0x13c0 .long exception_error ! 143 0x13e0 -#elif defined(CONFIG_CPU_SUBTYPE_SH7770) - .long do_IRQ ! 50 0x840 - .long do_IRQ ! 51 0x860 - .long do_IRQ ! 52 0x880 - .long do_IRQ ! 53 0x8a0 - .long do_IRQ ! 54 0x8c0 - .long do_IRQ ! 55 0x8e0 - .long do_IRQ ! 56 0x900 - .long do_IRQ ! 57 0x920 - .long do_IRQ ! 58 0x940 - .long do_IRQ ! 59 0x960 - .long do_IRQ ! 60 0x980 - .long do_IRQ ! 61 0x9a0 - .long do_IRQ ! 62 0x9c0 - .long do_IRQ ! 63 0x9e0 - .long do_IRQ ! 64 0xa00 - .long do_IRQ ! 65 0xa20 - .long do_IRQ ! 66 0xa4d - .long do_IRQ ! 67 0xa60 - .long do_IRQ ! 68 0xa80 - .long do_IRQ ! 69 0xaa0 - .long do_IRQ ! 70 0xac0 - .long do_IRQ ! 71 0xae0 - .long do_IRQ ! 72 0xb00 - .long do_IRQ ! 73 0xb20 - .long do_IRQ ! 74 0xb40 - .long do_IRQ ! 75 0xb60 - .long do_IRQ ! 76 0xb80 - .long do_IRQ ! 77 0xba0 - .long do_IRQ ! 78 0xbc0 - .long do_IRQ ! 79 0xbe0 - .long do_IRQ ! 80 0xc00 - .long do_IRQ ! 81 0xc20 - .long do_IRQ ! 82 0xc40 - .long do_IRQ ! 83 0xc60 - .long do_IRQ ! 84 0xc80 - .long do_IRQ ! 85 0xca0 - .long do_IRQ ! 86 0xcc0 - .long do_IRQ ! 87 0xce0 - .long do_IRQ ! 88 0xd00 - .long do_IRQ ! 89 0xd20 - .long do_IRQ ! 90 0xd40 - .long do_IRQ ! 91 0xd60 - .long do_IRQ ! 92 0xd80 - .long do_IRQ ! 93 0xda0 - .long do_IRQ ! 94 0xdc0 - .long do_IRQ ! 95 0xde0 - .long do_IRQ ! 96 0xe00 - .long do_IRQ ! 97 0xe20 - .long do_IRQ ! 98 0xe40 - .long do_IRQ ! 99 0xe60 - .long do_IRQ ! 100 0xe80 - .long do_IRQ ! 101 0xea0 - .long do_IRQ ! 102 0xec0 - .long do_IRQ ! 103 0xee0 - .long do_IRQ ! 104 0xf00 - .long do_IRQ ! 105 0xf20 - .long do_IRQ ! 106 0xf40 - .long do_IRQ ! 107 0xf60 - .long do_IRQ ! 108 0xf80 -#endif -#else - .long exception_error /* 400 */ - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! RTC ati - .long do_IRQ ! pri - .long do_IRQ ! cui - .long exception_error - .long exception_error /* 500 */ - .long exception_error - .long exception_error - .long do_IRQ ! WDT iti /* 560 */ - .long do_IRQ ! TMU-ch0 - .long do_IRQ ! TMU-ch1 - .long do_IRQ ! TMU-ch2 - .long do_IRQ ! ticpi2 /* 5E0 */ - .long do_IRQ ! 32 Hitachi UDI /* 600 */ - .long exception_error - .long do_IRQ ! 34 DMAC dmte0 - .long do_IRQ ! 35 dmte1 - .long do_IRQ ! 36 dmte2 - .long do_IRQ ! 37 dmte3 - .long do_IRQ ! 38 dmae - .long exception_error ! 39 /* 6E0 */ - .long do_IRQ ! 40 SCIF-ch0 eri /* 700 */ - .long do_IRQ ! 41 rxi - .long do_IRQ ! 42 bri - .long do_IRQ ! 43 txi - .long do_IRQ ! 44 DMAC dmte4 /* 780 */ - .long do_IRQ ! 45 dmte5 - .long do_IRQ ! 46 dmte6 - .long do_IRQ ! 47 dmte7 /* 7E0 */ -#if defined(CONFIG_SH_FPU) - .long do_fpu_state_restore ! 48 /* 800 */ - .long do_fpu_state_restore ! 49 /* 820 */ -#else - .long exception_error - .long exception_error -#endif - .long exception_error /* 840 */ - .long exception_error - .long exception_error - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! 56 CMT /* 900 */ - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! 60 HAC - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! PCI serr /* A00 */ - .long do_IRQ ! INTA - .long do_IRQ ! INTB - .long do_IRQ ! INTC - .long do_IRQ ! INTD - .long do_IRQ ! err - .long do_IRQ ! pwd3 - .long do_IRQ ! pwd2 - .long do_IRQ ! pwd1 /* B00 */ - .long do_IRQ ! pwd0 - .long exception_error - .long exception_error - .long do_IRQ ! SCIF-ch1 eri /* B80 */ - .long do_IRQ ! rxi - .long do_IRQ ! bri - .long do_IRQ ! txi - .long do_IRQ ! SIOF /* C00 */ - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! HSPI /* C80 */ - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! MMCIF fatat /* D00 */ - .long do_IRQ ! tran - .long do_IRQ ! err - .long do_IRQ ! frdy - .long do_IRQ ! DMAC dmint8 /* D80 */ - .long do_IRQ ! dmint9 - .long do_IRQ ! dmint10 - .long do_IRQ ! dmint11 - .long do_IRQ ! TMU-ch3 /* E00 */ - .long do_IRQ ! TMU-ch4 - .long do_IRQ ! TMU-ch5 - .long exception_error - .long do_IRQ ! SSI - .long exception_error - .long exception_error - .long exception_error - .long do_IRQ ! FLCTL flste /* F00 */ - .long do_IRQ ! fltend - .long do_IRQ ! fltrq0 - .long do_IRQ ! fltrq1 - .long do_IRQ ! GPIO gpioi0 /* F80 */ - .long do_IRQ ! gpioi1 - .long do_IRQ ! gpioi2 - .long do_IRQ ! gpioi3 #endif diff --git a/trunk/arch/sh/kernel/cpu/sh4/probe.c b/trunk/arch/sh/kernel/cpu/sh4/probe.c index c294de1e14a3..42427b79697b 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/probe.c +++ b/trunk/arch/sh/kernel/cpu/sh4/probe.c @@ -3,7 +3,7 @@ * * CPU Subtype Probing for SH-4. * - * Copyright (C) 2001 - 2006 Paul Mundt + * Copyright (C) 2001, 2002, 2003, 2004 Paul Mundt * Copyright (C) 2003 Richard Curnow * * This file is subject to the terms and conditions of the GNU General Public @@ -29,7 +29,7 @@ int __init detect_cpu_and_cache_system(void) [9] = (1 << 16) }; - pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffffff; + pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffff; prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff; cvr = (ctrl_inl(CCN_CVR)); @@ -38,6 +38,7 @@ int __init detect_cpu_and_cache_system(void) */ cpu_data->icache.way_incr = (1 << 13); cpu_data->icache.entry_shift = 5; + cpu_data->icache.entry_mask = 0x1fe0; cpu_data->icache.sets = 256; cpu_data->icache.ways = 1; cpu_data->icache.linesz = L1_CACHE_BYTES; @@ -47,29 +48,13 @@ int __init detect_cpu_and_cache_system(void) */ cpu_data->dcache.way_incr = (1 << 14); cpu_data->dcache.entry_shift = 5; + cpu_data->dcache.entry_mask = 0x3fe0; cpu_data->dcache.sets = 512; cpu_data->dcache.ways = 1; cpu_data->dcache.linesz = L1_CACHE_BYTES; - /* - * Setup some generic flags we can probe - * (L2 and DSP detection only work on SH-4A) - */ - if (((pvr >> 16) & 0xff) == 0x10) { - if ((cvr & 0x02000000) == 0) - cpu_data->flags |= CPU_HAS_L2_CACHE; - if ((cvr & 0x10000000) == 0) - cpu_data->flags |= CPU_HAS_DSP; - - cpu_data->flags |= CPU_HAS_LLSC; - } - - /* FPU detection works for everyone */ - if ((cvr & 0x20000000) == 1) - cpu_data->flags |= CPU_HAS_FPU; - - /* Mask off the upper chip ID */ - pvr &= 0xffff; + /* Set the FPU flag, virtually all SH-4's have one */ + cpu_data->flags |= CPU_HAS_FPU; /* * Probe the underlying processor version/revision and @@ -78,101 +63,56 @@ int __init detect_cpu_and_cache_system(void) switch (pvr) { case 0x205: cpu_data->type = CPU_SH7750; - cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | - CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA; + cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_PERF_COUNTER; break; case 0x206: cpu_data->type = CPU_SH7750S; - cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | - CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA; + cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_PERF_COUNTER; break; case 0x1100: cpu_data->type = CPU_SH7751; - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; break; case 0x2000: cpu_data->type = CPU_SH73180; cpu_data->icache.ways = 4; cpu_data->dcache.ways = 4; - cpu_data->flags |= CPU_HAS_LLSC; - break; - case 0x2001: - case 0x2004: - cpu_data->type = CPU_SH7770; - cpu_data->icache.ways = 4; - cpu_data->dcache.ways = 4; - - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_LLSC; - break; - case 0x2006: - case 0x200A: - if (prr == 0x61) - cpu_data->type = CPU_SH7781; - else - cpu_data->type = CPU_SH7780; - - cpu_data->icache.ways = 4; - cpu_data->dcache.ways = 4; - - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PERF_COUNTER | - CPU_HAS_LLSC; - break; - case 0x3000: - case 0x3003: - cpu_data->type = CPU_SH7343; - cpu_data->icache.ways = 4; - cpu_data->dcache.ways = 4; - cpu_data->flags |= CPU_HAS_LLSC; + cpu_data->flags &= ~CPU_HAS_FPU; break; case 0x8000: cpu_data->type = CPU_ST40RA; - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; break; case 0x8100: cpu_data->type = CPU_ST40GX1; - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; break; case 0x700: cpu_data->type = CPU_SH4_501; cpu_data->icache.ways = 2; cpu_data->dcache.ways = 2; - cpu_data->flags |= CPU_HAS_PTEA; + + /* No FPU on the SH4-500 series.. */ + cpu_data->flags &= ~CPU_HAS_FPU; break; case 0x600: cpu_data->type = CPU_SH4_202; cpu_data->icache.ways = 2; cpu_data->dcache.ways = 2; - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; break; case 0x500 ... 0x501: switch (prr) { - case 0x10: - cpu_data->type = CPU_SH7750R; - break; - case 0x11: - cpu_data->type = CPU_SH7751R; - break; - case 0x50 ... 0x5f: - cpu_data->type = CPU_SH7760; - break; + case 0x10: cpu_data->type = CPU_SH7750R; break; + case 0x11: cpu_data->type = CPU_SH7751R; break; + case 0x50: cpu_data->type = CPU_SH7760; break; } cpu_data->icache.ways = 2; cpu_data->dcache.ways = 2; - cpu_data->flags |= CPU_HAS_FPU | CPU_HAS_PTEA; - break; default: cpu_data->type = CPU_SH_NONE; break; } -#ifdef CONFIG_SH_DIRECT_MAPPED - cpu_data->icache.ways = 1; - cpu_data->dcache.ways = 1; -#endif - /* * On anything that's not a direct-mapped cache, look to the CVR * for I/D-cache specifics. @@ -181,56 +121,18 @@ int __init detect_cpu_and_cache_system(void) size = sizes[(cvr >> 20) & 0xf]; cpu_data->icache.way_incr = (size >> 1); cpu_data->icache.sets = (size >> 6); - + cpu_data->icache.entry_mask = + (cpu_data->icache.way_incr - (1 << 5)); } - /* Setup the rest of the I-cache info */ - cpu_data->icache.entry_mask = cpu_data->icache.way_incr - - cpu_data->icache.linesz; - - cpu_data->icache.way_size = cpu_data->icache.sets * - cpu_data->icache.linesz; - - /* And the rest of the D-cache */ if (cpu_data->dcache.ways > 1) { size = sizes[(cvr >> 16) & 0xf]; cpu_data->dcache.way_incr = (size >> 1); cpu_data->dcache.sets = (size >> 6); - } - - cpu_data->dcache.entry_mask = cpu_data->dcache.way_incr - - cpu_data->dcache.linesz; - - cpu_data->dcache.way_size = cpu_data->dcache.sets * - cpu_data->dcache.linesz; - - /* - * Setup the L2 cache desc - * - * SH-4A's have an optional PIPT L2. - */ - if (cpu_data->flags & CPU_HAS_L2_CACHE) { - /* - * Size calculation is much more sensible - * than it is for the L1. - * - * Sizes are 128KB, 258KB, 512KB, and 1MB. - */ - size = (cvr & 0xf) << 17; - - BUG_ON(!size); - - cpu_data->scache.way_incr = (1 << 16); - cpu_data->scache.entry_shift = 5; - cpu_data->scache.ways = 4; - cpu_data->scache.linesz = L1_CACHE_BYTES; - cpu_data->scache.entry_mask = - (cpu_data->scache.way_incr - cpu_data->scache.linesz); - cpu_data->scache.sets = size / - (cpu_data->scache.linesz * cpu_data->scache.ways); - cpu_data->scache.way_size = - (cpu_data->scache.sets * cpu_data->scache.linesz); + cpu_data->dcache.entry_mask = + (cpu_data->dcache.way_incr - (1 << 5)); } return 0; } + diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh4-202.c deleted file mode 100644 index 6e4e96541358..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SH4-202 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe80000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 41, 43, 42 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh4202_devices[] __initdata = { - &sci_device, -}; - -static int __init sh4202_devices_setup(void) -{ - return platform_add_devices(sh4202_devices, - ARRAY_SIZE(sh4202_devices)); -} -__initcall(sh4202_devices_setup); diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh73180.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh73180.c deleted file mode 100644 index cc9ea1e2e5df..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh73180.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SH73180 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe80000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 81, 83, 82 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh73180_devices[] __initdata = { - &sci_device, -}; - -static int __init sh73180_devices_setup(void) -{ - return platform_add_devices(sh73180_devices, - ARRAY_SIZE(sh73180_devices)); -} -__initcall(sh73180_devices_setup); diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7343.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7343.c deleted file mode 100644 index 91d61cf91ba1..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7343.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SH7343 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 81, 83, 82 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7343_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7343_devices_setup(void) -{ - return platform_add_devices(sh7343_devices, - ARRAY_SIZE(sh7343_devices)); -} -__initcall(sh7343_devices_setup); diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c deleted file mode 100644 index 50812d57c1c1..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SH7750/SH7751 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCI, - .irqs = { 23, 24, 25, 0 }, - }, { - .mapbase = 0xffe80000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 41, 43, 42 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7750_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7750_devices_setup(void) -{ - return platform_add_devices(sh7750_devices, - ARRAY_SIZE(sh7750_devices)); -} -__initcall(sh7750_devices_setup); diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c deleted file mode 100644 index 97f1c9af35d6..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SH7760 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xfe600000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 52, 53, 55, 54 }, - }, { - .mapbase = 0xfe610000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 72, 73, 75, 74 }, - }, { - .mapbase = 0xfe620000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 76, 77, 79, 78 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7760_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7760_devices_setup(void) -{ - return platform_add_devices(sh7760_devices, - ARRAY_SIZE(sh7760_devices)); -} -__initcall(sh7760_devices_setup); diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7770.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7770.c deleted file mode 100644 index 6a04cc5f5aca..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7770.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SH7770 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xff923000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 61, 61, 61, 61 }, - }, { - .mapbase = 0xff924000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 62, 62, 62, 62 }, - }, { - .mapbase = 0xff925000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 63, 63, 63, 63 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7770_devices[] __initdata = { - &sci_device, -}; - -static int __init sh7770_devices_setup(void) -{ - return platform_add_devices(sh7770_devices, - ARRAY_SIZE(sh7770_devices)); -} -__initcall(sh7770_devices_setup); diff --git a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c deleted file mode 100644 index 72493f259edc..000000000000 --- a/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * SH7780 Setup - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -static struct resource rtc_resources[] = { - [0] = { - .start = 0xffe80000, - .end = 0xffe80000 + 0x58 - 1, - .flags = IORESOURCE_IO, - }, - [1] = { - /* Period IRQ */ - .start = 21, - .flags = IORESOURCE_IRQ, - }, - [2] = { - /* Carry IRQ */ - .start = 22, - .flags = IORESOURCE_IRQ, - }, - [3] = { - /* Alarm IRQ */ - .start = 23, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device rtc_device = { - .name = "sh-rtc", - .id = -1, - .num_resources = ARRAY_SIZE(rtc_resources), - .resource = rtc_resources, -}; - -static struct plat_sci_port sci_platform_data[] = { - { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 41, 43, 42 }, - }, { - .mapbase = 0xffe10000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 76, 77, 79, 78 }, - }, { - .flags = 0, - } -}; - -static struct platform_device sci_device = { - .name = "sh-sci", - .id = -1, - .dev = { - .platform_data = sci_platform_data, - }, -}; - -static struct platform_device *sh7780_devices[] __initdata = { - &rtc_device, - &sci_device, -}; - -static int __init sh7780_devices_setup(void) -{ - return platform_add_devices(sh7780_devices, - ARRAY_SIZE(sh7780_devices)); -} -__initcall(sh7780_devices_setup); diff --git a/trunk/arch/sh/kernel/cpu/sh4/sq.c b/trunk/arch/sh/kernel/cpu/sh4/sq.c index 7bcc73f9b8df..b09805f3ee23 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/sq.c +++ b/trunk/arch/sh/kernel/cpu/sh4/sq.c @@ -1,52 +1,49 @@ /* - * arch/sh/kernel/cpu/sh4/sq.c + * arch/sh/kernel/cpu/sq.c * * General management API for SH-4 integrated Store Queues * - * Copyright (C) 2001 - 2006 Paul Mundt + * Copyright (C) 2001, 2002, 2003, 2004 Paul Mundt * Copyright (C) 2001, 2002 M. R. Brown * + * Some of this code has been adopted directly from the old arch/sh/mm/sq.c + * hack that was part of the LinuxDC project. For all intents and purposes, + * this is a completely new interface that really doesn't have much in common + * with the old zone-based approach at all. In fact, it's only listed here for + * general completeness. + * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ #include -#include -#include -#include #include #include #include +#include +#include +#include #include -#include + #include #include -#include +#include #include -struct sq_mapping; - -struct sq_mapping { - const char *name; - - unsigned long sq_addr; - unsigned long addr; - unsigned int size; - - struct sq_mapping *next; -}; - -static struct sq_mapping *sq_mapping_list; +static LIST_HEAD(sq_mapping_list); static DEFINE_SPINLOCK(sq_mapping_lock); -static kmem_cache_t *sq_cache; -static unsigned long *sq_bitmap; -#define store_queue_barrier() \ -do { \ - (void)ctrl_inl(P4SEG_STORE_QUE); \ - ctrl_outl(0, P4SEG_STORE_QUE + 0); \ - ctrl_outl(0, P4SEG_STORE_QUE + 8); \ -} while (0); +/** + * sq_flush - Flush (prefetch) the store queue cache + * @addr: the store queue address to flush + * + * Executes a prefetch instruction on the specified store queue cache, + * so that the cached data is written to physical memory. + */ +inline void sq_flush(void *addr) +{ + __asm__ __volatile__ ("pref @%0" : : "r" (addr) : "memory"); +} /** * sq_flush_range - Flush (prefetch) a specific SQ range @@ -59,73 +56,152 @@ do { \ void sq_flush_range(unsigned long start, unsigned int len) { volatile unsigned long *sq = (unsigned long *)start; + unsigned long dummy; /* Flush the queues */ for (len >>= 5; len--; sq += 8) - prefetchw((void *)sq); + sq_flush((void *)sq); /* Wait for completion */ - store_queue_barrier(); + dummy = ctrl_inl(P4SEG_STORE_QUE); + + ctrl_outl(0, P4SEG_STORE_QUE + 0); + ctrl_outl(0, P4SEG_STORE_QUE + 8); } -static inline void sq_mapping_list_add(struct sq_mapping *map) +static struct sq_mapping *__sq_alloc_mapping(unsigned long virt, unsigned long phys, unsigned long size, const char *name) { - struct sq_mapping **p, *tmp; + struct sq_mapping *map; - spin_lock_irq(&sq_mapping_lock); + if (virt + size > SQ_ADDRMAX) + return ERR_PTR(-ENOSPC); - p = &sq_mapping_list; - while ((tmp = *p) != NULL) - p = &tmp->next; + map = kmalloc(sizeof(struct sq_mapping), GFP_KERNEL); + if (!map) + return ERR_PTR(-ENOMEM); - map->next = tmp; - *p = map; + INIT_LIST_HEAD(&map->list); - spin_unlock_irq(&sq_mapping_lock); -} + map->sq_addr = virt; + map->addr = phys; + map->size = size + 1; + map->name = name; -static inline void sq_mapping_list_del(struct sq_mapping *map) -{ - struct sq_mapping **p, *tmp; + list_add(&map->list, &sq_mapping_list); - spin_lock_irq(&sq_mapping_lock); + return map; +} - for (p = &sq_mapping_list; (tmp = *p); p = &tmp->next) - if (tmp == map) { - *p = tmp->next; - break; +static unsigned long __sq_get_next_addr(void) +{ + if (!list_empty(&sq_mapping_list)) { + struct list_head *pos, *tmp; + + /* + * Read one off the list head, as it will have the highest + * mapped allocation. Set the next one up right above it. + * + * This is somewhat sub-optimal, as we don't look at + * gaps between allocations or anything lower then the + * highest-level allocation. + * + * However, in the interest of performance and the general + * lack of desire to do constant list rebalancing, we don't + * worry about it. + */ + list_for_each_safe(pos, tmp, &sq_mapping_list) { + struct sq_mapping *entry; + + entry = list_entry(pos, typeof(*entry), list); + + return entry->sq_addr + entry->size; } + } - spin_unlock_irq(&sq_mapping_lock); + return P4SEG_STORE_QUE; } -static int __sq_remap(struct sq_mapping *map, unsigned long flags) +/** + * __sq_remap - Perform a translation from the SQ to a phys addr + * @map: sq mapping containing phys and store queue addresses. + * + * Maps the store queue address specified in the mapping to the physical + * address specified in the mapping. + */ +static struct sq_mapping *__sq_remap(struct sq_mapping *map) { -#if defined(CONFIG_MMU) + unsigned long flags, pteh, ptel; struct vm_struct *vma; + pgprot_t pgprot; + + /* + * Without an MMU (or with it turned off), this is much more + * straightforward, as we can just load up each queue's QACR with + * the physical address appropriately masked. + */ + + ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0); + ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1); +#ifdef CONFIG_MMU + /* + * With an MMU on the other hand, things are slightly more involved. + * Namely, we have to have a direct mapping between the SQ addr and + * the associated physical address in the UTLB by way of setting up + * a virt<->phys translation by hand. We do this by simply specifying + * the SQ addr in UTLB.VPN and the associated physical address in + * UTLB.PPN. + * + * Notably, even though this is a special case translation, and some + * of the configuration bits are meaningless, we're still required + * to have a valid ASID context in PTEH. + * + * We could also probably get by without explicitly setting PTEA, but + * we do it here just for good measure. + */ + spin_lock_irqsave(&sq_mapping_lock, flags); + + pteh = map->sq_addr; + ctrl_outl((pteh & MMU_VPN_MASK) | get_asid(), MMU_PTEH); + + ptel = map->addr & PAGE_MASK; + ctrl_outl(((ptel >> 28) & 0xe) | (ptel & 0x1), MMU_PTEA); + + pgprot = pgprot_noncached(PAGE_KERNEL); + + ptel &= _PAGE_FLAGS_HARDWARE_MASK; + ptel |= pgprot_val(pgprot); + ctrl_outl(ptel, MMU_PTEL); + + __asm__ __volatile__ ("ldtlb" : : : "memory"); + + spin_unlock_irqrestore(&sq_mapping_lock, flags); + + /* + * Next, we need to map ourselves in the kernel page table, so that + * future accesses after a TLB flush will be handled when we take a + * page fault. + * + * Theoretically we could just do this directly and not worry about + * setting up the translation by hand ahead of time, but for the + * cases where we want a one-shot SQ mapping followed by a quick + * writeout before we hit the TLB flush, we do it anyways. This way + * we at least save ourselves the initial page fault overhead. + */ vma = __get_vm_area(map->size, VM_ALLOC, map->sq_addr, SQ_ADDRMAX); if (!vma) - return -ENOMEM; + return ERR_PTR(-ENOMEM); vma->phys_addr = map->addr; if (remap_area_pages((unsigned long)vma->addr, vma->phys_addr, - map->size, flags)) { + map->size, pgprot_val(pgprot))) { vunmap(vma->addr); - return -EAGAIN; + return NULL; } -#else - /* - * Without an MMU (or with it turned off), this is much more - * straightforward, as we can just load up each queue's QACR with - * the physical address appropriately masked. - */ - ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR0); - ctrl_outl(((map->addr >> 26) << 2) & 0x1c, SQ_QACR1); -#endif +#endif /* CONFIG_MMU */ - return 0; + return map; } /** @@ -133,65 +209,42 @@ static int __sq_remap(struct sq_mapping *map, unsigned long flags) * @phys: Physical address of mapping. * @size: Length of mapping. * @name: User invoking mapping. - * @flags: Protection flags. * * Remaps the physical address @phys through the next available store queue * address of @size length. @name is logged at boot time as well as through - * the sysfs interface. + * the procfs interface. + * + * A pre-allocated and filled sq_mapping pointer is returned, and must be + * cleaned up with a call to sq_unmap() when the user is done with the + * mapping. */ -unsigned long sq_remap(unsigned long phys, unsigned int size, - const char *name, unsigned long flags) +struct sq_mapping *sq_remap(unsigned long phys, unsigned int size, const char *name) { struct sq_mapping *map; - unsigned long end; + unsigned long virt, end; unsigned int psz; - int ret, page; /* Don't allow wraparound or zero size */ end = phys + size - 1; - if (unlikely(!size || end < phys)) - return -EINVAL; + if (!size || end < phys) + return NULL; /* Don't allow anyone to remap normal memory.. */ - if (unlikely(phys < virt_to_phys(high_memory))) - return -EINVAL; + if (phys < virt_to_phys(high_memory)) + return NULL; phys &= PAGE_MASK; - size = PAGE_ALIGN(end + 1) - phys; - - map = kmem_cache_alloc(sq_cache, GFP_KERNEL); - if (unlikely(!map)) - return -ENOMEM; - - map->addr = phys; - map->size = size; - map->name = name; - - page = bitmap_find_free_region(sq_bitmap, 0x04000000, - get_order(map->size)); - if (unlikely(page < 0)) { - ret = -ENOSPC; - goto out; - } - - map->sq_addr = P4SEG_STORE_QUE + (page << PAGE_SHIFT); - - ret = __sq_remap(map, flags); - if (unlikely(ret != 0)) - goto out; - - psz = (size + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - pr_info("sqremap: %15s [%4d page%s] va 0x%08lx pa 0x%08lx\n", - likely(map->name) ? map->name : "???", - psz, psz == 1 ? " " : "s", - map->sq_addr, map->addr); - sq_mapping_list_add(map); + size = PAGE_ALIGN(end + 1) - phys; + virt = __sq_get_next_addr(); + psz = (size + (PAGE_SIZE - 1)) / PAGE_SIZE; + map = __sq_alloc_mapping(virt, phys, size, name); - return map->sq_addr; + printk("sqremap: %15s [%4d page%s] va 0x%08lx pa 0x%08lx\n", + map->name ? map->name : "???", + psz, psz == 1 ? " " : "s", + map->sq_addr, map->addr); -out: - kmem_cache_free(sq_cache, map); - return ret; + return __sq_remap(map); } /** @@ -202,198 +255,188 @@ unsigned long sq_remap(unsigned long phys, unsigned int size, * sq_remap(). Also frees up the pte that was previously inserted into * the kernel page table and discards the UTLB translation. */ -void sq_unmap(unsigned long vaddr) +void sq_unmap(struct sq_mapping *map) { - struct sq_mapping **p, *map; - struct vm_struct *vma; - int page; + if (map->sq_addr > (unsigned long)high_memory) + vfree((void *)(map->sq_addr & PAGE_MASK)); - for (p = &sq_mapping_list; (map = *p); p = &map->next) - if (map->sq_addr == vaddr) - break; - - if (unlikely(!map)) { - printk("%s: bad store queue address 0x%08lx\n", - __FUNCTION__, vaddr); - return; - } + list_del(&map->list); + kfree(map); +} - page = (map->sq_addr - P4SEG_STORE_QUE) >> PAGE_SHIFT; - bitmap_release_region(sq_bitmap, page, get_order(map->size)); +/** + * sq_clear - Clear a store queue range + * @addr: Address to start clearing from. + * @len: Length to clear. + * + * A quick zero-fill implementation for clearing out memory that has been + * remapped through the store queues. + */ +void sq_clear(unsigned long addr, unsigned int len) +{ + int i; -#ifdef CONFIG_MMU - vma = remove_vm_area((void *)(map->sq_addr & PAGE_MASK)); - if (!vma) { - printk(KERN_ERR "%s: bad address 0x%08lx\n", - __FUNCTION__, map->sq_addr); - return; + /* Clear out both queues linearly */ + for (i = 0; i < 8; i++) { + ctrl_outl(0, addr + i + 0); + ctrl_outl(0, addr + i + 8); } -#endif - - sq_mapping_list_del(map); - kmem_cache_free(sq_cache, map); + sq_flush_range(addr, len); } -/* - * Needlessly complex sysfs interface. Unfortunately it doesn't seem like - * there is any other easy way to add things on a per-cpu basis without - * putting the directory entries somewhere stupid and having to create - * links in sysfs by hand back in to the per-cpu directories. +/** + * sq_vma_unmap - Unmap a VMA range + * @area: VMA containing range. + * @addr: Start of range. + * @len: Length of range. * - * Some day we may want to have an additional abstraction per store - * queue, but considering the kobject hell we already have to deal with, - * it's simply not worth the trouble. + * Searches the sq_mapping_list for a mapping matching the sq addr @addr, + * and subsequently frees up the entry. Further cleanup is done by generic + * code. */ -static struct kobject *sq_kobject[NR_CPUS]; - -struct sq_sysfs_attr { - struct attribute attr; - ssize_t (*show)(char *buf); - ssize_t (*store)(const char *buf, size_t count); -}; - -#define to_sq_sysfs_attr(attr) container_of(attr, struct sq_sysfs_attr, attr) - -static ssize_t sq_sysfs_show(struct kobject *kobj, struct attribute *attr, - char *buf) +static void sq_vma_unmap(struct vm_area_struct *area, + unsigned long addr, size_t len) { - struct sq_sysfs_attr *sattr = to_sq_sysfs_attr(attr); + struct list_head *pos, *tmp; - if (likely(sattr->show)) - return sattr->show(buf); + list_for_each_safe(pos, tmp, &sq_mapping_list) { + struct sq_mapping *entry; - return -EIO; -} + entry = list_entry(pos, typeof(*entry), list); -static ssize_t sq_sysfs_store(struct kobject *kobj, struct attribute *attr, - const char *buf, size_t count) -{ - struct sq_sysfs_attr *sattr = to_sq_sysfs_attr(attr); + if (entry->sq_addr == addr) { + /* + * We could probably get away without doing the tlb flush + * here, as generic code should take care of most of this + * when unmapping the rest of the VMA range for us. Leave + * it in for added sanity for the time being.. + */ + __flush_tlb_page(get_asid(), entry->sq_addr & PAGE_MASK); - if (likely(sattr->store)) - return sattr->store(buf, count); + list_del(&entry->list); + kfree(entry); - return -EIO; + return; + } + } } -static ssize_t mapping_show(char *buf) +/** + * sq_vma_sync - Sync a VMA range + * @area: VMA containing range. + * @start: Start of range. + * @len: Length of range. + * @flags: Additional flags. + * + * Synchronizes an sq mapped range by flushing the store queue cache for + * the duration of the mapping. + * + * Used internally for user mappings, which must use msync() to prefetch + * the store queue cache. + */ +static int sq_vma_sync(struct vm_area_struct *area, + unsigned long start, size_t len, unsigned int flags) { - struct sq_mapping **list, *entry; - char *p = buf; - - for (list = &sq_mapping_list; (entry = *list); list = &entry->next) - p += sprintf(p, "%08lx-%08lx [%08lx]: %s\n", - entry->sq_addr, entry->sq_addr + entry->size, - entry->addr, entry->name); + sq_flush_range(start, len); - return p - buf; + return 0; } -static ssize_t mapping_store(const char *buf, size_t count) +static struct vm_operations_struct sq_vma_ops = { + .unmap = sq_vma_unmap, + .sync = sq_vma_sync, +}; + +/** + * sq_mmap - mmap() for /dev/cpu/sq + * @file: unused. + * @vma: VMA to remap. + * + * Remap the specified vma @vma through the store queues, and setup associated + * information for the new mapping. Also build up the page tables for the new + * area. + */ +static int sq_mmap(struct file *file, struct vm_area_struct *vma) { - unsigned long base = 0, len = 0; + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + unsigned long size = vma->vm_end - vma->vm_start; + struct sq_mapping *map; - sscanf(buf, "%lx %lx", &base, &len); - if (!base) - return -EIO; + /* + * We're not interested in any arbitrary virtual address that has + * been stuck in the VMA, as we already know what addresses we + * want. Save off the size, and reposition the VMA to begin at + * the next available sq address. + */ + vma->vm_start = __sq_get_next_addr(); + vma->vm_end = vma->vm_start + size; - if (likely(len)) { - int ret = sq_remap(base, len, "Userspace", - pgprot_val(PAGE_SHARED)); - if (ret < 0) - return ret; - } else - sq_unmap(base); + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - return count; -} + vma->vm_flags |= VM_IO | VM_RESERVED; -static struct sq_sysfs_attr mapping_attr = - __ATTR(mapping, 0644, mapping_show, mapping_store); + map = __sq_alloc_mapping(vma->vm_start, offset, size, "Userspace"); -static struct attribute *sq_sysfs_attrs[] = { - &mapping_attr.attr, - NULL, -}; + if (io_remap_pfn_range(vma, map->sq_addr, map->addr >> PAGE_SHIFT, + size, vma->vm_page_prot)) + return -EAGAIN; -static struct sysfs_ops sq_sysfs_ops = { - .show = sq_sysfs_show, - .store = sq_sysfs_store, -}; + vma->vm_ops = &sq_vma_ops; -static struct kobj_type ktype_percpu_entry = { - .sysfs_ops = &sq_sysfs_ops, - .default_attrs = sq_sysfs_attrs, -}; + return 0; +} -static int __devinit sq_sysdev_add(struct sys_device *sysdev) +#ifdef CONFIG_PROC_FS +static int sq_mapping_read_proc(char *buf, char **start, off_t off, + int len, int *eof, void *data) { - unsigned int cpu = sysdev->id; - struct kobject *kobj; - - sq_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL); - if (unlikely(!sq_kobject[cpu])) - return -ENOMEM; + struct list_head *pos; + char *p = buf; - kobj = sq_kobject[cpu]; - kobj->parent = &sysdev->kobj; - kobject_set_name(kobj, "%s", "sq"); - kobj->ktype = &ktype_percpu_entry; + list_for_each_prev(pos, &sq_mapping_list) { + struct sq_mapping *entry; - return kobject_register(kobj); -} + entry = list_entry(pos, typeof(*entry), list); -static int __devexit sq_sysdev_remove(struct sys_device *sysdev) -{ - unsigned int cpu = sysdev->id; - struct kobject *kobj = sq_kobject[cpu]; + p += sprintf(p, "%08lx-%08lx [%08lx]: %s\n", entry->sq_addr, + entry->sq_addr + entry->size - 1, entry->addr, + entry->name); + } - kobject_unregister(kobj); - return 0; + return p - buf; } +#endif -static struct sysdev_driver sq_sysdev_driver = { - .add = sq_sysdev_add, - .remove = __devexit_p(sq_sysdev_remove), +static struct file_operations sq_fops = { + .owner = THIS_MODULE, + .mmap = sq_mmap, +}; + +static struct miscdevice sq_dev = { + .minor = STORE_QUEUE_MINOR, + .name = "sq", + .fops = &sq_fops, }; static int __init sq_api_init(void) { - unsigned int nr_pages = 0x04000000 >> PAGE_SHIFT; - unsigned int size = (nr_pages + (BITS_PER_LONG - 1)) / BITS_PER_LONG; - int ret = -ENOMEM; - + int ret; printk(KERN_NOTICE "sq: Registering store queue API.\n"); - sq_cache = kmem_cache_create("store_queue_cache", - sizeof(struct sq_mapping), 0, 0, - NULL, NULL); - if (unlikely(!sq_cache)) - return ret; + create_proc_read_entry("sq_mapping", 0, 0, sq_mapping_read_proc, 0); - sq_bitmap = kzalloc(size, GFP_KERNEL); - if (unlikely(!sq_bitmap)) - goto out; - - ret = sysdev_driver_register(&cpu_sysdev_class, &sq_sysdev_driver); - if (unlikely(ret != 0)) - goto out; - - return 0; - -out: - kfree(sq_bitmap); - kmem_cache_destroy(sq_cache); + ret = misc_register(&sq_dev); + if (ret) + remove_proc_entry("sq_mapping", NULL); return ret; } static void __exit sq_api_exit(void) { - sysdev_driver_unregister(&cpu_sysdev_class, &sq_sysdev_driver); - kfree(sq_bitmap); - kmem_cache_destroy(sq_cache); + misc_deregister(&sq_dev); + remove_proc_entry("sq_mapping", NULL); } module_init(sq_api_init); @@ -402,7 +445,11 @@ module_exit(sq_api_exit); MODULE_AUTHOR("Paul Mundt , M. R. Brown "); MODULE_DESCRIPTION("Simple API for SH-4 integrated Store Queues"); MODULE_LICENSE("GPL"); +MODULE_ALIAS_MISCDEV(STORE_QUEUE_MINOR); EXPORT_SYMBOL(sq_remap); EXPORT_SYMBOL(sq_unmap); +EXPORT_SYMBOL(sq_clear); +EXPORT_SYMBOL(sq_flush); EXPORT_SYMBOL(sq_flush_range); + diff --git a/trunk/arch/sh/kernel/early_printk.c b/trunk/arch/sh/kernel/early_printk.c index a00022722e9e..1378db375e17 100644 --- a/trunk/arch/sh/kernel/early_printk.c +++ b/trunk/arch/sh/kernel/early_printk.c @@ -3,7 +3,7 @@ * * Copyright (C) 1999, 2000 Niibe Yutaka * Copyright (C) 2002 M. R. Brown - * Copyright (C) 2004 - 2006 Paul Mundt + * Copyright (C) 2004 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -49,7 +49,7 @@ static int __init sh_console_setup(struct console *co, char *options) return 0; } -static struct console bios_console = { +static struct console early_console = { .name = "bios", .write = sh_console_write, .setup = sh_console_setup, @@ -59,43 +59,34 @@ static struct console bios_console = { #endif #ifdef CONFIG_EARLY_SCIF_CONSOLE -#include -#include "../../../drivers/serial/sh-sci.h" - -#ifdef CONFIG_CPU_SH4 #define SCIF_REG 0xffe80000 -#elif defined(CONFIG_CPU_SUBTYPE_SH72060) -#define SCIF_REG 0xfffe9800 -#else -#error "Undefined SCIF for this subtype" -#endif - -static struct uart_port scif_port = { - .mapbase = SCIF_REG, - .membase = (char __iomem *)SCIF_REG, -}; static void scif_sercon_putc(int c) { - while (((sci_in(&scif_port, SCFDR) & 0x1f00 >> 8) == 16)) - ; + while (!(ctrl_inw(SCIF_REG + 0x10) & 0x20)) ; - sci_out(&scif_port, SCxTDR, c); - sci_in(&scif_port, SCxSR); - sci_out(&scif_port, SCxSR, 0xf3 & ~(0x20 | 0x40)); - - while ((sci_in(&scif_port, SCxSR) & 0x40) == 0); - ; + ctrl_outb(c, SCIF_REG + 12); + ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0x9f), SCIF_REG + 0x10); if (c == '\n') scif_sercon_putc('\r'); } -static void scif_sercon_write(struct console *con, const char *s, - unsigned count) +static void scif_sercon_flush(void) +{ + ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10); + + while (!(ctrl_inw(SCIF_REG + 0x10) & 0x40)) ; + + ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0xbf), SCIF_REG + 0x10); +} + +static void scif_sercon_write(struct console *con, const char *s, unsigned count) { while (count-- > 0) scif_sercon_putc(*s++); + + scif_sercon_flush(); } static int __init scif_sercon_setup(struct console *con, char *options) @@ -105,7 +96,7 @@ static int __init scif_sercon_setup(struct console *con, char *options) return 0; } -static struct console scif_console = { +static struct console early_console = { .name = "sercon", .write = scif_sercon_write, .setup = scif_sercon_setup, @@ -113,7 +104,7 @@ static struct console scif_console = { .index = -1, }; -static void scif_sercon_init(int baud) +void scif_sercon_init(int baud) { ctrl_outw(0, SCIF_REG + 8); ctrl_outw(0, SCIF_REG); @@ -131,61 +122,16 @@ static void scif_sercon_init(int baud) } #endif -/* - * Setup a default console, if more than one is compiled in, rely on the - * earlyprintk= parsing to give priority. - */ -static struct console *early_console = -#ifdef CONFIG_SH_STANDARD_BIOS - &bios_console -#elif defined(CONFIG_EARLY_SCIF_CONSOLE) - &scif_console -#else - NULL -#endif - ; - -static int __initdata keep_early; - -int __init setup_early_printk(char *opt) +void __init enable_early_printk(void) { - char *space; - char buf[256]; - - strlcpy(buf, opt, sizeof(buf)); - space = strchr(buf, ' '); - if (space) - *space = 0; - - if (strstr(buf, "keep")) - keep_early = 1; - -#ifdef CONFIG_SH_STANDARD_BIOS - if (!strncmp(buf, "bios", 4)) - early_console = &bios_console; -#endif -#if defined(CONFIG_EARLY_SCIF_CONSOLE) - if (!strncmp(buf, "serial", 6)) { - early_console = &scif_console; - -#ifdef CONFIG_CPU_SH4 - scif_sercon_init(115200); -#endif - } +#ifdef CONFIG_EARLY_SCIF_CONSOLE + scif_sercon_init(115200); #endif - - if (likely(early_console)) - register_console(early_console); - - return 1; + register_console(&early_console); } -__setup("earlyprintk=", setup_early_printk); -void __init disable_early_printk(void) +void disable_early_printk(void) { - if (!keep_early) { - printk("disabling early console\n"); - unregister_console(early_console); - } else - printk("keeping early console\n"); + unregister_console(&early_console); } + diff --git a/trunk/arch/sh/kernel/entry.S b/trunk/arch/sh/kernel/entry.S index fe8221855b28..7dfd2ba75f7f 100644 --- a/trunk/arch/sh/kernel/entry.S +++ b/trunk/arch/sh/kernel/entry.S @@ -18,6 +18,24 @@ #include #include +#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE) +#define sys_nfsservctl sys_ni_syscall +#endif + +#if !defined(CONFIG_MMU) +#define sys_madvise sys_ni_syscall +#define sys_readahead sys_ni_syscall +#define sys_mprotect sys_ni_syscall +#define sys_msync sys_ni_syscall +#define sys_mlock sys_ni_syscall +#define sys_munlock sys_ni_syscall +#define sys_mlockall sys_ni_syscall +#define sys_munlockall sys_ni_syscall +#define sys_mremap sys_ni_syscall +#define sys_mincore sys_ni_syscall +#define sys_remap_file_pages sys_ni_syscall +#endif + ! NOTE: ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address ! to be jumped is too far, but it causes illegal slot exception. @@ -308,7 +326,7 @@ ENTRY(exception_error) .align 2 ret_from_exception: preempt_stop() -ENTRY(ret_from_irq) +ret_from_irq: ! mov #OFF_SR, r0 mov.l @(r0,r15), r0 ! get status register @@ -371,12 +389,11 @@ work_pending: ! r8: current_thread_info ! t: result of "tst #_TIF_NEED_RESCHED, r0" bf/s work_resched - tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0 + tst #_TIF_SIGPENDING, r0 work_notifysig: bt/s restore_all mov r15, r4 - mov r12, r5 ! set arg1(save_r0) - mov r0, r6 + mov #0, r5 mov.l 2f, r1 mova restore_all, r0 jmp @r1 @@ -414,7 +431,7 @@ work_resched: .align 2 1: .long schedule -2: .long do_notify_resume +2: .long do_signal .align 2 syscall_exit_work: @@ -535,7 +552,6 @@ syscall_call: mov.l @r9, r8 jsr @r8 ! jump to specific syscall handler nop - mov.l @(OFF_R0,r15), r12 ! save r0 mov.l r0, @(OFF_R0,r15) ! save the return value ! syscall_exit: @@ -628,7 +644,7 @@ skip_restore: ! #if defined(CONFIG_KGDB_NMI) ! Clear in_nmi - mov.l 6f, k0 + mov.l 4f, k0 mov #0, k1 mov.b k1, @k0 #endif @@ -706,7 +722,7 @@ interrupt: ! ! .align 2 -ENTRY(handle_exception) +handle_exception: ! Using k0, k1 for scratch registers (r0_bank1, r1_bank), ! save all registers onto stack. ! @@ -716,8 +732,8 @@ ENTRY(handle_exception) bt/s 1f ! It's a kernel to kernel transition. mov r15, k0 ! save original stack to k0 /* User space to kernel */ - mov #(THREAD_SIZE >> 8), k1 - shll8 k1 ! k1 := THREAD_SIZE + mov #0x20, k1 + shll8 k1 ! k1 := 8192 (== THREAD_SIZE) add current, k1 mov k1, r15 ! change to kernel stack ! @@ -822,3 +838,300 @@ ENTRY(exception_none) rts nop + .data +ENTRY(sys_call_table) + .long sys_ni_syscall /* 0 - old "setup()" system call*/ + .long sys_exit + .long sys_fork + .long sys_read + .long sys_write + .long sys_open /* 5 */ + .long sys_close + .long sys_waitpid + .long sys_creat + .long sys_link + .long sys_unlink /* 10 */ + .long sys_execve + .long sys_chdir + .long sys_time + .long sys_mknod + .long sys_chmod /* 15 */ + .long sys_lchown16 + .long sys_ni_syscall /* old break syscall holder */ + .long sys_stat + .long sys_lseek + .long sys_getpid /* 20 */ + .long sys_mount + .long sys_oldumount + .long sys_setuid16 + .long sys_getuid16 + .long sys_stime /* 25 */ + .long sys_ptrace + .long sys_alarm + .long sys_fstat + .long sys_pause + .long sys_utime /* 30 */ + .long sys_ni_syscall /* old stty syscall holder */ + .long sys_ni_syscall /* old gtty syscall holder */ + .long sys_access + .long sys_nice + .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */ + .long sys_sync + .long sys_kill + .long sys_rename + .long sys_mkdir + .long sys_rmdir /* 40 */ + .long sys_dup + .long sys_pipe + .long sys_times + .long sys_ni_syscall /* old prof syscall holder */ + .long sys_brk /* 45 */ + .long sys_setgid16 + .long sys_getgid16 + .long sys_signal + .long sys_geteuid16 + .long sys_getegid16 /* 50 */ + .long sys_acct + .long sys_umount /* recycled never used phys() */ + .long sys_ni_syscall /* old lock syscall holder */ + .long sys_ioctl + .long sys_fcntl /* 55 */ + .long sys_ni_syscall /* old mpx syscall holder */ + .long sys_setpgid + .long sys_ni_syscall /* old ulimit syscall holder */ + .long sys_ni_syscall /* sys_olduname */ + .long sys_umask /* 60 */ + .long sys_chroot + .long sys_ustat + .long sys_dup2 + .long sys_getppid + .long sys_getpgrp /* 65 */ + .long sys_setsid + .long sys_sigaction + .long sys_sgetmask + .long sys_ssetmask + .long sys_setreuid16 /* 70 */ + .long sys_setregid16 + .long sys_sigsuspend + .long sys_sigpending + .long sys_sethostname + .long sys_setrlimit /* 75 */ + .long sys_old_getrlimit + .long sys_getrusage + .long sys_gettimeofday + .long sys_settimeofday + .long sys_getgroups16 /* 80 */ + .long sys_setgroups16 + .long sys_ni_syscall /* sys_oldselect */ + .long sys_symlink + .long sys_lstat + .long sys_readlink /* 85 */ + .long sys_uselib + .long sys_swapon + .long sys_reboot + .long old_readdir + .long old_mmap /* 90 */ + .long sys_munmap + .long sys_truncate + .long sys_ftruncate + .long sys_fchmod + .long sys_fchown16 /* 95 */ + .long sys_getpriority + .long sys_setpriority + .long sys_ni_syscall /* old profil syscall holder */ + .long sys_statfs + .long sys_fstatfs /* 100 */ + .long sys_ni_syscall /* ioperm */ + .long sys_socketcall + .long sys_syslog + .long sys_setitimer + .long sys_getitimer /* 105 */ + .long sys_newstat + .long sys_newlstat + .long sys_newfstat + .long sys_uname + .long sys_ni_syscall /* 110 */ /* iopl */ + .long sys_vhangup + .long sys_ni_syscall /* idle */ + .long sys_ni_syscall /* vm86old */ + .long sys_wait4 + .long sys_swapoff /* 115 */ + .long sys_sysinfo + .long sys_ipc + .long sys_fsync + .long sys_sigreturn + .long sys_clone /* 120 */ + .long sys_setdomainname + .long sys_newuname + .long sys_ni_syscall /* sys_modify_ldt */ + .long sys_adjtimex + .long sys_mprotect /* 125 */ + .long sys_sigprocmask + .long sys_ni_syscall /* old "create_module" */ + .long sys_init_module + .long sys_delete_module + .long sys_ni_syscall /* 130: old "get_kernel_syms" */ + .long sys_quotactl + .long sys_getpgid + .long sys_fchdir + .long sys_bdflush + .long sys_sysfs /* 135 */ + .long sys_personality + .long sys_ni_syscall /* for afs_syscall */ + .long sys_setfsuid16 + .long sys_setfsgid16 + .long sys_llseek /* 140 */ + .long sys_getdents + .long sys_select + .long sys_flock + .long sys_msync + .long sys_readv /* 145 */ + .long sys_writev + .long sys_getsid + .long sys_fdatasync + .long sys_sysctl + .long sys_mlock /* 150 */ + .long sys_munlock + .long sys_mlockall + .long sys_munlockall + .long sys_sched_setparam + .long sys_sched_getparam /* 155 */ + .long sys_sched_setscheduler + .long sys_sched_getscheduler + .long sys_sched_yield + .long sys_sched_get_priority_max + .long sys_sched_get_priority_min /* 160 */ + .long sys_sched_rr_get_interval + .long sys_nanosleep + .long sys_mremap + .long sys_setresuid16 + .long sys_getresuid16 /* 165 */ + .long sys_ni_syscall /* vm86 */ + .long sys_ni_syscall /* old "query_module" */ + .long sys_poll + .long sys_nfsservctl + .long sys_setresgid16 /* 170 */ + .long sys_getresgid16 + .long sys_prctl + .long sys_rt_sigreturn + .long sys_rt_sigaction + .long sys_rt_sigprocmask /* 175 */ + .long sys_rt_sigpending + .long sys_rt_sigtimedwait + .long sys_rt_sigqueueinfo + .long sys_rt_sigsuspend + .long sys_pread_wrapper /* 180 */ + .long sys_pwrite_wrapper + .long sys_chown16 + .long sys_getcwd + .long sys_capget + .long sys_capset /* 185 */ + .long sys_sigaltstack + .long sys_sendfile + .long sys_ni_syscall /* streams1 */ + .long sys_ni_syscall /* streams2 */ + .long sys_vfork /* 190 */ + .long sys_getrlimit + .long sys_mmap2 + .long sys_truncate64 + .long sys_ftruncate64 + .long sys_stat64 /* 195 */ + .long sys_lstat64 + .long sys_fstat64 + .long sys_lchown + .long sys_getuid + .long sys_getgid /* 200 */ + .long sys_geteuid + .long sys_getegid + .long sys_setreuid + .long sys_setregid + .long sys_getgroups /* 205 */ + .long sys_setgroups + .long sys_fchown + .long sys_setresuid + .long sys_getresuid + .long sys_setresgid /* 210 */ + .long sys_getresgid + .long sys_chown + .long sys_setuid + .long sys_setgid + .long sys_setfsuid /* 215 */ + .long sys_setfsgid + .long sys_pivot_root + .long sys_mincore + .long sys_madvise + .long sys_getdents64 /* 220 */ + .long sys_fcntl64 + .long sys_ni_syscall /* reserved for TUX */ + .long sys_ni_syscall /* Reserved for Security */ + .long sys_gettid + .long sys_readahead /* 225 */ + .long sys_setxattr + .long sys_lsetxattr + .long sys_fsetxattr + .long sys_getxattr + .long sys_lgetxattr /* 230 */ + .long sys_fgetxattr + .long sys_listxattr + .long sys_llistxattr + .long sys_flistxattr + .long sys_removexattr /* 235 */ + .long sys_lremovexattr + .long sys_fremovexattr + .long sys_tkill + .long sys_sendfile64 + .long sys_futex /* 240 */ + .long sys_sched_setaffinity + .long sys_sched_getaffinity + .long sys_ni_syscall + .long sys_ni_syscall + .long sys_io_setup /* 245 */ + .long sys_io_destroy + .long sys_io_getevents + .long sys_io_submit + .long sys_io_cancel + .long sys_fadvise64 /* 250 */ + .long sys_ni_syscall + .long sys_exit_group + .long sys_lookup_dcookie + .long sys_epoll_create + .long sys_epoll_ctl /* 255 */ + .long sys_epoll_wait + .long sys_remap_file_pages + .long sys_set_tid_address + .long sys_timer_create + .long sys_timer_settime /* 260 */ + .long sys_timer_gettime + .long sys_timer_getoverrun + .long sys_timer_delete + .long sys_clock_settime + .long sys_clock_gettime /* 265 */ + .long sys_clock_getres + .long sys_clock_nanosleep + .long sys_statfs64 + .long sys_fstatfs64 + .long sys_tgkill /* 270 */ + .long sys_utimes + .long sys_fadvise64_64_wrapper + .long sys_ni_syscall /* Reserved for vserver */ + .long sys_ni_syscall /* Reserved for mbind */ + .long sys_ni_syscall /* 275 - get_mempolicy */ + .long sys_ni_syscall /* set_mempolicy */ + .long sys_mq_open + .long sys_mq_unlink + .long sys_mq_timedsend + .long sys_mq_timedreceive /* 280 */ + .long sys_mq_notify + .long sys_mq_getsetattr + .long sys_ni_syscall /* Reserved for kexec */ + .long sys_waitid + .long sys_add_key /* 285 */ + .long sys_request_key + .long sys_keyctl + .long sys_ioprio_set + .long sys_ioprio_get + .long sys_inotify_init /* 290 */ + .long sys_inotify_add_watch + .long sys_inotify_rm_watch + +/* End of entry.S */ diff --git a/trunk/arch/sh/kernel/head.S b/trunk/arch/sh/kernel/head.S index f5f53d14f245..9b9e6ef626ce 100644 --- a/trunk/arch/sh/kernel/head.S +++ b/trunk/arch/sh/kernel/head.S @@ -11,18 +11,6 @@ * Head.S contains the SH exception handlers and startup code. */ #include -#include - -#ifdef CONFIG_CPU_SH4A -#define SYNCO() synco - -#define PREFI(label, reg) \ - mov.l label, reg; \ - prefi @reg -#else -#define SYNCO() -#define PREFI(label, reg) -#endif .section .empty_zero_page, "aw" ENTRY(empty_zero_page) @@ -54,25 +42,18 @@ ENTRY(_stext) ! Initialize global interrupt mask mov #0, r0 ldc r0, r6_bank - - /* - * Prefetch if possible to reduce cache miss penalty. - * - * We do this early on for SH-4A as a micro-optimization, - * as later on we will have speculative execution enabled - * and this will become less of an issue. - */ - PREFI(5f, r0) - PREFI(6f, r0) - ! mov.l 2f, r0 mov r0, r15 ! Set initial r15 (stack pointer) - mov #(THREAD_SIZE >> 8), r1 - shll8 r1 ! r1 = THREAD_SIZE + mov #0x20, r1 ! + shll8 r1 ! r1 = 8192 sub r1, r0 ! ldc r0, r7_bank ! ... and initial thread_info - + ! + ! Additional CPU initialization + mov.l 6f, r0 + jsr @r0 + nop ! Clear BSS area mov.l 3f, r1 add #4, r1 @@ -81,14 +62,6 @@ ENTRY(_stext) 9: cmp/hs r2, r1 bf/s 9b ! while (r1 < r2) mov.l r0,@-r2 - - ! Additional CPU initialization - mov.l 6f, r0 - jsr @r0 - nop - - SYNCO() ! Wait for pending instructions.. - ! Start kernel mov.l 5f, r0 jmp @r0 @@ -96,7 +69,7 @@ ENTRY(_stext) .balign 4 1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF -2: .long init_thread_union+THREAD_SIZE +2: .long stack 3: .long __bss_start 4: .long _end 5: .long start_kernel diff --git a/trunk/arch/sh/kernel/io.c b/trunk/arch/sh/kernel/io.c index 501fe03e3715..71c9fde2fd90 100644 --- a/trunk/arch/sh/kernel/io.c +++ b/trunk/arch/sh/kernel/io.c @@ -61,73 +61,6 @@ void memset_io(volatile void __iomem *dst, int c, unsigned long count) } EXPORT_SYMBOL(memset_io); -void __raw_readsl(unsigned long addr, void *datap, int len) -{ - u32 *data; - - for (data = datap; (len != 0) && (((u32)data & 0x1f) != 0); len--) - *data++ = ctrl_inl(addr); - - if (likely(len >= (0x20 >> 2))) { - int tmp2, tmp3, tmp4, tmp5, tmp6; - - __asm__ __volatile__( - "1: \n\t" - "mov.l @%7, r0 \n\t" - "mov.l @%7, %2 \n\t" -#ifdef CONFIG_CPU_SH4 - "movca.l r0, @%0 \n\t" -#else - "mov.l r0, @%0 \n\t" -#endif - "mov.l @%7, %3 \n\t" - "mov.l @%7, %4 \n\t" - "mov.l @%7, %5 \n\t" - "mov.l @%7, %6 \n\t" - "mov.l @%7, r7 \n\t" - "mov.l @%7, r0 \n\t" - "mov.l %2, @(0x04,%0) \n\t" - "mov #0x20>>2, %2 \n\t" - "mov.l %3, @(0x08,%0) \n\t" - "sub %2, %1 \n\t" - "mov.l %4, @(0x0c,%0) \n\t" - "cmp/hi %1, %2 ! T if 32 > len \n\t" - "mov.l %5, @(0x10,%0) \n\t" - "mov.l %6, @(0x14,%0) \n\t" - "mov.l r7, @(0x18,%0) \n\t" - "mov.l r0, @(0x1c,%0) \n\t" - "bf.s 1b \n\t" - " add #0x20, %0 \n\t" - : "=&r" (data), "=&r" (len), - "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4), - "=&r" (tmp5), "=&r" (tmp6) - : "r"(addr), "0" (data), "1" (len) - : "r0", "r7", "t", "memory"); - } - - for (; len != 0; len--) - *data++ = ctrl_inl(addr); -} -EXPORT_SYMBOL(__raw_readsl); - -void __raw_writesl(unsigned long addr, const void *data, int len) -{ - if (likely(len != 0)) { - int tmp1; - - __asm__ __volatile__ ( - "1: \n\t" - "mov.l @%0+, %1 \n\t" - "dt %3 \n\t" - "bf.s 1b \n\t" - " mov.l %1, @%4 \n\t" - : "=&r" (data), "=&r" (tmp1) - : "0" (data), "r" (len), "r"(addr) - : "t", "memory"); - } -} -EXPORT_SYMBOL(__raw_writesl); - void __iomem *ioport_map(unsigned long port, unsigned int nr) { return sh_mv.mv_ioport_map(port, nr); diff --git a/trunk/arch/sh/kernel/irq.c b/trunk/arch/sh/kernel/irq.c index c7ebd6aec951..c2e07f7f3496 100644 --- a/trunk/arch/sh/kernel/irq.c +++ b/trunk/arch/sh/kernel/irq.c @@ -1,4 +1,5 @@ -/* +/* $Id: irq.c,v 1.20 2004/01/13 05:52:11 kkojima Exp $ + * * linux/arch/sh/kernel/irq.c * * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar @@ -6,15 +7,13 @@ * * SuperH version: Copyright (C) 1999 Niibe Yutaka */ + #include #include -#include #include #include #include #include -#include -#include #include /* @@ -61,46 +60,15 @@ int show_interrupts(struct seq_file *p, void *v) } #endif -#ifdef CONFIG_4KSTACKS -/* - * per-CPU IRQ handling contexts (thread information and stack) - */ -union irq_ctx { - struct thread_info tinfo; - u32 stack[THREAD_SIZE/sizeof(u32)]; -}; - -static union irq_ctx *hardirq_ctx[NR_CPUS]; -static union irq_ctx *softirq_ctx[NR_CPUS]; -#endif asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs regs) { int irq = r4; -#ifdef CONFIG_4KSTACKS - union irq_ctx *curctx, *irqctx; -#endif irq_enter(); -#ifdef CONFIG_DEBUG_STACKOVERFLOW - /* Debugging check for stack overflow: is there less than 1KB free? */ - { - long sp; - - __asm__ __volatile__ ("and r15, %0" : - "=r" (sp) : "0" (THREAD_SIZE - 1)); - - if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) { - printk("do_IRQ: stack overflow: %ld\n", - sp - sizeof(struct thread_info)); - dump_stack(); - } - } -#endif - #ifdef CONFIG_CPU_HAS_INTEVT __asm__ __volatile__ ( #ifdef CONFIG_CPU_HAS_SR_RB @@ -119,135 +87,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, #endif irq = irq_demux(irq); - -#ifdef CONFIG_4KSTACKS - curctx = (union irq_ctx *)current_thread_info(); - irqctx = hardirq_ctx[smp_processor_id()]; - - /* - * this is where we switch to the IRQ stack. However, if we are - * already using the IRQ stack (because we interrupted a hardirq - * handler) we can't do that and just have to keep using the - * current stack (which is the irq stack already after all) - */ - if (curctx != irqctx) { - u32 *isp; - - isp = (u32 *)((char *)irqctx + sizeof(*irqctx)); - irqctx->tinfo.task = curctx->tinfo.task; - irqctx->tinfo.previous_sp = current_stack_pointer; - - __asm__ __volatile__ ( - "mov %0, r4 \n" - "mov %1, r5 \n" - "mov r15, r9 \n" - "jsr @%2 \n" - /* swith to the irq stack */ - " mov %3, r15 \n" - /* restore the stack (ring zero) */ - "mov r9, r15 \n" - : /* no outputs */ - : "r" (irq), "r" (®s), "r" (__do_IRQ), "r" (isp) - /* XXX: A somewhat excessive clobber list? -PFM */ - : "memory", "r0", "r1", "r2", "r3", "r4", - "r5", "r6", "r7", "r8", "t", "pr" - ); - } else -#endif - __do_IRQ(irq, ®s); - + __do_IRQ(irq, ®s); irq_exit(); - return 1; } - -#ifdef CONFIG_4KSTACKS -/* - * These should really be __section__(".bss.page_aligned") as well, but - * gcc's 3.0 and earlier don't handle that correctly. - */ -static char softirq_stack[NR_CPUS * THREAD_SIZE] - __attribute__((__aligned__(THREAD_SIZE))); - -static char hardirq_stack[NR_CPUS * THREAD_SIZE] - __attribute__((__aligned__(THREAD_SIZE))); - -/* - * allocate per-cpu stacks for hardirq and for softirq processing - */ -void irq_ctx_init(int cpu) -{ - union irq_ctx *irqctx; - - if (hardirq_ctx[cpu]) - return; - - irqctx = (union irq_ctx *)&hardirq_stack[cpu * THREAD_SIZE]; - irqctx->tinfo.task = NULL; - irqctx->tinfo.exec_domain = NULL; - irqctx->tinfo.cpu = cpu; - irqctx->tinfo.preempt_count = HARDIRQ_OFFSET; - irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); - - hardirq_ctx[cpu] = irqctx; - - irqctx = (union irq_ctx *)&softirq_stack[cpu * THREAD_SIZE]; - irqctx->tinfo.task = NULL; - irqctx->tinfo.exec_domain = NULL; - irqctx->tinfo.cpu = cpu; - irqctx->tinfo.preempt_count = SOFTIRQ_OFFSET; - irqctx->tinfo.addr_limit = MAKE_MM_SEG(0); - - softirq_ctx[cpu] = irqctx; - - printk("CPU %u irqstacks, hard=%p soft=%p\n", - cpu, hardirq_ctx[cpu], softirq_ctx[cpu]); -} - -void irq_ctx_exit(int cpu) -{ - hardirq_ctx[cpu] = NULL; -} - -extern asmlinkage void __do_softirq(void); - -asmlinkage void do_softirq(void) -{ - unsigned long flags; - struct thread_info *curctx; - union irq_ctx *irqctx; - u32 *isp; - - if (in_interrupt()) - return; - - local_irq_save(flags); - - if (local_softirq_pending()) { - curctx = current_thread_info(); - irqctx = softirq_ctx[smp_processor_id()]; - irqctx->tinfo.task = curctx->task; - irqctx->tinfo.previous_sp = current_stack_pointer; - - /* build the stack frame on the softirq stack */ - isp = (u32 *)((char *)irqctx + sizeof(*irqctx)); - - __asm__ __volatile__ ( - "mov r15, r9 \n" - "jsr @%0 \n" - /* switch to the softirq stack */ - " mov %1, r15 \n" - /* restore the thread stack */ - "mov r9, r15 \n" - : /* no outputs */ - : "r" (__do_softirq), "r" (isp) - /* XXX: A somewhat excessive clobber list? -PFM */ - : "memory", "r0", "r1", "r2", "r3", "r4", - "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr" - ); - } - - local_irq_restore(flags); -} -EXPORT_SYMBOL(do_softirq); -#endif diff --git a/trunk/arch/sh/kernel/kgdb_stub.c b/trunk/arch/sh/kernel/kgdb_stub.c index 9c6315f0335d..42638b92b51c 100644 --- a/trunk/arch/sh/kernel/kgdb_stub.c +++ b/trunk/arch/sh/kernel/kgdb_stub.c @@ -101,17 +101,16 @@ #include #include -#ifdef CONFIG_SH_KGDB_CONSOLE -#include -#endif - #include #include #include #include #include #include -#include + +#ifdef CONFIG_SH_KGDB_CONSOLE +#include +#endif /* Function pointers for linkage */ kgdb_debug_hook_t *kgdb_debug_hook; @@ -241,6 +240,7 @@ static jmp_buf rem_com_env; /* Misc static */ static int stepped_address; static short stepped_opcode; +static const char hexchars[] = "0123456789abcdef"; static char in_buffer[BUFMAX]; static char out_buffer[OUTBUFMAX]; @@ -253,6 +253,29 @@ typedef unsigned char threadref[8]; #define BUF_THREAD_ID_SIZE 16 #endif +/* Return addr as a real volatile address */ +static inline unsigned int ctrl_inl(const unsigned long addr) +{ + return *(volatile unsigned long *) addr; +} + +/* Correctly set *addr using volatile */ +static inline void ctrl_outl(const unsigned int b, unsigned long addr) +{ + *(volatile unsigned long *) addr = b; +} + +/* Get high hex bits */ +static char highhex(const int x) +{ + return hexchars[(x >> 4) & 0xf]; +} + +/* Get low hex bits */ +static char lowhex(const int x) +{ + return hexchars[x & 0xf]; +} /* Convert ch to hex */ static int hex(const char ch) diff --git a/trunk/arch/sh/kernel/machine_kexec.c b/trunk/arch/sh/kernel/machine_kexec.c index 08587cdb64d6..6bcd8d92399f 100644 --- a/trunk/arch/sh/kernel/machine_kexec.c +++ b/trunk/arch/sh/kernel/machine_kexec.c @@ -29,6 +29,12 @@ extern const unsigned char relocate_new_kernel[]; extern const unsigned int relocate_new_kernel_size; extern void *gdb_vbr_vector; +/* + * Provide a dummy crash_notes definition while crash dump arrives to ppc. + * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. + */ +void *crash_notes = NULL; + void machine_shutdown(void) { } diff --git a/trunk/arch/sh/kernel/pm.c b/trunk/arch/sh/kernel/pm.c deleted file mode 100644 index 10ab62c9aede..000000000000 --- a/trunk/arch/sh/kernel/pm.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Generic Power Management Routine - * - * Copyright (c) 2006 Andriy Skulysh - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License. - */ -#include -#include -#include -#include -#include -#include -#include - -#define INTR_OFFSET 0x600 - -#define STBCR 0xffffff82 -#define STBCR2 0xffffff88 - -#define STBCR_STBY 0x80 -#define STBCR_MSTP2 0x04 - -#define MCR 0xffffff68 -#define RTCNT 0xffffff70 - -#define MCR_RMODE 2 -#define MCR_RFSH 4 - -void pm_enter(void) -{ - u8 stbcr, csr; - u16 frqcr, mcr; - u32 vbr_new, vbr_old; - - set_bl_bit(); - - /* set wdt */ - csr = sh_wdt_read_csr(); - csr &= ~WTCSR_TME; - csr |= WTCSR_CKS_4096; - sh_wdt_write_csr(csr); - csr = sh_wdt_read_csr(); - sh_wdt_write_cnt(0); - - /* disable PLL1 */ - frqcr = ctrl_inw(FRQCR); - frqcr &= ~(FRQCR_PLLEN | FRQCR_PSTBY); - ctrl_outw(frqcr, FRQCR); - - /* enable standby */ - stbcr = ctrl_inb(STBCR); - ctrl_outb(stbcr | STBCR_STBY | STBCR_MSTP2, STBCR); - - /* set self-refresh */ - mcr = ctrl_inw(MCR); - ctrl_outw(mcr & ~MCR_RFSH, MCR); - - /* set interrupt handler */ - asm volatile("stc vbr, %0" : "=r" (vbr_old)); - vbr_new = get_zeroed_page(GFP_ATOMIC); - udelay(50); - memcpy((void*)(vbr_new + INTR_OFFSET), - &wakeup_start, &wakeup_end - &wakeup_start); - asm volatile("ldc %0, vbr" : : "r" (vbr_new)); - - ctrl_outw(0, RTCNT); - ctrl_outw(mcr | MCR_RFSH | MCR_RMODE, MCR); - - cpu_sleep(); - - asm volatile("ldc %0, vbr" : : "r" (vbr_old)); - - free_page(vbr_new); - - /* enable PLL1 */ - frqcr = ctrl_inw(FRQCR); - frqcr |= FRQCR_PSTBY; - ctrl_outw(frqcr, FRQCR); - udelay(50); - frqcr |= FRQCR_PLLEN; - ctrl_outw(frqcr, FRQCR); - - ctrl_outb(stbcr, STBCR); - - clear_bl_bit(); -} diff --git a/trunk/arch/sh/kernel/process.c b/trunk/arch/sh/kernel/process.c index 0b1d5dd7a93b..f2031314cb2b 100644 --- a/trunk/arch/sh/kernel/process.c +++ b/trunk/arch/sh/kernel/process.c @@ -81,6 +81,16 @@ void cpu_idle(void) void machine_restart(char * __unused) { + +#ifdef CONFIG_KEXEC + struct kimage *image; + image = xchg(&kexec_image, 0); + if (image) { + machine_shutdown(); + machine_kexec(image); + } +#endif + /* SR.BL=1 and invoke address error to let CPU reset (manual reset) */ asm volatile("ldc %0, sr\n\t" "mov.l @%1, %0" : : "r" (0x10000000), "r" (0x80000001)); @@ -253,7 +263,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, unsigned long unused, struct task_struct *p, struct pt_regs *regs) { - struct thread_info *ti = task_thread_info(p); struct pt_regs *childregs; #if defined(CONFIG_SH_FPU) struct task_struct *tsk = current; @@ -268,10 +277,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, if (user_mode(regs)) { childregs->regs[15] = usp; - ti->addr_limit = USER_DS; } else { childregs->regs[15] = (unsigned long)task_stack_page(p) + THREAD_SIZE; - ti->addr_limit = KERNEL_DS; } if (clone_flags & CLONE_SETTLS) { childregs->gbr = childregs->regs[0]; @@ -292,15 +299,13 @@ ubc_set_tracing(int asid, unsigned long pc) { ctrl_outl(pc, UBC_BARA); -#ifdef CONFIG_MMU /* We don't have any ASID settings for the SH-2! */ if (cpu_data->type != CPU_SH7604) ctrl_outb(asid, UBC_BASRA); -#endif ctrl_outl(0, UBC_BAMRA); - if (cpu_data->type == CPU_SH7729 || cpu_data->type == CPU_SH7710) { + if (cpu_data->type == CPU_SH7729) { ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR); } else { @@ -339,7 +344,6 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne } #endif -#ifdef CONFIG_MMU /* * Restore the kernel mode register * k7 (r7_bank1) @@ -347,21 +351,19 @@ struct task_struct *__switch_to(struct task_struct *prev, struct task_struct *ne asm volatile("ldc %0, r7_bank" : /* no output */ : "r" (task_thread_info(next))); -#endif +#ifdef CONFIG_MMU /* If no tasks are using the UBC, we're done */ if (ubc_usercnt == 0) /* If no tasks are using the UBC, we're done */; else if (next->thread.ubc_pc && next->mm) { - int asid = 0; -#ifdef CONFIG_MMU - asid |= next->mm->context.id & MMU_CONTEXT_ASID_MASK; -#endif - ubc_set_tracing(asid, next->thread.ubc_pc); + ubc_set_tracing(next->mm->context & MMU_CONTEXT_ASID_MASK, + next->thread.ubc_pc); } else { ctrl_outw(0, UBC_BBRA); ctrl_outw(0, UBC_BBRB); } +#endif return prev; } diff --git a/trunk/arch/sh/kernel/ptrace.c b/trunk/arch/sh/kernel/ptrace.c index 04ca13a041c1..f7eebbde3291 100644 --- a/trunk/arch/sh/kernel/ptrace.c +++ b/trunk/arch/sh/kernel/ptrace.c @@ -224,6 +224,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_SETDSPREGS: { unsigned long dp; + int i; ret = -EIO; dp = ((unsigned long) child) + THREAD_SIZE - diff --git a/trunk/arch/sh/kernel/semaphore.c b/trunk/arch/sh/kernel/semaphore.c index 184119eeae56..a3c24dcbf01d 100644 --- a/trunk/arch/sh/kernel/semaphore.c +++ b/trunk/arch/sh/kernel/semaphore.c @@ -14,7 +14,7 @@ #include #include -DEFINE_SPINLOCK(semaphore_wake_lock); +spinlock_t semaphore_wake_lock; /* * Semaphores are implemented using a two-way counter: diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index 77491cf9b259..e75189cb1db7 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -43,14 +43,27 @@ extern void * __rd_start, * __rd_end; * The bigger value means no problem. */ struct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, }; -#ifdef CONFIG_VT struct screen_info screen_info; -#endif #if defined(CONFIG_SH_UNKNOWN) struct sh_machine_vector sh_mv; #endif +/* We need this to satisfy some external references. */ +struct screen_info screen_info = { + 0, 25, /* orig-x, orig-y */ + 0, /* unused */ + 0, /* orig-video-page */ + 0, /* orig-video-mode */ + 80, /* orig-video-cols */ + 0,0,0, /* ega_ax, ega_bx, ega_cx */ + 25, /* orig-video-lines */ + 0, /* orig-video-isVGA */ + 16 /* orig-video-points */ +}; + +extern void platform_setup(void); +extern char *get_system_type(void); extern int root_mountflags; #define MV_NAME_SIZE 32 @@ -77,8 +90,29 @@ static struct sh_machine_vector* __init get_mv_byname(const char* name); static char command_line[COMMAND_LINE_SIZE] = { 0, }; -static struct resource code_resource = { .name = "Kernel code", }; -static struct resource data_resource = { .name = "Kernel data", }; +struct resource standard_io_resources[] = { + { "dma1", 0x00, 0x1f }, + { "pic1", 0x20, 0x3f }, + { "timer", 0x40, 0x5f }, + { "keyboard", 0x60, 0x6f }, + { "dma page reg", 0x80, 0x8f }, + { "pic2", 0xa0, 0xbf }, + { "dma2", 0xc0, 0xdf }, + { "fpu", 0xf0, 0xff } +}; + +#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource)) + +/* System RAM - interrupted by the 640kB-1M hole */ +#define code_resource (ram_resources[3]) +#define data_resource (ram_resources[4]) +static struct resource ram_resources[] = { + { "System RAM", 0x000000, 0x09ffff, IORESOURCE_BUSY }, + { "System RAM", 0x100000, 0x100000, IORESOURCE_BUSY }, + { "Video RAM area", 0x0a0000, 0x0bffff }, + { "Kernel code", 0x100000, 0 }, + { "Kernel data", 0, 0 } +}; unsigned long memory_start, memory_end; @@ -111,24 +145,6 @@ static inline void parse_cmdline (char ** cmdline_p, char mv_name[MV_NAME_SIZE], memory_end = memory_start + mem_size; } } - -#ifdef CONFIG_EARLY_PRINTK - if (c == ' ' && !memcmp(from, "earlyprintk=", 12)) { - char *ep_end; - - if (to != command_line) - to--; - - from += 12; - ep_end = strchr(from, ' '); - - setup_early_printk(from); - printk("early console enabled\n"); - - from = ep_end; - } -#endif - if (c == ' ' && !memcmp(from, "sh_mv=", 6)) { char* mv_end; char* mv_comma; @@ -221,9 +237,6 @@ static int __init sh_mv_setup(char **cmdline_p) __set_io_port_base(mv_io_base); #endif - if (!sh_mv.mv_nr_irqs) - sh_mv.mv_nr_irqs = NR_IRQS; - return 0; } @@ -232,6 +245,11 @@ void __init setup_arch(char **cmdline_p) unsigned long bootmap_size; unsigned long start_pfn, max_pfn, max_low_pfn; +#ifdef CONFIG_EARLY_PRINTK + extern void enable_early_printk(void); + + enable_early_printk(); +#endif #ifdef CONFIG_CMDLINE_BOOL strcpy(COMMAND_LINE, CONFIG_CMDLINE); #endif @@ -350,14 +368,14 @@ void __init setup_arch(char **cmdline_p) #endif /* Perform the machine specific initialisation */ - if (likely(sh_mv.mv_setup)) - sh_mv.mv_setup(cmdline_p); + platform_setup(); paging_init(); } struct sh_machine_vector* __init get_mv_byname(const char* name) { + extern int strcasecmp(const char *, const char *); extern long __machvec_start, __machvec_end; struct sh_machine_vector *all_vecs = (struct sh_machine_vector *)&__machvec_start; @@ -392,18 +410,25 @@ static int __init topology_init(void) subsys_initcall(topology_init); static const char *cpu_name[] = { - [CPU_SH7604] = "SH7604", [CPU_SH7300] = "SH7300", - [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", - [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708", - [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710", - [CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750", - [CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R", - [CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R", - [CPU_SH7760] = "SH7760", [CPU_SH73180] = "SH73180", - [CPU_ST40RA] = "ST40RA", [CPU_ST40GX1] = "ST40GX1", - [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501", - [CPU_SH7770] = "SH7770", [CPU_SH7780] = "SH7780", - [CPU_SH7781] = "SH7781", [CPU_SH7343] = "SH7343", + [CPU_SH7604] = "SH7604", + [CPU_SH7705] = "SH7705", + [CPU_SH7708] = "SH7708", + [CPU_SH7729] = "SH7729", + [CPU_SH7300] = "SH7300", + [CPU_SH7750] = "SH7750", + [CPU_SH7750S] = "SH7750S", + [CPU_SH7750R] = "SH7750R", + [CPU_SH7751] = "SH7751", + [CPU_SH7751R] = "SH7751R", + [CPU_SH7760] = "SH7760", + [CPU_SH73180] = "SH73180", + [CPU_ST40RA] = "ST40RA", + [CPU_ST40GX1] = "ST40GX1", + [CPU_SH4_202] = "SH4-202", + [CPU_SH4_501] = "SH4-501", + [CPU_SH7770] = "SH7770", + [CPU_SH7780] = "SH7780", + [CPU_SH7781] = "SH7781", [CPU_SH_NONE] = "Unknown" }; @@ -413,10 +438,8 @@ const char *get_cpu_subtype(void) } #ifdef CONFIG_PROC_FS -/* Symbolic CPU flags, keep in sync with asm/cpu-features.h */ static const char *cpu_flags[] = { - "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr", - "ptea", "llsc", "l2", NULL + "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr", "ptea", NULL }; static void show_cpuflags(struct seq_file *m) @@ -437,8 +460,7 @@ static void show_cpuflags(struct seq_file *m) seq_printf(m, "\n"); } -static void show_cacheinfo(struct seq_file *m, const char *type, - struct cache_info info) +static void show_cacheinfo(struct seq_file *m, const char *type, struct cache_info info) { unsigned int cache_size; @@ -459,7 +481,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "machine\t\t: %s\n", get_system_type()); seq_printf(m, "processor\t: %d\n", cpu); - seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine); + seq_printf(m, "cpu family\t: %s\n", system_utsname.machine); seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype()); show_cpuflags(m); @@ -471,7 +493,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) * unified cache on the SH-2 and SH-3, as well as the harvard * style cache on the SH-4. */ - if (boot_cpu_data.icache.flags & SH_CACHE_COMBINED) { + if (test_bit(SH_CACHE_COMBINED, &(boot_cpu_data.icache.flags))) { seq_printf(m, "unified\n"); show_cacheinfo(m, "cache", boot_cpu_data.icache); } else { @@ -480,10 +502,6 @@ static int show_cpuinfo(struct seq_file *m, void *v) show_cacheinfo(m, "dcache", boot_cpu_data.dcache); } - /* Optional secondary cache */ - if (boot_cpu_data.flags & CPU_HAS_L2_CACHE) - show_cacheinfo(m, "scache", boot_cpu_data.scache); - seq_printf(m, "bogomips\t: %lu.%02lu\n", boot_cpu_data.loops_per_jiffy/(500000/HZ), (boot_cpu_data.loops_per_jiffy/(5000/HZ)) % 100); @@ -599,3 +617,4 @@ static int __init kgdb_parse_options(char *options) } __setup("kgdb=", kgdb_parse_options); #endif /* CONFIG_SH_KGDB */ + diff --git a/trunk/arch/sh/kernel/sh_ksyms.c b/trunk/arch/sh/kernel/sh_ksyms.c index d3cbfa2ad4a7..245ed8f945e8 100644 --- a/trunk/arch/sh/kernel/sh_ksyms.c +++ b/trunk/arch/sh/kernel/sh_ksyms.c @@ -27,11 +27,21 @@ EXPORT_SYMBOL(sh_mv); /* platform dependent support */ EXPORT_SYMBOL(dump_fpu); +EXPORT_SYMBOL(iounmap); +EXPORT_SYMBOL(enable_irq); +EXPORT_SYMBOL(disable_irq); +EXPORT_SYMBOL(probe_irq_mask); EXPORT_SYMBOL(kernel_thread); +EXPORT_SYMBOL(disable_irq_nosync); EXPORT_SYMBOL(irq_desc); EXPORT_SYMBOL(no_irq_type); +EXPORT_SYMBOL(strstr); EXPORT_SYMBOL(strlen); +EXPORT_SYMBOL(strnlen); +EXPORT_SYMBOL(strchr); +EXPORT_SYMBOL(strcat); +EXPORT_SYMBOL(strncat); /* PCI exports */ #ifdef CONFIG_PCI @@ -42,8 +52,13 @@ EXPORT_SYMBOL(pci_free_consistent); /* mem exports */ EXPORT_SYMBOL(memchr); EXPORT_SYMBOL(memcpy); +EXPORT_SYMBOL(memcpy_fromio); +EXPORT_SYMBOL(memcpy_toio); EXPORT_SYMBOL(memset); +EXPORT_SYMBOL(memset_io); EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(memcmp); +EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(__copy_user); EXPORT_SYMBOL(boot_cpu_data); @@ -79,9 +94,7 @@ EXPORT_SYMBOL(strcpy); DECLARE_EXPORT(__movstr_i4_even); DECLARE_EXPORT(__movstr_i4_odd); DECLARE_EXPORT(__movstrSI12_i4); -#endif -#if defined(CONFIG_CPU_SH4) || defined(CONFIG_SH7705_CACHE_32KB) /* needed by some modules */ EXPORT_SYMBOL(flush_cache_all); EXPORT_SYMBOL(flush_cache_range); @@ -89,9 +102,11 @@ EXPORT_SYMBOL(flush_dcache_page); EXPORT_SYMBOL(__flush_purge_region); #endif -#if defined(CONFIG_MMU) && (defined(CONFIG_CPU_SH4) || \ - defined(CONFIG_SH7705_CACHE_32KB)) -EXPORT_SYMBOL(clear_user_page); +#if defined(CONFIG_SH7705_CACHE_32KB) +EXPORT_SYMBOL(flush_cache_all); +EXPORT_SYMBOL(flush_cache_range); +EXPORT_SYMBOL(flush_dcache_page); +EXPORT_SYMBOL(__flush_purge_region); #endif EXPORT_SYMBOL(flush_tlb_page); @@ -101,12 +116,7 @@ EXPORT_SYMBOL(__down_trylock); EXPORT_SYMBOL(synchronize_irq); #endif -#ifdef CONFIG_PM -EXPORT_SYMBOL(pm_suspend); -#endif - EXPORT_SYMBOL(csum_partial); -#ifdef CONFIG_IPV6 EXPORT_SYMBOL(csum_ipv6_magic); -#endif +EXPORT_SYMBOL(consistent_sync); EXPORT_SYMBOL(clear_page); diff --git a/trunk/arch/sh/kernel/signal.c b/trunk/arch/sh/kernel/signal.c index 5213f5bc6ce0..b475c4d2405f 100644 --- a/trunk/arch/sh/kernel/signal.c +++ b/trunk/arch/sh/kernel/signal.c @@ -8,6 +8,7 @@ * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima * */ + #include #include #include @@ -20,7 +21,6 @@ #include #include #include -#include #include #include @@ -29,8 +29,12 @@ #include #include +#define DEBUG_SIG 0 + #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) +asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); + /* * Atomically swap in the new signal mask, and wait for a signal. */ @@ -39,17 +43,51 @@ sys_sigsuspend(old_sigset_t mask, unsigned long r5, unsigned long r6, unsigned long r7, struct pt_regs regs) { + sigset_t saveset; + mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); - current->saved_sigmask = current->blocked; + saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - current->state = TASK_INTERRUPTIBLE; - schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); - return -ERESTARTNOHAND; + regs.regs[0] = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(®s, &saveset)) + return -EINTR; + } +} + +asmlinkage int +sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, + unsigned long r6, unsigned long r7, + struct pt_regs regs) +{ + sigset_t saveset, newset; + + /* XXX: Don't preclude handling different sized sigset_t's. */ + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + + if (copy_from_user(&newset, unewset, sizeof(newset))) + return -EFAULT; + sigdelsetmask(&newset, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + + regs.regs[0] = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(®s, &saveset)) + return -EINTR; + } } asmlinkage int @@ -310,12 +348,7 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) return (void __user *)((sp - frame_size) & -8ul); } -/* These symbols are defined with the addresses in the vsyscall page. - See vsyscall-trapa.S. */ -extern void __user __kernel_sigreturn; -extern void __user __kernel_rt_sigreturn; - -static int setup_frame(int sig, struct k_sigaction *ka, +static void setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *regs) { struct sigframe __user *frame; @@ -335,18 +368,15 @@ static int setup_frame(int sig, struct k_sigaction *ka, err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); - if (_NSIG_WORDS > 1) + if (_NSIG_WORDS > 1) { err |= __copy_to_user(frame->extramask, &set->sig[1], sizeof(frame->extramask)); + } /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { regs->pr = (unsigned long) ka->sa.sa_restorer; -#ifdef CONFIG_VSYSCALL - } else if (likely(current->mm->context.vdso)) { - regs->pr = VDSO_SYM(&__kernel_sigreturn); -#endif } else { /* Generate return code (system call to sigreturn) */ err |= __put_user(MOVW(7), &frame->retcode[0]); @@ -372,22 +402,21 @@ static int setup_frame(int sig, struct k_sigaction *ka, set_fs(USER_DS); - pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", - current->comm, current->pid, frame, regs->pc, regs->pr); +#if DEBUG_SIG + printk("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", + current->comm, current->pid, frame, regs->pc, regs->pr); +#endif flush_cache_sigtramp(regs->pr); - if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode)) flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES); - - return 0; + return; give_sigsegv: force_sigsegv(sig, current); - return -EFAULT; } -static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, +static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs) { struct rt_sigframe __user *frame; @@ -423,10 +452,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { regs->pr = (unsigned long) ka->sa.sa_restorer; -#ifdef CONFIG_VSYSCALL - } else if (likely(current->mm->context.vdso)) { - regs->pr = VDSO_SYM(&__kernel_rt_sigreturn); -#endif } else { /* Generate return code (system call to rt_sigreturn) */ err |= __put_user(MOVW(7), &frame->retcode[0]); @@ -452,31 +477,28 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, set_fs(USER_DS); - pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", - current->comm, current->pid, frame, regs->pc, regs->pr); +#if DEBUG_SIG + printk("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", + current->comm, current->pid, frame, regs->pc, regs->pr); +#endif flush_cache_sigtramp(regs->pr); - if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode)) flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES); - - return 0; + return; give_sigsegv: force_sigsegv(sig, current); - return -EFAULT; } /* * OK, we're invoking a handler */ -static int +static void handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { - int ret; - /* Are we from a system call? */ if (regs->tra >= 0) { /* If so, check system call restarting.. */ @@ -517,23 +539,19 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, /* Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) - ret = setup_rt_frame(sig, ka, info, oldset, regs); + setup_rt_frame(sig, ka, info, oldset, regs); else - ret = setup_frame(sig, ka, oldset, regs); + setup_frame(sig, ka, oldset, regs); if (ka->sa.sa_flags & SA_ONESHOT) ka->sa.sa_handler = SIG_DFL; - if (ret == 0) { - spin_lock_irq(¤t->sighand->siglock); - sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(¤t->blocked,sig); - recalc_sigpending(); - spin_unlock_irq(¤t->sighand->siglock); - } - - return ret; + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); } /* @@ -545,12 +563,11 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, * the kernel can handle, and then we build all the user-level signal handling * stack-frames in one go after that. */ -static void do_signal(struct pt_regs *regs, unsigned int save_r0) +int do_signal(struct pt_regs *regs, sigset_t *oldset) { siginfo_t info; int signr; struct k_sigaction ka; - sigset_t *oldset; /* * We want the common case to go fast, which @@ -559,27 +576,19 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) * if so. */ if (!user_mode(regs)) - return; + return 1; if (try_to_freeze()) goto no_signal; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else + if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { /* Whee! Actually deliver the signal. */ - if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - } + handle_signal(signr, &ka, &info, oldset, regs); + return 1; } no_signal: @@ -588,27 +597,10 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0) /* Restart the system call - no handlers present */ if (regs->regs[0] == -ERESTARTNOHAND || regs->regs[0] == -ERESTARTSYS || - regs->regs[0] == -ERESTARTNOINTR) { - regs->regs[0] = save_r0; - regs->pc -= 2; - } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) { + regs->regs[0] == -ERESTARTNOINTR || + regs->regs[0] == -ERESTART_RESTARTBLOCK) { regs->pc -= 2; - regs->regs[3] = __NR_restart_syscall; } } - - /* if there's no signal to deliver, we just put the saved sigmask - * back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } -} - -asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0, - __u32 thread_info_flags) -{ - /* deal with pending signal delivery */ - if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) - do_signal(regs, save_r0); + return 0; } diff --git a/trunk/arch/sh/kernel/smp.c b/trunk/arch/sh/kernel/smp.c index dbebaddcfe39..6c0fb7c4af11 100644 --- a/trunk/arch/sh/kernel/smp.c +++ b/trunk/arch/sh/kernel/smp.c @@ -42,7 +42,6 @@ cpumask_t cpu_possible_map; EXPORT_SYMBOL(cpu_possible_map); cpumask_t cpu_online_map; -EXPORT_SYMBOL(cpu_online_map); static atomic_t cpus_booted = ATOMIC_INIT(0); /* These are defined by the board-specific code. */ diff --git a/trunk/arch/sh/kernel/sys_sh.c b/trunk/arch/sh/kernel/sys_sh.c index 8fde95001c34..917b2f32f260 100644 --- a/trunk/arch/sh/kernel/sys_sh.c +++ b/trunk/arch/sh/kernel/sys_sh.c @@ -21,11 +21,9 @@ #include #include #include -#include -#include + #include #include -#include /* * sys_pipe() is the normal C calling standard for creating @@ -46,16 +44,11 @@ asmlinkage int sys_pipe(unsigned long r4, unsigned long r5, return error; } -unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ - -EXPORT_SYMBOL(shm_align_mask); - +#if defined(HAVE_ARCH_UNMAPPED_AREA) /* - * To avoid cache aliases, we map the shared page with same color. + * To avoid cache alias, we map the shard page with same color. */ -#define COLOUR_ALIGN(addr, pgoff) \ - ((((addr) + shm_align_mask) & ~shm_align_mask) + \ - (((pgoff) << PAGE_SHIFT) & shm_align_mask)) +#define COLOUR_ALIGN(addr) (((addr)+SHMLBA-1)&~(SHMLBA-1)) unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) @@ -63,52 +56,43 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, struct mm_struct *mm = current->mm; struct vm_area_struct *vma; unsigned long start_addr; - int do_colour_align; if (flags & MAP_FIXED) { /* We do not accept a shared mapping if it would violate * cache aliasing constraints. */ - if ((flags & MAP_SHARED) && (addr & shm_align_mask)) + if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1))) return -EINVAL; return addr; } - if (unlikely(len > TASK_SIZE)) + if (len > TASK_SIZE) return -ENOMEM; - do_colour_align = 0; - if (filp || (flags & MAP_SHARED)) - do_colour_align = 1; - if (addr) { - if (do_colour_align) - addr = COLOUR_ALIGN(addr, pgoff); - else + if (flags & MAP_PRIVATE) addr = PAGE_ALIGN(addr); - + else + addr = COLOUR_ALIGN(addr); vma = find_vma(mm, addr); if (TASK_SIZE - len >= addr && (!vma || addr + len <= vma->vm_start)) return addr; } - - if (len > mm->cached_hole_size) { - start_addr = addr = mm->free_area_cache; - } else { + if (len <= mm->cached_hole_size) { mm->cached_hole_size = 0; - start_addr = addr = TASK_UNMAPPED_BASE; + mm->free_area_cache = TASK_UNMAPPED_BASE; } - -full_search: - if (do_colour_align) - addr = COLOUR_ALIGN(addr, pgoff); - else + if (flags & MAP_PRIVATE) addr = PAGE_ALIGN(mm->free_area_cache); + else + addr = COLOUR_ALIGN(mm->free_area_cache); + start_addr = addr; +full_search: for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { /* At this point: (!vma || addr < vma->vm_end). */ - if (unlikely(TASK_SIZE - len < addr)) { + if (TASK_SIZE - len < addr) { /* * Start a new search - just in case we missed * some holes. @@ -120,7 +104,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, } return -ENOMEM; } - if (likely(!vma || addr + len <= vma->vm_start)) { + if (!vma || addr + len <= vma->vm_start) { /* * Remember the place where we stopped the search: */ @@ -131,10 +115,11 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, mm->cached_hole_size = vma->vm_start - addr; addr = vma->vm_end; - if (do_colour_align) - addr = COLOUR_ALIGN(addr, pgoff); + if (!(flags & MAP_PRIVATE)) + addr = COLOUR_ALIGN(addr); } } +#endif static inline long do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, @@ -282,7 +267,7 @@ asmlinkage int sys_uname(struct old_utsname * name) if (!name) return -EFAULT; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err=copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } @@ -310,19 +295,3 @@ asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1, (u64)len0 << 32 | len1, advice); #endif } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register long __sc0 __asm__ ("r3") = __NR_execve; - register long __sc4 __asm__ ("r4") = (long) filename; - register long __sc5 __asm__ ("r5") = (long) argv; - register long __sc6 __asm__ ("r6") = (long) envp; - __asm__ __volatile__ ("trapa #0x13" : "=z" (__sc0) - : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6) - : "memory"); - return __sc0; -} diff --git a/trunk/arch/sh/kernel/syscalls.S b/trunk/arch/sh/kernel/syscalls.S deleted file mode 100644 index 768334e95075..000000000000 --- a/trunk/arch/sh/kernel/syscalls.S +++ /dev/null @@ -1,353 +0,0 @@ -/* - * arch/sh/kernel/syscalls.S - * - * System call table for SuperH - * - * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2003 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - */ -#include -#include - -#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE) -#define sys_nfsservctl sys_ni_syscall -#endif - -#if !defined(CONFIG_MMU) -#define sys_madvise sys_ni_syscall -#define sys_readahead sys_ni_syscall -#define sys_mprotect sys_ni_syscall -#define sys_msync sys_ni_syscall -#define sys_mlock sys_ni_syscall -#define sys_munlock sys_ni_syscall -#define sys_mlockall sys_ni_syscall -#define sys_munlockall sys_ni_syscall -#define sys_mremap sys_ni_syscall -#define sys_mincore sys_ni_syscall -#define sys_remap_file_pages sys_ni_syscall -#endif - - .data -ENTRY(sys_call_table) - .long sys_restart_syscall /* 0 - old "setup()" system call*/ - .long sys_exit - .long sys_fork - .long sys_read - .long sys_write - .long sys_open /* 5 */ - .long sys_close - .long sys_waitpid - .long sys_creat - .long sys_link - .long sys_unlink /* 10 */ - .long sys_execve - .long sys_chdir - .long sys_time - .long sys_mknod - .long sys_chmod /* 15 */ - .long sys_lchown16 - .long sys_ni_syscall /* old break syscall holder */ - .long sys_stat - .long sys_lseek - .long sys_getpid /* 20 */ - .long sys_mount - .long sys_oldumount - .long sys_setuid16 - .long sys_getuid16 - .long sys_stime /* 25 */ - .long sys_ptrace - .long sys_alarm - .long sys_fstat - .long sys_pause - .long sys_utime /* 30 */ - .long sys_ni_syscall /* old stty syscall holder */ - .long sys_ni_syscall /* old gtty syscall holder */ - .long sys_access - .long sys_nice - .long sys_ni_syscall /* 35 */ /* old ftime syscall holder */ - .long sys_sync - .long sys_kill - .long sys_rename - .long sys_mkdir - .long sys_rmdir /* 40 */ - .long sys_dup - .long sys_pipe - .long sys_times - .long sys_ni_syscall /* old prof syscall holder */ - .long sys_brk /* 45 */ - .long sys_setgid16 - .long sys_getgid16 - .long sys_signal - .long sys_geteuid16 - .long sys_getegid16 /* 50 */ - .long sys_acct - .long sys_umount /* recycled never used phys() */ - .long sys_ni_syscall /* old lock syscall holder */ - .long sys_ioctl - .long sys_fcntl /* 55 */ - .long sys_ni_syscall /* old mpx syscall holder */ - .long sys_setpgid - .long sys_ni_syscall /* old ulimit syscall holder */ - .long sys_ni_syscall /* sys_olduname */ - .long sys_umask /* 60 */ - .long sys_chroot - .long sys_ustat - .long sys_dup2 - .long sys_getppid - .long sys_getpgrp /* 65 */ - .long sys_setsid - .long sys_sigaction - .long sys_sgetmask - .long sys_ssetmask - .long sys_setreuid16 /* 70 */ - .long sys_setregid16 - .long sys_sigsuspend - .long sys_sigpending - .long sys_sethostname - .long sys_setrlimit /* 75 */ - .long sys_old_getrlimit - .long sys_getrusage - .long sys_gettimeofday - .long sys_settimeofday - .long sys_getgroups16 /* 80 */ - .long sys_setgroups16 - .long sys_ni_syscall /* sys_oldselect */ - .long sys_symlink - .long sys_lstat - .long sys_readlink /* 85 */ - .long sys_uselib - .long sys_swapon - .long sys_reboot - .long old_readdir - .long old_mmap /* 90 */ - .long sys_munmap - .long sys_truncate - .long sys_ftruncate - .long sys_fchmod - .long sys_fchown16 /* 95 */ - .long sys_getpriority - .long sys_setpriority - .long sys_ni_syscall /* old profil syscall holder */ - .long sys_statfs - .long sys_fstatfs /* 100 */ - .long sys_ni_syscall /* ioperm */ - .long sys_socketcall - .long sys_syslog - .long sys_setitimer - .long sys_getitimer /* 105 */ - .long sys_newstat - .long sys_newlstat - .long sys_newfstat - .long sys_uname - .long sys_ni_syscall /* 110 */ /* iopl */ - .long sys_vhangup - .long sys_ni_syscall /* idle */ - .long sys_ni_syscall /* vm86old */ - .long sys_wait4 - .long sys_swapoff /* 115 */ - .long sys_sysinfo - .long sys_ipc - .long sys_fsync - .long sys_sigreturn - .long sys_clone /* 120 */ - .long sys_setdomainname - .long sys_newuname - .long sys_ni_syscall /* sys_modify_ldt */ - .long sys_adjtimex - .long sys_mprotect /* 125 */ - .long sys_sigprocmask - .long sys_ni_syscall /* old "create_module" */ - .long sys_init_module - .long sys_delete_module - .long sys_ni_syscall /* 130: old "get_kernel_syms" */ - .long sys_quotactl - .long sys_getpgid - .long sys_fchdir - .long sys_bdflush - .long sys_sysfs /* 135 */ - .long sys_personality - .long sys_ni_syscall /* for afs_syscall */ - .long sys_setfsuid16 - .long sys_setfsgid16 - .long sys_llseek /* 140 */ - .long sys_getdents - .long sys_select - .long sys_flock - .long sys_msync - .long sys_readv /* 145 */ - .long sys_writev - .long sys_getsid - .long sys_fdatasync - .long sys_sysctl - .long sys_mlock /* 150 */ - .long sys_munlock - .long sys_mlockall - .long sys_munlockall - .long sys_sched_setparam - .long sys_sched_getparam /* 155 */ - .long sys_sched_setscheduler - .long sys_sched_getscheduler - .long sys_sched_yield - .long sys_sched_get_priority_max - .long sys_sched_get_priority_min /* 160 */ - .long sys_sched_rr_get_interval - .long sys_nanosleep - .long sys_mremap - .long sys_setresuid16 - .long sys_getresuid16 /* 165 */ - .long sys_ni_syscall /* vm86 */ - .long sys_ni_syscall /* old "query_module" */ - .long sys_poll - .long sys_nfsservctl - .long sys_setresgid16 /* 170 */ - .long sys_getresgid16 - .long sys_prctl - .long sys_rt_sigreturn - .long sys_rt_sigaction - .long sys_rt_sigprocmask /* 175 */ - .long sys_rt_sigpending - .long sys_rt_sigtimedwait - .long sys_rt_sigqueueinfo - .long sys_rt_sigsuspend - .long sys_pread_wrapper /* 180 */ - .long sys_pwrite_wrapper - .long sys_chown16 - .long sys_getcwd - .long sys_capget - .long sys_capset /* 185 */ - .long sys_sigaltstack - .long sys_sendfile - .long sys_ni_syscall /* streams1 */ - .long sys_ni_syscall /* streams2 */ - .long sys_vfork /* 190 */ - .long sys_getrlimit - .long sys_mmap2 - .long sys_truncate64 - .long sys_ftruncate64 - .long sys_stat64 /* 195 */ - .long sys_lstat64 - .long sys_fstat64 - .long sys_lchown - .long sys_getuid - .long sys_getgid /* 200 */ - .long sys_geteuid - .long sys_getegid - .long sys_setreuid - .long sys_setregid - .long sys_getgroups /* 205 */ - .long sys_setgroups - .long sys_fchown - .long sys_setresuid - .long sys_getresuid - .long sys_setresgid /* 210 */ - .long sys_getresgid - .long sys_chown - .long sys_setuid - .long sys_setgid - .long sys_setfsuid /* 215 */ - .long sys_setfsgid - .long sys_pivot_root - .long sys_mincore - .long sys_madvise - .long sys_getdents64 /* 220 */ - .long sys_fcntl64 - .long sys_ni_syscall /* reserved for TUX */ - .long sys_ni_syscall /* Reserved for Security */ - .long sys_gettid - .long sys_readahead /* 225 */ - .long sys_setxattr - .long sys_lsetxattr - .long sys_fsetxattr - .long sys_getxattr - .long sys_lgetxattr /* 230 */ - .long sys_fgetxattr - .long sys_listxattr - .long sys_llistxattr - .long sys_flistxattr - .long sys_removexattr /* 235 */ - .long sys_lremovexattr - .long sys_fremovexattr - .long sys_tkill - .long sys_sendfile64 - .long sys_futex /* 240 */ - .long sys_sched_setaffinity - .long sys_sched_getaffinity - .long sys_ni_syscall - .long sys_ni_syscall - .long sys_io_setup /* 245 */ - .long sys_io_destroy - .long sys_io_getevents - .long sys_io_submit - .long sys_io_cancel - .long sys_fadvise64 /* 250 */ - .long sys_ni_syscall - .long sys_exit_group - .long sys_lookup_dcookie - .long sys_epoll_create - .long sys_epoll_ctl /* 255 */ - .long sys_epoll_wait - .long sys_remap_file_pages - .long sys_set_tid_address - .long sys_timer_create - .long sys_timer_settime /* 260 */ - .long sys_timer_gettime - .long sys_timer_getoverrun - .long sys_timer_delete - .long sys_clock_settime - .long sys_clock_gettime /* 265 */ - .long sys_clock_getres - .long sys_clock_nanosleep - .long sys_statfs64 - .long sys_fstatfs64 - .long sys_tgkill /* 270 */ - .long sys_utimes - .long sys_fadvise64_64_wrapper - .long sys_ni_syscall /* Reserved for vserver */ - .long sys_ni_syscall /* Reserved for mbind */ - .long sys_ni_syscall /* 275 - get_mempolicy */ - .long sys_ni_syscall /* set_mempolicy */ - .long sys_mq_open - .long sys_mq_unlink - .long sys_mq_timedsend - .long sys_mq_timedreceive /* 280 */ - .long sys_mq_notify - .long sys_mq_getsetattr - .long sys_kexec_load - .long sys_waitid - .long sys_ni_syscall /* 285 */ - .long sys_add_key - .long sys_request_key - .long sys_keyctl - .long sys_ioprio_set - .long sys_ioprio_get /* 290 */ - .long sys_inotify_init - .long sys_inotify_add_watch - .long sys_inotify_rm_watch - .long sys_migrate_pages - .long sys_openat /* 295 */ - .long sys_mkdirat - .long sys_mknodat - .long sys_fchownat - .long sys_futimesat - .long sys_fstatat64 /* 300 */ - .long sys_unlinkat - .long sys_renameat - .long sys_linkat - .long sys_symlinkat - .long sys_readlinkat /* 305 */ - .long sys_fchmodat - .long sys_faccessat - .long sys_pselect6 - .long sys_ppoll - .long sys_unshare /* 310 */ - .long sys_set_robust_list - .long sys_get_robust_list - .long sys_splice - .long sys_sync_file_range - .long sys_tee /* 315 */ - .long sys_vmsplice diff --git a/trunk/arch/sh/kernel/time.c b/trunk/arch/sh/kernel/time.c index 450c68f1df05..a1589f85499d 100644 --- a/trunk/arch/sh/kernel/time.c +++ b/trunk/arch/sh/kernel/time.c @@ -3,12 +3,13 @@ * * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 2002 - 2006 Paul Mundt + * Copyright (C) 2002, 2003, 2004, 2005 Paul Mundt * Copyright (C) 2002 M. R. Brown * * Some code taken from i386 version. * Copyright (C) 1991, 1992, 1995 Linus Torvalds */ + #include #include #include @@ -18,26 +19,22 @@ #include #include +extern unsigned long wall_jiffies; struct sys_timer *sys_timer; /* Move this somewhere more sensible.. */ DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); -/* Dummy RTC ops */ -static void null_rtc_get_time(struct timespec *tv) -{ - tv->tv_sec = mktime(2000, 1, 1, 0, 0, 0); - tv->tv_nsec = 0; -} - -static int null_rtc_set_time(const time_t secs) -{ - return 0; -} - -void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; -int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; +/* XXX: Can we initialize this in a routine somewhere? Dreamcast doesn't want + * these routines anywhere... */ +#ifdef CONFIG_SH_RTC +void (*rtc_get_time)(struct timespec *) = sh_rtc_gettimeofday; +int (*rtc_set_time)(const time_t) = sh_rtc_settimeofday; +#else +void (*rtc_get_time)(struct timespec *); +int (*rtc_set_time)(const time_t); +#endif /* * Scheduler clock - returns current time in nanosec units. @@ -51,10 +48,16 @@ void do_gettimeofday(struct timeval *tv) { unsigned long seq; unsigned long usec, sec; + unsigned long lost; do { seq = read_seqbegin(&xtime_lock); usec = get_timer_offset(); + + lost = jiffies - wall_jiffies; + if (lost) + usec += lost * (1000000 / HZ); + sec = xtime.tv_sec; usec += xtime.tv_nsec / 1000; } while (read_seqretry(&xtime_lock, seq)); @@ -67,6 +70,7 @@ void do_gettimeofday(struct timeval *tv) tv->tv_sec = sec; tv->tv_usec = usec; } + EXPORT_SYMBOL(do_gettimeofday); int do_settimeofday(struct timespec *tv) @@ -84,7 +88,8 @@ int do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ - nsec -= 1000 * get_timer_offset(); + nsec -= 1000 * (get_timer_offset() + + (jiffies - wall_jiffies) * (1000000 / HZ)); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -98,6 +103,7 @@ int do_settimeofday(struct timespec *tv) return 0; } + EXPORT_SYMBOL(do_settimeofday); /* last time the RTC clock got updated */ @@ -109,7 +115,7 @@ static long last_rtc_update; */ void handle_timer_tick(struct pt_regs *regs) { - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -129,7 +135,7 @@ void handle_timer_tick(struct pt_regs *regs) xtime.tv_sec > last_rtc_update + 660 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) { - if (rtc_sh_set_time(xtime.tv_sec) == 0) + if (rtc_set_time(xtime.tv_sec) == 0) last_rtc_update = xtime.tv_sec; else /* do it again in 60s */ @@ -137,33 +143,8 @@ void handle_timer_tick(struct pt_regs *regs) } } -#ifdef CONFIG_PM -int timer_suspend(struct sys_device *dev, pm_message_t state) -{ - struct sys_timer *sys_timer = container_of(dev, struct sys_timer, dev); - - sys_timer->ops->stop(); - - return 0; -} - -int timer_resume(struct sys_device *dev) -{ - struct sys_timer *sys_timer = container_of(dev, struct sys_timer, dev); - - sys_timer->ops->start(); - - return 0; -} -#else -#define timer_suspend NULL -#define timer_resume NULL -#endif - static struct sysdev_class timer_sysclass = { set_kset_name("timer"), - .suspend = timer_suspend, - .resume = timer_resume, }; static int __init timer_init_sysfs(void) @@ -175,6 +156,7 @@ static int __init timer_init_sysfs(void) sys_timer->dev.cls = &timer_sysclass; return sysdev_register(&sys_timer->dev); } + device_initcall(timer_init_sysfs); void (*board_time_init)(void); @@ -186,9 +168,15 @@ void __init time_init(void) clk_init(); - rtc_sh_get_time(&xtime); - set_normalized_timespec(&wall_to_monotonic, - -xtime.tv_sec, -xtime.tv_nsec); + if (rtc_get_time) { + rtc_get_time(&xtime); + } else { + xtime.tv_sec = mktime(2000, 1, 1, 0, 0, 0); + xtime.tv_nsec = 0; + } + + set_normalized_timespec(&wall_to_monotonic, + -xtime.tv_sec, -xtime.tv_nsec); /* * Find the timer to use as the system timer, it will be diff --git a/trunk/arch/sh/kernel/timers/timer-tmu.c b/trunk/arch/sh/kernel/timers/timer-tmu.c index 205816fcf0da..d4212add53b2 100644 --- a/trunk/arch/sh/kernel/timers/timer-tmu.c +++ b/trunk/arch/sh/kernel/timers/timer-tmu.c @@ -132,17 +132,17 @@ static unsigned long tmu_timer_get_frequency(void) ctrl_outl(0xffffffff, TMU0_TCOR); ctrl_outl(0xffffffff, TMU0_TCNT); - rtc_sh_get_time(&ts2); + rtc_get_time(&ts2); do { - rtc_sh_get_time(&ts1); + rtc_get_time(&ts1); } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); /* actually start the timer */ ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); do { - rtc_sh_get_time(&ts2); + rtc_get_time(&ts2); } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); freq = 0xffffffff - ctrl_inl(TMU0_TCNT); @@ -188,18 +188,6 @@ static struct clk tmu0_clk = { .ops = &tmu_clk_ops, }; -static int tmu_timer_start(void) -{ - ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); - return 0; -} - -static int tmu_timer_stop(void) -{ - ctrl_outb(0, TMU_TSTR); - return 0; -} - static int tmu_timer_init(void) { unsigned long interval; @@ -209,7 +197,7 @@ static int tmu_timer_init(void) tmu0_clk.parent = clk_get("module_clk"); /* Start TMU0 */ - tmu_timer_stop(); + ctrl_outb(0, TMU_TSTR); #if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); #endif @@ -223,15 +211,13 @@ static int tmu_timer_init(void) ctrl_outl(interval, TMU0_TCOR); ctrl_outl(interval, TMU0_TCNT); - tmu_timer_start(); + ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); return 0; } struct sys_timer_ops tmu_timer_ops = { .init = tmu_timer_init, - .start = tmu_timer_start, - .stop = tmu_timer_stop, .get_frequency = tmu_timer_get_frequency, .get_offset = tmu_timer_get_offset, }; diff --git a/trunk/arch/sh/kernel/traps.c b/trunk/arch/sh/kernel/traps.c index c2c597e09482..d9db1180f770 100644 --- a/trunk/arch/sh/kernel/traps.c +++ b/trunk/arch/sh/kernel/traps.c @@ -36,15 +36,40 @@ #ifdef CONFIG_SH_KGDB #include -#define CHK_REMOTE_DEBUG(regs) \ -{ \ - if (kgdb_debug_hook && !user_mode(regs))\ - (*kgdb_debug_hook)(regs); \ +#define CHK_REMOTE_DEBUG(regs) \ +{ \ + if ((kgdb_debug_hook != (kgdb_debug_hook_t *) NULL) && (!user_mode(regs))) \ + { \ + (*kgdb_debug_hook)(regs); \ + } \ } #else #define CHK_REMOTE_DEBUG(regs) #endif +#define DO_ERROR(trapnr, signr, str, name, tsk) \ +asmlinkage void do_##name(unsigned long r4, unsigned long r5, \ + unsigned long r6, unsigned long r7, \ + struct pt_regs regs) \ +{ \ + unsigned long error_code; \ + \ + /* Check if it's a DSP instruction */ \ + if (is_dsp_inst(®s)) { \ + /* Enable DSP mode, and restart instruction. */ \ + regs.sr |= SR_DSP; \ + return; \ + } \ + \ + asm volatile("stc r2_bank, %0": "=r" (error_code)); \ + local_irq_enable(); \ + tsk->thread.error_code = error_code; \ + tsk->thread.trap_no = trapnr; \ + CHK_REMOTE_DEBUG(®s); \ + force_sig(signr, tsk); \ + die_if_no_fixup(str,®s,error_code); \ +} + #ifdef CONFIG_CPU_SH2 #define TRAP_RESERVED_INST 4 #define TRAP_ILLEGAL_SLOT_INST 6 @@ -61,7 +86,7 @@ #define VMALLOC_OFFSET (8*1024*1024) #define MODULE_RANGE (8*1024*1024) -DEFINE_SPINLOCK(die_lock); +spinlock_t die_lock; void die(const char * str, struct pt_regs * regs, long err) { @@ -550,117 +575,8 @@ int is_dsp_inst(struct pt_regs *regs) #define is_dsp_inst(regs) (0) #endif /* CONFIG_SH_DSP */ -extern int do_fpu_inst(unsigned short, struct pt_regs*); - -asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs regs) -{ - unsigned long error_code; - struct task_struct *tsk = current; - -#ifdef CONFIG_SH_FPU_EMU - unsigned short inst; - int err; - - get_user(inst, (unsigned short*)regs.pc); - - err = do_fpu_inst(inst, ®s); - if (!err) { - regs.pc += 2; - return; - } - /* not a FPU inst. */ -#endif - -#ifdef CONFIG_SH_DSP - /* Check if it's a DSP instruction */ - if (is_dsp_inst(®s)) { - /* Enable DSP mode, and restart instruction. */ - regs.sr |= SR_DSP; - return; - } -#endif - - asm volatile("stc r2_bank, %0": "=r" (error_code)); - local_irq_enable(); - tsk->thread.error_code = error_code; - tsk->thread.trap_no = TRAP_RESERVED_INST; - CHK_REMOTE_DEBUG(®s); - force_sig(SIGILL, tsk); - die_if_no_fixup("reserved instruction", ®s, error_code); -} - -#ifdef CONFIG_SH_FPU_EMU -static int emulate_branch(unsigned short inst, struct pt_regs* regs) -{ - /* - * bfs: 8fxx: PC+=d*2+4; - * bts: 8dxx: PC+=d*2+4; - * bra: axxx: PC+=D*2+4; - * bsr: bxxx: PC+=D*2+4 after PR=PC+4; - * braf:0x23: PC+=Rn*2+4; - * bsrf:0x03: PC+=Rn*2+4 after PR=PC+4; - * jmp: 4x2b: PC=Rn; - * jsr: 4x0b: PC=Rn after PR=PC+4; - * rts: 000b: PC=PR; - */ - if ((inst & 0xfd00) == 0x8d00) { - regs->pc += SH_PC_8BIT_OFFSET(inst); - return 0; - } - - if ((inst & 0xe000) == 0xa000) { - regs->pc += SH_PC_12BIT_OFFSET(inst); - return 0; - } - - if ((inst & 0xf0df) == 0x0003) { - regs->pc += regs->regs[(inst & 0x0f00) >> 8] + 4; - return 0; - } - - if ((inst & 0xf0df) == 0x400b) { - regs->pc = regs->regs[(inst & 0x0f00) >> 8]; - return 0; - } - - if ((inst & 0xffff) == 0x000b) { - regs->pc = regs->pr; - return 0; - } - - return 1; -} -#endif - -asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs regs) -{ - unsigned long error_code; - struct task_struct *tsk = current; -#ifdef CONFIG_SH_FPU_EMU - unsigned short inst; - - get_user(inst, (unsigned short *)regs.pc + 1); - if (!do_fpu_inst(inst, ®s)) { - get_user(inst, (unsigned short *)regs.pc); - if (!emulate_branch(inst, ®s)) - return; - /* fault in branch.*/ - } - /* not a FPU inst. */ -#endif - - asm volatile("stc r2_bank, %0": "=r" (error_code)); - local_irq_enable(); - tsk->thread.error_code = error_code; - tsk->thread.trap_no = TRAP_RESERVED_INST; - CHK_REMOTE_DEBUG(®s); - force_sig(SIGILL, tsk); - die_if_no_fixup("illegal slot instruction", ®s, error_code); -} +DO_ERROR(TRAP_RESERVED_INST, SIGILL, "reserved instruction", reserved_inst, current) +DO_ERROR(TRAP_ILLEGAL_SLOT_INST, SIGILL, "illegal slot instruction", illegal_slot_inst, current) asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, @@ -718,16 +634,14 @@ void __init trap_init(void) exception_handling_table[TRAP_ILLEGAL_SLOT_INST] = (void *)do_illegal_slot_inst; -#if defined(CONFIG_CPU_SH4) && !defined(CONFIG_SH_FPU) || \ - defined(CONFIG_SH_FPU_EMU) - /* - * For SH-4 lacking an FPU, treat floating point instructions as - * reserved. They'll be handled in the math-emu case, or faulted on - * otherwise. - */ - /* entry 64 corresponds to EXPEVT=0x800 */ - exception_handling_table[64] = (void *)do_reserved_inst; - exception_handling_table[65] = (void *)do_illegal_slot_inst; +#ifdef CONFIG_CPU_SH4 + if (!(cpu_data->flags & CPU_HAS_FPU)) { + /* For SH-4 lacking an FPU, treat floating point instructions + as reserved. */ + /* entry 64 corresponds to EXPEVT=0x800 */ + exception_handling_table[64] = (void *)do_reserved_inst; + exception_handling_table[65] = (void *)do_illegal_slot_inst; + } #endif /* Setup VBR for boot cpu */ @@ -741,12 +655,20 @@ void show_stack(struct task_struct *tsk, unsigned long *sp) unsigned long module_end = VMALLOC_END; int i = 1; - if (!tsk) - tsk = current; - if (tsk == current) - sp = (unsigned long *)current_stack_pointer; - else + if (tsk && !sp) { sp = (unsigned long *)tsk->thread.sp; + } + + if (!sp) { + __asm__ __volatile__ ( + "mov r15, %0\n\t" + "stc r7_bank, %1\n\t" + : "=r" (module_start), + "=r" (module_end) + ); + + sp = (unsigned long *)module_start; + } stack = sp; diff --git a/trunk/arch/sh/kernel/vmlinux.lds.S b/trunk/arch/sh/kernel/vmlinux.lds.S index 5eb930918186..95fdd9135fcf 100644 --- a/trunk/arch/sh/kernel/vmlinux.lds.S +++ b/trunk/arch/sh/kernel/vmlinux.lds.S @@ -2,7 +2,6 @@ * ld script to make SuperH Linux kernel * Written by Niibe Yutaka */ -#include #include #ifdef CONFIG_CPU_LITTLE_ENDIAN @@ -14,7 +13,7 @@ OUTPUT_ARCH(sh) ENTRY(_start) SECTIONS { - . = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET; + . = 0x80000000 + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET; _text = .; /* Text and read-only data */ text = .; /* Text and read-only data */ .empty_zero_page : { @@ -41,16 +40,16 @@ SECTIONS *(.data) /* Align the initial ramdisk image (INITRD) on page boundaries. */ - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __rd_start = .; *(.initrd) - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __rd_end = .; CONSTRUCTORS } - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); .data.page_aligned : { *(.data.idt) } . = ALIGN(32); @@ -61,10 +60,12 @@ SECTIONS _edata = .; /* End of data section */ - . = ALIGN(THREAD_SIZE); /* init_task */ + . = ALIGN(8192); /* init_task */ .data.init_task : { *(.data.init_task) } + /* stack */ + .stack : { stack = .; _stack = .; } - . = ALIGN(PAGE_SIZE); /* Init code and data */ + . = ALIGN(4096); /* Init code and data */ __init_begin = .; _sinittext = .; .init.text : { *(.init.text) } @@ -95,7 +96,7 @@ SECTIONS __machvec_start = .; .init.machvec : { *(.init.machvec) } __machvec_end = .; - . = ALIGN(PAGE_SIZE); + . = ALIGN(4096); __init_end = .; . = ALIGN(4); diff --git a/trunk/arch/sh/kernel/vsyscall/Makefile b/trunk/arch/sh/kernel/vsyscall/Makefile deleted file mode 100644 index 4bbce1cfa359..000000000000 --- a/trunk/arch/sh/kernel/vsyscall/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -obj-y += vsyscall.o vsyscall-syscall.o - -$(obj)/vsyscall-syscall.o: \ - $(foreach F,trapa,$(obj)/vsyscall-$F.so) - -# Teach kbuild about targets -targets += $(foreach F,trapa,vsyscall-$F.o vsyscall-$F.so) -targets += vsyscall-note.o vsyscall.lds - -# The DSO images are built using a special linker script -quiet_cmd_syscall = SYSCALL $@ - cmd_syscall = $(CC) -nostdlib $(SYSCFLAGS_$(@F)) \ - -Wl,-T,$(filter-out FORCE,$^) -o $@ - -export CPPFLAGS_vsyscall.lds += -P -C -Ush - -vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \ - $(call ld-option, -Wl$(comma)--hash-style=sysv) - -SYSCFLAGS_vsyscall-trapa.so = $(vsyscall-flags) - -$(obj)/vsyscall-trapa.so: \ -$(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE - $(call if_changed,syscall) - -# We also create a special relocatable object that should mirror the symbol -# table and layout of the linked DSO. With ld -R we can then refer to -# these symbols in the kernel code rather than hand-coded addresses. -extra-y += vsyscall-syms.o -$(obj)/built-in.o: $(obj)/vsyscall-syms.o -$(obj)/built-in.o: ld_flags += -R $(obj)/vsyscall-syms.o - -SYSCFLAGS_vsyscall-syms.o = -r -$(obj)/vsyscall-syms.o: $(src)/vsyscall.lds \ - $(obj)/vsyscall-trapa.o $(obj)/vsyscall-note.o FORCE - $(call if_changed,syscall) diff --git a/trunk/arch/sh/kernel/vsyscall/vsyscall-note.S b/trunk/arch/sh/kernel/vsyscall/vsyscall-note.S deleted file mode 100644 index d4b5be4f3d5f..000000000000 --- a/trunk/arch/sh/kernel/vsyscall/vsyscall-note.S +++ /dev/null @@ -1,25 +0,0 @@ -/* - * This supplies .note.* sections to go into the PT_NOTE inside the vDSO text. - * Here we can supply some information useful to userland. - */ - -#include -#include - -#define ASM_ELF_NOTE_BEGIN(name, flags, vendor, type) \ - .section name, flags; \ - .balign 4; \ - .long 1f - 0f; /* name length */ \ - .long 3f - 2f; /* data length */ \ - .long type; /* note type */ \ -0: .asciz vendor; /* vendor name */ \ -1: .balign 4; \ -2: - -#define ASM_ELF_NOTE_END \ -3: .balign 4; /* pad out section */ \ - .previous - - ASM_ELF_NOTE_BEGIN(".note.kernel-version", "a", UTS_SYSNAME, 0) - .long LINUX_VERSION_CODE - ASM_ELF_NOTE_END diff --git a/trunk/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S b/trunk/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S deleted file mode 100644 index 555a64f124ca..000000000000 --- a/trunk/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S +++ /dev/null @@ -1,39 +0,0 @@ -#include - - .text - .balign 32 - .globl __kernel_sigreturn - .type __kernel_sigreturn,@function -__kernel_sigreturn: -.LSTART_sigreturn: - mov.w 1f, r3 - trapa #0x10 - or r0, r0 - or r0, r0 - or r0, r0 - or r0, r0 - or r0, r0 - -1: .short __NR_sigreturn -.LEND_sigreturn: - .size __kernel_sigreturn,.-.LSTART_sigreturn - - .balign 32 - .globl __kernel_rt_sigreturn - .type __kernel_rt_sigreturn,@function -__kernel_rt_sigreturn: -.LSTART_rt_sigreturn: - mov.w 1f, r3 - trapa #0x10 - or r0, r0 - or r0, r0 - or r0, r0 - or r0, r0 - or r0, r0 - -1: .short __NR_rt_sigreturn -.LEND_rt_sigreturn: - .size __kernel_rt_sigreturn,.-.LSTART_rt_sigreturn - - .section .eh_frame,"a",@progbits - .previous diff --git a/trunk/arch/sh/kernel/vsyscall/vsyscall-syscall.S b/trunk/arch/sh/kernel/vsyscall/vsyscall-syscall.S deleted file mode 100644 index c2ac7f0282b3..000000000000 --- a/trunk/arch/sh/kernel/vsyscall/vsyscall-syscall.S +++ /dev/null @@ -1,10 +0,0 @@ -#include - -__INITDATA - - .globl vsyscall_trapa_start, vsyscall_trapa_end -vsyscall_trapa_start: - .incbin "arch/sh/kernel/vsyscall/vsyscall-trapa.so" -vsyscall_trapa_end: - -__FINIT diff --git a/trunk/arch/sh/kernel/vsyscall/vsyscall-trapa.S b/trunk/arch/sh/kernel/vsyscall/vsyscall-trapa.S deleted file mode 100644 index 3b6eb34c43fa..000000000000 --- a/trunk/arch/sh/kernel/vsyscall/vsyscall-trapa.S +++ /dev/null @@ -1,42 +0,0 @@ - .text - .globl __kernel_vsyscall - .type __kernel_vsyscall,@function -__kernel_vsyscall: -.LSTART_vsyscall: - /* XXX: We'll have to do something here once we opt to use the vDSO - * page for something other than the signal trampoline.. as well as - * fill out .eh_frame -- PFM. */ -.LEND_vsyscall: - .size __kernel_vsyscall,.-.LSTART_vsyscall - .previous - - .section .eh_frame,"a",@progbits -.LCIE: - .ualong .LCIE_end - .LCIE_start -.LCIE_start: - .ualong 0 /* CIE ID */ - .byte 0x1 /* Version number */ - .string "zRS" /* NUL-terminated augmentation string */ - .uleb128 0x1 /* Code alignment factor */ - .sleb128 -4 /* Data alignment factor */ - .byte 0x11 /* Return address register column */ - /* Augmentation length and data (none) */ - .byte 0xc /* DW_CFA_def_cfa */ - .uleb128 0xf /* r15 */ - .uleb128 0x0 /* offset 0 */ - - .align 2 -.LCIE_end: - - .ualong .LFDE_end-.LFDE_start /* Length FDE */ -.LFDE_start: - .ualong .LCIE /* CIE pointer */ - .ualong .LSTART_vsyscall-. /* start address */ - .ualong .LEND_vsyscall-.LSTART_vsyscall - .uleb128 0 - .align 2 -.LFDE_end: - .previous - -/* Get the common code for the sigreturn entry points */ -#include "vsyscall-sigreturn.S" diff --git a/trunk/arch/sh/kernel/vsyscall/vsyscall.c b/trunk/arch/sh/kernel/vsyscall/vsyscall.c deleted file mode 100644 index 075d6cc1a2d7..000000000000 --- a/trunk/arch/sh/kernel/vsyscall/vsyscall.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * arch/sh/kernel/vsyscall.c - * - * Copyright (C) 2006 Paul Mundt - * - * vDSO randomization - * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include -#include - -/* - * Should the kernel map a VDSO page into processes and pass its - * address down to glibc upon exec()? - */ -unsigned int __read_mostly vdso_enabled = 1; -EXPORT_SYMBOL_GPL(vdso_enabled); - -static int __init vdso_setup(char *s) -{ - vdso_enabled = simple_strtoul(s, NULL, 0); - return 1; -} -__setup("vdso=", vdso_setup); - -/* - * These symbols are defined by vsyscall.o to mark the bounds - * of the ELF DSO images included therein. - */ -extern const char vsyscall_trapa_start, vsyscall_trapa_end; -static void *syscall_page; - -int __init vsyscall_init(void) -{ - syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); - - /* - * XXX: Map this page to a fixmap entry if we get around - * to adding the page to ELF core dumps - */ - - memcpy(syscall_page, - &vsyscall_trapa_start, - &vsyscall_trapa_end - &vsyscall_trapa_start); - - return 0; -} - -static struct page *syscall_vma_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) -{ - unsigned long offset = address - vma->vm_start; - struct page *page; - - if (address < vma->vm_start || address > vma->vm_end) - return NOPAGE_SIGBUS; - - page = virt_to_page(syscall_page + offset); - - get_page(page); - - return page; -} - -/* Prevent VMA merging */ -static void syscall_vma_close(struct vm_area_struct *vma) -{ -} - -static struct vm_operations_struct syscall_vm_ops = { - .nopage = syscall_vma_nopage, - .close = syscall_vma_close, -}; - -/* Setup a VMA at program startup for the vsyscall page */ -int arch_setup_additional_pages(struct linux_binprm *bprm, - int executable_stack) -{ - struct vm_area_struct *vma; - struct mm_struct *mm = current->mm; - unsigned long addr; - int ret; - - down_write(&mm->mmap_sem); - addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); - if (IS_ERR_VALUE(addr)) { - ret = addr; - goto up_fail; - } - - vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL); - if (!vma) { - ret = -ENOMEM; - goto up_fail; - } - - vma->vm_start = addr; - vma->vm_end = addr + PAGE_SIZE; - /* MAYWRITE to allow gdb to COW and set breakpoints */ - vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; - vma->vm_flags |= mm->def_flags; - vma->vm_page_prot = protection_map[vma->vm_flags & 7]; - vma->vm_ops = &syscall_vm_ops; - vma->vm_mm = mm; - - ret = insert_vm_struct(mm, vma); - if (unlikely(ret)) { - kmem_cache_free(vm_area_cachep, vma); - goto up_fail; - } - - current->mm->context.vdso = (void *)addr; - - mm->total_vm++; -up_fail: - up_write(&mm->mmap_sem); - return ret; -} - -const char *arch_vma_name(struct vm_area_struct *vma) -{ - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) - return "[vdso]"; - - return NULL; -} - -struct vm_area_struct *get_gate_vma(struct task_struct *task) -{ - return NULL; -} - -int in_gate_area(struct task_struct *task, unsigned long address) -{ - return 0; -} - -int in_gate_area_no_task(unsigned long address) -{ - return 0; -} diff --git a/trunk/arch/sh/kernel/vsyscall/vsyscall.lds.S b/trunk/arch/sh/kernel/vsyscall/vsyscall.lds.S deleted file mode 100644 index b13c3d439fee..000000000000 --- a/trunk/arch/sh/kernel/vsyscall/vsyscall.lds.S +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Linker script for vsyscall DSO. The vsyscall page is an ELF shared - * object prelinked to its virtual address, and with only one read-only - * segment (that fits in one page). This script controls its layout. - */ -#include - -#ifdef CONFIG_CPU_LITTLE_ENDIAN -OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux") -#else -OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux") -#endif -OUTPUT_ARCH(sh) - -/* The ELF entry point can be used to set the AT_SYSINFO value. */ -ENTRY(__kernel_vsyscall); - -SECTIONS -{ - . = SIZEOF_HEADERS; - - .hash : { *(.hash) } :text - .gnu.hash : { *(.gnu.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - - /* This linker script is used both with -r and with -shared. - For the layouts to match, we need to skip more than enough - space for the dynamic symbol table et al. If this amount - is insufficient, ld -shared will barf. Just increase it here. */ - . = 0x400; - - .text : { *(.text) } :text =0x90909090 - .note : { *(.note.*) } :text :note - .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr - .eh_frame : { KEEP (*(.eh_frame)) } :text - .dynamic : { *(.dynamic) } :text :dynamic - .useless : { - *(.got.plt) *(.got) - *(.data .data.* .gnu.linkonce.d.*) - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - } :text -} - -/* - * We must supply the ELF program headers explicitly to get just one - * PT_LOAD segment, and set the flags explicitly to make segments read-only. - */ -PHDRS -{ - text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ - dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ - note PT_NOTE FLAGS(4); /* PF_R */ - eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ -} - -/* - * This controls what symbols we export from the DSO. - */ -VERSION -{ - LINUX_2.6 { - global: - __kernel_vsyscall; - __kernel_sigreturn; - __kernel_rt_sigreturn; - - local: *; - }; -} diff --git a/trunk/arch/sh/lib/checksum.S b/trunk/arch/sh/lib/checksum.S index cbdd0d40e545..7c50dfe68c07 100644 --- a/trunk/arch/sh/lib/checksum.S +++ b/trunk/arch/sh/lib/checksum.S @@ -202,9 +202,8 @@ ENTRY(csum_partial_copy_generic) cmp/pz r6 ! Jump if we had at least two bytes. bt/s 1f clrt - add #2,r6 ! r6 was < 2. Deal with it. bra 4f - mov r6,r2 + add #2,r6 ! r6 was < 2. Deal with it. 3: ! Handle different src and dest alignments. ! This is not common, so simple byte by byte copy will do. diff --git a/trunk/arch/sh/lib/memcpy-sh4.S b/trunk/arch/sh/lib/memcpy-sh4.S index 560bc17eebdd..db6b736537ad 100644 --- a/trunk/arch/sh/lib/memcpy-sh4.S +++ b/trunk/arch/sh/lib/memcpy-sh4.S @@ -727,8 +727,8 @@ ENTRY(memcpy) mov.l @(0x04,r5), r11 ! 18 LS (latency=2) xtrct r9, r8 ! 48 EX - mov.l @(0x00,r5), r12 ! 18 LS (latency=2) - xtrct r10, r9 ! 48 EX + mov.w @(0x02,r5), r12 ! 18 LS (latency=2) + xtrct r10, r9 ! 48 EX movca.l r0,@r1 ! 40 LS (latency=3-7) add #-0x1c, r1 ! 50 EX diff --git a/trunk/arch/sh/lib/memset.S b/trunk/arch/sh/lib/memset.S index af91fe2b72a6..95670090680e 100644 --- a/trunk/arch/sh/lib/memset.S +++ b/trunk/arch/sh/lib/memset.S @@ -29,7 +29,6 @@ ENTRY(memset) bf/s 1b mov.b r5,@-r4 2: ! make VVVV - extu.b r5,r5 swap.b r5,r0 ! V0 or r0,r5 ! VV swap.w r5,r0 ! VV00 diff --git a/trunk/arch/sh/math-emu/Makefile b/trunk/arch/sh/math-emu/Makefile deleted file mode 100644 index 638b342c781a..000000000000 --- a/trunk/arch/sh/math-emu/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-y := math.o diff --git a/trunk/arch/sh/math-emu/math.c b/trunk/arch/sh/math-emu/math.c deleted file mode 100644 index 26b6046814fd..000000000000 --- a/trunk/arch/sh/math-emu/math.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * arch/sh/math-emu/math.c - * - * Copyright (C) 2006 Takashi YOSHII - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "sfp-util.h" -#include -#include -#include - -#define FPUL (fregs->fpul) -#define FPSCR (fregs->fpscr) -#define FPSCR_RM (FPSCR&3) -#define FPSCR_DN ((FPSCR>>18)&1) -#define FPSCR_PR ((FPSCR>>19)&1) -#define FPSCR_SZ ((FPSCR>>20)&1) -#define FPSCR_FR ((FPSCR>>21)&1) -#define FPSCR_MASK 0x003fffffUL - -#define BANK(n) (n^(FPSCR_FR?16:0)) -#define FR ((unsigned long*)(fregs->fp_regs)) -#define FR0 (FR[BANK(0)]) -#define FRn (FR[BANK(n)]) -#define FRm (FR[BANK(m)]) -#define DR ((unsigned long long*)(fregs->fp_regs)) -#define DRn (DR[BANK(n)/2]) -#define DRm (DR[BANK(m)/2]) - -#define XREG(n) (n^16) -#define XFn (FR[BANK(XREG(n))]) -#define XFm (FR[BANK(XREG(m))]) -#define XDn (DR[BANK(XREG(n))/2]) -#define XDm (DR[BANK(XREG(m))/2]) - -#define R0 (regs->regs[0]) -#define Rn (regs->regs[n]) -#define Rm (regs->regs[m]) - -#define WRITE(d,a) ({if(put_user(d, (typeof (d)*)a)) return -EFAULT;}) -#define READ(d,a) ({if(get_user(d, (typeof (d)*)a)) return -EFAULT;}) - -#define PACK_S(r,f) FP_PACK_SP(&r,f) -#define UNPACK_S(f,r) FP_UNPACK_SP(f,&r) -#define PACK_D(r,f) \ - {u32 t[2]; FP_PACK_DP(t,f); ((u32*)&r)[0]=t[1]; ((u32*)&r)[1]=t[0];} -#define UNPACK_D(f,r) \ - {u32 t[2]; t[0]=((u32*)&r)[1]; t[1]=((u32*)&r)[0]; FP_UNPACK_DP(f,t);} - -// 2 args instructions. -#define BOTH_PRmn(op,x) \ - FP_DECL_EX; if(FPSCR_PR) op(D,x,DRm,DRn); else op(S,x,FRm,FRn); - -#define CMP_X(SZ,R,M,N) do{ \ - FP_DECL_##SZ(Fm); FP_DECL_##SZ(Fn); \ - UNPACK_##SZ(Fm, M); UNPACK_##SZ(Fn, N); \ - FP_CMP_##SZ(R, Fn, Fm, 2); }while(0) -#define EQ_X(SZ,R,M,N) do{ \ - FP_DECL_##SZ(Fm); FP_DECL_##SZ(Fn); \ - UNPACK_##SZ(Fm, M); UNPACK_##SZ(Fn, N); \ - FP_CMP_EQ_##SZ(R, Fn, Fm); }while(0) -#define CMP(OP) ({ int r; BOTH_PRmn(OP##_X,r); r; }) - -static int -fcmp_gt(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n) -{ - if (CMP(CMP) > 0) - regs->sr |= 1; - else - regs->sr &= ~1; - - return 0; -} - -static int -fcmp_eq(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n) -{ - if (CMP(CMP /*EQ*/) == 0) - regs->sr |= 1; - else - regs->sr &= ~1; - return 0; -} - -#define ARITH_X(SZ,OP,M,N) do{ \ - FP_DECL_##SZ(Fm); FP_DECL_##SZ(Fn); FP_DECL_##SZ(Fr); \ - UNPACK_##SZ(Fm, M); UNPACK_##SZ(Fn, N); \ - FP_##OP##_##SZ(Fr, Fn, Fm); \ - PACK_##SZ(N, Fr); }while(0) - -static int -fadd(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n) -{ - BOTH_PRmn(ARITH_X, ADD); - return 0; -} - -static int -fsub(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n) -{ - BOTH_PRmn(ARITH_X, SUB); - return 0; -} - -static int -fmul(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n) -{ - BOTH_PRmn(ARITH_X, MUL); - return 0; -} - -static int -fdiv(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n) -{ - BOTH_PRmn(ARITH_X, DIV); - return 0; -} - -static int -fmac(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n) -{ - FP_DECL_EX; - FP_DECL_S(Fr); - FP_DECL_S(Ft); - FP_DECL_S(F0); - FP_DECL_S(Fm); - FP_DECL_S(Fn); - UNPACK_S(F0, FR0); - UNPACK_S(Fm, FRm); - UNPACK_S(Fn, FRn); - FP_MUL_S(Ft, Fm, F0); - FP_ADD_S(Fr, Fn, Ft); - PACK_S(FRn, Fr); - return 0; -} - -// to process fmov's extention (odd n for DR access XD). -#define FMOV_EXT(x) if(x&1) x+=16-1 - -static int -fmov_idx_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, - int n) -{ - if (FPSCR_SZ) { - FMOV_EXT(n); - READ(FRn, Rm + R0 + 4); - n++; - READ(FRn, Rm + R0); - } else { - READ(FRn, Rm + R0); - } - - return 0; -} - -static int -fmov_mem_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, - int n) -{ - if (FPSCR_SZ) { - FMOV_EXT(n); - READ(FRn, Rm + 4); - n++; - READ(FRn, Rm); - } else { - READ(FRn, Rm); - } - - return 0; -} - -static int -fmov_inc_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, - int n) -{ - if (FPSCR_SZ) { - FMOV_EXT(n); - READ(FRn, Rm + 4); - n++; - READ(FRn, Rm); - Rm += 8; - } else { - READ(FRn, Rm); - Rm += 4; - } - - return 0; -} - -static int -fmov_reg_idx(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, - int n) -{ - if (FPSCR_SZ) { - FMOV_EXT(m); - WRITE(FRm, Rn + R0 + 4); - m++; - WRITE(FRm, Rn + R0); - } else { - WRITE(FRm, Rn + R0); - } - - return 0; -} - -static int -fmov_reg_mem(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, - int n) -{ - if (FPSCR_SZ) { - FMOV_EXT(m); - WRITE(FRm, Rn + 4); - m++; - WRITE(FRm, Rn); - } else { - WRITE(FRm, Rn); - } - - return 0; -} - -static int -fmov_reg_dec(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, - int n) -{ - if (FPSCR_SZ) { - FMOV_EXT(m); - Rn -= 8; - WRITE(FRm, Rn + 4); - m++; - WRITE(FRm, Rn); - } else { - Rn -= 4; - WRITE(FRm, Rn); - } - - return 0; -} - -static int -fmov_reg_reg(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, - int n) -{ - if (FPSCR_SZ) { - FMOV_EXT(m); - FMOV_EXT(n); - DRn = DRm; - } else { - FRn = FRm; - } - - return 0; -} - -static int -fnop_mn(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n) -{ - return -EINVAL; -} - -// 1 arg instructions. -#define NOTYETn(i) static int i(struct sh_fpu_soft_struct *fregs, int n) \ - { printk( #i " not yet done.\n"); return 0; } - -NOTYETn(ftrv) -NOTYETn(fsqrt) -NOTYETn(fipr) -NOTYETn(fsca) -NOTYETn(fsrra) - -#define EMU_FLOAT_X(SZ,N) do { \ - FP_DECL_##SZ(Fn); \ - FP_FROM_INT_##SZ(Fn, FPUL, 32, int); \ - PACK_##SZ(N, Fn); }while(0) -static int ffloat(struct sh_fpu_soft_struct *fregs, int n) -{ - FP_DECL_EX; - - if (FPSCR_PR) - EMU_FLOAT_X(D, DRn); - else - EMU_FLOAT_X(S, FRn); - - return 0; -} - -#define EMU_FTRC_X(SZ,N) do { \ - FP_DECL_##SZ(Fn); \ - UNPACK_##SZ(Fn, N); \ - FP_TO_INT_##SZ(FPUL, Fn, 32, 1); }while(0) -static int ftrc(struct sh_fpu_soft_struct *fregs, int n) -{ - FP_DECL_EX; - - if (FPSCR_PR) - EMU_FTRC_X(D, DRn); - else - EMU_FTRC_X(S, FRn); - - return 0; -} - -static int fcnvsd(struct sh_fpu_soft_struct *fregs, int n) -{ - FP_DECL_EX; - FP_DECL_S(Fn); - FP_DECL_D(Fr); - UNPACK_S(Fn, FPUL); - FP_CONV(D, S, 2, 1, Fr, Fn); - PACK_D(DRn, Fr); - return 0; -} - -static int fcnvds(struct sh_fpu_soft_struct *fregs, int n) -{ - FP_DECL_EX; - FP_DECL_D(Fn); - FP_DECL_S(Fr); - UNPACK_D(Fn, DRn); - FP_CONV(S, D, 1, 2, Fr, Fn); - PACK_S(FPUL, Fr); - return 0; -} - -static int fxchg(struct sh_fpu_soft_struct *fregs, int flag) -{ - FPSCR ^= flag; - return 0; -} - -static int fsts(struct sh_fpu_soft_struct *fregs, int n) -{ - FRn = FPUL; - return 0; -} - -static int flds(struct sh_fpu_soft_struct *fregs, int n) -{ - FPUL = FRn; - return 0; -} - -static int fneg(struct sh_fpu_soft_struct *fregs, int n) -{ - FRn ^= (1 << (_FP_W_TYPE_SIZE - 1)); - return 0; -} - -static int fabs(struct sh_fpu_soft_struct *fregs, int n) -{ - FRn &= ~(1 << (_FP_W_TYPE_SIZE - 1)); - return 0; -} - -static int fld0(struct sh_fpu_soft_struct *fregs, int n) -{ - FRn = 0; - return 0; -} - -static int fld1(struct sh_fpu_soft_struct *fregs, int n) -{ - FRn = (_FP_EXPBIAS_S << (_FP_FRACBITS_S - 1)); - return 0; -} - -static int fnop_n(struct sh_fpu_soft_struct *fregs, int n) -{ - return -EINVAL; -} - -/// Instruction decoders. - -static int id_fxfd(struct sh_fpu_soft_struct *, int); -static int id_fnxd(struct sh_fpu_soft_struct *, struct pt_regs *, int, int); - -static int (*fnxd[])(struct sh_fpu_soft_struct *, int) = { - fsts, flds, ffloat, ftrc, fneg, fabs, fsqrt, fsrra, - fld0, fld1, fcnvsd, fcnvds, fnop_n, fnop_n, fipr, id_fxfd -}; - -static int (*fnmx[])(struct sh_fpu_soft_struct *, struct pt_regs *, int, int) = { - fadd, fsub, fmul, fdiv, fcmp_eq, fcmp_gt, fmov_idx_reg, fmov_reg_idx, - fmov_mem_reg, fmov_inc_reg, fmov_reg_mem, fmov_reg_dec, - fmov_reg_reg, id_fnxd, fmac, fnop_mn}; - -static int id_fxfd(struct sh_fpu_soft_struct *fregs, int x) -{ - const int flag[] = { FPSCR_SZ, FPSCR_PR, FPSCR_FR, 0 }; - switch (x & 3) { - case 3: - fxchg(fregs, flag[x >> 2]); - break; - case 1: - ftrv(fregs, x - 1); - break; - default: - fsca(fregs, x); - } - return 0; -} - -static int -id_fnxd(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int x, int n) -{ - return (fnxd[x])(fregs, n); -} - -static int -id_fnmx(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, u16 code) -{ - int n = (code >> 8) & 0xf, m = (code >> 4) & 0xf, x = code & 0xf; - return (fnmx[x])(fregs, regs, m, n); -} - -static int -id_sys(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, u16 code) -{ - int n = ((code >> 8) & 0xf); - unsigned long *reg = (code & 0x0010) ? &FPUL : &FPSCR; - - switch (code & 0xf0ff) { - case 0x005a: - case 0x006a: - Rn = *reg; - break; - case 0x405a: - case 0x406a: - *reg = Rn; - break; - case 0x4052: - case 0x4062: - Rn -= 4; - WRITE(*reg, Rn); - break; - case 0x4056: - case 0x4066: - READ(*reg, Rn); - Rn += 4; - break; - default: - return -EINVAL; - } - - return 0; -} - -static int fpu_emulate(u16 code, struct sh_fpu_soft_struct *fregs, struct pt_regs *regs) -{ - if ((code & 0xf000) == 0xf000) - return id_fnmx(fregs, regs, code); - else - return id_sys(fregs, regs, code); -} - -/** - * denormal_to_double - Given denormalized float number, - * store double float - * - * @fpu: Pointer to sh_fpu_hard structure - * @n: Index to FP register - */ -static void denormal_to_double(struct sh_fpu_hard_struct *fpu, int n) -{ - unsigned long du, dl; - unsigned long x = fpu->fpul; - int exp = 1023 - 126; - - if (x != 0 && (x & 0x7f800000) == 0) { - du = (x & 0x80000000); - while ((x & 0x00800000) == 0) { - x <<= 1; - exp--; - } - x &= 0x007fffff; - du |= (exp << 20) | (x >> 3); - dl = x << 29; - - fpu->fp_regs[n] = du; - fpu->fp_regs[n+1] = dl; - } -} - -/** - * ieee_fpe_handler - Handle denormalized number exception - * - * @regs: Pointer to register structure - * - * Returns 1 when it's handled (should not cause exception). - */ -static int ieee_fpe_handler(struct pt_regs *regs) -{ - unsigned short insn = *(unsigned short *)regs->pc; - unsigned short finsn; - unsigned long nextpc; - int nib[4] = { - (insn >> 12) & 0xf, - (insn >> 8) & 0xf, - (insn >> 4) & 0xf, - insn & 0xf}; - - if (nib[0] == 0xb || - (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */ - regs->pr = regs->pc + 4; - - if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */ - nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3); - finsn = *(unsigned short *) (regs->pc + 2); - } else if (nib[0] == 0x8 && nib[1] == 0xd) { /* bt/s */ - if (regs->sr & 1) - nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1); - else - nextpc = regs->pc + 4; - finsn = *(unsigned short *) (regs->pc + 2); - } else if (nib[0] == 0x8 && nib[1] == 0xf) { /* bf/s */ - if (regs->sr & 1) - nextpc = regs->pc + 4; - else - nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1); - finsn = *(unsigned short *) (regs->pc + 2); - } else if (nib[0] == 0x4 && nib[3] == 0xb && - (nib[2] == 0x0 || nib[2] == 0x2)) { /* jmp & jsr */ - nextpc = regs->regs[nib[1]]; - finsn = *(unsigned short *) (regs->pc + 2); - } else if (nib[0] == 0x0 && nib[3] == 0x3 && - (nib[2] == 0x0 || nib[2] == 0x2)) { /* braf & bsrf */ - nextpc = regs->pc + 4 + regs->regs[nib[1]]; - finsn = *(unsigned short *) (regs->pc + 2); - } else if (insn == 0x000b) { /* rts */ - nextpc = regs->pr; - finsn = *(unsigned short *) (regs->pc + 2); - } else { - nextpc = regs->pc + 2; - finsn = insn; - } - - if ((finsn & 0xf1ff) == 0xf0ad) { /* fcnvsd */ - struct task_struct *tsk = current; - - if ((tsk->thread.fpu.hard.fpscr & (1 << 17))) { - /* FPU error */ - denormal_to_double (&tsk->thread.fpu.hard, - (finsn >> 8) & 0xf); - tsk->thread.fpu.hard.fpscr &= - ~(FPSCR_CAUSE_MASK | FPSCR_FLAG_MASK); - set_tsk_thread_flag(tsk, TIF_USEDFPU); - } else { - tsk->thread.trap_no = 11; - tsk->thread.error_code = 0; - force_sig(SIGFPE, tsk); - } - - regs->pc = nextpc; - return 1; - } - - return 0; -} - -asmlinkage void do_fpu_error(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs regs) -{ - struct task_struct *tsk = current; - - if (ieee_fpe_handler (®s)) - return; - - regs.pc += 2; - tsk->thread.trap_no = 11; - tsk->thread.error_code = 0; - force_sig(SIGFPE, tsk); -} - -/** - * fpu_init - Initialize FPU registers - * @fpu: Pointer to software emulated FPU registers. - */ -static void fpu_init(struct sh_fpu_soft_struct *fpu) -{ - int i; - - fpu->fpscr = FPSCR_INIT; - fpu->fpul = 0; - - for (i = 0; i < 16; i++) { - fpu->fp_regs[i] = 0; - fpu->xfp_regs[i]= 0; - } -} - -/** - * do_fpu_inst - Handle reserved instructions for FPU emulation - * @inst: instruction code. - * @regs: registers on stack. - */ -int do_fpu_inst(unsigned short inst, struct pt_regs *regs) -{ - struct task_struct *tsk = current; - struct sh_fpu_soft_struct *fpu = &(tsk->thread.fpu.soft); - - if (!test_tsk_thread_flag(tsk, TIF_USEDFPU)) { - /* initialize once. */ - fpu_init(fpu); - set_tsk_thread_flag(tsk, TIF_USEDFPU); - } - - return fpu_emulate(inst, fpu, regs); -} diff --git a/trunk/arch/sh/math-emu/sfp-util.h b/trunk/arch/sh/math-emu/sfp-util.h deleted file mode 100644 index 8ae1bd310ad0..000000000000 --- a/trunk/arch/sh/math-emu/sfp-util.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * These are copied from glibc/stdlib/longlong.h - */ - -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - do { \ - UWtype __x; \ - __x = (al) + (bl); \ - (sh) = (ah) + (bh) + (__x < (al)); \ - (sl) = __x; \ - } while (0) - -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - do { \ - UWtype __x; \ - __x = (al) - (bl); \ - (sh) = (ah) - (bh) - (__x > (al)); \ - (sl) = __x; \ - } while (0) - -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("dmulu.l %2,%3\n\tsts macl,%1\n\tsts mach,%0" \ - : "=r" ((u32)(w1)), "=r" ((u32)(w0)) \ - : "r" ((u32)(u)), "r" ((u32)(v)) \ - : "macl", "mach") - -#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) -#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) -#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) - -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { \ - UWtype __d1, __d0, __q1, __q0; \ - UWtype __r1, __r0, __m; \ - __d1 = __ll_highpart (d); \ - __d0 = __ll_lowpart (d); \ - \ - __r1 = (n1) % __d1; \ - __q1 = (n1) / __d1; \ - __m = (UWtype) __q1 * __d0; \ - __r1 = __r1 * __ll_B | __ll_highpart (n0); \ - if (__r1 < __m) \ - { \ - __q1--, __r1 += (d); \ - if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ - if (__r1 < __m) \ - __q1--, __r1 += (d); \ - } \ - __r1 -= __m; \ - \ - __r0 = __r1 % __d1; \ - __q0 = __r1 / __d1; \ - __m = (UWtype) __q0 * __d0; \ - __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ - if (__r0 < __m) \ - { \ - __q0--, __r0 += (d); \ - if (__r0 >= (d)) \ - if (__r0 < __m) \ - __q0--, __r0 += (d); \ - } \ - __r0 -= __m; \ - \ - (q) = (UWtype) __q1 * __ll_B | __q0; \ - (r) = __r0; \ - } while (0) - -#define abort() return 0 - -#define __BYTE_ORDER __LITTLE_ENDIAN - - diff --git a/trunk/arch/sh/mm/Kconfig b/trunk/arch/sh/mm/Kconfig index 9dd606464d23..fb586b1cf8bb 100644 --- a/trunk/arch/sh/mm/Kconfig +++ b/trunk/arch/sh/mm/Kconfig @@ -20,10 +20,7 @@ config CPU_SH4 config CPU_SH4A bool select CPU_SH4 - -config CPU_SH4AL_DSP - bool - select CPU_SH4A + select CPU_HAS_INTC2_IRQ config CPU_SUBTYPE_ST40 bool @@ -51,12 +48,6 @@ config CPU_SUBTYPE_SH7705 select CPU_SH3 select CPU_HAS_PINT_IRQ -config CPU_SUBTYPE_SH7706 - bool "Support SH7706 processor" - select CPU_SH3 - help - Select SH7706 if you have a 133 Mhz SH-3 HD6417706 CPU. - config CPU_SUBTYPE_SH7707 bool "Support SH7707 processor" select CPU_SH3 @@ -78,12 +69,6 @@ config CPU_SUBTYPE_SH7709 help Select SH7709 if you have a 80 Mhz SH-3 HD6417709 CPU. -config CPU_SUBTYPE_SH7710 - bool "Support SH7710 processor" - select CPU_SH3 - help - Select SH7710 if you have a SH3-DSP SH7710 CPU. - comment "SH-4 Processor Support" config CPU_SUBTYPE_SH7750 @@ -148,6 +133,10 @@ config CPU_SUBTYPE_ST40GX1 comment "SH-4A Processor Support" +config CPU_SUBTYPE_SH73180 + bool "Support SH73180 processor" + select CPU_SH4A + config CPU_SUBTYPE_SH7770 bool "Support SH7770 processor" select CPU_SH4A @@ -155,17 +144,6 @@ config CPU_SUBTYPE_SH7770 config CPU_SUBTYPE_SH7780 bool "Support SH7780 processor" select CPU_SH4A - select CPU_HAS_INTC2_IRQ - -comment "SH4AL-DSP Processor Support" - -config CPU_SUBTYPE_SH73180 - bool "Support SH73180 processor" - select CPU_SH4AL_DSP - -config CPU_SUBTYPE_SH7343 - bool "Support SH7343 processor" - select CPU_SH4AL_DSP endmenu @@ -183,59 +161,15 @@ config MMU turning this off will boot the kernel on these machines with the MMU implicitly switched off. -config PAGE_OFFSET - hex - default "0x80000000" if MMU - default "0x00000000" - -config MEMORY_START - hex "Physical memory start address" - default "0x08000000" - ---help--- - Computers built with Hitachi SuperH processors always - map the ROM starting at address zero. But the processor - does not specify the range that RAM takes. - - The physical memory (RAM) start address will be automatically - set to 08000000. Other platforms, such as the Solution Engine - boards typically map RAM at 0C000000. - - Tweak this only when porting to a new machine which does not - already have a defconfig. Changing it from the known correct - value on any of the known systems will only lead to disaster. - -config MEMORY_SIZE - hex "Physical memory size" - default "0x00400000" - help - This sets the default memory size assumed by your SH kernel. It can - be overridden as normal by the 'mem=' argument on the kernel command - line. If unsure, consult your board specifications or just leave it - as 0x00400000 which was the default value before this became - configurable. - config 32BIT bool "Support 32-bit physical addressing through PMB" - depends on CPU_SH4A && MMU + depends on CPU_SH4A default y help If you say Y here, physical addressing will be extended to 32-bits through the SH-4A PMB. If this is not set, legacy 29-bit physical addressing will be used. -config VSYSCALL - bool "Support vsyscall page" - depends on MMU - default y - help - This will enable support for the kernel mapping a vDSO page - in process space, and subsequently handing down the entry point - to the libc through the ELF auxiliary vector. - - From the kernel side this is used for the signal trampoline. - For systems with an MMU that can afford to give up a page, - (the default value) say Y. - choice prompt "HugeTLB page size" depends on HUGETLB_PAGE && CPU_SH4 && MMU diff --git a/trunk/arch/sh/mm/Makefile b/trunk/arch/sh/mm/Makefile index 3ffd7f68c0a2..9489a1424644 100644 --- a/trunk/arch/sh/mm/Makefile +++ b/trunk/arch/sh/mm/Makefile @@ -6,26 +6,20 @@ obj-y := init.o extable.o consistent.o obj-$(CONFIG_CPU_SH2) += cache-sh2.o obj-$(CONFIG_CPU_SH3) += cache-sh3.o -obj-$(CONFIG_CPU_SH4) += cache-sh4.o +obj-$(CONFIG_CPU_SH4) += cache-sh4.o pg-sh4.o obj-$(CONFIG_DMA_PAGE_OPS) += pg-dma.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o mmu-y := fault-nommu.o tlb-nommu.o pg-nommu.o -mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o tlb-flush.o \ - ioremap.o +mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o obj-y += $(mmu-y) -ifdef CONFIG_DEBUG_FS -obj-$(CONFIG_CPU_SH4) += cache-debugfs.o -endif - ifdef CONFIG_MMU -obj-$(CONFIG_CPU_SH3) += tlb-sh3.o -obj-$(CONFIG_CPU_SH4) += tlb-sh4.o pg-sh4.o +obj-$(CONFIG_CPU_SH3) += tlb-sh3.o +obj-$(CONFIG_CPU_SH4) += tlb-sh4.o ioremap.o obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o endif -obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o -obj-$(CONFIG_32BIT) += pmb.o +obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o diff --git a/trunk/arch/sh/mm/cache-debugfs.c b/trunk/arch/sh/mm/cache-debugfs.c deleted file mode 100644 index a22d914e4d15..000000000000 --- a/trunk/arch/sh/mm/cache-debugfs.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * debugfs ops for the L1 cache - * - * Copyright (C) 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -enum cache_type { - CACHE_TYPE_ICACHE, - CACHE_TYPE_DCACHE, - CACHE_TYPE_UNIFIED, -}; - -static int cache_seq_show(struct seq_file *file, void *iter) -{ - unsigned int cache_type = (unsigned int)file->private; - struct cache_info *cache; - unsigned int waysize, way, cache_size; - unsigned long ccr, base; - static unsigned long addrstart = 0; - - /* - * Go uncached immediately so we don't skew the results any - * more than we already are.. - */ - jump_to_P2(); - - ccr = ctrl_inl(CCR); - if ((ccr & CCR_CACHE_ENABLE) == 0) { - back_to_P1(); - - seq_printf(file, "disabled\n"); - return 0; - } - - if (cache_type == CACHE_TYPE_DCACHE) { - base = CACHE_OC_ADDRESS_ARRAY; - cache = &cpu_data->dcache; - } else { - base = CACHE_IC_ADDRESS_ARRAY; - cache = &cpu_data->icache; - } - - /* - * Due to the amount of data written out (depending on the cache size), - * we may be iterated over multiple times. In this case, keep track of - * the entry position in addrstart, and rewind it when we've hit the - * end of the cache. - * - * Likewise, the same code is used for multiple caches, so care must - * be taken for bouncing addrstart back and forth so the appropriate - * cache is hit. - */ - cache_size = cache->ways * cache->sets * cache->linesz; - if (((addrstart & 0xff000000) != base) || - (addrstart & 0x00ffffff) > cache_size) - addrstart = base; - - waysize = cache->sets; - - /* - * If the OC is already in RAM mode, we only have - * half of the entries to consider.. - */ - if ((ccr & CCR_CACHE_ORA) && cache_type == CACHE_TYPE_DCACHE) - waysize >>= 1; - - waysize <<= cache->entry_shift; - - for (way = 0; way < cache->ways; way++) { - unsigned long addr; - unsigned int line; - - seq_printf(file, "-----------------------------------------\n"); - seq_printf(file, "Way %d\n", way); - seq_printf(file, "-----------------------------------------\n"); - - for (addr = addrstart, line = 0; - addr < addrstart + waysize; - addr += cache->linesz, line++) { - unsigned long data = ctrl_inl(addr); - - /* Check the V bit, ignore invalid cachelines */ - if ((data & 1) == 0) - continue; - - /* U: Dirty, cache tag is 10 bits up */ - seq_printf(file, "%3d: %c 0x%lx\n", - line, data & 2 ? 'U' : ' ', - data & 0x1ffffc00); - } - - addrstart += cache->way_incr; - } - - back_to_P1(); - - return 0; -} - -static int cache_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, cache_seq_show, inode->u.generic_ip); -} - -static struct file_operations cache_debugfs_fops = { - .owner = THIS_MODULE, - .open = cache_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static int __init cache_debugfs_init(void) -{ - struct dentry *dcache_dentry, *icache_dentry; - - dcache_dentry = debugfs_create_file("dcache", S_IRUSR, NULL, - (unsigned int *)CACHE_TYPE_DCACHE, - &cache_debugfs_fops); - if (IS_ERR(dcache_dentry)) - return PTR_ERR(dcache_dentry); - - icache_dentry = debugfs_create_file("icache", S_IRUSR, NULL, - (unsigned int *)CACHE_TYPE_ICACHE, - &cache_debugfs_fops); - if (IS_ERR(icache_dentry)) { - debugfs_remove(dcache_dentry); - return PTR_ERR(icache_dentry); - } - - return 0; -} -module_init(cache_debugfs_init); - -MODULE_LICENSE("GPL v2"); diff --git a/trunk/arch/sh/mm/cache-sh4.c b/trunk/arch/sh/mm/cache-sh4.c index e48cc22724d9..524cea5b47f9 100644 --- a/trunk/arch/sh/mm/cache-sh4.c +++ b/trunk/arch/sh/mm/cache-sh4.c @@ -2,120 +2,49 @@ * arch/sh/mm/cache-sh4.c * * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2001 - 2006 Paul Mundt + * Copyright (C) 2001, 2002, 2003, 2004 Paul Mundt * Copyright (C) 2003 Richard Curnow * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ + #include +#include #include +#include #include +#include #include #include #include #include +#include #include #include #include -/* - * The maximum number of pages we support up to when doing ranged dcache - * flushing. Anything exceeding this will simply flush the dcache in its - * entirety. - */ -#define MAX_DCACHE_PAGES 64 /* XXX: Tune for ways */ - -static void __flush_dcache_segment_1way(unsigned long start, - unsigned long extent); -static void __flush_dcache_segment_2way(unsigned long start, - unsigned long extent); -static void __flush_dcache_segment_4way(unsigned long start, - unsigned long extent); - -static void __flush_cache_4096(unsigned long addr, unsigned long phys, - unsigned long exec_offset); - -/* - * This is initialised here to ensure that it is not placed in the BSS. If - * that were to happen, note that cache_init gets called before the BSS is - * cleared, so this would get nulled out which would be hopeless. - */ -static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) = - (void (*)(unsigned long, unsigned long))0xdeadbeef; - -static void compute_alias(struct cache_info *c) -{ - c->alias_mask = ((c->sets - 1) << c->entry_shift) & ~(PAGE_SIZE - 1); - c->n_aliases = (c->alias_mask >> PAGE_SHIFT) + 1; -} - -static void __init emit_cache_params(void) -{ - printk("PVR=%08x CVR=%08x PRR=%08x\n", - ctrl_inl(CCN_PVR), - ctrl_inl(CCN_CVR), - ctrl_inl(CCN_PRR)); - printk("I-cache : n_ways=%d n_sets=%d way_incr=%d\n", - cpu_data->icache.ways, - cpu_data->icache.sets, - cpu_data->icache.way_incr); - printk("I-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n", - cpu_data->icache.entry_mask, - cpu_data->icache.alias_mask, - cpu_data->icache.n_aliases); - printk("D-cache : n_ways=%d n_sets=%d way_incr=%d\n", - cpu_data->dcache.ways, - cpu_data->dcache.sets, - cpu_data->dcache.way_incr); - printk("D-cache : entry_mask=0x%08x alias_mask=0x%08x n_aliases=%d\n", - cpu_data->dcache.entry_mask, - cpu_data->dcache.alias_mask, - cpu_data->dcache.n_aliases); - - if (!__flush_dcache_segment_fn) - panic("unknown number of cache ways\n"); -} +extern void __flush_cache_4096_all(unsigned long start); +static void __flush_cache_4096_all_ex(unsigned long start); +extern void __flush_dcache_all(void); +static void __flush_dcache_all_ex(void); /* * SH-4 has virtually indexed and physically tagged cache. */ -/* Worst case assumed to be 64k cache, direct-mapped i.e. 4 synonym bits. */ -#define MAX_P3_SEMAPHORES 16 - -struct semaphore p3map_sem[MAX_P3_SEMAPHORES]; +struct semaphore p3map_sem[4]; void __init p3_cache_init(void) { - int i; - - compute_alias(&cpu_data->icache); - compute_alias(&cpu_data->dcache); - - switch (cpu_data->dcache.ways) { - case 1: - __flush_dcache_segment_fn = __flush_dcache_segment_1way; - break; - case 2: - __flush_dcache_segment_fn = __flush_dcache_segment_2way; - break; - case 4: - __flush_dcache_segment_fn = __flush_dcache_segment_4way; - break; - default: - __flush_dcache_segment_fn = NULL; - break; - } - - emit_cache_params(); - - if (remap_area_pages(P3SEG, 0, PAGE_SIZE * 4, _PAGE_CACHABLE)) + if (remap_area_pages(P3SEG, 0, PAGE_SIZE*4, _PAGE_CACHABLE)) panic("%s failed.", __FUNCTION__); - for (i = 0; i < cpu_data->dcache.n_aliases; i++) - sema_init(&p3map_sem[i], 1); + sema_init (&p3map_sem[0], 1); + sema_init (&p3map_sem[1], 1); + sema_init (&p3map_sem[2], 1); + sema_init (&p3map_sem[3], 1); } /* @@ -160,6 +89,7 @@ void __flush_purge_region(void *start, int size) } } + /* * No write back please */ @@ -178,6 +108,40 @@ void __flush_invalidate_region(void *start, int size) } } +static void __flush_dcache_all_ex(void) +{ + unsigned long addr, end_addr, entry_offset; + + end_addr = CACHE_OC_ADDRESS_ARRAY + (cpu_data->dcache.sets << cpu_data->dcache.entry_shift) * cpu_data->dcache.ways; + entry_offset = 1 << cpu_data->dcache.entry_shift; + for (addr = CACHE_OC_ADDRESS_ARRAY; addr < end_addr; addr += entry_offset) { + ctrl_outl(0, addr); + } +} + +static void __flush_cache_4096_all_ex(unsigned long start) +{ + unsigned long addr, entry_offset; + int i; + + entry_offset = 1 << cpu_data->dcache.entry_shift; + for (i = 0; i < cpu_data->dcache.ways; i++, start += cpu_data->dcache.way_incr) { + for (addr = CACHE_OC_ADDRESS_ARRAY + start; + addr < CACHE_OC_ADDRESS_ARRAY + 4096 + start; + addr += entry_offset) { + ctrl_outl(0, addr); + } + } +} + +void flush_cache_4096_all(unsigned long start) +{ + if (cpu_data->dcache.ways == 1) + __flush_cache_4096_all(start); + else + __flush_cache_4096_all_ex(start); +} + /* * Write back the range of D-cache, and purge the I-cache. * @@ -189,14 +153,14 @@ void flush_icache_range(unsigned long start, unsigned long end) } /* - * Write back the D-cache and purge the I-cache for signal trampoline. + * Write back the D-cache and purge the I-cache for signal trampoline. * .. which happens to be the same behavior as flush_icache_range(). * So, we simply flush out a line. */ void flush_cache_sigtramp(unsigned long addr) { unsigned long v, index; - unsigned long flags; + unsigned long flags; int i; v = addr & ~(L1_CACHE_BYTES-1); @@ -208,33 +172,30 @@ void flush_cache_sigtramp(unsigned long addr) local_irq_save(flags); jump_to_P2(); - - for (i = 0; i < cpu_data->icache.ways; - i++, index += cpu_data->icache.way_incr) + for(i = 0; i < cpu_data->icache.ways; i++, index += cpu_data->icache.way_incr) ctrl_outl(0, index); /* Clear out Valid-bit */ - back_to_P1(); - wmb(); local_irq_restore(flags); } static inline void flush_cache_4096(unsigned long start, unsigned long phys) { - unsigned long flags, exec_offset = 0; + unsigned long flags; + extern void __flush_cache_4096(unsigned long addr, unsigned long phys, unsigned long exec_offset); /* - * All types of SH-4 require PC to be in P2 to operate on the I-cache. - * Some types of SH-4 require PC to be in P2 to operate on the D-cache. + * SH7751, SH7751R, and ST40 have no restriction to handle cache. + * (While SH7750 must do that at P2 area.) */ - if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) || - (start < CACHE_OC_ADDRESS_ARRAY)) - exec_offset = 0x20000000; - - local_irq_save(flags); - __flush_cache_4096(start | SH_CACHE_ASSOC, - P1SEGADDR(phys), exec_offset); - local_irq_restore(flags); + if ((cpu_data->flags & CPU_HAS_P2_FLUSH_BUG) + || start < CACHE_OC_ADDRESS_ARRAY) { + local_irq_save(flags); + __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0x20000000); + local_irq_restore(flags); + } else { + __flush_cache_4096(start | SH_CACHE_ASSOC, P1SEGADDR(phys), 0); + } } /* @@ -245,19 +206,15 @@ void flush_dcache_page(struct page *page) { if (test_bit(PG_mapped, &page->flags)) { unsigned long phys = PHYSADDR(page_address(page)); - unsigned long addr = CACHE_OC_ADDRESS_ARRAY; - int i, n; /* Loop all the D-cache */ - n = cpu_data->dcache.n_aliases; - for (i = 0; i < n; i++, addr += PAGE_SIZE) - flush_cache_4096(addr, phys); + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY, phys); + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x1000, phys); + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x2000, phys); + flush_cache_4096(CACHE_OC_ADDRESS_ARRAY | 0x3000, phys); } - - wmb(); } -/* TODO: Selective icache invalidation through IC address array.. */ static inline void flush_icache_all(void) { unsigned long flags, ccr; @@ -270,142 +227,34 @@ static inline void flush_icache_all(void) ccr |= CCR_CACHE_ICI; ctrl_outl(ccr, CCR); - /* - * back_to_P1() will take care of the barrier for us, don't add - * another one! - */ - back_to_P1(); local_irq_restore(flags); } -void flush_dcache_all(void) -{ - (*__flush_dcache_segment_fn)(0UL, cpu_data->dcache.way_size); - wmb(); -} - void flush_cache_all(void) { - flush_dcache_all(); + if (cpu_data->dcache.ways == 1) + __flush_dcache_all(); + else + __flush_dcache_all_ex(); flush_icache_all(); } -static void __flush_cache_mm(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - unsigned long d = 0, p = start & PAGE_MASK; - unsigned long alias_mask = cpu_data->dcache.alias_mask; - unsigned long n_aliases = cpu_data->dcache.n_aliases; - unsigned long select_bit; - unsigned long all_aliases_mask; - unsigned long addr_offset; - pgd_t *dir; - pmd_t *pmd; - pud_t *pud; - pte_t *pte; - int i; - - dir = pgd_offset(mm, p); - pud = pud_offset(dir, p); - pmd = pmd_offset(pud, p); - end = PAGE_ALIGN(end); - - all_aliases_mask = (1 << n_aliases) - 1; - - do { - if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) { - p &= PMD_MASK; - p += PMD_SIZE; - pmd++; - - continue; - } - - pte = pte_offset_kernel(pmd, p); - - do { - unsigned long phys; - pte_t entry = *pte; - - if (!(pte_val(entry) & _PAGE_PRESENT)) { - pte++; - p += PAGE_SIZE; - continue; - } - - phys = pte_val(entry) & PTE_PHYS_MASK; - - if ((p ^ phys) & alias_mask) { - d |= 1 << ((p & alias_mask) >> PAGE_SHIFT); - d |= 1 << ((phys & alias_mask) >> PAGE_SHIFT); - - if (d == all_aliases_mask) - goto loop_exit; - } - - pte++; - p += PAGE_SIZE; - } while (p < end && ((unsigned long)pte & ~PAGE_MASK)); - pmd++; - } while (p < end); - -loop_exit: - addr_offset = 0; - select_bit = 1; - - for (i = 0; i < n_aliases; i++) { - if (d & select_bit) { - (*__flush_dcache_segment_fn)(addr_offset, PAGE_SIZE); - wmb(); - } - - select_bit <<= 1; - addr_offset += PAGE_SIZE; - } -} - -/* - * Note : (RPC) since the caches are physically tagged, the only point - * of flush_cache_mm for SH-4 is to get rid of aliases from the - * D-cache. The assumption elsewhere, e.g. flush_cache_range, is that - * lines can stay resident so long as the virtual address they were - * accessed with (hence cache set) is in accord with the physical - * address (i.e. tag). It's no different here. So I reckon we don't - * need to flush the I-cache, since aliases don't matter for that. We - * should try that. - * - * Caller takes mm->mmap_sem. - */ void flush_cache_mm(struct mm_struct *mm) { - /* - * If cache is only 4k-per-way, there are never any 'aliases'. Since - * the cache is physically tagged, the data can just be left in there. - */ - if (cpu_data->dcache.n_aliases == 0) - return; - - /* - * Don't bother groveling around the dcache for the VMA ranges - * if there are too many PTEs to make it worthwhile. + /* Is there any good way? */ + /* XXX: possibly call flush_cache_range for each vm area */ + /* + * FIXME: Really, the optimal solution here would be able to flush out + * individual lines created by the specified context, but this isn't + * feasible for a number of architectures (such as MIPS, and some + * SPARC) .. is this possible for SuperH? + * + * In the meantime, we'll just flush all of the caches.. this + * seems to be the simplest way to avoid at least a few wasted + * cache flushes. -Lethal */ - if (mm->nr_ptes >= MAX_DCACHE_PAGES) - flush_dcache_all(); - else { - struct vm_area_struct *vma; - - /* - * In this case there are reasonably sized ranges to flush, - * iterate through the VMA list and take care of any aliases. - */ - for (vma = mm->mmap; vma; vma = vma->vm_next) - __flush_cache_mm(mm, vma->vm_start, vma->vm_end); - } - - /* Only touch the icache if one of the VMAs has VM_EXEC set. */ - if (mm->exec_vm) - flush_icache_all(); + flush_cache_all(); } /* @@ -414,40 +263,27 @@ void flush_cache_mm(struct mm_struct *mm) * ADDR: Virtual Address (U0 address) * PFN: Physical page number */ -void flush_cache_page(struct vm_area_struct *vma, unsigned long address, - unsigned long pfn) +void flush_cache_page(struct vm_area_struct *vma, unsigned long address, unsigned long pfn) { unsigned long phys = pfn << PAGE_SHIFT; - unsigned int alias_mask; - - alias_mask = cpu_data->dcache.alias_mask; /* We only need to flush D-cache when we have alias */ - if ((address^phys) & alias_mask) { + if ((address^phys) & CACHE_ALIAS) { /* Loop 4K of the D-cache */ flush_cache_4096( - CACHE_OC_ADDRESS_ARRAY | (address & alias_mask), + CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS), phys); /* Loop another 4K of the D-cache */ flush_cache_4096( - CACHE_OC_ADDRESS_ARRAY | (phys & alias_mask), + CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS), phys); } - alias_mask = cpu_data->icache.alias_mask; - if (vma->vm_flags & VM_EXEC) { - /* - * Evict entries from the portion of the cache from which code - * may have been executed at this address (virtual). There's - * no need to evict from the portion corresponding to the - * physical address as for the D-cache, because we know the - * kernel has never executed the code through its identity - * translation. - */ + if (vma->vm_flags & VM_EXEC) + /* Loop 4K (half) of the I-cache */ flush_cache_4096( - CACHE_IC_ADDRESS_ARRAY | (address & alias_mask), + CACHE_IC_ADDRESS_ARRAY | (address & 0x1000), phys); - } } /* @@ -462,31 +298,52 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address, void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - /* - * If cache is only 4k-per-way, there are never any 'aliases'. Since - * the cache is physically tagged, the data can just be left in there. - */ - if (cpu_data->dcache.n_aliases == 0) - return; + unsigned long p = start & PAGE_MASK; + pgd_t *dir; + pmd_t *pmd; + pte_t *pte; + pte_t entry; + unsigned long phys; + unsigned long d = 0; - /* - * Don't bother with the lookup and alias check if we have a - * wide range to cover, just blow away the dcache in its - * entirety instead. -- PFM. - */ - if (((end - start) >> PAGE_SHIFT) >= MAX_DCACHE_PAGES) - flush_dcache_all(); - else - __flush_cache_mm(vma->vm_mm, start, end); - - if (vma->vm_flags & VM_EXEC) { - /* - * TODO: Is this required??? Need to look at how I-cache - * coherency is assured when new programs are loaded to see if - * this matters. - */ + dir = pgd_offset(vma->vm_mm, p); + pmd = pmd_offset(dir, p); + + do { + if (pmd_none(*pmd) || pmd_bad(*pmd)) { + p &= ~((1 << PMD_SHIFT) -1); + p += (1 << PMD_SHIFT); + pmd++; + continue; + } + pte = pte_offset_kernel(pmd, p); + do { + entry = *pte; + if ((pte_val(entry) & _PAGE_PRESENT)) { + phys = pte_val(entry)&PTE_PHYS_MASK; + if ((p^phys) & CACHE_ALIAS) { + d |= 1 << ((p & CACHE_ALIAS)>>12); + d |= 1 << ((phys & CACHE_ALIAS)>>12); + if (d == 0x0f) + goto loop_exit; + } + } + pte++; + p += PAGE_SIZE; + } while (p < end && ((unsigned long)pte & ~PAGE_MASK)); + pmd++; + } while (p < end); + loop_exit: + if (d & 1) + flush_cache_4096_all(0); + if (d & 2) + flush_cache_4096_all(0x1000); + if (d & 4) + flush_cache_4096_all(0x2000); + if (d & 8) + flush_cache_4096_all(0x3000); + if (vma->vm_flags & VM_EXEC) flush_icache_all(); - } } /* @@ -500,273 +357,5 @@ void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, unsigned long addr, int len) { flush_cache_page(vma, addr, page_to_pfn(page)); - mb(); -} - -/** - * __flush_cache_4096 - * - * @addr: address in memory mapped cache array - * @phys: P1 address to flush (has to match tags if addr has 'A' bit - * set i.e. associative write) - * @exec_offset: set to 0x20000000 if flush has to be executed from P2 - * region else 0x0 - * - * The offset into the cache array implied by 'addr' selects the - * 'colour' of the virtual address range that will be flushed. The - * operation (purge/write-back) is selected by the lower 2 bits of - * 'phys'. - */ -static void __flush_cache_4096(unsigned long addr, unsigned long phys, - unsigned long exec_offset) -{ - int way_count; - unsigned long base_addr = addr; - struct cache_info *dcache; - unsigned long way_incr; - unsigned long a, ea, p; - unsigned long temp_pc; - - dcache = &cpu_data->dcache; - /* Write this way for better assembly. */ - way_count = dcache->ways; - way_incr = dcache->way_incr; - - /* - * Apply exec_offset (i.e. branch to P2 if required.). - * - * FIXME: - * - * If I write "=r" for the (temp_pc), it puts this in r6 hence - * trashing exec_offset before it's been added on - why? Hence - * "=&r" as a 'workaround' - */ - asm volatile("mov.l 1f, %0\n\t" - "add %1, %0\n\t" - "jmp @%0\n\t" - "nop\n\t" - ".balign 4\n\t" - "1: .long 2f\n\t" - "2:\n" : "=&r" (temp_pc) : "r" (exec_offset)); - - /* - * We know there will be >=1 iteration, so write as do-while to avoid - * pointless nead-of-loop check for 0 iterations. - */ - do { - ea = base_addr + PAGE_SIZE; - a = base_addr; - p = phys; - - do { - *(volatile unsigned long *)a = p; - /* - * Next line: intentionally not p+32, saves an add, p - * will do since only the cache tag bits need to - * match. - */ - *(volatile unsigned long *)(a+32) = p; - a += 64; - p += 64; - } while (a < ea); - - base_addr += way_incr; - } while (--way_count != 0); } -/* - * Break the 1, 2 and 4 way variants of this out into separate functions to - * avoid nearly all the overhead of having the conditional stuff in the function - * bodies (+ the 1 and 2 way cases avoid saving any registers too). - */ -static void __flush_dcache_segment_1way(unsigned long start, - unsigned long extent_per_way) -{ - unsigned long orig_sr, sr_with_bl; - unsigned long base_addr; - unsigned long way_incr, linesz, way_size; - struct cache_info *dcache; - register unsigned long a0, a0e; - - asm volatile("stc sr, %0" : "=r" (orig_sr)); - sr_with_bl = orig_sr | (1<<28); - base_addr = ((unsigned long)&empty_zero_page[0]); - - /* - * The previous code aligned base_addr to 16k, i.e. the way_size of all - * existing SH-4 D-caches. Whilst I don't see a need to have this - * aligned to any better than the cache line size (which it will be - * anyway by construction), let's align it to at least the way_size of - * any existing or conceivable SH-4 D-cache. -- RPC - */ - base_addr = ((base_addr >> 16) << 16); - base_addr |= start; - - dcache = &cpu_data->dcache; - linesz = dcache->linesz; - way_incr = dcache->way_incr; - way_size = dcache->way_size; - - a0 = base_addr; - a0e = base_addr + extent_per_way; - do { - asm volatile("ldc %0, sr" : : "r" (sr_with_bl)); - asm volatile("movca.l r0, @%0\n\t" - "ocbi @%0" : : "r" (a0)); - a0 += linesz; - asm volatile("movca.l r0, @%0\n\t" - "ocbi @%0" : : "r" (a0)); - a0 += linesz; - asm volatile("movca.l r0, @%0\n\t" - "ocbi @%0" : : "r" (a0)); - a0 += linesz; - asm volatile("movca.l r0, @%0\n\t" - "ocbi @%0" : : "r" (a0)); - asm volatile("ldc %0, sr" : : "r" (orig_sr)); - a0 += linesz; - } while (a0 < a0e); -} - -static void __flush_dcache_segment_2way(unsigned long start, - unsigned long extent_per_way) -{ - unsigned long orig_sr, sr_with_bl; - unsigned long base_addr; - unsigned long way_incr, linesz, way_size; - struct cache_info *dcache; - register unsigned long a0, a1, a0e; - - asm volatile("stc sr, %0" : "=r" (orig_sr)); - sr_with_bl = orig_sr | (1<<28); - base_addr = ((unsigned long)&empty_zero_page[0]); - - /* See comment under 1-way above */ - base_addr = ((base_addr >> 16) << 16); - base_addr |= start; - - dcache = &cpu_data->dcache; - linesz = dcache->linesz; - way_incr = dcache->way_incr; - way_size = dcache->way_size; - - a0 = base_addr; - a1 = a0 + way_incr; - a0e = base_addr + extent_per_way; - do { - asm volatile("ldc %0, sr" : : "r" (sr_with_bl)); - asm volatile("movca.l r0, @%0\n\t" - "movca.l r0, @%1\n\t" - "ocbi @%0\n\t" - "ocbi @%1" : : - "r" (a0), "r" (a1)); - a0 += linesz; - a1 += linesz; - asm volatile("movca.l r0, @%0\n\t" - "movca.l r0, @%1\n\t" - "ocbi @%0\n\t" - "ocbi @%1" : : - "r" (a0), "r" (a1)); - a0 += linesz; - a1 += linesz; - asm volatile("movca.l r0, @%0\n\t" - "movca.l r0, @%1\n\t" - "ocbi @%0\n\t" - "ocbi @%1" : : - "r" (a0), "r" (a1)); - a0 += linesz; - a1 += linesz; - asm volatile("movca.l r0, @%0\n\t" - "movca.l r0, @%1\n\t" - "ocbi @%0\n\t" - "ocbi @%1" : : - "r" (a0), "r" (a1)); - asm volatile("ldc %0, sr" : : "r" (orig_sr)); - a0 += linesz; - a1 += linesz; - } while (a0 < a0e); -} - -static void __flush_dcache_segment_4way(unsigned long start, - unsigned long extent_per_way) -{ - unsigned long orig_sr, sr_with_bl; - unsigned long base_addr; - unsigned long way_incr, linesz, way_size; - struct cache_info *dcache; - register unsigned long a0, a1, a2, a3, a0e; - - asm volatile("stc sr, %0" : "=r" (orig_sr)); - sr_with_bl = orig_sr | (1<<28); - base_addr = ((unsigned long)&empty_zero_page[0]); - - /* See comment under 1-way above */ - base_addr = ((base_addr >> 16) << 16); - base_addr |= start; - - dcache = &cpu_data->dcache; - linesz = dcache->linesz; - way_incr = dcache->way_incr; - way_size = dcache->way_size; - - a0 = base_addr; - a1 = a0 + way_incr; - a2 = a1 + way_incr; - a3 = a2 + way_incr; - a0e = base_addr + extent_per_way; - do { - asm volatile("ldc %0, sr" : : "r" (sr_with_bl)); - asm volatile("movca.l r0, @%0\n\t" - "movca.l r0, @%1\n\t" - "movca.l r0, @%2\n\t" - "movca.l r0, @%3\n\t" - "ocbi @%0\n\t" - "ocbi @%1\n\t" - "ocbi @%2\n\t" - "ocbi @%3\n\t" : : - "r" (a0), "r" (a1), "r" (a2), "r" (a3)); - a0 += linesz; - a1 += linesz; - a2 += linesz; - a3 += linesz; - asm volatile("movca.l r0, @%0\n\t" - "movca.l r0, @%1\n\t" - "movca.l r0, @%2\n\t" - "movca.l r0, @%3\n\t" - "ocbi @%0\n\t" - "ocbi @%1\n\t" - "ocbi @%2\n\t" - "ocbi @%3\n\t" : : - "r" (a0), "r" (a1), "r" (a2), "r" (a3)); - a0 += linesz; - a1 += linesz; - a2 += linesz; - a3 += linesz; - asm volatile("movca.l r0, @%0\n\t" - "movca.l r0, @%1\n\t" - "movca.l r0, @%2\n\t" - "movca.l r0, @%3\n\t" - "ocbi @%0\n\t" - "ocbi @%1\n\t" - "ocbi @%2\n\t" - "ocbi @%3\n\t" : : - "r" (a0), "r" (a1), "r" (a2), "r" (a3)); - a0 += linesz; - a1 += linesz; - a2 += linesz; - a3 += linesz; - asm volatile("movca.l r0, @%0\n\t" - "movca.l r0, @%1\n\t" - "movca.l r0, @%2\n\t" - "movca.l r0, @%3\n\t" - "ocbi @%0\n\t" - "ocbi @%1\n\t" - "ocbi @%2\n\t" - "ocbi @%3\n\t" : : - "r" (a0), "r" (a1), "r" (a2), "r" (a3)); - asm volatile("ldc %0, sr" : : "r" (orig_sr)); - a0 += linesz; - a1 += linesz; - a2 += linesz; - a3 += linesz; - } while (a0 < a0e); -} diff --git a/trunk/arch/sh/mm/cache-sh7705.c b/trunk/arch/sh/mm/cache-sh7705.c index 045abdf078f5..bf94eedb0a8e 100644 --- a/trunk/arch/sh/mm/cache-sh7705.c +++ b/trunk/arch/sh/mm/cache-sh7705.c @@ -9,6 +9,7 @@ * for more details. * */ + #include #include #include @@ -24,10 +25,14 @@ #include #include -/* - * The 32KB cache on the SH7705 suffers from the same synonym problem - * as SH4 CPUs - */ +/* The 32KB cache on the SH7705 suffers from the same synonym problem + * as SH4 CPUs */ + +#define __pte_offset(address) \ + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) +#define pte_offset(dir, address) ((pte_t *) pmd_page_vaddr(*(dir)) + \ + __pte_offset(address)) + static inline void cache_wback_all(void) { unsigned long ways, waysize, addrstart; @@ -68,6 +73,7 @@ void flush_icache_range(unsigned long start, unsigned long end) __flush_wback_region((void *)start, end - start); } + /* * Writeback&Invalidate the D-cache of the page */ @@ -122,6 +128,7 @@ static void __flush_dcache_page(unsigned long phys) local_irq_restore(flags); } + /* * Write back & invalidate the D-cache of the page. * (To avoid "alias" issues) @@ -179,8 +186,7 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, * * ADDRESS: Virtual Address (U0 address) */ -void flush_cache_page(struct vm_area_struct *vma, unsigned long address, - unsigned long pfn) +void flush_cache_page(struct vm_area_struct *vma, unsigned long address, unsigned long pfn) { __flush_dcache_page(pfn << PAGE_SHIFT); } @@ -197,3 +203,4 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *page) { __flush_purge_region(page_address(page), PAGE_SIZE); } + diff --git a/trunk/arch/sh/mm/clear_page.S b/trunk/arch/sh/mm/clear_page.S index 7b96425ae270..08acead7b2a1 100644 --- a/trunk/arch/sh/mm/clear_page.S +++ b/trunk/arch/sh/mm/clear_page.S @@ -193,5 +193,102 @@ ENTRY(__clear_user_page) nop .L4096: .word 4096 -#endif +ENTRY(__flush_cache_4096) + mov.l 1f,r3 + add r6,r3 + mov r4,r0 + mov #64,r2 + shll r2 + mov #64,r6 + jmp @r3 + mov #96,r7 + .align 2 +1: .long 2f +2: + .rept 32 + mov.l r5,@r0 + mov.l r5,@(32,r0) + mov.l r5,@(r0,r6) + mov.l r5,@(r0,r7) + add r2,r5 + add r2,r0 + .endr + nop + nop + nop + nop + nop + nop + nop + rts + nop +ENTRY(__flush_dcache_all) + mov.l 2f,r0 + mov.l 3f,r4 + and r0,r4 ! r4 = (unsigned long)&empty_zero_page[0] & ~0xffffc000 + stc sr,r1 ! save SR + mov.l 4f,r2 + or r1,r2 + mov #32,r3 + shll2 r3 +1: + ldc r2,sr ! set BL bit + movca.l r0,@r4 + ocbi @r4 + add #32,r4 + movca.l r0,@r4 + ocbi @r4 + add #32,r4 + movca.l r0,@r4 + ocbi @r4 + add #32,r4 + movca.l r0,@r4 + ocbi @r4 + ldc r1,sr ! restore SR + dt r3 + bf/s 1b + add #32,r4 + + rts + nop + .align 2 +2: .long 0xffffc000 +3: .long empty_zero_page +4: .long 0x10000000 ! BL bit + +/* __flush_cache_4096_all(unsigned long addr) */ +ENTRY(__flush_cache_4096_all) + mov.l 2f,r0 + mov.l 3f,r2 + and r0,r2 + or r2,r4 ! r4 = addr | (unsigned long)&empty_zero_page[0] & ~0x3fff + stc sr,r1 ! save SR + mov.l 4f,r2 + or r1,r2 + mov #32,r3 +1: + ldc r2,sr ! set BL bit + movca.l r0,@r4 + ocbi @r4 + add #32,r4 + movca.l r0,@r4 + ocbi @r4 + add #32,r4 + movca.l r0,@r4 + ocbi @r4 + add #32,r4 + movca.l r0,@r4 + ocbi @r4 + ldc r1,sr ! restore SR + dt r3 + bf/s 1b + add #32,r4 + + rts + nop + .align 2 +2: .long 0xffffc000 +3: .long empty_zero_page +4: .long 0x10000000 ! BL bit +#endif diff --git a/trunk/arch/sh/mm/consistent.c b/trunk/arch/sh/mm/consistent.c index c81e6b67ad30..ee73e30263af 100644 --- a/trunk/arch/sh/mm/consistent.c +++ b/trunk/arch/sh/mm/consistent.c @@ -9,8 +9,6 @@ */ #include #include -#include -#include #include void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *handle) diff --git a/trunk/arch/sh/mm/fault.c b/trunk/arch/sh/mm/fault.c index 68663b8f99ae..775f86cd3fe8 100644 --- a/trunk/arch/sh/mm/fault.c +++ b/trunk/arch/sh/mm/fault.c @@ -1,22 +1,33 @@ -/* - * Page fault handler for SH with an MMU. +/* $Id: fault.c,v 1.14 2004/01/13 05:52:11 kkojima Exp $ * + * linux/arch/sh/mm/fault.c * Copyright (C) 1999 Niibe Yutaka * Copyright (C) 2003 Paul Mundt * * Based on linux/arch/i386/mm/fault.c: * Copyright (C) 1995 Linus Torvalds - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. */ + +#include +#include #include +#include +#include +#include +#include +#include #include -#include -#include +#include +#include +#include +#include + #include +#include +#include +#include #include +#include #include extern void die(const char *,struct pt_regs *,long); @@ -69,7 +80,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, if (!(vma->vm_flags & VM_WRITE)) goto bad_area; } else { - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } @@ -149,7 +160,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_init(current)) { + if (current->pid == 1) { yield(); down_read(&mm->mmap_sem); goto survive; @@ -176,30 +187,18 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, goto no_context; } -#ifdef CONFIG_SH_STORE_QUEUES /* - * This is a special case for the SH-4 store queues, as pages for this - * space still need to be faulted in before it's possible to flush the - * store queue cache for writeout to the remapped region. + * Called with interrupt disabled. */ -#define P3_ADDR_MAX (P4SEG_STORE_QUE + 0x04000000) -#else -#define P3_ADDR_MAX P4SEG -#endif - -/* - * Called with interrupts disabled. - */ -asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, - unsigned long writeaccess, - unsigned long address) +asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess, + unsigned long address) { + unsigned long addrmax = P4SEG; pgd_t *pgd; - pud_t *pud; pmd_t *pmd; pte_t *pte; pte_t entry; - struct mm_struct *mm = current->mm; + struct mm_struct *mm; spinlock_t *ptl; int ret = 1; @@ -208,37 +207,31 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, kgdb_bus_err_hook(); #endif - /* - * We don't take page faults for P1, P2, and parts of P4, these - * are always mapped, whether it be due to legacy behaviour in - * 29-bit mode, or due to PMB configuration in 32-bit mode. - */ - if (address >= P3SEG && address < P3_ADDR_MAX) { +#ifdef CONFIG_SH_STORE_QUEUES + addrmax = P4SEG_STORE_QUE + 0x04000000; +#endif + + if (address >= P3SEG && address < addrmax) { pgd = pgd_offset_k(address); mm = NULL; - } else { - if (unlikely(address >= TASK_SIZE || !mm)) - return 1; - + } else if (address >= TASK_SIZE) + return 1; + else if (!(mm = current->mm)) + return 1; + else pgd = pgd_offset(mm, address); - } - pud = pud_offset(pgd, address); - if (pud_none_or_clear_bad(pud)) - return 1; - pmd = pmd_offset(pud, address); + pmd = pmd_offset(pgd, address); if (pmd_none_or_clear_bad(pmd)) return 1; - if (mm) pte = pte_offset_map_lock(mm, pmd, address, &ptl); else pte = pte_offset_kernel(pmd, address); entry = *pte; - if (unlikely(pte_none(entry) || pte_not_present(entry))) - goto unlock; - if (unlikely(writeaccess && !pte_write(entry))) + if (pte_none(entry) || pte_not_present(entry) + || (writeaccess && !pte_write(entry))) goto unlock; if (writeaccess) @@ -250,7 +243,13 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, * ITLB is not affected by "ldtlb" instruction. * So, we need to flush the entry by ourselves. */ - __flush_tlb_page(get_asid(), address & PAGE_MASK); + + { + unsigned long flags; + local_irq_save(flags); + __flush_tlb_page(get_asid(), address&PAGE_MASK); + local_irq_restore(flags); + } #endif set_pte(pte, entry); @@ -261,3 +260,121 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, pte_unmap_unlock(pte, ptl); return ret; } + +void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) +{ + if (vma->vm_mm && vma->vm_mm->context != NO_CONTEXT) { + unsigned long flags; + unsigned long asid; + unsigned long saved_asid = MMU_NO_ASID; + + asid = vma->vm_mm->context & MMU_CONTEXT_ASID_MASK; + page &= PAGE_MASK; + + local_irq_save(flags); + if (vma->vm_mm != current->mm) { + saved_asid = get_asid(); + set_asid(asid); + } + __flush_tlb_page(asid, page); + if (saved_asid != MMU_NO_ASID) + set_asid(saved_asid); + local_irq_restore(flags); + } +} + +void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, + unsigned long end) +{ + struct mm_struct *mm = vma->vm_mm; + + if (mm->context != NO_CONTEXT) { + unsigned long flags; + int size; + + local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */ + mm->context = NO_CONTEXT; + if (mm == current->mm) + activate_context(mm); + } else { + unsigned long asid = mm->context&MMU_CONTEXT_ASID_MASK; + unsigned long saved_asid = MMU_NO_ASID; + + start &= PAGE_MASK; + end += (PAGE_SIZE - 1); + end &= PAGE_MASK; + if (mm != current->mm) { + saved_asid = get_asid(); + set_asid(asid); + } + while (start < end) { + __flush_tlb_page(asid, start); + start += PAGE_SIZE; + } + if (saved_asid != MMU_NO_ASID) + set_asid(saved_asid); + } + local_irq_restore(flags); + } +} + +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + unsigned long flags; + int size; + + local_irq_save(flags); + size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; + if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */ + flush_tlb_all(); + } else { + unsigned long asid = init_mm.context&MMU_CONTEXT_ASID_MASK; + unsigned long saved_asid = get_asid(); + + start &= PAGE_MASK; + end += (PAGE_SIZE - 1); + end &= PAGE_MASK; + set_asid(asid); + while (start < end) { + __flush_tlb_page(asid, start); + start += PAGE_SIZE; + } + set_asid(saved_asid); + } + local_irq_restore(flags); +} + +void flush_tlb_mm(struct mm_struct *mm) +{ + /* Invalidate all TLB of this process. */ + /* Instead of invalidating each TLB, we get new MMU context. */ + if (mm->context != NO_CONTEXT) { + unsigned long flags; + + local_irq_save(flags); + mm->context = NO_CONTEXT; + if (mm == current->mm) + activate_context(mm); + local_irq_restore(flags); + } +} + +void flush_tlb_all(void) +{ + unsigned long flags, status; + + /* + * Flush all the TLB. + * + * Write to the MMU control register's bit: + * TF-bit for SH-3, TI-bit for SH-4. + * It's same position, bit #2. + */ + local_irq_save(flags); + status = ctrl_inl(MMUCR); + status |= 0x04; + ctrl_outl(status, MMUCR); + local_irq_restore(flags); +} diff --git a/trunk/arch/sh/mm/hugetlbpage.c b/trunk/arch/sh/mm/hugetlbpage.c index 329059d6b54a..2a85bc15a412 100644 --- a/trunk/arch/sh/mm/hugetlbpage.c +++ b/trunk/arch/sh/mm/hugetlbpage.c @@ -26,43 +26,63 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; - pud_t *pud; pmd_t *pmd; pte_t *pte = NULL; pgd = pgd_offset(mm, addr); if (pgd) { - pud = pud_alloc(mm, pgd, addr); - if (pud) { - pmd = pmd_alloc(mm, pud, addr); - if (pmd) - pte = pte_alloc_map(mm, pmd, addr); - } + pmd = pmd_alloc(mm, pgd, addr); + if (pmd) + pte = pte_alloc_map(mm, pmd, addr); } - return pte; } pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) { pgd_t *pgd; - pud_t *pud; pmd_t *pmd; pte_t *pte = NULL; pgd = pgd_offset(mm, addr); if (pgd) { - pud = pud_offset(pgd, addr); - if (pud) { - pmd = pmd_offset(pud, addr); - if (pmd) - pte = pte_offset_map(pmd, addr); - } + pmd = pmd_offset(pgd, addr); + if (pmd) + pte = pte_offset_map(pmd, addr); } - return pte; } +void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t entry) +{ + int i; + + for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { + set_pte_at(mm, addr, ptep, entry); + ptep++; + addr += PAGE_SIZE; + pte_val(entry) += PAGE_SIZE; + } +} + +pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep) +{ + pte_t entry; + int i; + + entry = *ptep; + + for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { + pte_clear(mm, addr, ptep); + addr += PAGE_SIZE; + ptep++; + } + + return entry; +} + struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address, int write) { diff --git a/trunk/arch/sh/mm/init.c b/trunk/arch/sh/mm/init.c index 7154d1ce9785..8ea27ca4b700 100644 --- a/trunk/arch/sh/mm/init.c +++ b/trunk/arch/sh/mm/init.c @@ -24,7 +24,7 @@ #include #include #include -#include + #include #include #include @@ -80,7 +80,6 @@ void show_mem(void) static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) { pgd_t *pgd; - pud_t *pud; pmd_t *pmd; pte_t *pte; @@ -90,17 +89,7 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) return; } - pud = pud_offset(pgd, addr); - if (pud_none(*pud)) { - pmd = (pmd_t *)get_zeroed_page(GFP_ATOMIC); - set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER)); - if (pmd != pmd_offset(pud, 0)) { - pud_ERROR(*pud); - return; - } - } - - pmd = pmd_offset(pud, addr); + pmd = pmd_offset(pgd, addr); if (pmd_none(*pmd)) { pte = (pte_t *)get_zeroed_page(GFP_ATOMIC); set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER)); @@ -223,8 +212,6 @@ void __init paging_init(void) free_area_init_node(0, NODE_DATA(0), zones_size, __MEMORY_START >> PAGE_SHIFT, 0); } -static struct kcore_list kcore_mem, kcore_vmalloc; - void __init mem_init(void) { extern unsigned long empty_zero_page[1024]; @@ -250,13 +237,8 @@ void __init mem_init(void) * Setup wrappers for copy/clear_page(), these will get overridden * later in the boot process if a better method is available. */ -#ifdef CONFIG_MMU copy_page = copy_page_slow; clear_page = clear_page_slow; -#else - copy_page = copy_page_nommu; - clear_page = clear_page_nommu; -#endif /* this will put all low memory onto the freelists */ totalram_pages += free_all_bootmem_node(NODE_DATA(0)); @@ -272,12 +254,7 @@ void __init mem_init(void) datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; - kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); - kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, - VMALLOC_END - VMALLOC_START); - - printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, " - "%dk reserved, %dk data, %dk init)\n", + printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), max_mapnr << (PAGE_SHIFT-10), codesize >> 10, @@ -286,9 +263,6 @@ void __init mem_init(void) initsize >> 10); p3_cache_init(); - - /* Initialize the vDSO */ - vsyscall_init(); } void free_initmem(void) diff --git a/trunk/arch/sh/mm/ioremap.c b/trunk/arch/sh/mm/ioremap.c index a9fe80cfc233..96fa4a999e2a 100644 --- a/trunk/arch/sh/mm/ioremap.c +++ b/trunk/arch/sh/mm/ioremap.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -135,20 +134,6 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size, if (phys_addr >= 0xA0000 && last_addr < 0x100000) return (void __iomem *)phys_to_virt(phys_addr); - /* - * If we're on an SH7751 or SH7780 PCI controller, PCI memory is - * mapped at the end of the address space (typically 0xfd000000) - * in a non-translatable area, so mapping through page tables for - * this area is not only pointless, but also fundamentally - * broken. Just return the physical address instead. - * - * For boards that map a small PCI memory aperture somewhere in - * P1/P2 space, ioremap() will already do the right thing, - * and we'll never get this far. - */ - if (is_pci_memaddr(phys_addr) && is_pci_memaddr(last_addr)) - return (void __iomem *)phys_addr; - /* * Don't allow anybody to remap normal RAM that we're using.. */ @@ -207,7 +192,7 @@ void __iounmap(void __iomem *addr) unsigned long vaddr = (unsigned long __force)addr; struct vm_struct *p; - if (PXSEG(vaddr) < P3SEG || is_pci_memaddr(vaddr)) + if (PXSEG(vaddr) < P3SEG) return; #ifdef CONFIG_32BIT diff --git a/trunk/arch/sh/mm/pg-nommu.c b/trunk/arch/sh/mm/pg-nommu.c index d15221beaa16..8f9165a4e333 100644 --- a/trunk/arch/sh/mm/pg-nommu.c +++ b/trunk/arch/sh/mm/pg-nommu.c @@ -14,24 +14,23 @@ #include #include -void copy_page_nommu(void *to, void *from) +static void copy_page_nommu(void *to, void *from) { memcpy(to, from, PAGE_SIZE); } -void clear_page_nommu(void *to) +static void clear_page_nommu(void *to) { memset(to, 0, PAGE_SIZE); } -__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n) +static int __init pg_nommu_init(void) { - memcpy(to, from, n); - return 0; -} + copy_page = copy_page_nommu; + clear_page = clear_page_nommu; -__kernel_size_t __clear_user(void *to, __kernel_size_t n) -{ - memset(to, 0, n); return 0; } + +subsys_initcall(pg_nommu_init); + diff --git a/trunk/arch/sh/mm/pg-sh4.c b/trunk/arch/sh/mm/pg-sh4.c index 07371ed7a313..c776b60fc250 100644 --- a/trunk/arch/sh/mm/pg-sh4.c +++ b/trunk/arch/sh/mm/pg-sh4.c @@ -2,7 +2,7 @@ * arch/sh/mm/pg-sh4.c * * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2002 - 2005 Paul Mundt + * Copyright (C) 2002 Paul Mundt * * Released under the terms of the GNU GPL v2.0. */ @@ -23,8 +23,6 @@ extern struct semaphore p3map_sem[]; -#define CACHE_ALIAS (cpu_data->dcache.alias_mask) - /* * clear_user_page * @to: P1 address @@ -37,15 +35,14 @@ void clear_user_page(void *to, unsigned long address, struct page *page) if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) clear_page(to); else { - pgprot_t pgprot = __pgprot(_PAGE_PRESENT | + pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_CACHABLE | - _PAGE_DIRTY | _PAGE_ACCESSED | + _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HW_SHARED | _PAGE_FLAGS_HARD); unsigned long phys_addr = PHYSADDR(to); unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); - pgd_t *pgd = pgd_offset_k(p3_addr); - pud_t *pud = pud_offset(pgd, p3_addr); - pmd_t *pmd = pmd_offset(pud, p3_addr); + pgd_t *dir = pgd_offset_k(p3_addr); + pmd_t *pmd = pmd_offset(dir, p3_addr); pte_t *pte = pte_offset_kernel(pmd, p3_addr); pte_t entry; unsigned long flags; @@ -70,22 +67,21 @@ void clear_user_page(void *to, unsigned long address, struct page *page) * @address: U0 address to be mapped * @page: page (virt_to_page(to)) */ -void copy_user_page(void *to, void *from, unsigned long address, +void copy_user_page(void *to, void *from, unsigned long address, struct page *page) { __set_bit(PG_mapped, &page->flags); if (((address ^ (unsigned long)to) & CACHE_ALIAS) == 0) copy_page(to, from); else { - pgprot_t pgprot = __pgprot(_PAGE_PRESENT | + pgprot_t pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_CACHABLE | - _PAGE_DIRTY | _PAGE_ACCESSED | + _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HW_SHARED | _PAGE_FLAGS_HARD); unsigned long phys_addr = PHYSADDR(to); unsigned long p3_addr = P3SEG + (address & CACHE_ALIAS); - pgd_t *pgd = pgd_offset_k(p3_addr); - pud_t *pud = pud_offset(pgd, p3_addr); - pmd_t *pmd = pmd_offset(pud, p3_addr); + pgd_t *dir = pgd_offset_k(p3_addr); + pmd_t *pmd = pmd_offset(dir, p3_addr); pte_t *pte = pte_offset_kernel(pmd, p3_addr); pte_t entry; unsigned long flags; diff --git a/trunk/arch/sh/mm/pmb.c b/trunk/arch/sh/mm/pmb.c deleted file mode 100644 index 92e745341e4d..000000000000 --- a/trunk/arch/sh/mm/pmb.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * arch/sh/mm/pmb.c - * - * Privileged Space Mapping Buffer (PMB) Support. - * - * Copyright (C) 2005, 2006 Paul Mundt - * - * P1/P2 Section mapping definitions from map32.h, which was: - * - * Copyright 2003 (c) Lineo Solutions,Inc. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NR_PMB_ENTRIES 16 - -static kmem_cache_t *pmb_cache; -static unsigned long pmb_map; - -static struct pmb_entry pmb_init_map[] = { - /* vpn ppn flags (ub/sz/c/wt) */ - - /* P1 Section Mappings */ - { 0x80000000, 0x00000000, PMB_SZ_64M | PMB_C, }, - { 0x84000000, 0x04000000, PMB_SZ_64M | PMB_C, }, - { 0x88000000, 0x08000000, PMB_SZ_128M | PMB_C, }, - { 0x90000000, 0x10000000, PMB_SZ_64M | PMB_C, }, - { 0x94000000, 0x14000000, PMB_SZ_64M | PMB_C, }, - { 0x98000000, 0x18000000, PMB_SZ_64M | PMB_C, }, - - /* P2 Section Mappings */ - { 0xa0000000, 0x00000000, PMB_UB | PMB_SZ_64M | PMB_WT, }, - { 0xa4000000, 0x04000000, PMB_UB | PMB_SZ_64M | PMB_WT, }, - { 0xa8000000, 0x08000000, PMB_UB | PMB_SZ_128M | PMB_WT, }, - { 0xb0000000, 0x10000000, PMB_UB | PMB_SZ_64M | PMB_WT, }, - { 0xb4000000, 0x14000000, PMB_UB | PMB_SZ_64M | PMB_WT, }, - { 0xb8000000, 0x18000000, PMB_UB | PMB_SZ_64M | PMB_WT, }, -}; - -static inline unsigned long mk_pmb_entry(unsigned int entry) -{ - return (entry & PMB_E_MASK) << PMB_E_SHIFT; -} - -static inline unsigned long mk_pmb_addr(unsigned int entry) -{ - return mk_pmb_entry(entry) | PMB_ADDR; -} - -static inline unsigned long mk_pmb_data(unsigned int entry) -{ - return mk_pmb_entry(entry) | PMB_DATA; -} - -struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, - unsigned long flags) -{ - struct pmb_entry *pmbe; - - pmbe = kmem_cache_alloc(pmb_cache, GFP_KERNEL); - if (!pmbe) - return ERR_PTR(-ENOMEM); - - pmbe->vpn = vpn; - pmbe->ppn = ppn; - pmbe->flags = flags; - - return pmbe; -} - -void pmb_free(struct pmb_entry *pmbe) -{ - kmem_cache_free(pmb_cache, pmbe); -} - -/* - * Must be in P2 for __set_pmb_entry() - */ -int __set_pmb_entry(unsigned long vpn, unsigned long ppn, - unsigned long flags, int *entry) -{ - unsigned int pos = *entry; - - if (unlikely(pos == PMB_NO_ENTRY)) - pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES); - -repeat: - if (unlikely(pos > NR_PMB_ENTRIES)) - return -ENOSPC; - - if (test_and_set_bit(pos, &pmb_map)) { - pos = find_first_zero_bit(&pmb_map, NR_PMB_ENTRIES); - goto repeat; - } - - ctrl_outl(vpn | PMB_V, mk_pmb_addr(pos)); - -#ifdef CONFIG_SH_WRITETHROUGH - /* - * When we are in 32-bit address extended mode, CCR.CB becomes - * invalid, so care must be taken to manually adjust cacheable - * translations. - */ - if (likely(flags & PMB_C)) - flags |= PMB_WT; -#endif - - ctrl_outl(ppn | flags | PMB_V, mk_pmb_data(pos)); - - *entry = pos; - - return 0; -} - -int set_pmb_entry(struct pmb_entry *pmbe) -{ - int ret; - - jump_to_P2(); - ret = __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &pmbe->entry); - back_to_P1(); - - return ret; -} - -void clear_pmb_entry(struct pmb_entry *pmbe) -{ - unsigned int entry = pmbe->entry; - unsigned long addr; - - /* - * Don't allow clearing of wired init entries, P1 or P2 access - * without a corresponding mapping in the PMB will lead to reset - * by the TLB. - */ - if (unlikely(entry < ARRAY_SIZE(pmb_init_map) || - entry >= NR_PMB_ENTRIES)) - return; - - jump_to_P2(); - - /* Clear V-bit */ - addr = mk_pmb_addr(entry); - ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr); - - addr = mk_pmb_data(entry); - ctrl_outl(ctrl_inl(addr) & ~PMB_V, addr); - - back_to_P1(); - - clear_bit(entry, &pmb_map); -} - -static DEFINE_SPINLOCK(pmb_list_lock); -static struct pmb_entry *pmb_list; - -static inline void pmb_list_add(struct pmb_entry *pmbe) -{ - struct pmb_entry **p, *tmp; - - p = &pmb_list; - while ((tmp = *p) != NULL) - p = &tmp->next; - - pmbe->next = tmp; - *p = pmbe; -} - -static inline void pmb_list_del(struct pmb_entry *pmbe) -{ - struct pmb_entry **p, *tmp; - - for (p = &pmb_list; (tmp = *p); p = &tmp->next) - if (tmp == pmbe) { - *p = tmp->next; - return; - } -} - -static struct { - unsigned long size; - int flag; -} pmb_sizes[] = { - { .size = 0x20000000, .flag = PMB_SZ_512M, }, - { .size = 0x08000000, .flag = PMB_SZ_128M, }, - { .size = 0x04000000, .flag = PMB_SZ_64M, }, - { .size = 0x01000000, .flag = PMB_SZ_16M, }, -}; - -long pmb_remap(unsigned long vaddr, unsigned long phys, - unsigned long size, unsigned long flags) -{ - struct pmb_entry *pmbp; - unsigned long wanted; - int pmb_flags, i; - - /* Convert typical pgprot value to the PMB equivalent */ - if (flags & _PAGE_CACHABLE) { - if (flags & _PAGE_WT) - pmb_flags = PMB_WT; - else - pmb_flags = PMB_C; - } else - pmb_flags = PMB_WT | PMB_UB; - - pmbp = NULL; - wanted = size; - -again: - for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) { - struct pmb_entry *pmbe; - int ret; - - if (size < pmb_sizes[i].size) - continue; - - pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag); - if (IS_ERR(pmbe)) - return PTR_ERR(pmbe); - - ret = set_pmb_entry(pmbe); - if (ret != 0) { - pmb_free(pmbe); - return -EBUSY; - } - - phys += pmb_sizes[i].size; - vaddr += pmb_sizes[i].size; - size -= pmb_sizes[i].size; - - /* - * Link adjacent entries that span multiple PMB entries - * for easier tear-down. - */ - if (likely(pmbp)) - pmbp->link = pmbe; - - pmbp = pmbe; - } - - if (size >= 0x1000000) - goto again; - - return wanted - size; -} - -void pmb_unmap(unsigned long addr) -{ - struct pmb_entry **p, *pmbe; - - for (p = &pmb_list; (pmbe = *p); p = &pmbe->next) - if (pmbe->vpn == addr) - break; - - if (unlikely(!pmbe)) - return; - - WARN_ON(!test_bit(pmbe->entry, &pmb_map)); - - do { - struct pmb_entry *pmblink = pmbe; - - clear_pmb_entry(pmbe); - pmbe = pmblink->link; - - pmb_free(pmblink); - } while (pmbe); -} - -static void pmb_cache_ctor(void *pmb, kmem_cache_t *cachep, unsigned long flags) -{ - struct pmb_entry *pmbe = pmb; - - memset(pmb, 0, sizeof(struct pmb_entry)); - - spin_lock_irq(&pmb_list_lock); - - pmbe->entry = PMB_NO_ENTRY; - pmb_list_add(pmbe); - - spin_unlock_irq(&pmb_list_lock); -} - -static void pmb_cache_dtor(void *pmb, kmem_cache_t *cachep, unsigned long flags) -{ - spin_lock_irq(&pmb_list_lock); - pmb_list_del(pmb); - spin_unlock_irq(&pmb_list_lock); -} - -static int __init pmb_init(void) -{ - unsigned int nr_entries = ARRAY_SIZE(pmb_init_map); - unsigned int entry; - - BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES)); - - pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), - 0, 0, pmb_cache_ctor, pmb_cache_dtor); - BUG_ON(!pmb_cache); - - jump_to_P2(); - - /* - * Ordering is important, P2 must be mapped in the PMB before we - * can set PMB.SE, and P1 must be mapped before we jump back to - * P1 space. - */ - for (entry = 0; entry < nr_entries; entry++) { - struct pmb_entry *pmbe = pmb_init_map + entry; - - __set_pmb_entry(pmbe->vpn, pmbe->ppn, pmbe->flags, &entry); - } - - ctrl_outl(0, PMB_IRMCR); - - /* PMB.SE and UB[7] */ - ctrl_outl((1 << 31) | (1 << 7), PMB_PASCR); - - back_to_P1(); - - return 0; -} -arch_initcall(pmb_init); - -static int pmb_seq_show(struct seq_file *file, void *iter) -{ - int i; - - seq_printf(file, "V: Valid, C: Cacheable, WT: Write-Through\n" - "CB: Copy-Back, B: Buffered, UB: Unbuffered\n"); - seq_printf(file, "ety vpn ppn size flags\n"); - - for (i = 0; i < NR_PMB_ENTRIES; i++) { - unsigned long addr, data; - unsigned int size; - char *sz_str = NULL; - - addr = ctrl_inl(mk_pmb_addr(i)); - data = ctrl_inl(mk_pmb_data(i)); - - size = data & PMB_SZ_MASK; - sz_str = (size == PMB_SZ_16M) ? " 16MB": - (size == PMB_SZ_64M) ? " 64MB": - (size == PMB_SZ_128M) ? "128MB": - "512MB"; - - /* 02: V 0x88 0x08 128MB C CB B */ - seq_printf(file, "%02d: %c 0x%02lx 0x%02lx %s %c %s %s\n", - i, ((addr & PMB_V) && (data & PMB_V)) ? 'V' : ' ', - (addr >> 24) & 0xff, (data >> 24) & 0xff, - sz_str, (data & PMB_C) ? 'C' : ' ', - (data & PMB_WT) ? "WT" : "CB", - (data & PMB_UB) ? "UB" : " B"); - } - - return 0; -} - -static int pmb_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, pmb_seq_show, NULL); -} - -static struct file_operations pmb_debugfs_fops = { - .owner = THIS_MODULE, - .open = pmb_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release, -}; - -static int __init pmb_debugfs_init(void) -{ - struct dentry *dentry; - - dentry = debugfs_create_file("pmb", S_IFREG | S_IRUGO, - NULL, NULL, &pmb_debugfs_fops); - if (IS_ERR(dentry)) - return PTR_ERR(dentry); - - return 0; -} -postcore_initcall(pmb_debugfs_init); diff --git a/trunk/arch/sh/mm/tlb-flush.c b/trunk/arch/sh/mm/tlb-flush.c deleted file mode 100644 index 73ec7f6084fa..000000000000 --- a/trunk/arch/sh/mm/tlb-flush.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * TLB flushing operations for SH with an MMU. - * - * Copyright (C) 1999 Niibe Yutaka - * Copyright (C) 2003 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include - -void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - if (vma->vm_mm && vma->vm_mm->context.id != NO_CONTEXT) { - unsigned long flags; - unsigned long asid; - unsigned long saved_asid = MMU_NO_ASID; - - asid = vma->vm_mm->context.id & MMU_CONTEXT_ASID_MASK; - page &= PAGE_MASK; - - local_irq_save(flags); - if (vma->vm_mm != current->mm) { - saved_asid = get_asid(); - set_asid(asid); - } - __flush_tlb_page(asid, page); - if (saved_asid != MMU_NO_ASID) - set_asid(saved_asid); - local_irq_restore(flags); - } -} - -void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end) -{ - struct mm_struct *mm = vma->vm_mm; - - if (mm->context.id != NO_CONTEXT) { - unsigned long flags; - int size; - - local_irq_save(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */ - mm->context.id = NO_CONTEXT; - if (mm == current->mm) - activate_context(mm); - } else { - unsigned long asid; - unsigned long saved_asid = MMU_NO_ASID; - - asid = mm->context.id & MMU_CONTEXT_ASID_MASK; - start &= PAGE_MASK; - end += (PAGE_SIZE - 1); - end &= PAGE_MASK; - if (mm != current->mm) { - saved_asid = get_asid(); - set_asid(asid); - } - while (start < end) { - __flush_tlb_page(asid, start); - start += PAGE_SIZE; - } - if (saved_asid != MMU_NO_ASID) - set_asid(saved_asid); - } - local_irq_restore(flags); - } -} - -void flush_tlb_kernel_range(unsigned long start, unsigned long end) -{ - unsigned long flags; - int size; - - local_irq_save(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */ - flush_tlb_all(); - } else { - unsigned long asid; - unsigned long saved_asid = get_asid(); - - asid = init_mm.context.id & MMU_CONTEXT_ASID_MASK; - start &= PAGE_MASK; - end += (PAGE_SIZE - 1); - end &= PAGE_MASK; - set_asid(asid); - while (start < end) { - __flush_tlb_page(asid, start); - start += PAGE_SIZE; - } - set_asid(saved_asid); - } - local_irq_restore(flags); -} - -void flush_tlb_mm(struct mm_struct *mm) -{ - /* Invalidate all TLB of this process. */ - /* Instead of invalidating each TLB, we get new MMU context. */ - if (mm->context.id != NO_CONTEXT) { - unsigned long flags; - - local_irq_save(flags); - mm->context.id = NO_CONTEXT; - if (mm == current->mm) - activate_context(mm); - local_irq_restore(flags); - } -} - -void flush_tlb_all(void) -{ - unsigned long flags, status; - - /* - * Flush all the TLB. - * - * Write to the MMU control register's bit: - * TF-bit for SH-3, TI-bit for SH-4. - * It's same position, bit #2. - */ - local_irq_save(flags); - status = ctrl_inl(MMUCR); - status |= 0x04; - ctrl_outl(status, MMUCR); - ctrl_barrier(); - local_irq_restore(flags); -} diff --git a/trunk/arch/sh/mm/tlb-sh4.c b/trunk/arch/sh/mm/tlb-sh4.c index 812b2d567de2..115b1b6be40b 100644 --- a/trunk/arch/sh/mm/tlb-sh4.c +++ b/trunk/arch/sh/mm/tlb-sh4.c @@ -36,6 +36,7 @@ void update_mmu_cache(struct vm_area_struct * vma, unsigned long vpn; struct page *page; unsigned long pfn; + unsigned long ptea; /* Ptrace may call this routine. */ if (vma && current->active_mm != vma->vm_mm) @@ -58,11 +59,10 @@ void update_mmu_cache(struct vm_area_struct * vma, ctrl_outl(vpn, MMU_PTEH); pteval = pte_val(pte); - /* Set PTEA register */ - if (cpu_data->flags & CPU_HAS_PTEA) - /* TODO: make this look less hacky */ - ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), MMU_PTEA); + /* TODO: make this look less hacky */ + ptea = ((pteval >> 28) & 0xe) | (pteval & 0x1); + ctrl_outl(ptea, MMU_PTEA); /* Set PTEL register */ pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */ diff --git a/trunk/arch/sh/oprofile/Makefile b/trunk/arch/sh/oprofile/Makefile index 1f25d9bb7538..686738d4aa3c 100644 --- a/trunk/arch/sh/oprofile/Makefile +++ b/trunk/arch/sh/oprofile/Makefile @@ -7,11 +7,7 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ timer_int.o ) profdrvr-y := op_model_null.o - -# SH7750-style performance counters exist across 7750/7750S and 7091. -profdrvr-$(CONFIG_CPU_SUBTYPE_SH7750S) := op_model_sh7750.o profdrvr-$(CONFIG_CPU_SUBTYPE_SH7750) := op_model_sh7750.o -profdrvr-$(CONFIG_CPU_SUBTYPE_SH7091) := op_model_sh7750.o oprofile-y := $(DRIVER_OBJS) $(profdrvr-y) diff --git a/trunk/arch/sh/tools/mach-types b/trunk/arch/sh/tools/mach-types index ac57638977ee..182fe9092577 100644 --- a/trunk/arch/sh/tools/mach-types +++ b/trunk/arch/sh/tools/mach-types @@ -8,15 +8,16 @@ SE SH_SOLUTION_ENGINE 7751SE SH_7751_SOLUTION_ENGINE 7300SE SH_7300_SOLUTION_ENGINE -7343SE SH_7343_SOLUTION_ENGINE 73180SE SH_73180_SOLUTION_ENGINE 7751SYSTEMH SH_7751_SYSTEMH HP6XX SH_HP6XX HD64461 HD64461 HD64465 HD64465 +SH2000 SH_SH2000 SATURN SH_SATURN DREAMCAST SH_DREAMCAST BIGSUR SH_BIGSUR +ADX SH_ADX MPC1211 SH_MPC1211 SNAPGEAR SH_SECUREEDGE5410 HS7751RVOIP SH_HS7751RVOIP @@ -24,9 +25,4 @@ RTS7751R2D SH_RTS7751R2D EDOSK7705 SH_EDOSK7705 SH4202_MICRODEV SH_SH4202_MICRODEV SH03 SH_SH03 -LANDISK SH_LANDISK -R7780RP SH_R7780RP -R7780MP SH_R7780MP -TITAN SH_TITAN -SHMIN SH_SHMIN -7710VOIPGW SH_7710VOIPGW + diff --git a/trunk/arch/sh64/kernel/process.c b/trunk/arch/sh64/kernel/process.c index 525d0ec19b78..db475b7833fb 100644 --- a/trunk/arch/sh64/kernel/process.c +++ b/trunk/arch/sh64/kernel/process.c @@ -20,16 +20,261 @@ /* * This file handles the architecture-dependent parts of process handling.. */ + +/* Temporary flags/tests. All to be removed/undefined. BEGIN */ +#define IDLE_TRACE +#define VM_SHOW_TABLES +#define VM_TEST_FAULT +#define VM_TEST_RTLBMISS +#define VM_TEST_WTLBMISS + +#undef VM_SHOW_TABLES +#undef IDLE_TRACE +/* Temporary flags/tests. All to be removed/undefined. END */ + +#define __KERNEL_SYSCALLS__ +#include + +#include +#include #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include -#include + #include #include +#include +#include +#include /* includes also */ +#include +#include +#include + +#include struct task_struct *last_task_used_math = NULL; +#ifdef IDLE_TRACE +#ifdef VM_SHOW_TABLES +/* For testing */ +static void print_PTE(long base) +{ + int i, skip=0; + long long x, y, *p = (long long *) base; + + for (i=0; i< 512; i++, p++){ + if (*p == 0) { + if (!skip) { + skip++; + printk("(0s) "); + } + } else { + skip=0; + x = (*p) >> 32; + y = (*p) & 0xffffffff; + printk("%08Lx%08Lx ", x, y); + if (!((i+1)&0x3)) printk("\n"); + } + } +} + +/* For testing */ +static void print_DIR(long base) +{ + int i, skip=0; + long *p = (long *) base; + + for (i=0; i< 512; i++, p++){ + if (*p == 0) { + if (!skip) { + skip++; + printk("(0s) "); + } + } else { + skip=0; + printk("%08lx ", *p); + if (!((i+1)&0x7)) printk("\n"); + } + } +} + +/* For testing */ +static void print_vmalloc_first_tables(void) +{ + +#define PRESENT 0x800 /* Bit 11 */ + + /* + * Do it really dirty by looking at raw addresses, + * raw offsets, no types. If we used pgtable/pgalloc + * macros/definitions we could hide potential bugs. + * + * Note that pointers are 32-bit for CDC. + */ + long pgdt, pmdt, ptet; + + pgdt = (long) &swapper_pg_dir; + printk("-->PGD (0x%08lx):\n", pgdt); + print_DIR(pgdt); + printk("\n"); + + /* VMALLOC pool is mapped at 0xc0000000, second (pointer) entry in PGD */ + pgdt += 4; + pmdt = (long) (* (long *) pgdt); + if (!(pmdt & PRESENT)) { + printk("No PMD\n"); + return; + } else pmdt &= 0xfffff000; + + printk("-->PMD (0x%08lx):\n", pmdt); + print_DIR(pmdt); + printk("\n"); + + /* Get the pmdt displacement for 0xc0000000 */ + pmdt += 2048; + + /* just look at first two address ranges ... */ + /* ... 0xc0000000 ... */ + ptet = (long) (* (long *) pmdt); + if (!(ptet & PRESENT)) { + printk("No PTE0\n"); + return; + } else ptet &= 0xfffff000; + + printk("-->PTE0 (0x%08lx):\n", ptet); + print_PTE(ptet); + printk("\n"); + + /* ... 0xc0001000 ... */ + ptet += 4; + if (!(ptet & PRESENT)) { + printk("No PTE1\n"); + return; + } else ptet &= 0xfffff000; + printk("-->PTE1 (0x%08lx):\n", ptet); + print_PTE(ptet); + printk("\n"); +} +#else +#define print_vmalloc_first_tables() +#endif /* VM_SHOW_TABLES */ + +static void test_VM(void) +{ + void *a, *b, *c; + +#ifdef VM_SHOW_TABLES + printk("Initial PGD/PMD/PTE\n"); +#endif + print_vmalloc_first_tables(); + + printk("Allocating 2 bytes\n"); + a = vmalloc(2); + print_vmalloc_first_tables(); + + printk("Allocating 4100 bytes\n"); + b = vmalloc(4100); + print_vmalloc_first_tables(); + + printk("Allocating 20234 bytes\n"); + c = vmalloc(20234); + print_vmalloc_first_tables(); + +#ifdef VM_TEST_FAULT + /* Here you may want to fault ! */ + +#ifdef VM_TEST_RTLBMISS + printk("Ready to fault upon read.\n"); + if (* (char *) a) { + printk("RTLBMISSed on area a !\n"); + } + printk("RTLBMISSed on area a !\n"); +#endif + +#ifdef VM_TEST_WTLBMISS + printk("Ready to fault upon write.\n"); + *((char *) b) = 'L'; + printk("WTLBMISSed on area b !\n"); +#endif + +#endif /* VM_TEST_FAULT */ + + printk("Deallocating the 4100 byte chunk\n"); + vfree(b); + print_vmalloc_first_tables(); + + printk("Deallocating the 2 byte chunk\n"); + vfree(a); + print_vmalloc_first_tables(); + + printk("Deallocating the last chunk\n"); + vfree(c); + print_vmalloc_first_tables(); +} + +extern unsigned long volatile jiffies; +int once = 0; +unsigned long old_jiffies; +int pid = -1, pgid = -1; + +void idle_trace(void) +{ + + _syscall0(int, getpid) + _syscall1(int, getpgid, int, pid) + + if (!once) { + /* VM allocation/deallocation simple test */ + test_VM(); + pid = getpid(); + + printk("Got all through to Idle !!\n"); + printk("I'm now going to loop forever ...\n"); + printk("Any ! below is a timer tick.\n"); + printk("Any . below is a getpgid system call from pid = %d.\n", pid); + + + old_jiffies = jiffies; + once++; + } + + if (old_jiffies != jiffies) { + old_jiffies = jiffies - old_jiffies; + switch (old_jiffies) { + case 1: + printk("!"); + break; + case 2: + printk("!!"); + break; + case 3: + printk("!!!"); + break; + case 4: + printk("!!!!"); + break; + default: + printk("(%d!)", (int) old_jiffies); + } + old_jiffies = jiffies; + } + pgid = getpgid(pid); + printk("."); +} +#else +#define idle_trace() do { } while (0) +#endif /* IDLE_TRACE */ + static int hlt_counter = 1; #define HARD_IDLE_TIMEOUT (HZ / 3) @@ -78,6 +323,7 @@ void cpu_idle(void) local_irq_disable(); while (!need_resched()) { local_irq_enable(); + idle_trace(); hlt(); local_irq_disable(); } @@ -376,10 +622,6 @@ void free_task_struct(struct task_struct *p) /* * Create a kernel thread */ -ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *)) -{ - do_exit(fn(arg)); -} /* * This is the mechanism for creating a new kernel thread. @@ -391,17 +633,19 @@ ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *)) */ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { - struct pt_regs regs; + /* A bit less processor dependent than older sh ... */ + unsigned int reply; - memset(®s, 0, sizeof(regs)); - regs.regs[2] = (unsigned long)arg; - regs.regs[3] = (unsigned long)fn; +static __inline__ _syscall2(int,clone,unsigned long,flags,unsigned long,newsp) +static __inline__ _syscall1(int,exit,int,ret) - regs.pc = (unsigned long)kernel_thread_helper; - regs.sr = (1 << 30); + reply = clone(flags | CLONE_VM, 0); + if (!reply) { + /* Child */ + reply = exit(fn(arg)); + } - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, - ®s, 0, NULL, NULL); + return reply; } /* diff --git a/trunk/arch/sh64/kernel/sys_sh64.c b/trunk/arch/sh64/kernel/sys_sh64.c index ad0fa4e003e7..58ff7d522d81 100644 --- a/trunk/arch/sh64/kernel/sys_sh64.c +++ b/trunk/arch/sh64/kernel/sys_sh64.c @@ -32,7 +32,6 @@ #include #include #include -#include #define REG_3 3 @@ -280,25 +279,7 @@ asmlinkage int sys_uname(struct old_utsname * name) if (!name) return -EFAULT; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err=copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_execve); - register unsigned long __sc2 __asm__ ("r2") = (unsigned long) filename; - register unsigned long __sc3 __asm__ ("r3") = (unsigned long) argv; - register unsigned long __sc4 __asm__ ("r4") = (unsigned long) envp; - __asm__ __volatile__ ("trapa %1 !\t\t\t execve(%2,%3,%4)" - : "=r" (__sc0) - : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) ); - __asm__ __volatile__ ("!dummy %0 %1 %2 %3" - : : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) : "memory"); - return __sc0; -} diff --git a/trunk/arch/sh64/kernel/time.c b/trunk/arch/sh64/kernel/time.c index 9c4a38a8698c..b8162e59030e 100644 --- a/trunk/arch/sh64/kernel/time.c +++ b/trunk/arch/sh64/kernel/time.c @@ -107,6 +107,8 @@ #define TICK_SIZE (tick_nsec / 1000) +extern unsigned long wall_jiffies; + static unsigned long tmu_base, rtc_base; unsigned long cprc_base; @@ -192,6 +194,13 @@ void do_gettimeofday(struct timeval *tv) do { seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = usecs_since_tick(); + { + unsigned long lost = jiffies - wall_jiffies; + + if (lost) + usec += lost * (1000000 / HZ); + } + sec = xtime.tv_sec; usec += xtime.tv_nsec / 1000; } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); @@ -220,7 +229,8 @@ int do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ - nsec -= 1000 * usecs_since_tick(); + nsec -= 1000 * (usecs_since_tick() + + (jiffies - wall_jiffies) * (1000000 / HZ)); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -288,7 +298,7 @@ static inline void do_timer_interrupt(int irq, struct pt_regs *regs) asm ("getcon cr62, %0" : "=r" (current_ctc)); ctc_last_interrupt = (unsigned long) current_ctc; - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif diff --git a/trunk/arch/sh64/mm/fault.c b/trunk/arch/sh64/mm/fault.c index 8e2f6c28b739..f08d0eaf6497 100644 --- a/trunk/arch/sh64/mm/fault.c +++ b/trunk/arch/sh64/mm/fault.c @@ -277,7 +277,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, show_regs(regs); #endif } - if (is_init(tsk)) { + if (tsk->pid == 1) { panic("INIT had user mode bad_area\n"); } tsk->thread.address = address; @@ -319,14 +319,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, * us unable to handle the page fault gracefully. */ out_of_memory: - if (is_init(current)) { + if (current->pid == 1) { panic("INIT out of memory\n"); yield(); goto survive; } printk("fault:Out of memory\n"); up_read(&mm->mmap_sem); - if (is_init(current)) { + if (current->pid == 1) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/sparc/kernel/pcic.c b/trunk/arch/sparc/kernel/pcic.c index edb6cc665f56..bfd31aac2df3 100644 --- a/trunk/arch/sparc/kernel/pcic.c +++ b/trunk/arch/sparc/kernel/pcic.c @@ -712,7 +712,7 @@ static irqreturn_t pcic_timer_handler (int irq, void *h, struct pt_regs *regs) { write_seqlock(&xtime_lock); /* Dummy, to show that we remember */ pcic_clear_clock_irq(); - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -765,6 +765,8 @@ static __inline__ unsigned long do_gettimeoffset(void) return count; } +extern unsigned long wall_jiffies; + static void pci_do_gettimeofday(struct timeval *tv) { unsigned long flags; @@ -773,17 +775,26 @@ static void pci_do_gettimeofday(struct timeval *tv) unsigned long max_ntp_tick = tick_usec - tickadj; do { + unsigned long lost; + seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = do_gettimeoffset(); + lost = jiffies - wall_jiffies; /* * If time_adjust is negative then NTP is slowing the clock * so make sure not to go into next possible interval. * Better to lose some accuracy than have time go backwards.. */ - if (unlikely(time_adjust < 0)) + if (unlikely(time_adjust < 0)) { usec = min(usec, max_ntp_tick); + if (lost) + usec += lost * max_ntp_tick; + } + else if (unlikely(lost)) + usec += lost * tick_usec; + sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); @@ -808,7 +819,8 @@ static int pci_do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ - tv->tv_nsec -= 1000 * do_gettimeoffset(); + tv->tv_nsec -= 1000 * (do_gettimeoffset() + + (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ)); while (tv->tv_nsec < 0) { tv->tv_nsec += NSEC_PER_SEC; tv->tv_sec--; diff --git a/trunk/arch/sparc/kernel/sys_sparc.c b/trunk/arch/sparc/kernel/sys_sparc.c index a954a0c00000..896863fb208a 100644 --- a/trunk/arch/sparc/kernel/sys_sparc.c +++ b/trunk/arch/sparc/kernel/sys_sparc.c @@ -24,7 +24,6 @@ #include #include -#include /* #define DEBUG_UNIMP_SYSCALL */ @@ -476,38 +475,16 @@ asmlinkage int sys_getdomainname(char __user *name, int len) down_read(&uts_sem); - nlen = strlen(utsname()->domainname) + 1; + nlen = strlen(system_utsname.domainname) + 1; err = -EINVAL; if (nlen > len) goto out; err = -EFAULT; - if (!copy_to_user(name, utsname()->domainname, nlen)) + if (!copy_to_user(name, system_utsname.domainname, nlen)) err = 0; out: up_read(&uts_sem); return err; } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - long __res; - register long __g1 __asm__ ("g1") = __NR_execve; - register long __o0 __asm__ ("o0") = (long)(filename); - register long __o1 __asm__ ("o1") = (long)(argv); - register long __o2 __asm__ ("o2") = (long)(envp); - asm volatile ("t 0x10\n\t" - "bcc 1f\n\t" - "mov %%o0, %0\n\t" - "sub %%g0, %%o0, %0\n\t" - "1:\n\t" - : "=r" (__res), "=&r" (__o0) - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) - : "cc"); - return __res; -} diff --git a/trunk/arch/sparc/kernel/sys_sunos.c b/trunk/arch/sparc/kernel/sys_sunos.c index 9d2cd97d1c3a..aa0fb2efb615 100644 --- a/trunk/arch/sparc/kernel/sys_sunos.c +++ b/trunk/arch/sparc/kernel/sys_sunos.c @@ -483,18 +483,13 @@ asmlinkage int sunos_uname(struct sunos_utsname __user *name) { int ret; down_read(&uts_sem); - ret = copy_to_user(&name->sname[0], &utsname()->sysname[0], - sizeof(name->sname) - 1); + ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1); if (!ret) { - ret |= __copy_to_user(&name->nname[0], &utsname()->nodename[0], - sizeof(name->nname) - 1); + ret |= __copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1); ret |= __put_user('\0', &name->nname[8]); - ret |= __copy_to_user(&name->rel[0], &utsname()->release[0], - sizeof(name->rel) - 1); - ret |= __copy_to_user(&name->ver[0], &utsname()->version[0], - sizeof(name->ver) - 1); - ret |= __copy_to_user(&name->mach[0], &utsname()->machine[0], - sizeof(name->mach) - 1); + ret |= __copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1); + ret |= __copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1); + ret |= __copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1); } up_read(&uts_sem); return ret ? -EFAULT : 0; diff --git a/trunk/arch/sparc/kernel/time.c b/trunk/arch/sparc/kernel/time.c index e10dc831944d..845081b01267 100644 --- a/trunk/arch/sparc/kernel/time.c +++ b/trunk/arch/sparc/kernel/time.c @@ -43,6 +43,8 @@ #include #include +extern unsigned long wall_jiffies; + DEFINE_SPINLOCK(rtc_lock); enum sparc_clock_type sp_clock_typ; DEFINE_SPINLOCK(mostek_lock); @@ -126,7 +128,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) #endif clear_clock_irq(); - do_timer(1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -447,7 +449,7 @@ unsigned long long sched_clock(void) /* Ok, my cute asm atomicity trick doesn't work anymore. * There are just too many variables that need to be protected - * now (both members of xtime, et al.) + * now (both members of xtime, wall_jiffies, et al.) */ void do_gettimeofday(struct timeval *tv) { @@ -457,17 +459,26 @@ void do_gettimeofday(struct timeval *tv) unsigned long max_ntp_tick = tick_usec - tickadj; do { + unsigned long lost; + seq = read_seqbegin_irqsave(&xtime_lock, flags); usec = do_gettimeoffset(); + lost = jiffies - wall_jiffies; /* * If time_adjust is negative then NTP is slowing the clock * so make sure not to go into next possible interval. * Better to lose some accuracy than have time go backwards.. */ - if (unlikely(time_adjust < 0)) + if (unlikely(time_adjust < 0)) { usec = min(usec, max_ntp_tick); + if (lost) + usec += lost * max_ntp_tick; + } + else if (unlikely(lost)) + usec += lost * tick_usec; + sec = xtime.tv_sec; usec += (xtime.tv_nsec / 1000); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); @@ -510,7 +521,8 @@ static int sbus_do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ - nsec -= 1000 * do_gettimeoffset(); + nsec -= 1000 * (do_gettimeoffset() + + (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ)); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); diff --git a/trunk/arch/sparc/lib/copy_user.S b/trunk/arch/sparc/lib/copy_user.S index ef095b6c43b1..577505b692ae 100644 --- a/trunk/arch/sparc/lib/copy_user.S +++ b/trunk/arch/sparc/lib/copy_user.S @@ -14,7 +14,6 @@ #include #include #include -#include /* Work around cpp -rob */ #define ALLOC #alloc @@ -367,9 +366,6 @@ fixupretl: blu 1f cmp %o1, %g1 bgeu 1f - ld [%g6 + TI_PREEMPT], %g1 - cmp %g1, 0 - bne 1f nop save %sp, -64, %sp mov %i0, %o0 diff --git a/trunk/arch/sparc64/Kconfig b/trunk/arch/sparc64/Kconfig index b627f8dbcaad..8d8ca716f7a7 100644 --- a/trunk/arch/sparc64/Kconfig +++ b/trunk/arch/sparc64/Kconfig @@ -420,7 +420,7 @@ source "arch/sparc64/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on KALLSYMS && EXPERIMENTAL && MODULES + depends on EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/trunk/arch/sparc64/defconfig b/trunk/arch/sparc64/defconfig index 0fbdaa5daa8c..51cf6027b701 100644 --- a/trunk/arch/sparc64/defconfig +++ b/trunk/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.18 -# Tue Sep 26 23:09:35 2006 +# Sat Sep 23 18:32:19 2006 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -141,7 +141,6 @@ CONFIG_SUN_AUXIO=y CONFIG_SUN_IO=y CONFIG_PCI=y CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set CONFIG_SUN_OPENPROMFS=m CONFIG_SPARC32_COMPAT=y @@ -195,9 +194,21 @@ CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_CONG_ADVANCED=y + +# +# TCP congestion control +# +CONFIG_TCP_CONG_BIC=y +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_VENO=m CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -236,7 +247,6 @@ CONFIG_IP_DCCP_TFRC_LIB=m # DCCP Kernel Hacking # # CONFIG_IP_DCCP_DEBUG is not set -# CONFIG_NET_DCCPPROBE is not set # # SCTP Configuration (EXPERIMENTAL) @@ -391,7 +401,6 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_RAID_ATTRS=m CONFIG_SCSI=y -CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y # @@ -413,13 +422,12 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transports +# SCSI Transport Attributes # CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y CONFIG_SCSI_ISCSI_ATTRS=m # CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers @@ -432,18 +440,16 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_ARCMSR is not set # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_SATA is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -455,11 +461,6 @@ CONFIG_ISCSI_TCP=m # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_SUNESP is not set -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -# CONFIG_ATA is not set - # # Multi-device support (RAID and LVM) # @@ -574,7 +575,6 @@ CONFIG_E1000_NAPI=y # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=m CONFIG_BNX2=m -# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) @@ -1006,7 +1006,6 @@ CONFIG_SND_ALI5451=m # CONFIG_SND_VIA82XX_MODEM is not set # CONFIG_SND_VX222 is not set # CONFIG_SND_YMFPCI is not set -# CONFIG_SND_AC97_POWER_SAVE is not set # # USB devices @@ -1354,7 +1353,6 @@ CONFIG_KPROBES=y # Kernel hacking # CONFIG_PRINTK_TIME=y -CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set CONFIG_DEBUG_KERNEL=y diff --git a/trunk/arch/sparc64/kernel/power.c b/trunk/arch/sparc64/kernel/power.c index 0b9c70627ce4..e55466c77b61 100644 --- a/trunk/arch/sparc64/kernel/power.c +++ b/trunk/arch/sparc64/kernel/power.c @@ -4,6 +4,8 @@ * Copyright (C) 1999 David S. Miller (davem@redhat.com) */ +#define __KERNEL_SYSCALLS__ + #include #include #include @@ -12,7 +14,6 @@ #include #include #include -#include #include #include @@ -97,7 +98,7 @@ static int powerd(void *__unused) /* Ok, down we go... */ button_pressed = 0; - if (kernel_execve("/sbin/shutdown", argv, envp) < 0) { + if (execve("/sbin/shutdown", argv, envp) < 0) { printk("powerd: shutdown execution failed\n"); add_wait_queue(&powerd_wait, &wait); goto again; diff --git a/trunk/arch/sparc64/kernel/sys_sparc.c b/trunk/arch/sparc64/kernel/sys_sparc.c index a53d4abb4b49..c608c947e6c3 100644 --- a/trunk/arch/sparc64/kernel/sys_sparc.c +++ b/trunk/arch/sparc64/kernel/sys_sparc.c @@ -31,7 +31,6 @@ #include #include #include -#include /* #define DEBUG_UNIMP_SYSCALL */ @@ -713,13 +712,13 @@ asmlinkage long sys_getdomainname(char __user *name, int len) down_read(&uts_sem); - nlen = strlen(utsname()->domainname) + 1; + nlen = strlen(system_utsname.domainname) + 1; err = -EINVAL; if (nlen > len) goto out; err = -EFAULT; - if (!copy_to_user(name, utsname()->domainname, nlen)) + if (!copy_to_user(name, system_utsname.domainname, nlen)) err = 0; out: @@ -964,23 +963,3 @@ asmlinkage long sys_perfctr(int opcode, unsigned long arg0, unsigned long arg1, }; return err; } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - long __res; - register long __g1 __asm__ ("g1") = __NR_execve; - register long __o0 __asm__ ("o0") = (long)(filename); - register long __o1 __asm__ ("o1") = (long)(argv); - register long __o2 __asm__ ("o2") = (long)(envp); - asm volatile ("t 0x6d\n\t" - "sub %%g0, %%o0, %0\n\t" - "movcc %%xcc, %%o0, %0\n\t" - : "=r" (__res), "=&r" (__o0) - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) - : "cc"); - return __res; -} diff --git a/trunk/arch/sparc64/kernel/sys_sparc32.c b/trunk/arch/sparc64/kernel/sys_sparc32.c index 69444f266e2d..c88ae23ce812 100644 --- a/trunk/arch/sparc64/kernel/sys_sparc32.c +++ b/trunk/arch/sparc64/kernel/sys_sparc32.c @@ -1016,7 +1016,7 @@ struct __sysctl_args32 { asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) { -#ifndef CONFIG_SYSCTL_SYSCALL +#ifndef CONFIG_SYSCTL return -ENOSYS; #else struct __sysctl_args32 tmp; diff --git a/trunk/arch/sparc64/kernel/sys_sunos32.c b/trunk/arch/sparc64/kernel/sys_sunos32.c index 953296b73f3f..87ebdf858a3a 100644 --- a/trunk/arch/sparc64/kernel/sys_sunos32.c +++ b/trunk/arch/sparc64/kernel/sys_sunos32.c @@ -439,16 +439,16 @@ asmlinkage int sunos_uname(struct sunos_utsname __user *name) int ret; down_read(&uts_sem); - ret = copy_to_user(&name->sname[0], &utsname()->sysname[0], + ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1); - ret |= copy_to_user(&name->nname[0], &utsname()->nodename[0], + ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1); ret |= put_user('\0', &name->nname[8]); - ret |= copy_to_user(&name->rel[0], &utsname()->release[0], + ret |= copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1); - ret |= copy_to_user(&name->ver[0], &utsname()->version[0], + ret |= copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1); - ret |= copy_to_user(&name->mach[0], &utsname()->machine[0], + ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1); up_read(&uts_sem); return (ret ? -EFAULT : 0); diff --git a/trunk/arch/sparc64/kernel/time.c b/trunk/arch/sparc64/kernel/time.c index 00f6fc4aaaff..b0b4feeec098 100644 --- a/trunk/arch/sparc64/kernel/time.c +++ b/trunk/arch/sparc64/kernel/time.c @@ -53,6 +53,8 @@ void __iomem *mstk48t02_regs = NULL; unsigned long ds1287_regs = 0UL; #endif +extern unsigned long wall_jiffies; + static void __iomem *mstk48t08_regs; static void __iomem *mstk48t59_regs; @@ -463,7 +465,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) profile_tick(CPU_PROFILING, regs); update_process_times(user_mode(regs)); #endif - do_timer(1); + do_timer(regs); /* Guarantee that the following sequences execute * uninterrupted. @@ -494,7 +496,7 @@ void timer_tick_interrupt(struct pt_regs *regs) { write_seqlock(&xtime_lock); - do_timer(1); + do_timer(regs); timer_check_rtc(); diff --git a/trunk/arch/sparc64/mm/init.c b/trunk/arch/sparc64/mm/init.c index 09cb7fccc03a..dcba4e6ab570 100644 --- a/trunk/arch/sparc64/mm/init.c +++ b/trunk/arch/sparc64/mm/init.c @@ -920,7 +920,8 @@ static unsigned long __init bootmem_init(unsigned long *pages_avail, if (sparc_ramdisk_image || sparc_ramdisk_image64) { unsigned long ramdisk_image = sparc_ramdisk_image ? sparc_ramdisk_image : sparc_ramdisk_image64; - ramdisk_image -= KERNBASE; + if (ramdisk_image >= (unsigned long)_end - 2 * PAGE_SIZE) + ramdisk_image -= KERNBASE; initrd_start = ramdisk_image + phys_base; initrd_end = initrd_start + sparc_ramdisk_size; if (initrd_end > end_of_phys_memory) { diff --git a/trunk/arch/sparc64/solaris/misc.c b/trunk/arch/sparc64/solaris/misc.c index 9ed997982f8d..642541769a17 100644 --- a/trunk/arch/sparc64/solaris/misc.c +++ b/trunk/arch/sparc64/solaris/misc.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -249,7 +248,7 @@ asmlinkage int solaris_utssys(u32 buf, u32 flags, int which, u32 buf2) /* Let's cheat */ err = set_utsfield(v->sysname, "SunOS", 1, 0); down_read(&uts_sem); - err |= set_utsfield(v->nodename, utsname()->nodename, + err |= set_utsfield(v->nodename, system_utsname.nodename, 1, 1); up_read(&uts_sem); err |= set_utsfield(v->release, "2.6", 0, 0); @@ -273,7 +272,7 @@ asmlinkage int solaris_utsname(u32 buf) /* Why should we not lie a bit? */ down_read(&uts_sem); err = set_utsfield(v->sysname, "SunOS", 0, 0); - err |= set_utsfield(v->nodename, utsname()->nodename, 1, 1); + err |= set_utsfield(v->nodename, system_utsname.nodename, 1, 1); err |= set_utsfield(v->release, "5.6", 0, 0); err |= set_utsfield(v->version, "Generic", 0, 0); err |= set_utsfield(v->machine, machine(), 0, 0); @@ -305,7 +304,7 @@ asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count) case SI_HOSTNAME: r = buffer + 256; down_read(&uts_sem); - for (p = utsname()->nodename, q = buffer; + for (p = system_utsname.nodename, q = buffer; q < r && *p && *p != '.'; *q++ = *p++); up_read(&uts_sem); *q = 0; @@ -423,9 +422,7 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid) Solaris setpgrp and setsid? */ ret = sys_setpgid(0, 0); if (ret) return ret; - mutex_lock(&tty_mutex); current->signal->tty = NULL; - mutex_unlock(&tty_mutex); return process_group(current); } case 2: /* getsid */ diff --git a/trunk/arch/um/Makefile-x86_64 b/trunk/arch/um/Makefile-x86_64 index 11154b6773ec..9558a7cf34d5 100644 --- a/trunk/arch/um/Makefile-x86_64 +++ b/trunk/arch/um/Makefile-x86_64 @@ -4,13 +4,10 @@ core-y += arch/um/sys-x86_64/ START := 0x60000000 -_extra_flags_ = -fno-builtin -m64 -mcmodel=kernel - #We #undef __x86_64__ for kernelspace, not for userspace where #it's needed for headers to work! -CFLAGS += -U__$(SUBARCH)__ $(_extra_flags_) -USER_CFLAGS += $(_extra_flags_) - +CFLAGS += -U__$(SUBARCH)__ -fno-builtin -m64 +USER_CFLAGS += -fno-builtin -m64 CHECKFLAGS += -m64 AFLAGS += -m64 LDFLAGS += -m elf_x86_64 diff --git a/trunk/arch/um/drivers/chan_kern.c b/trunk/arch/um/drivers/chan_kern.c index 3576b3cc505e..e82764f75e7f 100644 --- a/trunk/arch/um/drivers/chan_kern.c +++ b/trunk/arch/um/drivers/chan_kern.c @@ -110,7 +110,7 @@ static void not_configged_free(void *data) "UML\n"); } -static const struct chan_ops not_configged_ops = { +static struct chan_ops not_configged_ops = { .init = not_configged_init, .open = not_configged_open, .close = not_configged_close, @@ -373,7 +373,7 @@ int console_write_chan(struct list_head *chans, const char *buf, int len) } int console_open_chan(struct line *line, struct console *co, - const struct chan_opts *opts) + struct chan_opts *opts) { int err; @@ -494,10 +494,10 @@ int chan_config_string(struct list_head *chans, char *str, int size, struct chan_type { char *key; - const struct chan_ops *ops; + struct chan_ops *ops; }; -static const struct chan_type chan_table[] = { +static struct chan_type chan_table[] = { { "fd", &fd_ops }, #ifdef CONFIG_NULL_CHAN @@ -534,10 +534,10 @@ static const struct chan_type chan_table[] = { }; static struct chan *parse_chan(struct line *line, char *str, int device, - const struct chan_opts *opts) + struct chan_opts *opts) { - const struct chan_type *entry; - const struct chan_ops *ops; + struct chan_type *entry; + struct chan_ops *ops; struct chan *chan; void *data; int i; @@ -582,7 +582,7 @@ static struct chan *parse_chan(struct line *line, char *str, int device, } int parse_chan_pair(char *str, struct line *line, int device, - const struct chan_opts *opts) + struct chan_opts *opts) { struct list_head *chans = &line->chan_list; struct chan *new, *chan; diff --git a/trunk/arch/um/drivers/daemon.h b/trunk/arch/um/drivers/daemon.h index 3bc3cf6b94aa..7326c42f7ef9 100644 --- a/trunk/arch/um/drivers/daemon.h +++ b/trunk/arch/um/drivers/daemon.h @@ -18,7 +18,7 @@ struct daemon_data { void *dev; }; -extern const struct net_user_info daemon_user_info; +extern struct net_user_info daemon_user_info; extern int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri); diff --git a/trunk/arch/um/drivers/daemon_kern.c b/trunk/arch/um/drivers/daemon_kern.c index 824386974f88..53d09ed78b42 100644 --- a/trunk/arch/um/drivers/daemon_kern.c +++ b/trunk/arch/um/drivers/daemon_kern.c @@ -57,7 +57,7 @@ static int daemon_write(int fd, struct sk_buff **skb, (struct daemon_data *) &lp->user)); } -static const struct net_kern_info daemon_kern_info = { +static struct net_kern_info daemon_kern_info = { .init = daemon_init, .protocol = eth_protocol, .read = daemon_read, diff --git a/trunk/arch/um/drivers/daemon_user.c b/trunk/arch/um/drivers/daemon_user.c index 77954ea77043..c944265955e2 100644 --- a/trunk/arch/um/drivers/daemon_user.c +++ b/trunk/arch/um/drivers/daemon_user.c @@ -182,7 +182,7 @@ static int daemon_set_mtu(int mtu, void *data) return(mtu); } -const struct net_user_info daemon_user_info = { +struct net_user_info daemon_user_info = { .init = daemon_user_init, .open = daemon_open, .close = NULL, diff --git a/trunk/arch/um/drivers/fd.c b/trunk/arch/um/drivers/fd.c index 108b7dafbd0e..c41f75e4acb5 100644 --- a/trunk/arch/um/drivers/fd.c +++ b/trunk/arch/um/drivers/fd.c @@ -20,7 +20,7 @@ struct fd_chan { char str[sizeof("1234567890\0")]; }; -static void *fd_init(char *str, int device, const struct chan_opts *opts) +static void *fd_init(char *str, int device, struct chan_opts *opts) { struct fd_chan *data; char *end; @@ -77,7 +77,7 @@ static void fd_close(int fd, void *d) } } -const struct chan_ops fd_ops = { +struct chan_ops fd_ops = { .type = "fd", .init = fd_init, .open = fd_open, diff --git a/trunk/arch/um/drivers/hostaudio_kern.c b/trunk/arch/um/drivers/hostaudio_kern.c index d247ef45c374..37232f908cd7 100644 --- a/trunk/arch/um/drivers/hostaudio_kern.c +++ b/trunk/arch/um/drivers/hostaudio_kern.c @@ -280,7 +280,7 @@ static int hostmixer_release(struct inode *inode, struct file *file) /* kernel module operations */ -static const struct file_operations hostaudio_fops = { +static struct file_operations hostaudio_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = hostaudio_read, @@ -292,7 +292,7 @@ static const struct file_operations hostaudio_fops = { .release = hostaudio_release, }; -static const struct file_operations hostmixer_fops = { +static struct file_operations hostmixer_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .ioctl = hostmixer_ioctl_mixdev, diff --git a/trunk/arch/um/drivers/line.c b/trunk/arch/um/drivers/line.c index 24747a413785..ebebaabb78ad 100644 --- a/trunk/arch/um/drivers/line.c +++ b/trunk/arch/um/drivers/line.c @@ -251,7 +251,7 @@ void line_set_termios(struct tty_struct *tty, struct termios * old) /* nothing */ } -static const struct { +static struct { int cmd; char *level; char *name; @@ -405,7 +405,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data, int line_setup_irq(int fd, int input, int output, struct line *line, void *data) { - const struct line_driver *driver = line->driver; + struct line_driver *driver = line->driver; int err = 0, flags = IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM; if (input) @@ -558,7 +558,7 @@ int line_setup(struct line *lines, unsigned int num, char *init) } int line_config(struct line *lines, unsigned int num, char *str, - const struct chan_opts *opts) + struct chan_opts *opts) { struct line *line; char *new; @@ -642,9 +642,9 @@ int line_remove(struct line *lines, unsigned int num, int n) } struct tty_driver *line_register_devfs(struct lines *set, - struct line_driver *line_driver, - const struct tty_operations *ops, - struct line *lines, int nlines) + struct line_driver *line_driver, + struct tty_operations *ops, struct line *lines, + int nlines) { int i; struct tty_driver *driver = alloc_tty_driver(nlines); diff --git a/trunk/arch/um/drivers/mcast.h b/trunk/arch/um/drivers/mcast.h index bc56af9d3e53..a2c6db243458 100644 --- a/trunk/arch/um/drivers/mcast.h +++ b/trunk/arch/um/drivers/mcast.h @@ -13,7 +13,7 @@ struct mcast_data { void *dev; }; -extern const struct net_user_info mcast_user_info; +extern struct net_user_info mcast_user_info; extern int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri); diff --git a/trunk/arch/um/drivers/mcast_kern.c b/trunk/arch/um/drivers/mcast_kern.c index c090fbd464e7..3a7af18cf944 100644 --- a/trunk/arch/um/drivers/mcast_kern.c +++ b/trunk/arch/um/drivers/mcast_kern.c @@ -61,7 +61,7 @@ static int mcast_write(int fd, struct sk_buff **skb, (struct mcast_data *) &lp->user); } -static const struct net_kern_info mcast_kern_info = { +static struct net_kern_info mcast_kern_info = { .init = mcast_init, .protocol = eth_protocol, .read = mcast_read, diff --git a/trunk/arch/um/drivers/mcast_user.c b/trunk/arch/um/drivers/mcast_user.c index 4d2bd39a85bc..afe85bfa66e0 100644 --- a/trunk/arch/um/drivers/mcast_user.c +++ b/trunk/arch/um/drivers/mcast_user.c @@ -152,7 +152,7 @@ static int mcast_set_mtu(int mtu, void *data) return(mtu); } -const struct net_user_info mcast_user_info = { +struct net_user_info mcast_user_info = { .init = mcast_user_init, .open = mcast_open, .close = mcast_close, diff --git a/trunk/arch/um/drivers/mconsole_kern.c b/trunk/arch/um/drivers/mconsole_kern.c index a67dcbd78de4..79610b5ce67e 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -106,9 +106,9 @@ void mconsole_version(struct mc_request *req) { char version[256]; - sprintf(version, "%s %s %s %s %s", utsname()->sysname, - utsname()->nodename, utsname()->release, - utsname()->version, utsname()->machine); + sprintf(version, "%s %s %s %s %s", system_utsname.sysname, + system_utsname.nodename, system_utsname.release, + system_utsname.version, system_utsname.machine); mconsole_reply(req, version, 0, 0); } @@ -598,11 +598,6 @@ void mconsole_remove(struct mc_request *req) mconsole_reply(req, err_msg, err, 0); } -struct mconsole_output { - struct list_head list; - struct mc_request *req; -}; - static DEFINE_SPINLOCK(console_lock); static LIST_HEAD(clients); static char console_buf[MCONSOLE_MAX_DATA]; @@ -627,10 +622,10 @@ static void console_write(struct console *console, const char *string, return; list_for_each(ele, &clients){ - struct mconsole_output *entry; + struct mconsole_entry *entry; - entry = list_entry(ele, struct mconsole_output, list); - mconsole_reply_len(entry->req, console_buf, + entry = list_entry(ele, struct mconsole_entry, list); + mconsole_reply_len(&entry->request, console_buf, console_index, 0, 1); } @@ -654,10 +649,10 @@ late_initcall(mc_add_console); static void with_console(struct mc_request *req, void (*proc)(void *), void *arg) { - struct mconsole_output entry; + struct mconsole_entry entry; unsigned long flags; - entry.req = req; + entry.request = *req; list_add(&entry.list, &clients); spin_lock_irqsave(&console_lock, flags); diff --git a/trunk/arch/um/drivers/mconsole_user.c b/trunk/arch/um/drivers/mconsole_user.c index 17068eb746c0..5b2f5fe9e426 100644 --- a/trunk/arch/um/drivers/mconsole_user.c +++ b/trunk/arch/um/drivers/mconsole_user.c @@ -131,10 +131,6 @@ int mconsole_get_request(int fd, struct mc_request *req) int mconsole_reply_len(struct mc_request *req, const char *str, int total, int err, int more) { - /* XXX This is a stack consumption problem. It'd be nice to - * make it global and serialize access to it, but there are a - * ton of callers to this function. - */ struct mconsole_reply reply; int len, n; diff --git a/trunk/arch/um/drivers/mmapper_kern.c b/trunk/arch/um/drivers/mmapper_kern.c index 9a3b5daf6250..022f67bb6873 100644 --- a/trunk/arch/um/drivers/mmapper_kern.c +++ b/trunk/arch/um/drivers/mmapper_kern.c @@ -85,7 +85,7 @@ mmapper_release(struct inode *inode, struct file *file) return 0; } -static const struct file_operations mmapper_fops = { +static struct file_operations mmapper_fops = { .owner = THIS_MODULE, .read = mmapper_read, .write = mmapper_write, @@ -95,7 +95,7 @@ static const struct file_operations mmapper_fops = { .release = mmapper_release, }; -static const struct miscdevice mmapper_dev = { +static struct miscdevice mmapper_dev = { .minor = MISC_DYNAMIC_MINOR, .name = "mmapper", .fops = &mmapper_fops diff --git a/trunk/arch/um/drivers/net_kern.c b/trunk/arch/um/drivers/net_kern.c index 300a54a6523e..4a7966b21931 100644 --- a/trunk/arch/um/drivers/net_kern.c +++ b/trunk/arch/um/drivers/net_kern.c @@ -114,11 +114,18 @@ static int uml_net_open(struct net_device *dev) struct uml_net_private *lp = dev->priv; int err; + spin_lock(&lp->lock); + if(lp->fd >= 0){ err = -ENXIO; goto out; } + if(!lp->have_mac){ + dev_ip_addr(dev, &lp->mac[2]); + set_ether_mac(dev, lp->mac); + } + lp->fd = (*lp->open)(&lp->user); if(lp->fd < 0){ err = lp->fd; @@ -142,6 +149,8 @@ static int uml_net_open(struct net_device *dev) */ while((err = uml_net_rx(dev)) > 0) ; + spin_unlock(&lp->lock); + spin_lock(&opened_lock); list_add(&lp->list, &opened); spin_unlock(&opened_lock); @@ -151,6 +160,7 @@ static int uml_net_open(struct net_device *dev) if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); lp->fd = -1; out: + spin_unlock(&lp->lock); return err; } @@ -159,12 +169,15 @@ static int uml_net_close(struct net_device *dev) struct uml_net_private *lp = dev->priv; netif_stop_queue(dev); + spin_lock(&lp->lock); free_irq(dev->irq, dev); if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); lp->fd = -1; + spin_unlock(&lp->lock); + spin_lock(&opened_lock); list_del(&lp->list); spin_unlock(&opened_lock); @@ -233,9 +246,9 @@ static int uml_net_set_mac(struct net_device *dev, void *addr) struct uml_net_private *lp = dev->priv; struct sockaddr *hwaddr = addr; - spin_lock_irq(&lp->lock); + spin_lock(&lp->lock); set_ether_mac(dev, hwaddr->sa_data); - spin_unlock_irq(&lp->lock); + spin_unlock(&lp->lock); return(0); } @@ -245,7 +258,7 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu) struct uml_net_private *lp = dev->priv; int err = 0; - spin_lock_irq(&lp->lock); + spin_lock(&lp->lock); new_mtu = (*lp->set_mtu)(new_mtu, &lp->user); if(new_mtu < 0){ @@ -256,7 +269,7 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu) dev->mtu = new_mtu; out: - spin_unlock_irq(&lp->lock); + spin_unlock(&lp->lock); return err; } @@ -282,37 +295,6 @@ void uml_net_user_timer_expire(unsigned long _conn) #endif } -static void setup_etheraddr(char *str, unsigned char *addr) -{ - char *end; - int i; - - if(str == NULL) - goto random; - - for(i=0;i<6;i++){ - addr[i] = simple_strtoul(str, &end, 16); - if((end == str) || - ((*end != ':') && (*end != ',') && (*end != '\0'))){ - printk(KERN_ERR - "setup_etheraddr: failed to parse '%s' " - "as an ethernet address\n", str); - goto random; - } - str = end + 1; - } - if(addr[0] & 1){ - printk(KERN_ERR - "Attempt to assign a broadcast ethernet address to a " - "device disallowed\n"); - goto random; - } - return; - -random: - random_ether_addr(addr); -} - static DEFINE_SPINLOCK(devices_lock); static LIST_HEAD(devices); @@ -348,13 +330,15 @@ static int eth_configure(int n, void *init, char *mac, list_add(&device->list, &devices); spin_unlock(&devices_lock); - setup_etheraddr(mac, device->mac); + if (setup_etheraddr(mac, device->mac)) + device->have_mac = 1; printk(KERN_INFO "Netdevice %d ", n); - printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", - device->mac[0], device->mac[1], - device->mac[2], device->mac[3], - device->mac[4], device->mac[5]); + if (device->have_mac) + printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", + device->mac[0], device->mac[1], + device->mac[2], device->mac[3], + device->mac[4], device->mac[5]); printk(": "); dev = alloc_etherdev(size); if (dev == NULL) { @@ -420,6 +404,7 @@ static int eth_configure(int n, void *init, char *mac, .dev = dev, .fd = -1, .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0}, + .have_mac = device->have_mac, .protocol = transport->kern->protocol, .open = transport->user->open, .close = transport->user->close, @@ -434,12 +419,14 @@ static int eth_configure(int n, void *init, char *mac, init_timer(&lp->tl); spin_lock_init(&lp->lock); lp->tl.function = uml_net_user_timer_expire; - memcpy(lp->mac, device->mac, sizeof(lp->mac)); + if (lp->have_mac) + memcpy(lp->mac, device->mac, sizeof(lp->mac)); if (transport->user->init) (*transport->user->init)(&lp->user, dev); - set_ether_mac(dev, device->mac); + if (device->have_mac) + set_ether_mac(dev, device->mac); return 0; } @@ -582,13 +569,12 @@ static int eth_setup(char *str) int n, err; err = eth_parse(str, &n, &str); - if(err) - return 1; + if(err) return(1); - new = alloc_bootmem(sizeof(*new)); + new = alloc_bootmem(sizeof(new)); if (new == NULL){ printk("eth_init : alloc_bootmem failed\n"); - return 1; + return(1); } INIT_LIST_HEAD(&new->list); @@ -596,7 +582,7 @@ static int eth_setup(char *str) new->init = str; list_add_tail(&new->list, ð_cmd_line); - return 1; + return(1); } __setup("eth", eth_setup); @@ -768,6 +754,47 @@ static void close_devices(void) __uml_exitcall(close_devices); +int setup_etheraddr(char *str, unsigned char *addr) +{ + char *end; + int i; + + if(str == NULL) + return(0); + for(i=0;i<6;i++){ + addr[i] = simple_strtoul(str, &end, 16); + if((end == str) || + ((*end != ':') && (*end != ',') && (*end != '\0'))){ + printk(KERN_ERR + "setup_etheraddr: failed to parse '%s' " + "as an ethernet address\n", str); + return(0); + } + str = end + 1; + } + if(addr[0] & 1){ + printk(KERN_ERR + "Attempt to assign a broadcast ethernet address to a " + "device disallowed\n"); + return(0); + } + return(1); +} + +void dev_ip_addr(void *d, unsigned char *bin_buf) +{ + struct net_device *dev = d; + struct in_device *ip = dev->ip_ptr; + struct in_ifaddr *in; + + if((ip == NULL) || ((in = ip->ifa_list) == NULL)){ + printk(KERN_WARNING "dev_ip_addr - device not assigned an " + "IP address\n"); + return; + } + memcpy(bin_buf, &in->ifa_address, sizeof(in->ifa_address)); +} + struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra) { if((skb != NULL) && (skb_tailroom(skb) < extra)){ @@ -805,7 +832,7 @@ int dev_netmask(void *d, void *m) struct net_device *dev = d; struct in_device *ip = dev->ip_ptr; struct in_ifaddr *in; - __be32 *mask_out = m; + __u32 *mask_out = m; if(ip == NULL) return(1); diff --git a/trunk/arch/um/drivers/net_user.c b/trunk/arch/um/drivers/net_user.c index f3a3f8a29c7a..107c5e43fa00 100644 --- a/trunk/arch/um/drivers/net_user.c +++ b/trunk/arch/um/drivers/net_user.c @@ -12,7 +12,6 @@ #include #include #include -#include #include "user.h" #include "user_util.h" #include "kern_util.h" diff --git a/trunk/arch/um/drivers/null.c b/trunk/arch/um/drivers/null.c index 9016c68beee8..14cc5f78398a 100644 --- a/trunk/arch/um/drivers/null.c +++ b/trunk/arch/um/drivers/null.c @@ -8,10 +8,9 @@ #include "chan_user.h" #include "os.h" -/* This address is used only as a unique identifer */ static int null_chan; -static void *null_init(char *str, int device, const struct chan_opts *opts) +static void *null_init(char *str, int device, struct chan_opts *opts) { return(&null_chan); } @@ -32,7 +31,7 @@ static void null_free(void *data) { } -const struct chan_ops null_ops = { +struct chan_ops null_ops = { .type = "null", .init = null_init, .open = null_open, diff --git a/trunk/arch/um/drivers/pcap_kern.c b/trunk/arch/um/drivers/pcap_kern.c index 6e1ef8558283..4c767c7adb96 100644 --- a/trunk/arch/um/drivers/pcap_kern.c +++ b/trunk/arch/um/drivers/pcap_kern.c @@ -46,7 +46,7 @@ static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) return(-EPERM); } -static const struct net_kern_info pcap_kern_info = { +static struct net_kern_info pcap_kern_info = { .init = pcap_init, .protocol = eth_protocol, .read = pcap_read, diff --git a/trunk/arch/um/drivers/pcap_user.c b/trunk/arch/um/drivers/pcap_user.c index 2ef641ded960..edfcb29273e1 100644 --- a/trunk/arch/um/drivers/pcap_user.c +++ b/trunk/arch/um/drivers/pcap_user.c @@ -120,7 +120,7 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri) return(hdata.len); } -const struct net_user_info pcap_user_info = { +struct net_user_info pcap_user_info = { .init = pcap_user_init, .open = pcap_open, .close = NULL, diff --git a/trunk/arch/um/drivers/port_user.c b/trunk/arch/um/drivers/port_user.c index f2e8fc42ecc2..c43e8bb32502 100644 --- a/trunk/arch/um/drivers/port_user.c +++ b/trunk/arch/um/drivers/port_user.c @@ -27,7 +27,7 @@ struct port_chan { char dev[sizeof("32768\0")]; }; -static void *port_init(char *str, int device, const struct chan_opts *opts) +static void *port_init(char *str, int device, struct chan_opts *opts) { struct port_chan *data; void *kern_data; @@ -100,7 +100,7 @@ static void port_close(int fd, void *d) os_close_file(fd); } -const struct chan_ops port_ops = { +struct chan_ops port_ops = { .type = "port", .init = port_init, .open = port_open, diff --git a/trunk/arch/um/drivers/pty.c b/trunk/arch/um/drivers/pty.c index abec620e8380..1c555c38de4d 100644 --- a/trunk/arch/um/drivers/pty.c +++ b/trunk/arch/um/drivers/pty.c @@ -22,7 +22,7 @@ struct pty_chan { char dev_name[sizeof("/dev/pts/0123456\0")]; }; -static void *pty_chan_init(char *str, int device, const struct chan_opts *opts) +static void *pty_chan_init(char *str, int device, struct chan_opts *opts) { struct pty_chan *data; @@ -118,7 +118,7 @@ static int pty_open(int input, int output, int primary, void *d, return(fd); } -const struct chan_ops pty_ops = { +struct chan_ops pty_ops = { .type = "pty", .init = pty_chan_init, .open = pty_open, @@ -131,7 +131,7 @@ const struct chan_ops pty_ops = { .winch = 0, }; -const struct chan_ops pts_ops = { +struct chan_ops pts_ops = { .type = "pts", .init = pty_chan_init, .open = pts_open, diff --git a/trunk/arch/um/drivers/random.c b/trunk/arch/um/drivers/random.c index 73b2bdd6d2d3..ba471f5864a6 100644 --- a/trunk/arch/um/drivers/random.c +++ b/trunk/arch/um/drivers/random.c @@ -20,10 +20,6 @@ #define RNG_MISCDEV_MINOR 183 /* official */ -/* Changed at init time, in the non-modular case, and at module load - * time, in the module case. Presumably, the module subsystem - * protects against a module being loaded twice at the same time. - */ static int random_fd = -1; static int rng_dev_open (struct inode *inode, struct file *filp) @@ -72,7 +68,7 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size, return ret; } -static const struct file_operations rng_chrdev_ops = { +static struct file_operations rng_chrdev_ops = { .owner = THIS_MODULE, .open = rng_dev_open, .read = rng_dev_read, diff --git a/trunk/arch/um/drivers/slip.h b/trunk/arch/um/drivers/slip.h index c64f8c61d274..bb0dab41c2e4 100644 --- a/trunk/arch/um/drivers/slip.h +++ b/trunk/arch/um/drivers/slip.h @@ -12,7 +12,7 @@ struct slip_data { struct slip_proto slip; }; -extern const struct net_user_info slip_user_info; +extern struct net_user_info slip_user_info; extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri); extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri); diff --git a/trunk/arch/um/drivers/slip_kern.c b/trunk/arch/um/drivers/slip_kern.c index ccea2d7885e5..163ee0d5f75e 100644 --- a/trunk/arch/um/drivers/slip_kern.c +++ b/trunk/arch/um/drivers/slip_kern.c @@ -61,7 +61,7 @@ static int slip_write(int fd, struct sk_buff **skb, (struct slip_data *) &lp->user)); } -const struct net_kern_info slip_kern_info = { +struct net_kern_info slip_kern_info = { .init = slip_init, .protocol = slip_protocol, .read = slip_read, diff --git a/trunk/arch/um/drivers/slip_user.c b/trunk/arch/um/drivers/slip_user.c index 8460285c69a5..89fbec185cc1 100644 --- a/trunk/arch/um/drivers/slip_user.c +++ b/trunk/arch/um/drivers/slip_user.c @@ -241,7 +241,7 @@ static void slip_del_addr(unsigned char *addr, unsigned char *netmask, close_addr(addr, netmask, pri->name); } -const struct net_user_info slip_user_info = { +struct net_user_info slip_user_info = { .init = slip_user_init, .open = slip_open, .close = slip_close, diff --git a/trunk/arch/um/drivers/slirp.h b/trunk/arch/um/drivers/slirp.h index 89ccf83b7577..6cf88ab580c9 100644 --- a/trunk/arch/um/drivers/slirp.h +++ b/trunk/arch/um/drivers/slirp.h @@ -24,7 +24,7 @@ struct slirp_data { struct slip_proto slip; }; -extern const struct net_user_info slirp_user_info; +extern struct net_user_info slirp_user_info; extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri); extern int slirp_user_write(int fd, void *buf, int len, diff --git a/trunk/arch/um/drivers/slirp_kern.c b/trunk/arch/um/drivers/slirp_kern.c index ae322e1c8a87..95e50c943e14 100644 --- a/trunk/arch/um/drivers/slirp_kern.c +++ b/trunk/arch/um/drivers/slirp_kern.c @@ -64,7 +64,7 @@ static int slirp_write(int fd, struct sk_buff **skb, (struct slirp_data *) &lp->user)); } -const struct net_kern_info slirp_kern_info = { +struct net_kern_info slirp_kern_info = { .init = slirp_init, .protocol = slirp_protocol, .read = slirp_read, diff --git a/trunk/arch/um/drivers/slirp_user.c b/trunk/arch/um/drivers/slirp_user.c index ce5e85d1de3d..33c5f6e625e8 100644 --- a/trunk/arch/um/drivers/slirp_user.c +++ b/trunk/arch/um/drivers/slirp_user.c @@ -126,7 +126,7 @@ static int slirp_set_mtu(int mtu, void *data) return(mtu); } -const struct net_user_info slirp_user_info = { +struct net_user_info slirp_user_info = { .init = slirp_user_init, .open = slirp_open, .close = slirp_close, diff --git a/trunk/arch/um/drivers/ssl.c b/trunk/arch/um/drivers/ssl.c index 6f13e7c71a82..6dafd6fbfdae 100644 --- a/trunk/arch/um/drivers/ssl.c +++ b/trunk/arch/um/drivers/ssl.c @@ -23,7 +23,7 @@ #include "irq_user.h" #include "mconsole_kern.h" -static const int ssl_version = 1; +static int ssl_version = 1; /* Referenced only by tty_driver below - presumably it's locked correctly * by the tty driver. @@ -123,7 +123,7 @@ void ssl_hangup(struct tty_struct *tty) } #endif -static const struct tty_operations ssl_ops = { +static struct tty_operations ssl_ops = { .open = ssl_open, .close = line_close, .write = line_write, diff --git a/trunk/arch/um/drivers/stderr_console.c b/trunk/arch/um/drivers/stderr_console.c index 911539293871..6d2cf32a9e8f 100644 --- a/trunk/arch/um/drivers/stderr_console.c +++ b/trunk/arch/um/drivers/stderr_console.c @@ -9,8 +9,6 @@ /* * Don't register by default -- as this registeres very early in the * boot process it becomes the default console. - * - * Initialized at init time. */ static int use_stderr_console = 0; diff --git a/trunk/arch/um/drivers/stdio_console.c b/trunk/arch/um/drivers/stdio_console.c index e4bfcfe8550b..856f568c2687 100644 --- a/trunk/arch/um/drivers/stdio_console.c +++ b/trunk/arch/um/drivers/stdio_console.c @@ -108,10 +108,9 @@ static int con_open(struct tty_struct *tty, struct file *filp) return line_open(vts, tty); } -/* Set in an initcall, checked in an exitcall */ static int con_init_done = 0; -static const struct tty_operations console_ops = { +static struct tty_operations console_ops = { .open = con_open, .close = line_close, .write = line_write, diff --git a/trunk/arch/um/drivers/tty.c b/trunk/arch/um/drivers/tty.c index 11de3ac1eb5c..9f70edf5d8ef 100644 --- a/trunk/arch/um/drivers/tty.c +++ b/trunk/arch/um/drivers/tty.c @@ -18,7 +18,7 @@ struct tty_chan { struct termios tt; }; -static void *tty_chan_init(char *str, int device, const struct chan_opts *opts) +static void *tty_chan_init(char *str, int device, struct chan_opts *opts) { struct tty_chan *data; @@ -62,7 +62,7 @@ static int tty_open(int input, int output, int primary, void *d, return fd; } -const struct chan_ops tty_ops = { +struct chan_ops tty_ops = { .type = "tty", .init = tty_chan_init, .open = tty_open, diff --git a/trunk/arch/um/drivers/ubd_kern.c b/trunk/arch/um/drivers/ubd_kern.c index fda4a3940698..34085315aa57 100644 --- a/trunk/arch/um/drivers/ubd_kern.c +++ b/trunk/arch/um/drivers/ubd_kern.c @@ -668,15 +668,18 @@ static int ubd_add(int n) if(dev->file == NULL) goto out; + if (ubd_open_dev(dev)) + goto out; + err = ubd_file_size(dev, &dev->size); if(err < 0) - goto out; + goto out_close; dev->size = ROUND_BLOCK(dev->size); err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]); if(err) - goto out; + goto out_close; if(fake_major != MAJOR_NR) ubd_new_disk(fake_major, dev->size, n, @@ -688,6 +691,8 @@ static int ubd_add(int n) make_ide_entries(ubd_gendisk[n]->disk_name); err = 0; +out_close: + ubd_close(dev); out: return err; } @@ -981,6 +986,8 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) __u64 offset; int len; + if(req->rq_status == RQ_INACTIVE) return(1); + /* This should be impossible now */ if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ printk("Write attempted on readonly ubd device %s\n", diff --git a/trunk/arch/um/drivers/xterm.c b/trunk/arch/um/drivers/xterm.c index 386f8b952982..aaa636661043 100644 --- a/trunk/arch/um/drivers/xterm.c +++ b/trunk/arch/um/drivers/xterm.c @@ -31,7 +31,7 @@ struct xterm_chan { }; /* Not static because it's called directly by the tt mode gdb code */ -void *xterm_init(char *str, int device, const struct chan_opts *opts) +void *xterm_init(char *str, int device, struct chan_opts *opts) { struct xterm_chan *data; @@ -194,7 +194,7 @@ static void xterm_free(void *d) free(d); } -const struct chan_ops xterm_ops = { +struct chan_ops xterm_ops = { .type = "xterm", .init = xterm_init, .open = xterm_open, diff --git a/trunk/arch/um/include/chan_kern.h b/trunk/arch/um/include/chan_kern.h index 572d286ed2c6..1bb5e9d94270 100644 --- a/trunk/arch/um/include/chan_kern.h +++ b/trunk/arch/um/include/chan_kern.h @@ -23,21 +23,21 @@ struct chan { unsigned int opened:1; unsigned int enabled:1; int fd; - const struct chan_ops *ops; + struct chan_ops *ops; void *data; }; extern void chan_interrupt(struct list_head *chans, struct work_struct *task, struct tty_struct *tty, int irq); extern int parse_chan_pair(char *str, struct line *line, int device, - const struct chan_opts *opts); + struct chan_opts *opts); extern int open_chan(struct list_head *chans); extern int write_chan(struct list_head *chans, const char *buf, int len, int write_irq); extern int console_write_chan(struct list_head *chans, const char *buf, int len); extern int console_open_chan(struct line *line, struct console *co, - const struct chan_opts *opts); + struct chan_opts *opts); extern void deactivate_chan(struct list_head *chans, int irq); extern void reactivate_chan(struct list_head *chans, int irq); extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty); diff --git a/trunk/arch/um/include/chan_user.h b/trunk/arch/um/include/chan_user.h index a795547a1dbd..659bb3cac32f 100644 --- a/trunk/arch/um/include/chan_user.h +++ b/trunk/arch/um/include/chan_user.h @@ -20,7 +20,7 @@ enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE }; struct chan_ops { char *type; - void *(*init)(char *, int, const struct chan_opts *); + void *(*init)(char *, int, struct chan_opts *); int (*open)(int, int, int, void *, char **); void (*close)(int, void *); int (*read)(int, char *, void *); @@ -31,8 +31,8 @@ struct chan_ops { int winch; }; -extern const struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, - tty_ops, xterm_ops; +extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops, + xterm_ops; extern void generic_close(int fd, void *unused); extern int generic_read(int fd, char *c_out, void *unused); diff --git a/trunk/arch/um/include/kern_util.h b/trunk/arch/um/include/kern_util.h index 59cfa9e0cad0..89e1dc835a5b 100644 --- a/trunk/arch/um/include/kern_util.h +++ b/trunk/arch/um/include/kern_util.h @@ -21,7 +21,7 @@ struct kern_handlers { kern_hndl timer_handler; }; -extern const struct kern_handlers handlinfo_kern; +extern struct kern_handlers handlinfo_kern; extern int ncpus; extern char *linux_prog; diff --git a/trunk/arch/um/include/line.h b/trunk/arch/um/include/line.h index 7be24811bb30..27bf2f6fbc05 100644 --- a/trunk/arch/um/include/line.h +++ b/trunk/arch/um/include/line.h @@ -52,7 +52,7 @@ struct line { int sigio; struct work_struct task; - const struct line_driver *driver; + struct line_driver *driver; int have_irq; }; @@ -91,14 +91,15 @@ extern int line_setup_irq(int fd, int input, int output, struct line *line, void *data); extern void line_close_chan(struct line *line); extern struct tty_driver * line_register_devfs(struct lines *set, - struct line_driver *line_driver, - const struct tty_operations *driver, - struct line *lines, int nlines); + struct line_driver *line_driver, + struct tty_operations *driver, + struct line *lines, + int nlines); extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts); extern void close_lines(struct line *lines, int nlines); extern int line_config(struct line *lines, unsigned int sizeof_lines, - char *str, const struct chan_opts *opts); + char *str, struct chan_opts *opts); extern int line_id(char **str, int *start_out, int *end_out); extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n); extern int line_get_config(char *dev, struct line *lines, diff --git a/trunk/arch/um/include/net_kern.h b/trunk/arch/um/include/net_kern.h index 280459fb0b26..f7de6df60dd7 100644 --- a/trunk/arch/um/include/net_kern.h +++ b/trunk/arch/um/include/net_kern.h @@ -18,6 +18,7 @@ struct uml_net { struct platform_device pdev; int index; unsigned char mac[ETH_ALEN]; + int have_mac; }; struct uml_net_private { @@ -28,6 +29,7 @@ struct uml_net_private { struct net_device_stats stats; int fd; unsigned char mac[ETH_ALEN]; + int have_mac; unsigned short (*protocol)(struct sk_buff *); int (*open)(void *); void (*close)(int, void *); @@ -52,14 +54,15 @@ struct transport { struct list_head list; char *name; int (*setup)(char *, char **, void *); - const struct net_user_info *user; - const struct net_kern_info *kern; + struct net_user_info *user; + struct net_kern_info *kern; int private_size; int setup_size; }; extern struct net_device *ether_init(int); extern unsigned short ether_protocol(struct sk_buff *); +extern int setup_etheraddr(char *str, unsigned char *addr); extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra); extern int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out, char **gate_addr); @@ -67,3 +70,14 @@ extern void register_transport(struct transport *new); extern unsigned short eth_protocol(struct sk_buff *skb); #endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/net_user.h b/trunk/arch/um/include/net_user.h index 19f207cd70fe..47ef7cb49a8e 100644 --- a/trunk/arch/um/include/net_user.h +++ b/trunk/arch/um/include/net_user.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -25,8 +25,9 @@ struct net_user_info { }; extern void ether_user_init(void *data, void *dev); -extern void iter_addresses(void *d, void (*cb)(unsigned char *, - unsigned char *, void *), +extern void dev_ip_addr(void *d, unsigned char *bin_buf); +extern void iter_addresses(void *d, void (*cb)(unsigned char *, + unsigned char *, void *), void *arg); extern void *get_output_buffer(int *len_out); @@ -51,3 +52,14 @@ extern char *split_if_spec(char *str, ...); extern int dev_netmask(void *d, void *m); #endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/os.h b/trunk/arch/um/include/os.h index 120ca21a513a..24fb6d8680e1 100644 --- a/trunk/arch/um/include/os.h +++ b/trunk/arch/um/include/os.h @@ -14,7 +14,6 @@ #include "skas/mm_id.h" #include "irq_user.h" #include "sysdep/tls.h" -#include "sysdep/archsetjmp.h" #define OS_TYPE_FILE 1 #define OS_TYPE_DIR 2 @@ -199,9 +198,7 @@ extern long os_ptrace_ldt(long pid, long addr, long data); extern int os_getpid(void); extern int os_getpgrp(void); -#ifdef UML_CONFIG_MODE_TT extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); -#endif extern void init_new_thread_signals(void); extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); @@ -219,6 +216,7 @@ extern void os_flush_stdout(void); */ extern void forward_ipi(int fd, int pid); extern void kill_child_dead(int pid); +extern void stop(void); extern int wait_for_stop(int pid, int sig, int cont_type, void *relay); extern int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, int must_succeed); @@ -309,9 +307,12 @@ extern int copy_context_skas0(unsigned long stack, int pid); extern void userspace(union uml_pt_regs *regs); extern void map_stub_pages(int fd, unsigned long code, unsigned long data, unsigned long stack); -extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)); -extern void switch_threads(jmp_buf *me, jmp_buf *you); -extern int start_idle_thread(void *stack, jmp_buf *switch_buf); +extern void new_thread(void *stack, void **switch_buf_ptr, + void **fork_buf_ptr, void (*handler)(int)); +extern void thread_wait(void *sw, void *fb); +extern void switch_threads(void *me, void *next); +extern int start_idle_thread(void *stack, void *switch_buf_ptr, + void **fork_buf_ptr); extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); extern void halt_skas(void); diff --git a/trunk/arch/um/include/skas/skas.h b/trunk/arch/um/include/skas/skas.h index e88926b16072..853b26f148c5 100644 --- a/trunk/arch/um/include/skas/skas.h +++ b/trunk/arch/um/include/skas/skas.h @@ -14,7 +14,8 @@ extern int proc_mm, ptrace_faultinfo, ptrace_ldt; extern int skas_needs_stub; extern int user_thread(unsigned long stack, int flags); -extern void new_thread_handler(void); +extern void new_thread_proc(void *stack, void (*handler)(int sig)); +extern void new_thread_handler(int sig); extern void handle_syscall(union uml_pt_regs *regs); extern int new_mm(unsigned long stack); extern void get_skas_faultinfo(int pid, struct faultinfo * fi); diff --git a/trunk/arch/um/include/sysdep-i386/archsetjmp.h b/trunk/arch/um/include/sysdep-i386/archsetjmp.h index 11bafab669e9..ea1ba3d42aee 100644 --- a/trunk/arch/um/include/sysdep-i386/archsetjmp.h +++ b/trunk/arch/um/include/sysdep-i386/archsetjmp.h @@ -16,7 +16,4 @@ struct __jmp_buf { typedef struct __jmp_buf jmp_buf[1]; -#define JB_IP __eip -#define JB_SP __esp - #endif /* _SETJMP_H */ diff --git a/trunk/arch/um/include/sysdep-x86_64/archsetjmp.h b/trunk/arch/um/include/sysdep-x86_64/archsetjmp.h index 9a5e1a6ec800..454fc60aff6d 100644 --- a/trunk/arch/um/include/sysdep-x86_64/archsetjmp.h +++ b/trunk/arch/um/include/sysdep-x86_64/archsetjmp.h @@ -18,7 +18,4 @@ struct __jmp_buf { typedef struct __jmp_buf jmp_buf[1]; -#define JB_IP __rip -#define JB_SP __rsp - #endif /* _SETJMP_H */ diff --git a/trunk/arch/um/include/sysdep-x86_64/ptrace.h b/trunk/arch/um/include/sysdep-x86_64/ptrace.h index 617bb9efc934..8d353f0feec1 100644 --- a/trunk/arch/um/include/sysdep-x86_64/ptrace.h +++ b/trunk/arch/um/include/sysdep-x86_64/ptrace.h @@ -50,21 +50,6 @@ #define HOST_FS 25 #define HOST_GS 26 -/* Also defined in asm/ptrace-x86_64.h, but not in libc headers. So, these - * are already defined for kernel code, but not for userspace code. - */ -#ifndef FS_BASE -/* These aren't defined in ptrace.h, but exist in struct user_regs_struct, - * which is what x86_64 ptrace actually uses. - */ -#define FS_BASE (HOST_FS_BASE * sizeof(long)) -#define GS_BASE (HOST_GS_BASE * sizeof(long)) -#define DS (HOST_DS * sizeof(long)) -#define ES (HOST_ES * sizeof(long)) -#define FS (HOST_FS * sizeof(long)) -#define GS (HOST_GS * sizeof(long)) -#endif - #define REGS_FS_BASE(r) ((r)[HOST_FS_BASE]) #define REGS_GS_BASE(r) ((r)[HOST_GS_BASE]) #define REGS_DS(r) ((r)[HOST_DS]) @@ -104,12 +89,9 @@ union uml_pt_regs { #endif #ifdef UML_CONFIG_MODE_SKAS struct skas_regs { - /* x86_64 ptrace uses sizeof(user_regs_struct) as its register - * file size, while i386 uses FRAME_SIZE. Therefore, we need - * to use UM_FRAME_SIZE here instead of HOST_FRAME_SIZE. - */ - unsigned long regs[UM_FRAME_SIZE]; - unsigned long fp[HOST_FP_SIZE]; + /* XXX */ + unsigned long regs[27]; + unsigned long fp[65]; struct faultinfo faultinfo; long syscall; int is_user; @@ -138,16 +120,11 @@ extern int mode_tt; #define UPT_R14(r) __CHOOSE_MODE(SC_R14(UPT_SC(r)), REGS_R14((r)->skas.regs)) #define UPT_R15(r) __CHOOSE_MODE(SC_R15(UPT_SC(r)), REGS_R15((r)->skas.regs)) #define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) -#define UPT_FS_BASE(r) \ - __CHOOSE_MODE(SC_FS_BASE(UPT_SC(r)), REGS_FS_BASE((r)->skas.regs)) #define UPT_FS(r) __CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs)) -#define UPT_GS_BASE(r) \ - __CHOOSE_MODE(SC_GS_BASE(UPT_SC(r)), REGS_GS_BASE((r)->skas.regs)) #define UPT_GS(r) __CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs)) #define UPT_DS(r) __CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs)) #define UPT_ES(r) __CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs)) #define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) -#define UPT_SS(r) __CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs)) #define UPT_ORIG_RAX(r) \ __CHOOSE_MODE((r)->tt.orig_rax, REGS_ORIG_RAX((r)->skas.regs)) @@ -206,13 +183,6 @@ struct syscall_args { case RBP: val = UPT_RBP(regs); break; \ case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \ case CS: val = UPT_CS(regs); break; \ - case SS: val = UPT_SS(regs); break; \ - case FS_BASE: val = UPT_FS_BASE(regs); break; \ - case GS_BASE: val = UPT_GS_BASE(regs); break; \ - case DS: val = UPT_DS(regs); break; \ - case ES: val = UPT_ES(regs); break; \ - case FS : val = UPT_FS (regs); break; \ - case GS: val = UPT_GS(regs); break; \ case EFLAGS: val = UPT_EFLAGS(regs); break; \ default : \ panic("Bad register in UPT_REG : %d\n", reg); \ @@ -244,13 +214,6 @@ struct syscall_args { case RBP: UPT_RBP(regs) = __upt_val; break; \ case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ case CS: UPT_CS(regs) = __upt_val; break; \ - case SS: UPT_SS(regs) = __upt_val; break; \ - case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \ - case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \ - case DS: UPT_DS(regs) = __upt_val; break; \ - case ES: UPT_ES(regs) = __upt_val; break; \ - case FS: UPT_FS(regs) = __upt_val; break; \ - case GS: UPT_GS(regs) = __upt_val; break; \ case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \ default : \ panic("Bad register in UPT_SET : %d\n", reg); \ diff --git a/trunk/arch/um/include/sysdep-x86_64/sc.h b/trunk/arch/um/include/sysdep-x86_64/sc.h index 8aee45b07434..a160d9fcc596 100644 --- a/trunk/arch/um/include/sysdep-x86_64/sc.h +++ b/trunk/arch/um/include/sysdep-x86_64/sc.h @@ -35,11 +35,11 @@ #define SC_GS(sc) SC_OFFSET(sc, SC_GS) #define SC_EFLAGS(sc) SC_OFFSET(sc, SC_EFLAGS) #define SC_SIGMASK(sc) SC_OFFSET(sc, SC_SIGMASK) -#define SC_SS(sc) SC_OFFSET(sc, SC_SS) #if 0 #define SC_ORIG_RAX(sc) SC_OFFSET(sc, SC_ORIG_RAX) #define SC_DS(sc) SC_OFFSET(sc, SC_DS) #define SC_ES(sc) SC_OFFSET(sc, SC_ES) +#define SC_SS(sc) SC_OFFSET(sc, SC_SS) #endif #endif diff --git a/trunk/arch/um/kernel/Makefile b/trunk/arch/um/kernel/Makefile index 6fa63a2a89e3..a2d93065b2d0 100644 --- a/trunk/arch/um/kernel/Makefile +++ b/trunk/arch/um/kernel/Makefile @@ -7,7 +7,7 @@ extra-y := vmlinux.lds clean-files := obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \ - physmem.o process.o ptrace.o reboot.o resource.o sigio.o \ + physmem.o process_kern.o ptrace.o reboot.o resource.o sigio.o \ signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \ um_arch.o umid.o diff --git a/trunk/arch/um/kernel/exitcode.c b/trunk/arch/um/kernel/exitcode.c index 8b7f2cdedf94..d21ebad666b4 100644 --- a/trunk/arch/um/kernel/exitcode.c +++ b/trunk/arch/um/kernel/exitcode.c @@ -16,13 +16,9 @@ int uml_exitcode = 0; static int read_proc_exitcode(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len, val; + int len; - /* Save uml_exitcode in a local so that we don't need to guarantee - * that sprintf accesses it atomically. - */ - val = uml_exitcode; - len = sprintf(page, "%d\n", val); + len = sprintf(page, "%d\n", uml_exitcode); len -= off; if(len <= off+count) *eof = 1; *start = page + off; diff --git a/trunk/arch/um/kernel/gmon_syms.c b/trunk/arch/um/kernel/gmon_syms.c index 13aa115cd1b4..2c86e7fdb014 100644 --- a/trunk/arch/um/kernel/gmon_syms.c +++ b/trunk/arch/um/kernel/gmon_syms.c @@ -5,7 +5,7 @@ #include "linux/module.h" -extern void __bb_init_func(void *) __attribute__((weak)); +extern void __bb_init_func(void *); EXPORT_SYMBOL(__bb_init_func); /* This is defined (and referred to in profiling stub code) only by some GCC @@ -21,3 +21,14 @@ EXPORT_SYMBOL(__gcov_init); extern void __gcov_merge_add(void *) __attribute__((weak)); EXPORT_SYMBOL(__gcov_merge_add); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/kernel/ksyms.c b/trunk/arch/um/kernel/ksyms.c index f030e44262ba..c97045d6d89f 100644 --- a/trunk/arch/um/kernel/ksyms.c +++ b/trunk/arch/um/kernel/ksyms.c @@ -21,6 +21,7 @@ #include "mem_user.h" #include "os.h" +EXPORT_SYMBOL(stop); EXPORT_SYMBOL(uml_physmem); EXPORT_SYMBOL(set_signals); EXPORT_SYMBOL(get_signals); @@ -40,14 +41,12 @@ EXPORT_SYMBOL(handle_page_fault); EXPORT_SYMBOL(find_iomem); #ifdef CONFIG_MODE_TT -EXPORT_SYMBOL(stop); EXPORT_SYMBOL(strncpy_from_user_tt); EXPORT_SYMBOL(copy_from_user_tt); EXPORT_SYMBOL(copy_to_user_tt); #endif #ifdef CONFIG_MODE_SKAS -EXPORT_SYMBOL(strnlen_user_skas); EXPORT_SYMBOL(strncpy_from_user_skas); EXPORT_SYMBOL(copy_to_user_skas); EXPORT_SYMBOL(copy_from_user_skas); diff --git a/trunk/arch/um/kernel/mem.c b/trunk/arch/um/kernel/mem.c index c95855ba6ab5..93121c6d26e5 100644 --- a/trunk/arch/um/kernel/mem.c +++ b/trunk/arch/um/kernel/mem.c @@ -226,8 +226,7 @@ void paging_init(void) for(i = 0; i < ARRAY_SIZE(zones_size); i++) zones_size[i] = 0; - zones_size[ZONE_NORMAL] = (end_iomem >> PAGE_SHIFT) - - (uml_physmem >> PAGE_SHIFT); + zones_size[ZONE_DMA] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT); #ifdef CONFIG_HIGHMEM zones_size[ZONE_HIGHMEM] = highmem >> PAGE_SHIFT; #endif diff --git a/trunk/arch/um/kernel/process.c b/trunk/arch/um/kernel/process_kern.c similarity index 96% rename from trunk/arch/um/kernel/process.c rename to trunk/arch/um/kernel/process_kern.c index fe6c64abda5b..537895d68ad1 100644 --- a/trunk/arch/um/kernel/process.c +++ b/trunk/arch/um/kernel/process_kern.c @@ -1,9 +1,10 @@ -/* +/* * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) * Copyright 2003 PathScale, Inc. * Licensed under the GPL */ +#include "linux/config.h" #include "linux/kernel.h" #include "linux/sched.h" #include "linux/interrupt.h" @@ -112,11 +113,11 @@ void set_current(void *t) void *_switch_to(void *prev, void *next, void *last) { - struct task_struct *from = prev; - struct task_struct *to= next; + struct task_struct *from = prev; + struct task_struct *to= next; - to->thread.prev_sched = from; - set_current(to); + to->thread.prev_sched = from; + set_current(to); do { current->thread.saved_task = NULL ; @@ -127,7 +128,7 @@ void *_switch_to(void *prev, void *next, void *last) prev= current; } while(current->thread.saved_task); - return(current->thread.prev_sched); + return(current->thread.prev_sched); } @@ -141,19 +142,19 @@ void release_thread(struct task_struct *task) { CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task)); } - + void exit_thread(void) { unprotect_stack((unsigned long) current_thread); } - + void *get_current(void) { return(current); } int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, - unsigned long stack_top, struct task_struct * p, + unsigned long stack_top, struct task_struct * p, struct pt_regs *regs) { int ret; @@ -182,11 +183,11 @@ void initial_thread_cb(void (*proc)(void *), void *arg) int save_kmalloc_ok = kmalloc_ok; kmalloc_ok = 0; - CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc, + CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc, arg); kmalloc_ok = save_kmalloc_ok; } - + unsigned long stack_sp(unsigned long page) { return(page + PAGE_SIZE - sizeof(void *)); @@ -210,7 +211,7 @@ void default_idle(void) */ if(need_resched()) schedule(); - + idle_sleep(10); } } @@ -225,7 +226,7 @@ int page_size(void) return(PAGE_SIZE); } -void *um_virt_to_phys(struct task_struct *task, unsigned long addr, +void *um_virt_to_phys(struct task_struct *task, unsigned long addr, pte_t *pte_out) { pgd_t *pgd; @@ -234,7 +235,7 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr, pte_t *pte; pte_t ptent; - if(task->mm == NULL) + if(task->mm == NULL) return(ERR_PTR(-EINVAL)); pgd = pgd_offset(task->mm, addr); if(!pgd_present(*pgd)) @@ -245,7 +246,7 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr, return(ERR_PTR(-EINVAL)); pmd = pmd_offset(pud, addr); - if(!pmd_present(*pmd)) + if(!pmd_present(*pmd)) return(ERR_PTR(-EINVAL)); pte = pte_offset_kernel(pmd, addr); @@ -270,7 +271,7 @@ char *current_cmd(void) void force_sigbus(void) { - printk(KERN_ERR "Killing pid %d because of a lack of memory\n", + printk(KERN_ERR "Killing pid %d because of a lack of memory\n", current->pid); lock_kernel(); sigaddset(¤t->pending.signal, SIGBUS); diff --git a/trunk/arch/um/kernel/skas/Makefile b/trunk/arch/um/kernel/skas/Makefile index 3e3fa7e7e3cf..ea3a8e409a6e 100644 --- a/trunk/arch/um/kernel/skas/Makefile +++ b/trunk/arch/um/kernel/skas/Makefile @@ -3,7 +3,8 @@ # Licensed under the GPL # -obj-y := clone.o exec.o mem.o mmu.o process.o syscall.o tlb.o uaccess.o +obj-y := clone.o exec_kern.o mem.o mmu.o process_kern.o \ + syscall.o tlb.o uaccess.o # clone.o is in the stub, so it can't be built with profiling # GCC hardened also auto-enables -fpic, but we need %ebx so it can't work -> diff --git a/trunk/arch/um/kernel/skas/exec.c b/trunk/arch/um/kernel/skas/exec.c deleted file mode 100644 index 54b795951372..000000000000 --- a/trunk/arch/um/kernel/skas/exec.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include "linux/kernel.h" -#include "asm/current.h" -#include "asm/page.h" -#include "asm/signal.h" -#include "asm/ptrace.h" -#include "asm/uaccess.h" -#include "asm/mmu_context.h" -#include "tlb.h" -#include "skas.h" -#include "um_mmu.h" -#include "os.h" - -void flush_thread_skas(void) -{ - force_flush_all(); - switch_mm_skas(¤t->mm->context.skas.id); -} - -void start_thread_skas(struct pt_regs *regs, unsigned long eip, - unsigned long esp) -{ - set_fs(USER_DS); - PT_REGS_IP(regs) = eip; - PT_REGS_SP(regs) = esp; -} diff --git a/trunk/arch/um/kernel/skas/exec_kern.c b/trunk/arch/um/kernel/skas/exec_kern.c new file mode 100644 index 000000000000..77ed7bbab219 --- /dev/null +++ b/trunk/arch/um/kernel/skas/exec_kern.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include "linux/kernel.h" +#include "asm/current.h" +#include "asm/page.h" +#include "asm/signal.h" +#include "asm/ptrace.h" +#include "asm/uaccess.h" +#include "asm/mmu_context.h" +#include "tlb.h" +#include "skas.h" +#include "um_mmu.h" +#include "os.h" + +void flush_thread_skas(void) +{ + force_flush_all(); + switch_mm_skas(¤t->mm->context.skas.id); +} + +void start_thread_skas(struct pt_regs *regs, unsigned long eip, + unsigned long esp) +{ + set_fs(USER_DS); + PT_REGS_IP(regs) = eip; + PT_REGS_SP(regs) = esp; +} + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/kernel/skas/mmu.c b/trunk/arch/um/kernel/skas/mmu.c index 4cd2ff546ef6..79c22707a637 100644 --- a/trunk/arch/um/kernel/skas/mmu.c +++ b/trunk/arch/um/kernel/skas/mmu.c @@ -61,10 +61,8 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, #endif *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); - /* This is wrong for the code page, but it doesn't matter since the - * stub is mapped by hand with the correct permissions. - */ - *pte = pte_mkwrite(*pte); + *pte = pte_mkexec(*pte); + *pte = pte_wrprotect(*pte); return(0); out_pmd: diff --git a/trunk/arch/um/kernel/skas/process.c b/trunk/arch/um/kernel/skas/process_kern.c similarity index 85% rename from trunk/arch/um/kernel/skas/process.c rename to trunk/arch/um/kernel/skas/process_kern.c index ae4fa71d3b8b..55caeec8b257 100644 --- a/trunk/arch/um/kernel/skas/process.c +++ b/trunk/arch/um/kernel/skas/process_kern.c @@ -33,7 +33,7 @@ void switch_to_skas(void *prev, void *next) switch_timers(0); switch_threads(&from->thread.mode.skas.switch_buf, - &to->thread.mode.skas.switch_buf); + to->thread.mode.skas.switch_buf); arch_switch_to_skas(current->thread.prev_sched, current); @@ -43,21 +43,21 @@ void switch_to_skas(void *prev, void *next) extern void schedule_tail(struct task_struct *prev); -/* This is called magically, by its address being stuffed in a jmp_buf - * and being longjmp-d to. - */ -void new_thread_handler(void) +void new_thread_handler(int sig) { int (*fn)(void *), n; void *arg; + fn = current->thread.request.u.thread.proc; + arg = current->thread.request.u.thread.arg; + os_usr1_signal(1); + thread_wait(¤t->thread.mode.skas.switch_buf, + current->thread.mode.skas.fork_buf); + if(current->thread.prev_sched != NULL) schedule_tail(current->thread.prev_sched); current->thread.prev_sched = NULL; - fn = current->thread.request.u.thread.proc; - arg = current->thread.request.u.thread.arg; - /* The return value is 1 if the kernel thread execs a process, * 0 if it just exits */ @@ -70,13 +70,22 @@ void new_thread_handler(void) else do_exit(0); } +void new_thread_proc(void *stack, void (*handler)(int sig)) +{ + init_new_thread_stack(stack, handler); + os_usr1_process(os_getpid()); +} + void release_thread_skas(struct task_struct *task) { } -/* Called magically, see new_thread_handler above */ -void fork_handler(void) +void fork_handler(int sig) { + os_usr1_signal(1); + thread_wait(¤t->thread.mode.skas.switch_buf, + current->thread.mode.skas.fork_buf); + force_flush_all(); if(current->thread.prev_sched == NULL) panic("blech"); @@ -100,7 +109,7 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, unsigned long stack_top, struct task_struct * p, struct pt_regs *regs) { - void (*handler)(void); + void (*handler)(int); if(current->thread.forking){ memcpy(&p->thread.regs.regs.skas, ®s->regs.skas, @@ -114,12 +123,12 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, } else { init_thread_registers(&p->thread.regs.regs); - p->thread.request.u.thread = current->thread.request.u.thread; + p->thread.request.u.thread = current->thread.request.u.thread; handler = new_thread_handler; } new_thread(task_stack_page(p), &p->thread.mode.skas.switch_buf, - handler); + &p->thread.mode.skas.fork_buf, handler); return(0); } @@ -155,7 +164,7 @@ static int start_kernel_proc(void *unused) cpu_tasks[0].pid = pid; cpu_tasks[0].task = current; #ifdef CONFIG_SMP - cpu_online_map = cpumask_of_cpu(0); + cpu_online_map = cpumask_of_cpu(0); #endif start_kernel(); return(0); @@ -173,7 +182,8 @@ int start_uml_skas(void) init_task.thread.request.u.thread.proc = start_kernel_proc; init_task.thread.request.u.thread.arg = NULL; return(start_idle_thread(task_stack_page(&init_task), - &init_task.thread.mode.skas.switch_buf)); + &init_task.thread.mode.skas.switch_buf, + &init_task.thread.mode.skas.fork_buf)); } int external_pid_skas(struct task_struct *task) diff --git a/trunk/arch/um/kernel/syscall.c b/trunk/arch/um/kernel/syscall.c index f5ed8624648b..48cf88dd02d4 100644 --- a/trunk/arch/um/kernel/syscall.c +++ b/trunk/arch/um/kernel/syscall.c @@ -110,7 +110,7 @@ long sys_uname(struct old_utsname __user * name) if (!name) return -EFAULT; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err = copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); return err?-EFAULT:0; } @@ -126,21 +126,21 @@ long sys_olduname(struct oldold_utsname __user * name) down_read(&uts_sem); - error = __copy_to_user(&name->sysname, &utsname()->sysname, + error = __copy_to_user(&name->sysname,&system_utsname.sysname, __OLD_UTS_LEN); - error |= __put_user(0, name->sysname + __OLD_UTS_LEN); - error |= __copy_to_user(&name->nodename, &utsname()->nodename, + error |= __put_user(0,name->sysname+__OLD_UTS_LEN); + error |= __copy_to_user(&name->nodename,&system_utsname.nodename, __OLD_UTS_LEN); - error |= __put_user(0, name->nodename + __OLD_UTS_LEN); - error |= __copy_to_user(&name->release, &utsname()->release, + error |= __put_user(0,name->nodename+__OLD_UTS_LEN); + error |= __copy_to_user(&name->release,&system_utsname.release, __OLD_UTS_LEN); - error |= __put_user(0, name->release + __OLD_UTS_LEN); - error |= __copy_to_user(&name->version, &utsname()->version, + error |= __put_user(0,name->release+__OLD_UTS_LEN); + error |= __copy_to_user(&name->version,&system_utsname.version, __OLD_UTS_LEN); - error |= __put_user(0, name->version + __OLD_UTS_LEN); - error |= __copy_to_user(&name->machine, &utsname()->machine, + error |= __put_user(0,name->version+__OLD_UTS_LEN); + error |= __copy_to_user(&name->machine,&system_utsname.machine, __OLD_UTS_LEN); - error |= __put_user(0, name->machine + __OLD_UTS_LEN); + error |= __put_user(0,name->machine+__OLD_UTS_LEN); up_read(&uts_sem); @@ -164,16 +164,3 @@ int next_syscall_index(int limit) spin_unlock(&syscall_lock); return(ret); } - -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - mm_segment_t fs; - int ret; - - fs = get_fs(); - set_fs(KERNEL_DS); - ret = um_execve(filename, argv, envp); - set_fs(fs); - - return ret; -} diff --git a/trunk/arch/um/kernel/time.c b/trunk/arch/um/kernel/time.c index a92965f8f9cd..2454bbd9555d 100644 --- a/trunk/arch/um/kernel/time.c +++ b/trunk/arch/um/kernel/time.c @@ -93,9 +93,9 @@ irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs) write_seqlock_irqsave(&xtime_lock, flags); - do_timer(1); + do_timer(regs); - nsecs = get_time(); + nsecs = get_time() + local_offset; xtime.tv_sec = nsecs / NSEC_PER_SEC; xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC; diff --git a/trunk/arch/um/kernel/trap.c b/trunk/arch/um/kernel/trap.c index c7b195c7e51f..e5eeaf2b6af1 100644 --- a/trunk/arch/um/kernel/trap.c +++ b/trunk/arch/um/kernel/trap.c @@ -120,7 +120,7 @@ int handle_page_fault(unsigned long address, unsigned long ip, * us unable to handle the page fault gracefully. */ out_of_memory: - if (is_init(current)) { + if (current->pid == 1) { up_read(&mm->mmap_sem); yield(); down_read(&mm->mmap_sem); @@ -140,6 +140,14 @@ void segv_handler(int sig, union uml_pt_regs *regs) segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs); } +struct kern_handlers handlinfo_kern = { + .relay_signal = relay_signal, + .winch = winch, + .bus_handler = relay_signal, + .page_fault = segv_handler, + .sigio_handler = sigio_handler, + .timer_handler = timer_handler +}; /* * We give a *copy* of the faultinfo in the regs to segv. * This must be done, since nesting SEGVs could overwrite @@ -245,15 +253,6 @@ void winch(int sig, union uml_pt_regs *regs) do_IRQ(WINCH_IRQ, regs); } -const struct kern_handlers handlinfo_kern = { - .relay_signal = relay_signal, - .winch = winch, - .bus_handler = bus_handler, - .page_fault = segv_handler, - .sigio_handler = sigio_handler, - .timer_handler = timer_handler -}; - void trap_init(void) { } diff --git a/trunk/arch/um/kernel/um_arch.c b/trunk/arch/um/kernel/um_arch.c index 97d88e7902f7..7896cf98232d 100644 --- a/trunk/arch/um/kernel/um_arch.c +++ b/trunk/arch/um/kernel/um_arch.c @@ -106,7 +106,7 @@ static void c_stop(struct seq_file *m, void *v) { } -const struct seq_operations cpuinfo_op = { +struct seq_operations cpuinfo_op = { .start = c_start, .next = c_next, .stop = c_stop, @@ -167,7 +167,7 @@ static char *usage_string = static int __init uml_version_setup(char *line, int *add) { - printf("%s\n", init_utsname()->release); + printf("%s\n", system_utsname.release); exit(0); return 0; @@ -278,7 +278,7 @@ static int __init Usage(char *line, int *add) { const char **p; - printf(usage_string, init_utsname()->release); + printf(usage_string, system_utsname.release); p = &__uml_help_start; while (p < &__uml_help_end) { printf("%s", *p); @@ -403,7 +403,7 @@ int linux_main(int argc, char **argv) /* Reserve up to 4M after the current brk */ uml_reserved = ROUND_4M(brk_start) + (1 << 22); - setup_machinename(init_utsname()->machine); + setup_machinename(system_utsname.machine); #ifdef CONFIG_CMDLINE_ON_HOST argv1_begin = argv[1]; diff --git a/trunk/arch/um/os-Linux/Makefile b/trunk/arch/um/os-Linux/Makefile index b4183929b32c..f4bfc4c7ccac 100644 --- a/trunk/arch/um/os-Linux/Makefile +++ b/trunk/arch/um/os-Linux/Makefile @@ -4,19 +4,15 @@ # obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \ - signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \ + signal.o start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o tls.o \ user_syms.o util.o drivers/ sys-$(SUBARCH)/ obj-$(CONFIG_MODE_SKAS) += skas/ - -obj-$(CONFIG_MODE_TT) += tt.o -user-objs-$(CONFIG_MODE_TT) += tt.o - obj-$(CONFIG_TTY_LOG) += tty_log.o user-objs-$(CONFIG_TTY_LOG) += tty_log.o USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \ - process.o sigio.o signal.o start_up.o time.o trap.o tty.o tls.o \ + process.o sigio.o signal.o start_up.o time.o trap.o tt.o tty.o tls.o \ uaccess.o umid.o util.o CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) diff --git a/trunk/arch/um/os-Linux/drivers/etap.h b/trunk/arch/um/os-Linux/drivers/etap.h index 57ecdaf2f67e..b84f6c4740f7 100644 --- a/trunk/arch/um/os-Linux/drivers/etap.h +++ b/trunk/arch/um/os-Linux/drivers/etap.h @@ -13,7 +13,7 @@ struct ethertap_data { void *dev; }; -extern const struct net_user_info ethertap_user_info; +extern struct net_user_info ethertap_user_info; /* * Overrides for Emacs so that we follow Linus's tabbing style. diff --git a/trunk/arch/um/os-Linux/drivers/ethertap_kern.c b/trunk/arch/um/os-Linux/drivers/ethertap_kern.c index 16385e2ada85..768606bec233 100644 --- a/trunk/arch/um/os-Linux/drivers/ethertap_kern.c +++ b/trunk/arch/um/os-Linux/drivers/ethertap_kern.c @@ -65,7 +65,7 @@ static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) return(net_send(fd, (*skb)->data, (*skb)->len)); } -const struct net_kern_info ethertap_kern_info = { +struct net_kern_info ethertap_kern_info = { .init = etap_init, .protocol = eth_protocol, .read = etap_read, diff --git a/trunk/arch/um/os-Linux/drivers/ethertap_user.c b/trunk/arch/um/os-Linux/drivers/ethertap_user.c index f559bdf746e6..8f49507e64ef 100644 --- a/trunk/arch/um/os-Linux/drivers/ethertap_user.c +++ b/trunk/arch/um/os-Linux/drivers/ethertap_user.c @@ -216,7 +216,7 @@ static void etap_del_addr(unsigned char *addr, unsigned char *netmask, etap_close_addr(addr, netmask, &pri->control_fd); } -const struct net_user_info ethertap_user_info = { +struct net_user_info ethertap_user_info = { .init = etap_user_init, .open = etap_open, .close = etap_close, diff --git a/trunk/arch/um/os-Linux/drivers/tuntap.h b/trunk/arch/um/os-Linux/drivers/tuntap.h index d3e8d3af6245..25d4a2868814 100644 --- a/trunk/arch/um/os-Linux/drivers/tuntap.h +++ b/trunk/arch/um/os-Linux/drivers/tuntap.h @@ -16,7 +16,7 @@ struct tuntap_data { void *dev; }; -extern const struct net_user_info tuntap_user_info; +extern struct net_user_info tuntap_user_info; #endif diff --git a/trunk/arch/um/os-Linux/drivers/tuntap_kern.c b/trunk/arch/um/os-Linux/drivers/tuntap_kern.c index 0edbac63c527..190009a6f89c 100644 --- a/trunk/arch/um/os-Linux/drivers/tuntap_kern.c +++ b/trunk/arch/um/os-Linux/drivers/tuntap_kern.c @@ -53,7 +53,7 @@ static int tuntap_write(int fd, struct sk_buff **skb, return(net_write(fd, (*skb)->data, (*skb)->len)); } -const struct net_kern_info tuntap_kern_info = { +struct net_kern_info tuntap_kern_info = { .init = tuntap_init, .protocol = eth_protocol, .read = tuntap_read, diff --git a/trunk/arch/um/os-Linux/drivers/tuntap_user.c b/trunk/arch/um/os-Linux/drivers/tuntap_user.c index e846b23f7558..87c3aa0252db 100644 --- a/trunk/arch/um/os-Linux/drivers/tuntap_user.c +++ b/trunk/arch/um/os-Linux/drivers/tuntap_user.c @@ -205,7 +205,7 @@ static int tuntap_set_mtu(int mtu, void *data) return(mtu); } -const struct net_user_info tuntap_user_info = { +struct net_user_info tuntap_user_info = { .init = tuntap_user_init, .open = tuntap_open, .close = tuntap_close, diff --git a/trunk/arch/um/os-Linux/mem.c b/trunk/arch/um/os-Linux/mem.c index 4203681e508d..b170b4704dc4 100644 --- a/trunk/arch/um/os-Linux/mem.c +++ b/trunk/arch/um/os-Linux/mem.c @@ -132,9 +132,6 @@ static void which_tmpdir(void) else if(found < 0) printf("read returned errno %d\n", -found); -out: - close(fd); - return; found: @@ -144,12 +141,11 @@ static void which_tmpdir(void) if(strncmp(buf, "tmpfs", strlen("tmpfs"))){ printf("not tmpfs\n"); - goto out; + return; } printf("OK\n"); default_tmpdir = "/dev/shm"; - goto out; } /* diff --git a/trunk/arch/um/os-Linux/process.c b/trunk/arch/um/os-Linux/process.c index 51f0893640a6..ff203625a4bd 100644 --- a/trunk/arch/um/os-Linux/process.c +++ b/trunk/arch/um/os-Linux/process.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "ptrace_user.h" #include "os.h" #include "user.h" @@ -141,9 +140,11 @@ void os_usr1_process(int pid) * syscalls, and also breaks with clone(), which does not unshare the TLS. */ +inline _syscall0(pid_t, getpid) + int os_getpid(void) { - return(syscall(__NR_getpid)); + return(getpid()); } int os_getpgrp(void) diff --git a/trunk/arch/um/os-Linux/skas/process.c b/trunk/arch/um/os-Linux/skas/process.c index cb9ab54146cc..42e3d1ed802c 100644 --- a/trunk/arch/um/os-Linux/skas/process.c +++ b/trunk/arch/um/os-Linux/skas/process.c @@ -444,22 +444,56 @@ void map_stub_pages(int fd, unsigned long code, } } -void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)) +void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, + void (*handler)(int)) { - (*buf)[0].JB_IP = (unsigned long) handler; - (*buf)[0].JB_SP = (unsigned long) stack + - (PAGE_SIZE << UML_CONFIG_KERNEL_STACK_ORDER) - sizeof(void *); + unsigned long flags; + jmp_buf switch_buf, fork_buf; + + *switch_buf_ptr = &switch_buf; + *fork_buf_ptr = &fork_buf; + + /* Somewhat subtle - siglongjmp restores the signal mask before doing + * the longjmp. This means that when jumping from one stack to another + * when the target stack has interrupts enabled, an interrupt may occur + * on the source stack. This is bad when starting up a process because + * it's not supposed to get timer ticks until it has been scheduled. + * So, we disable interrupts around the sigsetjmp to ensure that + * they can't happen until we get back here where they are safe. + */ + flags = get_signals(); + block_signals(); + if(UML_SETJMP(&fork_buf) == 0) + new_thread_proc(stack, handler); + + remove_sigstack(); + + set_signals(flags); } #define INIT_JMP_NEW_THREAD 0 -#define INIT_JMP_CALLBACK 1 -#define INIT_JMP_HALT 2 -#define INIT_JMP_REBOOT 3 +#define INIT_JMP_REMOVE_SIGSTACK 1 +#define INIT_JMP_CALLBACK 2 +#define INIT_JMP_HALT 3 +#define INIT_JMP_REBOOT 4 + +void thread_wait(void *sw, void *fb) +{ + jmp_buf buf, **switch_buf = sw, *fork_buf; + + *switch_buf = &buf; + fork_buf = fb; + if(UML_SETJMP(&buf) == 0) + UML_LONGJMP(fork_buf, INIT_JMP_REMOVE_SIGSTACK); +} -void switch_threads(jmp_buf *me, jmp_buf *you) +void switch_threads(void *me, void *next) { - if(UML_SETJMP(me) == 0) - UML_LONGJMP(you, 1); + jmp_buf my_buf, **me_ptr = me, *next_buf = next; + + *me_ptr = &my_buf; + if(UML_SETJMP(&my_buf) == 0) + UML_LONGJMP(next_buf, 1); } static jmp_buf initial_jmpbuf; @@ -469,21 +503,23 @@ static void (*cb_proc)(void *arg); static void *cb_arg; static jmp_buf *cb_back; -int start_idle_thread(void *stack, jmp_buf *switch_buf) +int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) { + jmp_buf **switch_buf = switch_buf_ptr; int n; set_handler(SIGWINCH, (__sighandler_t) sig_handler, SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, SIGVTALRM, -1); + *fork_buf_ptr = &initial_jmpbuf; n = UML_SETJMP(&initial_jmpbuf); switch(n){ case INIT_JMP_NEW_THREAD: - (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler; - (*switch_buf)[0].JB_SP = (unsigned long) stack + - (PAGE_SIZE << UML_CONFIG_KERNEL_STACK_ORDER) - - sizeof(void *); + new_thread_proc((void *) stack, new_thread_handler); + break; + case INIT_JMP_REMOVE_SIGSTACK: + remove_sigstack(); break; case INIT_JMP_CALLBACK: (*cb_proc)(cb_arg); @@ -498,7 +534,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) default: panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); } - UML_LONGJMP(switch_buf, 1); + UML_LONGJMP(*switch_buf, 1); } void initial_thread_cb_skas(void (*proc)(void *), void *arg) diff --git a/trunk/arch/um/os-Linux/sys-i386/tls.c b/trunk/arch/um/os-Linux/sys-i386/tls.c index 6e945ab45843..120abbe4e3ce 100644 --- a/trunk/arch/um/os-Linux/sys-i386/tls.c +++ b/trunk/arch/um/os-Linux/sys-i386/tls.c @@ -1,9 +1,10 @@ #include #include -#include #include "sysdep/tls.h" #include "user_util.h" +static _syscall1(int, get_thread_area, user_desc_t *, u_info); + /* Checks whether host supports TLS, and sets *tls_min according to the value * valid on the host. * i386 host have it == 6; x86_64 host have it == 12, for i386 emulation. */ @@ -16,7 +17,7 @@ void check_host_supports_tls(int *supports_tls, int *tls_min) { user_desc_t info; info.entry_number = val[i]; - if (syscall(__NR_get_thread_area, &info) == 0) { + if (get_thread_area(&info) == 0) { *tls_min = val[i]; *supports_tls = 1; return; diff --git a/trunk/arch/um/os-Linux/tls.c b/trunk/arch/um/os-Linux/tls.c index a2de2580b8af..9cb09a45546b 100644 --- a/trunk/arch/um/os-Linux/tls.c +++ b/trunk/arch/um/os-Linux/tls.c @@ -1,6 +1,5 @@ #include #include -#include #include #include "sysdep/tls.h" #include "uml-config.h" @@ -49,11 +48,14 @@ int os_get_thread_area(user_desc_t *info, int pid) #ifdef UML_CONFIG_MODE_TT #include "linux/unistd.h" +static _syscall1(int, get_thread_area, user_desc_t *, u_info); +static _syscall1(int, set_thread_area, user_desc_t *, u_info); + int do_set_thread_area_tt(user_desc_t *info) { int ret; - ret = syscall(__NR_set_thread_area,info); + ret = set_thread_area(info); if (ret < 0) { ret = -errno; } @@ -64,7 +66,7 @@ int do_get_thread_area_tt(user_desc_t *info) { int ret; - ret = syscall(__NR_get_thread_area,info); + ret = get_thread_area(info); if (ret < 0) { ret = -errno; } diff --git a/trunk/arch/um/sys-i386/Makefile b/trunk/arch/um/sys-i386/Makefile index 0e32adf03be1..59cc70275754 100644 --- a/trunk/arch/um/sys-i386/Makefile +++ b/trunk/arch/um/sys-i386/Makefile @@ -4,7 +4,7 @@ obj-y = bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o -subarch-obj-y = lib/bitops.o lib/semaphore.o +subarch-obj-y = lib/bitops.o kernel/semaphore.o subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o subarch-obj-$(CONFIG_MODULES) += kernel/module.o diff --git a/trunk/arch/um/sys-i386/unmap.c b/trunk/arch/um/sys-i386/unmap.c index 8e55cd5d3d07..1b0ad0e4adcd 100644 --- a/trunk/arch/um/sys-i386/unmap.c +++ b/trunk/arch/um/sys-i386/unmap.c @@ -5,17 +5,20 @@ #include #include -#include +static int errno; + +static inline _syscall2(int,munmap,void *,start,size_t,len) +static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) int switcheroo(int fd, int prot, void *from, void *to, int size) { - if (syscall(__NR_munmap, to, size) < 0){ + if(munmap(to, size) < 0){ return(-1); } - if (syscall(__NR_mmap2, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ + if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ return(-1); } - if (syscall(__NR_munmap, from, size) < 0){ + if(munmap(from, size) < 0){ return(-1); } return(0); diff --git a/trunk/arch/um/sys-x86_64/syscalls.c b/trunk/arch/um/sys-x86_64/syscalls.c index 73ce4463f70c..6fce9f45dfdc 100644 --- a/trunk/arch/um/sys-x86_64/syscalls.c +++ b/trunk/arch/um/sys-x86_64/syscalls.c @@ -21,7 +21,7 @@ asmlinkage long sys_uname64(struct new_utsname __user * name) { int err; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err = copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); if (personality(current->personality) == PER_LINUX32) err |= copy_to_user(&name->machine, "i686", 5); diff --git a/trunk/arch/um/sys-x86_64/sysrq.c b/trunk/arch/um/sys-x86_64/sysrq.c index ce3e07fcf283..d0a25af19a5b 100644 --- a/trunk/arch/um/sys-x86_64/sysrq.c +++ b/trunk/arch/um/sys-x86_64/sysrq.c @@ -16,7 +16,7 @@ void __show_regs(struct pt_regs * regs) printk("\n"); print_modules(); printk("Pid: %d, comm: %.20s %s %s\n", - current->pid, current->comm, print_tainted(), init_utsname()->release); + current->pid, current->comm, print_tainted(), system_utsname.release); printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff, PT_REGS_RIP(regs)); printk("\nRSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs), diff --git a/trunk/arch/um/sys-x86_64/unmap.c b/trunk/arch/um/sys-x86_64/unmap.c index 57c9286a701b..f4a4bffd8a18 100644 --- a/trunk/arch/um/sys-x86_64/unmap.c +++ b/trunk/arch/um/sys-x86_64/unmap.c @@ -5,17 +5,20 @@ #include #include -#include +static int errno; + +static inline _syscall2(int,munmap,void *,start,size_t,len) +static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) int switcheroo(int fd, int prot, void *from, void *to, int size) { - if (syscall(__NR_munmap, to, size) < 0){ + if(munmap(to, size) < 0){ return(-1); } - if (syscall(__NR_mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ + if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ return(-1); } - if (syscall(__NR_munmap, from, size) < 0){ + if(munmap(from, size) < 0){ return(-1); } return(0); diff --git a/trunk/arch/v850/kernel/memcons.c b/trunk/arch/v850/kernel/memcons.c index 92f514fdcc79..491614c435cd 100644 --- a/trunk/arch/v850/kernel/memcons.c +++ b/trunk/arch/v850/kernel/memcons.c @@ -30,7 +30,7 @@ static DEFINE_SPINLOCK(memcons_lock); static size_t write (const char *buf, size_t len) { - unsigned long flags; + int flags; char *point; spin_lock_irqsave (memcons_lock, flags); @@ -104,7 +104,7 @@ int memcons_tty_chars_in_buffer (struct tty_struct *tty) return 0; } -static const struct tty_operations ops = { +static struct tty_operations ops = { .open = memcons_tty_open, .write = memcons_tty_write, .write_room = memcons_tty_write_room, diff --git a/trunk/arch/v850/kernel/rte_cb_leds.c b/trunk/arch/v850/kernel/rte_cb_leds.c index 996bd4f33ecb..f654088b2760 100644 --- a/trunk/arch/v850/kernel/rte_cb_leds.c +++ b/trunk/arch/v850/kernel/rte_cb_leds.c @@ -42,7 +42,7 @@ do { \ len = LED_NUM_DIGITS - pos; \ \ if (len > 0) { \ - unsigned long _flags; \ + int _flags; \ const char *_end = buf + len; \ img_decl = &leds_image[pos]; \ \ diff --git a/trunk/arch/v850/kernel/rte_mb_a_pci.c b/trunk/arch/v850/kernel/rte_mb_a_pci.c index 35213fa9f7d8..f36b778f1432 100644 --- a/trunk/arch/v850/kernel/rte_mb_a_pci.c +++ b/trunk/arch/v850/kernel/rte_mb_a_pci.c @@ -365,7 +365,7 @@ static DEFINE_SPINLOCK(mb_sram_lock); static void *alloc_mb_sram (size_t size) { struct mb_sram_free_area *prev, *fa; - unsigned long flags; + int flags; void *mem = 0; spin_lock_irqsave (mb_sram_lock, flags); @@ -406,7 +406,7 @@ static void *alloc_mb_sram (size_t size) static void free_mb_sram (void *mem, size_t size) { struct mb_sram_free_area *prev, *fa, *new_fa; - unsigned long flags; + int flags; void *end = mem + size; spin_lock_irqsave (mb_sram_lock, flags); @@ -517,7 +517,7 @@ static DEFINE_SPINLOCK(dma_mappings_lock); static struct dma_mapping *new_dma_mapping (size_t size) { - unsigned long flags; + int flags; struct dma_mapping *mapping; void *mb_sram_block = alloc_mb_sram (size); @@ -575,7 +575,7 @@ static struct dma_mapping *new_dma_mapping (size_t size) static struct dma_mapping *find_dma_mapping (void *mb_sram_addr) { - unsigned long flags; + int flags; struct dma_mapping *mapping; spin_lock_irqsave (dma_mappings_lock, flags); @@ -592,7 +592,7 @@ static struct dma_mapping *find_dma_mapping (void *mb_sram_addr) static struct dma_mapping *deactivate_dma_mapping (void *mb_sram_addr) { - unsigned long flags; + int flags; struct dma_mapping *mapping, *prev; spin_lock_irqsave (dma_mappings_lock, flags); @@ -622,7 +622,7 @@ static struct dma_mapping *deactivate_dma_mapping (void *mb_sram_addr) static inline void free_dma_mapping (struct dma_mapping *mapping) { - unsigned long flags; + int flags; free_mb_sram (mapping->mb_sram_addr, mapping->size); diff --git a/trunk/arch/v850/kernel/simcons.c b/trunk/arch/v850/kernel/simcons.c index 9973596ae304..3975aa02cef8 100644 --- a/trunk/arch/v850/kernel/simcons.c +++ b/trunk/arch/v850/kernel/simcons.c @@ -77,7 +77,7 @@ int simcons_tty_chars_in_buffer (struct tty_struct *tty) return 0; } -static const struct tty_operations ops = { +static struct tty_operations ops = { .open = simcons_tty_open, .write = simcons_tty_write, .write_room = simcons_tty_write_room, diff --git a/trunk/arch/v850/kernel/syscalls.c b/trunk/arch/v850/kernel/syscalls.c index d2b1fb19d243..2ec0700fc46b 100644 --- a/trunk/arch/v850/kernel/syscalls.c +++ b/trunk/arch/v850/kernel/syscalls.c @@ -33,7 +33,6 @@ #include #include #include -#include /* * sys_ipc() is the de-multiplexer for the SysV IPC calls.. @@ -195,22 +194,3 @@ unsigned long sys_mmap (unsigned long addr, size_t len, out: return err; } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register char *__a __asm__ ("r6") = filename; - register void *__b __asm__ ("r7") = argv; - register void *__c __asm__ ("r8") = envp; - register unsigned long __syscall __asm__ ("r12") = __NR_execve; - register unsigned long __ret __asm__ ("r10"); - __asm__ __volatile__ ("trap 0" - : "=r" (__ret), "=r" (__syscall) - : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c) - : "r1", "r5", "r11", "r13", "r14", - "r15", "r16", "r17", "r18", "r19"); - return __ret; -} diff --git a/trunk/arch/v850/kernel/time.c b/trunk/arch/v850/kernel/time.c index f4d1a4d3cdc2..a0b46695f186 100644 --- a/trunk/arch/v850/kernel/time.c +++ b/trunk/arch/v850/kernel/time.c @@ -51,7 +51,7 @@ static irqreturn_t timer_interrupt (int irq, void *dummy, struct pt_regs *regs) if (mach_tick) mach_tick (); - do_timer (1); + do_timer (regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig index 0a5d8e659aa4..581ce9af0ec8 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -85,9 +85,6 @@ config ARCH_MAY_HAVE_PC_FDC bool default y -config ARCH_POPULATES_NODE_MAP - def_bool y - config DMI bool default y @@ -112,7 +109,6 @@ config X86_PC config X86_VSMP bool "Support for ScaleMP vSMP" - depends on PCI help Support for ScaleMP vSMP systems. Say 'Y' here if this kernel is supposed to run on these EM64T-based machines. Only choose this option @@ -171,7 +167,6 @@ config X86_GOOD_APIC config MICROCODE tristate "/dev/cpu/microcode - Intel CPU microcode support" - select FW_LOADER ---help--- If you say Y here the 'File systems' section, you will be able to update the microcode on Intel processors. You will @@ -187,11 +182,6 @@ config MICROCODE If you use modprobe or kmod you may also want to add the line 'alias char-major-10-184 microcode' to your /etc/modules.conf file. -config MICROCODE_OLD_INTERFACE - bool - depends on MICROCODE - default y - config X86_MSR tristate "/dev/cpu/*/msr - Model-specific register support" help @@ -305,7 +295,7 @@ config NUMA config K8_NUMA bool "Old style AMD Opteron NUMA detection" - depends on NUMA && PCI + depends on NUMA default y help Enable K8 NUMA node topology detection. You should say Y here if @@ -367,10 +357,6 @@ config ARCH_FLATMEM_ENABLE source "mm/Kconfig" -config MEMORY_HOTPLUG_RESERVE - def_bool y - depends on (MEMORY_HOTPLUG && DISCONTIGMEM) - config HAVE_ARCH_EARLY_PFN_TO_NID def_bool y depends on NUMA @@ -439,6 +425,7 @@ config IOMMU config CALGARY_IOMMU bool "IBM Calgary IOMMU support" + default y select SWIOTLB depends on PCI && EXPERIMENTAL help @@ -485,7 +472,8 @@ config X86_MCE_AMD the DRAM Error Threshold. config KEXEC - bool "kexec system call" + bool "kexec system call (EXPERIMENTAL)" + depends on EXPERIMENTAL help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot @@ -504,14 +492,7 @@ config CRASH_DUMP bool "kernel crash dumps (EXPERIMENTAL)" depends on EXPERIMENTAL help - Generate crash dump after being started by kexec. - This should be normally only set in special crash dump kernels - which are loaded in the main kernel with kexec-tools into - a specially reserved region and then later executed after - a crash by kdump/kexec. The crash dump kernel must be compiled - to a memory address not used by the main kernel or BIOS using - PHYSICAL_START. - For more details see Documentation/kdump/kdump.txt + Generate crash dump after being started by kexec. config PHYSICAL_START hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP) @@ -549,30 +530,6 @@ config SECCOMP If unsure, say Y. Only embedded should say N here. -config CC_STACKPROTECTOR - bool "Enable -fstack-protector buffer overflow detection (EXPRIMENTAL)" - depends on EXPERIMENTAL - help - This option turns on the -fstack-protector GCC feature. This - feature puts, at the beginning of critical functions, a canary - value on the stack just before the return address, and validates - the value just before actually returning. Stack based buffer - overflows (that need to overwrite this return address) now also - overwrite the canary, which gets detected and the attack is then - neutralized via a kernel panic. - - This feature requires gcc version 4.2 or above, or a distribution - gcc with the feature backported. Older versions are automatically - detected and for those versions, this configuration option is ignored. - -config CC_STACKPROTECTOR_ALL - bool "Use stack-protector for all functions" - depends on CC_STACKPROTECTOR - help - Normally, GCC only inserts the canary value protection for - functions that use large-ish on-stack buffers. By enabling - this option, GCC will be asked to do this for ALL functions. - source kernel/Kconfig.hz config REORDER @@ -690,7 +647,7 @@ source "arch/x86_64/oprofile/Kconfig" config KPROBES bool "Kprobes (EXPERIMENTAL)" - depends on KALLSYMS && EXPERIMENTAL && MODULES + depends on EXPERIMENTAL && MODULES help Kprobes allows you to trap at almost any kernel address and execute a callback function. register_kprobe() establishes diff --git a/trunk/arch/x86_64/Makefile b/trunk/arch/x86_64/Makefile index 1c0f18d4f887..431bb4bc36cd 100644 --- a/trunk/arch/x86_64/Makefile +++ b/trunk/arch/x86_64/Makefile @@ -54,16 +54,6 @@ endif cflags-y += $(call cc-option,-funit-at-a-time) # prevent gcc from generating any FP code by mistake cflags-y += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) -# do binutils support CFI? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_endproc,-DCONFIG_AS_CFI=1,) - -# is .cfi_signal_frame supported too? -cflags-y += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) -AFLAGS += $(call as-instr,.cfi_startproc\n.cfi_signal_frame\n.cfi_endproc,-DCONFIG_AS_CFI_SIGNAL_FRAME=1,) - -cflags-$(CONFIG_CC_STACKPROTECTOR) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector ) -cflags-$(CONFIG_CC_STACKPROTECTOR_ALL) += $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) -fstack-protector-all ) CFLAGS += $(cflags-y) CFLAGS_KERNEL += $(cflags-kernel-y) diff --git a/trunk/arch/x86_64/boot/compressed/Makefile b/trunk/arch/x86_64/boot/compressed/Makefile index e70fa6e1da08..f89d96f11a9f 100644 --- a/trunk/arch/x86_64/boot/compressed/Makefile +++ b/trunk/arch/x86_64/boot/compressed/Makefile @@ -7,8 +7,7 @@ # targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o -EXTRA_AFLAGS := -traditional -AFLAGS := $(subst -m64,-m32,$(AFLAGS)) +EXTRA_AFLAGS := -traditional -m32 # cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with # -m32 diff --git a/trunk/arch/x86_64/boot/setup.S b/trunk/arch/x86_64/boot/setup.S index c3bfd223ab49..a50b631f4d2b 100644 --- a/trunk/arch/x86_64/boot/setup.S +++ b/trunk/arch/x86_64/boot/setup.S @@ -526,12 +526,12 @@ is_disk1: movw %cs, %ax # aka SETUPSEG subw $DELTA_INITSEG, %ax # aka INITSEG movw %ax, %ds - movb $0, (0x1ff) # default is no pointing device + movw $0, (0x1ff) # default is no pointing device int $0x11 # int 0x11: equipment list testb $0x04, %al # check if mouse installed jz no_psmouse - movb $0xAA, (0x1ff) # device present + movw $0xAA, (0x1ff) # device present no_psmouse: #include "../../i386/boot/edd.S" diff --git a/trunk/arch/x86_64/defconfig b/trunk/arch/x86_64/defconfig index 4844b543bed0..5fb970715941 100644 --- a/trunk/arch/x86_64/defconfig +++ b/trunk/arch/x86_64/defconfig @@ -1,12 +1,11 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-git7 -# Wed Sep 27 21:53:10 2006 +# Linux kernel version: 2.6.18-rc4 +# Thu Aug 24 21:05:55 2006 # CONFIG_X86_64=y CONFIG_64BIT=y CONFIG_X86=y -CONFIG_ZONE_DMA32=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_SEMAPHORE_SLEEPERS=y @@ -20,7 +19,6 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_IOMAP=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_DMI=y -CONFIG_AUDIT_ARCH=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -40,16 +38,16 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set +CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y # CONFIG_CPUSETS is not set # CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y # CONFIG_EMBEDDED is not set -CONFIG_UID16=y -CONFIG_SYSCTL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set @@ -58,12 +56,12 @@ CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y +CONFIG_RT_MUTEXES=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y CONFIG_SLAB=y CONFIG_VM_EVENT_COUNTERS=y -CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 # CONFIG_SLOB is not set @@ -162,7 +160,6 @@ CONFIG_X86_MCE_AMD=y # CONFIG_CRASH_DUMP is not set CONFIG_PHYSICAL_START=0x200000 CONFIG_SECCOMP=y -# CONFIG_CC_STACKPROTECTOR is not set # CONFIG_HZ_100 is not set CONFIG_HZ_250=y # CONFIG_HZ_1000 is not set @@ -180,7 +177,6 @@ CONFIG_GENERIC_PENDING_IRQ=y CONFIG_PM=y # CONFIG_PM_LEGACY is not set # CONFIG_PM_DEBUG is not set -# CONFIG_PM_SYSFS_DEPRECATED is not set CONFIG_SOFTWARE_SUSPEND=y CONFIG_PM_STD_PARTITION="" CONFIG_SUSPEND_SMP=y @@ -253,7 +249,6 @@ CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y CONFIG_PCIEPORTBUS=y CONFIG_PCI_MSI=y -# CONFIG_PCI_MULTITHREAD_PROBE is not set # CONFIG_PCI_DEBUG is not set # @@ -312,23 +307,18 @@ CONFIG_IP_PNP_DHCP=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" +CONFIG_TCP_CONG_BIC=y CONFIG_IPV6=y # CONFIG_IPV6_PRIVACY is not set # CONFIG_IPV6_ROUTER_PREF is not set # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set -# CONFIG_IPV6_MIP6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set # CONFIG_INET6_XFRM_MODE_TUNNEL is not set -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set # CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPV6_SUBTREES is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set @@ -355,6 +345,7 @@ CONFIG_IPV6=y # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set @@ -496,7 +487,6 @@ CONFIG_IDEDMA_AUTO=y # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y -CONFIG_SCSI_NETLINK=y # CONFIG_SCSI_PROC_FS is not set # @@ -518,13 +508,12 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transports +# SCSI Transport Attributes # CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y # CONFIG_SCSI_ISCSI_ATTRS is not set CONFIG_SCSI_SAS_ATTRS=y -# CONFIG_SCSI_SAS_LIBSAS is not set # # SCSI low-level drivers @@ -543,14 +532,29 @@ CONFIG_AIC79XX_RESET_DELAY_MS=4000 # CONFIG_AIC79XX_DEBUG_ENABLE is not set CONFIG_AIC79XX_DEBUG_MASK=0 # CONFIG_AIC79XX_REG_PRETTY_PRINT is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_ARCMSR is not set CONFIG_MEGARAID_NEWGEN=y CONFIG_MEGARAID_MM=y CONFIG_MEGARAID_MAILBOX=y # CONFIG_MEGARAID_LEGACY is not set CONFIG_MEGARAID_SAS=y +CONFIG_SCSI_SATA=y +CONFIG_SCSI_SATA_AHCI=y +CONFIG_SCSI_SATA_SVW=y +CONFIG_SCSI_ATA_PIIX=y +# CONFIG_SCSI_SATA_MV is not set +CONFIG_SCSI_SATA_NV=y +# CONFIG_SCSI_PDC_ADMA is not set # CONFIG_SCSI_HPTIOP is not set +# CONFIG_SCSI_SATA_QSTOR is not set +# CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_SX4 is not set +CONFIG_SCSI_SATA_SIL=y +# CONFIG_SCSI_SATA_SIL24 is not set +# CONFIG_SCSI_SATA_SIS is not set +# CONFIG_SCSI_SATA_ULI is not set +CONFIG_SCSI_SATA_VIA=y +# CONFIG_SCSI_SATA_VITESSE is not set +CONFIG_SCSI_SATA_INTEL_COMBINED=y # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set @@ -559,7 +563,6 @@ CONFIG_MEGARAID_SAS=y # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set @@ -569,62 +572,6 @@ CONFIG_MEGARAID_SAS=y # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set -# -# Serial ATA (prod) and Parallel ATA (experimental) drivers -# -CONFIG_ATA=y -CONFIG_SATA_AHCI=y -CONFIG_SATA_SVW=y -CONFIG_ATA_PIIX=y -# CONFIG_SATA_MV is not set -CONFIG_SATA_NV=y -# CONFIG_PDC_ADMA is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_SX4 is not set -CONFIG_SATA_SIL=y -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_ULI is not set -CONFIG_SATA_VIA=y -# CONFIG_SATA_VITESSE is not set -CONFIG_SATA_INTEL_COMBINED=y -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_LEGACY is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_QDI is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set - # # Multi-device support (RAID and LVM) # @@ -731,7 +678,6 @@ CONFIG_NET_PCI=y # CONFIG_ADAPTEC_STARFIRE is not set CONFIG_B44=y CONFIG_FORCEDETH=y -# CONFIG_FORCEDETH_NAPI is not set # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y @@ -768,7 +714,6 @@ CONFIG_E1000=y # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y CONFIG_BNX2=y -# CONFIG_QLA3XXX is not set # # Ethernet (10000 Mbit) @@ -1091,7 +1036,6 @@ CONFIG_SOUND=y # Open Sound System # CONFIG_SOUND_PRIME=y -CONFIG_OSS_OBSOLETE_DRIVER=y # CONFIG_SOUND_BT878 is not set # CONFIG_SOUND_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set @@ -1102,6 +1046,7 @@ CONFIG_SOUND_ICH=y # CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set +# CONFIG_SOUND_TVMIXER is not set # # USB support @@ -1258,6 +1203,7 @@ CONFIG_USB_MON=y # InfiniBand support # # CONFIG_INFINIBAND is not set +# CONFIG_IPATH_CORE is not set # # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) @@ -1461,7 +1407,6 @@ CONFIG_KPROBES=y # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -# CONFIG_ENABLE_MUST_CHECK is not set CONFIG_MAGIC_SYSRQ=y CONFIG_UNUSED_SYMBOLS=y CONFIG_DEBUG_KERNEL=y @@ -1503,6 +1448,10 @@ CONFIG_DEBUG_STACKOVERFLOW=y # # CONFIG_CRYPTO is not set +# +# Hardware crypto devices +# + # # Library routines # diff --git a/trunk/arch/x86_64/ia32/ia32_aout.c b/trunk/arch/x86_64/ia32/ia32_aout.c index 396d3c100011..3bf58af98936 100644 --- a/trunk/arch/x86_64/ia32/ia32_aout.c +++ b/trunk/arch/x86_64/ia32/ia32_aout.c @@ -333,8 +333,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) return error; } - error = bprm->file->f_op->read(bprm->file, - (char __user *)text_addr, + error = bprm->file->f_op->read(bprm->file, (char *)text_addr, ex.a_text+ex.a_data, &pos); if ((signed long)error < 0) { send_sig(SIGKILL, current, 0); @@ -367,8 +366,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) down_write(¤t->mm->mmap_sem); do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); up_write(¤t->mm->mmap_sem); - bprm->file->f_op->read(bprm->file, - (char __user *)N_TXTADDR(ex), + bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); flush_icache_range((unsigned long) N_TXTADDR(ex), (unsigned long) N_TXTADDR(ex) + @@ -479,7 +477,7 @@ static int load_aout_library(struct file *file) do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); up_write(¤t->mm->mmap_sem); - file->f_op->read(file, (char __user *)start_addr, + file->f_op->read(file, (char *)start_addr, ex.a_text + ex.a_data, &pos); flush_icache_range((unsigned long) start_addr, (unsigned long) start_addr + ex.a_text + ex.a_data); diff --git a/trunk/arch/x86_64/ia32/ia32_signal.c b/trunk/arch/x86_64/ia32/ia32_signal.c index a6ba9951e86c..25e5ca22204c 100644 --- a/trunk/arch/x86_64/ia32/ia32_signal.c +++ b/trunk/arch/x86_64/ia32/ia32_signal.c @@ -113,19 +113,25 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) } asmlinkage long -sys32_sigsuspend(int history0, int history1, old_sigset_t mask) +sys32_sigsuspend(int history0, int history1, old_sigset_t mask, + struct pt_regs *regs) { + sigset_t saveset; + mask &= _BLOCKABLE; spin_lock_irq(¤t->sighand->siglock); - current->saved_sigmask = current->blocked; + saveset = current->blocked; siginitset(¤t->blocked, mask); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - current->state = TASK_INTERRUPTIBLE; - schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); - return -ERESTARTNOHAND; + regs->rax = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(regs, &saveset)) + return -EINTR; + } } asmlinkage long @@ -431,7 +437,15 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) goto give_sigsegv; - err |= __put_user(sig, &frame->sig); + { + struct exec_domain *ed = current_thread_info()->exec_domain; + err |= __put_user((ed + && ed->signal_invmap + && sig < 32 + ? ed->signal_invmap[sig] + : sig), + &frame->sig); + } if (err) goto give_sigsegv; @@ -478,11 +492,6 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, regs->rsp = (unsigned long) frame; regs->rip = (unsigned long) ka->sa.sa_handler; - /* Make -mregparm=3 work */ - regs->rax = sig; - regs->rdx = 0; - regs->rcx = 0; - asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); @@ -490,20 +499,20 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, regs->ss = __USER32_DS; set_fs(USER_DS); - regs->eflags &= ~TF_MASK; - if (test_thread_flag(TIF_SINGLESTEP)) - ptrace_notify(SIGTRAP); + regs->eflags &= ~TF_MASK; + if (test_thread_flag(TIF_SINGLESTEP)) + ptrace_notify(SIGTRAP); #if DEBUG_SIG printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", current->comm, current->pid, frame, regs->rip, frame->pretcode); #endif - return 0; + return 1; give_sigsegv: force_sigsegv(sig, current); - return -EFAULT; + return 0; } int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, @@ -586,18 +595,18 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->ss = __USER32_DS; set_fs(USER_DS); - regs->eflags &= ~TF_MASK; - if (test_thread_flag(TIF_SINGLESTEP)) - ptrace_notify(SIGTRAP); + regs->eflags &= ~TF_MASK; + if (test_thread_flag(TIF_SINGLESTEP)) + ptrace_notify(SIGTRAP); #if DEBUG_SIG printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", current->comm, current->pid, frame, regs->rip, frame->pretcode); #endif - return 0; + return 1; give_sigsegv: force_sigsegv(sig, current); - return -EFAULT; + return 0; } diff --git a/trunk/arch/x86_64/ia32/ia32entry.S b/trunk/arch/x86_64/ia32/ia32entry.S index b4aa875e175b..5d4a7d125ed0 100644 --- a/trunk/arch/x86_64/ia32/ia32entry.S +++ b/trunk/arch/x86_64/ia32/ia32entry.S @@ -71,7 +71,6 @@ */ ENTRY(ia32_sysenter_target) CFI_STARTPROC32 simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,0 CFI_REGISTER rsp,rbp swapgs @@ -187,7 +186,6 @@ ENDPROC(ia32_sysenter_target) */ ENTRY(ia32_cstar_target) CFI_STARTPROC32 simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,PDA_STACKOFFSET CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ @@ -295,7 +293,6 @@ ia32_badarg: ENTRY(ia32_syscall) CFI_STARTPROC simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,SS+8-RIP /*CFI_REL_OFFSET ss,SS-RIP*/ CFI_REL_OFFSET rsp,RSP-RIP @@ -373,7 +370,6 @@ ENTRY(ia32_ptregs_common) popq %r11 CFI_ENDPROC CFI_STARTPROC32 simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,SS+8-ARGOFFSET CFI_REL_OFFSET rax,RAX-ARGOFFSET CFI_REL_OFFSET rcx,RCX-ARGOFFSET @@ -707,8 +703,8 @@ ia32_sys_call_table: .quad sys_readlinkat /* 305 */ .quad sys_fchmodat .quad sys_faccessat - .quad compat_sys_pselect6 - .quad compat_sys_ppoll + .quad quiet_ni_syscall /* pselect6 for now */ + .quad quiet_ni_syscall /* ppoll for now */ .quad sys_unshare /* 310 */ .quad compat_sys_set_robust_list .quad compat_sys_get_robust_list @@ -717,5 +713,4 @@ ia32_sys_call_table: .quad sys_tee .quad compat_sys_vmsplice .quad compat_sys_move_pages - .quad sys_getcpu ia32_syscall_end: diff --git a/trunk/arch/x86_64/ia32/ptrace32.c b/trunk/arch/x86_64/ia32/ptrace32.c index d18198ed636b..659c0722f6b8 100644 --- a/trunk/arch/x86_64/ia32/ptrace32.c +++ b/trunk/arch/x86_64/ia32/ptrace32.c @@ -117,10 +117,6 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 val) if ((0x5454 >> ((val >> (16 + 4*i)) & 0xf)) & 1) return -EIO; child->thread.debugreg7 = val; - if (val) - set_tsk_thread_flag(child, TIF_DEBUG); - else - clear_tsk_thread_flag(child, TIF_DEBUG); break; default: @@ -375,10 +371,8 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) ret = -EIO; if (!access_ok(VERIFY_READ, u, sizeof(*u))) break; - /* no checking to be bug-to-bug compatible with i386. */ - /* but silence warning */ - if (__copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u))) - ; + /* no checking to be bug-to-bug compatible with i386 */ + __copy_from_user(&child->thread.i387.fxsave, u, sizeof(*u)); set_stopped_child_used_math(child); child->thread.i387.fxsave.mxcsr &= mxcsr_feature_mask; ret = 0; diff --git a/trunk/arch/x86_64/ia32/sys_ia32.c b/trunk/arch/x86_64/ia32/sys_ia32.c index 26a01717cc1a..9c130993380d 100644 --- a/trunk/arch/x86_64/ia32/sys_ia32.c +++ b/trunk/arch/x86_64/ia32/sys_ia32.c @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -390,9 +389,7 @@ sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, } } set_fs (KERNEL_DS); - ret = sys_rt_sigprocmask(how, - set ? (sigset_t __user *)&s : NULL, - oset ? (sigset_t __user *)&s : NULL, + ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sigsetsize); set_fs (old_fs); if (ret) return ret; @@ -544,7 +541,7 @@ sys32_sysinfo(struct sysinfo32 __user *info) int bitcount = 0; set_fs (KERNEL_DS); - ret = sys_sysinfo((struct sysinfo __user *)&s); + ret = sys_sysinfo(&s); set_fs (old_fs); /* Check to see if any memory value is too large for 32-bit and scale @@ -592,7 +589,7 @@ sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *int mm_segment_t old_fs = get_fs (); set_fs (KERNEL_DS); - ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t); + ret = sys_sched_rr_get_interval(pid, &t); set_fs (old_fs); if (put_compat_timespec(&t, interval)) return -EFAULT; @@ -608,7 +605,7 @@ sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) mm_segment_t old_fs = get_fs(); set_fs (KERNEL_DS); - ret = sys_rt_sigpending((sigset_t __user *)&s, sigsetsize); + ret = sys_rt_sigpending(&s, sigsetsize); set_fs (old_fs); if (!ret) { switch (_NSIG_WORDS) { @@ -633,7 +630,7 @@ sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo) if (copy_siginfo_from_user32(&info, uinfo)) return -EFAULT; set_fs (KERNEL_DS); - ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info); + ret = sys_rt_sigqueueinfo(pid, sig, &info); set_fs (old_fs); return ret; } @@ -648,7 +645,7 @@ sys32_pause(void) } -#ifdef CONFIG_SYSCTL_SYSCALL +#ifdef CONFIG_SYSCTL struct sysctl_ia32 { unsigned int name; int nlen; @@ -669,6 +666,9 @@ sys32_sysctl(struct sysctl_ia32 __user *args32) size_t oldlen; int __user *namep; long ret; + extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp, + void *newval, size_t newlen); + if (copy_from_user(&a32, args32, sizeof (a32))) return -EFAULT; @@ -692,8 +692,7 @@ sys32_sysctl(struct sysctl_ia32 __user *args32) set_fs(KERNEL_DS); lock_kernel(); - ret = do_sysctl(namep, a32.nlen, oldvalp, (size_t __user *)&oldlen, - newvalp, (size_t) a32.newlen); + ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen); unlock_kernel(); set_fs(old_fs); @@ -744,8 +743,7 @@ sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count) return -EFAULT; set_fs(KERNEL_DS); - ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, - count); + ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count); set_fs(old_fs); if (offset && put_user(of, offset)) @@ -780,40 +778,36 @@ asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len, asmlinkage long sys32_olduname(struct oldold_utsname __user * name) { - int err; + int error; if (!name) return -EFAULT; - if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname))) + if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; down_read(&uts_sem); - - err = __copy_to_user(&name->sysname,&utsname()->sysname, - __OLD_UTS_LEN); - err |= __put_user(0,name->sysname+__OLD_UTS_LEN); - err |= __copy_to_user(&name->nodename,&utsname()->nodename, - __OLD_UTS_LEN); - err |= __put_user(0,name->nodename+__OLD_UTS_LEN); - err |= __copy_to_user(&name->release,&utsname()->release, - __OLD_UTS_LEN); - err |= __put_user(0,name->release+__OLD_UTS_LEN); - err |= __copy_to_user(&name->version,&utsname()->version, - __OLD_UTS_LEN); - err |= __put_user(0,name->version+__OLD_UTS_LEN); - { - char *arch = "x86_64"; - if (personality(current->personality) == PER_LINUX32) - arch = "i686"; + + error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); + __put_user(0,name->sysname+__OLD_UTS_LEN); + __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); + __put_user(0,name->nodename+__OLD_UTS_LEN); + __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); + __put_user(0,name->release+__OLD_UTS_LEN); + __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); + __put_user(0,name->version+__OLD_UTS_LEN); + { + char *arch = "x86_64"; + if (personality(current->personality) == PER_LINUX32) + arch = "i686"; - err |= __copy_to_user(&name->machine, arch, strlen(arch)+1); - } - - up_read(&uts_sem); - - err = err ? -EFAULT : 0; - - return err; + __copy_to_user(&name->machine,arch,strlen(arch)+1); + } + + up_read(&uts_sem); + + error = error ? -EFAULT : 0; + + return error; } long sys32_uname(struct old_utsname __user * name) @@ -822,7 +816,7 @@ long sys32_uname(struct old_utsname __user * name) if (!name) return -EFAULT; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err=copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); if (personality(current->personality) == PER_LINUX32) err |= copy_to_user(&name->machine, "i686", 5); @@ -837,7 +831,7 @@ long sys32_ustat(unsigned dev, struct ustat32 __user *u32p) seg = get_fs(); set_fs(KERNEL_DS); - ret = sys_ustat(dev, (struct ustat __user *)&u); + ret = sys_ustat(dev,&u); set_fs(seg); if (ret >= 0) { if (!access_ok(VERIFY_WRITE,u32p,sizeof(struct ustat32)) || diff --git a/trunk/arch/x86_64/kernel/Makefile b/trunk/arch/x86_64/kernel/Makefile index 3c7cbff04d3d..b5aaeafc1cd3 100644 --- a/trunk/arch/x86_64/kernel/Makefile +++ b/trunk/arch/x86_64/kernel/Makefile @@ -11,7 +11,7 @@ obj-y := process.o signal.o entry.o traps.o irq.o \ pci-dma.o pci-nommu.o alternative.o obj-$(CONFIG_STACKTRACE) += stacktrace.o -obj-$(CONFIG_X86_MCE) += mce.o therm_throt.o +obj-$(CONFIG_X86_MCE) += mce.o obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o obj-$(CONFIG_X86_MCE_AMD) += mce_amd.o obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/ @@ -20,8 +20,8 @@ obj-$(CONFIG_X86_MSR) += msr.o obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_X86_CPUID) += cpuid.o obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o -obj-y += apic.o nmi.o -obj-y += io_apic.o mpparse.o \ +obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o +obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o \ genapic.o genapic_cluster.o genapic_flat.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o @@ -39,14 +39,12 @@ obj-$(CONFIG_K8_NB) += k8.o obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_MODULES) += module.o -obj-$(CONFIG_PCI) += early-quirks.o obj-y += topology.o obj-y += intel_cacheinfo.o CFLAGS_vsyscall.o := $(PROFILING) -g0 -therm_throt-y += ../../i386/kernel/cpu/mcheck/therm_throt.o bootflag-y += ../../i386/kernel/bootflag.o cpuid-$(subst m,y,$(CONFIG_X86_CPUID)) += ../../i386/kernel/cpuid.o topology-y += ../../i386/kernel/topology.o @@ -56,3 +54,4 @@ quirks-y += ../../i386/kernel/quirks.o i8237-y += ../../i386/kernel/i8237.o msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o alternative-y += ../../i386/kernel/alternative.o + diff --git a/trunk/arch/x86_64/kernel/aperture.c b/trunk/arch/x86_64/kernel/aperture.c index b487396c4c5b..58af8e73738b 100644 --- a/trunk/arch/x86_64/kernel/aperture.c +++ b/trunk/arch/x86_64/kernel/aperture.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -34,18 +33,6 @@ int fallback_aper_force __initdata = 0; int fix_aperture __initdata = 1; -static struct resource gart_resource = { - .name = "GART", - .flags = IORESOURCE_MEM, -}; - -static void __init insert_aperture_resource(u32 aper_base, u32 aper_size) -{ - gart_resource.start = aper_base; - gart_resource.end = aper_base + aper_size - 1; - insert_resource(&iomem_resource, &gart_resource); -} - /* This code runs before the PCI subsystem is initialized, so just access the northbridge directly. */ @@ -61,7 +48,7 @@ static u32 __init allocate_aperture(void) /* * Aperture has to be naturally aligned. This means an 2GB aperture won't - * have much chance of finding a place in the lower 4GB of memory. + * have much chances to find a place in the lower 4GB of memory. * Unfortunately we cannot move it up because that would make the * IOMMU useless. */ @@ -75,7 +62,6 @@ static u32 __init allocate_aperture(void) } printk("Mapping aperture over %d KB of RAM @ %lx\n", aper_size >> 10, __pa(p)); - insert_aperture_resource((u32)__pa(p), aper_size); return (u32)__pa(p); } @@ -212,7 +198,7 @@ void __init iommu_hole_init(void) u64 aper_base, last_aper_base = 0; int valid_agp = 0; - if (iommu_aperture_disabled || !fix_aperture || !early_pci_allowed()) + if (iommu_aperture_disabled || !fix_aperture) return; printk("Checking aperture...\n"); @@ -247,13 +233,8 @@ void __init iommu_hole_init(void) last_aper_base = aper_base; } - if (!fix && !fallback_aper_force) { - if (last_aper_base) { - unsigned long n = (32 * 1024 * 1024) << last_aper_order; - insert_aperture_resource((u32)last_aper_base, n); - } + if (!fix && !fallback_aper_force) return; - } if (!fallback_aper_force) aper_alloc = search_agp_bridge(&aper_order, &valid_agp); diff --git a/trunk/arch/x86_64/kernel/apic.c b/trunk/arch/x86_64/kernel/apic.c index 135ff25e6b44..2b8cef037a65 100644 --- a/trunk/arch/x86_64/kernel/apic.c +++ b/trunk/arch/x86_64/kernel/apic.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -37,20 +36,13 @@ #include #include #include -#include -int apic_mapped; int apic_verbosity; int apic_runs_main_timer; int apic_calibrate_pmtmr __initdata; int disable_apic_timer __initdata; -static struct resource lapic_resource = { - .name = "Local APIC", - .flags = IORESOURCE_MEM | IORESOURCE_BUSY, -}; - /* * cpu_mask that denotes the CPUs that needs timer interrupt coming in as * IPIs in place of local APIC timers @@ -144,40 +136,72 @@ void clear_local_APIC(void) apic_read(APIC_ESR); } -void disconnect_bsp_APIC(int virt_wire_setup) +void __init connect_bsp_APIC(void) { - /* Go back to Virtual Wire compatibility mode */ - unsigned long value; - - /* For the spurious interrupt use vector F, and enable it */ - value = apic_read(APIC_SPIV); - value &= ~APIC_VECTOR_MASK; - value |= APIC_SPIV_APIC_ENABLED; - value |= 0xf; - apic_write(APIC_SPIV, value); + if (pic_mode) { + /* + * Do not trust the local APIC being empty at bootup. + */ + clear_local_APIC(); + /* + * PIC mode, enable APIC mode in the IMCR, i.e. + * connect BSP's local APIC to INT and NMI lines. + */ + apic_printk(APIC_VERBOSE, "leaving PIC mode, enabling APIC mode.\n"); + outb(0x70, 0x22); + outb(0x01, 0x23); + } +} - if (!virt_wire_setup) { - /* For LVT0 make it edge triggered, active high, external and enabled */ - value = apic_read(APIC_LVT0); - value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | - APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | - APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED ); - value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; - value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); - apic_write(APIC_LVT0, value); - } else { - /* Disable LVT0 */ - apic_write(APIC_LVT0, APIC_LVT_MASKED); +void disconnect_bsp_APIC(int virt_wire_setup) +{ + if (pic_mode) { + /* + * Put the board back into PIC mode (has an effect + * only on certain older boards). Note that APIC + * interrupts, including IPIs, won't work beyond + * this point! The only exception are INIT IPIs. + */ + apic_printk(APIC_QUIET, "disabling APIC mode, entering PIC mode.\n"); + outb(0x70, 0x22); + outb(0x00, 0x23); } + else { + /* Go back to Virtual Wire compatibility mode */ + unsigned long value; + + /* For the spurious interrupt use vector F, and enable it */ + value = apic_read(APIC_SPIV); + value &= ~APIC_VECTOR_MASK; + value |= APIC_SPIV_APIC_ENABLED; + value |= 0xf; + apic_write(APIC_SPIV, value); + + if (!virt_wire_setup) { + /* For LVT0 make it edge triggered, active high, external and enabled */ + value = apic_read(APIC_LVT0); + value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | + APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | + APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED ); + value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; + value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT); + apic_write(APIC_LVT0, value); + } + else { + /* Disable LVT0 */ + apic_write(APIC_LVT0, APIC_LVT_MASKED); + } - /* For LVT1 make it edge triggered, active high, nmi and enabled */ - value = apic_read(APIC_LVT1); - value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING | + /* For LVT1 make it edge triggered, active high, nmi and enabled */ + value = apic_read(APIC_LVT1); + value &= ~( + APIC_MODE_MASK | APIC_SEND_PENDING | APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED); - value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; - value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); - apic_write(APIC_LVT1, value); + value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING; + value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI); + apic_write(APIC_LVT1, value); + } } void disable_local_APIC(void) @@ -273,6 +297,8 @@ void __init sync_Arb_IDs(void) | APIC_DM_INIT); } +extern void __error_in_apic_c (void); + /* * An initial setup of the virtual wire mode. */ @@ -319,7 +345,8 @@ void __cpuinit setup_local_APIC (void) value = apic_read(APIC_LVR); - BUILD_BUG_ON((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f); + if ((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f) + __error_in_apic_c(); /* * Double-check whether this APIC is really registered. @@ -372,8 +399,32 @@ void __cpuinit setup_local_APIC (void) */ value |= APIC_SPIV_APIC_ENABLED; - /* We always use processor focus */ - + /* + * Some unknown Intel IO/APIC (or APIC) errata is biting us with + * certain networking cards. If high frequency interrupts are + * happening on a particular IOAPIC pin, plus the IOAPIC routing + * entry is masked/unmasked at a high rate as well then sooner or + * later IOAPIC line gets 'stuck', no more interrupts are received + * from the device. If focus CPU is disabled then the hang goes + * away, oh well :-( + * + * [ This bug can be reproduced easily with a level-triggered + * PCI Ne2000 networking cards and PII/PIII processors, dual + * BX chipset. ] + */ + /* + * Actually disabling the focus CPU check just makes the hang less + * frequent as it makes the interrupt distributon model be more + * like LRU than MRU (the short-term load is more even across CPUs). + * See also the comment in end_level_ioapic_irq(). --macro + */ +#if 1 + /* Enable focus processor (bit==0) */ + value &= ~APIC_SPIV_FOCUS_DISABLED; +#else + /* Disable focus processor (bit==1) */ + value |= APIC_SPIV_FOCUS_DISABLED; +#endif /* * Set spurious IRQ vector */ @@ -391,7 +442,7 @@ void __cpuinit setup_local_APIC (void) * TODO: set up through-local-APIC from through-I/O-APIC? --macro */ value = apic_read(APIC_LVT0) & APIC_LVT_MASKED; - if (!smp_processor_id() && !value) { + if (!smp_processor_id() && (pic_mode || !value)) { value = APIC_DM_EXTINT; apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", smp_processor_id()); } else { @@ -428,7 +479,8 @@ void __cpuinit setup_local_APIC (void) } nmi_watchdog_default(); - setup_apic_nmi_watchdog(NULL); + if (nmi_watchdog == NMI_LOCAL_APIC) + setup_apic_nmi_watchdog(); apic_pm_activate(); } @@ -475,7 +527,8 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state) apic_pm_state.apic_tmict = apic_read(APIC_TMICT); apic_pm_state.apic_tdcr = apic_read(APIC_TDCR); apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR); - local_irq_save(flags); + local_save_flags(flags); + local_irq_disable(); disable_local_APIC(); local_irq_restore(flags); return 0; @@ -553,24 +606,18 @@ static void apic_pm_activate(void) { } static int __init apic_set_verbosity(char *str) { - if (str == NULL) { - skip_ioapic_setup = 0; - ioapic_force = 1; - return 0; - } if (strcmp("debug", str) == 0) apic_verbosity = APIC_DEBUG; else if (strcmp("verbose", str) == 0) apic_verbosity = APIC_VERBOSE; - else { + else printk(KERN_WARNING "APIC Verbosity level %s not recognised" - " use apic=verbose or apic=debug\n", str); - return -EINVAL; - } + " use apic=verbose or apic=debug", str); - return 0; + return 1; } -early_param("apic", apic_set_verbosity); + +__setup("apic=", apic_set_verbosity); /* * Detect and enable local APICs on non-SMP boards. @@ -591,40 +638,6 @@ static int __init detect_init_APIC (void) return 0; } -#ifdef CONFIG_X86_IO_APIC -static struct resource * __init ioapic_setup_resources(void) -{ -#define IOAPIC_RESOURCE_NAME_SIZE 11 - unsigned long n; - struct resource *res; - char *mem; - int i; - - if (nr_ioapics <= 0) - return NULL; - - n = IOAPIC_RESOURCE_NAME_SIZE + sizeof(struct resource); - n *= nr_ioapics; - - res = alloc_bootmem(n); - - if (!res) - return NULL; - - memset(res, 0, n); - mem = (void *)&res[nr_ioapics]; - - for (i = 0; i < nr_ioapics; i++) { - res[i].name = mem; - res[i].flags = IORESOURCE_MEM | IORESOURCE_BUSY; - snprintf(mem, IOAPIC_RESOURCE_NAME_SIZE, "IOAPIC %u", i); - mem += IOAPIC_RESOURCE_NAME_SIZE; - } - - return res; -} -#endif - void __init init_apic_mappings(void) { unsigned long apic_phys; @@ -641,26 +654,19 @@ void __init init_apic_mappings(void) apic_phys = mp_lapic_addr; set_fixmap_nocache(FIX_APIC_BASE, apic_phys); - apic_mapped = 1; apic_printk(APIC_VERBOSE,"mapped APIC to %16lx (%16lx)\n", APIC_BASE, apic_phys); - /* Put local APIC into the resource map. */ - lapic_resource.start = apic_phys; - lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1; - insert_resource(&iomem_resource, &lapic_resource); - /* * Fetch the APIC ID of the BSP in case we have a * default configuration (or the MP table is broken). */ boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID)); +#ifdef CONFIG_X86_IO_APIC { unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0; int i; - struct resource *ioapic_res; - ioapic_res = ioapic_setup_resources(); for (i = 0; i < nr_ioapics; i++) { if (smp_found_config) { ioapic_phys = mp_ioapics[i].mpc_apicaddr; @@ -672,15 +678,9 @@ void __init init_apic_mappings(void) apic_printk(APIC_VERBOSE,"mapped IOAPIC to %016lx (%016lx)\n", __fix_to_virt(idx), ioapic_phys); idx++; - - if (ioapic_res) { - ioapic_res->start = ioapic_phys; - ioapic_res->end = ioapic_phys + (4 * 1024) - 1; - insert_resource(&iomem_resource, ioapic_res); - ioapic_res++; - } } } +#endif } /* @@ -951,7 +951,7 @@ void smp_local_timer_interrupt(struct pt_regs *regs) * We take the 'long' return path, and there every subsystem * grabs the appropriate locks (kernel lock/ irq lock). * - * We might want to decouple profiling from the 'long path', + * we might want to decouple profiling from the 'long path', * and do the profiling totally in assembly. * * Currently this isn't too much of an issue (performance wise), @@ -1123,15 +1123,19 @@ int __init APIC_init_uniprocessor (void) verify_local_APIC(); + connect_bsp_APIC(); + phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id); apic_write(APIC_ID, SET_APIC_ID(boot_cpu_id)); setup_local_APIC(); +#ifdef CONFIG_X86_IO_APIC if (smp_found_config && !skip_ioapic_setup && nr_ioapics) - setup_IO_APIC(); + setup_IO_APIC(); else nr_ioapics = 0; +#endif setup_boot_APIC_clock(); check_nmi_watchdog(); return 0; @@ -1140,17 +1144,14 @@ int __init APIC_init_uniprocessor (void) static __init int setup_disableapic(char *str) { disable_apic = 1; - clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); - return 0; -} -early_param("disableapic", setup_disableapic); + return 1; +} -/* same as disableapic, for compatibility */ static __init int setup_nolapic(char *str) { - return setup_disableapic(str); + disable_apic = 1; + return 1; } -early_param("nolapic", setup_nolapic); static __init int setup_noapictimer(char *str) { @@ -1183,5 +1184,11 @@ static __init int setup_apicpmtimer(char *s) } __setup("apicpmtimer", setup_apicpmtimer); +/* dummy parsing: see setup.c */ + +__setup("disableapic", setup_disableapic); +__setup("nolapic", setup_nolapic); /* same as disableapic, for compatibility */ + __setup("noapictimer", setup_noapictimer); +/* no "lapic" flag - we only use the lapic when the BIOS tells us so. */ diff --git a/trunk/arch/x86_64/kernel/crash.c b/trunk/arch/x86_64/kernel/crash.c index 3525f884af82..d8d5750d6106 100644 --- a/trunk/arch/x86_64/kernel/crash.c +++ b/trunk/arch/x86_64/kernel/crash.c @@ -23,7 +23,6 @@ #include #include #include -#include /* This keeps a track of which one is crashing cpu. */ static int crashing_cpu; @@ -69,7 +68,7 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu) * for the data I pass, and I need tags * on the data to indicate what information I have * squirrelled away. ELF notes happen to provide - * all of that, no need to invent something new. + * all of that that no need to invent something new. */ buf = (u32*)per_cpu_ptr(crash_notes, cpu); @@ -96,25 +95,15 @@ static void crash_save_self(struct pt_regs *regs) #ifdef CONFIG_SMP static atomic_t waiting_for_crash_ipi; -static int crash_nmi_callback(struct notifier_block *self, - unsigned long val, void *data) +static int crash_nmi_callback(struct pt_regs *regs, int cpu) { - struct pt_regs *regs; - int cpu; - - if (val != DIE_NMI_IPI) - return NOTIFY_OK; - - regs = ((struct die_args *)data)->regs; - cpu = raw_smp_processor_id(); - /* * Don't do anything if this handler is invoked on crashing cpu. * Otherwise, system will completely hang. Crashing cpu can get * an NMI if system was initially booted with nmi_watchdog parameter. */ if (cpu == crashing_cpu) - return NOTIFY_STOP; + return 1; local_irq_disable(); crash_save_this_cpu(regs, cpu); @@ -138,17 +127,12 @@ static void smp_send_nmi_allbutself(void) * cpu hotplug shouldn't matter. */ -static struct notifier_block crash_nmi_nb = { - .notifier_call = crash_nmi_callback, -}; - static void nmi_shootdown_cpus(void) { unsigned long msecs; atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); - if (register_die_notifier(&crash_nmi_nb)) - return; /* return what? */ + set_nmi_callback(crash_nmi_callback); /* * Ensure the new callback function is set before sending @@ -194,7 +178,9 @@ void machine_crash_shutdown(struct pt_regs *regs) if(cpu_has_apic) disable_local_APIC(); +#if defined(CONFIG_X86_IO_APIC) disable_IO_APIC(); +#endif crash_save_self(regs); } diff --git a/trunk/arch/x86_64/kernel/e820.c b/trunk/arch/x86_64/kernel/e820.c index b3f0908668ec..708a3cd9a27e 100644 --- a/trunk/arch/x86_64/kernel/e820.c +++ b/trunk/arch/x86_64/kernel/e820.c @@ -25,8 +25,6 @@ #include #include -struct e820map e820 __initdata; - /* * PFN of last memory page. */ @@ -43,7 +41,7 @@ unsigned long end_pfn_map; /* * Last pfn which the user wants to use. */ -static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT; +unsigned long end_user_pfn = MAXMEM>>PAGE_SHIFT; extern struct resource code_resource, data_resource; @@ -72,7 +70,12 @@ static inline int bad_addr(unsigned long *addrp, unsigned long size) return 1; } #endif - /* kernel code */ + /* kernel code + 640k memory hole (later should not be needed, but + be paranoid for now) */ + if (last >= 640*1024 && addr < 1024*1024) { + *addrp = 1024*1024; + return 1; + } if (last >= __pa_symbol(&_text) && last < __pa_symbol(&_end)) { *addrp = __pa_symbol(&_end); return 1; @@ -162,14 +165,59 @@ unsigned long __init find_e820_area(unsigned long start, unsigned long end, unsi return -1UL; } +/* + * Free bootmem based on the e820 table for a node. + */ +void __init e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end) +{ + int i; + for (i = 0; i < e820.nr_map; i++) { + struct e820entry *ei = &e820.map[i]; + unsigned long last, addr; + + if (ei->type != E820_RAM || + ei->addr+ei->size <= start || + ei->addr >= end) + continue; + + addr = round_up(ei->addr, PAGE_SIZE); + if (addr < start) + addr = start; + + last = round_down(ei->addr + ei->size, PAGE_SIZE); + if (last >= end) + last = end; + + if (last > addr && last-addr >= PAGE_SIZE) + free_bootmem_node(pgdat, addr, last-addr); + } +} + /* * Find the highest page frame number we have available */ unsigned long __init e820_end_of_ram(void) { + int i; unsigned long end_pfn = 0; - end_pfn = find_max_pfn_with_active_regions(); + for (i = 0; i < e820.nr_map; i++) { + struct e820entry *ei = &e820.map[i]; + unsigned long start, end; + + start = round_up(ei->addr, PAGE_SIZE); + end = round_down(ei->addr + ei->size, PAGE_SIZE); + if (start >= end) + continue; + if (ei->type == E820_RAM) { + if (end > end_pfn<>PAGE_SHIFT; + } else { + if (end > end_pfn_map<>PAGE_SHIFT; + } + } + if (end_pfn > end_pfn_map) end_pfn_map = end_pfn; if (end_pfn_map > MAXMEM>>PAGE_SHIFT) @@ -179,10 +227,43 @@ unsigned long __init e820_end_of_ram(void) if (end_pfn > end_pfn_map) end_pfn = end_pfn_map; - printk("end_pfn_map = %lu\n", end_pfn_map); return end_pfn; } +/* + * Compute how much memory is missing in a range. + * Unlike the other functions in this file the arguments are in page numbers. + */ +unsigned long __init +e820_hole_size(unsigned long start_pfn, unsigned long end_pfn) +{ + unsigned long ram = 0; + unsigned long start = start_pfn << PAGE_SHIFT; + unsigned long end = end_pfn << PAGE_SHIFT; + int i; + for (i = 0; i < e820.nr_map; i++) { + struct e820entry *ei = &e820.map[i]; + unsigned long last, addr; + + if (ei->type != E820_RAM || + ei->addr+ei->size <= start || + ei->addr >= end) + continue; + + addr = round_up(ei->addr, PAGE_SIZE); + if (addr < start) + addr = start; + + last = round_down(ei->addr + ei->size, PAGE_SIZE); + if (last >= end) + last = end; + + if (last > addr) + ram += last - addr; + } + return ((end - start) - ram) >> PAGE_SHIFT; +} + /* * Mark e820 reserved areas as busy for the resource manager. */ @@ -264,49 +345,6 @@ void __init e820_mark_nosave_regions(void) } } -/* Walk the e820 map and register active regions within a node */ -void __init -e820_register_active_regions(int nid, unsigned long start_pfn, - unsigned long end_pfn) -{ - int i; - unsigned long ei_startpfn, ei_endpfn; - for (i = 0; i < e820.nr_map; i++) { - struct e820entry *ei = &e820.map[i]; - ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT; - ei_endpfn = round_down(ei->addr + ei->size, PAGE_SIZE) - >> PAGE_SHIFT; - - /* Skip map entries smaller than a page */ - if (ei_startpfn > ei_endpfn) - continue; - - /* Check if end_pfn_map should be updated */ - if (ei->type != E820_RAM && ei_endpfn > end_pfn_map) - end_pfn_map = ei_endpfn; - - /* Skip if map is outside the node */ - if (ei->type != E820_RAM || - ei_endpfn <= start_pfn || - ei_startpfn >= end_pfn) - continue; - - /* Check for overlaps */ - if (ei_startpfn < start_pfn) - ei_startpfn = start_pfn; - if (ei_endpfn > end_pfn) - ei_endpfn = end_pfn; - - /* Obey end_user_pfn to save on memmap */ - if (ei_startpfn >= end_user_pfn) - continue; - if (ei_endpfn > end_user_pfn) - ei_endpfn = end_user_pfn; - - add_active_range(nid, ei_startpfn, ei_endpfn); - } -} - /* * Add a memory region to the kernel e820 map. */ @@ -527,6 +565,13 @@ static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) * If we're lucky and live on a modern system, the setup code * will have given us a memory map that we can use to properly * set up memory. If we aren't, we'll fake a memory map. + * + * We check to see that the memory map contains at least 2 elements + * before we'll use it, because the detection code in setup.S may + * not be perfect and most every PC known to man has two memory + * regions: one from 0 to 640k, and one from 1mb up. (The IBM + * thinkpad 560x, for example, does not cooperate with the memory + * detection code.) */ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) { @@ -544,19 +589,34 @@ static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) if (start > end) return -1; + /* + * Some BIOSes claim RAM in the 640k - 1M region. + * Not right. Fix it up. + * + * This should be removed on Hammer which is supposed to not + * have non e820 covered ISA mappings there, but I had some strange + * problems so it stays for now. -AK + */ + if (type == E820_RAM) { + if (start < 0x100000ULL && end > 0xA0000ULL) { + if (start < 0xA0000ULL) + add_memory_region(start, 0xA0000ULL-start, type); + if (end <= 0x100000ULL) + continue; + start = 0x100000ULL; + size = end - start; + } + } + add_memory_region(start, size, type); } while (biosmap++,--nr_map); return 0; } -void early_panic(char *msg) -{ - early_printk(msg); - panic(msg); -} - void __init setup_memory_region(void) { + char *who = "BIOS-e820"; + /* * Try to copy the BIOS-supplied E820-map. * @@ -564,70 +624,51 @@ void __init setup_memory_region(void) * the next section from 1mb->appropriate_mem_k */ sanitize_e820_map(E820_MAP, &E820_MAP_NR); - if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) - early_panic("Cannot find a valid memory map"); + if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { + unsigned long mem_size; + + /* compare results from other methods and take the greater */ + if (ALT_MEM_K < EXT_MEM_K) { + mem_size = EXT_MEM_K; + who = "BIOS-88"; + } else { + mem_size = ALT_MEM_K; + who = "BIOS-e801"; + } + + e820.nr_map = 0; + add_memory_region(0, LOWMEMSIZE(), E820_RAM); + add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); + } printk(KERN_INFO "BIOS-provided physical RAM map:\n"); - e820_print_map("BIOS-e820"); + e820_print_map(who); } -static int __init parse_memopt(char *p) -{ - if (!p) - return -EINVAL; - end_user_pfn = memparse(p, &p); +void __init parse_memopt(char *p, char **from) +{ + end_user_pfn = memparse(p, from); end_user_pfn >>= PAGE_SHIFT; - return 0; } -early_param("mem", parse_memopt); -static int userdef __initdata; - -static int __init parse_memmap_opt(char *p) +void __init parse_memmapopt(char *p, char **from) { - char *oldp; unsigned long long start_at, mem_size; - if (!strcmp(p, "exactmap")) { -#ifdef CONFIG_CRASH_DUMP - /* If we are doing a crash dump, we - * still need to know the real mem - * size before original memory map is - * reset. - */ - saved_max_pfn = e820_end_of_ram(); -#endif - end_pfn_map = 0; - e820.nr_map = 0; - userdef = 1; - return 0; - } - - oldp = p; - mem_size = memparse(p, &p); - if (p == oldp) - return -EINVAL; + mem_size = memparse(p, from); + p = *from; if (*p == '@') { - start_at = memparse(p+1, &p); + start_at = memparse(p+1, from); add_memory_region(start_at, mem_size, E820_RAM); } else if (*p == '#') { - start_at = memparse(p+1, &p); + start_at = memparse(p+1, from); add_memory_region(start_at, mem_size, E820_ACPI); } else if (*p == '$') { - start_at = memparse(p+1, &p); + start_at = memparse(p+1, from); add_memory_region(start_at, mem_size, E820_RESERVED); } else { end_user_pfn = (mem_size >> PAGE_SHIFT); } - return *p == '\0' ? 0 : -EINVAL; -} -early_param("memmap", parse_memmap_opt); - -void finish_e820_parsing(void) -{ - if (userdef) { - printk(KERN_INFO "user-defined physical RAM map:\n"); - e820_print_map("user"); - } + p = *from; } unsigned long pci_mem_start = 0xaeedbabe; diff --git a/trunk/arch/x86_64/kernel/early-quirks.c b/trunk/arch/x86_64/kernel/early-quirks.c deleted file mode 100644 index 208e38a372c1..000000000000 --- a/trunk/arch/x86_64/kernel/early-quirks.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Various workarounds for chipset bugs. - This code runs very early and can't use the regular PCI subsystem - The entries are keyed to PCI bridges which usually identify chipsets - uniquely. - This is only for whole classes of chipsets with specific problems which - need early invasive action (e.g. before the timers are initialized). - Most PCI device specific workarounds can be done later and should be - in standard PCI quirks - Mainboard specific bugs should be handled by DMI entries. - CPU specific bugs in setup.c */ - -#include -#include -#include -#include -#include -#include - -static void via_bugs(void) -{ -#ifdef CONFIG_IOMMU - if ((end_pfn > MAX_DMA32_PFN || force_iommu) && - !iommu_aperture_allowed) { - printk(KERN_INFO - "Looks like a VIA chipset. Disabling IOMMU. Override with iommu=allowed\n"); - iommu_aperture_disabled = 1; - } -#endif -} - -#ifdef CONFIG_ACPI - -static int nvidia_hpet_detected __initdata; - -static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) -{ - nvidia_hpet_detected = 1; - return 0; -} -#endif - -static void nvidia_bugs(void) -{ -#ifdef CONFIG_ACPI - /* - * All timer overrides on Nvidia are - * wrong unless HPET is enabled. - */ - nvidia_hpet_detected = 0; - acpi_table_parse(ACPI_HPET, nvidia_hpet_check); - if (nvidia_hpet_detected == 0) { - acpi_skip_timer_override = 1; - printk(KERN_INFO "Nvidia board " - "detected. Ignoring ACPI " - "timer override.\n"); - } -#endif - /* RED-PEN skip them on mptables too? */ - -} - -static void ati_bugs(void) -{ -#if 1 /* for testing */ - printk("ATI board detected\n"); -#endif - /* No bugs right now */ -} - -struct chipset { - u16 vendor; - void (*f)(void); -}; - -static struct chipset early_qrk[] = { - { PCI_VENDOR_ID_NVIDIA, nvidia_bugs }, - { PCI_VENDOR_ID_VIA, via_bugs }, - { PCI_VENDOR_ID_ATI, ati_bugs }, - {} -}; - -void __init early_quirks(void) -{ - int num, slot, func; - - if (!early_pci_allowed()) - return; - - /* Poor man's PCI discovery */ - for (num = 0; num < 32; num++) { - for (slot = 0; slot < 32; slot++) { - for (func = 0; func < 8; func++) { - u32 class; - u32 vendor; - u8 type; - int i; - class = read_pci_config(num,slot,func, - PCI_CLASS_REVISION); - if (class == 0xffffffff) - break; - - if ((class >> 16) != PCI_CLASS_BRIDGE_PCI) - continue; - - vendor = read_pci_config(num, slot, func, - PCI_VENDOR_ID); - vendor &= 0xffff; - - for (i = 0; early_qrk[i].f; i++) - if (early_qrk[i].vendor == vendor) { - early_qrk[i].f(); - return; - } - - type = read_pci_config_byte(num, slot, func, - PCI_HEADER_TYPE); - if (!(type & 0x80)) - break; - } - } - } -} diff --git a/trunk/arch/x86_64/kernel/early_printk.c b/trunk/arch/x86_64/kernel/early_printk.c index e22ecd54870d..140051e07fa6 100644 --- a/trunk/arch/x86_64/kernel/early_printk.c +++ b/trunk/arch/x86_64/kernel/early_printk.c @@ -215,16 +215,20 @@ void early_printk(const char *fmt, ...) static int __initdata keep_early; -static int __init setup_early_printk(char *buf) +int __init setup_early_printk(char *opt) { - if (!buf) - return 0; + char *space; + char buf[256]; if (early_console_initialized) - return 0; - early_console_initialized = 1; + return 1; + + strlcpy(buf,opt,sizeof(buf)); + space = strchr(buf, ' '); + if (space) + *space = 0; - if (!strcmp(buf,"keep")) + if (strstr(buf,"keep")) keep_early = 1; if (!strncmp(buf, "serial", 6)) { @@ -244,12 +248,11 @@ static int __init setup_early_printk(char *buf) early_console = &simnow_console; keep_early = 1; } + early_console_initialized = 1; register_console(early_console); return 0; } -early_param("earlyprintk", setup_early_printk); - void __init disable_early_printk(void) { if (!early_console_initialized || !early_console) @@ -263,3 +266,4 @@ void __init disable_early_printk(void) } } +__setup("earlyprintk=", setup_early_printk); diff --git a/trunk/arch/x86_64/kernel/entry.S b/trunk/arch/x86_64/kernel/entry.S index b8285cf1a9c3..aa8d8939abc1 100644 --- a/trunk/arch/x86_64/kernel/entry.S +++ b/trunk/arch/x86_64/kernel/entry.S @@ -4,6 +4,8 @@ * Copyright (C) 1991, 1992 Linus Torvalds * Copyright (C) 2000, 2001, 2002 Andi Kleen SuSE Labs * Copyright (C) 2000 Pavel Machek + * + * $Id$ */ /* @@ -20,25 +22,15 @@ * at the top of the kernel process stack. * - partial stack frame: partially saved registers upto R11. * - full stack frame: Like partial stack frame, but all register saved. - * - * Some macro usage: - * - CFI macros are used to generate dwarf2 unwind information for better - * backtraces. They don't change any code. - * - SAVE_ALL/RESTORE_ALL - Save/restore all registers - * - SAVE_ARGS/RESTORE_ARGS - Save/restore registers that C functions modify. - * There are unfortunately lots of special cases where some registers - * not touched. The macro is a big mess that should be cleaned up. - * - SAVE_REST/RESTORE_REST - Handle the registers not saved by SAVE_ARGS. - * Gives a full stack frame. - * - ENTRY/END Define functions in the symbol table. - * - FIXUP_TOP_OF_STACK/RESTORE_TOP_OF_STACK - Fix up the hardware stack - * frame that is otherwise undefined after a SYSCALL - * - TRACE_IRQ_* - Trace hard interrupt state for lock debugging. - * - errorentry/paranoidentry/zeroentry - Define exception entry points. + * + * TODO: + * - schedule it carefully for the final hardware. */ +#define ASSEMBLY 1 #include #include +#include #include #include #include @@ -123,7 +115,6 @@ .macro CFI_DEFAULT_STACK start=1 .if \start CFI_STARTPROC simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,SS+8 .else CFI_DEF_CFA_OFFSET SS+8 @@ -155,10 +146,6 @@ /* rdi: prev */ ENTRY(ret_from_fork) CFI_DEFAULT_STACK - push kernel_eflags(%rip) - CFI_ADJUST_CFA_OFFSET 4 - popf # reset kernel eflags - CFI_ADJUST_CFA_OFFSET -4 call schedule_tail GET_THREAD_INFO(%rcx) testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),threadinfo_flags(%rcx) @@ -212,7 +199,6 @@ END(ret_from_fork) ENTRY(system_call) CFI_STARTPROC simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,PDA_STACKOFFSET CFI_REGISTER rip,rcx /*CFI_REGISTER rflags,r11*/ @@ -330,7 +316,6 @@ END(system_call) */ ENTRY(int_ret_from_sys_call) CFI_STARTPROC simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,SS+8-ARGOFFSET /*CFI_REL_OFFSET ss,SS-ARGOFFSET*/ CFI_REL_OFFSET rsp,RSP-ARGOFFSET @@ -491,7 +476,6 @@ END(stub_rt_sigreturn) */ .macro _frame ref CFI_STARTPROC simple - CFI_SIGNAL_FRAME CFI_DEF_CFA rsp,SS+8-\ref /*CFI_REL_OFFSET ss,SS-\ref*/ CFI_REL_OFFSET rsp,RSP-\ref @@ -527,12 +511,7 @@ END(stub_rt_sigreturn) testl $3,CS(%rdi) je 1f swapgs - /* irqcount is used to check if a CPU is already on an interrupt - stack or not. While this is essentially redundant with preempt_count - it is a little cheaper to use a separate counter in the PDA - (short of moving irq_enter into assembly, which would be too - much work) */ -1: incl %gs:pda_irqcount +1: incl %gs:pda_irqcount # RED-PEN should check preempt count cmoveq %gs:pda_irqstackptr,%rsp push %rbp # backlink for old unwinder /* @@ -640,7 +619,8 @@ retint_signal: #ifdef CONFIG_PREEMPT /* Returning to kernel space. Check if we need preemption */ /* rcx: threadinfo. interrupts off. */ -ENTRY(retint_kernel) + .p2align +retint_kernel: cmpl $0,threadinfo_preempt_count(%rcx) jnz retint_restore_args bt $TIF_NEED_RESCHED,threadinfo_flags(%rcx) @@ -699,6 +679,7 @@ ENTRY(call_function_interrupt) END(call_function_interrupt) #endif +#ifdef CONFIG_X86_LOCAL_APIC ENTRY(apic_timer_interrupt) apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt END(apic_timer_interrupt) @@ -710,6 +691,7 @@ END(error_interrupt) ENTRY(spurious_interrupt) apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt END(spurious_interrupt) +#endif /* * Exception entry points. @@ -786,9 +768,7 @@ paranoid_exit\trace: testl $3,CS(%rsp) jnz paranoid_userspace\trace paranoid_swapgs\trace: - .if \trace TRACE_IRQS_IRETQ 0 - .endif swapgs paranoid_restore\trace: RESTORE_ALL 8 @@ -834,7 +814,7 @@ paranoid_schedule\trace: * Exception entry point. This expects an error code/orig_rax on the stack * and the exception handler in %rax. */ -KPROBE_ENTRY(error_entry) +ENTRY(error_entry) _frame RDI /* rdi slot contains rax, oldrax contains error code */ cld @@ -918,7 +898,7 @@ error_kernelspace: cmpq $gs_change,RIP(%rsp) je error_swapgs jmp error_sti -KPROBE_END(error_entry) +END(error_entry) /* Reload gs selector with exception handling */ /* edi: new selector */ @@ -1023,7 +1003,7 @@ ENDPROC(child_rip) * do_sys_execve asm fallback arguments: * rdi: name, rsi: argv, rdx: envp, fake frame on the stack */ -ENTRY(kernel_execve) +ENTRY(execve) CFI_STARTPROC FAKE_STACK_FRAME $0 SAVE_ALL @@ -1036,11 +1016,12 @@ ENTRY(kernel_execve) UNFAKE_STACK_FRAME ret CFI_ENDPROC -ENDPROC(kernel_execve) +ENDPROC(execve) KPROBE_ENTRY(page_fault) errorentry do_page_fault -KPROBE_END(page_fault) +END(page_fault) + .previous .text ENTRY(coprocessor_error) zeroentry do_coprocessor_error @@ -1061,7 +1042,8 @@ KPROBE_ENTRY(debug) CFI_ADJUST_CFA_OFFSET 8 paranoidentry do_debug, DEBUG_STACK paranoidexit -KPROBE_END(debug) +END(debug) + .previous .text /* runs on exception stack */ KPROBE_ENTRY(nmi) @@ -1075,7 +1057,8 @@ KPROBE_ENTRY(nmi) jmp paranoid_exit1 CFI_ENDPROC #endif -KPROBE_END(nmi) +END(nmi) + .previous .text KPROBE_ENTRY(int3) INTR_FRAME @@ -1084,7 +1067,8 @@ KPROBE_ENTRY(int3) paranoidentry do_int3, DEBUG_STACK jmp paranoid_exit1 CFI_ENDPROC -KPROBE_END(int3) +END(int3) + .previous .text ENTRY(overflow) zeroentry do_overflow @@ -1132,7 +1116,8 @@ END(stack_segment) KPROBE_ENTRY(general_protection) errorentry do_general_protection -KPROBE_END(general_protection) +END(general_protection) + .previous .text ENTRY(alignment_check) errorentry do_alignment_check diff --git a/trunk/arch/x86_64/kernel/genapic_cluster.c b/trunk/arch/x86_64/kernel/genapic_cluster.c index cdb90e671b88..3020917546de 100644 --- a/trunk/arch/x86_64/kernel/genapic_cluster.c +++ b/trunk/arch/x86_64/kernel/genapic_cluster.c @@ -118,6 +118,7 @@ struct genapic apic_cluster = { .name = "clustered", .int_delivery_mode = dest_Fixed, .int_dest_mode = (APIC_DEST_PHYSICAL != 0), + .int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_FIXED, .target_cpus = cluster_target_cpus, .apic_id_registered = cluster_apic_id_registered, .init_apic_ldr = cluster_init_apic_ldr, diff --git a/trunk/arch/x86_64/kernel/genapic_flat.c b/trunk/arch/x86_64/kernel/genapic_flat.c index 50ad153eaac4..eb86d374813a 100644 --- a/trunk/arch/x86_64/kernel/genapic_flat.c +++ b/trunk/arch/x86_64/kernel/genapic_flat.c @@ -49,7 +49,8 @@ static void flat_send_IPI_mask(cpumask_t cpumask, int vector) unsigned long cfg; unsigned long flags; - local_irq_save(flags); + local_save_flags(flags); + local_irq_disable(); /* * Wait for idle. @@ -120,6 +121,7 @@ struct genapic apic_flat = { .name = "flat", .int_delivery_mode = dest_LowestPrio, .int_dest_mode = (APIC_DEST_LOGICAL != 0), + .int_delivery_dest = APIC_DEST_LOGICAL | APIC_DM_LOWEST, .target_cpus = flat_target_cpus, .apic_id_registered = flat_apic_id_registered, .init_apic_ldr = flat_init_apic_ldr, @@ -178,6 +180,7 @@ struct genapic apic_physflat = { .name = "physical flat", .int_delivery_mode = dest_Fixed, .int_dest_mode = (APIC_DEST_PHYSICAL != 0), + .int_delivery_dest = APIC_DEST_PHYSICAL | APIC_DM_FIXED, .target_cpus = physflat_target_cpus, .apic_id_registered = flat_apic_id_registered, .init_apic_ldr = flat_init_apic_ldr,/*not needed, but shouldn't hurt*/ diff --git a/trunk/arch/x86_64/kernel/head.S b/trunk/arch/x86_64/kernel/head.S index 1e6f80870679..c9739ca81d06 100644 --- a/trunk/arch/x86_64/kernel/head.S +++ b/trunk/arch/x86_64/kernel/head.S @@ -5,6 +5,8 @@ * Copyright (C) 2000 Pavel Machek * Copyright (C) 2000 Karsten Keil * Copyright (C) 2001,2002 Andi Kleen + * + * $Id: head.S,v 1.49 2002/03/19 17:39:25 ak Exp $ */ @@ -185,15 +187,12 @@ startup_64: /* Finally jump to run C code and to be on real kernel address * Since we are running on identity-mapped space we have to jump - * to the full 64bit address, this is only possible as indirect - * jump. In addition we need to ensure %cs is set so we make this - * a far return. + * to the full 64bit address , this is only possible as indirect + * jump */ movq initial_code(%rip),%rax - pushq $0 # fake return address to stop unwinder - pushq $__KERNEL_CS # set correct cs - pushq %rax # target address in negative space - lretq + pushq $0 # fake return address + jmp *%rax /* SMP bootup changes these two */ .align 8 @@ -372,7 +371,7 @@ ENTRY(cpu_gdt_table) .quad 0,0 /* TSS */ .quad 0,0 /* LDT */ .quad 0,0,0 /* three TLS descriptors */ - .quad 0x0000f40000000000 /* node/CPU stored in limit */ + .quad 0 /* unused */ gdt_end: /* asm/segment.h:GDT_ENTRIES must match this */ /* This should be a multiple of the cache line size */ diff --git a/trunk/arch/x86_64/kernel/head64.c b/trunk/arch/x86_64/kernel/head64.c index 9561eb3c5b5c..36647ce6aecb 100644 --- a/trunk/arch/x86_64/kernel/head64.c +++ b/trunk/arch/x86_64/kernel/head64.c @@ -45,16 +45,38 @@ static void __init copy_bootdata(char *real_mode_data) new_data = *(int *) (x86_boot_params + NEW_CL_POINTER); if (!new_data) { if (OLD_CL_MAGIC != * (u16 *) OLD_CL_MAGIC_ADDR) { + printk("so old bootloader that it does not support commandline?!\n"); return; } new_data = OLD_CL_BASE_ADDR + * (u16 *) OLD_CL_OFFSET; + printk("old bootloader convention, maybe loadlin?\n"); } command_line = (char *) ((u64)(new_data)); memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); + printk("Bootdata ok (command line is %s)\n", saved_command_line); +} + +static void __init setup_boot_cpu_data(void) +{ + unsigned int dummy, eax; + + /* get vendor info */ + cpuid(0, (unsigned int *)&boot_cpu_data.cpuid_level, + (unsigned int *)&boot_cpu_data.x86_vendor_id[0], + (unsigned int *)&boot_cpu_data.x86_vendor_id[8], + (unsigned int *)&boot_cpu_data.x86_vendor_id[4]); + + /* get cpu type */ + cpuid(1, &eax, &dummy, &dummy, + (unsigned int *) &boot_cpu_data.x86_capability); + boot_cpu_data.x86 = (eax >> 8) & 0xf; + boot_cpu_data.x86_model = (eax >> 4) & 0xf; + boot_cpu_data.x86_mask = eax & 0xf; } void __init x86_64_start_kernel(char * real_mode_data) { + char *s; int i; for (i = 0; i < 256; i++) @@ -62,7 +84,10 @@ void __init x86_64_start_kernel(char * real_mode_data) asm volatile("lidt %0" :: "m" (idt_descr)); clear_bss(); - early_printk("Kernel alive\n"); + /* + * This must be called really, really early: + */ + lockdep_init(); /* * switch to init_level4_pgt from boot_level4_pgt @@ -78,5 +103,22 @@ void __init x86_64_start_kernel(char * real_mode_data) #ifdef CONFIG_SMP cpu_set(0, cpu_online_map); #endif + s = strstr(saved_command_line, "earlyprintk="); + if (s != NULL) + setup_early_printk(strchr(s, '=') + 1); +#ifdef CONFIG_NUMA + s = strstr(saved_command_line, "numa="); + if (s != NULL) + numa_setup(s+5); +#endif +#ifdef CONFIG_X86_IO_APIC + if (strstr(saved_command_line, "disableapic")) + disable_apic = 1; +#endif + /* You need early console to see that */ + if (__pa_symbol(&_end) >= KERNEL_TEXT_SIZE) + panic("Kernel too big for kernel mapping\n"); + + setup_boot_cpu_data(); start_kernel(); } diff --git a/trunk/arch/x86_64/kernel/i8259.c b/trunk/arch/x86_64/kernel/i8259.c index 2dd51f364ea2..0434b1f8e3dd 100644 --- a/trunk/arch/x86_64/kernel/i8259.c +++ b/trunk/arch/x86_64/kernel/i8259.c @@ -55,6 +55,7 @@ */ BUILD_16_IRQS(0x0) +#ifdef CONFIG_X86_LOCAL_APIC /* * The IO-APIC gives us many more interrupt sources. Most of these * are unused but an SMP system is supposed to have enough memory ... @@ -74,6 +75,8 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) BUILD_15_IRQS(0xe) #endif +#endif + #undef BUILD_16_IRQS #undef BUILD_15_IRQS #undef BI @@ -97,6 +100,7 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) void (*interrupt[NR_IRQS])(void) = { IRQLIST_16(0x0), +#ifdef CONFIG_X86_IO_APIC IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3), IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7), IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb), @@ -106,6 +110,7 @@ void (*interrupt[NR_IRQS])(void) = { , IRQLIST_15(0xe) #endif +#endif }; #undef IRQ @@ -123,8 +128,6 @@ void (*interrupt[NR_IRQS])(void) = { DEFINE_SPINLOCK(i8259A_lock); -static int i8259A_auto_eoi; - static void end_8259A_irq (unsigned int irq) { if (irq > 256) { @@ -338,8 +341,6 @@ void init_8259A(int auto_eoi) { unsigned long flags; - i8259A_auto_eoi = auto_eoi; - spin_lock_irqsave(&i8259A_lock, flags); outb(0xff, 0x21); /* mask all of 8259A-1 */ @@ -398,7 +399,7 @@ static void save_ELCR(char *trigger) static int i8259A_resume(struct sys_device *dev) { - init_8259A(i8259A_auto_eoi); + init_8259A(0); restore_ELCR(irq_trigger); return 0; } @@ -452,7 +453,9 @@ void __init init_ISA_irqs (void) { int i; +#ifdef CONFIG_X86_LOCAL_APIC init_bsp_APIC(); +#endif init_8259A(0); for (i = 0; i < NR_IRQS; i++) { @@ -578,12 +581,14 @@ void __init init_IRQ(void) set_intr_gate(THERMAL_APIC_VECTOR, thermal_interrupt); set_intr_gate(THRESHOLD_APIC_VECTOR, threshold_interrupt); +#ifdef CONFIG_X86_LOCAL_APIC /* self generated IPI for local APIC timer */ set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt); /* IPI vectors for APIC spurious and error interrupts */ set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); set_intr_gate(ERROR_APIC_VECTOR, error_interrupt); +#endif /* * Set the clock to HZ Hz, we already have a valid diff --git a/trunk/arch/x86_64/kernel/io_apic.c b/trunk/arch/x86_64/kernel/io_apic.c index 0491019d4c8d..924a4a332954 100644 --- a/trunk/arch/x86_64/kernel/io_apic.c +++ b/trunk/arch/x86_64/kernel/io_apic.c @@ -48,7 +48,7 @@ int sis_apic_bug; /* not actually supported, dummy for compile */ static int no_timer_check; -static int disable_timer_pin_1 __initdata; +int disable_timer_pin_1 __initdata; int timer_over_8254 __initdata = 0; @@ -111,33 +111,6 @@ int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1}; FINAL; \ } -union entry_union { - struct { u32 w1, w2; }; - struct IO_APIC_route_entry entry; -}; - -static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin) -{ - union entry_union eu; - unsigned long flags; - spin_lock_irqsave(&ioapic_lock, flags); - eu.w1 = io_apic_read(apic, 0x10 + 2 * pin); - eu.w2 = io_apic_read(apic, 0x11 + 2 * pin); - spin_unlock_irqrestore(&ioapic_lock, flags); - return eu.entry; -} - -static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e) -{ - unsigned long flags; - union entry_union eu; - eu.entry = e; - spin_lock_irqsave(&ioapic_lock, flags); - io_apic_write(apic, 0x10 + 2*pin, eu.w1); - io_apic_write(apic, 0x11 + 2*pin, eu.w2); - spin_unlock_irqrestore(&ioapic_lock, flags); -} - #ifdef CONFIG_SMP static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask) { @@ -223,9 +196,13 @@ static void unmask_IO_APIC_irq (unsigned int irq) static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) { struct IO_APIC_route_entry entry; + unsigned long flags; /* Check delivery_mode to be sure we're not clearing an SMI pin */ - entry = ioapic_read_entry(apic, pin); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + *(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); if (entry.delivery_mode == dest_SMI) return; /* @@ -233,7 +210,10 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin) */ memset(&entry, 0, sizeof(entry)); entry.mask = 1; - ioapic_write_entry(apic, pin, entry); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0)); + io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1)); + spin_unlock_irqrestore(&ioapic_lock, flags); } static void clear_IO_APIC (void) @@ -245,6 +225,14 @@ static void clear_IO_APIC (void) clear_IO_APIC_pin(apic, pin); } +/* + * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to + * specific CPU-side IRQs. + */ + +#define MAX_PIRQS 8 +static int pirq_entries [MAX_PIRQS]; +static int pirqs_enabled; int skip_ioapic_setup; int ioapic_force; @@ -253,17 +241,18 @@ int ioapic_force; static int __init disable_ioapic_setup(char *str) { skip_ioapic_setup = 1; - return 0; + return 1; } -early_param("noapic", disable_ioapic_setup); -/* Actually the next is obsolete, but keep it for paranoid reasons -AK */ -static int __init disable_timer_pin_setup(char *arg) +static int __init enable_ioapic_setup(char *str) { - disable_timer_pin_1 = 1; + ioapic_force = 1; + skip_ioapic_setup = 0; return 1; } -__setup("disable_timer_pin_1", disable_timer_pin_setup); + +__setup("noapic", disable_ioapic_setup); +__setup("apic", enable_ioapic_setup); static int __init setup_disable_8254_timer(char *s) { @@ -279,6 +268,135 @@ static int __init setup_enable_8254_timer(char *s) __setup("disable_8254_timer", setup_disable_8254_timer); __setup("enable_8254_timer", setup_enable_8254_timer); +#include +#include +#include + + +#ifdef CONFIG_ACPI + +static int nvidia_hpet_detected __initdata; + +static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) +{ + nvidia_hpet_detected = 1; + return 0; +} +#endif + +/* Temporary Hack. Nvidia and VIA boards currently only work with IO-APIC + off. Check for an Nvidia or VIA PCI bridge and turn it off. + Use pci direct infrastructure because this runs before the PCI subsystem. + + Can be overwritten with "apic" + + And another hack to disable the IOMMU on VIA chipsets. + + ... and others. Really should move this somewhere else. + + Kludge-O-Rama. */ +void __init check_ioapic(void) +{ + int num,slot,func; + /* Poor man's PCI discovery */ + for (num = 0; num < 32; num++) { + for (slot = 0; slot < 32; slot++) { + for (func = 0; func < 8; func++) { + u32 class; + u32 vendor; + u8 type; + class = read_pci_config(num,slot,func, + PCI_CLASS_REVISION); + if (class == 0xffffffff) + break; + + if ((class >> 16) != PCI_CLASS_BRIDGE_PCI) + continue; + + vendor = read_pci_config(num, slot, func, + PCI_VENDOR_ID); + vendor &= 0xffff; + switch (vendor) { + case PCI_VENDOR_ID_VIA: +#ifdef CONFIG_IOMMU + if ((end_pfn > MAX_DMA32_PFN || + force_iommu) && + !iommu_aperture_allowed) { + printk(KERN_INFO + "Looks like a VIA chipset. Disabling IOMMU. Override with \"iommu=allowed\"\n"); + iommu_aperture_disabled = 1; + } +#endif + return; + case PCI_VENDOR_ID_NVIDIA: +#ifdef CONFIG_ACPI + /* + * All timer overrides on Nvidia are + * wrong unless HPET is enabled. + */ + nvidia_hpet_detected = 0; + acpi_table_parse(ACPI_HPET, + nvidia_hpet_check); + if (nvidia_hpet_detected == 0) { + acpi_skip_timer_override = 1; + printk(KERN_INFO "Nvidia board " + "detected. Ignoring ACPI " + "timer override.\n"); + } +#endif + /* RED-PEN skip them on mptables too? */ + return; + + /* This should be actually default, but + for 2.6.16 let's do it for ATI only where + it's really needed. */ + case PCI_VENDOR_ID_ATI: + if (timer_over_8254 == 1) { + timer_over_8254 = 0; + printk(KERN_INFO + "ATI board detected. Disabling timer routing over 8254.\n"); + } + return; + } + + + /* No multi-function device? */ + type = read_pci_config_byte(num,slot,func, + PCI_HEADER_TYPE); + if (!(type & 0x80)) + break; + } + } + } +} + +static int __init ioapic_pirq_setup(char *str) +{ + int i, max; + int ints[MAX_PIRQS+1]; + + get_options(str, ARRAY_SIZE(ints), ints); + + for (i = 0; i < MAX_PIRQS; i++) + pirq_entries[i] = -1; + + pirqs_enabled = 1; + apic_printk(APIC_VERBOSE, "PIRQ redirection, working around broken MP-BIOS.\n"); + max = MAX_PIRQS; + if (ints[0] < MAX_PIRQS) + max = ints[0]; + + for (i = 0; i < max; i++) { + apic_printk(APIC_VERBOSE, "... PIRQ%d -> IRQ %d\n", i, ints[i+1]); + /* + * PIRQs are mapped upside down, usually. + */ + pirq_entries[MAX_PIRQS-i-1] = ints[i+1]; + } + return 1; +} + +__setup("pirq=", ioapic_pirq_setup); /* * Find the IRQ entry number of a certain pin. @@ -307,7 +425,9 @@ static int __init find_isa_irq_pin(int irq, int type) for (i = 0; i < mp_irq_entries; i++) { int lbus = mp_irqs[i].mpc_srcbus; - if (test_bit(lbus, mp_bus_not_pci) && + if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || + mp_bus_id_to_type[lbus] == MP_BUS_EISA || + mp_bus_id_to_type[lbus] == MP_BUS_MCA) && (mp_irqs[i].mpc_irqtype == type) && (mp_irqs[i].mpc_srcbusirq == irq)) @@ -323,7 +443,9 @@ static int __init find_isa_irq_apic(int irq, int type) for (i = 0; i < mp_irq_entries; i++) { int lbus = mp_irqs[i].mpc_srcbus; - if (test_bit(lbus, mp_bus_not_pci) && + if ((mp_bus_id_to_type[lbus] == MP_BUS_ISA || + mp_bus_id_to_type[lbus] == MP_BUS_EISA || + mp_bus_id_to_type[lbus] == MP_BUS_MCA) && (mp_irqs[i].mpc_irqtype == type) && (mp_irqs[i].mpc_srcbusirq == irq)) break; @@ -363,7 +485,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) mp_irqs[i].mpc_dstapic == MP_APIC_ALL) break; - if (!test_bit(lbus, mp_bus_not_pci) && + if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) && !mp_irqs[i].mpc_irqtype && (bus == lbus) && (slot == ((mp_irqs[i].mpc_srcbusirq >> 2) & 0x1f))) { @@ -386,6 +508,27 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) return best_guess; } +/* + * EISA Edge/Level control register, ELCR + */ +static int EISA_ELCR(unsigned int irq) +{ + if (irq < 16) { + unsigned int port = 0x4d0 + (irq >> 3); + return (inb(port) >> (irq & 7)) & 1; + } + apic_printk(APIC_VERBOSE, "Broken MPtable reports ISA irq %d\n", irq); + return 0; +} + +/* EISA interrupts are always polarity zero and can be edge or level + * trigger depending on the ELCR value. If an interrupt is listed as + * EISA conforming in the MP table, that means its trigger type must + * be read in from the ELCR */ + +#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mpc_srcbusirq)) +#define default_EISA_polarity(idx) (0) + /* ISA interrupts are always polarity zero edge triggered, * when listed as conforming in the MP table. */ @@ -398,6 +541,12 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) #define default_PCI_trigger(idx) (1) #define default_PCI_polarity(idx) (1) +/* MCA interrupts are always polarity zero level triggered, + * when listed as conforming in the MP table. */ + +#define default_MCA_trigger(idx) (1) +#define default_MCA_polarity(idx) (0) + static int __init MPBIOS_polarity(int idx) { int bus = mp_irqs[idx].mpc_srcbus; @@ -409,11 +558,38 @@ static int __init MPBIOS_polarity(int idx) switch (mp_irqs[idx].mpc_irqflag & 3) { case 0: /* conforms, ie. bus-type dependent polarity */ - if (test_bit(bus, mp_bus_not_pci)) - polarity = default_ISA_polarity(idx); - else - polarity = default_PCI_polarity(idx); + { + switch (mp_bus_id_to_type[bus]) + { + case MP_BUS_ISA: /* ISA pin */ + { + polarity = default_ISA_polarity(idx); + break; + } + case MP_BUS_EISA: /* EISA pin */ + { + polarity = default_EISA_polarity(idx); + break; + } + case MP_BUS_PCI: /* PCI pin */ + { + polarity = default_PCI_polarity(idx); + break; + } + case MP_BUS_MCA: /* MCA pin */ + { + polarity = default_MCA_polarity(idx); + break; + } + default: + { + printk(KERN_WARNING "broken BIOS!!\n"); + polarity = 1; + break; + } + } break; + } case 1: /* high active */ { polarity = 0; @@ -451,11 +627,38 @@ static int MPBIOS_trigger(int idx) switch ((mp_irqs[idx].mpc_irqflag>>2) & 3) { case 0: /* conforms, ie. bus-type dependent */ - if (test_bit(bus, mp_bus_not_pci)) - trigger = default_ISA_trigger(idx); - else - trigger = default_PCI_trigger(idx); + { + switch (mp_bus_id_to_type[bus]) + { + case MP_BUS_ISA: /* ISA pin */ + { + trigger = default_ISA_trigger(idx); + break; + } + case MP_BUS_EISA: /* EISA pin */ + { + trigger = default_EISA_trigger(idx); + break; + } + case MP_BUS_PCI: /* PCI pin */ + { + trigger = default_PCI_trigger(idx); + break; + } + case MP_BUS_MCA: /* MCA pin */ + { + trigger = default_MCA_trigger(idx); + break; + } + default: + { + printk(KERN_WARNING "broken BIOS!!\n"); + trigger = 1; + break; + } + } break; + } case 1: /* edge */ { trigger = 0; @@ -561,17 +764,49 @@ static int pin_2_irq(int idx, int apic, int pin) if (mp_irqs[idx].mpc_dstirq != pin) printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n"); - if (test_bit(bus, mp_bus_not_pci)) { - irq = mp_irqs[idx].mpc_srcbusirq; - } else { - /* - * PCI IRQs are mapped in order - */ - i = irq = 0; - while (i < apic) - irq += nr_ioapic_registers[i++]; - irq += pin; - irq = gsi_irq_sharing(irq); + switch (mp_bus_id_to_type[bus]) + { + case MP_BUS_ISA: /* ISA pin */ + case MP_BUS_EISA: + case MP_BUS_MCA: + { + irq = mp_irqs[idx].mpc_srcbusirq; + break; + } + case MP_BUS_PCI: /* PCI pin */ + { + /* + * PCI IRQs are mapped in order + */ + i = irq = 0; + while (i < apic) + irq += nr_ioapic_registers[i++]; + irq += pin; + irq = gsi_irq_sharing(irq); + break; + } + default: + { + printk(KERN_ERR "unknown bus type %d.\n",bus); + irq = 0; + break; + } + } + BUG_ON(irq >= NR_IRQS); + + /* + * PCI IRQ command line redirection. Yes, limits are hardcoded. + */ + if ((pin >= 16) && (pin <= 23)) { + if (pirq_entries[pin-16] != -1) { + if (!pirq_entries[pin-16]) { + apic_printk(APIC_VERBOSE, "disabling PIRQ%d\n", pin-16); + } else { + irq = pirq_entries[pin-16]; + apic_printk(APIC_VERBOSE, "using PIRQ%d -> IRQ %d\n", + pin-16, irq); + } + } } BUG_ON(irq >= NR_IRQS); return irq; @@ -708,9 +943,9 @@ static void __init setup_IO_APIC_irqs(void) if (!apic && (irq < 16)) disable_8259A_irq(irq); } - ioapic_write_entry(apic, pin, entry); - spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); + io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0)); set_native_irq_info(irq, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); } @@ -848,7 +1083,10 @@ void __apicdebuginit print_IO_APIC(void) for (i = 0; i <= reg_01.bits.entries; i++) { struct IO_APIC_route_entry entry; - entry = ioapic_read_entry(apic, i); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int *)&entry)+0) = io_apic_read(apic, 0x10+i*2); + *(((int *)&entry)+1) = io_apic_read(apic, 0x11+i*2); + spin_unlock_irqrestore(&ioapic_lock, flags); printk(KERN_DEBUG " %02x %03X %02X ", i, @@ -1043,6 +1281,9 @@ static void __init enable_IO_APIC(void) irq_2_pin[i].pin = -1; irq_2_pin[i].next = 0; } + if (!pirqs_enabled) + for (i = 0; i < MAX_PIRQS; i++) + pirq_entries[i] = -1; /* * The number of IO-APIC IRQ registers (== #pins): @@ -1058,7 +1299,11 @@ static void __init enable_IO_APIC(void) /* See if any of the pins is in ExtINT mode */ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { struct IO_APIC_route_entry entry; - entry = ioapic_read_entry(apic, pin); + spin_lock_irqsave(&ioapic_lock, flags); + *(((int *)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin); + *(((int *)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin); + spin_unlock_irqrestore(&ioapic_lock, flags); + /* If the interrupt line is enabled and in ExtInt mode * I have found the pin where the i8259 is connected. @@ -1110,6 +1355,7 @@ void disable_IO_APIC(void) */ if (ioapic_i8259.pin != -1) { struct IO_APIC_route_entry entry; + unsigned long flags; memset(&entry, 0, sizeof(entry)); entry.mask = 0; /* Enabled */ @@ -1126,12 +1372,83 @@ void disable_IO_APIC(void) /* * Add it to the IO-APIC irq-routing table: */ - ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry); + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(ioapic_i8259.apic, 0x11+2*ioapic_i8259.pin, + *(((int *)&entry)+1)); + io_apic_write(ioapic_i8259.apic, 0x10+2*ioapic_i8259.pin, + *(((int *)&entry)+0)); + spin_unlock_irqrestore(&ioapic_lock, flags); } disconnect_bsp_APIC(ioapic_i8259.pin != -1); } +/* + * function to set the IO-APIC physical IDs based on the + * values stored in the MPC table. + * + * by Matt Domsch Tue Dec 21 12:25:05 CST 1999 + */ + +static void __init setup_ioapic_ids_from_mpc (void) +{ + union IO_APIC_reg_00 reg_00; + int apic; + int i; + unsigned char old_id; + unsigned long flags; + + /* + * Set the IOAPIC ID to the value stored in the MPC table. + */ + for (apic = 0; apic < nr_ioapics; apic++) { + + /* Read the register 0 value */ + spin_lock_irqsave(&ioapic_lock, flags); + reg_00.raw = io_apic_read(apic, 0); + spin_unlock_irqrestore(&ioapic_lock, flags); + + old_id = mp_ioapics[apic].mpc_apicid; + + + printk(KERN_INFO "Using IO-APIC %d\n", mp_ioapics[apic].mpc_apicid); + + + /* + * We need to adjust the IRQ routing table + * if the ID changed. + */ + if (old_id != mp_ioapics[apic].mpc_apicid) + for (i = 0; i < mp_irq_entries; i++) + if (mp_irqs[i].mpc_dstapic == old_id) + mp_irqs[i].mpc_dstapic + = mp_ioapics[apic].mpc_apicid; + + /* + * Read the right value from the MPC table and + * write it into the ID register. + */ + apic_printk(APIC_VERBOSE,KERN_INFO "...changing IO-APIC physical APIC ID to %d ...", + mp_ioapics[apic].mpc_apicid); + + reg_00.bits.ID = mp_ioapics[apic].mpc_apicid; + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apic, 0, reg_00.raw); + spin_unlock_irqrestore(&ioapic_lock, flags); + + /* + * Sanity check + */ + spin_lock_irqsave(&ioapic_lock, flags); + reg_00.raw = io_apic_read(apic, 0); + spin_unlock_irqrestore(&ioapic_lock, flags); + if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid) + printk("could not set ID!\n"); + else + apic_printk(APIC_VERBOSE," ok.\n"); + } +} + /* * There is a nasty bug in some older SMP boards, their mptable lies * about the timer IRQ. We do the following to work around the situation: @@ -1647,6 +1964,11 @@ void __init setup_IO_APIC(void) apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n"); + /* + * Set up the IO-APIC IRQ routing table. + */ + if (!acpi_ioapic) + setup_ioapic_ids_from_mpc(); sync_Arb_IDs(); setup_IO_APIC_irqs(); init_IO_APIC_traps(); @@ -1665,12 +1987,17 @@ static int ioapic_suspend(struct sys_device *dev, pm_message_t state) { struct IO_APIC_route_entry *entry; struct sysfs_ioapic_data *data; + unsigned long flags; int i; data = container_of(dev, struct sysfs_ioapic_data, dev); entry = data->entry; - for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) - *entry = ioapic_read_entry(dev->id, i); + spin_lock_irqsave(&ioapic_lock, flags); + for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { + *(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i); + *(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i); + } + spin_unlock_irqrestore(&ioapic_lock, flags); return 0; } @@ -1692,9 +2019,11 @@ static int ioapic_resume(struct sys_device *dev) reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid; io_apic_write(dev->id, 0, reg_00.raw); } + for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) { + io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1)); + io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0)); + } spin_unlock_irqrestore(&ioapic_lock, flags); - for (i = 0; i < nr_ioapic_registers[dev->id]; i++) - ioapic_write_entry(dev->id, i, entry[i]); return 0; } @@ -1748,6 +2077,19 @@ device_initcall(ioapic_init_sysfs); #define IO_APIC_MAX_ID 0xFE +int __init io_apic_get_version (int ioapic) +{ + union IO_APIC_reg_01 reg_01; + unsigned long flags; + + spin_lock_irqsave(&ioapic_lock, flags); + reg_01.raw = io_apic_read(ioapic, 1); + spin_unlock_irqrestore(&ioapic_lock, flags); + + return reg_01.bits.version; +} + + int __init io_apic_get_redir_entries (int ioapic) { union IO_APIC_reg_01 reg_01; @@ -1806,10 +2148,10 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p if (!ioapic && (irq < 16)) disable_8259A_irq(irq); - ioapic_write_entry(ioapic, pin, entry); - spin_lock_irqsave(&ioapic_lock, flags); - set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); + io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); + io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0)); + set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); spin_unlock_irqrestore(&ioapic_lock, flags); return 0; diff --git a/trunk/arch/x86_64/kernel/ioport.c b/trunk/arch/x86_64/kernel/ioport.c index fe063d3cfe42..b81614970ecc 100644 --- a/trunk/arch/x86_64/kernel/ioport.c +++ b/trunk/arch/x86_64/kernel/ioport.c @@ -56,7 +56,6 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) memset(bitmap, 0xff, IO_BITMAP_BYTES); t->io_bitmap_ptr = bitmap; - set_thread_flag(TIF_IO_BITMAP); } /* diff --git a/trunk/arch/x86_64/kernel/irq.c b/trunk/arch/x86_64/kernel/irq.c index b3677e6ccc6e..5221a53e90c1 100644 --- a/trunk/arch/x86_64/kernel/irq.c +++ b/trunk/arch/x86_64/kernel/irq.c @@ -20,6 +20,11 @@ #include atomic_t irq_err_count; +#ifdef CONFIG_X86_IO_APIC +#ifdef APIC_MISMATCH_DEBUG +atomic_t irq_mis_count; +#endif +#endif #ifdef CONFIG_DEBUG_STACKOVERFLOW /* @@ -87,11 +92,18 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count); seq_putc(p, '\n'); +#ifdef CONFIG_X86_LOCAL_APIC seq_printf(p, "LOC: "); for_each_online_cpu(j) seq_printf(p, "%10u ", cpu_pda(j)->apic_timer_irqs); seq_putc(p, '\n'); +#endif seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count)); +#ifdef CONFIG_X86_IO_APIC +#ifdef APIC_MISMATCH_DEBUG + seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count)); +#endif +#endif } return 0; } diff --git a/trunk/arch/x86_64/kernel/kprobes.c b/trunk/arch/x86_64/kernel/kprobes.c index ac241567e682..ffc73ac72485 100644 --- a/trunk/arch/x86_64/kernel/kprobes.c +++ b/trunk/arch/x86_64/kernel/kprobes.c @@ -270,19 +270,20 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) { unsigned long *sara = (unsigned long *)regs->rsp; - struct kretprobe_instance *ri; + struct kretprobe_instance *ri; - if ((ri = get_free_rp_inst(rp)) != NULL) { - ri->rp = rp; - ri->task = current; + if ((ri = get_free_rp_inst(rp)) != NULL) { + ri->rp = rp; + ri->task = current; ri->ret_addr = (kprobe_opcode_t *) *sara; /* Replace the return addr with trampoline addr */ *sara = (unsigned long) &kretprobe_trampoline; - add_rp_inst(ri); - } else { - rp->nmissed++; - } + + add_rp_inst(ri); + } else { + rp->nmissed++; + } } int __kprobes kprobe_handler(struct pt_regs *regs) @@ -404,15 +405,14 @@ int __kprobes kprobe_handler(struct pt_regs *regs) */ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) { - struct kretprobe_instance *ri = NULL; - struct hlist_head *head, empty_rp; - struct hlist_node *node, *tmp; + struct kretprobe_instance *ri = NULL; + struct hlist_head *head; + struct hlist_node *node, *tmp; unsigned long flags, orig_ret_address = 0; unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; - INIT_HLIST_HEAD(&empty_rp); spin_lock_irqsave(&kretprobe_lock, flags); - head = kretprobe_inst_table_head(current); + head = kretprobe_inst_table_head(current); /* * It is possible to have multiple instances associated with a given @@ -423,20 +423,20 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) * We can handle this because: * - instances are always inserted at the head of the list * - when multiple return probes are registered for the same - * function, the first instance's ret_addr will point to the + * function, the first instance's ret_addr will point to the * real return address, and all the rest will point to * kretprobe_trampoline */ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { - if (ri->task != current) + if (ri->task != current) /* another task is sharing our hash bucket */ - continue; + continue; if (ri->rp && ri->rp->handler) ri->rp->handler(ri, regs); orig_ret_address = (unsigned long)ri->ret_addr; - recycle_rp_inst(ri, &empty_rp); + recycle_rp_inst(ri); if (orig_ret_address != trampoline_address) /* @@ -454,16 +454,12 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) spin_unlock_irqrestore(&kretprobe_lock, flags); preempt_enable_no_resched(); - hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { - hlist_del(&ri->hlist); - kfree(ri); - } - /* - * By returning a non-zero value, we are telling - * kprobe_handler() that we don't want the post_handler + /* + * By returning a non-zero value, we are telling + * kprobe_handler() that we don't want the post_handler * to run (and have re-enabled preemption) - */ - return 1; + */ + return 1; } /* diff --git a/trunk/arch/x86_64/kernel/machine_kexec.c b/trunk/arch/x86_64/kernel/machine_kexec.c index 0497e3bd5bff..106076b370fc 100644 --- a/trunk/arch/x86_64/kernel/machine_kexec.c +++ b/trunk/arch/x86_64/kernel/machine_kexec.c @@ -15,15 +15,6 @@ #include #include -#define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) -static u64 kexec_pgd[512] PAGE_ALIGNED; -static u64 kexec_pud0[512] PAGE_ALIGNED; -static u64 kexec_pmd0[512] PAGE_ALIGNED; -static u64 kexec_pte0[512] PAGE_ALIGNED; -static u64 kexec_pud1[512] PAGE_ALIGNED; -static u64 kexec_pmd1[512] PAGE_ALIGNED; -static u64 kexec_pte1[512] PAGE_ALIGNED; - static void init_level2_page(pmd_t *level2p, unsigned long addr) { unsigned long end_addr; @@ -153,19 +144,32 @@ static void load_segments(void) ); } +typedef NORET_TYPE void (*relocate_new_kernel_t)(unsigned long indirection_page, + unsigned long control_code_buffer, + unsigned long start_address, + unsigned long pgtable) ATTRIB_NORET; + +extern const unsigned char relocate_new_kernel[]; +extern const unsigned long relocate_new_kernel_size; + int machine_kexec_prepare(struct kimage *image) { - unsigned long start_pgtable; + unsigned long start_pgtable, control_code_buffer; int result; /* Calculate the offsets */ start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; + control_code_buffer = start_pgtable + PAGE_SIZE; /* Setup the identity mapped 64bit page table */ result = init_pgtable(image, start_pgtable); if (result) return result; + /* Place the code in the reboot code buffer */ + memcpy(__va(control_code_buffer), relocate_new_kernel, + relocate_new_kernel_size); + return 0; } @@ -180,34 +184,28 @@ void machine_kexec_cleanup(struct kimage *image) */ NORET_TYPE void machine_kexec(struct kimage *image) { - unsigned long page_list[PAGES_NR]; - void *control_page; + unsigned long page_list; + unsigned long control_code_buffer; + unsigned long start_pgtable; + relocate_new_kernel_t rnk; /* Interrupts aren't acceptable while we reboot */ local_irq_disable(); - control_page = page_address(image->control_code_page) + PAGE_SIZE; - memcpy(control_page, relocate_kernel, PAGE_SIZE); - - page_list[PA_CONTROL_PAGE] = __pa(control_page); - page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel; - page_list[PA_PGD] = __pa(kexec_pgd); - page_list[VA_PGD] = (unsigned long)kexec_pgd; - page_list[PA_PUD_0] = __pa(kexec_pud0); - page_list[VA_PUD_0] = (unsigned long)kexec_pud0; - page_list[PA_PMD_0] = __pa(kexec_pmd0); - page_list[VA_PMD_0] = (unsigned long)kexec_pmd0; - page_list[PA_PTE_0] = __pa(kexec_pte0); - page_list[VA_PTE_0] = (unsigned long)kexec_pte0; - page_list[PA_PUD_1] = __pa(kexec_pud1); - page_list[VA_PUD_1] = (unsigned long)kexec_pud1; - page_list[PA_PMD_1] = __pa(kexec_pmd1); - page_list[VA_PMD_1] = (unsigned long)kexec_pmd1; - page_list[PA_PTE_1] = __pa(kexec_pte1); - page_list[VA_PTE_1] = (unsigned long)kexec_pte1; - - page_list[PA_TABLE_PAGE] = - (unsigned long)__pa(page_address(image->control_code_page)); + /* Calculate the offsets */ + page_list = image->head; + start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT; + control_code_buffer = start_pgtable + PAGE_SIZE; + + /* Set the low half of the page table to my identity mapped + * page table for kexec. Leave the high half pointing at the + * kernel pages. Don't bother to flush the global pages + * as that will happen when I fully switch to my identity mapped + * page table anyway. + */ + memcpy(__va(read_cr3()), __va(start_pgtable), PAGE_SIZE/2); + __flush_tlb(); + /* The segment registers are funny things, they have both a * visible and an invisible part. Whenever the visible part is @@ -224,36 +222,7 @@ NORET_TYPE void machine_kexec(struct kimage *image) */ set_gdt(phys_to_virt(0),0); set_idt(phys_to_virt(0),0); - /* now call it */ - relocate_kernel((unsigned long)image->head, (unsigned long)page_list, - image->start); + rnk = (relocate_new_kernel_t) control_code_buffer; + (*rnk)(page_list, control_code_buffer, image->start, start_pgtable); } - -/* crashkernel=size@addr specifies the location to reserve for - * a crash kernel. By reserving this memory we guarantee - * that linux never set's it up as a DMA target. - * Useful for holding code to do something appropriate - * after a kernel panic. - */ -static int __init setup_crashkernel(char *arg) -{ - unsigned long size, base; - char *p; - if (!arg) - return -EINVAL; - size = memparse(arg, &p); - if (arg == p) - return -EINVAL; - if (*p == '@') { - base = memparse(p+1, &p); - /* FIXME: Do I want a sanity check to validate the - * memory range? Yes you do, but it's too early for - * e820 -AK */ - crashk_res.start = base; - crashk_res.end = base + size - 1; - } - return 0; -} -early_param("crashkernel", setup_crashkernel); - diff --git a/trunk/arch/x86_64/kernel/mce.c b/trunk/arch/x86_64/kernel/mce.c index bbea88801d88..4e017fb30fb3 100644 --- a/trunk/arch/x86_64/kernel/mce.c +++ b/trunk/arch/x86_64/kernel/mce.c @@ -182,7 +182,7 @@ void do_machine_check(struct pt_regs * regs, long error_code) goto out2; memset(&m, 0, sizeof(struct mce)); - m.cpu = smp_processor_id(); + m.cpu = safe_smp_processor_id(); rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus); if (!(m.mcgstatus & MCG_STATUS_RIPV)) kill_it = 1; @@ -274,33 +274,6 @@ void do_machine_check(struct pt_regs * regs, long error_code) atomic_dec(&mce_entry); } -#ifdef CONFIG_X86_MCE_INTEL -/*** - * mce_log_therm_throt_event - Logs the thermal throttling event to mcelog - * @cpu: The CPU on which the event occured. - * @status: Event status information - * - * This function should be called by the thermal interrupt after the - * event has been processed and the decision was made to log the event - * further. - * - * The status parameter will be saved to the 'status' field of 'struct mce' - * and historically has been the register value of the - * MSR_IA32_THERMAL_STATUS (Intel) msr. - */ -void mce_log_therm_throt_event(unsigned int cpu, __u64 status) -{ - struct mce m; - - memset(&m, 0, sizeof(m)); - m.cpu = cpu; - m.bank = MCE_THERMAL_BANK; - m.status = status; - rdtscll(m.tsc); - mce_log(&m); -} -#endif /* CONFIG_X86_MCE_INTEL */ - /* * Periodic polling timer for "silent" machine check errors. */ diff --git a/trunk/arch/x86_64/kernel/mce_intel.c b/trunk/arch/x86_64/kernel/mce_intel.c index 6551505d8a2c..8f533d2c40cb 100644 --- a/trunk/arch/x86_64/kernel/mce_intel.c +++ b/trunk/arch/x86_64/kernel/mce_intel.c @@ -11,21 +11,36 @@ #include #include #include -#include + +static DEFINE_PER_CPU(unsigned long, next_check); asmlinkage void smp_thermal_interrupt(void) { - __u64 msr_val; + struct mce m; ack_APIC_irq(); exit_idle(); irq_enter(); + if (time_before(jiffies, __get_cpu_var(next_check))) + goto done; + + __get_cpu_var(next_check) = jiffies + HZ*300; + memset(&m, 0, sizeof(m)); + m.cpu = smp_processor_id(); + m.bank = MCE_THERMAL_BANK; + rdtscll(m.tsc); + rdmsrl(MSR_IA32_THERM_STATUS, m.status); + if (m.status & 0x1) { + printk(KERN_EMERG + "CPU%d: Temperature above threshold, cpu clock throttled\n", m.cpu); + add_taint(TAINT_MACHINE_CHECK); + } else { + printk(KERN_EMERG "CPU%d: Temperature/speed normal\n", m.cpu); + } - rdmsrl(MSR_IA32_THERM_STATUS, msr_val); - if (therm_throt_process(msr_val & 1)) - mce_log_therm_throt_event(smp_processor_id(), msr_val); - + mce_log(&m); +done: irq_exit(); } @@ -77,9 +92,6 @@ static void __cpuinit intel_init_thermal(struct cpuinfo_x86 *c) apic_write(APIC_LVTTHMR, l & ~APIC_LVT_MASKED); printk(KERN_INFO "CPU%d: Thermal monitoring enabled (%s)\n", cpu, tm2 ? "TM2" : "TM1"); - - /* enable thermal throttle processing */ - atomic_set(&therm_throt_en, 1); return; } diff --git a/trunk/arch/x86_64/kernel/mpparse.c b/trunk/arch/x86_64/kernel/mpparse.c index b8d53dfa9931..a1ab4197f8a1 100644 --- a/trunk/arch/x86_64/kernel/mpparse.c +++ b/trunk/arch/x86_64/kernel/mpparse.c @@ -41,7 +41,8 @@ int acpi_found_madt; * Various Linux-internal data structures created from the * MP-table. */ -DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES); +unsigned char apic_version [MAX_APICS]; +unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 }; static int mp_current_pci_id = 0; @@ -55,6 +56,7 @@ struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; int mp_irq_entries; int nr_ioapics; +int pic_mode; unsigned long mp_lapic_addr = 0; @@ -69,6 +71,19 @@ unsigned disabled_cpus __initdata; /* Bitmask of physically existing CPUs */ physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE; +/* ACPI MADT entry parsing functions */ +#ifdef CONFIG_ACPI +extern struct acpi_boot_flags acpi_boot; +#ifdef CONFIG_X86_LOCAL_APIC +extern int acpi_parse_lapic (acpi_table_entry_header *header); +extern int acpi_parse_lapic_addr_ovr (acpi_table_entry_header *header); +extern int acpi_parse_lapic_nmi (acpi_table_entry_header *header); +#endif /*CONFIG_X86_LOCAL_APIC*/ +#ifdef CONFIG_X86_IO_APIC +extern int acpi_parse_ioapic (acpi_table_entry_header *header); +#endif /*CONFIG_X86_IO_APIC*/ +#endif /*CONFIG_ACPI*/ + u8 bios_cpu_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; @@ -93,20 +108,24 @@ static int __init mpf_checksum(unsigned char *mp, int len) static void __cpuinit MP_processor_info (struct mpc_config_processor *m) { int cpu; + unsigned char ver; cpumask_t tmp_map; - char *bootup_cpu = ""; if (!(m->mpc_cpuflag & CPU_ENABLED)) { disabled_cpus++; return; } + + printk(KERN_INFO "Processor #%d %d:%d APIC version %d\n", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK)>>8, + (m->mpc_cpufeature & CPU_MODEL_MASK)>>4, + m->mpc_apicver); + if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { - bootup_cpu = " (Bootup-CPU)"; + Dprintk(" Bootup CPU\n"); boot_cpu_id = m->mpc_apicid; } - - printk(KERN_INFO "Processor #%d%s\n", m->mpc_apicid, bootup_cpu); - if (num_processors >= NR_CPUS) { printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached." " Processor ignored.\n", NR_CPUS); @@ -117,7 +136,24 @@ static void __cpuinit MP_processor_info (struct mpc_config_processor *m) cpus_complement(tmp_map, cpu_present_map); cpu = first_cpu(tmp_map); +#if MAX_APICS < 255 + if ((int)m->mpc_apicid > MAX_APICS) { + printk(KERN_ERR "Processor #%d INVALID. (Max ID: %d).\n", + m->mpc_apicid, MAX_APICS); + return; + } +#endif + ver = m->mpc_apicver; + physid_set(m->mpc_apicid, phys_cpu_present_map); + /* + * Validate version + */ + if (ver == 0x0) { + printk(KERN_ERR "BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid); + ver = 0x10; + } + apic_version[m->mpc_apicid] = ver; if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { /* * bios_cpu_apicid is required to have processors listed @@ -142,42 +178,37 @@ static void __init MP_bus_info (struct mpc_config_bus *m) Dprintk("Bus #%d is %s\n", m->mpc_busid, str); if (strncmp(str, "ISA", 3) == 0) { - set_bit(m->mpc_busid, mp_bus_not_pci); + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; + } else if (strncmp(str, "EISA", 4) == 0) { + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA; } else if (strncmp(str, "PCI", 3) == 0) { - clear_bit(m->mpc_busid, mp_bus_not_pci); + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI; mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id; mp_current_pci_id++; + } else if (strncmp(str, "MCA", 3) == 0) { + mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA; } else { printk(KERN_ERR "Unknown bustype %s\n", str); } } -static int bad_ioapic(unsigned long address) -{ - if (nr_ioapics >= MAX_IO_APICS) { - printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " - "(found %d)\n", MAX_IO_APICS, nr_ioapics); - panic("Recompile kernel with bigger MAX_IO_APICS!\n"); - } - if (!address) { - printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" - " found in table, skipping!\n"); - return 1; - } - return 0; -} - static void __init MP_ioapic_info (struct mpc_config_ioapic *m) { if (!(m->mpc_flags & MPC_APIC_USABLE)) return; - printk("I/O APIC #%d at 0x%X.\n", - m->mpc_apicid, m->mpc_apicaddr); - - if (bad_ioapic(m->mpc_apicaddr)) + printk("I/O APIC #%d Version %d at 0x%X.\n", + m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr); + if (nr_ioapics >= MAX_IO_APICS) { + printk(KERN_ERR "Max # of I/O APICs (%d) exceeded (found %d).\n", + MAX_IO_APICS, nr_ioapics); + panic("Recompile kernel with bigger MAX_IO_APICS!.\n"); + } + if (!m->mpc_apicaddr) { + printk(KERN_ERR "WARNING: bogus zero I/O APIC address" + " found in MP table, skipping!\n"); return; - + } mp_ioapics[nr_ioapics] = *m; nr_ioapics++; } @@ -201,6 +232,19 @@ static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m) m->mpc_irqtype, m->mpc_irqflag & 3, (m->mpc_irqflag >> 2) &3, m->mpc_srcbusid, m->mpc_srcbusirq, m->mpc_destapic, m->mpc_destapiclint); + /* + * Well it seems all SMP boards in existence + * use ExtINT/LVT1 == LINT0 and + * NMI/LVT2 == LINT1 - the following check + * will show us if this assumptions is false. + * Until then we do not have to add baggage. + */ + if ((m->mpc_irqtype == mp_ExtINT) && + (m->mpc_destapiclint != 0)) + BUG(); + if ((m->mpc_irqtype == mp_NMI) && + (m->mpc_destapiclint != 1)) + BUG(); } /* @@ -214,7 +258,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) unsigned char *mpt=((unsigned char *)mpc)+count; if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) { - printk("MPTABLE: bad signature [%c%c%c%c]!\n", + printk("SMP mptable: bad signature [%c%c%c%c]!\n", mpc->mpc_signature[0], mpc->mpc_signature[1], mpc->mpc_signature[2], @@ -222,31 +266,31 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) return 0; } if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) { - printk("MPTABLE: checksum error!\n"); + printk("SMP mptable: checksum error!\n"); return 0; } if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) { - printk(KERN_ERR "MPTABLE: bad table version (%d)!!\n", + printk(KERN_ERR "SMP mptable: bad table version (%d)!!\n", mpc->mpc_spec); return 0; } if (!mpc->mpc_lapic) { - printk(KERN_ERR "MPTABLE: null local APIC address!\n"); + printk(KERN_ERR "SMP mptable: null local APIC address!\n"); return 0; } memcpy(str,mpc->mpc_oem,8); - str[8] = 0; - printk(KERN_INFO "MPTABLE: OEM ID: %s ",str); + str[8]=0; + printk(KERN_INFO "OEM ID: %s ",str); memcpy(str,mpc->mpc_productid,12); - str[12] = 0; - printk("MPTABLE: Product ID: %s ",str); + str[12]=0; + printk("Product ID: %s ",str); - printk("MPTABLE: APIC at: 0x%X\n",mpc->mpc_lapic); + printk("APIC at: 0x%X\n",mpc->mpc_lapic); /* save the local APIC address, it might be non-default */ if (!acpi_lapic) - mp_lapic_addr = mpc->mpc_lapic; + mp_lapic_addr = mpc->mpc_lapic; /* * Now process the configuration blocks. @@ -258,7 +302,7 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) struct mpc_config_processor *m= (struct mpc_config_processor *)mpt; if (!acpi_lapic) - MP_processor_info(m); + MP_processor_info(m); mpt += sizeof(*m); count += sizeof(*m); break; @@ -277,8 +321,8 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) struct mpc_config_ioapic *m= (struct mpc_config_ioapic *)mpt; MP_ioapic_info(m); - mpt += sizeof(*m); - count += sizeof(*m); + mpt+=sizeof(*m); + count+=sizeof(*m); break; } case MP_INTSRC: @@ -287,8 +331,8 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) (struct mpc_config_intsrc *)mpt; MP_intsrc_info(m); - mpt += sizeof(*m); - count += sizeof(*m); + mpt+=sizeof(*m); + count+=sizeof(*m); break; } case MP_LINTSRC: @@ -296,15 +340,15 @@ static int __init smp_read_mpc(struct mp_config_table *mpc) struct mpc_config_lintsrc *m= (struct mpc_config_lintsrc *)mpt; MP_lintsrc_info(m); - mpt += sizeof(*m); - count += sizeof(*m); + mpt+=sizeof(*m); + count+=sizeof(*m); break; } } } clustered_apic_check(); if (!num_processors) - printk(KERN_ERR "MPTABLE: no processors registered!\n"); + printk(KERN_ERR "SMP mptable: no processors registered!\n"); return num_processors; } @@ -400,10 +444,13 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) * 2 CPUs, numbered 0 & 1. */ processor.mpc_type = MP_PROCESSOR; - processor.mpc_apicver = 0; + /* Either an integrated APIC or a discrete 82489DX. */ + processor.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01; processor.mpc_cpuflag = CPU_ENABLED; - processor.mpc_cpufeature = 0; - processor.mpc_featureflag = 0; + processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | + (boot_cpu_data.x86_model << 4) | + boot_cpu_data.x86_mask; + processor.mpc_featureflag = boot_cpu_data.x86_capability[0]; processor.mpc_reserved[0] = 0; processor.mpc_reserved[1] = 0; for (i = 0; i < 2; i++) { @@ -422,6 +469,14 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) case 5: memcpy(bus.mpc_bustype, "ISA ", 6); break; + case 2: + case 6: + case 3: + memcpy(bus.mpc_bustype, "EISA ", 6); + break; + case 4: + case 7: + memcpy(bus.mpc_bustype, "MCA ", 6); } MP_bus_info(&bus); if (mpc_default_type > 4) { @@ -432,7 +487,7 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type) ioapic.mpc_type = MP_IOAPIC; ioapic.mpc_apicid = 2; - ioapic.mpc_apicver = 0; + ioapic.mpc_apicver = mpc_default_type > 4 ? 0x10 : 0x01; ioapic.mpc_flags = MPC_APIC_USABLE; ioapic.mpc_apicaddr = 0xFEC00000; MP_ioapic_info(&ioapic); @@ -475,6 +530,13 @@ void __init get_smp_config (void) printk(KERN_INFO "Using ACPI for processor (LAPIC) configuration information\n"); printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification); + if (mpf->mpf_feature2 & (1<<7)) { + printk(KERN_INFO " IMCR and PIC compatibility mode.\n"); + pic_mode = 1; + } else { + printk(KERN_INFO " Virtual Wire compatibility mode.\n"); + pic_mode = 0; + } /* * Now see if we need to read further. @@ -554,7 +616,7 @@ static int __init smp_scan_config (unsigned long base, unsigned long length) return 0; } -void __init find_smp_config(void) +void __init find_intel_smp (void) { unsigned int address; @@ -571,7 +633,9 @@ void __init find_smp_config(void) smp_scan_config(0xF0000,0x10000)) return; /* - * If it is an SMP machine we should know now. + * If it is an SMP machine we should know now, unless the + * configuration is in an EISA/MCA bus machine with an + * extended bios data area. * * there is a real-mode segmented pointer pointing to the * 4K EBDA area at 0x40E, calculate and scan it here. @@ -592,41 +656,69 @@ void __init find_smp_config(void) printk(KERN_INFO "No mptable found.\n"); } +/* + * - Intel MP Configuration Table + */ +void __init find_smp_config (void) +{ +#ifdef CONFIG_X86_LOCAL_APIC + find_intel_smp(); +#endif +} + + /* -------------------------------------------------------------------------- ACPI-based MP Configuration -------------------------------------------------------------------------- */ #ifdef CONFIG_ACPI -void __init mp_register_lapic_address(u64 address) +void __init mp_register_lapic_address ( + u64 address) { mp_lapic_addr = (unsigned long) address; + set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr); + if (boot_cpu_id == -1U) boot_cpu_id = GET_APIC_ID(apic_read(APIC_ID)); + + Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid); } -void __cpuinit mp_register_lapic (u8 id, u8 enabled) + +void __cpuinit mp_register_lapic ( + u8 id, + u8 enabled) { struct mpc_config_processor processor; int boot_cpu = 0; - if (id == boot_cpu_id) + if (id >= MAX_APICS) { + printk(KERN_WARNING "Processor #%d invalid (max %d)\n", + id, MAX_APICS); + return; + } + + if (id == boot_cpu_physical_apicid) boot_cpu = 1; processor.mpc_type = MP_PROCESSOR; processor.mpc_apicid = id; - processor.mpc_apicver = 0; + processor.mpc_apicver = GET_APIC_VERSION(apic_read(APIC_LVR)); processor.mpc_cpuflag = (enabled ? CPU_ENABLED : 0); processor.mpc_cpuflag |= (boot_cpu ? CPU_BOOTPROCESSOR : 0); - processor.mpc_cpufeature = 0; - processor.mpc_featureflag = 0; + processor.mpc_cpufeature = (boot_cpu_data.x86 << 8) | + (boot_cpu_data.x86_model << 4) | boot_cpu_data.x86_mask; + processor.mpc_featureflag = boot_cpu_data.x86_capability[0]; processor.mpc_reserved[0] = 0; processor.mpc_reserved[1] = 0; MP_processor_info(&processor); } +#ifdef CONFIG_X86_IO_APIC + #define MP_ISA_BUS 0 #define MP_MAX_IOAPIC_PIN 127 @@ -637,9 +729,11 @@ static struct mp_ioapic_routing { u32 pin_programmed[4]; } mp_ioapic_routing[MAX_IO_APICS]; -static int mp_find_ioapic(int gsi) + +static int mp_find_ioapic ( + int gsi) { - int i = 0; + int i = 0; /* Find the IOAPIC that manages this GSI. */ for (i = 0; i < nr_ioapics; i++) { @@ -649,15 +743,28 @@ static int mp_find_ioapic(int gsi) } printk(KERN_ERR "ERROR: Unable to locate IOAPIC for GSI %d\n", gsi); + return -1; } + -void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) +void __init mp_register_ioapic ( + u8 id, + u32 address, + u32 gsi_base) { - int idx = 0; + int idx = 0; - if (bad_ioapic(address)) + if (nr_ioapics >= MAX_IO_APICS) { + printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded " + "(found %d)\n", MAX_IO_APICS, nr_ioapics); + panic("Recompile kernel with bigger MAX_IO_APICS!\n"); + } + if (!address) { + printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address" + " found in MADT table, skipping!\n"); return; + } idx = nr_ioapics++; @@ -667,7 +774,7 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); mp_ioapics[idx].mpc_apicid = id; - mp_ioapics[idx].mpc_apicver = 0; + mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); /* * Build basic IRQ lookup table to facilitate gsi->io_apic lookups @@ -678,15 +785,21 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) mp_ioapic_routing[idx].gsi_end = gsi_base + io_apic_get_redir_entries(idx); - printk(KERN_INFO "IOAPIC[%d]: apic_id %d, address 0x%x, " + printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " "GSI %d-%d\n", idx, mp_ioapics[idx].mpc_apicid, - mp_ioapics[idx].mpc_apicaddr, + mp_ioapics[idx].mpc_apicver, mp_ioapics[idx].mpc_apicaddr, mp_ioapic_routing[idx].gsi_start, mp_ioapic_routing[idx].gsi_end); + + return; } -void __init -mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) + +void __init mp_override_legacy_irq ( + u8 bus_irq, + u8 polarity, + u8 trigger, + u32 gsi) { struct mpc_config_intsrc intsrc; int ioapic = -1; @@ -724,18 +837,22 @@ mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi) mp_irqs[mp_irq_entries] = intsrc; if (++mp_irq_entries == MAX_IRQ_SOURCES) panic("Max # of irq sources exceeded!\n"); + + return; } -void __init mp_config_acpi_legacy_irqs(void) + +void __init mp_config_acpi_legacy_irqs (void) { struct mpc_config_intsrc intsrc; - int i = 0; - int ioapic = -1; + int i = 0; + int ioapic = -1; /* * Fabricate the legacy ISA bus (bus #31). */ - set_bit(MP_ISA_BUS, mp_bus_not_pci); + mp_bus_id_to_type[MP_ISA_BUS] = MP_BUS_ISA; + Dprintk("Bus #%d is ISA\n", MP_ISA_BUS); /* * Locate the IOAPIC that manages the ISA IRQs (0-15). @@ -788,22 +905,24 @@ void __init mp_config_acpi_legacy_irqs(void) if (++mp_irq_entries == MAX_IRQ_SOURCES) panic("Max # of irq sources exceeded!\n"); } + + return; } #define MAX_GSI_NUM 4096 int mp_register_gsi(u32 gsi, int triggering, int polarity) { - int ioapic = -1; - int ioapic_pin = 0; - int idx, bit = 0; - static int pci_irq = 16; + int ioapic = -1; + int ioapic_pin = 0; + int idx, bit = 0; + static int pci_irq = 16; /* * Mapping between Global System Interrupts, which * represent all possible interrupts, to the IRQs * assigned to actual devices. */ - static int gsi_to_irq[MAX_GSI_NUM]; + static int gsi_to_irq[MAX_GSI_NUM]; if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) return gsi; @@ -877,4 +996,6 @@ int mp_register_gsi(u32 gsi, int triggering, int polarity) polarity == ACPI_ACTIVE_HIGH ? 0 : 1); return gsi; } + +#endif /*CONFIG_X86_IO_APIC*/ #endif /*CONFIG_ACPI*/ diff --git a/trunk/arch/x86_64/kernel/nmi.c b/trunk/arch/x86_64/kernel/nmi.c index 7af9cb3e2d99..5baa0c726e97 100644 --- a/trunk/arch/x86_64/kernel/nmi.c +++ b/trunk/arch/x86_64/kernel/nmi.c @@ -28,142 +28,71 @@ #include #include -int unknown_nmi_panic; -int nmi_watchdog_enabled; -int panic_on_unrecovered_nmi; - -/* perfctr_nmi_owner tracks the ownership of the perfctr registers: - * evtsel_nmi_owner tracks the ownership of the event selection - * - different performance counters/ event selection may be reserved for - * different subsystems this reservation system just tries to coordinate - * things a little - */ -static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner); -static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[2]); - -/* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's - * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) +/* + * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: + * - it may be reserved by some other driver, or not + * - when not reserved by some other driver, it may be used for + * the NMI watchdog, or not + * + * This is maintained separately from nmi_active because the NMI + * watchdog may also be driven from the I/O APIC timer. */ -#define NMI_MAX_COUNTER_BITS 66 +static DEFINE_SPINLOCK(lapic_nmi_owner_lock); +static unsigned int lapic_nmi_owner; +#define LAPIC_NMI_WATCHDOG (1<<0) +#define LAPIC_NMI_RESERVED (1<<1) /* nmi_active: - * >0: the lapic NMI watchdog is active, but can be disabled - * <0: the lapic NMI watchdog has not been set up, and cannot + * +1: the lapic NMI watchdog is active, but can be disabled + * 0: the lapic NMI watchdog has not been set up, and cannot * be enabled - * 0: the lapic NMI watchdog is disabled, but can be enabled + * -1: the lapic NMI watchdog is disabled, but can be enabled */ -atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */ +int nmi_active; /* oprofile uses this */ int panic_on_timeout; unsigned int nmi_watchdog = NMI_DEFAULT; static unsigned int nmi_hz = HZ; +static unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ +static unsigned int nmi_p4_cccr_val; -struct nmi_watchdog_ctlblk { - int enabled; - u64 check_bit; - unsigned int cccr_msr; - unsigned int perfctr_msr; /* the MSR to reset in NMI handler */ - unsigned int evntsel_msr; /* the MSR to select the events to handle */ -}; -static DEFINE_PER_CPU(struct nmi_watchdog_ctlblk, nmi_watchdog_ctlblk); - -/* local prototypes */ -static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu); - -/* converts an msr to an appropriate reservation bit */ -static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr) -{ - /* returns the bit offset of the performance counter register */ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return (msr - MSR_K7_PERFCTR0); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return (msr - MSR_ARCH_PERFMON_PERFCTR0); - else - return (msr - MSR_P4_BPU_PERFCTR0); - } - return 0; -} - -/* converts an msr to an appropriate reservation bit */ -static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr) -{ - /* returns the bit offset of the event selection register */ - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - return (msr - MSR_K7_EVNTSEL0); - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) - return (msr - MSR_ARCH_PERFMON_EVENTSEL0); - else - return (msr - MSR_P4_BSU_ESCR0); - } - return 0; -} - -/* checks for a bit availability (hack for oprofile) */ -int avail_to_resrv_perfctr_nmi_bit(unsigned int counter) -{ - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner))); -} - -/* checks the an msr for availability */ -int avail_to_resrv_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - return (!test_bit(counter, &__get_cpu_var(perfctr_nmi_owner))); -} - -int reserve_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - if (!test_and_set_bit(counter, &__get_cpu_var(perfctr_nmi_owner))) - return 1; - return 0; -} - -void release_perfctr_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_perfctr_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - clear_bit(counter, &__get_cpu_var(perfctr_nmi_owner)); -} - -int reserve_evntsel_nmi(unsigned int msr) -{ - unsigned int counter; - - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); - - if (!test_and_set_bit(counter, &__get_cpu_var(evntsel_nmi_owner))) - return 1; - return 0; -} +/* Note that these events don't tick when the CPU idles. This means + the frequency varies with CPU load. */ -void release_evntsel_nmi(unsigned int msr) -{ - unsigned int counter; +#define K7_EVNTSEL_ENABLE (1 << 22) +#define K7_EVNTSEL_INT (1 << 20) +#define K7_EVNTSEL_OS (1 << 17) +#define K7_EVNTSEL_USR (1 << 16) +#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 +#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING - counter = nmi_evntsel_msr_to_bit(msr); - BUG_ON(counter > NMI_MAX_COUNTER_BITS); +#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL +#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK - clear_bit(counter, &__get_cpu_var(evntsel_nmi_owner)); -} +#define MSR_P4_MISC_ENABLE 0x1A0 +#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) +#define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL (1<<12) +#define MSR_P4_PERFCTR0 0x300 +#define MSR_P4_CCCR0 0x360 +#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) +#define P4_ESCR_OS (1<<3) +#define P4_ESCR_USR (1<<2) +#define P4_CCCR_OVF_PMI0 (1<<26) +#define P4_CCCR_OVF_PMI1 (1<<27) +#define P4_CCCR_THRESHOLD(N) ((N)<<20) +#define P4_CCCR_COMPLEMENT (1<<19) +#define P4_CCCR_COMPARE (1<<18) +#define P4_CCCR_REQUIRED (3<<16) +#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) +#define P4_CCCR_ENABLE (1<<12) +/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter + CRU_ESCR0 (with any non-null event selector) through a complemented + max threshold. [IA32-Vol3, Section 14.9.9] */ +#define MSR_P4_IQ_COUNTER0 0x30C +#define P4_NMI_CRU_ESCR0 (P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR) +#define P4_NMI_IQ_CCCR0 \ + (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ + P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) static __cpuinit inline int nmi_known_cpu(void) { @@ -180,7 +109,7 @@ static __cpuinit inline int nmi_known_cpu(void) } /* Run after command line and cpu_init init, but before all other checks */ -void nmi_watchdog_default(void) +void __cpuinit nmi_watchdog_default(void) { if (nmi_watchdog != NMI_DEFAULT) return; @@ -216,12 +145,6 @@ int __init check_nmi_watchdog (void) int *counts; int cpu; - if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT)) - return 0; - - if (!atomic_read(&nmi_active)) - return 0; - counts = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); if (!counts) return -1; @@ -239,43 +162,26 @@ int __init check_nmi_watchdog (void) mdelay((10*1000)/nmi_hz); // wait 10 ticks for_each_online_cpu(cpu) { - if (!per_cpu(nmi_watchdog_ctlblk, cpu).enabled) - continue; if (cpu_pda(cpu)->__nmi_count - counts[cpu] <= 5) { + endflag = 1; printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n", cpu, counts[cpu], cpu_pda(cpu)->__nmi_count); - per_cpu(nmi_watchdog_ctlblk, cpu).enabled = 0; - atomic_dec(&nmi_active); + nmi_active = 0; + lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG; + nmi_perfctr_msr = 0; + kfree(counts); + return -1; } } - if (!atomic_read(&nmi_active)) { - kfree(counts); - atomic_set(&nmi_active, -1); - return -1; - } endflag = 1; printk("OK.\n"); /* now that we know it works we can reduce NMI frequency to something more reasonable; makes a difference in some configs */ - if (nmi_watchdog == NMI_LOCAL_APIC) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - + if (nmi_watchdog == NMI_LOCAL_APIC) nmi_hz = 1; - /* - * On Intel CPUs with ARCH_PERFMON only 32 bits in the counter - * are writable, with higher bits sign extending from bit 31. - * So, we can only program the counter with 31 bit values and - * 32nd bit should be 1, for 33.. to be 1. - * Find the appropriate nmi_hz - */ - if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0 && - ((u64)cpu_khz * 1000) > 0x7fffffffULL) { - nmi_hz = ((u64)cpu_khz * 1000) / 0x7fffffffUL + 1; - } - } kfree(counts); return 0; @@ -295,65 +201,91 @@ int __init setup_nmi_watchdog(char *str) get_option(&str, &nmi); - if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE)) + if (nmi >= NMI_INVALID) return 0; - - if ((nmi == NMI_LOCAL_APIC) && (nmi_known_cpu() == 0)) - return 0; /* no lapic support */ nmi_watchdog = nmi; return 1; } __setup("nmi_watchdog=", setup_nmi_watchdog); +static void disable_intel_arch_watchdog(void); + static void disable_lapic_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); - - if (atomic_read(&nmi_active) <= 0) + if (nmi_active <= 0) return; - - on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); - - BUG_ON(atomic_read(&nmi_active) != 0); + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + wrmsr(MSR_K7_EVNTSEL0, 0, 0); + break; + case X86_VENDOR_INTEL: + if (boot_cpu_data.x86 == 15) { + wrmsr(MSR_P4_IQ_CCCR0, 0, 0); + wrmsr(MSR_P4_CRU_ESCR0, 0, 0); + } else if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + disable_intel_arch_watchdog(); + } + break; + } + nmi_active = -1; + /* tell do_nmi() and others that we're not active any more */ + nmi_watchdog = 0; } static void enable_lapic_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_LOCAL_APIC); + if (nmi_active < 0) { + nmi_watchdog = NMI_LOCAL_APIC; + touch_nmi_watchdog(); + setup_apic_nmi_watchdog(); + } +} - /* are we already enabled */ - if (atomic_read(&nmi_active) != 0) - return; +int reserve_lapic_nmi(void) +{ + unsigned int old_owner; - /* are we lapic aware */ - if (nmi_known_cpu() <= 0) - return; + spin_lock(&lapic_nmi_owner_lock); + old_owner = lapic_nmi_owner; + lapic_nmi_owner |= LAPIC_NMI_RESERVED; + spin_unlock(&lapic_nmi_owner_lock); + if (old_owner & LAPIC_NMI_RESERVED) + return -EBUSY; + if (old_owner & LAPIC_NMI_WATCHDOG) + disable_lapic_nmi_watchdog(); + return 0; +} + +void release_lapic_nmi(void) +{ + unsigned int new_owner; - on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); - touch_nmi_watchdog(); + spin_lock(&lapic_nmi_owner_lock); + new_owner = lapic_nmi_owner & ~LAPIC_NMI_RESERVED; + lapic_nmi_owner = new_owner; + spin_unlock(&lapic_nmi_owner_lock); + if (new_owner & LAPIC_NMI_WATCHDOG) + enable_lapic_nmi_watchdog(); } void disable_timer_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_IO_APIC); - - if (atomic_read(&nmi_active) <= 0) + if ((nmi_watchdog != NMI_IO_APIC) || (nmi_active <= 0)) return; disable_irq(0); - on_each_cpu(stop_apic_nmi_watchdog, NULL, 0, 1); - - BUG_ON(atomic_read(&nmi_active) != 0); + unset_nmi_callback(); + nmi_active = -1; + nmi_watchdog = NMI_NONE; } void enable_timer_nmi_watchdog(void) { - BUG_ON(nmi_watchdog != NMI_IO_APIC); - - if (atomic_read(&nmi_active) == 0) { + if (nmi_active < 0) { + nmi_watchdog = NMI_IO_APIC; touch_nmi_watchdog(); - on_each_cpu(setup_apic_nmi_watchdog, NULL, 0, 1); + nmi_active = 1; enable_irq(0); } } @@ -364,20 +296,15 @@ static int nmi_pm_active; /* nmi_active before suspend */ static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state) { - /* only CPU0 goes here, other CPUs should be offline */ - nmi_pm_active = atomic_read(&nmi_active); - stop_apic_nmi_watchdog(NULL); - BUG_ON(atomic_read(&nmi_active) != 0); + nmi_pm_active = nmi_active; + disable_lapic_nmi_watchdog(); return 0; } static int lapic_nmi_resume(struct sys_device *dev) { - /* only CPU0 goes here, other CPUs should be offline */ - if (nmi_pm_active > 0) { - setup_apic_nmi_watchdog(NULL); - touch_nmi_watchdog(); - } + if (nmi_pm_active > 0) + enable_lapic_nmi_watchdog(); return 0; } @@ -396,13 +323,7 @@ static int __init init_lapic_nmi_sysfs(void) { int error; - /* should really be a BUG_ON but b/c this is an - * init call, it just doesn't work. -dcz - */ - if (nmi_watchdog != NMI_LOCAL_APIC) - return 0; - - if ( atomic_read(&nmi_active) < 0 ) + if (nmi_active == 0 || nmi_watchdog != NMI_LOCAL_APIC) return 0; error = sysdev_class_register(&nmi_sysclass); @@ -420,209 +341,74 @@ late_initcall(init_lapic_nmi_sysfs); * Original code written by Keith Owens. */ -/* Note that these events don't tick when the CPU idles. This means - the frequency varies with CPU load. */ +static void clear_msr_range(unsigned int base, unsigned int n) +{ + unsigned int i; -#define K7_EVNTSEL_ENABLE (1 << 22) -#define K7_EVNTSEL_INT (1 << 20) -#define K7_EVNTSEL_OS (1 << 17) -#define K7_EVNTSEL_USR (1 << 16) -#define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 -#define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING + for(i = 0; i < n; ++i) + wrmsr(base+i, 0, 0); +} -static int setup_k7_watchdog(void) +static void setup_k7_watchdog(void) { - unsigned int perfctr_msr, evntsel_msr; + int i; unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - perfctr_msr = MSR_K7_PERFCTR0; - evntsel_msr = MSR_K7_EVNTSEL0; - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; + nmi_perfctr_msr = MSR_K7_PERFCTR0; - /* Simulator may not support it */ - if (checking_wrmsrl(evntsel_msr, 0UL)) - goto fail2; - wrmsrl(perfctr_msr, 0UL); + for(i = 0; i < 4; ++i) { + /* Simulator may not support it */ + if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL)) { + nmi_perfctr_msr = 0; + return; + } + wrmsrl(MSR_K7_PERFCTR0+i, 0UL); + } evntsel = K7_EVNTSEL_INT | K7_EVNTSEL_OS | K7_EVNTSEL_USR | K7_NMI_EVENT; - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - wrmsrl(perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); + wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); + wrmsrl(MSR_K7_PERFCTR0, -((u64)cpu_khz * 1000 / nmi_hz)); apic_write(APIC_LVTPC, APIC_DM_NMI); evntsel |= K7_EVNTSEL_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL<<63; - return 1; -fail2: - release_evntsel_nmi(evntsel_msr); -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; + wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); } -static void stop_k7_watchdog(void) +static void disable_intel_arch_watchdog(void) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->evntsel_msr, 0, 0); - - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); -} - -/* Note that these events don't tick when the CPU idles. This means - the frequency varies with CPU load. */ - -#define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) -#define P4_ESCR_EVENT_SELECT(N) ((N)<<25) -#define P4_ESCR_OS (1<<3) -#define P4_ESCR_USR (1<<2) -#define P4_CCCR_OVF_PMI0 (1<<26) -#define P4_CCCR_OVF_PMI1 (1<<27) -#define P4_CCCR_THRESHOLD(N) ((N)<<20) -#define P4_CCCR_COMPLEMENT (1<<19) -#define P4_CCCR_COMPARE (1<<18) -#define P4_CCCR_REQUIRED (3<<16) -#define P4_CCCR_ESCR_SELECT(N) ((N)<<13) -#define P4_CCCR_ENABLE (1<<12) -#define P4_CCCR_OVF (1<<31) -/* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter - CRU_ESCR0 (with any non-null event selector) through a complemented - max threshold. [IA32-Vol3, Section 14.9.9] */ - -static int setup_p4_watchdog(void) -{ - unsigned int perfctr_msr, evntsel_msr, cccr_msr; - unsigned int evntsel, cccr_val; - unsigned int misc_enable, dummy; - unsigned int ht_num; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - rdmsr(MSR_IA32_MISC_ENABLE, misc_enable, dummy); - if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) - return 0; - -#ifdef CONFIG_SMP - /* detect which hyperthread we are on */ - if (smp_num_siblings == 2) { - unsigned int ebx, apicid; - - ebx = cpuid_ebx(1); - apicid = (ebx >> 24) & 0xff; - ht_num = apicid & 1; - } else -#endif - ht_num = 0; + unsigned ebx; - /* performance counters are shared resources - * assign each hyperthread its own set - * (re-use the ESCR0 register, seems safe - * and keeps the cccr_val the same) + /* + * Check whether the Architectural PerfMon supports + * Unhalted Core Cycles Event or not. + * NOTE: Corresponding bit = 0 in ebp indicates event present. */ - if (!ht_num) { - /* logical cpu 0 */ - perfctr_msr = MSR_P4_IQ_PERFCTR0; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR0; - cccr_val = P4_CCCR_OVF_PMI0 | P4_CCCR_ESCR_SELECT(4); - } else { - /* logical cpu 1 */ - perfctr_msr = MSR_P4_IQ_PERFCTR1; - evntsel_msr = MSR_P4_CRU_ESCR0; - cccr_msr = MSR_P4_IQ_CCCR1; - cccr_val = P4_CCCR_OVF_PMI1 | P4_CCCR_ESCR_SELECT(4); - } - - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; - - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; - - evntsel = P4_ESCR_EVENT_SELECT(0x3F) - | P4_ESCR_OS - | P4_ESCR_USR; - - cccr_val |= P4_CCCR_THRESHOLD(15) - | P4_CCCR_COMPLEMENT - | P4_CCCR_COMPARE - | P4_CCCR_REQUIRED; - - wrmsr(evntsel_msr, evntsel, 0); - wrmsr(cccr_msr, cccr_val, 0); - wrmsrl(perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); - apic_write(APIC_LVTPC, APIC_DM_NMI); - cccr_val |= P4_CCCR_ENABLE; - wrmsr(cccr_msr, cccr_val, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = cccr_msr; - wd->check_bit = 1ULL<<39; - return 1; -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; -} - -static void stop_p4_watchdog(void) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - wrmsr(wd->cccr_msr, 0, 0); - wrmsr(wd->evntsel_msr, 0, 0); - - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); + ebx = cpuid_ebx(10); + if (!(ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, 0, 0); } -#define ARCH_PERFMON_NMI_EVENT_SEL ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL -#define ARCH_PERFMON_NMI_EVENT_UMASK ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK - static int setup_intel_arch_watchdog(void) { - unsigned int ebx; - union cpuid10_eax eax; - unsigned int unused; - unsigned int perfctr_msr, evntsel_msr; unsigned int evntsel; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + unsigned ebx; /* * Check whether the Architectural PerfMon supports * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebx indicates event present. + * NOTE: Corresponding bit = 0 in ebp indicates event present. */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); - if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || - (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - goto fail; - - perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; - evntsel_msr = MSR_ARCH_PERFMON_EVENTSEL0; - - if (!reserve_perfctr_nmi(perfctr_msr)) - goto fail; + ebx = cpuid_ebx(10); + if ((ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) + return 0; - if (!reserve_evntsel_nmi(evntsel_msr)) - goto fail1; + nmi_perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0; - wrmsrl(perfctr_msr, 0UL); + clear_msr_range(MSR_ARCH_PERFMON_EVENTSEL0, 2); + clear_msr_range(MSR_ARCH_PERFMON_PERFCTR0, 2); evntsel = ARCH_PERFMON_EVENTSEL_INT | ARCH_PERFMON_EVENTSEL_OS @@ -630,122 +416,84 @@ static int setup_intel_arch_watchdog(void) | ARCH_PERFMON_NMI_EVENT_SEL | ARCH_PERFMON_NMI_EVENT_UMASK; - /* setup the timer */ - wrmsr(evntsel_msr, evntsel, 0); - wrmsrl(perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); - + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); + wrmsrl(MSR_ARCH_PERFMON_PERFCTR0, -((u64)cpu_khz * 1000 / nmi_hz)); apic_write(APIC_LVTPC, APIC_DM_NMI); evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE; - wrmsr(evntsel_msr, evntsel, 0); - - wd->perfctr_msr = perfctr_msr; - wd->evntsel_msr = evntsel_msr; - wd->cccr_msr = 0; //unused - wd->check_bit = 1ULL << (eax.split.bit_width - 1); + wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0); return 1; -fail1: - release_perfctr_nmi(perfctr_msr); -fail: - return 0; } -static void stop_intel_arch_watchdog(void) + +static int setup_p4_watchdog(void) { - unsigned int ebx; - union cpuid10_eax eax; - unsigned int unused; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); + unsigned int misc_enable, dummy; - /* - * Check whether the Architectural PerfMon supports - * Unhalted Core Cycles Event or not. - * NOTE: Corresponding bit = 0 in ebx indicates event present. - */ - cpuid(10, &(eax.full), &ebx, &unused, &unused); - if ((eax.split.mask_length < (ARCH_PERFMON_UNHALTED_CORE_CYCLES_INDEX+1)) || - (ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT)) - return; + rdmsr(MSR_P4_MISC_ENABLE, misc_enable, dummy); + if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) + return 0; - wrmsr(wd->evntsel_msr, 0, 0); + nmi_perfctr_msr = MSR_P4_IQ_COUNTER0; + nmi_p4_cccr_val = P4_NMI_IQ_CCCR0; +#ifdef CONFIG_SMP + if (smp_num_siblings == 2) + nmi_p4_cccr_val |= P4_CCCR_OVF_PMI1; +#endif - release_evntsel_nmi(wd->evntsel_msr); - release_perfctr_nmi(wd->perfctr_msr); + if (!(misc_enable & MSR_P4_MISC_ENABLE_PEBS_UNAVAIL)) + clear_msr_range(0x3F1, 2); + /* MSR 0x3F0 seems to have a default value of 0xFC00, but current + docs doesn't fully define it, so leave it alone for now. */ + if (boot_cpu_data.x86_model >= 0x3) { + /* MSR_P4_IQ_ESCR0/1 (0x3ba/0x3bb) removed */ + clear_msr_range(0x3A0, 26); + clear_msr_range(0x3BC, 3); + } else { + clear_msr_range(0x3A0, 31); + } + clear_msr_range(0x3C0, 6); + clear_msr_range(0x3C8, 6); + clear_msr_range(0x3E0, 2); + clear_msr_range(MSR_P4_CCCR0, 18); + clear_msr_range(MSR_P4_PERFCTR0, 18); + + wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0); + wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0); + Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz * 1000UL / nmi_hz)); + wrmsrl(MSR_P4_IQ_COUNTER0, -((u64)cpu_khz * 1000 / nmi_hz)); + apic_write(APIC_LVTPC, APIC_DM_NMI); + wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); + return 1; } -void setup_apic_nmi_watchdog(void *unused) +void setup_apic_nmi_watchdog(void) { - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - - /* only support LOCAL and IO APICs for now */ - if ((nmi_watchdog != NMI_LOCAL_APIC) && - (nmi_watchdog != NMI_IO_APIC)) - return; - - if (wd->enabled == 1) - return; - - /* cheap hack to support suspend/resume */ - /* if cpu0 is not active neither should the other cpus */ - if ((smp_processor_id() != 0) && (atomic_read(&nmi_active) <= 0)) - return; - - if (nmi_watchdog == NMI_LOCAL_APIC) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - if (strstr(boot_cpu_data.x86_model_id, "Screwdriver")) - return; - if (!setup_k7_watchdog()) + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + if (boot_cpu_data.x86 != 15) + return; + if (strstr(boot_cpu_data.x86_model_id, "Screwdriver")) + return; + setup_k7_watchdog(); + break; + case X86_VENDOR_INTEL: + if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { + if (!setup_intel_arch_watchdog()) return; - break; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - if (!setup_intel_arch_watchdog()) - return; - break; - } + } else if (boot_cpu_data.x86 == 15) { if (!setup_p4_watchdog()) return; - break; - default: + } else { return; } - } - wd->enabled = 1; - atomic_inc(&nmi_active); -} - -void stop_apic_nmi_watchdog(void *unused) -{ - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - /* only support LOCAL and IO APICs for now */ - if ((nmi_watchdog != NMI_LOCAL_APIC) && - (nmi_watchdog != NMI_IO_APIC)) - return; + break; - if (wd->enabled == 0) + default: return; - - if (nmi_watchdog == NMI_LOCAL_APIC) { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: - if (strstr(boot_cpu_data.x86_model_id, "Screwdriver")) - return; - stop_k7_watchdog(); - break; - case X86_VENDOR_INTEL: - if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { - stop_intel_arch_watchdog(); - break; - } - stop_p4_watchdog(); - break; - default: - return; - } } - wd->enabled = 0; - atomic_dec(&nmi_active); + lapic_nmi_owner = LAPIC_NMI_WATCHDOG; + nmi_active = 1; } /* @@ -778,109 +526,93 @@ void touch_nmi_watchdog (void) touch_softlockup_watchdog(); } -int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) +void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) { int sum; int touched = 0; - struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); - u64 dummy; - int rc=0; - - /* check for other users first */ - if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) - == NOTIFY_STOP) { - rc = 1; - touched = 1; - } sum = read_pda(apic_timer_irqs); if (__get_cpu_var(nmi_touch)) { __get_cpu_var(nmi_touch) = 0; touched = 1; } - #ifdef CONFIG_X86_MCE /* Could check oops_in_progress here too, but it's safer not too */ if (atomic_read(&mce_entry) > 0) touched = 1; #endif - /* if the apic timer isn't firing, this cpu isn't doing much */ if (!touched && __get_cpu_var(last_irq_sum) == sum) { /* * Ayiee, looks like this CPU is stuck ... * wait a few IRQs (5 seconds) before doing the oops ... */ local_inc(&__get_cpu_var(alert_counter)); - if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) - die_nmi("NMI Watchdog detected LOCKUP on CPU %d\n", regs, - panic_on_timeout); + if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) { + if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) + == NOTIFY_STOP) { + local_set(&__get_cpu_var(alert_counter), 0); + return; + } + die_nmi("NMI Watchdog detected LOCKUP on CPU %d\n", regs); + } } else { __get_cpu_var(last_irq_sum) = sum; local_set(&__get_cpu_var(alert_counter), 0); } - - /* see if the nmi watchdog went off */ - if (wd->enabled) { - if (nmi_watchdog == NMI_LOCAL_APIC) { - rdmsrl(wd->perfctr_msr, dummy); - if (dummy & wd->check_bit){ - /* this wasn't a watchdog timer interrupt */ - goto done; - } - - /* only Intel uses the cccr msr */ - if (wd->cccr_msr != 0) { - /* - * P4 quirks: - * - An overflown perfctr will assert its interrupt - * until the OVF flag in its CCCR is cleared. - * - LVTPC is masked on interrupt and must be - * unmasked by the LVTPC handler. - */ - rdmsrl(wd->cccr_msr, dummy); - dummy &= ~P4_CCCR_OVF; - wrmsrl(wd->cccr_msr, dummy); - apic_write(APIC_LVTPC, APIC_DM_NMI); - } else if (wd->perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { - /* - * ArchPerfom/Core Duo needs to re-unmask - * the apic vector - */ - apic_write(APIC_LVTPC, APIC_DM_NMI); - } - /* start the cycle over again */ - wrmsrl(wd->perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); - rc = 1; - } else if (nmi_watchdog == NMI_IO_APIC) { - /* don't know how to accurately check for this. - * just assume it was a watchdog timer interrupt - * This matches the old behaviour. + if (nmi_perfctr_msr) { + if (nmi_perfctr_msr == MSR_P4_IQ_COUNTER0) { + /* + * P4 quirks: + * - An overflown perfctr will assert its interrupt + * until the OVF flag in its CCCR is cleared. + * - LVTPC is masked on interrupt and must be + * unmasked by the LVTPC handler. + */ + wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); + apic_write(APIC_LVTPC, APIC_DM_NMI); + } else if (nmi_perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) { + /* + * For Intel based architectural perfmon + * - LVTPC is masked on interrupt and must be + * unmasked by the LVTPC handler. */ - rc = 1; - } else - printk(KERN_WARNING "Unknown enabled NMI hardware?!\n"); + apic_write(APIC_LVTPC, APIC_DM_NMI); + } + wrmsrl(nmi_perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz)); } -done: - return rc; } +static __kprobes int dummy_nmi_callback(struct pt_regs * regs, int cpu) +{ + return 0; +} + +static nmi_callback_t nmi_callback = dummy_nmi_callback; + asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code) { + int cpu = safe_smp_processor_id(); + nmi_enter(); add_pda(__nmi_count,1); - default_do_nmi(regs); + if (!rcu_dereference(nmi_callback)(regs, cpu)) + default_do_nmi(regs); nmi_exit(); } -int do_nmi_callback(struct pt_regs * regs, int cpu) +void set_nmi_callback(nmi_callback_t callback) { -#ifdef CONFIG_SYSCTL - if (unknown_nmi_panic) - return unknown_nmi_panic_callback(regs, cpu); -#endif - return 0; + vmalloc_sync_all(); + rcu_assign_pointer(nmi_callback, callback); +} +EXPORT_SYMBOL_GPL(set_nmi_callback); + +void unset_nmi_callback(void) +{ + nmi_callback = dummy_nmi_callback; } +EXPORT_SYMBOL_GPL(unset_nmi_callback); #ifdef CONFIG_SYSCTL @@ -889,42 +621,36 @@ static int unknown_nmi_panic_callback(struct pt_regs *regs, int cpu) unsigned char reason = get_nmi_reason(); char buf[64]; - sprintf(buf, "NMI received for unknown reason %02x\n", reason); - die_nmi(buf, regs, 1); /* Always panic here */ + if (!(reason & 0xc0)) { + sprintf(buf, "NMI received for unknown reason %02x\n", reason); + die_nmi(buf,regs); + } return 0; } /* - * proc handler for /proc/sys/kernel/nmi + * proc handler for /proc/sys/kernel/unknown_nmi_panic */ -int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, +int proc_unknown_nmi_panic(struct ctl_table *table, int write, struct file *file, void __user *buffer, size_t *length, loff_t *ppos) { int old_state; - nmi_watchdog_enabled = (atomic_read(&nmi_active) > 0) ? 1 : 0; - old_state = nmi_watchdog_enabled; + old_state = unknown_nmi_panic; proc_dointvec(table, write, file, buffer, length, ppos); - if (!!old_state == !!nmi_watchdog_enabled) + if (!!old_state == !!unknown_nmi_panic) return 0; - if (atomic_read(&nmi_active) < 0) { - printk( KERN_WARNING "NMI watchdog is permanently disabled\n"); - return -EIO; - } - - /* if nmi_watchdog is not set yet, then set it */ - nmi_watchdog_default(); - - if (nmi_watchdog == NMI_LOCAL_APIC) { - if (nmi_watchdog_enabled) - enable_lapic_nmi_watchdog(); - else - disable_lapic_nmi_watchdog(); + if (unknown_nmi_panic) { + if (reserve_lapic_nmi() < 0) { + unknown_nmi_panic = 0; + return -EBUSY; + } else { + set_nmi_callback(unknown_nmi_panic_callback); + } } else { - printk( KERN_WARNING - "NMI watchdog doesn't know what hardware to touch\n"); - return -EIO; + release_lapic_nmi(); + unset_nmi_callback(); } return 0; } @@ -933,12 +659,8 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); -EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi_bit); -EXPORT_SYMBOL(reserve_perfctr_nmi); -EXPORT_SYMBOL(release_perfctr_nmi); -EXPORT_SYMBOL(reserve_evntsel_nmi); -EXPORT_SYMBOL(release_evntsel_nmi); +EXPORT_SYMBOL(reserve_lapic_nmi); +EXPORT_SYMBOL(release_lapic_nmi); EXPORT_SYMBOL(disable_timer_nmi_watchdog); EXPORT_SYMBOL(enable_timer_nmi_watchdog); EXPORT_SYMBOL(touch_nmi_watchdog); diff --git a/trunk/arch/x86_64/kernel/pci-calgary.c b/trunk/arch/x86_64/kernel/pci-calgary.c index cfb09b07ae99..146924ba5df5 100644 --- a/trunk/arch/x86_64/kernel/pci-calgary.c +++ b/trunk/arch/x86_64/kernel/pci-calgary.c @@ -86,8 +86,7 @@ #define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ #define MAX_NUM_CHASSIS 8 /* max number of chassis */ -/* MAX_PHB_BUS_NUM is the maximal possible dev->bus->number */ -#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2) +#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2) /* max dev->bus->number */ #define PHBS_PER_CALGARY 4 /* register offsets in Calgary's internal register space */ @@ -112,49 +111,31 @@ static const unsigned long phb_offsets[] = { 0xB000 /* PHB3 */ }; +static char bus_to_phb[MAX_PHB_BUS_NUM]; +void* tce_table_kva[MAX_PHB_BUS_NUM]; unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED; static int translate_empty_slots __read_mostly = 0; static int calgary_detected __read_mostly = 0; -struct calgary_bus_info { - void *tce_space; - unsigned char translation_disabled; - signed char phbid; -}; - -static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, }; +/* + * the bitmap of PHBs the user requested that we disable + * translation on. + */ +static DECLARE_BITMAP(translation_disabled, MAX_PHB_BUS_NUM); static void tce_cache_blast(struct iommu_table *tbl); /* enable this to stress test the chip's TCE cache */ #ifdef CONFIG_IOMMU_DEBUG -int debugging __read_mostly = 1; - -static inline unsigned long verify_bit_range(unsigned long* bitmap, - int expected, unsigned long start, unsigned long end) +static inline void tce_cache_blast_stress(struct iommu_table *tbl) { - unsigned long idx = start; - - BUG_ON(start >= end); - - while (idx < end) { - if (!!test_bit(idx, bitmap) != expected) - return idx; - ++idx; - } - - /* all bits have the expected value */ - return ~0UL; + tce_cache_blast(tbl); } -#else /* debugging is disabled */ -int debugging __read_mostly = 0; - -static inline unsigned long verify_bit_range(unsigned long* bitmap, - int expected, unsigned long start, unsigned long end) +#else +static inline void tce_cache_blast_stress(struct iommu_table *tbl) { - return ~0UL; } -#endif /* CONFIG_IOMMU_DEBUG */ +#endif /* BLAST_TCE_CACHE_ON_UNMAP */ static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen) { @@ -168,7 +149,7 @@ static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen) static inline int translate_phb(struct pci_dev* dev) { - int disabled = bus_info[dev->bus->number].translation_disabled; + int disabled = test_bit(dev->bus->number, translation_disabled); return !disabled; } @@ -177,7 +158,6 @@ static void iommu_range_reserve(struct iommu_table *tbl, { unsigned long index; unsigned long end; - unsigned long badbit; index = start_addr >> PAGE_SHIFT; @@ -189,15 +169,14 @@ static void iommu_range_reserve(struct iommu_table *tbl, if (end > tbl->it_size) /* don't go off the table */ end = tbl->it_size; - badbit = verify_bit_range(tbl->it_map, 0, index, end); - if (badbit != ~0UL) { - if (printk_ratelimit()) + while (index < end) { + if (test_bit(index, tbl->it_map)) printk(KERN_ERR "Calgary: entry already allocated at " "0x%lx tbl %p dma 0x%lx npages %u\n", - badbit, tbl, start_addr, npages); + index, tbl, start_addr, npages); + ++index; } - - set_bit_string(tbl->it_map, index, npages); + set_bit_string(tbl->it_map, start_addr >> PAGE_SHIFT, npages); } static unsigned long iommu_range_alloc(struct iommu_table *tbl, @@ -264,7 +243,7 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, unsigned int npages) { unsigned long entry; - unsigned long badbit; + unsigned long i; entry = dma_addr >> PAGE_SHIFT; @@ -272,15 +251,16 @@ static void __iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, tce_free(tbl, entry, npages); - badbit = verify_bit_range(tbl->it_map, 1, entry, entry + npages); - if (badbit != ~0UL) { - if (printk_ratelimit()) + for (i = 0; i < npages; ++i) { + if (!test_bit(entry + i, tbl->it_map)) printk(KERN_ERR "Calgary: bit is off at 0x%lx " "tbl %p dma 0x%Lx entry 0x%lx npages %u\n", - badbit, tbl, dma_addr, entry, npages); + entry + i, tbl, dma_addr, entry, npages); } __clear_bit_string(tbl->it_map, entry, npages); + + tce_cache_blast_stress(tbl); } static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, @@ -474,7 +454,7 @@ static struct dma_mapping_ops calgary_dma_ops = { static inline int busno_to_phbid(unsigned char num) { - return bus_info[num].phbid; + return bus_to_phb[num]; } static inline unsigned long split_queue_offset(unsigned char num) @@ -651,10 +631,6 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar) if (ret) return ret; - tbl = dev->sysdata; - tbl->it_base = (unsigned long)bus_info[dev->bus->number].tce_space; - tce_free(tbl, 0, tbl->it_size); - calgary_reserve_regions(dev); /* set TARs for each PHB */ @@ -678,12 +654,11 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar) return 0; } -static void __init calgary_free_bus(struct pci_dev *dev) +static void __init calgary_free_tar(struct pci_dev *dev) { u64 val64; struct iommu_table *tbl = dev->sysdata; void __iomem *target; - unsigned int bitmapsz; target = calgary_reg(tbl->bbar, tar_offset(dev->bus->number)); val64 = be64_to_cpu(readq(target)); @@ -691,15 +666,8 @@ static void __init calgary_free_bus(struct pci_dev *dev) writeq(cpu_to_be64(val64), target); readq(target); /* flush */ - bitmapsz = tbl->it_size / BITS_PER_BYTE; - free_pages((unsigned long)tbl->it_map, get_order(bitmapsz)); - tbl->it_map = NULL; - kfree(tbl); dev->sysdata = NULL; - - /* Can't free bootmem allocated memory after system is up :-( */ - bus_info[dev->bus->number].tce_space = NULL; } static void calgary_watchdog(unsigned long data) @@ -804,11 +772,12 @@ static inline unsigned int __init locate_register_space(struct pci_dev *dev) return address; } -static void __init calgary_init_one_nontraslated(struct pci_dev *dev) +static int __init calgary_init_one_nontraslated(struct pci_dev *dev) { - pci_dev_get(dev); dev->sysdata = NULL; dev->bus->self = dev; + + return 0; } static int __init calgary_init_one(struct pci_dev *dev) @@ -829,7 +798,6 @@ static int __init calgary_init_one(struct pci_dev *dev) if (ret) goto iounmap; - pci_dev_get(dev); dev->bus->self = dev; calgary_enable_translation(dev); @@ -856,9 +824,10 @@ static int __init calgary_init(void) calgary_init_one_nontraslated(dev); continue; } - if (!bus_info[dev->bus->number].tce_space && !translate_empty_slots) + if (!tce_table_kva[dev->bus->number] && !translate_empty_slots) { + pci_dev_put(dev); continue; - + } ret = calgary_init_one(dev); if (ret) goto error; @@ -871,18 +840,15 @@ static int __init calgary_init(void) dev = pci_find_device_reverse(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CALGARY, dev); - if (!dev) - break; if (!translate_phb(dev)) { pci_dev_put(dev); continue; } - if (!bus_info[dev->bus->number].tce_space && !translate_empty_slots) + if (!tce_table_kva[dev->bus->number] && !translate_empty_slots) continue; - calgary_disable_translation(dev); - calgary_free_bus(dev); - pci_dev_put(dev); /* Undo calgary_init_one()'s pci_dev_get() */ + calgary_free_tar(dev); + pci_dev_put(dev); } return ret; @@ -924,15 +890,13 @@ void __init detect_calgary(void) if (swiotlb || no_iommu || iommu_detected) return; - if (!early_pci_allowed()) - return; - specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE); for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { int dev; - struct calgary_bus_info *info = &bus_info[bus]; - info->phbid = -1; + + tce_table_kva[bus] = NULL; + bus_to_phb[bus] = -1; if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) continue; @@ -943,9 +907,12 @@ void __init detect_calgary(void) */ phb = (phb + 1) % PHBS_PER_CALGARY; - if (info->translation_disabled) + if (test_bit(bus, translation_disabled)) { + printk(KERN_INFO "Calgary: translation is disabled for " + "PHB 0x%x\n", bus); + /* skip this phb, don't allocate a tbl for it */ continue; - + } /* * Scan the slots of the PCI bus to see if there is a device present. * The parent bus will be the zero-ith device, so start at 1. @@ -956,8 +923,8 @@ void __init detect_calgary(void) tbl = alloc_tce_table(); if (!tbl) goto cleanup; - info->tce_space = tbl; - info->phbid = phb; + tce_table_kva[bus] = tbl; + bus_to_phb[bus] = phb; calgary_found = 1; break; } @@ -967,20 +934,15 @@ void __init detect_calgary(void) if (calgary_found) { iommu_detected = 1; calgary_detected = 1; - printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected.\n"); - printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d, " - "CONFIG_IOMMU_DEBUG is %s.\n", specified_table_size, - debugging ? "enabled" : "disabled"); + printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected. " + "TCE table spec is %d.\n", specified_table_size); } return; cleanup: - for (--bus; bus >= 0; --bus) { - struct calgary_bus_info *info = &bus_info[bus]; - - if (info->tce_space) - free_tce_table(info->tce_space); - } + for (--bus; bus >= 0; --bus) + if (tce_table_kva[bus]) + free_tce_table(tce_table_kva[bus]); } int __init calgary_iommu_init(void) @@ -1054,7 +1016,7 @@ static int __init calgary_parse_options(char *p) if (bridge < MAX_PHB_BUS_NUM) { printk(KERN_INFO "Calgary: disabling " "translation for PHB 0x%x\n", bridge); - bus_info[bridge].translation_disabled = 1; + set_bit(bridge, translation_disabled); } } diff --git a/trunk/arch/x86_64/kernel/pci-dma.c b/trunk/arch/x86_64/kernel/pci-dma.c index f8d857453f8a..9c44f4f2433d 100644 --- a/trunk/arch/x86_64/kernel/pci-dma.c +++ b/trunk/arch/x86_64/kernel/pci-dma.c @@ -170,20 +170,8 @@ void dma_free_coherent(struct device *dev, size_t size, } EXPORT_SYMBOL(dma_free_coherent); -static int forbid_dac __read_mostly; - int dma_supported(struct device *dev, u64 mask) { -#ifdef CONFIG_PCI - if (mask > 0xffffffff && forbid_dac > 0) { - - - - printk(KERN_INFO "PCI: Disallowing DAC for device %s\n", dev->bus_id); - return 0; - } -#endif - if (dma_ops->dma_supported) return dma_ops->dma_supported(dev, mask); @@ -243,66 +231,56 @@ EXPORT_SYMBOL(dma_set_mask); allowed overwrite iommu off workarounds for specific chipsets. soft Use software bounce buffering (default for Intel machines) noaperture Don't touch the aperture for AGP. - allowdac Allow DMA >4GB - nodac Forbid DMA >4GB - panic Force panic when IOMMU overflows */ __init int iommu_setup(char *p) { - iommu_merge = 1; - - if (!p) - return -EINVAL; - - while (*p) { - if (!strncmp(p,"off",3)) - no_iommu = 1; - /* gart_parse_options has more force support */ - if (!strncmp(p,"force",5)) - force_iommu = 1; - if (!strncmp(p,"noforce",7)) { - iommu_merge = 0; - force_iommu = 0; - } - - if (!strncmp(p, "biomerge",8)) { - iommu_bio_merge = 4096; - iommu_merge = 1; - force_iommu = 1; - } - if (!strncmp(p, "panic",5)) - panic_on_overflow = 1; - if (!strncmp(p, "nopanic",7)) - panic_on_overflow = 0; - if (!strncmp(p, "merge",5)) { - iommu_merge = 1; - force_iommu = 1; - } - if (!strncmp(p, "nomerge",7)) - iommu_merge = 0; - if (!strncmp(p, "forcesac",8)) - iommu_sac_force = 1; - if (!strncmp(p, "allowdac", 8)) - forbid_dac = 0; - if (!strncmp(p, "nodac", 5)) - forbid_dac = -1; + iommu_merge = 1; + + while (*p) { + if (!strncmp(p,"off",3)) + no_iommu = 1; + /* gart_parse_options has more force support */ + if (!strncmp(p,"force",5)) + force_iommu = 1; + if (!strncmp(p,"noforce",7)) { + iommu_merge = 0; + force_iommu = 0; + } + + if (!strncmp(p, "biomerge",8)) { + iommu_bio_merge = 4096; + iommu_merge = 1; + force_iommu = 1; + } + if (!strncmp(p, "panic",5)) + panic_on_overflow = 1; + if (!strncmp(p, "nopanic",7)) + panic_on_overflow = 0; + if (!strncmp(p, "merge",5)) { + iommu_merge = 1; + force_iommu = 1; + } + if (!strncmp(p, "nomerge",7)) + iommu_merge = 0; + if (!strncmp(p, "forcesac",8)) + iommu_sac_force = 1; #ifdef CONFIG_SWIOTLB - if (!strncmp(p, "soft",4)) - swiotlb = 1; + if (!strncmp(p, "soft",4)) + swiotlb = 1; #endif #ifdef CONFIG_IOMMU - gart_parse_options(p); + gart_parse_options(p); #endif - p += strcspn(p, ","); - if (*p == ',') - ++p; - } - return 0; + p += strcspn(p, ","); + if (*p == ',') + ++p; + } + return 1; } -early_param("iommu", iommu_setup); +__setup("iommu=", iommu_setup); void __init pci_iommu_alloc(void) { diff --git a/trunk/arch/x86_64/kernel/pci-gart.c b/trunk/arch/x86_64/kernel/pci-gart.c index 16261a8a3303..6d3e61baf7a0 100644 --- a/trunk/arch/x86_64/kernel/pci-gart.c +++ b/trunk/arch/x86_64/kernel/pci-gart.c @@ -239,6 +239,8 @@ dma_addr_t gart_map_single(struct device *dev, void *addr, size_t size, int dir) { unsigned long phys_mem, bus; + BUG_ON(dir == DMA_NONE); + if (!dev) dev = &fallback_dev; @@ -381,6 +383,7 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) unsigned long pages = 0; int need = 0, nextneed; + BUG_ON(dir == DMA_NONE); if (nents == 0) return 0; diff --git a/trunk/arch/x86_64/kernel/pci-nommu.c b/trunk/arch/x86_64/kernel/pci-nommu.c index df09ab05a1bd..aad7609d8e92 100644 --- a/trunk/arch/x86_64/kernel/pci-nommu.c +++ b/trunk/arch/x86_64/kernel/pci-nommu.c @@ -59,6 +59,7 @@ int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, { int i; + BUG_ON(direction == DMA_NONE); for (i = 0; i < nents; i++ ) { struct scatterlist *s = &sg[i]; BUG_ON(!s->page); diff --git a/trunk/arch/x86_64/kernel/pci-swiotlb.c b/trunk/arch/x86_64/kernel/pci-swiotlb.c index 697f0aa794b9..6a55f87ba97f 100644 --- a/trunk/arch/x86_64/kernel/pci-swiotlb.c +++ b/trunk/arch/x86_64/kernel/pci-swiotlb.c @@ -3,8 +3,7 @@ #include #include #include -#include - +#include #include #include #include diff --git a/trunk/arch/x86_64/kernel/process.c b/trunk/arch/x86_64/kernel/process.c index de10cb8a2c97..bb6745d13b8f 100644 --- a/trunk/arch/x86_64/kernel/process.c +++ b/trunk/arch/x86_64/kernel/process.c @@ -80,25 +80,25 @@ void idle_notifier_unregister(struct notifier_block *n) } EXPORT_SYMBOL(idle_notifier_unregister); +enum idle_state { CPU_IDLE, CPU_NOT_IDLE }; +static DEFINE_PER_CPU(enum idle_state, idle_state) = CPU_NOT_IDLE; + void enter_idle(void) { - write_pda(isidle, 1); + __get_cpu_var(idle_state) = CPU_IDLE; atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL); } static void __exit_idle(void) { - if (read_pda(isidle) == 0) - return; - write_pda(isidle, 0); + __get_cpu_var(idle_state) = CPU_NOT_IDLE; atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); } /* Called from interrupts to signify idle end */ void exit_idle(void) { - /* idle loop has pid 0 */ - if (current->pid) + if (current->pid | read_pda(irqcount)) return; __exit_idle(); } @@ -220,9 +220,6 @@ void cpu_idle (void) play_dead(); enter_idle(); idle(); - /* In many cases the interrupt that ended idle - has already called exit_idle. But some idle - loops can be woken up without interrupt. */ __exit_idle(); } @@ -294,9 +291,9 @@ void __show_regs(struct pt_regs * regs) print_modules(); printk("Pid: %d, comm: %.20s %s %s %.*s\n", current->pid, current->comm, print_tainted(), - init_utsname()->release, - (int)strcspn(init_utsname()->version, " "), - init_utsname()->version); + system_utsname.release, + (int)strcspn(system_utsname.version, " "), + system_utsname.version); printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip); printk_address(regs->rip); printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp, @@ -353,7 +350,6 @@ void exit_thread(void) kfree(t->io_bitmap_ptr); t->io_bitmap_ptr = NULL; - clear_thread_flag(TIF_IO_BITMAP); /* * Careful, clear this in the TSS too: */ @@ -373,7 +369,6 @@ void flush_thread(void) if (t->flags & _TIF_IA32) current_thread_info()->status |= TS_COMPAT; } - t->flags &= ~_TIF_DEBUG; tsk->thread.debugreg0 = 0; tsk->thread.debugreg1 = 0; @@ -466,7 +461,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, asm("mov %%es,%0" : "=m" (p->thread.es)); asm("mov %%ds,%0" : "=m" (p->thread.ds)); - if (unlikely(test_tsk_thread_flag(me, TIF_IO_BITMAP))) { + if (unlikely(me->thread.io_bitmap_ptr != NULL)) { p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); if (!p->thread.io_bitmap_ptr) { p->thread.io_bitmap_max = 0; @@ -474,7 +469,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, } memcpy(p->thread.io_bitmap_ptr, me->thread.io_bitmap_ptr, IO_BITMAP_BYTES); - set_tsk_thread_flag(p, TIF_IO_BITMAP); } /* @@ -504,40 +498,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp, */ #define loaddebug(thread,r) set_debugreg(thread->debugreg ## r, r) -static inline void __switch_to_xtra(struct task_struct *prev_p, - struct task_struct *next_p, - struct tss_struct *tss) -{ - struct thread_struct *prev, *next; - - prev = &prev_p->thread, - next = &next_p->thread; - - if (test_tsk_thread_flag(next_p, TIF_DEBUG)) { - loaddebug(next, 0); - loaddebug(next, 1); - loaddebug(next, 2); - loaddebug(next, 3); - /* no 4 and 5 */ - loaddebug(next, 6); - loaddebug(next, 7); - } - - if (test_tsk_thread_flag(next_p, TIF_IO_BITMAP)) { - /* - * Copy the relevant range of the IO bitmap. - * Normally this is 128 bytes or less: - */ - memcpy(tss->io_bitmap, next->io_bitmap_ptr, - max(prev->io_bitmap_max, next->io_bitmap_max)); - } else if (test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) { - /* - * Clear any possible leftover bits: - */ - memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); - } -} - /* * switch_to(x,y) should switch tasks from x to y. * @@ -555,10 +515,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) int cpu = smp_processor_id(); struct tss_struct *tss = &per_cpu(init_tss, cpu); - /* we're going to use this soon, after a few expensive things */ - if (next_p->fpu_counter>5) - prefetch(&next->i387.fxsave); - /* * Reload esp0, LDT and the page table pointer: */ @@ -627,29 +583,41 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) And the AMD workaround requires it to be after DS reload. */ unlazy_fpu(prev_p); write_pda(kernelstack, - (unsigned long)task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); -#ifdef CONFIG_CC_STACKPROTECTOR - write_pda(stack_canary, next_p->stack_canary); - /* - * Build time only check to make sure the stack_canary is at - * offset 40 in the pda; this is a gcc ABI requirement - */ - BUILD_BUG_ON(offsetof(struct x8664_pda, stack_canary) != 40); -#endif + task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); /* - * Now maybe reload the debug registers and handle I/O bitmaps + * Now maybe reload the debug registers */ - if (unlikely((task_thread_info(next_p)->flags & _TIF_WORK_CTXSW)) - || test_tsk_thread_flag(prev_p, TIF_IO_BITMAP)) - __switch_to_xtra(prev_p, next_p, tss); + if (unlikely(next->debugreg7)) { + loaddebug(next, 0); + loaddebug(next, 1); + loaddebug(next, 2); + loaddebug(next, 3); + /* no 4 and 5 */ + loaddebug(next, 6); + loaddebug(next, 7); + } + + + /* + * Handle the IO bitmap + */ + if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) { + if (next->io_bitmap_ptr) + /* + * Copy the relevant range of the IO bitmap. + * Normally this is 128 bytes or less: + */ + memcpy(tss->io_bitmap, next->io_bitmap_ptr, + max(prev->io_bitmap_max, next->io_bitmap_max)); + else { + /* + * Clear any possible leftover bits: + */ + memset(tss->io_bitmap, 0xff, prev->io_bitmap_max); + } + } - /* If the task has used fpu the last 5 timeslices, just do a full - * restore of the math state immediately to avoid the trap; the - * chances of needing FPU soon are obviously high now - */ - if (next_p->fpu_counter>5) - math_state_restore(); return prev_p; } @@ -866,7 +834,7 @@ int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) unsigned long arch_align_stack(unsigned long sp) { - if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) + if (randomize_va_space) sp -= get_random_int() % 8192; return sp & ~0xf; } diff --git a/trunk/arch/x86_64/kernel/ptrace.c b/trunk/arch/x86_64/kernel/ptrace.c index addc14af0c56..2d50024c9f30 100644 --- a/trunk/arch/x86_64/kernel/ptrace.c +++ b/trunk/arch/x86_64/kernel/ptrace.c @@ -116,17 +116,17 @@ unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *r return addr; } -static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs) +static int is_at_popf(struct task_struct *child, struct pt_regs *regs) { int i, copied; - unsigned char opcode[15]; + unsigned char opcode[16]; unsigned long addr = convert_rip_to_linear(child, regs); copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); for (i = 0; i < copied; i++) { switch (opcode[i]) { - /* popf and iret */ - case 0x9d: case 0xcf: + /* popf */ + case 0x9d: return 1; /* CHECKME: 64 65 */ @@ -138,17 +138,14 @@ static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs) case 0x26: case 0x2e: case 0x36: case 0x3e: case 0x64: case 0x65: - case 0xf2: case 0xf3: + case 0xf0: case 0xf2: case 0xf3: continue; + /* REX prefixes */ case 0x40 ... 0x4f: - if (regs->cs != __USER_CS) - /* 32-bit mode: register increment */ - return 0; - /* 64-bit mode: REX prefix */ continue; - /* CHECKME: f2, f3 */ + /* CHECKME: f0, f2, f3 */ /* * pushf: NOTE! We should probably not let @@ -189,8 +186,10 @@ static void set_singlestep(struct task_struct *child) * ..but if TF is changed by the instruction we will trace, * don't mark it as being "us" that set it, so that we * won't clear it by hand later. + * + * AK: this is not enough, LAHF and IRET can change TF in user space too. */ - if (is_setting_trap_flag(child, regs)) + if (is_at_popf(child, regs)) return; child->ptrace |= PT_DTRACE; @@ -421,13 +420,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) if ((0x5554 >> ((data >> (16 + 4*i)) & 0xf)) & 1) break; if (i == 4) { - child->thread.debugreg7 = data; - if (data) - set_tsk_thread_flag(child, TIF_DEBUG); - else - clear_tsk_thread_flag(child, TIF_DEBUG); + child->thread.debugreg7 = data; ret = 0; - } + } break; } break; diff --git a/trunk/arch/x86_64/kernel/relocate_kernel.S b/trunk/arch/x86_64/kernel/relocate_kernel.S index 14e95872c6a3..d24fa9b72a2b 100644 --- a/trunk/arch/x86_64/kernel/relocate_kernel.S +++ b/trunk/arch/x86_64/kernel/relocate_kernel.S @@ -7,169 +7,31 @@ */ #include -#include -#include -/* - * Must be relocatable PIC code callable as a C function - */ - -#define PTR(x) (x << 3) -#define PAGE_ALIGNED (1 << PAGE_SHIFT) -#define PAGE_ATTR 0x63 /* _PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY */ - - .text - .align PAGE_ALIGNED - .code64 - .globl relocate_kernel -relocate_kernel: - /* %rdi indirection_page - * %rsi page_list - * %rdx start address + /* + * Must be relocatable PIC code callable as a C function, that once + * it starts can not use the previous processes stack. */ - - /* map the control page at its virtual address */ - - movq $0x0000ff8000000000, %r10 /* mask */ - mov $(39 - 3), %cl /* bits to shift */ - movq PTR(VA_CONTROL_PAGE)(%rsi), %r11 /* address to map */ - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PGD)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_PUD_0)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - shrq $9, %r10 - sub $9, %cl - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PUD_0)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_PMD_0)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - shrq $9, %r10 - sub $9, %cl - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PMD_0)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_PTE_0)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - shrq $9, %r10 - sub $9, %cl - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PTE_0)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_CONTROL_PAGE)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - /* identity map the control page at its physical address */ - - movq $0x0000ff8000000000, %r10 /* mask */ - mov $(39 - 3), %cl /* bits to shift */ - movq PTR(PA_CONTROL_PAGE)(%rsi), %r11 /* address to map */ - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PGD)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_PUD_1)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - shrq $9, %r10 - sub $9, %cl - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PUD_1)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_PMD_1)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - shrq $9, %r10 - sub $9, %cl - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PMD_1)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_PTE_1)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - - shrq $9, %r10 - sub $9, %cl - - movq %r11, %r9 - andq %r10, %r9 - shrq %cl, %r9 - - movq PTR(VA_PTE_1)(%rsi), %r8 - addq %r8, %r9 - movq PTR(PA_CONTROL_PAGE)(%rsi), %r8 - orq $PAGE_ATTR, %r8 - movq %r8, (%r9) - + .globl relocate_new_kernel + .code64 relocate_new_kernel: - /* %rdi indirection_page - * %rsi page_list + /* %rdi page_list + * %rsi reboot_code_buffer * %rdx start address + * %rcx page_table + * %r8 arg5 + * %r9 arg6 */ /* zero out flags, and disable interrupts */ pushq $0 popfq - /* get physical address of control page now */ - /* this is impossible after page table switch */ - movq PTR(PA_CONTROL_PAGE)(%rsi), %r8 - - /* get physical address of page table now too */ - movq PTR(PA_TABLE_PAGE)(%rsi), %rcx + /* set a new stack at the bottom of our page... */ + lea 4096(%rsi), %rsp - /* switch to new set of page tables */ - movq PTR(PA_PGD)(%rsi), %r9 - movq %r9, %cr3 - - /* setup a new stack at the end of the physical control page */ - lea 4096(%r8), %rsp - - /* jump to identity mapped page */ - addq $(identity_mapped - relocate_kernel), %r8 - pushq %r8 - ret - -identity_mapped: - /* store the start address on the stack */ - pushq %rdx + /* store the parameters back on the stack */ + pushq %rdx /* store the start address */ /* Set cr0 to a known state: * 31 1 == Paging enabled @@ -274,3 +136,8 @@ identity_mapped: xorq %r15, %r15 ret +relocate_new_kernel_end: + + .globl relocate_new_kernel_size +relocate_new_kernel_size: + .quad relocate_new_kernel_end - relocate_new_kernel diff --git a/trunk/arch/x86_64/kernel/setup.c b/trunk/arch/x86_64/kernel/setup.c index fc944b5e8f4a..4b39f0da17f3 100644 --- a/trunk/arch/x86_64/kernel/setup.c +++ b/trunk/arch/x86_64/kernel/setup.c @@ -74,6 +74,16 @@ EXPORT_SYMBOL(boot_cpu_data); unsigned long mmu_cr4_features; +int acpi_disabled; +EXPORT_SYMBOL(acpi_disabled); +#ifdef CONFIG_ACPI +extern int __initdata acpi_ht; +extern acpi_interrupt_flags acpi_sci_flags; +int __initdata acpi_force = 0; +#endif + +int acpi_numa __initdata; + /* Boot loader ID as an integer, for the benefit of proc_dointvec */ int bootloader_type; @@ -97,6 +107,7 @@ struct sys_desc_table_struct { struct edid_info edid_info; EXPORT_SYMBOL_GPL(edid_info); +struct e820map e820; extern int root_mountflags; @@ -123,6 +134,9 @@ struct resource standard_io_resources[] = { .flags = IORESOURCE_BUSY | IORESOURCE_IO } }; +#define STANDARD_IO_RESOURCES \ + (sizeof standard_io_resources / sizeof standard_io_resources[0]) + #define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM) struct resource data_resource = { @@ -169,6 +183,9 @@ static struct resource adapter_rom_resources[] = { .flags = IORESOURCE_ROM } }; +#define ADAPTER_ROM_RESOURCES \ + (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0]) + static struct resource video_rom_resource = { .name = "Video ROM", .start = 0xc0000, @@ -239,8 +256,7 @@ static void __init probe_roms(void) } /* check for adapter roms on 2k boundaries */ - for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; - start += 2048) { + for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) { rom = isa_bus_to_virt(start); if (!romsignature(rom)) continue; @@ -260,22 +276,185 @@ static void __init probe_roms(void) } } -#ifdef CONFIG_PROC_VMCORE -/* elfcorehdr= specifies the location of elf core header - * stored by the crashed kernel. This option will be passed - * by kexec loader to the capture kernel. - */ -static int __init setup_elfcorehdr(char *arg) +/* Check for full argument with no trailing characters */ +static int fullarg(char *p, char *arg) { - char *end; - if (!arg) - return -EINVAL; - elfcorehdr_addr = memparse(arg, &end); - return end > arg ? 0 : -EINVAL; + int l = strlen(arg); + return !memcmp(p, arg, l) && (p[l] == 0 || isspace(p[l])); } -early_param("elfcorehdr", setup_elfcorehdr); + +static __init void parse_cmdline_early (char ** cmdline_p) +{ + char c = ' ', *to = command_line, *from = COMMAND_LINE; + int len = 0; + int userdef = 0; + + for (;;) { + if (c != ' ') + goto next_char; + +#ifdef CONFIG_SMP + /* + * If the BIOS enumerates physical processors before logical, + * maxcpus=N at enumeration-time can be used to disable HT. + */ + else if (!memcmp(from, "maxcpus=", 8)) { + extern unsigned int maxcpus; + + maxcpus = simple_strtoul(from + 8, NULL, 0); + } +#endif +#ifdef CONFIG_ACPI + /* "acpi=off" disables both ACPI table parsing and interpreter init */ + if (fullarg(from,"acpi=off")) + disable_acpi(); + + if (fullarg(from, "acpi=force")) { + /* add later when we do DMI horrors: */ + acpi_force = 1; + acpi_disabled = 0; + } + + /* acpi=ht just means: do ACPI MADT parsing + at bootup, but don't enable the full ACPI interpreter */ + if (fullarg(from, "acpi=ht")) { + if (!acpi_force) + disable_acpi(); + acpi_ht = 1; + } + else if (fullarg(from, "pci=noacpi")) + acpi_disable_pci(); + else if (fullarg(from, "acpi=noirq")) + acpi_noirq_set(); + + else if (fullarg(from, "acpi_sci=edge")) + acpi_sci_flags.trigger = 1; + else if (fullarg(from, "acpi_sci=level")) + acpi_sci_flags.trigger = 3; + else if (fullarg(from, "acpi_sci=high")) + acpi_sci_flags.polarity = 1; + else if (fullarg(from, "acpi_sci=low")) + acpi_sci_flags.polarity = 3; + + /* acpi=strict disables out-of-spec workarounds */ + else if (fullarg(from, "acpi=strict")) { + acpi_strict = 1; + } +#ifdef CONFIG_X86_IO_APIC + else if (fullarg(from, "acpi_skip_timer_override")) + acpi_skip_timer_override = 1; +#endif #endif + if (fullarg(from, "disable_timer_pin_1")) + disable_timer_pin_1 = 1; + if (fullarg(from, "enable_timer_pin_1")) + disable_timer_pin_1 = -1; + + if (fullarg(from, "nolapic") || fullarg(from, "disableapic")) { + clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); + disable_apic = 1; + } + + if (fullarg(from, "noapic")) + skip_ioapic_setup = 1; + + if (fullarg(from,"apic")) { + skip_ioapic_setup = 0; + ioapic_force = 1; + } + + if (!memcmp(from, "mem=", 4)) + parse_memopt(from+4, &from); + + if (!memcmp(from, "memmap=", 7)) { + /* exactmap option is for used defined memory */ + if (!memcmp(from+7, "exactmap", 8)) { +#ifdef CONFIG_CRASH_DUMP + /* If we are doing a crash dump, we + * still need to know the real mem + * size before original memory map is + * reset. + */ + saved_max_pfn = e820_end_of_ram(); +#endif + from += 8+7; + end_pfn_map = 0; + e820.nr_map = 0; + userdef = 1; + } + else { + parse_memmapopt(from+7, &from); + userdef = 1; + } + } + +#ifdef CONFIG_NUMA + if (!memcmp(from, "numa=", 5)) + numa_setup(from+5); +#endif + + if (!memcmp(from,"iommu=",6)) { + iommu_setup(from+6); + } + + if (fullarg(from,"oops=panic")) + panic_on_oops = 1; + + if (!memcmp(from, "noexec=", 7)) + nonx_setup(from + 7); + +#ifdef CONFIG_KEXEC + /* crashkernel=size@addr specifies the location to reserve for + * a crash kernel. By reserving this memory we guarantee + * that linux never set's it up as a DMA target. + * Useful for holding code to do something appropriate + * after a kernel panic. + */ + else if (!memcmp(from, "crashkernel=", 12)) { + unsigned long size, base; + size = memparse(from+12, &from); + if (*from == '@') { + base = memparse(from+1, &from); + /* FIXME: Do I want a sanity check + * to validate the memory range? + */ + crashk_res.start = base; + crashk_res.end = base + size - 1; + } + } +#endif + +#ifdef CONFIG_PROC_VMCORE + /* elfcorehdr= specifies the location of elf core header + * stored by the crashed kernel. This option will be passed + * by kexec loader to the capture kernel. + */ + else if(!memcmp(from, "elfcorehdr=", 11)) + elfcorehdr_addr = memparse(from+11, &from); +#endif + +#ifdef CONFIG_HOTPLUG_CPU + else if (!memcmp(from, "additional_cpus=", 16)) + setup_additional_cpus(from+16); +#endif + + next_char: + c = *(from++); + if (!c) + break; + if (COMMAND_LINE_SIZE <= ++len) + break; + *(to++) = c; + } + if (userdef) { + printk(KERN_INFO "user-defined physical RAM map:\n"); + e820_print_map("user"); + } + *to = '\0'; + *cmdline_p = command_line; +} + #ifndef CONFIG_NUMA static void __init contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) @@ -287,8 +466,7 @@ contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) if (bootmap == -1L) panic("Cannot find bootmem map of size %ld\n",bootmap_size); bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); - e820_register_active_regions(0, start_pfn, end_pfn); - free_bootmem_with_active_regions(0, end_pfn); + e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT); reserve_bootmem(bootmap, bootmap_size); } #endif @@ -343,8 +521,6 @@ static void discover_ebda(void) void __init setup_arch(char **cmdline_p) { - printk(KERN_INFO "Command line: %s\n", saved_command_line); - ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); screen_info = SCREEN_INFO; edid_info = EDID_INFO; @@ -371,22 +547,16 @@ void __init setup_arch(char **cmdline_p) data_resource.start = virt_to_phys(&_etext); data_resource.end = virt_to_phys(&_edata)-1; - early_identify_cpu(&boot_cpu_data); - - strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; - - parse_early_param(); + parse_cmdline_early(cmdline_p); - finish_e820_parsing(); + early_identify_cpu(&boot_cpu_data); - e820_register_active_regions(0, 0, -1UL); /* * partially used pages are not usable - thus * we are rounding upwards: */ end_pfn = e820_end_of_ram(); - num_physpages = end_pfn; + num_physpages = end_pfn; /* for pfn_valid */ check_efer(); @@ -406,14 +576,6 @@ void __init setup_arch(char **cmdline_p) acpi_boot_table_init(); #endif - /* How many end-of-memory variables you have, grandma! */ - max_low_pfn = end_pfn; - max_pfn = end_pfn; - high_memory = (void *)__va(end_pfn * PAGE_SIZE - 1) + 1; - - /* Remove active ranges so rediscovery with NUMA-awareness happens */ - remove_all_active_ranges(); - #ifdef CONFIG_ACPI_NUMA /* * Parse SRAT to discover nodes. @@ -463,10 +625,12 @@ void __init setup_arch(char **cmdline_p) */ acpi_reserve_bootmem(); #endif +#ifdef CONFIG_X86_LOCAL_APIC /* * Find and reserve possible boot-time SMP configuration: */ find_smp_config(); +#endif #ifdef CONFIG_BLK_DEV_INITRD if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) { @@ -493,9 +657,7 @@ void __init setup_arch(char **cmdline_p) paging_init(); -#ifdef CONFIG_PCI - early_quirks(); -#endif + check_ioapic(); /* * set this early, so we dont allocate cpu0 @@ -512,12 +674,14 @@ void __init setup_arch(char **cmdline_p) init_cpu_to_node(); +#ifdef CONFIG_X86_LOCAL_APIC /* * get boot-time SMP configuration: */ if (smp_found_config) get_smp_config(); init_apic_mappings(); +#endif /* * Request address space for all standard RAM and ROM resources @@ -532,7 +696,7 @@ void __init setup_arch(char **cmdline_p) { unsigned i; /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) + for (i = 0; i < STANDARD_IO_RESOURCES; i++) request_resource(&ioport_resource, &standard_io_resources[i]); } @@ -675,7 +839,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) #endif } -static void __cpuinit init_amd(struct cpuinfo_x86 *c) +static void __init init_amd(struct cpuinfo_x86 *c) { unsigned level; @@ -731,12 +895,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) /* Fix cpuid4 emulation for more */ num_cache_leaves = 3; - - /* When there is only one core no need to synchronize RDTSC */ - if (num_possible_cpus() == 1) - set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); - else - clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); } static void __cpuinit detect_ht(struct cpuinfo_x86 *c) @@ -818,7 +976,8 @@ static void srat_detect_node(void) node = first_node(node_online_map); numa_set_node(cpu, node); - printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); + if (acpi_numa > 0) + printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node); #endif } @@ -852,8 +1011,6 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) if ((c->x86 == 0xf && c->x86_model >= 0x03) || (c->x86 == 0x6 && c->x86_model >= 0x0e)) set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); - if (c->x86 == 6) - set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); c->x86_max_cores = intel_num_cpu_cores(c); @@ -1072,8 +1229,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) /* Intel-defined (#2) */ "pni", NULL, NULL, "monitor", "ds_cpl", "vmx", "smx", "est", - "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL, - NULL, NULL, "dca", NULL, NULL, NULL, NULL, NULL, + "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* VIA/Cyrix/Centaur-defined */ diff --git a/trunk/arch/x86_64/kernel/setup64.c b/trunk/arch/x86_64/kernel/setup64.c index 8c4b80fe71a1..417de564456e 100644 --- a/trunk/arch/x86_64/kernel/setup64.c +++ b/trunk/arch/x86_64/kernel/setup64.c @@ -24,7 +24,7 @@ #include #include -char x86_boot_params[BOOT_PARAM_SIZE] __initdata; +char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,}; cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; @@ -46,10 +46,8 @@ Control non executable mappings for 64bit processes. on Enable(default) off Disable */ -static int __init nonx_setup(char *str) +int __init nonx_setup(char *str) { - if (!str) - return -EINVAL; if (!strncmp(str, "on", 2)) { __supported_pte_mask |= _PAGE_NX; do_not_nx = 0; @@ -57,9 +55,9 @@ static int __init nonx_setup(char *str) do_not_nx = 1; __supported_pte_mask &= ~_PAGE_NX; } - return 0; + return 1; } -early_param("noexec", nonx_setup); +__setup("noexec=", nonx_setup); /* parsed early actually */ int force_personality32 = 0; @@ -95,9 +93,12 @@ void __init setup_per_cpu_areas(void) #endif /* Copy section for each CPU (we discard the original) */ - size = PERCPU_ENOUGH_ROOM; + size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES); +#ifdef CONFIG_MODULES + if (size < PERCPU_ENOUGH_ROOM) + size = PERCPU_ENOUGH_ROOM; +#endif - printk(KERN_INFO "PERCPU: Allocating %lu bytes of per cpu data\n", size); for_each_cpu_mask (i, cpu_possible_map) { char *ptr; @@ -121,10 +122,7 @@ void pda_init(int cpu) /* Setup up data that may be needed in __get_free_pages early */ asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0)); - /* Memory clobbers used to order PDA accessed */ - mb(); wrmsrl(MSR_GS_BASE, pda); - mb(); pda->cpunumber = cpu; pda->irqcount = -1; @@ -180,8 +178,6 @@ void __cpuinit check_efer(void) } } -unsigned long kernel_eflags; - /* * cpu_init() initializes state that is per-CPU. Some data is already * initialized (naturally) in the bootstrap process, such as the GDT @@ -239,17 +235,28 @@ void __cpuinit cpu_init (void) * set up and load the per-CPU TSS */ for (v = 0; v < N_EXCEPTION_STACKS; v++) { - static const unsigned int order[N_EXCEPTION_STACKS] = { - [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, - [DEBUG_STACK - 1] = DEBUG_STACK_ORDER - }; if (cpu) { + static const unsigned int order[N_EXCEPTION_STACKS] = { + [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER, + [DEBUG_STACK - 1] = DEBUG_STACK_ORDER + }; + estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]); if (!estacks) panic("Cannot allocate exception stack %ld %d\n", v, cpu); } - estacks += PAGE_SIZE << order[v]; + switch (v + 1) { +#if DEBUG_STKSZ > EXCEPTION_STKSZ + case DEBUG_STACK: + cpu_pda(cpu)->debugstack = (unsigned long)estacks; + estacks += DEBUG_STKSZ; + break; +#endif + default: + estacks += EXCEPTION_STKSZ; + break; + } orig_ist->ist[v] = t->ist[v] = (unsigned long)estacks; } @@ -283,6 +290,4 @@ void __cpuinit cpu_init (void) set_debugreg(0UL, 7); fpu_init(); - - raw_local_save_flags(kernel_eflags); } diff --git a/trunk/arch/x86_64/kernel/signal.c b/trunk/arch/x86_64/kernel/signal.c index 49ec324cd141..28161170fb0a 100644 --- a/trunk/arch/x86_64/kernel/signal.c +++ b/trunk/arch/x86_64/kernel/signal.c @@ -37,6 +37,37 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, int ia32_setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs); +asmlinkage long +sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *regs) +{ + sigset_t saveset, newset; + + /* XXX: Don't preclude handling different sized sigset_t's. */ + if (sigsetsize != sizeof(sigset_t)) + return -EINVAL; + + if (copy_from_user(&newset, unewset, sizeof(newset))) + return -EFAULT; + sigdelsetmask(&newset, ~_BLOCKABLE); + + spin_lock_irq(¤t->sighand->siglock); + saveset = current->blocked; + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); +#ifdef DEBUG_SIG + printk("rt_sigsuspend savset(%lx) newset(%lx) regs(%p) rip(%lx)\n", + saveset, newset, regs, regs->rip); +#endif + regs->rax = -EINTR; + while (1) { + current->state = TASK_INTERRUPTIBLE; + schedule(); + if (do_signal(regs, &saveset)) + return -EINTR; + } +} + asmlinkage long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, struct pt_regs *regs) @@ -277,6 +308,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, #endif /* Set up registers for signal handler */ + { + struct exec_domain *ed = current_thread_info()->exec_domain; + if (unlikely(ed && ed->signal_invmap && sig < 32)) + sig = ed->signal_invmap[sig]; + } regs->rdi = sig; /* In case the signal handler was declared without prototypes */ regs->rax = 0; @@ -305,11 +341,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, current->comm, current->pid, frame, regs->rip, frame->pretcode); #endif - return 0; + return 1; give_sigsegv: force_sigsegv(sig, current); - return -EFAULT; + return 0; } /* @@ -372,7 +408,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, #endif ret = setup_rt_frame(sig, ka, info, oldset, regs); - if (ret == 0) { + if (ret) { spin_lock_irq(¤t->sighand->siglock); sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); if (!(ka->sa.sa_flags & SA_NODEFER)) @@ -389,12 +425,11 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, * want to handle. Thus you cannot kill init even with a SIGKILL even by * mistake. */ -static void do_signal(struct pt_regs *regs) +int do_signal(struct pt_regs *regs, sigset_t *oldset) { struct k_sigaction ka; siginfo_t info; int signr; - sigset_t *oldset; /* * We want the common case to go fast, which @@ -403,11 +438,9 @@ static void do_signal(struct pt_regs *regs) * if so. */ if (!user_mode(regs)) - return; + return 1; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else + if (!oldset) oldset = ¤t->blocked; signr = get_signal_to_deliver(&info, &ka, regs, NULL); @@ -421,46 +454,30 @@ static void do_signal(struct pt_regs *regs) set_debugreg(current->thread.debugreg7, 7); /* Whee! Actually deliver the signal. */ - if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag */ - clear_thread_flag(TIF_RESTORE_SIGMASK); - } - return; + return handle_signal(signr, &info, &ka, oldset, regs); } /* Did we come from a system call? */ if ((long)regs->orig_rax >= 0) { /* Restart the system call - no handlers present */ long res = regs->rax; - switch (res) { - case -ERESTARTNOHAND: - case -ERESTARTSYS: - case -ERESTARTNOINTR: + if (res == -ERESTARTNOHAND || + res == -ERESTARTSYS || + res == -ERESTARTNOINTR) { regs->rax = regs->orig_rax; regs->rip -= 2; - break; - case -ERESTART_RESTARTBLOCK: + } + if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) { regs->rax = test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall; regs->rip -= 2; - break; } } - - /* if there's no signal to deliver, we just put the saved sigmask - back. */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } + return 0; } -void -do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) +void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, __u32 thread_info_flags) { #ifdef DEBUG_SIG printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%lx pending:%lx\n", @@ -474,8 +491,8 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) } /* deal with pending signal delivery */ - if (thread_info_flags & (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK)) - do_signal(regs); + if (thread_info_flags & _TIF_SIGPENDING) + do_signal(regs,oldset); } void signal_fault(struct pt_regs *regs, void __user *frame, char *where) diff --git a/trunk/arch/x86_64/kernel/smp.c b/trunk/arch/x86_64/kernel/smp.c index 4f67697f5036..06af6ca60129 100644 --- a/trunk/arch/x86_64/kernel/smp.c +++ b/trunk/arch/x86_64/kernel/smp.c @@ -522,3 +522,26 @@ asmlinkage void smp_call_function_interrupt(void) } } +int safe_smp_processor_id(void) +{ + unsigned apicid, i; + + if (disable_apic) + return 0; + + apicid = hard_smp_processor_id(); + if (apicid < NR_CPUS && x86_cpu_to_apicid[apicid] == apicid) + return apicid; + + for (i = 0; i < NR_CPUS; ++i) { + if (x86_cpu_to_apicid[i] == apicid) + return i; + } + + /* No entries in x86_cpu_to_apicid? Either no MPS|ACPI, + * or called too early. Either way, we must be CPU 0. */ + if (x86_cpu_to_apicid[0] == BAD_APICID) + return 0; + + return 0; /* Should not happen */ +} diff --git a/trunk/arch/x86_64/kernel/smpboot.c b/trunk/arch/x86_64/kernel/smpboot.c index 7b7a6870288a..3ae9ffddddc0 100644 --- a/trunk/arch/x86_64/kernel/smpboot.c +++ b/trunk/arch/x86_64/kernel/smpboot.c @@ -1091,6 +1091,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) /* * Switch from PIC to APIC mode. */ + connect_bsp_APIC(); setup_local_APIC(); if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id) { @@ -1175,9 +1176,12 @@ int __cpuinit __cpu_up(unsigned int cpu) void __init smp_cpus_done(unsigned int max_cpus) { smp_cleanup_boot(); + +#ifdef CONFIG_X86_IO_APIC setup_ioapic_dest(); +#endif + check_nmi_watchdog(); - time_init_gtod(); } #ifdef CONFIG_HOTPLUG_CPU @@ -1230,8 +1234,6 @@ int __cpu_disable(void) if (cpu == 0) return -EBUSY; - if (nmi_watchdog == NMI_LOCAL_APIC) - stop_apic_nmi_watchdog(NULL); clear_local_APIC(); /* @@ -1271,11 +1273,11 @@ void __cpu_die(unsigned int cpu) printk(KERN_ERR "CPU %u didn't die...\n", cpu); } -static __init int setup_additional_cpus(char *s) +__init int setup_additional_cpus(char *s) { - return s && get_option(&s, &additional_cpus) ? 0 : -EINVAL; + return get_option(&s, &additional_cpus); } -early_param("additional_cpus", setup_additional_cpus); +__setup("additional_cpus=", setup_additional_cpus); #else /* ... !CONFIG_HOTPLUG_CPU */ diff --git a/trunk/arch/x86_64/kernel/stacktrace.c b/trunk/arch/x86_64/kernel/stacktrace.c index 6026b31d037e..32cf55eb9af8 100644 --- a/trunk/arch/x86_64/kernel/stacktrace.c +++ b/trunk/arch/x86_64/kernel/stacktrace.c @@ -7,49 +7,215 @@ */ #include #include -#include -#include -static void save_stack_warning(void *data, char *msg) -{ -} +#include -static void -save_stack_warning_symbol(void *data, char *msg, unsigned long symbol) +static inline int +in_range(unsigned long start, unsigned long addr, unsigned long end) { + return addr >= start && addr <= end; } -static int save_stack_stack(void *data, char *name) +static unsigned long +get_stack_end(struct task_struct *task, unsigned long stack) { - struct stack_trace *trace = (struct stack_trace *)data; - return trace->all_contexts ? 0 : -1; + unsigned long stack_start, stack_end, flags; + int i, cpu; + + /* + * The most common case is that we are in the task stack: + */ + stack_start = (unsigned long)task->thread_info; + stack_end = stack_start + THREAD_SIZE; + + if (in_range(stack_start, stack, stack_end)) + return stack_end; + + /* + * We are in an interrupt if irqstackptr is set: + */ + raw_local_irq_save(flags); + cpu = safe_smp_processor_id(); + stack_end = (unsigned long)cpu_pda(cpu)->irqstackptr; + + if (stack_end) { + stack_start = stack_end & ~(IRQSTACKSIZE-1); + if (in_range(stack_start, stack, stack_end)) + goto out_restore; + /* + * We get here if we are in an IRQ context but we + * are also in an exception stack. + */ + } + + /* + * Iterate over all exception stacks, and figure out whether + * 'stack' is in one of them: + */ + for (i = 0; i < N_EXCEPTION_STACKS; i++) { + /* + * set 'end' to the end of the exception stack. + */ + stack_end = per_cpu(init_tss, cpu).ist[i]; + stack_start = stack_end - EXCEPTION_STKSZ; + + /* + * Is 'stack' above this exception frame's end? + * If yes then skip to the next frame. + */ + if (stack >= stack_end) + continue; + /* + * Is 'stack' above this exception frame's start address? + * If yes then we found the right frame. + */ + if (stack >= stack_start) + goto out_restore; + + /* + * If this is a debug stack, and if it has a larger size than + * the usual exception stacks, then 'stack' might still + * be within the lower portion of the debug stack: + */ +#if DEBUG_STKSZ > EXCEPTION_STKSZ + if (i == DEBUG_STACK - 1 && stack >= stack_end - DEBUG_STKSZ) { + /* + * Black magic. A large debug stack is composed of + * multiple exception stack entries, which we + * iterate through now. Dont look: + */ + do { + stack_end -= EXCEPTION_STKSZ; + stack_start -= EXCEPTION_STKSZ; + } while (stack < stack_start); + + goto out_restore; + } +#endif + } + /* + * Ok, 'stack' is not pointing to any of the system stacks. + */ + stack_end = 0; + +out_restore: + raw_local_irq_restore(flags); + + return stack_end; } -static void save_stack_address(void *data, unsigned long addr) + +/* + * Save stack-backtrace addresses into a stack_trace buffer: + */ +static inline unsigned long +save_context_stack(struct stack_trace *trace, unsigned int skip, + unsigned long stack, unsigned long stack_end) { - struct stack_trace *trace = (struct stack_trace *)data; - if (trace->skip > 0) { - trace->skip--; - return; + unsigned long addr; + +#ifdef CONFIG_FRAME_POINTER + unsigned long prev_stack = 0; + + while (in_range(prev_stack, stack, stack_end)) { + pr_debug("stack: %p\n", (void *)stack); + addr = (unsigned long)(((unsigned long *)stack)[1]); + pr_debug("addr: %p\n", (void *)addr); + if (!skip) + trace->entries[trace->nr_entries++] = addr-1; + else + skip--; + if (trace->nr_entries >= trace->max_entries) + break; + if (!addr) + return 0; + /* + * Stack frames must go forwards (otherwise a loop could + * happen if the stackframe is corrupted), so we move + * prev_stack forwards: + */ + prev_stack = stack; + stack = (unsigned long)(((unsigned long *)stack)[0]); } - if (trace->nr_entries < trace->max_entries - 1) - trace->entries[trace->nr_entries++] = addr; + pr_debug("invalid: %p\n", (void *)stack); +#else + while (stack < stack_end) { + addr = ((unsigned long *)stack)[0]; + stack += sizeof(long); + if (__kernel_text_address(addr)) { + if (!skip) + trace->entries[trace->nr_entries++] = addr-1; + else + skip--; + if (trace->nr_entries >= trace->max_entries) + break; + } + } +#endif + return stack; } -static struct stacktrace_ops save_stack_ops = { - .warning = save_stack_warning, - .warning_symbol = save_stack_warning_symbol, - .stack = save_stack_stack, - .address = save_stack_address, -}; +#define MAX_STACKS 10 /* * Save stack-backtrace addresses into a stack_trace buffer. + * If all_contexts is set, all contexts (hardirq, softirq and process) + * are saved. If not set then only the current context is saved. */ -void save_stack_trace(struct stack_trace *trace, struct task_struct *task) +void save_stack_trace(struct stack_trace *trace, + struct task_struct *task, int all_contexts, + unsigned int skip) { - dump_trace(task, NULL, NULL, &save_stack_ops, trace); - trace->entries[trace->nr_entries++] = ULONG_MAX; + unsigned long stack = (unsigned long)&stack; + int i, nr_stacks = 0, stacks_done[MAX_STACKS]; + + WARN_ON(trace->nr_entries || !trace->max_entries); + + if (!task) + task = current; + + pr_debug("task: %p, ti: %p\n", task, task->thread_info); + + if (!task || task == current) { + /* Grab rbp right from our regs: */ + asm ("mov %%rbp, %0" : "=r" (stack)); + pr_debug("rbp: %p\n", (void *)stack); + } else { + /* rbp is the last reg pushed by switch_to(): */ + stack = task->thread.rsp; + pr_debug("other task rsp: %p\n", (void *)stack); + stack = (unsigned long)(((unsigned long *)stack)[0]); + pr_debug("other task rbp: %p\n", (void *)stack); + } + + while (1) { + unsigned long stack_end = get_stack_end(task, stack); + + pr_debug("stack: %p\n", (void *)stack); + pr_debug("stack end: %p\n", (void *)stack_end); + + /* + * Invalid stack addres? + */ + if (!stack_end) + return; + /* + * Were we in this stack already? (recursion) + */ + for (i = 0; i < nr_stacks; i++) + if (stacks_done[i] == stack_end) + return; + stacks_done[nr_stacks] = stack_end; + + stack = save_context_stack(trace, skip, stack, stack_end); + if (!all_contexts || !stack || + trace->nr_entries >= trace->max_entries) + return; + trace->entries[trace->nr_entries++] = ULONG_MAX; + if (trace->nr_entries >= trace->max_entries) + return; + if (++nr_stacks >= MAX_STACKS) + return; + } } -EXPORT_SYMBOL(save_stack_trace); diff --git a/trunk/arch/x86_64/kernel/sys_x86_64.c b/trunk/arch/x86_64/kernel/sys_x86_64.c index 76bf7c241fe4..6449ea8fe756 100644 --- a/trunk/arch/x86_64/kernel/sys_x86_64.c +++ b/trunk/arch/x86_64/kernel/sys_x86_64.c @@ -148,7 +148,7 @@ asmlinkage long sys_uname(struct new_utsname __user * name) { int err; down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof (*name)); + err = copy_to_user(name, &system_utsname, sizeof (*name)); up_read(&uts_sem); if (personality(current->personality) == PER_LINUX32) err |= copy_to_user(&name->machine, "i686", 5); diff --git a/trunk/arch/x86_64/kernel/tce.c b/trunk/arch/x86_64/kernel/tce.c index cbabfdf78e06..5530dda3f27a 100644 --- a/trunk/arch/x86_64/kernel/tce.c +++ b/trunk/arch/x86_64/kernel/tce.c @@ -1,6 +1,4 @@ /* - * This file manages the translation entries for the IBM Calgary IOMMU. - * * Derived from arch/powerpc/platforms/pseries/iommu.c * * Copyright (C) IBM Corporation, 2006 @@ -106,6 +104,14 @@ static int tce_table_setparms(struct pci_dev *dev, struct iommu_table *tbl) /* set the tce table size - measured in entries */ tbl->it_size = table_size_to_number_of_entries(specified_table_size); + tbl->it_base = (unsigned long)tce_table_kva[dev->bus->number]; + if (!tbl->it_base) { + printk(KERN_ERR "Calgary: iommu_table_setparms: " + "no table allocated?!\n"); + ret = -ENOMEM; + goto done; + } + /* * number of bytes needed for the bitmap size in number of * entries; we need one bit per entry @@ -154,6 +160,8 @@ int build_tce_table(struct pci_dev *dev, void __iomem *bbar) if (ret) goto free_tbl; + tce_free(tbl, 0, tbl->it_size); + tbl->bbar = bbar; /* diff --git a/trunk/arch/x86_64/kernel/time.c b/trunk/arch/x86_64/kernel/time.c index 557e92af7bea..7700e6cd2bd9 100644 --- a/trunk/arch/x86_64/kernel/time.c +++ b/trunk/arch/x86_64/kernel/time.c @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include #ifdef CONFIG_ACPI @@ -41,7 +39,9 @@ #include #include #include +#ifdef CONFIG_X86_LOCAL_APIC #include +#endif #ifdef CONFIG_CPU_FREQ static void cpufreq_delayed_get(void); @@ -49,7 +49,7 @@ static void cpufreq_delayed_get(void); extern void i8254_timer_resume(void); extern int using_apic_timer; -static char *timename = NULL; +static char *time_init_gtod(void); DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -77,6 +77,7 @@ unsigned long long monotonic_base; struct vxtime_data __vxtime __section_vxtime; /* for vsyscalls */ volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES; +unsigned long __wall_jiffies __section_wall_jiffies = INITIAL_JIFFIES; struct timespec __xtime __section_xtime; struct timezone __sys_tz __section_sys_tz; @@ -118,7 +119,7 @@ unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc; void do_gettimeofday(struct timeval *tv) { - unsigned long seq; + unsigned long seq, t; unsigned int sec, usec; do { @@ -135,7 +136,10 @@ void do_gettimeofday(struct timeval *tv) be found. Note when you fix it here you need to do the same in arch/x86_64/kernel/vsyscall.c and export all needed variables in vmlinux.lds. -AK */ - usec += do_gettimeoffset(); + + t = (jiffies - wall_jiffies) * USEC_PER_TICK + + do_gettimeoffset(); + usec += t; } while (read_seqretry(&xtime_lock, seq)); @@ -161,7 +165,8 @@ int do_settimeofday(struct timespec *tv) write_seqlock_irq(&xtime_lock); - nsec -= do_gettimeoffset() * NSEC_PER_USEC; + nsec -= do_gettimeoffset() * NSEC_PER_USEC + + (jiffies - wall_jiffies) * NSEC_PER_TICK; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -182,15 +187,20 @@ unsigned long profile_pc(struct pt_regs *regs) { unsigned long pc = instruction_pointer(regs); - /* Assume the lock function has either no stack frame or a copy - of eflags from PUSHF - Eflags always has bits 22 and up cleared unlike kernel addresses. */ + /* Assume the lock function has either no stack frame or only a single + word. This checks if the address on the stack looks like a kernel + text address. + There is a small window for false hits, but in that case the tick + is just accounted to the spinlock function. + Better would be to write these functions in assembler again + and check exactly. */ if (!user_mode(regs) && in_lock_functions(pc)) { - unsigned long *sp = (unsigned long *)regs->rsp; - if (sp[0] >> 22) - return sp[0]; - if (sp[1] >> 22) - return sp[1]; + char *v = *(char **)regs->rsp; + if ((v >= _stext && v <= _etext) || + (v >= _sinittext && v <= _einittext) || + (v >= (char *)MODULES_VADDR && v <= (char *)MODULES_END)) + return (unsigned long)v; + return ((unsigned long *)regs->rsp)[1]; } return pc; } @@ -271,7 +281,6 @@ static void set_rtc_mmss(unsigned long nowtime) * Note: This function is required to return accurate * time even in the absence of multiple timer ticks. */ -static inline unsigned long long cycles_2_ns(unsigned long long cyc); unsigned long long monotonic_clock(void) { unsigned long seq; @@ -296,7 +305,8 @@ unsigned long long monotonic_clock(void) base = monotonic_base; } while (read_seqretry(&xtime_lock, seq)); this_offset = get_cycles_sync(); - offset = cycles_2_ns(this_offset - last_offset); + /* FIXME: 1000 or 1000000? */ + offset = (this_offset - last_offset)*1000 / cpu_khz; } return base + offset; } @@ -400,7 +410,8 @@ void main_timer_handler(struct pt_regs *regs) offset %= USEC_PER_TICK; } - monotonic_base += cycles_2_ns(tsc - vxtime.last_tsc); + /* FIXME: 1000 or 1000000? */ + monotonic_base += (tsc - vxtime.last_tsc) * 1000000 / cpu_khz; vxtime.last_tsc = tsc - vxtime.quot * delay / vxtime.tsc_quot; @@ -410,16 +421,16 @@ void main_timer_handler(struct pt_regs *regs) (((long) offset << US_SCALE) / vxtime.tsc_quot) - 1; } - if (lost > 0) + if (lost > 0) { handle_lost_ticks(lost, regs); - else - lost = 0; + jiffies += lost; + } /* * Do the timer stuff. */ - do_timer(lost + 1); + do_timer(regs); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -430,8 +441,12 @@ void main_timer_handler(struct pt_regs *regs) * have to call the local interrupt handler. */ +#ifndef CONFIG_X86_LOCAL_APIC + profile_tick(CPU_PROFILING, regs); +#else if (!using_apic_timer) smp_local_timer_interrupt(regs); +#endif /* * If we have an externally synchronized Linux clock, then update CMOS clock @@ -455,8 +470,10 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (apic_runs_main_timer > 1) return IRQ_HANDLED; main_timer_handler(regs); +#ifdef CONFIG_X86_LOCAL_APIC if (using_apic_timer) smp_send_timer_broadcast_ipi(); +#endif return IRQ_HANDLED; } @@ -876,17 +893,11 @@ static struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL }; -static int __cpuinit -time_cpu_notifier(struct notifier_block *nb, unsigned long action, void *hcpu) -{ - unsigned cpu = (unsigned long) hcpu; - if (action == CPU_ONLINE) - vsyscall_set_cpu(cpu); - return NOTIFY_DONE; -} - void __init time_init(void) { + char *timename; + char *gtod; + if (nohpet) vxtime.hpet_address = 0; @@ -920,17 +931,18 @@ void __init time_init(void) } vxtime.mode = VXTIME_TSC; + gtod = time_init_gtod(); + + printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n", + vxtime_hz / 1000000, vxtime_hz % 1000000, timename, gtod); + printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", + cpu_khz / 1000, cpu_khz % 1000); vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz; vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz; vxtime.last_tsc = get_cycles_sync(); - set_cyc2ns_scale(cpu_khz); setup_irq(0, &irq0); - hotcpu_notifier(time_cpu_notifier, 0); - time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id()); -#ifndef CONFIG_SMP - time_init_gtod(); -#endif + set_cyc2ns_scale(cpu_khz); } /* @@ -961,18 +973,12 @@ __cpuinit int unsynchronized_tsc(void) /* * Decide what mode gettimeofday should use. */ -void time_init_gtod(void) +__init static char *time_init_gtod(void) { char *timetype; if (unsynchronized_tsc()) notsc = 1; - - if (cpu_has(&boot_cpu_data, X86_FEATURE_RDTSCP)) - vgetcpu_mode = VGETCPU_RDTSCP; - else - vgetcpu_mode = VGETCPU_LSL; - if (vxtime.hpet_address && notsc) { timetype = hpet_use_timer ? "HPET" : "PIT/HPET"; if (hpet_use_timer) @@ -995,16 +1001,7 @@ void time_init_gtod(void) timetype = hpet_use_timer ? "HPET/TSC" : "PIT/TSC"; vxtime.mode = VXTIME_TSC; } - - printk(KERN_INFO "time.c: Using %ld.%06ld MHz WALL %s GTOD %s timer.\n", - vxtime_hz / 1000000, vxtime_hz % 1000000, timename, timetype); - printk(KERN_INFO "time.c: Detected %d.%03d MHz processor.\n", - cpu_khz / 1000, cpu_khz % 1000); - vxtime.quot = (USEC_PER_SEC << US_SCALE) / vxtime_hz; - vxtime.tsc_quot = (USEC_PER_MSEC << US_SCALE) / cpu_khz; - vxtime.last_tsc = get_cycles_sync(); - - set_cyc2ns_scale(cpu_khz); + return timetype; } __setup("report_lost_ticks", time_setup); @@ -1034,16 +1031,8 @@ static int timer_resume(struct sys_device *dev) unsigned long flags; unsigned long sec; unsigned long ctime = get_cmos_time(); - long sleep_length = (ctime - sleep_start) * HZ; + unsigned long sleep_length = (ctime - sleep_start) * HZ; - if (sleep_length < 0) { - printk(KERN_WARNING "Time skew detected in timer resume!\n"); - /* The time after the resume must not be earlier than the time - * before the suspend or some nasty things will happen - */ - sleep_length = 0; - ctime = sleep_start; - } if (vxtime.hpet_address) hpet_reenable(); else @@ -1066,6 +1055,7 @@ static int timer_resume(struct sys_device *dev) vxtime.last_tsc = get_cycles_sync(); write_sequnlock_irqrestore(&xtime_lock,flags); jiffies += sleep_length; + wall_jiffies += sleep_length; monotonic_base += sleep_length * (NSEC_PER_SEC/HZ); touch_softlockup_watchdog(); return 0; diff --git a/trunk/arch/x86_64/kernel/trampoline.S b/trunk/arch/x86_64/kernel/trampoline.S index c79b99a9e2f6..23a03eb91fc7 100644 --- a/trunk/arch/x86_64/kernel/trampoline.S +++ b/trunk/arch/x86_64/kernel/trampoline.S @@ -64,7 +64,7 @@ idt_48: .word 0, 0 # idt base = 0L gdt_48: - .short GDT_ENTRIES*8 - 1 # gdt limit + .short __KERNEL32_CS + 7 # gdt limit .long cpu_gdt_table-__START_KERNEL_map .globl trampoline_end diff --git a/trunk/arch/x86_64/kernel/traps.c b/trunk/arch/x86_64/kernel/traps.c index 01f2a8d254c2..b1249774d1e8 100644 --- a/trunk/arch/x86_64/kernel/traps.c +++ b/trunk/arch/x86_64/kernel/traps.c @@ -45,7 +45,6 @@ #include #include #include -#include asmlinkage void divide_error(void); asmlinkage void debug(void); @@ -143,7 +142,7 @@ void printk_address(unsigned long address) #endif static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, - unsigned *usedp, char **idp) + unsigned *usedp, const char **idp) { static char ids[][8] = { [DEBUG_STACK - 1] = "#DB", @@ -162,7 +161,26 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, * 'stack' is in one of them: */ for (k = 0; k < N_EXCEPTION_STACKS; k++) { - unsigned long end = per_cpu(orig_ist, cpu).ist[k]; + unsigned long end; + + /* + * set 'end' to the end of the exception stack. + */ + switch (k + 1) { + /* + * TODO: this block is not needed i think, because + * setup64.c:cpu_init() sets up t->ist[DEBUG_STACK] + * properly too. + */ +#if DEBUG_STKSZ > EXCEPTION_STKSZ + case DEBUG_STACK: + end = cpu_pda(cpu)->debugstack + DEBUG_STKSZ; + break; +#endif + default: + end = per_cpu(orig_ist, cpu).ist[k]; + break; + } /* * Is 'stack' above this exception frame's end? * If yes then skip to the next frame. @@ -216,19 +234,13 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack, return NULL; } -struct ops_and_data { - struct stacktrace_ops *ops; - void *data; -}; - -static int dump_trace_unwind(struct unwind_frame_info *info, void *context) +static int show_trace_unwind(struct unwind_frame_info *info, void *context) { - struct ops_and_data *oad = (struct ops_and_data *)context; int n = 0; while (unwind(info) == 0 && UNW_PC(info)) { n++; - oad->ops->address(oad->data, UNW_PC(info)); + printk_address(UNW_PC(info)); if (arch_unw_user_mode(info)) break; } @@ -242,53 +254,45 @@ static int dump_trace_unwind(struct unwind_frame_info *info, void *context) * severe exception (double fault, nmi, stack fault, debug, mce) hardware stack */ -void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack, - struct stacktrace_ops *ops, void *data) +void show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * stack) { - const unsigned cpu = smp_processor_id(); + const unsigned cpu = safe_smp_processor_id(); unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; unsigned used = 0; + printk("\nCall Trace:\n"); + if (!tsk) tsk = current; if (call_trace >= 0) { int unw_ret = 0; struct unwind_frame_info info; - struct ops_and_data oad = { .ops = ops, .data = data }; if (regs) { if (unwind_init_frame_info(&info, tsk, regs) == 0) - unw_ret = dump_trace_unwind(&info, &oad); + unw_ret = show_trace_unwind(&info, NULL); } else if (tsk == current) - unw_ret = unwind_init_running(&info, dump_trace_unwind, &oad); + unw_ret = unwind_init_running(&info, show_trace_unwind, NULL); else { if (unwind_init_blocked(&info, tsk) == 0) - unw_ret = dump_trace_unwind(&info, &oad); + unw_ret = show_trace_unwind(&info, NULL); } if (unw_ret > 0) { if (call_trace == 1 && !arch_unw_user_mode(&info)) { - ops->warning_symbol(data, "DWARF2 unwinder stuck at %s\n", + print_symbol("DWARF2 unwinder stuck at %s\n", UNW_PC(&info)); if ((long)UNW_SP(&info) < 0) { - ops->warning(data, "Leftover inexact backtrace:\n"); + printk("Leftover inexact backtrace:\n"); stack = (unsigned long *)UNW_SP(&info); - if (!stack) - return; } else - ops->warning(data, "Full inexact backtrace again:\n"); + printk("Full inexact backtrace again:\n"); } else if (call_trace >= 1) return; else - ops->warning(data, "Full inexact backtrace again:\n"); + printk("Full inexact backtrace again:\n"); } else - ops->warning(data, "Inexact backtrace:\n"); - } - if (!stack) { - unsigned long dummy; - stack = &dummy; - if (tsk && tsk != current) - stack = (unsigned long *)tsk->thread.rsp; + printk("Inexact backtrace:\n"); } /* @@ -299,9 +303,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s #define HANDLE_STACK(cond) \ do while (cond) { \ unsigned long addr = *stack++; \ - if (oops_in_progress ? \ - __kernel_text_address(addr) : \ - kernel_text_address(addr)) { \ + if (kernel_text_address(addr)) { \ /* \ * If the address is either in the text segment of the \ * kernel, or in the region which contains vmalloc'ed \ @@ -310,7 +312,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s * down the cause of the crash will be able to figure \ * out the call path that was taken. \ */ \ - ops->address(data, addr); \ + printk_address(addr); \ } \ } while (0) @@ -319,17 +321,16 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s * current stack address. If the stacks consist of nested * exceptions */ - for (;;) { - char *id; + for ( ; ; ) { + const char *id; unsigned long *estack_end; estack_end = in_exception_stack(cpu, (unsigned long)stack, &used, &id); if (estack_end) { - if (ops->stack(data, id) < 0) - break; + printk(" <%s>", id); HANDLE_STACK (stack < estack_end); - ops->stack(data, ""); + printk(" "); /* * We link to the next stack via the * second-to-last pointer (index -2 to end) in the @@ -344,8 +345,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s (IRQSTACKSIZE - 64) / sizeof(*irqstack); if (stack >= irqstack && stack < irqstack_end) { - if (ops->stack(data, "IRQ") < 0) - break; + printk(" "); HANDLE_STACK (stack < irqstack_end); /* * We link to the next stack (which would be @@ -354,7 +354,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s */ stack = (unsigned long *) (irqstack_end[-1]); irqstack_end = NULL; - ops->stack(data, "EOI"); + printk(" "); continue; } } @@ -362,57 +362,19 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long * s } /* - * This handles the process stack: + * This prints the process stack: */ HANDLE_STACK (((long) stack & (THREAD_SIZE-1)) != 0); #undef HANDLE_STACK -} -EXPORT_SYMBOL(dump_trace); - -static void -print_trace_warning_symbol(void *data, char *msg, unsigned long symbol) -{ - print_symbol(msg, symbol); - printk("\n"); -} - -static void print_trace_warning(void *data, char *msg) -{ - printk("%s\n", msg); -} - -static int print_trace_stack(void *data, char *name) -{ - printk(" <%s> ", name); - return 0; -} - -static void print_trace_address(void *data, unsigned long addr) -{ - printk_address(addr); -} - -static struct stacktrace_ops print_trace_ops = { - .warning = print_trace_warning, - .warning_symbol = print_trace_warning_symbol, - .stack = print_trace_stack, - .address = print_trace_address, -}; -void -show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack) -{ - printk("\nCall Trace:\n"); - dump_trace(tsk, regs, stack, &print_trace_ops, NULL); printk("\n"); } -static void -_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *rsp) +static void _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long * rsp) { unsigned long *stack; int i; - const int cpu = smp_processor_id(); + const int cpu = safe_smp_processor_id(); unsigned long *irqstack_end = (unsigned long *) (cpu_pda(cpu)->irqstackptr); unsigned long *irqstack = (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE); @@ -466,7 +428,7 @@ void show_registers(struct pt_regs *regs) int i; int in_kernel = !user_mode(regs); unsigned long rsp; - const int cpu = smp_processor_id(); + const int cpu = safe_smp_processor_id(); struct task_struct *cur = cpu_pda(cpu)->pcurrent; rsp = regs->rsp; @@ -541,11 +503,9 @@ static unsigned int die_nest_count; unsigned __kprobes long oops_begin(void) { - int cpu = smp_processor_id(); + int cpu = safe_smp_processor_id(); unsigned long flags; - oops_enter(); - /* racy, but better than risking deadlock. */ local_irq_save(flags); if (!spin_trylock(&die_lock)) { @@ -574,7 +534,6 @@ void __kprobes oops_end(unsigned long flags) spin_unlock_irqrestore(&die_lock, flags); if (panic_on_oops) panic("Fatal exception"); - oops_exit(); } void __kprobes __die(const char * str, struct pt_regs * regs, long err) @@ -611,7 +570,7 @@ void die(const char * str, struct pt_regs * regs, long err) do_exit(SIGSEGV); } -void __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic) +void __kprobes die_nmi(char *str, struct pt_regs *regs) { unsigned long flags = oops_begin(); @@ -619,12 +578,13 @@ void __kprobes die_nmi(char *str, struct pt_regs *regs, int do_panic) * We are in trouble anyway, lets at least try * to get a message out. */ - printk(str, smp_processor_id()); + printk(str, safe_smp_processor_id()); show_registers(regs); if (kexec_should_crash(current)) crash_kexec(regs); - if (do_panic || panic_on_oops) - panic("Non maskable interrupt"); + if (panic_on_timeout || panic_on_oops) + panic("nmi watchdog"); + printk("console shuts up ...\n"); oops_end(flags); nmi_exit(); local_irq_enable(); @@ -770,15 +730,8 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, static __kprobes void mem_parity_error(unsigned char reason, struct pt_regs * regs) { - printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", - reason); - printk(KERN_EMERG "You probably have a hardware problem with your " - "RAM chips\n"); - - if (panic_on_unrecovered_nmi) - panic("NMI: Not continuing"); - - printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); + printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n"); + printk("You probably have a hardware problem with your RAM chips\n"); /* Clear and disable the memory parity error line. */ reason = (reason & 0xf) | 4; @@ -801,15 +754,9 @@ io_check_error(unsigned char reason, struct pt_regs * regs) static __kprobes void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) -{ - printk(KERN_EMERG "Uhhuh. NMI received for unknown reason %02x.\n", - reason); - printk(KERN_EMERG "Do you have a strange power saving mode enabled?\n"); - - if (panic_on_unrecovered_nmi) - panic("NMI: Not continuing"); - - printk(KERN_EMERG "Dazed and confused, but trying to continue\n"); +{ printk("Uhhuh. NMI received for unknown reason %02x.\n", reason); + printk("Dazed and confused, but trying to continue\n"); + printk("Do you have a strange power saving mode enabled?\n"); } /* Runs on IST stack. This code must keep interrupts off all the time. @@ -829,15 +776,17 @@ asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs) if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT) == NOTIFY_STOP) return; +#ifdef CONFIG_X86_LOCAL_APIC /* * Ok, so this is none of the documented NMI sources, * so it must be the NMI watchdog. */ - if (nmi_watchdog_tick(regs,reason)) + if (nmi_watchdog > 0) { + nmi_watchdog_tick(regs,reason); return; - if (!do_nmi_callback(regs,cpu)) - unknown_nmi_error(reason, regs); - + } +#endif + unknown_nmi_error(reason, regs); return; } if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) @@ -1122,7 +1071,6 @@ asmlinkage void math_state_restore(void) init_fpu(me); restore_fpu_checking(&me->thread.i387.fxsave); task_thread_info(me)->status |= TS_USEDFPU; - me->fpu_counter++; } void __init trap_init(void) @@ -1161,30 +1109,24 @@ void __init trap_init(void) } -static int __init oops_setup(char *s) +/* Actual parsing is done early in setup.c. */ +static int __init oops_dummy(char *s) { - if (!s) - return -EINVAL; - if (!strcmp(s, "panic")) - panic_on_oops = 1; - return 0; + panic_on_oops = 1; + return 1; } -early_param("oops", oops_setup); +__setup("oops=", oops_dummy); static int __init kstack_setup(char *s) { - if (!s) - return -EINVAL; kstack_depth_to_print = simple_strtoul(s,NULL,0); - return 0; + return 1; } -early_param("kstack", kstack_setup); +__setup("kstack=", kstack_setup); #ifdef CONFIG_STACK_UNWIND static int __init call_trace_setup(char *s) { - if (!s) - return -EINVAL; if (strcmp(s, "old") == 0) call_trace = -1; else if (strcmp(s, "both") == 0) @@ -1193,7 +1135,7 @@ static int __init call_trace_setup(char *s) call_trace = 1; else if (strcmp(s, "new") == 0) call_trace = 2; - return 0; + return 1; } -early_param("call_trace", call_trace_setup); +__setup("call_trace=", call_trace_setup); #endif diff --git a/trunk/arch/x86_64/kernel/vmlinux.lds.S b/trunk/arch/x86_64/kernel/vmlinux.lds.S index b9df2ab6529f..7c4de31471d4 100644 --- a/trunk/arch/x86_64/kernel/vmlinux.lds.S +++ b/trunk/arch/x86_64/kernel/vmlinux.lds.S @@ -13,12 +13,6 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") OUTPUT_ARCH(i386:x86-64) ENTRY(phys_startup_64) jiffies_64 = jiffies; -PHDRS { - text PT_LOAD FLAGS(5); /* R_E */ - data PT_LOAD FLAGS(7); /* RWE */ - user PT_LOAD FLAGS(7); /* RWE */ - note PT_NOTE FLAGS(4); /* R__ */ -} SECTIONS { . = __START_KERNEL; @@ -37,7 +31,7 @@ SECTIONS KPROBES_TEXT *(.fixup) *(.gnu.warning) - } :text = 0x9090 + } = 0x9090 /* out-of-line lock text */ .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET) { *(.text.lock) } @@ -63,10 +57,17 @@ SECTIONS .data : AT(ADDR(.data) - LOAD_OFFSET) { *(.data) CONSTRUCTORS - } :data + } _edata = .; /* End of data section */ + __bss_start = .; /* BSS */ + .bss : AT(ADDR(.bss) - LOAD_OFFSET) { + *(.bss.page_aligned) + *(.bss) + } + __bss_stop = .; + . = ALIGN(PAGE_SIZE); . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) { @@ -88,7 +89,7 @@ SECTIONS #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET) . = VSYSCALL_ADDR; - .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } :user + .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) { *(.vsyscall_0) } __vsyscall_0 = VSYSCALL_VIRT_ADDR; . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); @@ -98,8 +99,8 @@ SECTIONS .vxtime : AT(VLOAD(.vxtime)) { *(.vxtime) } vxtime = VVIRT(.vxtime); - .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) { *(.vgetcpu_mode) } - vgetcpu_mode = VVIRT(.vgetcpu_mode); + .wall_jiffies : AT(VLOAD(.wall_jiffies)) { *(.wall_jiffies) } + wall_jiffies = VVIRT(.wall_jiffies); .sys_tz : AT(VLOAD(.sys_tz)) { *(.sys_tz) } sys_tz = VVIRT(.sys_tz); @@ -131,7 +132,7 @@ SECTIONS . = ALIGN(8192); /* init_task */ .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) { *(.data.init_task) - } :data + } . = ALIGN(4096); .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) { @@ -206,12 +207,14 @@ SECTIONS __initramfs_start = .; .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } __initramfs_end = .; - . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); + /* temporary here to work around NR_CPUS. If you see this comment in 2.6.17+ + complain */ + . = ALIGN(4096); + __init_end = .; + . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); __per_cpu_start = .; .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } __per_cpu_end = .; - . = ALIGN(4096); - __init_end = .; . = ALIGN(4096); __nosave_begin = .; @@ -219,13 +222,6 @@ SECTIONS . = ALIGN(4096); __nosave_end = .; - __bss_start = .; /* BSS */ - .bss : AT(ADDR(.bss) - LOAD_OFFSET) { - *(.bss.page_aligned) - *(.bss) - } - __bss_stop = .; - _end = . ; /* Sections to be discarded */ diff --git a/trunk/arch/x86_64/kernel/vsmp.c b/trunk/arch/x86_64/kernel/vsmp.c index 044e852bd25e..92f70c74965f 100644 --- a/trunk/arch/x86_64/kernel/vsmp.c +++ b/trunk/arch/x86_64/kernel/vsmp.c @@ -20,9 +20,6 @@ static int __init vsmp_init(void) void *address; unsigned int cap, ctl; - if (!early_pci_allowed()) - return 0; - /* Check if we are running on a ScaleMP vSMP box */ if ((read_pci_config_16(0, 0x1f, 0, PCI_VENDOR_ID) != PCI_VENDOR_ID_SCALEMP) || (read_pci_config_16(0, 0x1f, 0, PCI_DEVICE_ID) != PCI_DEVICE_ID_SCALEMP_VSMP_CTL)) diff --git a/trunk/arch/x86_64/kernel/vsyscall.c b/trunk/arch/x86_64/kernel/vsyscall.c index a98b460af6a1..f603037df162 100644 --- a/trunk/arch/x86_64/kernel/vsyscall.c +++ b/trunk/arch/x86_64/kernel/vsyscall.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include @@ -34,15 +33,11 @@ #include #include #include -#include -#include -#include #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) int __sysctl_vsyscall __section_sysctl_vsyscall = 1; seqlock_t __xtime_lock __section_xtime_lock = SEQLOCK_UNLOCKED; -int __vgetcpu_mode __section_vgetcpu_mode; #include @@ -66,7 +61,8 @@ static __always_inline void do_vgettimeofday(struct timeval * tv) sequence = read_seqbegin(&__xtime_lock); sec = __xtime.tv_sec; - usec = __xtime.tv_nsec / 1000; + usec = (__xtime.tv_nsec / 1000) + + (__jiffies - __wall_jiffies) * (1000000 / HZ); if (__vxtime.mode != VXTIME_HPET) { t = get_cycles_sync(); @@ -76,8 +72,7 @@ static __always_inline void do_vgettimeofday(struct timeval * tv) __vxtime.tsc_quot) >> 32; /* See comment in x86_64 do_gettimeofday. */ } else { - usec += ((readl((void __iomem *) - fix_to_virt(VSYSCALL_HPET) + 0xf0) - + usec += ((readl((void *)fix_to_virt(VSYSCALL_HPET) + 0xf0) - __vxtime.last) * __vxtime.quot) >> 32; } } while (read_seqretry(&__xtime_lock, sequence)); @@ -132,46 +127,9 @@ time_t __vsyscall(1) vtime(time_t *t) return __xtime.tv_sec; } -/* Fast way to get current CPU and node. - This helps to do per node and per CPU caches in user space. - The result is not guaranteed without CPU affinity, but usually - works out because the scheduler tries to keep a thread on the same - CPU. - - tcache must point to a two element sized long array. - All arguments can be NULL. */ -long __vsyscall(2) -vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) +long __vsyscall(2) venosys_0(void) { - unsigned int dummy, p; - unsigned long j = 0; - - /* Fast cache - only recompute value once per jiffies and avoid - relatively costly rdtscp/cpuid otherwise. - This works because the scheduler usually keeps the process - on the same CPU and this syscall doesn't guarantee its - results anyways. - We do this here because otherwise user space would do it on - its own in a likely inferior way (no access to jiffies). - If you don't like it pass NULL. */ - if (tcache && tcache->blob[0] == (j = __jiffies)) { - p = tcache->blob[1]; - } else if (__vgetcpu_mode == VGETCPU_RDTSCP) { - /* Load per CPU data from RDTSCP */ - rdtscp(dummy, dummy, p); - } else { - /* Load per CPU data from GDT */ - asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); - } - if (tcache) { - tcache->blob[0] = j; - tcache->blob[1] = p; - } - if (cpu) - *cpu = p & 0xfff; - if (node) - *node = p >> 12; - return 0; + return -ENOSYS; } long __vsyscall(3) venosys_1(void) @@ -191,8 +149,7 @@ static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos) { extern u16 vsysc1, vsysc2; - u16 __iomem *map1; - u16 __iomem *map2; + u16 *map1, *map2; int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); if (!write) return ret; @@ -207,11 +164,11 @@ static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp, goto out; } if (!sysctl_vsyscall) { - writew(SYSCALL, map1); - writew(SYSCALL, map2); + *map1 = SYSCALL; + *map2 = SYSCALL; } else { - writew(NOP2, map1); - writew(NOP2, map2); + *map1 = NOP2; + *map2 = NOP2; } iounmap(map2); out: @@ -243,43 +200,6 @@ static ctl_table kernel_root_table2[] = { #endif -static void __cpuinit write_rdtscp_cb(void *info) -{ - write_rdtscp_aux((unsigned long)info); -} - -void __cpuinit vsyscall_set_cpu(int cpu) -{ - unsigned long *d; - unsigned long node = 0; -#ifdef CONFIG_NUMA - node = cpu_to_node[cpu]; -#endif - if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) { - void *info = (void *)((node << 12) | cpu); - /* Can happen on preemptive kernel */ - if (get_cpu() == cpu) - write_rdtscp_cb(info); -#ifdef CONFIG_SMP - else { - /* the notifier is unfortunately not executed on the - target CPU */ - smp_call_function_single(cpu,write_rdtscp_cb,info,0,1); - } -#endif - put_cpu(); - } - - /* Store cpu number in limit so that it can be loaded quickly - in user space in vgetcpu. - 12 bits for the CPU and 8 bits for the node. */ - d = (unsigned long *)(cpu_gdt(cpu) + GDT_ENTRY_PER_CPU); - *d = 0x0f40000000000ULL; - *d |= cpu; - *d |= (node & 0xf) << 12; - *d |= (node >> 4) << 48; -} - static void __init map_vsyscall(void) { extern char __vsyscall_0; @@ -294,7 +214,6 @@ static int __init vsyscall_init(void) VSYSCALL_ADDR(__NR_vgettimeofday))); BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime)); BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE))); - BUG_ON((unsigned long) &vgetcpu != VSYSCALL_ADDR(__NR_vgetcpu)); map_vsyscall(); #ifdef CONFIG_SYSCTL register_sysctl_table(kernel_root_table2, 0); diff --git a/trunk/arch/x86_64/kernel/x8664_ksyms.c b/trunk/arch/x86_64/kernel/x8664_ksyms.c index c3454af5e3a2..370952c4ff22 100644 --- a/trunk/arch/x86_64/kernel/x8664_ksyms.c +++ b/trunk/arch/x86_64/kernel/x8664_ksyms.c @@ -29,7 +29,6 @@ EXPORT_SYMBOL(__put_user_8); EXPORT_SYMBOL(copy_user_generic); EXPORT_SYMBOL(copy_from_user); EXPORT_SYMBOL(copy_to_user); -EXPORT_SYMBOL(__copy_from_user_inatomic); EXPORT_SYMBOL(copy_page); EXPORT_SYMBOL(clear_page); diff --git a/trunk/arch/x86_64/lib/Makefile b/trunk/arch/x86_64/lib/Makefile index b78d4170fce2..ccef6ae747a3 100644 --- a/trunk/arch/x86_64/lib/Makefile +++ b/trunk/arch/x86_64/lib/Makefile @@ -9,4 +9,4 @@ obj-y := io.o iomap_copy.o lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \ usercopy.o getuser.o putuser.o \ thunk.o clear_page.o copy_page.o bitstr.o bitops.o -lib-y += memcpy.o memmove.o memset.o copy_user.o rwlock.o +lib-y += memcpy.o memmove.o memset.o copy_user.o diff --git a/trunk/arch/x86_64/lib/clear_page.S b/trunk/arch/x86_64/lib/clear_page.S index 9a10a78bb4a4..1f81b79b796c 100644 --- a/trunk/arch/x86_64/lib/clear_page.S +++ b/trunk/arch/x86_64/lib/clear_page.S @@ -1,22 +1,10 @@ -#include -#include - /* * Zero a page. * rdi page */ - ALIGN -clear_page_c: - CFI_STARTPROC - movl $4096/8,%ecx - xorl %eax,%eax - rep stosq - ret - CFI_ENDPROC -ENDPROC(clear_page) - -ENTRY(clear_page) - CFI_STARTPROC + .globl clear_page + .p2align 4 +clear_page: xorl %eax,%eax movl $4096/64,%ecx .p2align 4 @@ -35,25 +23,28 @@ ENTRY(clear_page) jnz .Lloop nop ret - CFI_ENDPROC -.Lclear_page_end: -ENDPROC(clear_page) +clear_page_end: /* Some CPUs run faster using the string instructions. It is also a lot simpler. Use this when possible */ #include - .section .altinstr_replacement,"ax" -1: .byte 0xeb /* jmp */ - .byte (clear_page_c - clear_page) - (2f - 1b) /* offset */ -2: - .previous .section .altinstructions,"a" .align 8 - .quad clear_page - .quad 1b - .byte X86_FEATURE_REP_GOOD - .byte .Lclear_page_end - clear_page - .byte 2b - 1b + .quad clear_page + .quad clear_page_c + .byte X86_FEATURE_REP_GOOD + .byte clear_page_end-clear_page + .byte clear_page_c_end-clear_page_c + .previous + + .section .altinstr_replacement,"ax" +clear_page_c: + movl $4096/8,%ecx + xorl %eax,%eax + rep + stosq + ret +clear_page_c_end: .previous diff --git a/trunk/arch/x86_64/lib/copy_page.S b/trunk/arch/x86_64/lib/copy_page.S index 0ebb03b60e79..8fa19d96a7ee 100644 --- a/trunk/arch/x86_64/lib/copy_page.S +++ b/trunk/arch/x86_64/lib/copy_page.S @@ -1,33 +1,17 @@ /* Written 2003 by Andi Kleen, based on a kernel by Evandro Menezes */ -#include -#include -#include - - ALIGN -copy_page_c: - CFI_STARTPROC - movl $4096/8,%ecx - rep movsq - ret - CFI_ENDPROC -ENDPROC(copy_page_c) - /* Don't use streaming store because it's better when the target ends up in cache. */ /* Could vary the prefetch distance based on SMP/UP */ -ENTRY(copy_page) - CFI_STARTPROC + .globl copy_page + .p2align 4 +copy_page: subq $3*8,%rsp - CFI_ADJUST_CFA_OFFSET 3*8 movq %rbx,(%rsp) - CFI_REL_OFFSET rbx, 0 movq %r12,1*8(%rsp) - CFI_REL_OFFSET r12, 1*8 movq %r13,2*8(%rsp) - CFI_REL_OFFSET r13, 2*8 movl $(4096/64)-5,%ecx .p2align 4 @@ -88,33 +72,30 @@ ENTRY(copy_page) jnz .Loop2 movq (%rsp),%rbx - CFI_RESTORE rbx movq 1*8(%rsp),%r12 - CFI_RESTORE r12 movq 2*8(%rsp),%r13 - CFI_RESTORE r13 addq $3*8,%rsp - CFI_ADJUST_CFA_OFFSET -3*8 ret -.Lcopy_page_end: - CFI_ENDPROC -ENDPROC(copy_page) /* Some CPUs run faster using the string copy instructions. It is also a lot simpler. Use this when possible */ #include - .section .altinstr_replacement,"ax" -1: .byte 0xeb /* jmp */ - .byte (copy_page_c - copy_page) - (2f - 1b) /* offset */ -2: - .previous .section .altinstructions,"a" .align 8 - .quad copy_page - .quad 1b - .byte X86_FEATURE_REP_GOOD - .byte .Lcopy_page_end - copy_page - .byte 2b - 1b + .quad copy_page + .quad copy_page_c + .byte X86_FEATURE_REP_GOOD + .byte copy_page_c_end-copy_page_c + .byte copy_page_c_end-copy_page_c + .previous + + .section .altinstr_replacement,"ax" +copy_page_c: + movl $4096/8,%ecx + rep + movsq + ret +copy_page_c_end: .previous diff --git a/trunk/arch/x86_64/lib/copy_user.S b/trunk/arch/x86_64/lib/copy_user.S index 70bebd310408..f64569b83b54 100644 --- a/trunk/arch/x86_64/lib/copy_user.S +++ b/trunk/arch/x86_64/lib/copy_user.S @@ -4,78 +4,56 @@ * Functions to copy from and to user space. */ -#include -#include - #define FIX_ALIGNMENT 1 -#include -#include -#include -#include + #include + #include + #include + #include - .macro ALTERNATIVE_JUMP feature,orig,alt -0: +/* Standard copy_to_user with segment limit checking */ + .globl copy_to_user + .p2align 4 +copy_to_user: + GET_THREAD_INFO(%rax) + movq %rdi,%rcx + addq %rdx,%rcx + jc bad_to_user + cmpq threadinfo_addr_limit(%rax),%rcx + jae bad_to_user +2: .byte 0xe9 /* 32bit jump */ - .long \orig-1f /* by default jump to orig */ + .long .Lcug-1f 1: + .section .altinstr_replacement,"ax" -2: .byte 0xe9 /* near jump with 32bit immediate */ - .long \alt-1b /* offset */ /* or alternatively to alt */ +3: .byte 0xe9 /* replacement jmp with 8 bit immediate */ + .long copy_user_generic_c-1b /* offset */ .previous .section .altinstructions,"a" .align 8 - .quad 0b .quad 2b - .byte \feature /* when feature is set */ + .quad 3b + .byte X86_FEATURE_REP_GOOD .byte 5 .byte 5 .previous - .endm - -/* Standard copy_to_user with segment limit checking */ -ENTRY(copy_to_user) - CFI_STARTPROC - GET_THREAD_INFO(%rax) - movq %rdi,%rcx - addq %rdx,%rcx - jc bad_to_user - cmpq threadinfo_addr_limit(%rax),%rcx - jae bad_to_user - xorl %eax,%eax /* clear zero flag */ - ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string - CFI_ENDPROC - -ENTRY(copy_user_generic) - CFI_STARTPROC - movl $1,%ecx /* set zero flag */ - ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string - CFI_ENDPROC - -ENTRY(__copy_from_user_inatomic) - CFI_STARTPROC - xorl %ecx,%ecx /* clear zero flag */ - ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string - CFI_ENDPROC /* Standard copy_from_user with segment limit checking */ -ENTRY(copy_from_user) - CFI_STARTPROC + .globl copy_from_user + .p2align 4 +copy_from_user: GET_THREAD_INFO(%rax) movq %rsi,%rcx addq %rdx,%rcx jc bad_from_user cmpq threadinfo_addr_limit(%rax),%rcx jae bad_from_user - movl $1,%ecx /* set zero flag */ - ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string - CFI_ENDPROC -ENDPROC(copy_from_user) + /* FALL THROUGH to copy_user_generic */ .section .fixup,"ax" /* must zero dest */ bad_from_user: - CFI_STARTPROC movl %edx,%ecx xorl %eax,%eax rep @@ -83,32 +61,40 @@ bad_from_user: bad_to_user: movl %edx,%eax ret - CFI_ENDPROC -END(bad_from_user) .previous /* - * copy_user_generic_unrolled - memory copy with exception handling. - * This version is for CPUs like P4 that don't have efficient micro code for rep movsq + * copy_user_generic - memory copy with exception handling. * * Input: * rdi destination * rsi source * rdx count - * ecx zero flag -- if true zero destination on error * * Output: * eax uncopied bytes or 0 if successful. */ -ENTRY(copy_user_generic_unrolled) - CFI_STARTPROC + .globl copy_user_generic + .p2align 4 +copy_user_generic: + .byte 0x66,0x66,0x90 /* 5 byte nop for replacement jump */ + .byte 0x66,0x90 +1: + .section .altinstr_replacement,"ax" +2: .byte 0xe9 /* near jump with 32bit immediate */ + .long copy_user_generic_c-1b /* offset */ + .previous + .section .altinstructions,"a" + .align 8 + .quad copy_user_generic + .quad 2b + .byte X86_FEATURE_REP_GOOD + .byte 5 + .byte 5 + .previous +.Lcug: pushq %rbx - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rbx, 0 - pushq %rcx - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rcx, 0 xorl %eax,%eax /*zero for the exception handler */ #ifdef FIX_ALIGNMENT @@ -182,16 +168,9 @@ ENTRY(copy_user_generic_unrolled) decl %ecx jnz .Lloop_1 - CFI_REMEMBER_STATE .Lende: - popq %rcx - CFI_ADJUST_CFA_OFFSET -8 - CFI_RESTORE rcx popq %rbx - CFI_ADJUST_CFA_OFFSET -8 - CFI_RESTORE rbx ret - CFI_RESTORE_STATE #ifdef FIX_ALIGNMENT /* align destination */ @@ -273,8 +252,6 @@ ENTRY(copy_user_generic_unrolled) addl %ecx,%edx /* edx: bytes to zero, rdi: dest, eax:zero */ .Lzero_rest: - cmpl $0,(%rsp) - jz .Le_zero movq %rdx,%rcx .Le_byte: xorl %eax,%eax @@ -284,9 +261,6 @@ ENTRY(copy_user_generic_unrolled) .Le_zero: movq %rdx,%rax jmp .Lende - CFI_ENDPROC -ENDPROC(copy_user_generic) - /* Some CPUs run faster using the string copy instructions. This is also a lot simpler. Use them when possible. @@ -296,7 +270,6 @@ ENDPROC(copy_user_generic) /* rdi destination * rsi source * rdx count - * ecx zero flag * * Output: * eax uncopied bytes or 0 if successfull. @@ -307,48 +280,22 @@ ENDPROC(copy_user_generic) * And more would be dangerous because both Intel and AMD have * errata with rep movsq > 4GB. If someone feels the need to fix * this please consider this. - */ -ENTRY(copy_user_generic_string) - CFI_STARTPROC - movl %ecx,%r8d /* save zero flag */ + */ +copy_user_generic_c: movl %edx,%ecx shrl $3,%ecx andl $7,%edx - jz 10f 1: rep movsq movl %edx,%ecx 2: rep movsb -9: movl %ecx,%eax +4: movl %ecx,%eax ret - - /* multiple of 8 byte */ -10: rep - movsq - xor %eax,%eax +3: lea (%rdx,%rcx,8),%rax ret - /* exception handling */ -3: lea (%rdx,%rcx,8),%rax /* exception on quad loop */ - jmp 6f -5: movl %ecx,%eax /* exception on byte loop */ - /* eax: left over bytes */ -6: testl %r8d,%r8d /* zero flag set? */ - jz 7f - movl %eax,%ecx /* initialize x86 loop counter */ - push %rax - xorl %eax,%eax -8: rep - stosb /* zero the rest */ -11: pop %rax -7: ret - CFI_ENDPROC -END(copy_user_generic_c) - .section __ex_table,"a" .quad 1b,3b - .quad 2b,5b - .quad 8b,11b - .quad 10b,3b + .quad 2b,4b .previous diff --git a/trunk/arch/x86_64/lib/csum-copy.S b/trunk/arch/x86_64/lib/csum-copy.S index f0dba36578ea..72fd55ee896e 100644 --- a/trunk/arch/x86_64/lib/csum-copy.S +++ b/trunk/arch/x86_64/lib/csum-copy.S @@ -5,9 +5,8 @@ * License. See the file COPYING in the main directory of this archive * for more details. No warranty for anything given at all. */ -#include -#include -#include + #include + #include /* * Checksum copy with exception handling. @@ -54,24 +53,19 @@ .endm -ENTRY(csum_partial_copy_generic) - CFI_STARTPROC + .globl csum_partial_copy_generic + .p2align 4 +csum_partial_copy_generic: cmpl $3*64,%edx jle .Lignore .Lignore: subq $7*8,%rsp - CFI_ADJUST_CFA_OFFSET 7*8 movq %rbx,2*8(%rsp) - CFI_REL_OFFSET rbx, 2*8 movq %r12,3*8(%rsp) - CFI_REL_OFFSET r12, 3*8 movq %r14,4*8(%rsp) - CFI_REL_OFFSET r14, 4*8 movq %r13,5*8(%rsp) - CFI_REL_OFFSET r13, 5*8 movq %rbp,6*8(%rsp) - CFI_REL_OFFSET rbp, 6*8 movq %r8,(%rsp) movq %r9,1*8(%rsp) @@ -214,22 +208,14 @@ ENTRY(csum_partial_copy_generic) addl %ebx,%eax adcl %r9d,%eax /* carry */ - CFI_REMEMBER_STATE .Lende: movq 2*8(%rsp),%rbx - CFI_RESTORE rbx movq 3*8(%rsp),%r12 - CFI_RESTORE r12 movq 4*8(%rsp),%r14 - CFI_RESTORE r14 movq 5*8(%rsp),%r13 - CFI_RESTORE r13 movq 6*8(%rsp),%rbp - CFI_RESTORE rbp addq $7*8,%rsp - CFI_ADJUST_CFA_OFFSET -7*8 ret - CFI_RESTORE_STATE /* Exception handlers. Very simple, zeroing is done in the wrappers */ .Lbad_source: @@ -245,5 +231,3 @@ ENTRY(csum_partial_copy_generic) jz .Lende movl $-EFAULT,(%rax) jmp .Lende - CFI_ENDPROC -ENDPROC(csum_partial_copy_generic) diff --git a/trunk/arch/x86_64/lib/getuser.S b/trunk/arch/x86_64/lib/getuser.S index 5448876261f8..3844d5e885a4 100644 --- a/trunk/arch/x86_64/lib/getuser.S +++ b/trunk/arch/x86_64/lib/getuser.S @@ -27,26 +27,25 @@ */ #include -#include #include #include #include #include .text -ENTRY(__get_user_1) - CFI_STARTPROC + .p2align 4 +.globl __get_user_1 +__get_user_1: GET_THREAD_INFO(%r8) cmpq threadinfo_addr_limit(%r8),%rcx jae bad_get_user 1: movzb (%rcx),%edx xorl %eax,%eax ret - CFI_ENDPROC -ENDPROC(__get_user_1) -ENTRY(__get_user_2) - CFI_STARTPROC + .p2align 4 +.globl __get_user_2 +__get_user_2: GET_THREAD_INFO(%r8) addq $1,%rcx jc 20f @@ -58,11 +57,10 @@ ENTRY(__get_user_2) ret 20: decq %rcx jmp bad_get_user - CFI_ENDPROC -ENDPROC(__get_user_2) -ENTRY(__get_user_4) - CFI_STARTPROC + .p2align 4 +.globl __get_user_4 +__get_user_4: GET_THREAD_INFO(%r8) addq $3,%rcx jc 30f @@ -74,11 +72,10 @@ ENTRY(__get_user_4) ret 30: subq $3,%rcx jmp bad_get_user - CFI_ENDPROC -ENDPROC(__get_user_4) -ENTRY(__get_user_8) - CFI_STARTPROC + .p2align 4 +.globl __get_user_8 +__get_user_8: GET_THREAD_INFO(%r8) addq $7,%rcx jc 40f @@ -90,16 +87,11 @@ ENTRY(__get_user_8) ret 40: subq $7,%rcx jmp bad_get_user - CFI_ENDPROC -ENDPROC(__get_user_8) bad_get_user: - CFI_STARTPROC xorl %edx,%edx movq $(-EFAULT),%rax ret - CFI_ENDPROC -END(bad_get_user) .section __ex_table,"a" .quad 1b,bad_get_user diff --git a/trunk/arch/x86_64/lib/iomap_copy.S b/trunk/arch/x86_64/lib/iomap_copy.S index 05a95e713da8..8bbade5fea05 100644 --- a/trunk/arch/x86_64/lib/iomap_copy.S +++ b/trunk/arch/x86_64/lib/iomap_copy.S @@ -15,16 +15,12 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include -#include - /* * override generic version in lib/iomap_copy.c */ -ENTRY(__iowrite32_copy) - CFI_STARTPROC + .globl __iowrite32_copy + .p2align 4 +__iowrite32_copy: movl %edx,%ecx rep movsd ret - CFI_ENDPROC -ENDPROC(__iowrite32_copy) diff --git a/trunk/arch/x86_64/lib/memcpy.S b/trunk/arch/x86_64/lib/memcpy.S index 967b22fa7d07..5554948b5554 100644 --- a/trunk/arch/x86_64/lib/memcpy.S +++ b/trunk/arch/x86_64/lib/memcpy.S @@ -1,10 +1,6 @@ /* Copyright 2002 Andi Kleen */ -#include -#include -#include -#include - + #include /* * memcpy - Copy a memory block. * @@ -17,26 +13,12 @@ * rax original destination */ - ALIGN -memcpy_c: - CFI_STARTPROC - movq %rdi,%rax - movl %edx,%ecx - shrl $3,%ecx - andl $7,%edx - rep movsq - movl %edx,%ecx - rep movsb - ret - CFI_ENDPROC -ENDPROC(memcpy_c) - -ENTRY(__memcpy) -ENTRY(memcpy) - CFI_STARTPROC + .globl __memcpy + .globl memcpy + .p2align 4 +__memcpy: +memcpy: pushq %rbx - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rbx, 0 movq %rdi,%rax movl %edx,%ecx @@ -104,27 +86,36 @@ ENTRY(memcpy) .Lende: popq %rbx - CFI_ADJUST_CFA_OFFSET -8 - CFI_RESTORE rbx ret .Lfinal: - CFI_ENDPROC -ENDPROC(memcpy) -ENDPROC(__memcpy) /* Some CPUs run faster using the string copy instructions. It is also a lot simpler. Use this when possible */ - .section .altinstr_replacement,"ax" -1: .byte 0xeb /* jmp */ - .byte (memcpy_c - memcpy) - (2f - 1b) /* offset */ -2: - .previous .section .altinstructions,"a" .align 8 - .quad memcpy - .quad 1b - .byte X86_FEATURE_REP_GOOD - .byte .Lfinal - memcpy - .byte 2b - 1b + .quad memcpy + .quad memcpy_c + .byte X86_FEATURE_REP_GOOD + .byte .Lfinal-memcpy + .byte memcpy_c_end-memcpy_c + .previous + + .section .altinstr_replacement,"ax" + /* rdi destination + * rsi source + * rdx count + */ +memcpy_c: + movq %rdi,%rax + movl %edx,%ecx + shrl $3,%ecx + andl $7,%edx + rep + movsq + movl %edx,%ecx + rep + movsb + ret +memcpy_c_end: .previous diff --git a/trunk/arch/x86_64/lib/memset.S b/trunk/arch/x86_64/lib/memset.S index 09ed1f6b0eaa..ad397f2c7de8 100644 --- a/trunk/arch/x86_64/lib/memset.S +++ b/trunk/arch/x86_64/lib/memset.S @@ -1,9 +1,4 @@ /* Copyright 2002 Andi Kleen, SuSE Labs */ - -#include -#include -#include - /* * ISO C memset - set a memory block to a byte value. * @@ -13,29 +8,11 @@ * * rax original destination */ - ALIGN -memset_c: - CFI_STARTPROC - movq %rdi,%r9 - movl %edx,%r8d - andl $7,%r8d - movl %edx,%ecx - shrl $3,%ecx - /* expand byte value */ - movzbl %sil,%esi - movabs $0x0101010101010101,%rax - mulq %rsi /* with rax, clobbers rdx */ - rep stosq - movl %r8d,%ecx - rep stosb - movq %r9,%rax - ret - CFI_ENDPROC -ENDPROC(memset_c) - -ENTRY(memset) -ENTRY(__memset) - CFI_STARTPROC + .globl __memset + .globl memset + .p2align 4 +memset: +__memset: movq %rdi,%r10 movq %rdx,%r11 @@ -48,7 +25,6 @@ ENTRY(__memset) movl %edi,%r9d andl $7,%r9d jnz .Lbad_alignment - CFI_REMEMBER_STATE .Lafter_bad_alignment: movl %r11d,%ecx @@ -99,7 +75,6 @@ ENTRY(__memset) movq %r10,%rax ret - CFI_RESTORE_STATE .Lbad_alignment: cmpq $7,%r11 jbe .Lhandle_7 @@ -109,26 +84,42 @@ ENTRY(__memset) addq %r8,%rdi subq %r8,%r11 jmp .Lafter_bad_alignment -.Lfinal: - CFI_ENDPROC -ENDPROC(memset) -ENDPROC(__memset) /* Some CPUs run faster using the string instructions. It is also a lot simpler. Use this when possible */ #include - .section .altinstr_replacement,"ax" -1: .byte 0xeb /* jmp */ - .byte (memset_c - memset) - (2f - 1b) /* offset */ -2: - .previous .section .altinstructions,"a" .align 8 - .quad memset - .quad 1b - .byte X86_FEATURE_REP_GOOD - .byte .Lfinal - memset - .byte 2b - 1b + .quad memset + .quad memset_c + .byte X86_FEATURE_REP_GOOD + .byte memset_c_end-memset_c + .byte memset_c_end-memset_c + .previous + + .section .altinstr_replacement,"ax" + /* rdi destination + * rsi value + * rdx count + */ +memset_c: + movq %rdi,%r9 + movl %edx,%r8d + andl $7,%r8d + movl %edx,%ecx + shrl $3,%ecx + /* expand byte value */ + movzbl %sil,%esi + movabs $0x0101010101010101,%rax + mulq %rsi /* with rax, clobbers rdx */ + rep + stosq + movl %r8d,%ecx + rep + stosb + movq %r9,%rax + ret +memset_c_end: .previous diff --git a/trunk/arch/x86_64/lib/putuser.S b/trunk/arch/x86_64/lib/putuser.S index 4989f5a8fa9b..7f5593974e2d 100644 --- a/trunk/arch/x86_64/lib/putuser.S +++ b/trunk/arch/x86_64/lib/putuser.S @@ -25,26 +25,25 @@ */ #include -#include #include #include #include #include .text -ENTRY(__put_user_1) - CFI_STARTPROC + .p2align 4 +.globl __put_user_1 +__put_user_1: GET_THREAD_INFO(%r8) cmpq threadinfo_addr_limit(%r8),%rcx jae bad_put_user 1: movb %dl,(%rcx) xorl %eax,%eax ret - CFI_ENDPROC -ENDPROC(__put_user_1) -ENTRY(__put_user_2) - CFI_STARTPROC + .p2align 4 +.globl __put_user_2 +__put_user_2: GET_THREAD_INFO(%r8) addq $1,%rcx jc 20f @@ -56,11 +55,10 @@ ENTRY(__put_user_2) ret 20: decq %rcx jmp bad_put_user - CFI_ENDPROC -ENDPROC(__put_user_2) -ENTRY(__put_user_4) - CFI_STARTPROC + .p2align 4 +.globl __put_user_4 +__put_user_4: GET_THREAD_INFO(%r8) addq $3,%rcx jc 30f @@ -72,11 +70,10 @@ ENTRY(__put_user_4) ret 30: subq $3,%rcx jmp bad_put_user - CFI_ENDPROC -ENDPROC(__put_user_4) -ENTRY(__put_user_8) - CFI_STARTPROC + .p2align 4 +.globl __put_user_8 +__put_user_8: GET_THREAD_INFO(%r8) addq $7,%rcx jc 40f @@ -88,15 +85,10 @@ ENTRY(__put_user_8) ret 40: subq $7,%rcx jmp bad_put_user - CFI_ENDPROC -ENDPROC(__put_user_8) bad_put_user: - CFI_STARTPROC movq $(-EFAULT),%rax ret - CFI_ENDPROC -END(bad_put_user) .section __ex_table,"a" .quad 1b,bad_put_user diff --git a/trunk/arch/x86_64/lib/rwlock.S b/trunk/arch/x86_64/lib/rwlock.S deleted file mode 100644 index 0cde1f807314..000000000000 --- a/trunk/arch/x86_64/lib/rwlock.S +++ /dev/null @@ -1,38 +0,0 @@ -/* Slow paths of read/write spinlocks. */ - -#include -#include -#include -#include - -/* rdi: pointer to rwlock_t */ -ENTRY(__write_lock_failed) - CFI_STARTPROC - LOCK_PREFIX - addl $RW_LOCK_BIAS,(%rdi) -1: rep - nop - cmpl $RW_LOCK_BIAS,(%rdi) - jne 1b - LOCK_PREFIX - subl $RW_LOCK_BIAS,(%rdi) - jnz __write_lock_failed - ret - CFI_ENDPROC -END(__write_lock_failed) - -/* rdi: pointer to rwlock_t */ -ENTRY(__read_lock_failed) - CFI_STARTPROC - LOCK_PREFIX - incl (%rdi) -1: rep - nop - cmpl $1,(%rdi) - js 1b - LOCK_PREFIX - decl (%rdi) - js __read_lock_failed - ret - CFI_ENDPROC -END(__read_lock_failed) diff --git a/trunk/arch/x86_64/lib/thunk.S b/trunk/arch/x86_64/lib/thunk.S index 0025535cac8d..332ea5dff916 100644 --- a/trunk/arch/x86_64/lib/thunk.S +++ b/trunk/arch/x86_64/lib/thunk.S @@ -1,9 +1,10 @@ -/* - * Save registers before calling assembly functions. This avoids - * disturbance of register allocation in some inline assembly constructs. - * Copyright 2001,2002 by Andi Kleen, SuSE Labs. - * Subject to the GNU public license, v.2. No warranty of any kind. - */ + /* + * Save registers before calling assembly functions. This avoids + * disturbance of register allocation in some inline assembly constructs. + * Copyright 2001,2002 by Andi Kleen, SuSE Labs. + * Subject to the GNU public license, v.2. No warranty of any kind. + * $Id: thunk.S,v 1.2 2002/03/13 20:06:58 ak Exp $ + */ #include #include @@ -66,3 +67,33 @@ restore_norax: RESTORE_ARGS 1 ret CFI_ENDPROC + +#ifdef CONFIG_SMP +/* Support for read/write spinlocks. */ + .text +/* rax: pointer to rwlock_t */ +ENTRY(__write_lock_failed) + lock + addl $RW_LOCK_BIAS,(%rax) +1: rep + nop + cmpl $RW_LOCK_BIAS,(%rax) + jne 1b + lock + subl $RW_LOCK_BIAS,(%rax) + jnz __write_lock_failed + ret + +/* rax: pointer to rwlock_t */ +ENTRY(__read_lock_failed) + lock + incl (%rax) +1: rep + nop + cmpl $1,(%rax) + js 1b + lock + decl (%rax) + js __read_lock_failed + ret +#endif diff --git a/trunk/arch/x86_64/mm/fault.c b/trunk/arch/x86_64/mm/fault.c index 3751b4788e28..4198798e1469 100644 --- a/trunk/arch/x86_64/mm/fault.c +++ b/trunk/arch/x86_64/mm/fault.c @@ -40,7 +40,8 @@ #define PF_RSVD (1<<3) #define PF_INSTR (1<<4) -static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); +#ifdef CONFIG_KPROBES +ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); /* Hook to register for page fault notifications */ int register_page_fault_notifier(struct notifier_block *nb) @@ -48,13 +49,11 @@ int register_page_fault_notifier(struct notifier_block *nb) vmalloc_sync_all(); return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); } -EXPORT_SYMBOL_GPL(register_page_fault_notifier); int unregister_page_fault_notifier(struct notifier_block *nb) { return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); } -EXPORT_SYMBOL_GPL(unregister_page_fault_notifier); static inline int notify_page_fault(enum die_val val, const char *str, struct pt_regs *regs, long err, int trap, int sig) @@ -68,6 +67,13 @@ static inline int notify_page_fault(enum die_val val, const char *str, }; return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); } +#else +static inline int notify_page_fault(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + return NOTIFY_DONE; +} +#endif void bust_spinlocks(int yes) { @@ -96,7 +102,7 @@ void bust_spinlocks(int yes) static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, unsigned long error_code) { - unsigned char __user *instr; + unsigned char *instr; int scan_more = 1; int prefetch = 0; unsigned char *max_instr; @@ -105,7 +111,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, if (error_code & PF_INSTR) return 0; - instr = (unsigned char __user *)convert_rip_to_linear(current, regs); + instr = (unsigned char *)convert_rip_to_linear(current, regs); max_instr = instr + 15; if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE) @@ -116,7 +122,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, unsigned char instr_hi; unsigned char instr_lo; - if (__get_user(opcode, (char __user *)instr)) + if (__get_user(opcode, instr)) break; instr_hi = opcode & 0xf0; @@ -154,7 +160,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, case 0x00: /* Prefetch instruction is 0x0F0D or 0x0F18 */ scan_more = 0; - if (__get_user(opcode, (char __user *)instr)) + if (__get_user(opcode, instr)) break; prefetch = (instr_lo == 0xF) && (opcode == 0x0D || opcode == 0x18); @@ -170,7 +176,7 @@ static noinline int is_prefetch(struct pt_regs *regs, unsigned long addr, static int bad_address(void *p) { unsigned long dummy; - return __get_user(dummy, (unsigned long __user *)p); + return __get_user(dummy, (unsigned long *)p); } void dump_pagetable(unsigned long address) @@ -244,7 +250,7 @@ static int is_errata93(struct pt_regs *regs, unsigned long address) int unhandled_signal(struct task_struct *tsk, int sig) { - if (is_init(tsk)) + if (tsk->pid == 1) return 1; if (tsk->ptrace & PT_PTRACED) return 0; @@ -464,7 +470,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, case PF_PROT: /* read, present */ goto bad_area; case 0: /* read, not present */ - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; } @@ -580,7 +586,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_init(current)) { + if (current->pid == 1) { yield(); goto again; } diff --git a/trunk/arch/x86_64/mm/init.c b/trunk/arch/x86_64/mm/init.c index 19c72520a868..52fd42c40c86 100644 --- a/trunk/arch/x86_64/mm/init.c +++ b/trunk/arch/x86_64/mm/init.c @@ -229,6 +229,7 @@ __init void *early_ioremap(unsigned long addr, unsigned long size) /* actually usually some more */ if (size >= LARGE_PAGE_SIZE) { + printk("SMBIOS area too long %lu\n", size); return NULL; } set_pmd(temp_mappings[0].pmd, __pmd(map | _KERNPG_TABLE | _PAGE_PSE)); @@ -249,13 +250,12 @@ __init void early_iounmap(void *addr, unsigned long size) } static void __meminit -phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end) +phys_pmd_init(pmd_t *pmd, unsigned long address, unsigned long end) { - int i = pmd_index(address); + int i; - for (; i < PTRS_PER_PMD; i++, address += PMD_SIZE) { + for (i = 0; i < PTRS_PER_PMD; pmd++, i++, address += PMD_SIZE) { unsigned long entry; - pmd_t *pmd = pmd_page + pmd_index(address); if (address >= end) { if (!after_bootmem) @@ -263,10 +263,6 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end) set_pmd(pmd, __pmd(0)); break; } - - if (pmd_val(*pmd)) - continue; - entry = _PAGE_NX|_PAGE_PSE|_KERNPG_TABLE|_PAGE_GLOBAL|address; entry &= __supported_pte_mask; set_pmd(pmd, __pmd(entry)); @@ -276,41 +272,45 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end) static void __meminit phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end) { - pmd_t *pmd = pmd_offset(pud,0); - spin_lock(&init_mm.page_table_lock); - phys_pmd_init(pmd, address, end); - spin_unlock(&init_mm.page_table_lock); - __flush_tlb_all(); + pmd_t *pmd = pmd_offset(pud, (unsigned long)__va(address)); + + if (pmd_none(*pmd)) { + spin_lock(&init_mm.page_table_lock); + phys_pmd_init(pmd, address, end); + spin_unlock(&init_mm.page_table_lock); + __flush_tlb_all(); + } } -static void __meminit phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end) +static void __meminit phys_pud_init(pud_t *pud, unsigned long address, unsigned long end) { - int i = pud_index(addr); + long i = pud_index(address); + pud = pud + i; - for (; i < PTRS_PER_PUD; i++, addr = (addr & PUD_MASK) + PUD_SIZE ) { + if (after_bootmem && pud_val(*pud)) { + phys_pmd_update(pud, address, end); + return; + } + + for (; i < PTRS_PER_PUD; pud++, i++) { int map; - unsigned long pmd_phys; - pud_t *pud = pud_page + pud_index(addr); + unsigned long paddr, pmd_phys; pmd_t *pmd; - if (addr >= end) + paddr = (address & PGDIR_MASK) + i*PUD_SIZE; + if (paddr >= end) break; - if (!after_bootmem && !e820_any_mapped(addr,addr+PUD_SIZE,0)) { + if (!after_bootmem && !e820_any_mapped(paddr, paddr+PUD_SIZE, 0)) { set_pud(pud, __pud(0)); continue; } - if (pud_val(*pud)) { - phys_pmd_update(pud, addr, end); - continue; - } - pmd = alloc_low_page(&map, &pmd_phys); spin_lock(&init_mm.page_table_lock); set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE)); - phys_pmd_init(pmd, addr, end); + phys_pmd_init(pmd, paddr, end); spin_unlock(&init_mm.page_table_lock); unmap_low_page(map); } @@ -403,15 +403,69 @@ void __cpuinit zap_low_mappings(int cpu) __flush_tlb_all(); } +/* Compute zone sizes for the DMA and DMA32 zones in a node. */ +__init void +size_zones(unsigned long *z, unsigned long *h, + unsigned long start_pfn, unsigned long end_pfn) +{ + int i; + unsigned long w; + + for (i = 0; i < MAX_NR_ZONES; i++) + z[i] = 0; + + if (start_pfn < MAX_DMA_PFN) + z[ZONE_DMA] = MAX_DMA_PFN - start_pfn; + if (start_pfn < MAX_DMA32_PFN) { + unsigned long dma32_pfn = MAX_DMA32_PFN; + if (dma32_pfn > end_pfn) + dma32_pfn = end_pfn; + z[ZONE_DMA32] = dma32_pfn - start_pfn; + } + z[ZONE_NORMAL] = end_pfn - start_pfn; + + /* Remove lower zones from higher ones. */ + w = 0; + for (i = 0; i < MAX_NR_ZONES; i++) { + if (z[i]) + z[i] -= w; + w += z[i]; + } + + /* Compute holes */ + w = start_pfn; + for (i = 0; i < MAX_NR_ZONES; i++) { + unsigned long s = w; + w += z[i]; + h[i] = e820_hole_size(s, w); + } + + /* Add the space pace needed for mem_map to the holes too. */ + for (i = 0; i < MAX_NR_ZONES; i++) + h[i] += (z[i] * sizeof(struct page)) / PAGE_SIZE; + + /* The 16MB DMA zone has the kernel and other misc mappings. + Account them too */ + if (h[ZONE_DMA]) { + h[ZONE_DMA] += dma_reserve; + if (h[ZONE_DMA] >= z[ZONE_DMA]) { + printk(KERN_WARNING + "Kernel too large and filling up ZONE_DMA?\n"); + h[ZONE_DMA] = z[ZONE_DMA]; + } + } +} + #ifndef CONFIG_NUMA void __init paging_init(void) { - unsigned long max_zone_pfns[MAX_NR_ZONES] = {MAX_DMA_PFN, - MAX_DMA32_PFN, - end_pfn}; + unsigned long zones[MAX_NR_ZONES], holes[MAX_NR_ZONES]; + memory_present(0, 0, end_pfn); sparse_init(); - free_area_init_nodes(max_zone_pfns); + size_zones(zones, holes, 0, end_pfn); + free_area_init_node(0, NODE_DATA(0), zones, + __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes); } #endif @@ -462,6 +516,19 @@ void online_page(struct page *page) } #ifdef CONFIG_MEMORY_HOTPLUG +/* + * XXX: memory_add_physaddr_to_nid() is to find node id from physical address + * via probe interface of sysfs. If acpi notifies hot-add event, then it + * can tell node id by searching dsdt. But, probe interface doesn't have + * node id. So, return 0 as node id at this time. + */ +#ifdef CONFIG_NUMA +int memory_add_physaddr_to_nid(u64 start) +{ + return 0; +} +#endif + /* * Memory is added always to NORMAL zone. This means you will never get * additional DMA/DMA32 memory. @@ -474,12 +541,12 @@ int arch_add_memory(int nid, u64 start, u64 size) unsigned long nr_pages = size >> PAGE_SHIFT; int ret; - init_memory_mapping(start, (start + size -1)); - ret = __add_pages(zone, start_pfn, nr_pages); if (ret) goto error; + init_memory_mapping(start, (start + size -1)); + return ret; error: printk("%s: Problem encountered in __add_pages!\n", __func__); @@ -493,24 +560,7 @@ int remove_memory(u64 start, u64 size) } EXPORT_SYMBOL_GPL(remove_memory); -#ifndef CONFIG_ACPI_NUMA -int memory_add_physaddr_to_nid(u64 start) -{ - return 0; -} -EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); -#endif - -#ifndef CONFIG_ACPI_NUMA -int memory_add_physaddr_to_nid(u64 start) -{ - return 0; -} -#endif - -#endif /* CONFIG_MEMORY_HOTPLUG */ - -#ifdef CONFIG_MEMORY_HOTPLUG_RESERVE +#else /* CONFIG_MEMORY_HOTPLUG */ /* * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, * just online the pages. @@ -536,7 +586,7 @@ int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) } return err; } -#endif +#endif /* CONFIG_MEMORY_HOTPLUG */ static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, kcore_vsyscall; @@ -547,6 +597,12 @@ void __init mem_init(void) pci_iommu_alloc(); + /* How many end-of-memory variables you have, grandma! */ + max_low_pfn = end_pfn; + max_pfn = end_pfn; + num_physpages = end_pfn; + high_memory = (void *) __va(end_pfn * PAGE_SIZE); + /* clear the zero-page */ memset(empty_zero_page, 0, PAGE_SIZE); @@ -558,8 +614,7 @@ void __init mem_init(void) #else totalram_pages = free_all_bootmem(); #endif - reservedpages = end_pfn - totalram_pages - - absent_pages_in_range(0, end_pfn); + reservedpages = end_pfn - totalram_pages - e820_hole_size(0, end_pfn); after_bootmem = 1; @@ -659,10 +714,8 @@ void __init reserve_bootmem_generic(unsigned long phys, unsigned len) #else reserve_bootmem(phys, len); #endif - if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) { + if (phys+len <= MAX_DMA_PFN*PAGE_SIZE) dma_reserve += len / PAGE_SIZE; - set_dma_reserve(dma_reserve); - } } int kern_addr_valid(unsigned long addr) diff --git a/trunk/arch/x86_64/mm/ioremap.c b/trunk/arch/x86_64/mm/ioremap.c index c6e5e8d401a4..45d7d823c3b8 100644 --- a/trunk/arch/x86_64/mm/ioremap.c +++ b/trunk/arch/x86_64/mm/ioremap.c @@ -12,16 +12,117 @@ #include #include #include -#include +#include #include #include -#include #include +#include #include #define ISA_START_ADDRESS 0xa0000 #define ISA_END_ADDRESS 0x100000 +static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + unsigned long pfn; + + address &= ~PMD_MASK; + end = address + size; + if (end > PMD_SIZE) + end = PMD_SIZE; + if (address >= end) + BUG(); + pfn = phys_addr >> PAGE_SHIFT; + do { + if (!pte_none(*pte)) { + printk("remap_area_pte: page already exists\n"); + BUG(); + } + set_pte(pte, pfn_pte(pfn, __pgprot(_PAGE_PRESENT | _PAGE_RW | + _PAGE_GLOBAL | _PAGE_DIRTY | _PAGE_ACCESSED | flags))); + address += PAGE_SIZE; + pfn++; + pte++; + } while (address && (address < end)); +} + +static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PUD_MASK; + end = address + size; + if (end > PUD_SIZE) + end = PUD_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pte_t * pte = pte_alloc_kernel(pmd, address); + if (!pte) + return -ENOMEM; + remap_area_pte(pte, address, end - address, address + phys_addr, flags); + address = (address + PMD_SIZE) & PMD_MASK; + pmd++; + } while (address && (address < end)); + return 0; +} + +static inline int remap_area_pud(pud_t * pud, unsigned long address, unsigned long size, + unsigned long phys_addr, unsigned long flags) +{ + unsigned long end; + + address &= ~PGDIR_MASK; + end = address + size; + if (end > PGDIR_SIZE) + end = PGDIR_SIZE; + phys_addr -= address; + if (address >= end) + BUG(); + do { + pmd_t * pmd = pmd_alloc(&init_mm, pud, address); + if (!pmd) + return -ENOMEM; + remap_area_pmd(pmd, address, end - address, address + phys_addr, flags); + address = (address + PUD_SIZE) & PUD_MASK; + pud++; + } while (address && (address < end)); + return 0; +} + +static int remap_area_pages(unsigned long address, unsigned long phys_addr, + unsigned long size, unsigned long flags) +{ + int error; + pgd_t *pgd; + unsigned long end = address + size; + + phys_addr -= address; + pgd = pgd_offset_k(address); + flush_cache_all(); + if (address >= end) + BUG(); + do { + pud_t *pud; + pud = pud_alloc(&init_mm, pgd, address); + error = -ENOMEM; + if (!pud) + break; + if (remap_area_pud(pud, address, end - address, + phys_addr + address, flags)) + break; + error = 0; + address = (address + PGDIR_SIZE) & PGDIR_MASK; + pgd++; + } while (address && (address < end)); + flush_tlb_all(); + return error; +} + /* * Fix up the linear direct mapping of the kernel to avoid cache attribute * conflicts. @@ -64,7 +165,6 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l void * addr; struct vm_struct * area; unsigned long offset, last_addr; - pgprot_t pgprot; /* Don't allow wraparound or zero size */ last_addr = phys_addr + size - 1; @@ -94,8 +194,6 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l } #endif - pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_GLOBAL - | _PAGE_DIRTY | _PAGE_ACCESSED | flags); /* * Mappings have to be page-aligned */ @@ -111,8 +209,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l return NULL; area->phys_addr = phys_addr; addr = area->addr; - if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, - phys_addr, pgprot)) { + if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr)); return NULL; } diff --git a/trunk/arch/x86_64/mm/k8topology.c b/trunk/arch/x86_64/mm/k8topology.c index b5b8dba28b4e..7c45c2d2b8b2 100644 --- a/trunk/arch/x86_64/mm/k8topology.c +++ b/trunk/arch/x86_64/mm/k8topology.c @@ -54,9 +54,6 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end) nodes_clear(nodes_parsed); - if (!early_pci_allowed()) - return -1; - nb = find_northbridge(); if (nb < 0) return nb; @@ -149,9 +146,6 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end) nodes[nodeid].start = base; nodes[nodeid].end = limit; - e820_register_active_regions(nodeid, - nodes[nodeid].start >> PAGE_SHIFT, - nodes[nodeid].end >> PAGE_SHIFT); prevbase = base; diff --git a/trunk/arch/x86_64/mm/numa.c b/trunk/arch/x86_64/mm/numa.c index 829a008bd39b..b2fac14baac0 100644 --- a/trunk/arch/x86_64/mm/numa.c +++ b/trunk/arch/x86_64/mm/numa.c @@ -161,7 +161,7 @@ void __init setup_node_bootmem(int nodeid, unsigned long start, unsigned long en bootmap_start >> PAGE_SHIFT, start_pfn, end_pfn); - free_bootmem_with_active_regions(nodeid, end); + e820_bootmem_free(NODE_DATA(nodeid), start, end); reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<> PAGE_SHIFT, - nodes[i].end >> PAGE_SHIFT); + for_each_online_node(i) setup_node_bootmem(i, nodes[i].start, nodes[i].end); - } numa_init_array(); return 0; } @@ -296,7 +299,6 @@ void __init numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn) for (i = 0; i < NR_CPUS; i++) numa_set_node(i, 0); node_to_cpumask[0] = cpumask_of_cpu(0); - e820_register_active_regions(0, start_pfn, end_pfn); setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT); } @@ -338,23 +340,17 @@ static void __init arch_sparse_init(void) void __init paging_init(void) { int i; - unsigned long max_zone_pfns[MAX_NR_ZONES] = { MAX_DMA_PFN, - MAX_DMA32_PFN, - end_pfn}; arch_sparse_init(); for_each_online_node(i) { setup_node_zones(i); } - - free_area_init_nodes(max_zone_pfns); } -static __init int numa_setup(char *opt) +/* [numa=off] */ +__init int numa_setup(char *opt) { - if (!opt) - return -EINVAL; if (!strncmp(opt,"off",3)) numa_off = 1; #ifdef CONFIG_NUMA_EMU @@ -370,11 +366,9 @@ static __init int numa_setup(char *opt) if (!strncmp(opt,"hotadd=", 7)) hotadd_percent = simple_strtoul(opt+7, NULL, 10); #endif - return 0; + return 1; } -early_param("numa", numa_setup); - /* * Setup early cpu_to_node. * diff --git a/trunk/arch/x86_64/mm/pageattr.c b/trunk/arch/x86_64/mm/pageattr.c index 3e231d762aaa..2685b1f3671c 100644 --- a/trunk/arch/x86_64/mm/pageattr.c +++ b/trunk/arch/x86_64/mm/pageattr.c @@ -108,8 +108,8 @@ static void revert_page(unsigned long address, pgprot_t ref_prot) BUG_ON(pud_none(*pud)); pmd = pmd_offset(pud, address); BUG_ON(pmd_val(*pmd) & _PAGE_PSE); + pgprot_val(ref_prot) |= _PAGE_PSE; large_pte = mk_pte_phys(__pa(address) & LARGE_PAGE_MASK, ref_prot); - large_pte = pte_mkhuge(large_pte); set_pte((pte_t *)pmd, large_pte); } @@ -119,28 +119,32 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, { pte_t *kpte; struct page *kpte_page; + unsigned kpte_flags; pgprot_t ref_prot2; kpte = lookup_address(address); if (!kpte) return 0; kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK); + kpte_flags = pte_val(*kpte); if (pgprot_val(prot) != pgprot_val(ref_prot)) { - if (!pte_huge(*kpte)) { + if ((kpte_flags & _PAGE_PSE) == 0) { set_pte(kpte, pfn_pte(pfn, prot)); } else { /* * split_large_page will take the reference for this * change_page_attr on the split page. */ + struct page *split; - ref_prot2 = pte_pgprot(pte_clrhuge(*kpte)); + ref_prot2 = __pgprot(pgprot_val(pte_pgprot(*lookup_address(address))) & ~(1<<_PAGE_BIT_PSE)); + split = split_large_page(address, prot, ref_prot2); if (!split) return -ENOMEM; - set_pte(kpte, mk_pte(split, ref_prot2)); + set_pte(kpte,mk_pte(split, ref_prot2)); kpte_page = split; - } + } page_private(kpte_page)++; - } else if (!pte_huge(*kpte)) { + } else if ((kpte_flags & _PAGE_PSE) == 0) { set_pte(kpte, pfn_pte(pfn, ref_prot)); BUG_ON(page_private(kpte_page) == 0); page_private(kpte_page)--; @@ -186,12 +190,10 @@ int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot) * lowmem */ if (__pa(address) < KERNEL_TEXT_SIZE) { unsigned long addr2; - pgprot_t prot2; + pgprot_t prot2 = prot; addr2 = __START_KERNEL_map + __pa(address); - /* Make sure the kernel mappings stay executable */ - prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot))); - err = __change_page_attr(addr2, pfn, prot2, - PAGE_KERNEL_EXEC); + pgprot_val(prot2) &= ~_PAGE_NX; + err = __change_page_attr(addr2, pfn, prot2, PAGE_KERNEL_EXEC); } } up_write(&init_mm.mmap_sem); diff --git a/trunk/arch/x86_64/mm/srat.c b/trunk/arch/x86_64/mm/srat.c index 3cc0544e25f5..502fce65e96a 100644 --- a/trunk/arch/x86_64/mm/srat.c +++ b/trunk/arch/x86_64/mm/srat.c @@ -21,15 +21,22 @@ #include #include -int acpi_numa __initdata; +#if (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \ + defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) \ + && !defined(CONFIG_MEMORY_HOTPLUG) +#define RESERVE_HOTADD 1 +#endif static struct acpi_table_slit *acpi_slit; static nodemask_t nodes_parsed __initdata; static struct bootnode nodes[MAX_NUMNODES] __initdata; -static struct bootnode nodes_add[MAX_NUMNODES]; +static struct bootnode nodes_add[MAX_NUMNODES] __initdata; static int found_add_area __initdata; int hotadd_percent __initdata = 0; +#ifndef RESERVE_HOTADD +#define hotadd_percent 0 /* Ignore all settings */ +#endif /* Too small nodes confuse the VM badly. Usually they result from BIOS bugs. */ @@ -84,7 +91,6 @@ static __init void bad_srat(void) apicid_to_node[i] = NUMA_NO_NODE; for (i = 0; i < MAX_NUMNODES; i++) nodes_add[i].start = nodes[i].end = 0; - remove_all_active_ranges(); } static __init inline int srat_disabled(void) @@ -151,7 +157,7 @@ acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) pxm, pa->apic_id, node); } -#ifdef CONFIG_MEMORY_HOTPLUG_RESERVE +#ifdef RESERVE_HOTADD /* * Protect against too large hotadd areas that would fill up memory. */ @@ -167,7 +173,7 @@ static int hotadd_enough_memory(struct bootnode *nd) if (mem < 0) return 0; - allowed = (end_pfn - absent_pages_in_range(0, end_pfn)) * PAGE_SIZE; + allowed = (end_pfn - e820_hole_size(0, end_pfn)) * PAGE_SIZE; allowed = (allowed / 100) * hotadd_percent; if (allocated + mem > allowed) { unsigned long range; @@ -194,37 +200,15 @@ static int hotadd_enough_memory(struct bootnode *nd) return 1; } -static int update_end_of_memory(unsigned long end) -{ - found_add_area = 1; - if ((end >> PAGE_SHIFT) > end_pfn) - end_pfn = end >> PAGE_SHIFT; - return 1; -} - -static inline int save_add_info(void) -{ - return hotadd_percent > 0; -} -#else -int update_end_of_memory(unsigned long end) {return 0;} -static int hotadd_enough_memory(struct bootnode *nd) {return 1;} -#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE -static inline int save_add_info(void) {return 1;} -#else -static inline int save_add_info(void) {return 0;} -#endif -#endif /* - * Update nodes_add and decide if to include add are in the zone. - * Both SPARSE and RESERVE need nodes_add infomation. + * It is fine to add this area to the nodes data it will be used later * This code supports one contigious hot add area per node. */ static int reserve_hotadd(int node, unsigned long start, unsigned long end) { unsigned long s_pfn = start >> PAGE_SHIFT; unsigned long e_pfn = end >> PAGE_SHIFT; - int ret = 0, changed = 0; + int changed = 0; struct bootnode *nd = &nodes_add[node]; /* I had some trouble with strange memory hotadd regions breaking @@ -239,10 +223,8 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end) } /* This check might be a bit too strict, but I'm keeping it for now. */ - if (absent_pages_in_range(s_pfn, e_pfn) != e_pfn - s_pfn) { - printk(KERN_ERR - "SRAT: Hotplug area %lu -> %lu has existing memory\n", - s_pfn, e_pfn); + if (e820_hole_size(s_pfn, e_pfn) != e_pfn - s_pfn) { + printk(KERN_ERR "SRAT: Hotplug area has existing memory\n"); return -1; } @@ -253,6 +235,7 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end) /* Looks good */ + found_add_area = 1; if (nd->start == nd->end) { nd->start = start; nd->end = end; @@ -270,12 +253,14 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end) printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n"); } - ret = update_end_of_memory(nd->end); + if ((nd->end >> PAGE_SHIFT) > end_pfn) + end_pfn = nd->end >> PAGE_SHIFT; if (changed) printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", nd->start, nd->end); - return ret; + return 0; } +#endif /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ void __init @@ -294,7 +279,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) } if (ma->flags.enabled == 0) return; - if (ma->flags.hot_pluggable && !save_add_info()) + if (ma->flags.hot_pluggable && hotadd_percent == 0) return; start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); @@ -332,18 +317,16 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm, nd->start, nd->end); - e820_register_active_regions(node, nd->start >> PAGE_SHIFT, - nd->end >> PAGE_SHIFT); - push_node_boundaries(node, nd->start >> PAGE_SHIFT, - nd->end >> PAGE_SHIFT); - if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) < 0) { +#ifdef RESERVE_HOTADD + if (ma->flags.hot_pluggable && reserve_hotadd(node, start, end) < 0) { /* Ignore hotadd region. Undo damage */ printk(KERN_NOTICE "SRAT: Hotplug region ignored\n"); *nd = oldnode; if ((nd->start | nd->end) == 0) node_clear(node, nodes_parsed); } +#endif } /* Sanity check to catch more bad SRATs (they are amazingly common). @@ -358,12 +341,13 @@ static int nodes_cover_memory(void) unsigned long s = nodes[i].start >> PAGE_SHIFT; unsigned long e = nodes[i].end >> PAGE_SHIFT; pxmram += e - s; - pxmram -= absent_pages_in_range(s, e); + pxmram -= e820_hole_size(s, e); + pxmram -= nodes_add[i].end - nodes_add[i].start; if ((long)pxmram < 0) pxmram = 0; } - e820ram = end_pfn - absent_pages_in_range(0, end_pfn); + e820ram = end_pfn - e820_hole_size(0, end_pfn); /* We seem to lose 3 pages somewhere. Allow a bit of slack. */ if ((long)(e820ram - pxmram) >= 1*1024*1024) { printk(KERN_ERR @@ -466,16 +450,3 @@ int __node_distance(int a, int b) } EXPORT_SYMBOL(__node_distance); - -int memory_add_physaddr_to_nid(u64 start) -{ - int i, ret = 0; - - for_each_node(i) - if (nodes_add[i].start <= start && nodes_add[i].end > start) - ret = i; - - return ret; -} -EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); - diff --git a/trunk/arch/x86_64/pci/Makefile b/trunk/arch/x86_64/pci/Makefile index 1eb18f421edf..a3f6ad570179 100644 --- a/trunk/arch/x86_64/pci/Makefile +++ b/trunk/arch/x86_64/pci/Makefile @@ -9,7 +9,7 @@ obj-y := i386.o obj-$(CONFIG_PCI_DIRECT)+= direct.o obj-y += fixup.o init.o obj-$(CONFIG_ACPI) += acpi.o -obj-y += legacy.o irq.o common.o early.o +obj-y += legacy.o irq.o common.o # mmconfig has a 64bit special obj-$(CONFIG_PCI_MMCONFIG) += mmconfig.o direct.o @@ -23,4 +23,3 @@ common-y += ../../i386/pci/common.o fixup-y += ../../i386/pci/fixup.o i386-y += ../../i386/pci/i386.o init-y += ../../i386/pci/init.o -early-y += ../../i386/pci/early.o diff --git a/trunk/arch/x86_64/pci/mmconfig.c b/trunk/arch/x86_64/pci/mmconfig.c index 7732f4254d21..3c55c76c6fd5 100644 --- a/trunk/arch/x86_64/pci/mmconfig.c +++ b/trunk/arch/x86_64/pci/mmconfig.c @@ -156,45 +156,15 @@ static __init void unreachable_devices(void) addr = pci_dev_base(0, k, PCI_DEVFN(i, 0)); if (addr == NULL|| readl(addr) != val1) { set_bit(i + 32*k, fallback_slots); - printk(KERN_NOTICE "PCI: No mmconfig possible" - " on device %02x:%02x\n", k, i); + printk(KERN_NOTICE + "PCI: No mmconfig possible on device %x:%x\n", + k, i); } } } } -static __init void pci_mmcfg_insert_resources(void) -{ -#define PCI_MMCFG_RESOURCE_NAME_LEN 19 - int i; - struct resource *res; - char *names; - unsigned num_buses; - - res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res), - pci_mmcfg_config_num, GFP_KERNEL); - - if (!res) { - printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n"); - return; - } - - names = (void *)&res[pci_mmcfg_config_num]; - for (i = 0; i < pci_mmcfg_config_num; i++, res++) { - num_buses = pci_mmcfg_config[i].end_bus_number - - pci_mmcfg_config[i].start_bus_number + 1; - res->name = names; - snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN, "PCI MMCONFIG %u", - pci_mmcfg_config[i].pci_segment_group_number); - res->start = pci_mmcfg_config[i].base_address; - res->end = res->start + (num_buses << 20) - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - insert_resource(&iomem_resource, res); - names += PCI_MMCFG_RESOURCE_NAME_LEN; - } -} - -void __init pci_mmcfg_init(int type) +void __init pci_mmcfg_init(void) { int i; @@ -207,9 +177,7 @@ void __init pci_mmcfg_init(int type) (pci_mmcfg_config[0].base_address == 0)) return; - /* Only do this check when type 1 works. If it doesn't work - assume we run on a Mac and always use MCFG */ - if (type == 1 && !e820_all_mapped(pci_mmcfg_config[0].base_address, + if (!e820_all_mapped(pci_mmcfg_config[0].base_address, pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, E820_RESERVED)) { printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", @@ -218,6 +186,7 @@ void __init pci_mmcfg_init(int type) return; } + /* RED-PEN i386 doesn't do _nocache right now */ pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); if (pci_mmcfg_virt == NULL) { printk("PCI: Can not allocate memory for mmconfig structures\n"); @@ -236,7 +205,6 @@ void __init pci_mmcfg_init(int type) } unreachable_devices(); - pci_mmcfg_insert_resources(); raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; diff --git a/trunk/arch/xtensa/kernel/syscalls.c b/trunk/arch/xtensa/kernel/syscalls.c index d9285d4d5565..4688ba2db84d 100644 --- a/trunk/arch/xtensa/kernel/syscalls.c +++ b/trunk/arch/xtensa/kernel/syscalls.c @@ -128,7 +128,7 @@ int sys_execve(struct pt_regs *regs) int sys_uname(struct old_utsname * name) { - if (name && !copy_to_user(name, utsname(), sizeof (*name))) + if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) return 0; return -EFAULT; } @@ -266,23 +266,3 @@ void system_call (struct pt_regs *regs) regs->areg[2] = res; do_syscall_trace(); } - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - long __res; - asm volatile ( - " mov a5, %2 \n" - " mov a4, %4 \n" - " mov a3, %3 \n" - " movi a2, %1 \n" - " syscall \n" - " mov %0, a2 \n" - : "=a" (__res) - : "i" (__NR_execve), "a" (filename), "a" (argv), "a" (envp) - : "a2", "a3", "a4", "a5"); - return __res; -} diff --git a/trunk/arch/xtensa/kernel/time.c b/trunk/arch/xtensa/kernel/time.c index 37347e369987..412ab32de391 100644 --- a/trunk/arch/xtensa/kernel/time.c +++ b/trunk/arch/xtensa/kernel/time.c @@ -26,6 +26,8 @@ #include +extern volatile unsigned long wall_jiffies; + DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -108,6 +110,7 @@ int do_settimeofday(struct timespec *tv) */ ccount = get_ccount(); nsec -= (ccount - last_ccount_stamp) * CCOUNT_NSEC; + nsec -= (jiffies - wall_jiffies) * CCOUNT_PER_JIFFY * CCOUNT_NSEC; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -126,7 +129,7 @@ EXPORT_SYMBOL(do_settimeofday); void do_gettimeofday(struct timeval *tv) { unsigned long flags; - unsigned long sec, usec, delta, seq; + unsigned long sec, usec, delta, lost, seq; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); @@ -134,9 +137,12 @@ void do_gettimeofday(struct timeval *tv) delta = get_ccount() - last_ccount_stamp; sec = xtime.tv_sec; usec = (xtime.tv_nsec / NSEC_PER_USEC); + + lost = jiffies - wall_jiffies; + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - usec += (delta * CCOUNT_NSEC) / NSEC_PER_USEC; + usec += lost * (1000000UL/HZ) + (delta * CCOUNT_NSEC) / NSEC_PER_USEC; for (; usec >= 1000000; sec++, usec -= 1000000) ; @@ -169,11 +175,12 @@ irqreturn_t timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) last_ccount_stamp = next; next += CCOUNT_PER_JIFFY; - do_timer (1); /* Linux handler in kernel/timer.c */ + do_timer (regs); /* Linux handler in kernel/timer.c */ if (ntp_synced() && xtime.tv_sec - last_rtc_update >= 659 && - abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ) { + abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ && + jiffies - wall_jiffies == 1) { if (platform_set_rtc_time(xtime.tv_sec+1) == 0) last_rtc_update = xtime.tv_sec+1; diff --git a/trunk/arch/xtensa/mm/fault.c b/trunk/arch/xtensa/mm/fault.c index dd0dbec2e57e..a945a33e85a1 100644 --- a/trunk/arch/xtensa/mm/fault.c +++ b/trunk/arch/xtensa/mm/fault.c @@ -144,7 +144,7 @@ void do_page_fault(struct pt_regs *regs) */ out_of_memory: up_read(&mm->mmap_sem); - if (is_init(current)) { + if (current->pid == 1) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/xtensa/platform-iss/console.c b/trunk/arch/xtensa/platform-iss/console.c index 5c947cae7520..22d3c571a7bc 100644 --- a/trunk/arch/xtensa/platform-iss/console.c +++ b/trunk/arch/xtensa/platform-iss/console.c @@ -191,7 +191,7 @@ static int rs_read_proc(char *page, char **start, off_t off, int count, } -static const struct tty_operations serial_ops = { +static struct tty_operations serial_ops = { .open = rs_open, .close = rs_close, .write = rs_write, diff --git a/trunk/arch/xtensa/platform-iss/network.c b/trunk/arch/xtensa/platform-iss/network.c index 15d64414bd60..d96164e602fe 100644 --- a/trunk/arch/xtensa/platform-iss/network.c +++ b/trunk/arch/xtensa/platform-iss/network.c @@ -201,7 +201,7 @@ static void dev_ip_addr(void *d, char *buf, char *bin_buf) struct net_device *dev = d; struct in_device *ip = dev->ip_ptr; struct in_ifaddr *in; - __be32 addr; + u32 addr; if ((ip == NULL) || ((in = ip->ifa_list) == NULL)) { printk(KERN_WARNING "Device not assigned an IP address!\n"); diff --git a/trunk/block/Kconfig b/trunk/block/Kconfig index 83766a6bdee2..b6f5f0a79655 100644 --- a/trunk/block/Kconfig +++ b/trunk/block/Kconfig @@ -1,24 +1,6 @@ # # Block layer core configuration # -config BLOCK - bool "Enable the block layer" if EMBEDDED - default y - help - This permits the block layer to be removed from the kernel if it's not - needed (on some embedded devices for example). If this option is - disabled, then blockdev files will become unusable and some - filesystems (such as ext3) will become unavailable. - - This option will also disable SCSI character devices and USB storage - since they make use of various block layer definitions and - facilities. - - Say Y here unless you know you really don't want to mount disks and - suchlike. - -if BLOCK - #XXX - it makes sense to enable this only for 32-bit subarch's, not for x86_64 #for instance. config LBD @@ -51,6 +33,4 @@ config LSF If unsure, say Y. -endif - source block/Kconfig.iosched diff --git a/trunk/block/Kconfig.iosched b/trunk/block/Kconfig.iosched index 903f0d3b6852..48d090e266fc 100644 --- a/trunk/block/Kconfig.iosched +++ b/trunk/block/Kconfig.iosched @@ -1,4 +1,3 @@ -if BLOCK menu "IO Schedulers" @@ -68,5 +67,3 @@ config DEFAULT_IOSCHED default "noop" if DEFAULT_NOOP endmenu - -endif diff --git a/trunk/block/Makefile b/trunk/block/Makefile index 4b84d0d5947b..c05de0e0037f 100644 --- a/trunk/block/Makefile +++ b/trunk/block/Makefile @@ -2,7 +2,7 @@ # Makefile for the kernel block layer # -obj-$(CONFIG_BLOCK) := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o +obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o obj-$(CONFIG_IOSCHED_AS) += as-iosched.o diff --git a/trunk/block/as-iosched.c b/trunk/block/as-iosched.c index 50b95e4c1425..5da56d48fbd3 100644 --- a/trunk/block/as-iosched.c +++ b/trunk/block/as-iosched.c @@ -1,7 +1,7 @@ /* * Anticipatory & deadline i/o scheduler. * - * Copyright (C) 2002 Jens Axboe + * Copyright (C) 2002 Jens Axboe * Nick Piggin * */ @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -92,8 +93,9 @@ struct as_data { struct rb_root sort_list[2]; struct list_head fifo_list[2]; - struct request *next_rq[2]; /* next in sort order */ + struct as_rq *next_arq[2]; /* next in sort order */ sector_t last_sector[2]; /* last REQ_SYNC & REQ_ASYNC sectors */ + struct hlist_head *hash; /* request hash */ unsigned long exit_prob; /* probability a task will exit while being waited on */ @@ -113,6 +115,7 @@ struct as_data { int write_batch_count; /* max # of reqs in a write batch */ int current_write_count; /* how many requests left this batch */ int write_batch_idled; /* has the write batch gone idle? */ + mempool_t *arq_pool; enum anticipation_status antic_status; unsigned long antic_start; /* jiffies: when it started */ @@ -130,6 +133,8 @@ struct as_data { unsigned long antic_expire; }; +#define list_entry_fifo(ptr) list_entry((ptr), struct as_rq, fifo) + /* * per-request data. */ @@ -145,14 +150,40 @@ enum arq_state { AS_RQ_POSTSCHED, /* when they shouldn't be */ }; -#define RQ_IOC(rq) ((struct io_context *) (rq)->elevator_private) -#define RQ_STATE(rq) ((enum arq_state)(rq)->elevator_private2) -#define RQ_SET_STATE(rq, state) ((rq)->elevator_private2 = (void *) state) +struct as_rq { + /* + * rbtree index, key is the starting offset + */ + struct rb_node rb_node; + sector_t rb_key; + + struct request *request; + + struct io_context *io_context; /* The submitting task */ + + /* + * request hash, key is the ending offset (for back merge lookup) + */ + struct hlist_node hash; + + /* + * expire fifo + */ + struct list_head fifo; + unsigned long expires; -static DEFINE_PER_CPU(unsigned long, ioc_count); + unsigned int is_sync; + enum arq_state state; +}; + +#define RQ_DATA(rq) ((struct as_rq *) (rq)->elevator_private) + +static kmem_cache_t *arq_pool; + +static atomic_t ioc_count = ATOMIC_INIT(0); static struct completion *ioc_gone; -static void as_move_to_dispatch(struct as_data *ad, struct request *rq); +static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq); static void as_antic_stop(struct as_data *ad); /* @@ -163,8 +194,7 @@ static void as_antic_stop(struct as_data *ad); static void free_as_io_context(struct as_io_context *aic) { kfree(aic); - elv_ioc_count_dec(ioc_count); - if (ioc_gone && !elv_ioc_count_read(ioc_count)) + if (atomic_dec_and_test(&ioc_count) && ioc_gone) complete(ioc_gone); } @@ -200,7 +230,7 @@ static struct as_io_context *alloc_as_io_context(void) ret->seek_total = 0; ret->seek_samples = 0; ret->seek_mean = 0; - elv_ioc_count_inc(ioc_count); + atomic_inc(&ioc_count); } return ret; @@ -210,9 +240,9 @@ static struct as_io_context *alloc_as_io_context(void) * If the current task has no AS IO context then create one and initialise it. * Then take a ref on the task's io context and return it. */ -static struct io_context *as_get_io_context(int node) +static struct io_context *as_get_io_context(void) { - struct io_context *ioc = get_io_context(GFP_ATOMIC, node); + struct io_context *ioc = get_io_context(GFP_ATOMIC); if (ioc && !ioc->aic) { ioc->aic = alloc_as_io_context(); if (!ioc->aic) { @@ -223,43 +253,194 @@ static struct io_context *as_get_io_context(int node) return ioc; } -static void as_put_io_context(struct request *rq) +static void as_put_io_context(struct as_rq *arq) { struct as_io_context *aic; - if (unlikely(!RQ_IOC(rq))) + if (unlikely(!arq->io_context)) return; - aic = RQ_IOC(rq)->aic; + aic = arq->io_context->aic; - if (rq_is_sync(rq) && aic) { + if (arq->is_sync == REQ_SYNC && aic) { spin_lock(&aic->lock); set_bit(AS_TASK_IORUNNING, &aic->state); aic->last_end_request = jiffies; spin_unlock(&aic->lock); } - put_io_context(RQ_IOC(rq)); + put_io_context(arq->io_context); +} + +/* + * the back merge hash support functions + */ +static const int as_hash_shift = 6; +#define AS_HASH_BLOCK(sec) ((sec) >> 3) +#define AS_HASH_FN(sec) (hash_long(AS_HASH_BLOCK((sec)), as_hash_shift)) +#define AS_HASH_ENTRIES (1 << as_hash_shift) +#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) + +static inline void __as_del_arq_hash(struct as_rq *arq) +{ + hlist_del_init(&arq->hash); +} + +static inline void as_del_arq_hash(struct as_rq *arq) +{ + if (!hlist_unhashed(&arq->hash)) + __as_del_arq_hash(arq); +} + +static void as_add_arq_hash(struct as_data *ad, struct as_rq *arq) +{ + struct request *rq = arq->request; + + BUG_ON(!hlist_unhashed(&arq->hash)); + + hlist_add_head(&arq->hash, &ad->hash[AS_HASH_FN(rq_hash_key(rq))]); +} + +/* + * move hot entry to front of chain + */ +static inline void as_hot_arq_hash(struct as_data *ad, struct as_rq *arq) +{ + struct request *rq = arq->request; + struct hlist_head *head = &ad->hash[AS_HASH_FN(rq_hash_key(rq))]; + + if (hlist_unhashed(&arq->hash)) { + WARN_ON(1); + return; + } + + if (&arq->hash != head->first) { + hlist_del(&arq->hash); + hlist_add_head(&arq->hash, head); + } +} + +static struct request *as_find_arq_hash(struct as_data *ad, sector_t offset) +{ + struct hlist_head *hash_list = &ad->hash[AS_HASH_FN(offset)]; + struct hlist_node *entry, *next; + struct as_rq *arq; + + hlist_for_each_entry_safe(arq, entry, next, hash_list, hash) { + struct request *__rq = arq->request; + + BUG_ON(hlist_unhashed(&arq->hash)); + + if (!rq_mergeable(__rq)) { + as_del_arq_hash(arq); + continue; + } + + if (rq_hash_key(__rq) == offset) + return __rq; + } + + return NULL; } /* * rb tree support functions */ -#define RQ_RB_ROOT(ad, rq) (&(ad)->sort_list[rq_is_sync((rq))]) +#define rb_entry_arq(node) rb_entry((node), struct as_rq, rb_node) +#define ARQ_RB_ROOT(ad, arq) (&(ad)->sort_list[(arq)->is_sync]) +#define rq_rb_key(rq) (rq)->sector + +/* + * as_find_first_arq finds the first (lowest sector numbered) request + * for the specified data_dir. Used to sweep back to the start of the disk + * (1-way elevator) after we process the last (highest sector) request. + */ +static struct as_rq *as_find_first_arq(struct as_data *ad, int data_dir) +{ + struct rb_node *n = ad->sort_list[data_dir].rb_node; + + if (n == NULL) + return NULL; + + for (;;) { + if (n->rb_left == NULL) + return rb_entry_arq(n); + + n = n->rb_left; + } +} + +/* + * Add the request to the rb tree if it is unique. If there is an alias (an + * existing request against the same sector), which can happen when using + * direct IO, then return the alias. + */ +static struct as_rq *__as_add_arq_rb(struct as_data *ad, struct as_rq *arq) +{ + struct rb_node **p = &ARQ_RB_ROOT(ad, arq)->rb_node; + struct rb_node *parent = NULL; + struct as_rq *__arq; + struct request *rq = arq->request; + + arq->rb_key = rq_rb_key(rq); + + while (*p) { + parent = *p; + __arq = rb_entry_arq(parent); + + if (arq->rb_key < __arq->rb_key) + p = &(*p)->rb_left; + else if (arq->rb_key > __arq->rb_key) + p = &(*p)->rb_right; + else + return __arq; + } + + rb_link_node(&arq->rb_node, parent, p); + rb_insert_color(&arq->rb_node, ARQ_RB_ROOT(ad, arq)); + + return NULL; +} -static void as_add_rq_rb(struct as_data *ad, struct request *rq) +static void as_add_arq_rb(struct as_data *ad, struct as_rq *arq) { - struct request *alias; + struct as_rq *alias; - while ((unlikely(alias = elv_rb_add(RQ_RB_ROOT(ad, rq), rq)))) { + while ((unlikely(alias = __as_add_arq_rb(ad, arq)))) { as_move_to_dispatch(ad, alias); as_antic_stop(ad); } } -static inline void as_del_rq_rb(struct as_data *ad, struct request *rq) +static inline void as_del_arq_rb(struct as_data *ad, struct as_rq *arq) +{ + if (!RB_EMPTY_NODE(&arq->rb_node)) { + WARN_ON(1); + return; + } + + rb_erase(&arq->rb_node, ARQ_RB_ROOT(ad, arq)); + RB_CLEAR_NODE(&arq->rb_node); +} + +static struct request * +as_find_arq_rb(struct as_data *ad, sector_t sector, int data_dir) { - elv_rb_del(RQ_RB_ROOT(ad, rq), rq); + struct rb_node *n = ad->sort_list[data_dir].rb_node; + struct as_rq *arq; + + while (n) { + arq = rb_entry_arq(n); + + if (sector < arq->rb_key) + n = n->rb_left; + else if (sector > arq->rb_key) + n = n->rb_right; + else + return arq->request; + } + + return NULL; } /* @@ -277,26 +458,26 @@ static inline void as_del_rq_rb(struct as_data *ad, struct request *rq) * as_choose_req selects the preferred one of two requests of the same data_dir * ignoring time - eg. timeouts, which is the job of as_dispatch_request */ -static struct request * -as_choose_req(struct as_data *ad, struct request *rq1, struct request *rq2) +static struct as_rq * +as_choose_req(struct as_data *ad, struct as_rq *arq1, struct as_rq *arq2) { int data_dir; sector_t last, s1, s2, d1, d2; int r1_wrap=0, r2_wrap=0; /* requests are behind the disk head */ const sector_t maxback = MAXBACK; - if (rq1 == NULL || rq1 == rq2) - return rq2; - if (rq2 == NULL) - return rq1; + if (arq1 == NULL || arq1 == arq2) + return arq2; + if (arq2 == NULL) + return arq1; - data_dir = rq_is_sync(rq1); + data_dir = arq1->is_sync; last = ad->last_sector[data_dir]; - s1 = rq1->sector; - s2 = rq2->sector; + s1 = arq1->request->sector; + s2 = arq2->request->sector; - BUG_ON(data_dir != rq_is_sync(rq2)); + BUG_ON(data_dir != arq2->is_sync); /* * Strict one way elevator _except_ in the case where we allow @@ -323,58 +504,61 @@ as_choose_req(struct as_data *ad, struct request *rq1, struct request *rq2) /* Found required data */ if (!r1_wrap && r2_wrap) - return rq1; + return arq1; else if (!r2_wrap && r1_wrap) - return rq2; + return arq2; else if (r1_wrap && r2_wrap) { /* both behind the head */ if (s1 <= s2) - return rq1; + return arq1; else - return rq2; + return arq2; } /* Both requests in front of the head */ if (d1 < d2) - return rq1; + return arq1; else if (d2 < d1) - return rq2; + return arq2; else { if (s1 >= s2) - return rq1; + return arq1; else - return rq2; + return arq2; } } /* - * as_find_next_rq finds the next request after @prev in elevator order. + * as_find_next_arq finds the next request after @prev in elevator order. * this with as_choose_req form the basis for how the scheduler chooses * what request to process next. Anticipation works on top of this. */ -static struct request * -as_find_next_rq(struct as_data *ad, struct request *last) +static struct as_rq *as_find_next_arq(struct as_data *ad, struct as_rq *last) { + const int data_dir = last->is_sync; + struct as_rq *ret; struct rb_node *rbnext = rb_next(&last->rb_node); struct rb_node *rbprev = rb_prev(&last->rb_node); - struct request *next = NULL, *prev = NULL; + struct as_rq *arq_next, *arq_prev; - BUG_ON(RB_EMPTY_NODE(&last->rb_node)); + BUG_ON(!RB_EMPTY_NODE(&last->rb_node)); if (rbprev) - prev = rb_entry_rq(rbprev); + arq_prev = rb_entry_arq(rbprev); + else + arq_prev = NULL; if (rbnext) - next = rb_entry_rq(rbnext); + arq_next = rb_entry_arq(rbnext); else { - const int data_dir = rq_is_sync(last); - - rbnext = rb_first(&ad->sort_list[data_dir]); - if (rbnext && rbnext != &last->rb_node) - next = rb_entry_rq(rbnext); + arq_next = as_find_first_arq(ad, data_dir); + if (arq_next == last) + arq_next = NULL; } - return as_choose_req(ad, next, prev); + ret = as_choose_req(ad, arq_next, arq_prev); + + return ret; } /* @@ -528,7 +712,8 @@ static void as_update_seekdist(struct as_data *ad, struct as_io_context *aic, static void as_update_iohist(struct as_data *ad, struct as_io_context *aic, struct request *rq) { - int data_dir = rq_is_sync(rq); + struct as_rq *arq = RQ_DATA(rq); + int data_dir = arq->is_sync; unsigned long thinktime = 0; sector_t seek_dist; @@ -567,11 +752,11 @@ static void as_update_iohist(struct as_data *ad, struct as_io_context *aic, * previous one issued. */ static int as_close_req(struct as_data *ad, struct as_io_context *aic, - struct request *rq) + struct as_rq *arq) { unsigned long delay; /* milliseconds */ sector_t last = ad->last_sector[ad->batch_data_dir]; - sector_t next = rq->sector; + sector_t next = arq->request->sector; sector_t delta; /* acceptable close offset (in sectors) */ sector_t s; @@ -628,7 +813,7 @@ static int as_close_req(struct as_data *ad, struct as_io_context *aic, * * If this task has queued some other IO, do not enter enticipation. */ -static int as_can_break_anticipation(struct as_data *ad, struct request *rq) +static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq) { struct io_context *ioc; struct as_io_context *aic; @@ -636,7 +821,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct request *rq) ioc = ad->io_context; BUG_ON(!ioc); - if (rq && ioc == RQ_IOC(rq)) { + if (arq && ioc == arq->io_context) { /* request from same process */ return 1; } @@ -663,7 +848,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct request *rq) return 1; } - if (rq && rq_is_sync(rq) && as_close_req(ad, aic, rq)) { + if (arq && arq->is_sync == REQ_SYNC && as_close_req(ad, aic, arq)) { /* * Found a close request that is not one of ours. * @@ -679,7 +864,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct request *rq) ad->exit_no_coop = (7*ad->exit_no_coop)/8; } - as_update_iohist(ad, aic, rq); + as_update_iohist(ad, aic, arq->request); return 1; } @@ -706,10 +891,10 @@ static int as_can_break_anticipation(struct as_data *ad, struct request *rq) } /* - * as_can_anticipate indicates whether we should either run rq + * as_can_anticipate indicates whether we should either run arq * or keep anticipating a better request. */ -static int as_can_anticipate(struct as_data *ad, struct request *rq) +static int as_can_anticipate(struct as_data *ad, struct as_rq *arq) { if (!ad->io_context) /* @@ -723,7 +908,7 @@ static int as_can_anticipate(struct as_data *ad, struct request *rq) */ return 0; - if (as_can_break_anticipation(ad, rq)) + if (as_can_break_anticipation(ad, arq)) /* * This request is a good candidate. Don't keep anticipating, * run it. @@ -741,16 +926,16 @@ static int as_can_anticipate(struct as_data *ad, struct request *rq) } /* - * as_update_rq must be called whenever a request (rq) is added to + * as_update_arq must be called whenever a request (arq) is added to * the sort_list. This function keeps caches up to date, and checks if the * request might be one we are "anticipating" */ -static void as_update_rq(struct as_data *ad, struct request *rq) +static void as_update_arq(struct as_data *ad, struct as_rq *arq) { - const int data_dir = rq_is_sync(rq); + const int data_dir = arq->is_sync; - /* keep the next_rq cache up to date */ - ad->next_rq[data_dir] = as_choose_req(ad, rq, ad->next_rq[data_dir]); + /* keep the next_arq cache up to date */ + ad->next_arq[data_dir] = as_choose_req(ad, arq, ad->next_arq[data_dir]); /* * have we been anticipating this request? @@ -759,7 +944,7 @@ static void as_update_rq(struct as_data *ad, struct request *rq) */ if (ad->antic_status == ANTIC_WAIT_REQ || ad->antic_status == ANTIC_WAIT_NEXT) { - if (as_can_break_anticipation(ad, rq)) + if (as_can_break_anticipation(ad, arq)) as_antic_stop(ad); } } @@ -799,11 +984,12 @@ static void update_write_batch(struct as_data *ad) static void as_completed_request(request_queue_t *q, struct request *rq) { struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq = RQ_DATA(rq); WARN_ON(!list_empty(&rq->queuelist)); - if (RQ_STATE(rq) != AS_RQ_REMOVED) { - printk("rq->state %d\n", RQ_STATE(rq)); + if (arq->state != AS_RQ_REMOVED) { + printk("arq->state %d\n", arq->state); WARN_ON(1); goto out; } @@ -823,14 +1009,14 @@ static void as_completed_request(request_queue_t *q, struct request *rq) * actually serviced. This should help devices with big TCQ windows * and writeback caches */ - if (ad->new_batch && ad->batch_data_dir == rq_is_sync(rq)) { + if (ad->new_batch && ad->batch_data_dir == arq->is_sync) { update_write_batch(ad); ad->current_batch_expires = jiffies + ad->batch_expire[REQ_SYNC]; ad->new_batch = 0; } - if (ad->io_context == RQ_IOC(rq) && ad->io_context) { + if (ad->io_context == arq->io_context && ad->io_context) { ad->antic_start = jiffies; ad->ioc_finished = 1; if (ad->antic_status == ANTIC_WAIT_REQ) { @@ -842,9 +1028,9 @@ static void as_completed_request(request_queue_t *q, struct request *rq) } } - as_put_io_context(rq); + as_put_io_context(arq); out: - RQ_SET_STATE(rq, AS_RQ_POSTSCHED); + arq->state = AS_RQ_POSTSCHED; } /* @@ -855,27 +1041,27 @@ static void as_completed_request(request_queue_t *q, struct request *rq) */ static void as_remove_queued_request(request_queue_t *q, struct request *rq) { - const int data_dir = rq_is_sync(rq); + struct as_rq *arq = RQ_DATA(rq); + const int data_dir = arq->is_sync; struct as_data *ad = q->elevator->elevator_data; - struct io_context *ioc; - WARN_ON(RQ_STATE(rq) != AS_RQ_QUEUED); + WARN_ON(arq->state != AS_RQ_QUEUED); - ioc = RQ_IOC(rq); - if (ioc && ioc->aic) { - BUG_ON(!atomic_read(&ioc->aic->nr_queued)); - atomic_dec(&ioc->aic->nr_queued); + if (arq->io_context && arq->io_context->aic) { + BUG_ON(!atomic_read(&arq->io_context->aic->nr_queued)); + atomic_dec(&arq->io_context->aic->nr_queued); } /* - * Update the "next_rq" cache if we are about to remove its + * Update the "next_arq" cache if we are about to remove its * entry */ - if (ad->next_rq[data_dir] == rq) - ad->next_rq[data_dir] = as_find_next_rq(ad, rq); + if (ad->next_arq[data_dir] == arq) + ad->next_arq[data_dir] = as_find_next_arq(ad, arq); - rq_fifo_clear(rq); - as_del_rq_rb(ad, rq); + list_del_init(&arq->fifo); + as_del_arq_hash(arq); + as_del_arq_rb(ad, arq); } /* @@ -888,7 +1074,7 @@ static void as_remove_queued_request(request_queue_t *q, struct request *rq) */ static int as_fifo_expired(struct as_data *ad, int adir) { - struct request *rq; + struct as_rq *arq; long delta_jif; delta_jif = jiffies - ad->last_check_fifo[adir]; @@ -902,9 +1088,9 @@ static int as_fifo_expired(struct as_data *ad, int adir) if (list_empty(&ad->fifo_list[adir])) return 0; - rq = rq_entry_fifo(ad->fifo_list[adir].next); + arq = list_entry_fifo(ad->fifo_list[adir].next); - return time_after(jiffies, rq_fifo_time(rq)); + return time_after(jiffies, arq->expires); } /* @@ -927,25 +1113,25 @@ static inline int as_batch_expired(struct as_data *ad) /* * move an entry to dispatch queue */ -static void as_move_to_dispatch(struct as_data *ad, struct request *rq) +static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq) { - const int data_dir = rq_is_sync(rq); + struct request *rq = arq->request; + const int data_dir = arq->is_sync; - BUG_ON(RB_EMPTY_NODE(&rq->rb_node)); + BUG_ON(!RB_EMPTY_NODE(&arq->rb_node)); as_antic_stop(ad); ad->antic_status = ANTIC_OFF; /* * This has to be set in order to be correctly updated by - * as_find_next_rq + * as_find_next_arq */ ad->last_sector[data_dir] = rq->sector + rq->nr_sectors; if (data_dir == REQ_SYNC) { - struct io_context *ioc = RQ_IOC(rq); /* In case we have to anticipate after this */ - copy_io_context(&ad->io_context, &ioc); + copy_io_context(&ad->io_context, &arq->io_context); } else { if (ad->io_context) { put_io_context(ad->io_context); @@ -957,19 +1143,19 @@ static void as_move_to_dispatch(struct as_data *ad, struct request *rq) } ad->ioc_finished = 0; - ad->next_rq[data_dir] = as_find_next_rq(ad, rq); + ad->next_arq[data_dir] = as_find_next_arq(ad, arq); /* * take it off the sort and fifo list, add to dispatch queue */ as_remove_queued_request(ad->q, rq); - WARN_ON(RQ_STATE(rq) != AS_RQ_QUEUED); + WARN_ON(arq->state != AS_RQ_QUEUED); elv_dispatch_sort(ad->q, rq); - RQ_SET_STATE(rq, AS_RQ_DISPATCHED); - if (RQ_IOC(rq) && RQ_IOC(rq)->aic) - atomic_inc(&RQ_IOC(rq)->aic->nr_dispatched); + arq->state = AS_RQ_DISPATCHED; + if (arq->io_context && arq->io_context->aic) + atomic_inc(&arq->io_context->aic->nr_dispatched); ad->nr_dispatched++; } @@ -981,9 +1167,9 @@ static void as_move_to_dispatch(struct as_data *ad, struct request *rq) static int as_dispatch_request(request_queue_t *q, int force) { struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq; const int reads = !list_empty(&ad->fifo_list[REQ_SYNC]); const int writes = !list_empty(&ad->fifo_list[REQ_ASYNC]); - struct request *rq; if (unlikely(force)) { /* @@ -999,14 +1185,14 @@ static int as_dispatch_request(request_queue_t *q, int force) ad->changed_batch = 0; ad->new_batch = 0; - while (ad->next_rq[REQ_SYNC]) { - as_move_to_dispatch(ad, ad->next_rq[REQ_SYNC]); + while (ad->next_arq[REQ_SYNC]) { + as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]); dispatched++; } ad->last_check_fifo[REQ_SYNC] = jiffies; - while (ad->next_rq[REQ_ASYNC]) { - as_move_to_dispatch(ad, ad->next_rq[REQ_ASYNC]); + while (ad->next_arq[REQ_ASYNC]) { + as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]); dispatched++; } ad->last_check_fifo[REQ_ASYNC] = jiffies; @@ -1030,19 +1216,19 @@ static int as_dispatch_request(request_queue_t *q, int force) /* * batch is still running or no reads or no writes */ - rq = ad->next_rq[ad->batch_data_dir]; + arq = ad->next_arq[ad->batch_data_dir]; if (ad->batch_data_dir == REQ_SYNC && ad->antic_expire) { if (as_fifo_expired(ad, REQ_SYNC)) goto fifo_expired; - if (as_can_anticipate(ad, rq)) { + if (as_can_anticipate(ad, arq)) { as_antic_waitreq(ad); return 0; } } - if (rq) { + if (arq) { /* we have a "next request" */ if (reads && !writes) ad->current_batch_expires = @@ -1070,7 +1256,7 @@ static int as_dispatch_request(request_queue_t *q, int force) ad->changed_batch = 1; } ad->batch_data_dir = REQ_SYNC; - rq = rq_entry_fifo(ad->fifo_list[REQ_SYNC].next); + arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next); ad->last_check_fifo[ad->batch_data_dir] = jiffies; goto dispatch_request; } @@ -1096,7 +1282,7 @@ static int as_dispatch_request(request_queue_t *q, int force) ad->batch_data_dir = REQ_ASYNC; ad->current_write_count = ad->write_batch_count; ad->write_batch_idled = 0; - rq = ad->next_rq[ad->batch_data_dir]; + arq = ad->next_arq[ad->batch_data_dir]; goto dispatch_request; } @@ -1110,7 +1296,8 @@ static int as_dispatch_request(request_queue_t *q, int force) if (as_fifo_expired(ad, ad->batch_data_dir)) { fifo_expired: - rq = rq_entry_fifo(ad->fifo_list[ad->batch_data_dir].next); + arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next); + BUG_ON(arq == NULL); } if (ad->changed_batch) { @@ -1129,58 +1316,70 @@ static int as_dispatch_request(request_queue_t *q, int force) } /* - * rq is the selected appropriate request. + * arq is the selected appropriate request. */ - as_move_to_dispatch(ad, rq); + as_move_to_dispatch(ad, arq); return 1; } /* - * add rq to rbtree and fifo + * add arq to rbtree and fifo */ static void as_add_request(request_queue_t *q, struct request *rq) { struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq = RQ_DATA(rq); int data_dir; - RQ_SET_STATE(rq, AS_RQ_NEW); + arq->state = AS_RQ_NEW; - data_dir = rq_is_sync(rq); + if (rq_data_dir(arq->request) == READ + || (arq->request->flags & REQ_RW_SYNC)) + arq->is_sync = 1; + else + arq->is_sync = 0; + data_dir = arq->is_sync; - rq->elevator_private = as_get_io_context(q->node); + arq->io_context = as_get_io_context(); - if (RQ_IOC(rq)) { - as_update_iohist(ad, RQ_IOC(rq)->aic, rq); - atomic_inc(&RQ_IOC(rq)->aic->nr_queued); + if (arq->io_context) { + as_update_iohist(ad, arq->io_context->aic, arq->request); + atomic_inc(&arq->io_context->aic->nr_queued); } - as_add_rq_rb(ad, rq); + as_add_arq_rb(ad, arq); + if (rq_mergeable(arq->request)) + as_add_arq_hash(ad, arq); /* * set expire time (only used for reads) and add to fifo list */ - rq_set_fifo_time(rq, jiffies + ad->fifo_expire[data_dir]); - list_add_tail(&rq->queuelist, &ad->fifo_list[data_dir]); + arq->expires = jiffies + ad->fifo_expire[data_dir]; + list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]); - as_update_rq(ad, rq); /* keep state machine up to date */ - RQ_SET_STATE(rq, AS_RQ_QUEUED); + as_update_arq(ad, arq); /* keep state machine up to date */ + arq->state = AS_RQ_QUEUED; } static void as_activate_request(request_queue_t *q, struct request *rq) { - WARN_ON(RQ_STATE(rq) != AS_RQ_DISPATCHED); - RQ_SET_STATE(rq, AS_RQ_REMOVED); - if (RQ_IOC(rq) && RQ_IOC(rq)->aic) - atomic_dec(&RQ_IOC(rq)->aic->nr_dispatched); + struct as_rq *arq = RQ_DATA(rq); + + WARN_ON(arq->state != AS_RQ_DISPATCHED); + arq->state = AS_RQ_REMOVED; + if (arq->io_context && arq->io_context->aic) + atomic_dec(&arq->io_context->aic->nr_dispatched); } static void as_deactivate_request(request_queue_t *q, struct request *rq) { - WARN_ON(RQ_STATE(rq) != AS_RQ_REMOVED); - RQ_SET_STATE(rq, AS_RQ_DISPATCHED); - if (RQ_IOC(rq) && RQ_IOC(rq)->aic) - atomic_inc(&RQ_IOC(rq)->aic->nr_dispatched); + struct as_rq *arq = RQ_DATA(rq); + + WARN_ON(arq->state != AS_RQ_REMOVED); + arq->state = AS_RQ_DISPATCHED; + if (arq->io_context && arq->io_context->aic) + atomic_inc(&arq->io_context->aic->nr_dispatched); } /* @@ -1197,35 +1396,93 @@ static int as_queue_empty(request_queue_t *q) && list_empty(&ad->fifo_list[REQ_SYNC]); } +static struct request *as_former_request(request_queue_t *q, + struct request *rq) +{ + struct as_rq *arq = RQ_DATA(rq); + struct rb_node *rbprev = rb_prev(&arq->rb_node); + struct request *ret = NULL; + + if (rbprev) + ret = rb_entry_arq(rbprev)->request; + + return ret; +} + +static struct request *as_latter_request(request_queue_t *q, + struct request *rq) +{ + struct as_rq *arq = RQ_DATA(rq); + struct rb_node *rbnext = rb_next(&arq->rb_node); + struct request *ret = NULL; + + if (rbnext) + ret = rb_entry_arq(rbnext)->request; + + return ret; +} + static int as_merge(request_queue_t *q, struct request **req, struct bio *bio) { struct as_data *ad = q->elevator->elevator_data; sector_t rb_key = bio->bi_sector + bio_sectors(bio); struct request *__rq; + int ret; + + /* + * see if the merge hash can satisfy a back merge + */ + __rq = as_find_arq_hash(ad, bio->bi_sector); + if (__rq) { + BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector); + + if (elv_rq_merge_ok(__rq, bio)) { + ret = ELEVATOR_BACK_MERGE; + goto out; + } + } /* * check for front merge */ - __rq = elv_rb_find(&ad->sort_list[bio_data_dir(bio)], rb_key); - if (__rq && elv_rq_merge_ok(__rq, bio)) { - *req = __rq; - return ELEVATOR_FRONT_MERGE; + __rq = as_find_arq_rb(ad, rb_key, bio_data_dir(bio)); + if (__rq) { + BUG_ON(rb_key != rq_rb_key(__rq)); + + if (elv_rq_merge_ok(__rq, bio)) { + ret = ELEVATOR_FRONT_MERGE; + goto out; + } } return ELEVATOR_NO_MERGE; +out: + if (ret) { + if (rq_mergeable(__rq)) + as_hot_arq_hash(ad, RQ_DATA(__rq)); + } + *req = __rq; + return ret; } -static void as_merged_request(request_queue_t *q, struct request *req, int type) +static void as_merged_request(request_queue_t *q, struct request *req) { struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq = RQ_DATA(req); + + /* + * hash always needs to be repositioned, key is end sector + */ + as_del_arq_hash(arq); + as_add_arq_hash(ad, arq); /* * if the merge was a front merge, we need to reposition request */ - if (type == ELEVATOR_FRONT_MERGE) { - as_del_rq_rb(ad, req); - as_add_rq_rb(ad, req); + if (rq_rb_key(req) != arq->rb_key) { + as_del_arq_rb(ad, arq); + as_add_arq_rb(ad, arq); /* * Note! At this stage of this and the next function, our next * request may not be optimal - eg the request may have "grown" @@ -1237,22 +1494,38 @@ static void as_merged_request(request_queue_t *q, struct request *req, int type) static void as_merged_requests(request_queue_t *q, struct request *req, struct request *next) { + struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq = RQ_DATA(req); + struct as_rq *anext = RQ_DATA(next); + + BUG_ON(!arq); + BUG_ON(!anext); + /* - * if next expires before rq, assign its expire time to arq - * and move into next position (next will be deleted) in fifo + * reposition arq (this is the merged request) in hash, and in rbtree + * in case of a front merge */ - if (!list_empty(&req->queuelist) && !list_empty(&next->queuelist)) { - if (time_before(rq_fifo_time(next), rq_fifo_time(req))) { - struct io_context *rioc = RQ_IOC(req); - struct io_context *nioc = RQ_IOC(next); + as_del_arq_hash(arq); + as_add_arq_hash(ad, arq); + + if (rq_rb_key(req) != arq->rb_key) { + as_del_arq_rb(ad, arq); + as_add_arq_rb(ad, arq); + } - list_move(&req->queuelist, &next->queuelist); - rq_set_fifo_time(req, rq_fifo_time(next)); + /* + * if anext expires before arq, assign its expire time to arq + * and move into anext position (anext will be deleted) in fifo + */ + if (!list_empty(&arq->fifo) && !list_empty(&anext->fifo)) { + if (time_before(anext->expires, arq->expires)) { + list_move(&arq->fifo, &anext->fifo); + arq->expires = anext->expires; /* * Don't copy here but swap, because when anext is * removed below, it must contain the unused context */ - swap_io_context(&rioc, &nioc); + swap_io_context(&arq->io_context, &anext->io_context); } } @@ -1260,9 +1533,9 @@ static void as_merged_requests(request_queue_t *q, struct request *req, * kill knowledge of next, this one is a goner */ as_remove_queued_request(q, next); - as_put_io_context(next); + as_put_io_context(anext); - RQ_SET_STATE(next, AS_RQ_MERGED); + anext->state = AS_RQ_MERGED; } /* @@ -1280,18 +1553,61 @@ static void as_work_handler(void *data) unsigned long flags; spin_lock_irqsave(q->queue_lock, flags); - blk_start_queueing(q); + if (!as_queue_empty(q)) + q->request_fn(q); spin_unlock_irqrestore(q->queue_lock, flags); } -static int as_may_queue(request_queue_t *q, int rw) +static void as_put_request(request_queue_t *q, struct request *rq) +{ + struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq = RQ_DATA(rq); + + if (!arq) { + WARN_ON(1); + return; + } + + if (unlikely(arq->state != AS_RQ_POSTSCHED && + arq->state != AS_RQ_PRESCHED && + arq->state != AS_RQ_MERGED)) { + printk("arq->state %d\n", arq->state); + WARN_ON(1); + } + + mempool_free(arq, ad->arq_pool); + rq->elevator_private = NULL; +} + +static int as_set_request(request_queue_t *q, struct request *rq, + struct bio *bio, gfp_t gfp_mask) +{ + struct as_data *ad = q->elevator->elevator_data; + struct as_rq *arq = mempool_alloc(ad->arq_pool, gfp_mask); + + if (arq) { + memset(arq, 0, sizeof(*arq)); + RB_CLEAR_NODE(&arq->rb_node); + arq->request = rq; + arq->state = AS_RQ_PRESCHED; + arq->io_context = NULL; + INIT_HLIST_NODE(&arq->hash); + INIT_LIST_HEAD(&arq->fifo); + rq->elevator_private = arq; + return 0; + } + + return 1; +} + +static int as_may_queue(request_queue_t *q, int rw, struct bio *bio) { int ret = ELV_MQUEUE_MAY; struct as_data *ad = q->elevator->elevator_data; struct io_context *ioc; if (ad->antic_status == ANTIC_WAIT_REQ || ad->antic_status == ANTIC_WAIT_NEXT) { - ioc = as_get_io_context(q->node); + ioc = as_get_io_context(); if (ad->io_context == ioc) ret = ELV_MQUEUE_MUST; put_io_context(ioc); @@ -1310,16 +1626,23 @@ static void as_exit_queue(elevator_t *e) BUG_ON(!list_empty(&ad->fifo_list[REQ_SYNC])); BUG_ON(!list_empty(&ad->fifo_list[REQ_ASYNC])); + mempool_destroy(ad->arq_pool); put_io_context(ad->io_context); + kfree(ad->hash); kfree(ad); } /* - * initialize elevator private data (as_data). + * initialize elevator private data (as_data), and alloc a arq for + * each request on the free lists */ static void *as_init_queue(request_queue_t *q, elevator_t *e) { struct as_data *ad; + int i; + + if (!arq_pool) + return NULL; ad = kmalloc_node(sizeof(*ad), GFP_KERNEL, q->node); if (!ad) @@ -1328,12 +1651,30 @@ static void *as_init_queue(request_queue_t *q, elevator_t *e) ad->q = q; /* Identify what queue the data belongs to */ + ad->hash = kmalloc_node(sizeof(struct hlist_head)*AS_HASH_ENTRIES, + GFP_KERNEL, q->node); + if (!ad->hash) { + kfree(ad); + return NULL; + } + + ad->arq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, + mempool_free_slab, arq_pool, q->node); + if (!ad->arq_pool) { + kfree(ad->hash); + kfree(ad); + return NULL; + } + /* anticipatory scheduling helpers */ ad->antic_timer.function = as_antic_timeout; ad->antic_timer.data = (unsigned long)q; init_timer(&ad->antic_timer); INIT_WORK(&ad->antic_work, as_work_handler, q); + for (i = 0; i < AS_HASH_ENTRIES; i++) + INIT_HLIST_HEAD(&ad->hash[i]); + INIT_LIST_HEAD(&ad->fifo_list[REQ_SYNC]); INIT_LIST_HEAD(&ad->fifo_list[REQ_ASYNC]); ad->sort_list[REQ_SYNC] = RB_ROOT; @@ -1446,8 +1787,10 @@ static struct elevator_type iosched_as = { .elevator_deactivate_req_fn = as_deactivate_request, .elevator_queue_empty_fn = as_queue_empty, .elevator_completed_req_fn = as_completed_request, - .elevator_former_req_fn = elv_rb_former_request, - .elevator_latter_req_fn = elv_rb_latter_request, + .elevator_former_req_fn = as_former_request, + .elevator_latter_req_fn = as_latter_request, + .elevator_set_req_fn = as_set_request, + .elevator_put_req_fn = as_put_request, .elevator_may_queue_fn = as_may_queue, .elevator_init_fn = as_init_queue, .elevator_exit_fn = as_exit_queue, @@ -1463,6 +1806,11 @@ static int __init as_init(void) { int ret; + arq_pool = kmem_cache_create("as_arq", sizeof(struct as_rq), + 0, 0, NULL, NULL); + if (!arq_pool) + return -ENOMEM; + ret = elv_register(&iosched_as); if (!ret) { /* @@ -1474,19 +1822,21 @@ static int __init as_init(void) return 0; } + kmem_cache_destroy(arq_pool); return ret; } static void __exit as_exit(void) { - DECLARE_COMPLETION_ONSTACK(all_gone); + DECLARE_COMPLETION(all_gone); elv_unregister(&iosched_as); ioc_gone = &all_gone; /* ioc_gone's update must be visible before reading ioc_count */ smp_wmb(); - if (elv_ioc_count_read(ioc_count)) + if (atomic_read(&ioc_count)) wait_for_completion(ioc_gone); synchronize_rcu(); + kmem_cache_destroy(arq_pool); } module_init(as_init); diff --git a/trunk/block/blktrace.c b/trunk/block/blktrace.c index 135593c8e45b..265f7a830619 100644 --- a/trunk/block/blktrace.c +++ b/trunk/block/blktrace.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Jens Axboe + * Copyright (C) 2006 Jens Axboe * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -69,7 +69,7 @@ static u32 ddir_act[2] __read_mostly = { BLK_TC_ACT(BLK_TC_READ), BLK_TC_ACT(BLK /* * Bio action bits of interest */ -static u32 bio_act[9] __read_mostly = { 0, BLK_TC_ACT(BLK_TC_BARRIER), BLK_TC_ACT(BLK_TC_SYNC), 0, BLK_TC_ACT(BLK_TC_AHEAD), 0, 0, 0, BLK_TC_ACT(BLK_TC_META) }; +static u32 bio_act[5] __read_mostly = { 0, BLK_TC_ACT(BLK_TC_BARRIER), BLK_TC_ACT(BLK_TC_SYNC), 0, BLK_TC_ACT(BLK_TC_AHEAD) }; /* * More could be added as needed, taking care to increment the decrementer @@ -81,8 +81,6 @@ static u32 bio_act[9] __read_mostly = { 0, BLK_TC_ACT(BLK_TC_BARRIER), BLK_TC_AC (((rw) & (1 << BIO_RW_SYNC)) >> (BIO_RW_SYNC - 1)) #define trace_ahead_bit(rw) \ (((rw) & (1 << BIO_RW_AHEAD)) << (2 - BIO_RW_AHEAD)) -#define trace_meta_bit(rw) \ - (((rw) & (1 << BIO_RW_META)) >> (BIO_RW_META - 3)) /* * The worker for the various blk_add_trace*() types. Fills out a @@ -105,7 +103,6 @@ void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, what |= bio_act[trace_barrier_bit(rw)]; what |= bio_act[trace_sync_bit(rw)]; what |= bio_act[trace_ahead_bit(rw)]; - what |= bio_act[trace_meta_bit(rw)]; pid = tsk->pid; if (unlikely(act_log_check(bt, what, sector, pid))) @@ -220,7 +217,7 @@ static int blk_trace_remove(request_queue_t *q) static int blk_dropped_open(struct inode *inode, struct file *filp) { - filp->private_data = inode->i_private; + filp->private_data = inode->u.generic_ip; return 0; } @@ -453,10 +450,8 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) **/ void blk_trace_shutdown(request_queue_t *q) { - if (q->blk_trace) { - blk_trace_startstop(q, 0); - blk_trace_remove(q); - } + blk_trace_startstop(q, 0); + blk_trace_remove(q); } /* @@ -476,9 +471,6 @@ static void blk_check_time(unsigned long long *t) *t -= (a + b) / 2; } -/* - * calibrate our inter-CPU timings - */ static void blk_trace_check_cpu_time(void *data) { unsigned long long *t; @@ -496,6 +488,20 @@ static void blk_trace_check_cpu_time(void *data) put_cpu(); } +/* + * Call blk_trace_check_cpu_time() on each CPU to calibrate our inter-CPU + * timings + */ +static void blk_trace_calibrate_offsets(void) +{ + unsigned long flags; + + smp_call_function(blk_trace_check_cpu_time, NULL, 1, 1); + local_irq_save(flags); + blk_trace_check_cpu_time(NULL); + local_irq_restore(flags); +} + static void blk_trace_set_ht_offsets(void) { #if defined(CONFIG_SCHED_SMT) @@ -524,7 +530,7 @@ static void blk_trace_set_ht_offsets(void) static __init int blk_trace_init(void) { mutex_init(&blk_tree_mutex); - on_each_cpu(blk_trace_check_cpu_time, NULL, 1, 1); + blk_trace_calibrate_offsets(); blk_trace_set_ht_offsets(); return 0; diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index d3d76136f53a..3a3aee08ec5f 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -4,7 +4,7 @@ * Based on ideas from a previously unfinished io * scheduler (round robin per-process disk scheduling) and Andrea Arcangeli. * - * Copyright (C) 2003 Jens Axboe + * Copyright (C) 2003 Jens Axboe */ #include #include @@ -17,6 +17,7 @@ * tunables */ static const int cfq_quantum = 4; /* max queue in one round of service */ +static const int cfq_queued = 8; /* minimum rq allocate limit per-queue*/ static const int cfq_fifo_expire[2] = { HZ / 4, HZ / 8 }; static const int cfq_back_max = 16 * 1024; /* maximum backwards seek, in KiB */ static const int cfq_back_penalty = 2; /* penalty of a backwards seek */ @@ -31,6 +32,8 @@ static int cfq_slice_idle = HZ / 125; #define CFQ_KEY_ASYNC (0) +static DEFINE_SPINLOCK(cfq_exit_lock); + /* * for the hash of cfqq inside the cfqd */ @@ -38,19 +41,37 @@ static int cfq_slice_idle = HZ / 125; #define CFQ_QHASH_ENTRIES (1 << CFQ_QHASH_SHIFT) #define list_entry_qhash(entry) hlist_entry((entry), struct cfq_queue, cfq_hash) +/* + * for the hash of crq inside the cfqq + */ +#define CFQ_MHASH_SHIFT 6 +#define CFQ_MHASH_BLOCK(sec) ((sec) >> 3) +#define CFQ_MHASH_ENTRIES (1 << CFQ_MHASH_SHIFT) +#define CFQ_MHASH_FN(sec) hash_long(CFQ_MHASH_BLOCK(sec), CFQ_MHASH_SHIFT) +#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) +#define list_entry_hash(ptr) hlist_entry((ptr), struct cfq_rq, hash) + #define list_entry_cfqq(ptr) list_entry((ptr), struct cfq_queue, cfq_list) +#define list_entry_fifo(ptr) list_entry((ptr), struct request, queuelist) -#define RQ_CIC(rq) ((struct cfq_io_context*)(rq)->elevator_private) -#define RQ_CFQQ(rq) ((rq)->elevator_private2) +#define RQ_DATA(rq) (rq)->elevator_private +/* + * rb-tree defines + */ +#define rb_entry_crq(node) rb_entry((node), struct cfq_rq, rb_node) +#define rq_rb_key(rq) (rq)->sector + +static kmem_cache_t *crq_pool; static kmem_cache_t *cfq_pool; static kmem_cache_t *cfq_ioc_pool; -static DEFINE_PER_CPU(unsigned long, ioc_count); +static atomic_t ioc_count = ATOMIC_INIT(0); static struct completion *ioc_gone; #define CFQ_PRIO_LISTS IOPRIO_BE_NR #define cfq_class_idle(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_IDLE) +#define cfq_class_be(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_BE) #define cfq_class_rt(cfqq) ((cfqq)->ioprio_class == IOPRIO_CLASS_RT) #define ASYNC (0) @@ -81,14 +102,29 @@ struct cfq_data { struct list_head idle_rr; unsigned int busy_queues; + /* + * non-ordered list of empty cfqq's + */ + struct list_head empty_list; + /* * cfqq lookup hash */ struct hlist_head *cfq_hash; + /* + * global crq hash for all queues + */ + struct hlist_head *crq_hash; + + mempool_t *crq_pool; + int rq_in_driver; int hw_tag; + /* + * schedule slice state info + */ /* * idle window management */ @@ -105,10 +141,13 @@ struct cfq_data { sector_t last_sector; unsigned long last_end_request; + unsigned int rq_starved; + /* * tunables, see top of file */ unsigned int cfq_quantum; + unsigned int cfq_queued; unsigned int cfq_fifo_expire[2]; unsigned int cfq_back_penalty; unsigned int cfq_back_max; @@ -131,24 +170,23 @@ struct cfq_queue { struct hlist_node cfq_hash; /* hash key */ unsigned int key; - /* member of the rr/busy/cur/idle cfqd list */ + /* on either rr or empty list of cfqd */ struct list_head cfq_list; /* sorted list of pending requests */ struct rb_root sort_list; /* if fifo isn't expired, next request to serve */ - struct request *next_rq; + struct cfq_rq *next_crq; /* requests queued in sort_list */ int queued[2]; /* currently allocated requests */ int allocated[2]; - /* pending metadata requests */ - int meta_pending; /* fifo list of requests in sort_list */ struct list_head fifo; unsigned long slice_start; unsigned long slice_end; unsigned long slice_left; + unsigned long service_last; /* number of requests that are on the dispatch list */ int on_dispatch[2]; @@ -161,6 +199,18 @@ struct cfq_queue { unsigned int flags; }; +struct cfq_rq { + struct rb_node rb_node; + sector_t rb_key; + struct request *request; + struct hlist_node hash; + + struct cfq_queue *cfq_queue; + struct cfq_io_context *io_context; + + unsigned int crq_flags; +}; + enum cfqq_state_flags { CFQ_CFQQ_FLAG_on_rr = 0, CFQ_CFQQ_FLAG_wait_request, @@ -170,7 +220,6 @@ enum cfqq_state_flags { CFQ_CFQQ_FLAG_fifo_expire, CFQ_CFQQ_FLAG_idle_window, CFQ_CFQQ_FLAG_prio_changed, - CFQ_CFQQ_FLAG_queue_new, }; #define CFQ_CFQQ_FNS(name) \ @@ -195,13 +244,69 @@ CFQ_CFQQ_FNS(must_dispatch); CFQ_CFQQ_FNS(fifo_expire); CFQ_CFQQ_FNS(idle_window); CFQ_CFQQ_FNS(prio_changed); -CFQ_CFQQ_FNS(queue_new); #undef CFQ_CFQQ_FNS +enum cfq_rq_state_flags { + CFQ_CRQ_FLAG_is_sync = 0, +}; + +#define CFQ_CRQ_FNS(name) \ +static inline void cfq_mark_crq_##name(struct cfq_rq *crq) \ +{ \ + crq->crq_flags |= (1 << CFQ_CRQ_FLAG_##name); \ +} \ +static inline void cfq_clear_crq_##name(struct cfq_rq *crq) \ +{ \ + crq->crq_flags &= ~(1 << CFQ_CRQ_FLAG_##name); \ +} \ +static inline int cfq_crq_##name(const struct cfq_rq *crq) \ +{ \ + return (crq->crq_flags & (1 << CFQ_CRQ_FLAG_##name)) != 0; \ +} + +CFQ_CRQ_FNS(is_sync); +#undef CFQ_CRQ_FNS + static struct cfq_queue *cfq_find_cfq_hash(struct cfq_data *, unsigned int, unsigned short); -static void cfq_dispatch_insert(request_queue_t *, struct request *); +static void cfq_dispatch_insert(request_queue_t *, struct cfq_rq *); static struct cfq_queue *cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, gfp_t gfp_mask); +/* + * lots of deadline iosched dupes, can be abstracted later... + */ +static inline void cfq_del_crq_hash(struct cfq_rq *crq) +{ + hlist_del_init(&crq->hash); +} + +static inline void cfq_add_crq_hash(struct cfq_data *cfqd, struct cfq_rq *crq) +{ + const int hash_idx = CFQ_MHASH_FN(rq_hash_key(crq->request)); + + hlist_add_head(&crq->hash, &cfqd->crq_hash[hash_idx]); +} + +static struct request *cfq_find_rq_hash(struct cfq_data *cfqd, sector_t offset) +{ + struct hlist_head *hash_list = &cfqd->crq_hash[CFQ_MHASH_FN(offset)]; + struct hlist_node *entry, *next; + + hlist_for_each_safe(entry, next, hash_list) { + struct cfq_rq *crq = list_entry_hash(entry); + struct request *__rq = crq->request; + + if (!rq_mergeable(__rq)) { + cfq_del_crq_hash(crq); + continue; + } + + if (rq_hash_key(__rq) == offset) + return __rq; + } + + return NULL; +} + /* * scheduler run of queue, if there are requests pending and no one in the * driver that will restart queueing @@ -228,12 +333,12 @@ static inline pid_t cfq_queue_pid(struct task_struct *task, int rw) } /* - * Lifted from AS - choose which of rq1 and rq2 that is best served now. + * Lifted from AS - choose which of crq1 and crq2 that is best served now. * We choose the request that is closest to the head right now. Distance * behind the head is penalized and only allowed to a certain extent. */ -static struct request * -cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2) +static struct cfq_rq * +cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2) { sector_t last, s1, s2, d1 = 0, d2 = 0; unsigned long back_max; @@ -241,22 +346,18 @@ cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2) #define CFQ_RQ2_WRAP 0x02 /* request 2 wraps */ unsigned wrap = 0; /* bit mask: requests behind the disk head? */ - if (rq1 == NULL || rq1 == rq2) - return rq2; - if (rq2 == NULL) - return rq1; + if (crq1 == NULL || crq1 == crq2) + return crq2; + if (crq2 == NULL) + return crq1; - if (rq_is_sync(rq1) && !rq_is_sync(rq2)) - return rq1; - else if (rq_is_sync(rq2) && !rq_is_sync(rq1)) - return rq2; - if (rq_is_meta(rq1) && !rq_is_meta(rq2)) - return rq1; - else if (rq_is_meta(rq2) && !rq_is_meta(rq1)) - return rq2; + if (cfq_crq_is_sync(crq1) && !cfq_crq_is_sync(crq2)) + return crq1; + else if (cfq_crq_is_sync(crq2) && !cfq_crq_is_sync(crq1)) + return crq2; - s1 = rq1->sector; - s2 = rq2->sector; + s1 = crq1->request->sector; + s2 = crq2->request->sector; last = cfqd->last_sector; @@ -291,23 +392,23 @@ cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2) * check two variables for all permutations: --> faster! */ switch (wrap) { - case 0: /* common case for CFQ: rq1 and rq2 not wrapped */ + case 0: /* common case for CFQ: crq1 and crq2 not wrapped */ if (d1 < d2) - return rq1; + return crq1; else if (d2 < d1) - return rq2; + return crq2; else { if (s1 >= s2) - return rq1; + return crq1; else - return rq2; + return crq2; } case CFQ_RQ2_WRAP: - return rq1; + return crq1; case CFQ_RQ1_WRAP: - return rq2; - case (CFQ_RQ1_WRAP|CFQ_RQ2_WRAP): /* both rqs wrapped */ + return crq2; + case (CFQ_RQ1_WRAP|CFQ_RQ2_WRAP): /* both crqs wrapped */ default: /* * Since both rqs are wrapped, @@ -316,43 +417,50 @@ cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2) * since back seek takes more time than forward. */ if (s1 <= s2) - return rq1; + return crq1; else - return rq2; + return crq2; } } /* * would be nice to take fifo expire time into account as well */ -static struct request * -cfq_find_next_rq(struct cfq_data *cfqd, struct cfq_queue *cfqq, - struct request *last) +static struct cfq_rq * +cfq_find_next_crq(struct cfq_data *cfqd, struct cfq_queue *cfqq, + struct cfq_rq *last) { - struct rb_node *rbnext = rb_next(&last->rb_node); - struct rb_node *rbprev = rb_prev(&last->rb_node); - struct request *next = NULL, *prev = NULL; + struct cfq_rq *crq_next = NULL, *crq_prev = NULL; + struct rb_node *rbnext, *rbprev; - BUG_ON(RB_EMPTY_NODE(&last->rb_node)); + if (!(rbnext = rb_next(&last->rb_node))) { + rbnext = rb_first(&cfqq->sort_list); + if (rbnext == &last->rb_node) + rbnext = NULL; + } - if (rbprev) - prev = rb_entry_rq(rbprev); + rbprev = rb_prev(&last->rb_node); + if (rbprev) + crq_prev = rb_entry_crq(rbprev); if (rbnext) - next = rb_entry_rq(rbnext); - else { - rbnext = rb_first(&cfqq->sort_list); - if (rbnext && rbnext != &last->rb_node) - next = rb_entry_rq(rbnext); - } + crq_next = rb_entry_crq(rbnext); - return cfq_choose_req(cfqd, next, prev); + return cfq_choose_req(cfqd, crq_next, crq_prev); +} + +static void cfq_update_next_crq(struct cfq_rq *crq) +{ + struct cfq_queue *cfqq = crq->cfq_queue; + + if (cfqq->next_crq == crq) + cfqq->next_crq = cfq_find_next_crq(cfqq->cfqd, cfqq, crq); } static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted) { struct cfq_data *cfqd = cfqq->cfqd; - struct list_head *list; + struct list_head *list, *entry; BUG_ON(!cfq_cfqq_on_rr(cfqq)); @@ -377,26 +485,31 @@ static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted) } /* - * If this queue was preempted or is new (never been serviced), let - * it be added first for fairness but beind other new queues. - * Otherwise, just add to the back of the list. + * if queue was preempted, just add to front to be fair. busy_rr + * isn't sorted, but insert at the back for fairness. */ - if (preempted || cfq_cfqq_queue_new(cfqq)) { - struct list_head *n = list; - struct cfq_queue *__cfqq; + if (preempted || list == &cfqd->busy_rr) { + if (preempted) + list = list->prev; - while (n->next != list) { - __cfqq = list_entry_cfqq(n->next); - if (!cfq_cfqq_queue_new(__cfqq)) - break; + list_add_tail(&cfqq->cfq_list, list); + return; + } - n = n->next; - } + /* + * sort by when queue was last serviced + */ + entry = list; + while ((entry = entry->prev) != list) { + struct cfq_queue *__cfqq = list_entry_cfqq(entry); - list = n; + if (!__cfqq->service_last) + break; + if (time_before(__cfqq->service_last, cfqq->service_last)) + break; } - list_add_tail(&cfqq->cfq_list, list); + list_add(&cfqq->cfq_list, entry); } /* @@ -418,7 +531,7 @@ cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) { BUG_ON(!cfq_cfqq_on_rr(cfqq)); cfq_clear_cfqq_on_rr(cfqq); - list_del_init(&cfqq->cfq_list); + list_move(&cfqq->cfq_list, &cfqd->empty_list); BUG_ON(!cfqd->busy_queues); cfqd->busy_queues--; @@ -427,43 +540,81 @@ cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) /* * rb tree support functions */ -static inline void cfq_del_rq_rb(struct request *rq) +static inline void cfq_del_crq_rb(struct cfq_rq *crq) { - struct cfq_queue *cfqq = RQ_CFQQ(rq); + struct cfq_queue *cfqq = crq->cfq_queue; struct cfq_data *cfqd = cfqq->cfqd; - const int sync = rq_is_sync(rq); + const int sync = cfq_crq_is_sync(crq); BUG_ON(!cfqq->queued[sync]); cfqq->queued[sync]--; - elv_rb_del(&cfqq->sort_list, rq); + cfq_update_next_crq(crq); + + rb_erase(&crq->rb_node, &cfqq->sort_list); if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list)) cfq_del_cfqq_rr(cfqd, cfqq); } -static void cfq_add_rq_rb(struct request *rq) +static struct cfq_rq * +__cfq_add_crq_rb(struct cfq_rq *crq) { - struct cfq_queue *cfqq = RQ_CFQQ(rq); + struct rb_node **p = &crq->cfq_queue->sort_list.rb_node; + struct rb_node *parent = NULL; + struct cfq_rq *__crq; + + while (*p) { + parent = *p; + __crq = rb_entry_crq(parent); + + if (crq->rb_key < __crq->rb_key) + p = &(*p)->rb_left; + else if (crq->rb_key > __crq->rb_key) + p = &(*p)->rb_right; + else + return __crq; + } + + rb_link_node(&crq->rb_node, parent, p); + return NULL; +} + +static void cfq_add_crq_rb(struct cfq_rq *crq) +{ + struct cfq_queue *cfqq = crq->cfq_queue; struct cfq_data *cfqd = cfqq->cfqd; - struct request *__alias; + struct request *rq = crq->request; + struct cfq_rq *__alias; - cfqq->queued[rq_is_sync(rq)]++; + crq->rb_key = rq_rb_key(rq); + cfqq->queued[cfq_crq_is_sync(crq)]++; /* * looks a little odd, but the first insert might return an alias. * if that happens, put the alias on the dispatch list */ - while ((__alias = elv_rb_add(&cfqq->sort_list, rq)) != NULL) + while ((__alias = __cfq_add_crq_rb(crq)) != NULL) cfq_dispatch_insert(cfqd->queue, __alias); + + rb_insert_color(&crq->rb_node, &cfqq->sort_list); + + if (!cfq_cfqq_on_rr(cfqq)) + cfq_add_cfqq_rr(cfqd, cfqq); + + /* + * check if this request is a better next-serve candidate + */ + cfqq->next_crq = cfq_choose_req(cfqd, cfqq->next_crq, crq); } static inline void -cfq_reposition_rq_rb(struct cfq_queue *cfqq, struct request *rq) +cfq_reposition_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq) { - elv_rb_del(&cfqq->sort_list, rq); - cfqq->queued[rq_is_sync(rq)]--; - cfq_add_rq_rb(rq); + rb_erase(&crq->rb_node, &cfqq->sort_list); + cfqq->queued[cfq_crq_is_sync(crq)]--; + + cfq_add_crq_rb(crq); } static struct request * @@ -472,14 +623,27 @@ cfq_find_rq_fmerge(struct cfq_data *cfqd, struct bio *bio) struct task_struct *tsk = current; pid_t key = cfq_queue_pid(tsk, bio_data_dir(bio)); struct cfq_queue *cfqq; + struct rb_node *n; + sector_t sector; cfqq = cfq_find_cfq_hash(cfqd, key, tsk->ioprio); - if (cfqq) { - sector_t sector = bio->bi_sector + bio_sectors(bio); + if (!cfqq) + goto out; + + sector = bio->bi_sector + bio_sectors(bio); + n = cfqq->sort_list.rb_node; + while (n) { + struct cfq_rq *crq = rb_entry_crq(n); - return elv_rb_find(&cfqq->sort_list, sector); + if (sector < crq->rb_key) + n = n->rb_left; + else if (sector > crq->rb_key) + n = n->rb_right; + else + return crq->request; } +out: return NULL; } @@ -509,18 +673,11 @@ static void cfq_deactivate_request(request_queue_t *q, struct request *rq) static void cfq_remove_request(struct request *rq) { - struct cfq_queue *cfqq = RQ_CFQQ(rq); - - if (cfqq->next_rq == rq) - cfqq->next_rq = cfq_find_next_rq(cfqq->cfqd, cfqq, rq); + struct cfq_rq *crq = RQ_DATA(rq); list_del_init(&rq->queuelist); - cfq_del_rq_rb(rq); - - if (rq_is_meta(rq)) { - WARN_ON(!cfqq->meta_pending); - cfqq->meta_pending--; - } + cfq_del_crq_rb(crq); + cfq_del_crq_hash(crq); } static int @@ -528,23 +685,39 @@ cfq_merge(request_queue_t *q, struct request **req, struct bio *bio) { struct cfq_data *cfqd = q->elevator->elevator_data; struct request *__rq; + int ret; + + __rq = cfq_find_rq_hash(cfqd, bio->bi_sector); + if (__rq && elv_rq_merge_ok(__rq, bio)) { + ret = ELEVATOR_BACK_MERGE; + goto out; + } __rq = cfq_find_rq_fmerge(cfqd, bio); if (__rq && elv_rq_merge_ok(__rq, bio)) { - *req = __rq; - return ELEVATOR_FRONT_MERGE; + ret = ELEVATOR_FRONT_MERGE; + goto out; } return ELEVATOR_NO_MERGE; +out: + *req = __rq; + return ret; } -static void cfq_merged_request(request_queue_t *q, struct request *req, - int type) +static void cfq_merged_request(request_queue_t *q, struct request *req) { - if (type == ELEVATOR_FRONT_MERGE) { - struct cfq_queue *cfqq = RQ_CFQQ(req); + struct cfq_data *cfqd = q->elevator->elevator_data; + struct cfq_rq *crq = RQ_DATA(req); + + cfq_del_crq_hash(crq); + cfq_add_crq_hash(cfqd, crq); + + if (rq_rb_key(req) != crq->rb_key) { + struct cfq_queue *cfqq = crq->cfq_queue; - cfq_reposition_rq_rb(cfqq, req); + cfq_update_next_crq(crq); + cfq_reposition_crq_rb(cfqq, crq); } } @@ -552,6 +725,8 @@ static void cfq_merged_requests(request_queue_t *q, struct request *rq, struct request *next) { + cfq_merged_request(q, rq); + /* * reposition in fifo if next is older than rq */ @@ -593,12 +768,13 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, if (cfq_cfqq_wait_request(cfqq)) del_timer(&cfqd->idle_slice_timer); - if (!preempted && !cfq_cfqq_dispatched(cfqq)) + if (!preempted && !cfq_cfqq_dispatched(cfqq)) { + cfqq->service_last = now; cfq_schedule_dispatch(cfqd); + } cfq_clear_cfqq_must_dispatch(cfqq); cfq_clear_cfqq_wait_request(cfqq); - cfq_clear_cfqq_queue_new(cfqq); /* * store what was left of this slice, if the queue idled out @@ -692,25 +868,26 @@ static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd) { struct cfq_queue *cfqq = NULL; - if (!list_empty(&cfqd->cur_rr) || cfq_get_next_prio_level(cfqd) != -1) { - /* - * if current list is non-empty, grab first entry. if it is - * empty, get next prio level and grab first entry then if any - * are spliced - */ + /* + * if current list is non-empty, grab first entry. if it is empty, + * get next prio level and grab first entry then if any are spliced + */ + if (!list_empty(&cfqd->cur_rr) || cfq_get_next_prio_level(cfqd) != -1) cfqq = list_entry_cfqq(cfqd->cur_rr.next); - } else if (!list_empty(&cfqd->busy_rr)) { - /* - * If no new queues are available, check if the busy list has - * some before falling back to idle io. - */ + + /* + * If no new queues are available, check if the busy list has some + * before falling back to idle io. + */ + if (!cfqq && !list_empty(&cfqd->busy_rr)) cfqq = list_entry_cfqq(cfqd->busy_rr.next); - } else if (!list_empty(&cfqd->idle_rr)) { - /* - * if we have idle queues and no rt or be queues had pending - * requests, either allow immediate service if the grace period - * has passed or arm the idle grace timer - */ + + /* + * if we have idle queues and no rt or be queues had pending + * requests, either allow immediate service if the grace period + * has passed or arm the idle grace timer + */ + if (!cfqq && !list_empty(&cfqd->idle_rr)) { unsigned long end = cfqd->last_end_request + CFQ_IDLE_GRACE; if (time_after_eq(jiffies, end)) @@ -765,14 +942,16 @@ static int cfq_arm_slice_timer(struct cfq_data *cfqd, struct cfq_queue *cfqq) return 1; } -static void cfq_dispatch_insert(request_queue_t *q, struct request *rq) +static void cfq_dispatch_insert(request_queue_t *q, struct cfq_rq *crq) { struct cfq_data *cfqd = q->elevator->elevator_data; - struct cfq_queue *cfqq = RQ_CFQQ(rq); + struct cfq_queue *cfqq = crq->cfq_queue; + struct request *rq; - cfq_remove_request(rq); - cfqq->on_dispatch[rq_is_sync(rq)]++; - elv_dispatch_sort(q, rq); + cfqq->next_crq = cfq_find_next_crq(cfqd, cfqq, crq); + cfq_remove_request(crq->request); + cfqq->on_dispatch[cfq_crq_is_sync(crq)]++; + elv_dispatch_sort(q, crq->request); rq = list_entry(q->queue_head.prev, struct request, queuelist); cfqd->last_sector = rq->sector + rq->nr_sectors; @@ -781,23 +960,24 @@ static void cfq_dispatch_insert(request_queue_t *q, struct request *rq) /* * return expired entry, or NULL to just start from scratch in rbtree */ -static inline struct request *cfq_check_fifo(struct cfq_queue *cfqq) +static inline struct cfq_rq *cfq_check_fifo(struct cfq_queue *cfqq) { struct cfq_data *cfqd = cfqq->cfqd; struct request *rq; - int fifo; + struct cfq_rq *crq; if (cfq_cfqq_fifo_expire(cfqq)) return NULL; - if (list_empty(&cfqq->fifo)) - return NULL; - fifo = cfq_cfqq_class_sync(cfqq); - rq = rq_entry_fifo(cfqq->fifo.next); + if (!list_empty(&cfqq->fifo)) { + int fifo = cfq_cfqq_class_sync(cfqq); - if (time_after(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo])) { - cfq_mark_cfqq_fifo_expire(cfqq); - return rq; + crq = RQ_DATA(list_entry_fifo(cfqq->fifo.next)); + rq = crq->request; + if (time_after(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo])) { + cfq_mark_cfqq_fifo_expire(cfqq); + return crq; + } } return NULL; @@ -883,25 +1063,25 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq, BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list)); do { - struct request *rq; + struct cfq_rq *crq; /* * follow expired path, else get first next available */ - if ((rq = cfq_check_fifo(cfqq)) == NULL) - rq = cfqq->next_rq; + if ((crq = cfq_check_fifo(cfqq)) == NULL) + crq = cfqq->next_crq; /* * finally, insert request into driver dispatch list */ - cfq_dispatch_insert(cfqd->queue, rq); + cfq_dispatch_insert(cfqd->queue, crq); cfqd->dispatch_slice++; dispatched++; if (!cfqd->active_cic) { - atomic_inc(&RQ_CIC(rq)->ioc->refcount); - cfqd->active_cic = RQ_CIC(rq); + atomic_inc(&crq->io_context->ioc->refcount); + cfqd->active_cic = crq->io_context; } if (RB_EMPTY_ROOT(&cfqq->sort_list)) @@ -932,12 +1112,13 @@ static int cfq_forced_dispatch_cfqqs(struct list_head *list) { struct cfq_queue *cfqq, *next; + struct cfq_rq *crq; int dispatched; dispatched = 0; list_for_each_entry_safe(cfqq, next, list, cfq_list) { - while (cfqq->next_rq) { - cfq_dispatch_insert(cfqq->cfqd->queue, cfqq->next_rq); + while ((crq = cfqq->next_crq)) { + cfq_dispatch_insert(cfqq->cfqd->queue, crq); dispatched++; } BUG_ON(!list_empty(&cfqq->fifo)); @@ -1013,8 +1194,8 @@ cfq_dispatch_requests(request_queue_t *q, int force) } /* - * task holds one reference to the queue, dropped when task exits. each rq - * in-flight on this queue also holds a reference, dropped when rq is freed. + * task holds one reference to the queue, dropped when task exits. each crq + * in-flight on this queue also holds a reference, dropped when crq is freed. * * queue lock must be held here. */ @@ -1042,7 +1223,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq) kmem_cache_free(cfq_pool, cfqq); } -static struct cfq_queue * +static inline struct cfq_queue * __cfq_find_cfq_hash(struct cfq_data *cfqd, unsigned int key, unsigned int prio, const int hashval) { @@ -1079,63 +1260,62 @@ static void cfq_free_io_context(struct io_context *ioc) freed++; } - elv_ioc_count_mod(ioc_count, -freed); - - if (ioc_gone && !elv_ioc_count_read(ioc_count)) + if (atomic_sub_and_test(freed, &ioc_count) && ioc_gone) complete(ioc_gone); } -static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) +static void cfq_trim(struct io_context *ioc) { - if (unlikely(cfqq == cfqd->active_queue)) - __cfq_slice_expired(cfqd, cfqq, 0); - - cfq_put_queue(cfqq); + ioc->set_ioprio = NULL; + cfq_free_io_context(ioc); } -static void __cfq_exit_single_io_context(struct cfq_data *cfqd, - struct cfq_io_context *cic) +/* + * Called with interrupts disabled + */ +static void cfq_exit_single_io_context(struct cfq_io_context *cic) { - list_del_init(&cic->queue_list); - smp_wmb(); - cic->key = NULL; + struct cfq_data *cfqd = cic->key; + request_queue_t *q; + + if (!cfqd) + return; + + q = cfqd->queue; + + WARN_ON(!irqs_disabled()); + + spin_lock(q->queue_lock); if (cic->cfqq[ASYNC]) { - cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]); + if (unlikely(cic->cfqq[ASYNC] == cfqd->active_queue)) + __cfq_slice_expired(cfqd, cic->cfqq[ASYNC], 0); + cfq_put_queue(cic->cfqq[ASYNC]); cic->cfqq[ASYNC] = NULL; } if (cic->cfqq[SYNC]) { - cfq_exit_cfqq(cfqd, cic->cfqq[SYNC]); + if (unlikely(cic->cfqq[SYNC] == cfqd->active_queue)) + __cfq_slice_expired(cfqd, cic->cfqq[SYNC], 0); + cfq_put_queue(cic->cfqq[SYNC]); cic->cfqq[SYNC] = NULL; } -} - -/* - * Called with interrupts disabled - */ -static void cfq_exit_single_io_context(struct cfq_io_context *cic) -{ - struct cfq_data *cfqd = cic->key; - - if (cfqd) { - request_queue_t *q = cfqd->queue; - - spin_lock_irq(q->queue_lock); - __cfq_exit_single_io_context(cfqd, cic); - spin_unlock_irq(q->queue_lock); - } + cic->key = NULL; + list_del_init(&cic->queue_list); + spin_unlock(q->queue_lock); } static void cfq_exit_io_context(struct io_context *ioc) { struct cfq_io_context *__cic; + unsigned long flags; struct rb_node *n; /* * put the reference this task is holding to the various queues */ + spin_lock_irqsave(&cfq_exit_lock, flags); n = rb_first(&ioc->cic_root); while (n != NULL) { @@ -1144,21 +1324,22 @@ static void cfq_exit_io_context(struct io_context *ioc) cfq_exit_single_io_context(__cic); n = rb_next(n); } + + spin_unlock_irqrestore(&cfq_exit_lock, flags); } static struct cfq_io_context * cfq_alloc_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) { - struct cfq_io_context *cic; + struct cfq_io_context *cic = kmem_cache_alloc(cfq_ioc_pool, gfp_mask); - cic = kmem_cache_alloc_node(cfq_ioc_pool, gfp_mask, cfqd->queue->node); if (cic) { memset(cic, 0, sizeof(*cic)); cic->last_end_request = jiffies; INIT_LIST_HEAD(&cic->queue_list); cic->dtor = cfq_free_io_context; cic->exit = cfq_exit_io_context; - elv_ioc_count_inc(ioc_count); + atomic_inc(&ioc_count); } return cic; @@ -1239,12 +1420,15 @@ static inline void changed_ioprio(struct cfq_io_context *cic) spin_unlock(cfqd->queue->queue_lock); } -static void cfq_ioc_set_ioprio(struct io_context *ioc) +/* + * callback from sys_ioprio_set, irqs are disabled + */ +static int cfq_ioc_set_ioprio(struct io_context *ioc, unsigned int ioprio) { struct cfq_io_context *cic; struct rb_node *n; - ioc->ioprio_changed = 0; + spin_lock(&cfq_exit_lock); n = rb_first(&ioc->cic_root); while (n != NULL) { @@ -1253,6 +1437,10 @@ static void cfq_ioc_set_ioprio(struct io_context *ioc) changed_ioprio(cic); n = rb_next(n); } + + spin_unlock(&cfq_exit_lock); + + return 0; } static struct cfq_queue * @@ -1272,18 +1460,12 @@ cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, cfqq = new_cfqq; new_cfqq = NULL; } else if (gfp_mask & __GFP_WAIT) { - /* - * Inform the allocator of the fact that we will - * just repeat this allocation if it fails, to allow - * the allocator to do whatever it needs to attempt to - * free memory. - */ spin_unlock_irq(cfqd->queue->queue_lock); - new_cfqq = kmem_cache_alloc_node(cfq_pool, gfp_mask|__GFP_NOFAIL, cfqd->queue->node); + new_cfqq = kmem_cache_alloc(cfq_pool, gfp_mask); spin_lock_irq(cfqd->queue->queue_lock); goto retry; } else { - cfqq = kmem_cache_alloc_node(cfq_pool, gfp_mask, cfqd->queue->node); + cfqq = kmem_cache_alloc(cfq_pool, gfp_mask); if (!cfqq) goto out; } @@ -1298,13 +1480,13 @@ cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, hlist_add_head(&cfqq->cfq_hash, &cfqd->cfq_hash[hashval]); atomic_set(&cfqq->ref, 0); cfqq->cfqd = cfqd; + cfqq->service_last = 0; /* * set ->slice_left to allow preemption for a new process */ cfqq->slice_left = 2 * cfqd->cfq_slice_idle; cfq_mark_cfqq_idle_window(cfqq); cfq_mark_cfqq_prio_changed(cfqq); - cfq_mark_cfqq_queue_new(cfqq); cfq_init_prio_data(cfqq); } @@ -1320,10 +1502,12 @@ cfq_get_queue(struct cfq_data *cfqd, unsigned int key, struct task_struct *tsk, static void cfq_drop_dead_cic(struct io_context *ioc, struct cfq_io_context *cic) { - WARN_ON(!list_empty(&cic->queue_list)); + spin_lock(&cfq_exit_lock); rb_erase(&cic->rb_node, &ioc->cic_root); + list_del_init(&cic->queue_list); + spin_unlock(&cfq_exit_lock); kmem_cache_free(cfq_ioc_pool, cic); - elv_ioc_count_dec(ioc_count); + atomic_dec(&ioc_count); } static struct cfq_io_context * @@ -1367,6 +1551,7 @@ cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, cic->ioc = ioc; cic->key = cfqd; + ioc->set_ioprio = cfq_ioc_set_ioprio; restart: parent = NULL; p = &ioc->cic_root.rb_node; @@ -1388,12 +1573,11 @@ cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, BUG(); } + spin_lock(&cfq_exit_lock); rb_link_node(&cic->rb_node, parent, p); rb_insert_color(&cic->rb_node, &ioc->cic_root); - - spin_lock_irq(cfqd->queue->queue_lock); list_add(&cic->queue_list, &cfqd->cic_list); - spin_unlock_irq(cfqd->queue->queue_lock); + spin_unlock(&cfq_exit_lock); } /* @@ -1409,7 +1593,7 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) might_sleep_if(gfp_mask & __GFP_WAIT); - ioc = get_io_context(gfp_mask, cfqd->queue->node); + ioc = get_io_context(gfp_mask); if (!ioc) return NULL; @@ -1423,10 +1607,6 @@ cfq_get_io_context(struct cfq_data *cfqd, gfp_t gfp_mask) cfq_cic_link(cfqd, ioc, cic); out: - smp_read_barrier_depends(); - if (unlikely(ioc->ioprio_changed)) - cfq_ioc_set_ioprio(ioc); - return cic; err: put_io_context(ioc); @@ -1460,15 +1640,15 @@ cfq_update_io_thinktime(struct cfq_data *cfqd, struct cfq_io_context *cic) static void cfq_update_io_seektime(struct cfq_data *cfqd, struct cfq_io_context *cic, - struct request *rq) + struct cfq_rq *crq) { sector_t sdist; u64 total; - if (cic->last_request_pos < rq->sector) - sdist = rq->sector - cic->last_request_pos; + if (cic->last_request_pos < crq->request->sector) + sdist = crq->request->sector - cic->last_request_pos; else - sdist = cic->last_request_pos - rq->sector; + sdist = cic->last_request_pos - crq->request->sector; /* * Don't allow the seek distance to get too large from the @@ -1519,7 +1699,7 @@ cfq_update_idle_window(struct cfq_data *cfqd, struct cfq_queue *cfqq, */ static int cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, - struct request *rq) + struct cfq_rq *crq) { struct cfq_queue *cfqq = cfqd->active_queue; @@ -1538,17 +1718,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, */ if (new_cfqq->slice_left < cfqd->cfq_slice_idle) return 0; - /* - * if the new request is sync, but the currently running queue is - * not, let the sync request have priority. - */ - if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq)) - return 1; - /* - * So both queues are sync. Let the new request get disk time if - * it's a metadata request and the current queue is doing regular IO. - */ - if (rq_is_meta(rq) && !cfqq->meta_pending) + if (cfq_crq_is_sync(crq) && !cfq_cfqq_sync(cfqq)) return 1; return 0; @@ -1560,45 +1730,47 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, */ static void cfq_preempt_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq) { - cfq_slice_expired(cfqd, 1); + struct cfq_queue *__cfqq, *next; + + list_for_each_entry_safe(__cfqq, next, &cfqd->cur_rr, cfq_list) + cfq_resort_rr_list(__cfqq, 1); if (!cfqq->slice_left) cfqq->slice_left = cfq_prio_to_slice(cfqd, cfqq) / 2; - /* - * Put the new queue at the front of the of the current list, - * so we know that it will be selected next. - */ - BUG_ON(!cfq_cfqq_on_rr(cfqq)); - list_move(&cfqq->cfq_list, &cfqd->cur_rr); - cfqq->slice_end = cfqq->slice_left + jiffies; + cfq_slice_expired(cfqd, 1); + __cfq_set_active_queue(cfqd, cfqq); } /* - * Called when a new fs request (rq) is added (to cfqq). Check if there's - * something we should do about it + * should really be a ll_rw_blk.c helper */ -static void -cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, - struct request *rq) +static void cfq_start_queueing(struct cfq_data *cfqd, struct cfq_queue *cfqq) { - struct cfq_io_context *cic = RQ_CIC(rq); + request_queue_t *q = cfqd->queue; - if (rq_is_meta(rq)) - cfqq->meta_pending++; + if (!blk_queue_plugged(q)) + q->request_fn(q); + else + __generic_unplug_device(q); +} - /* - * check if this request is a better next-serve candidate)) { - */ - cfqq->next_rq = cfq_choose_req(cfqd, cfqq->next_rq, rq); - BUG_ON(!cfqq->next_rq); +/* + * Called when a new fs request (crq) is added (to cfqq). Check if there's + * something we should do about it + */ +static void +cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, + struct cfq_rq *crq) +{ + struct cfq_io_context *cic = crq->io_context; /* * we never wait for an async request and we don't allow preemption * of an async request. so just return early */ - if (!rq_is_sync(rq)) { + if (!cfq_crq_is_sync(crq)) { /* * sync process issued an async request, if it's waiting * then expire it and kick rq handling. @@ -1606,17 +1778,17 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, if (cic == cfqd->active_cic && del_timer(&cfqd->idle_slice_timer)) { cfq_slice_expired(cfqd, 0); - blk_start_queueing(cfqd->queue); + cfq_start_queueing(cfqd, cfqq); } return; } cfq_update_io_thinktime(cfqd, cic); - cfq_update_io_seektime(cfqd, cic, rq); + cfq_update_io_seektime(cfqd, cic, crq); cfq_update_idle_window(cfqd, cfqq, cic); cic->last_queue = jiffies; - cic->last_request_pos = rq->sector + rq->nr_sectors; + cic->last_request_pos = crq->request->sector + crq->request->nr_sectors; if (cfqq == cfqd->active_queue) { /* @@ -1627,9 +1799,9 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, if (cfq_cfqq_wait_request(cfqq)) { cfq_mark_cfqq_must_dispatch(cfqq); del_timer(&cfqd->idle_slice_timer); - blk_start_queueing(cfqd->queue); + cfq_start_queueing(cfqd, cfqq); } - } else if (cfq_should_preempt(cfqd, cfqq, rq)) { + } else if (cfq_should_preempt(cfqd, cfqq, crq)) { /* * not the active queue - expire current slice if it is * idle and has expired it's mean thinktime or this new queue @@ -1637,32 +1809,34 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, */ cfq_preempt_queue(cfqd, cfqq); cfq_mark_cfqq_must_dispatch(cfqq); - blk_start_queueing(cfqd->queue); + cfq_start_queueing(cfqd, cfqq); } } static void cfq_insert_request(request_queue_t *q, struct request *rq) { struct cfq_data *cfqd = q->elevator->elevator_data; - struct cfq_queue *cfqq = RQ_CFQQ(rq); + struct cfq_rq *crq = RQ_DATA(rq); + struct cfq_queue *cfqq = crq->cfq_queue; cfq_init_prio_data(cfqq); - cfq_add_rq_rb(rq); - - if (!cfq_cfqq_on_rr(cfqq)) - cfq_add_cfqq_rr(cfqd, cfqq); + cfq_add_crq_rb(crq); list_add_tail(&rq->queuelist, &cfqq->fifo); - cfq_rq_enqueued(cfqd, cfqq, rq); + if (rq_mergeable(rq)) + cfq_add_crq_hash(cfqd, crq); + + cfq_crq_enqueued(cfqd, cfqq, crq); } static void cfq_completed_request(request_queue_t *q, struct request *rq) { - struct cfq_queue *cfqq = RQ_CFQQ(rq); + struct cfq_rq *crq = RQ_DATA(rq); + struct cfq_queue *cfqq = crq->cfq_queue; struct cfq_data *cfqd = cfqq->cfqd; - const int sync = rq_is_sync(rq); + const int sync = cfq_crq_is_sync(crq); unsigned long now; now = jiffies; @@ -1675,11 +1849,15 @@ static void cfq_completed_request(request_queue_t *q, struct request *rq) if (!cfq_class_idle(cfqq)) cfqd->last_end_request = now; - if (!cfq_cfqq_dispatched(cfqq) && cfq_cfqq_on_rr(cfqq)) - cfq_resort_rr_list(cfqq, 0); + if (!cfq_cfqq_dispatched(cfqq)) { + if (cfq_cfqq_on_rr(cfqq)) { + cfqq->service_last = now; + cfq_resort_rr_list(cfqq, 0); + } + } if (sync) - RQ_CIC(rq)->last_end_request = now; + crq->io_context->last_end_request = now; /* * If this is the active queue, check if it needs to be expired, @@ -1695,6 +1873,30 @@ static void cfq_completed_request(request_queue_t *q, struct request *rq) } } +static struct request * +cfq_former_request(request_queue_t *q, struct request *rq) +{ + struct cfq_rq *crq = RQ_DATA(rq); + struct rb_node *rbprev = rb_prev(&crq->rb_node); + + if (rbprev) + return rb_entry_crq(rbprev)->request; + + return NULL; +} + +static struct request * +cfq_latter_request(request_queue_t *q, struct request *rq) +{ + struct cfq_rq *crq = RQ_DATA(rq); + struct rb_node *rbnext = rb_next(&crq->rb_node); + + if (rbnext) + return rb_entry_crq(rbnext)->request; + + return NULL; +} + /* * we temporarily boost lower priority queues if they are holding fs exclusive * resources. they are boosted to normal prio (CLASS_BE/4) @@ -1731,7 +1933,9 @@ static void cfq_prio_boost(struct cfq_queue *cfqq) cfq_resort_rr_list(cfqq, 0); } -static inline int __cfq_may_queue(struct cfq_queue *cfqq) +static inline int +__cfq_may_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq, + struct task_struct *task, int rw) { if ((cfq_cfqq_wait_request(cfqq) || cfq_cfqq_must_alloc(cfqq)) && !cfq_cfqq_must_alloc_slice(cfqq)) { @@ -1742,7 +1946,7 @@ static inline int __cfq_may_queue(struct cfq_queue *cfqq) return ELV_MQUEUE_MAY; } -static int cfq_may_queue(request_queue_t *q, int rw) +static int cfq_may_queue(request_queue_t *q, int rw, struct bio *bio) { struct cfq_data *cfqd = q->elevator->elevator_data; struct task_struct *tsk = current; @@ -1759,30 +1963,48 @@ static int cfq_may_queue(request_queue_t *q, int rw) cfq_init_prio_data(cfqq); cfq_prio_boost(cfqq); - return __cfq_may_queue(cfqq); + return __cfq_may_queue(cfqd, cfqq, tsk, rw); } return ELV_MQUEUE_MAY; } +static void cfq_check_waiters(request_queue_t *q, struct cfq_queue *cfqq) +{ + struct cfq_data *cfqd = q->elevator->elevator_data; + + if (unlikely(cfqd->rq_starved)) { + struct request_list *rl = &q->rq; + + smp_mb(); + if (waitqueue_active(&rl->wait[READ])) + wake_up(&rl->wait[READ]); + if (waitqueue_active(&rl->wait[WRITE])) + wake_up(&rl->wait[WRITE]); + } +} + /* * queue lock held here */ static void cfq_put_request(request_queue_t *q, struct request *rq) { - struct cfq_queue *cfqq = RQ_CFQQ(rq); + struct cfq_data *cfqd = q->elevator->elevator_data; + struct cfq_rq *crq = RQ_DATA(rq); - if (cfqq) { + if (crq) { + struct cfq_queue *cfqq = crq->cfq_queue; const int rw = rq_data_dir(rq); BUG_ON(!cfqq->allocated[rw]); cfqq->allocated[rw]--; - put_io_context(RQ_CIC(rq)->ioc); + put_io_context(crq->io_context->ioc); + mempool_free(crq, cfqd->crq_pool); rq->elevator_private = NULL; - rq->elevator_private2 = NULL; + cfq_check_waiters(q, cfqq); cfq_put_queue(cfqq); } } @@ -1791,7 +2013,8 @@ static void cfq_put_request(request_queue_t *q, struct request *rq) * Allocate cfq data structures associated with this request. */ static int -cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask) +cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio, + gfp_t gfp_mask) { struct cfq_data *cfqd = q->elevator->elevator_data; struct task_struct *tsk = current; @@ -1799,6 +2022,7 @@ cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask) const int rw = rq_data_dir(rq); pid_t key = cfq_queue_pid(tsk, rw); struct cfq_queue *cfqq; + struct cfq_rq *crq; unsigned long flags; int is_sync = key != CFQ_KEY_ASYNC; @@ -1822,18 +2046,42 @@ cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask) cfqq->allocated[rw]++; cfq_clear_cfqq_must_alloc(cfqq); + cfqd->rq_starved = 0; atomic_inc(&cfqq->ref); - spin_unlock_irqrestore(q->queue_lock, flags); - rq->elevator_private = cic; - rq->elevator_private2 = cfqq; - return 0; + crq = mempool_alloc(cfqd->crq_pool, gfp_mask); + if (crq) { + RB_CLEAR_NODE(&crq->rb_node); + crq->rb_key = 0; + crq->request = rq; + INIT_HLIST_NODE(&crq->hash); + crq->cfq_queue = cfqq; + crq->io_context = cic; + + if (is_sync) + cfq_mark_crq_is_sync(crq); + else + cfq_clear_crq_is_sync(crq); + rq->elevator_private = crq; + return 0; + } + + spin_lock_irqsave(q->queue_lock, flags); + cfqq->allocated[rw]--; + if (!(cfqq->allocated[0] + cfqq->allocated[1])) + cfq_mark_cfqq_must_alloc(cfqq); + cfq_put_queue(cfqq); queue_fail: if (cic) put_io_context(cic->ioc); - + /* + * mark us rq allocation starved. we need to kickstart the process + * ourselves if there are no pending requests that can do it for us. + * that would be an extremely rare OOM situation + */ + cfqd->rq_starved = 1; cfq_schedule_dispatch(cfqd); spin_unlock_irqrestore(q->queue_lock, flags); return 1; @@ -1842,10 +2090,27 @@ cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask) static void cfq_kick_queue(void *data) { request_queue_t *q = data; + struct cfq_data *cfqd = q->elevator->elevator_data; unsigned long flags; spin_lock_irqsave(q->queue_lock, flags); - blk_start_queueing(q); + + if (cfqd->rq_starved) { + struct request_list *rl = &q->rq; + + /* + * we aren't guaranteed to get a request after this, but we + * have to be opportunistic + */ + smp_mb(); + if (waitqueue_active(&rl->wait[READ])) + wake_up(&rl->wait[READ]); + if (waitqueue_active(&rl->wait[WRITE])) + wake_up(&rl->wait[WRITE]); + } + + blk_remove_plug(q); + q->request_fn(q); spin_unlock_irqrestore(q->queue_lock, flags); } @@ -1928,6 +2193,7 @@ static void cfq_exit_queue(elevator_t *e) cfq_shutdown_timer_wq(cfqd); + spin_lock(&cfq_exit_lock); spin_lock_irq(q->queue_lock); if (cfqd->active_queue) @@ -1937,14 +2203,25 @@ static void cfq_exit_queue(elevator_t *e) struct cfq_io_context *cic = list_entry(cfqd->cic_list.next, struct cfq_io_context, queue_list); - - __cfq_exit_single_io_context(cfqd, cic); + if (cic->cfqq[ASYNC]) { + cfq_put_queue(cic->cfqq[ASYNC]); + cic->cfqq[ASYNC] = NULL; + } + if (cic->cfqq[SYNC]) { + cfq_put_queue(cic->cfqq[SYNC]); + cic->cfqq[SYNC] = NULL; + } + cic->key = NULL; + list_del_init(&cic->queue_list); } spin_unlock_irq(q->queue_lock); + spin_unlock(&cfq_exit_lock); cfq_shutdown_timer_wq(cfqd); + mempool_destroy(cfqd->crq_pool); + kfree(cfqd->crq_hash); kfree(cfqd->cfq_hash); kfree(cfqd); } @@ -1954,7 +2231,7 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e) struct cfq_data *cfqd; int i; - cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL, q->node); + cfqd = kmalloc(sizeof(*cfqd), GFP_KERNEL); if (!cfqd) return NULL; @@ -1966,12 +2243,23 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e) INIT_LIST_HEAD(&cfqd->busy_rr); INIT_LIST_HEAD(&cfqd->cur_rr); INIT_LIST_HEAD(&cfqd->idle_rr); + INIT_LIST_HEAD(&cfqd->empty_list); INIT_LIST_HEAD(&cfqd->cic_list); - cfqd->cfq_hash = kmalloc_node(sizeof(struct hlist_head) * CFQ_QHASH_ENTRIES, GFP_KERNEL, q->node); + cfqd->crq_hash = kmalloc(sizeof(struct hlist_head) * CFQ_MHASH_ENTRIES, GFP_KERNEL); + if (!cfqd->crq_hash) + goto out_crqhash; + + cfqd->cfq_hash = kmalloc(sizeof(struct hlist_head) * CFQ_QHASH_ENTRIES, GFP_KERNEL); if (!cfqd->cfq_hash) - goto out_free; + goto out_cfqhash; + + cfqd->crq_pool = mempool_create_slab_pool(BLKDEV_MIN_RQ, crq_pool); + if (!cfqd->crq_pool) + goto out_crqpool; + for (i = 0; i < CFQ_MHASH_ENTRIES; i++) + INIT_HLIST_HEAD(&cfqd->crq_hash[i]); for (i = 0; i < CFQ_QHASH_ENTRIES; i++) INIT_HLIST_HEAD(&cfqd->cfq_hash[i]); @@ -1987,6 +2275,7 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e) INIT_WORK(&cfqd->unplug_work, cfq_kick_queue, q); + cfqd->cfq_queued = cfq_queued; cfqd->cfq_quantum = cfq_quantum; cfqd->cfq_fifo_expire[0] = cfq_fifo_expire[0]; cfqd->cfq_fifo_expire[1] = cfq_fifo_expire[1]; @@ -1998,13 +2287,19 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e) cfqd->cfq_slice_idle = cfq_slice_idle; return cfqd; -out_free: +out_crqpool: + kfree(cfqd->cfq_hash); +out_cfqhash: + kfree(cfqd->crq_hash); +out_crqhash: kfree(cfqd); return NULL; } static void cfq_slab_kill(void) { + if (crq_pool) + kmem_cache_destroy(crq_pool); if (cfq_pool) kmem_cache_destroy(cfq_pool); if (cfq_ioc_pool) @@ -2013,6 +2308,11 @@ static void cfq_slab_kill(void) static int __init cfq_slab_setup(void) { + crq_pool = kmem_cache_create("crq_pool", sizeof(struct cfq_rq), 0, 0, + NULL, NULL); + if (!crq_pool) + goto fail; + cfq_pool = kmem_cache_create("cfq_pool", sizeof(struct cfq_queue), 0, 0, NULL, NULL); if (!cfq_pool) @@ -2058,6 +2358,7 @@ static ssize_t __FUNC(elevator_t *e, char *page) \ return cfq_var_show(__data, (page)); \ } SHOW_FUNCTION(cfq_quantum_show, cfqd->cfq_quantum, 0); +SHOW_FUNCTION(cfq_queued_show, cfqd->cfq_queued, 0); SHOW_FUNCTION(cfq_fifo_expire_sync_show, cfqd->cfq_fifo_expire[1], 1); SHOW_FUNCTION(cfq_fifo_expire_async_show, cfqd->cfq_fifo_expire[0], 1); SHOW_FUNCTION(cfq_back_seek_max_show, cfqd->cfq_back_max, 0); @@ -2085,6 +2386,7 @@ static ssize_t __FUNC(elevator_t *e, const char *page, size_t count) \ return ret; \ } STORE_FUNCTION(cfq_quantum_store, &cfqd->cfq_quantum, 1, UINT_MAX, 0); +STORE_FUNCTION(cfq_queued_store, &cfqd->cfq_queued, 1, UINT_MAX, 0); STORE_FUNCTION(cfq_fifo_expire_sync_store, &cfqd->cfq_fifo_expire[1], 1, UINT_MAX, 1); STORE_FUNCTION(cfq_fifo_expire_async_store, &cfqd->cfq_fifo_expire[0], 1, UINT_MAX, 1); STORE_FUNCTION(cfq_back_seek_max_store, &cfqd->cfq_back_max, 0, UINT_MAX, 0); @@ -2100,6 +2402,7 @@ STORE_FUNCTION(cfq_slice_async_rq_store, &cfqd->cfq_slice_async_rq, 1, UINT_MAX, static struct elv_fs_entry cfq_attrs[] = { CFQ_ATTR(quantum), + CFQ_ATTR(queued), CFQ_ATTR(fifo_expire_sync), CFQ_ATTR(fifo_expire_async), CFQ_ATTR(back_seek_max), @@ -2122,14 +2425,14 @@ static struct elevator_type iosched_cfq = { .elevator_deactivate_req_fn = cfq_deactivate_request, .elevator_queue_empty_fn = cfq_queue_empty, .elevator_completed_req_fn = cfq_completed_request, - .elevator_former_req_fn = elv_rb_former_request, - .elevator_latter_req_fn = elv_rb_latter_request, + .elevator_former_req_fn = cfq_former_request, + .elevator_latter_req_fn = cfq_latter_request, .elevator_set_req_fn = cfq_set_request, .elevator_put_req_fn = cfq_put_request, .elevator_may_queue_fn = cfq_may_queue, .elevator_init_fn = cfq_init_queue, .elevator_exit_fn = cfq_exit_queue, - .trim = cfq_free_io_context, + .trim = cfq_trim, }, .elevator_attrs = cfq_attrs, .elevator_name = "cfq", @@ -2160,12 +2463,12 @@ static int __init cfq_init(void) static void __exit cfq_exit(void) { - DECLARE_COMPLETION_ONSTACK(all_gone); + DECLARE_COMPLETION(all_gone); elv_unregister(&iosched_cfq); ioc_gone = &all_gone; /* ioc_gone's update must be visible before reading ioc_count */ smp_wmb(); - if (elv_ioc_count_read(ioc_count)) + if (atomic_read(&ioc_count)) wait_for_completion(ioc_gone); synchronize_rcu(); cfq_slab_kill(); diff --git a/trunk/block/deadline-iosched.c b/trunk/block/deadline-iosched.c index b7c5b34cb7b4..c7ca9f0b6498 100644 --- a/trunk/block/deadline-iosched.c +++ b/trunk/block/deadline-iosched.c @@ -1,7 +1,7 @@ /* * Deadline i/o scheduler. * - * Copyright (C) 2002 Jens Axboe + * Copyright (C) 2002 Jens Axboe */ #include #include @@ -12,6 +12,7 @@ #include #include #include +#include #include /* @@ -23,6 +24,13 @@ static const int writes_starved = 2; /* max times reads can starve a write */ static const int fifo_batch = 16; /* # of sequential requests treated as one by the above parameters. For throughput. */ +static const int deadline_hash_shift = 5; +#define DL_HASH_BLOCK(sec) ((sec) >> 3) +#define DL_HASH_FN(sec) (hash_long(DL_HASH_BLOCK((sec)), deadline_hash_shift)) +#define DL_HASH_ENTRIES (1 << deadline_hash_shift) +#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) +#define ON_HASH(drq) (!hlist_unhashed(&(drq)->hash)) + struct deadline_data { /* * run time data @@ -37,7 +45,8 @@ struct deadline_data { /* * next in sort order. read, write or both are NULL */ - struct request *next_rq[2]; + struct deadline_rq *next_drq[2]; + struct hlist_head *hash; /* request hash */ unsigned int batching; /* number of sequential requests made */ sector_t last_sector; /* head position */ unsigned int starved; /* times reads have starved writes */ @@ -49,69 +58,240 @@ struct deadline_data { int fifo_batch; int writes_starved; int front_merges; + + mempool_t *drq_pool; }; -static void deadline_move_request(struct deadline_data *, struct request *); +/* + * pre-request data. + */ +struct deadline_rq { + /* + * rbtree index, key is the starting offset + */ + struct rb_node rb_node; + sector_t rb_key; + + struct request *request; + + /* + * request hash, key is the ending offset (for back merge lookup) + */ + struct hlist_node hash; + + /* + * expire fifo + */ + struct list_head fifo; + unsigned long expires; +}; + +static void deadline_move_request(struct deadline_data *dd, struct deadline_rq *drq); + +static kmem_cache_t *drq_pool; + +#define RQ_DATA(rq) ((struct deadline_rq *) (rq)->elevator_private) -#define RQ_RB_ROOT(dd, rq) (&(dd)->sort_list[rq_data_dir((rq))]) +/* + * the back merge hash support functions + */ +static inline void __deadline_del_drq_hash(struct deadline_rq *drq) +{ + hlist_del_init(&drq->hash); +} + +static inline void deadline_del_drq_hash(struct deadline_rq *drq) +{ + if (ON_HASH(drq)) + __deadline_del_drq_hash(drq); +} + +static inline void +deadline_add_drq_hash(struct deadline_data *dd, struct deadline_rq *drq) +{ + struct request *rq = drq->request; + + BUG_ON(ON_HASH(drq)); + + hlist_add_head(&drq->hash, &dd->hash[DL_HASH_FN(rq_hash_key(rq))]); +} + +/* + * move hot entry to front of chain + */ +static inline void +deadline_hot_drq_hash(struct deadline_data *dd, struct deadline_rq *drq) +{ + struct request *rq = drq->request; + struct hlist_head *head = &dd->hash[DL_HASH_FN(rq_hash_key(rq))]; + + if (ON_HASH(drq) && &drq->hash != head->first) { + hlist_del(&drq->hash); + hlist_add_head(&drq->hash, head); + } +} + +static struct request * +deadline_find_drq_hash(struct deadline_data *dd, sector_t offset) +{ + struct hlist_head *hash_list = &dd->hash[DL_HASH_FN(offset)]; + struct hlist_node *entry, *next; + struct deadline_rq *drq; + + hlist_for_each_entry_safe(drq, entry, next, hash_list, hash) { + struct request *__rq = drq->request; + + BUG_ON(!ON_HASH(drq)); + + if (!rq_mergeable(__rq)) { + __deadline_del_drq_hash(drq); + continue; + } + + if (rq_hash_key(__rq) == offset) + return __rq; + } + + return NULL; +} + +/* + * rb tree support functions + */ +#define rb_entry_drq(node) rb_entry((node), struct deadline_rq, rb_node) +#define DRQ_RB_ROOT(dd, drq) (&(dd)->sort_list[rq_data_dir((drq)->request)]) +#define rq_rb_key(rq) (rq)->sector + +static struct deadline_rq * +__deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq) +{ + struct rb_node **p = &DRQ_RB_ROOT(dd, drq)->rb_node; + struct rb_node *parent = NULL; + struct deadline_rq *__drq; + + while (*p) { + parent = *p; + __drq = rb_entry_drq(parent); + + if (drq->rb_key < __drq->rb_key) + p = &(*p)->rb_left; + else if (drq->rb_key > __drq->rb_key) + p = &(*p)->rb_right; + else + return __drq; + } + + rb_link_node(&drq->rb_node, parent, p); + return NULL; +} static void -deadline_add_rq_rb(struct deadline_data *dd, struct request *rq) +deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq) { - struct rb_root *root = RQ_RB_ROOT(dd, rq); - struct request *__alias; + struct deadline_rq *__alias; + + drq->rb_key = rq_rb_key(drq->request); retry: - __alias = elv_rb_add(root, rq); - if (unlikely(__alias)) { - deadline_move_request(dd, __alias); - goto retry; + __alias = __deadline_add_drq_rb(dd, drq); + if (!__alias) { + rb_insert_color(&drq->rb_node, DRQ_RB_ROOT(dd, drq)); + return; } + + deadline_move_request(dd, __alias); + goto retry; } static inline void -deadline_del_rq_rb(struct deadline_data *dd, struct request *rq) +deadline_del_drq_rb(struct deadline_data *dd, struct deadline_rq *drq) { - const int data_dir = rq_data_dir(rq); + const int data_dir = rq_data_dir(drq->request); - if (dd->next_rq[data_dir] == rq) { - struct rb_node *rbnext = rb_next(&rq->rb_node); + if (dd->next_drq[data_dir] == drq) { + struct rb_node *rbnext = rb_next(&drq->rb_node); - dd->next_rq[data_dir] = NULL; + dd->next_drq[data_dir] = NULL; if (rbnext) - dd->next_rq[data_dir] = rb_entry_rq(rbnext); + dd->next_drq[data_dir] = rb_entry_drq(rbnext); + } + + BUG_ON(!RB_EMPTY_NODE(&drq->rb_node)); + rb_erase(&drq->rb_node, DRQ_RB_ROOT(dd, drq)); + RB_CLEAR_NODE(&drq->rb_node); +} + +static struct request * +deadline_find_drq_rb(struct deadline_data *dd, sector_t sector, int data_dir) +{ + struct rb_node *n = dd->sort_list[data_dir].rb_node; + struct deadline_rq *drq; + + while (n) { + drq = rb_entry_drq(n); + + if (sector < drq->rb_key) + n = n->rb_left; + else if (sector > drq->rb_key) + n = n->rb_right; + else + return drq->request; } - elv_rb_del(RQ_RB_ROOT(dd, rq), rq); + return NULL; } /* - * add rq to rbtree and fifo + * deadline_find_first_drq finds the first (lowest sector numbered) request + * for the specified data_dir. Used to sweep back to the start of the disk + * (1-way elevator) after we process the last (highest sector) request. + */ +static struct deadline_rq * +deadline_find_first_drq(struct deadline_data *dd, int data_dir) +{ + struct rb_node *n = dd->sort_list[data_dir].rb_node; + + for (;;) { + if (n->rb_left == NULL) + return rb_entry_drq(n); + + n = n->rb_left; + } +} + +/* + * add drq to rbtree and fifo */ static void deadline_add_request(struct request_queue *q, struct request *rq) { struct deadline_data *dd = q->elevator->elevator_data; - const int data_dir = rq_data_dir(rq); + struct deadline_rq *drq = RQ_DATA(rq); - deadline_add_rq_rb(dd, rq); + const int data_dir = rq_data_dir(drq->request); + deadline_add_drq_rb(dd, drq); /* * set expire time (only used for reads) and add to fifo list */ - rq_set_fifo_time(rq, jiffies + dd->fifo_expire[data_dir]); - list_add_tail(&rq->queuelist, &dd->fifo_list[data_dir]); + drq->expires = jiffies + dd->fifo_expire[data_dir]; + list_add_tail(&drq->fifo, &dd->fifo_list[data_dir]); + + if (rq_mergeable(rq)) + deadline_add_drq_hash(dd, drq); } /* - * remove rq from rbtree and fifo. + * remove rq from rbtree, fifo, and hash */ static void deadline_remove_request(request_queue_t *q, struct request *rq) { + struct deadline_rq *drq = RQ_DATA(rq); struct deadline_data *dd = q->elevator->elevator_data; - rq_fifo_clear(rq); - deadline_del_rq_rb(dd, rq); + list_del_init(&drq->fifo); + deadline_del_drq_rb(dd, drq); + deadline_del_drq_hash(drq); } static int @@ -121,15 +301,28 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) struct request *__rq; int ret; + /* + * see if the merge hash can satisfy a back merge + */ + __rq = deadline_find_drq_hash(dd, bio->bi_sector); + if (__rq) { + BUG_ON(__rq->sector + __rq->nr_sectors != bio->bi_sector); + + if (elv_rq_merge_ok(__rq, bio)) { + ret = ELEVATOR_BACK_MERGE; + goto out; + } + } + /* * check for front merge */ if (dd->front_merges) { - sector_t sector = bio->bi_sector + bio_sectors(bio); + sector_t rb_key = bio->bi_sector + bio_sectors(bio); - __rq = elv_rb_find(&dd->sort_list[bio_data_dir(bio)], sector); + __rq = deadline_find_drq_rb(dd, rb_key, bio_data_dir(bio)); if (__rq) { - BUG_ON(sector != __rq->sector); + BUG_ON(rb_key != rq_rb_key(__rq)); if (elv_rq_merge_ok(__rq, bio)) { ret = ELEVATOR_FRONT_MERGE; @@ -140,21 +333,29 @@ deadline_merge(request_queue_t *q, struct request **req, struct bio *bio) return ELEVATOR_NO_MERGE; out: + if (ret) + deadline_hot_drq_hash(dd, RQ_DATA(__rq)); *req = __rq; return ret; } -static void deadline_merged_request(request_queue_t *q, struct request *req, - int type) +static void deadline_merged_request(request_queue_t *q, struct request *req) { struct deadline_data *dd = q->elevator->elevator_data; + struct deadline_rq *drq = RQ_DATA(req); + + /* + * hash always needs to be repositioned, key is end sector + */ + deadline_del_drq_hash(drq); + deadline_add_drq_hash(dd, drq); /* * if the merge was a front merge, we need to reposition request */ - if (type == ELEVATOR_FRONT_MERGE) { - elv_rb_del(RQ_RB_ROOT(dd, req), req); - deadline_add_rq_rb(dd, req); + if (rq_rb_key(req) != drq->rb_key) { + deadline_del_drq_rb(dd, drq); + deadline_add_drq_rb(dd, drq); } } @@ -162,14 +363,33 @@ static void deadline_merged_requests(request_queue_t *q, struct request *req, struct request *next) { + struct deadline_data *dd = q->elevator->elevator_data; + struct deadline_rq *drq = RQ_DATA(req); + struct deadline_rq *dnext = RQ_DATA(next); + + BUG_ON(!drq); + BUG_ON(!dnext); + /* - * if next expires before rq, assign its expire time to rq - * and move into next position (next will be deleted) in fifo + * reposition drq (this is the merged request) in hash, and in rbtree + * in case of a front merge */ - if (!list_empty(&req->queuelist) && !list_empty(&next->queuelist)) { - if (time_before(rq_fifo_time(next), rq_fifo_time(req))) { - list_move(&req->queuelist, &next->queuelist); - rq_set_fifo_time(req, rq_fifo_time(next)); + deadline_del_drq_hash(drq); + deadline_add_drq_hash(dd, drq); + + if (rq_rb_key(req) != drq->rb_key) { + deadline_del_drq_rb(dd, drq); + deadline_add_drq_rb(dd, drq); + } + + /* + * if dnext expires before drq, assign its expire time to drq + * and move into dnext position (dnext will be deleted) in fifo + */ + if (!list_empty(&drq->fifo) && !list_empty(&dnext->fifo)) { + if (time_before(dnext->expires, drq->expires)) { + list_move(&drq->fifo, &dnext->fifo); + drq->expires = dnext->expires; } } @@ -183,50 +403,52 @@ deadline_merged_requests(request_queue_t *q, struct request *req, * move request from sort list to dispatch queue. */ static inline void -deadline_move_to_dispatch(struct deadline_data *dd, struct request *rq) +deadline_move_to_dispatch(struct deadline_data *dd, struct deadline_rq *drq) { - request_queue_t *q = rq->q; + request_queue_t *q = drq->request->q; - deadline_remove_request(q, rq); - elv_dispatch_add_tail(q, rq); + deadline_remove_request(q, drq->request); + elv_dispatch_add_tail(q, drq->request); } /* * move an entry to dispatch queue */ static void -deadline_move_request(struct deadline_data *dd, struct request *rq) +deadline_move_request(struct deadline_data *dd, struct deadline_rq *drq) { - const int data_dir = rq_data_dir(rq); - struct rb_node *rbnext = rb_next(&rq->rb_node); + const int data_dir = rq_data_dir(drq->request); + struct rb_node *rbnext = rb_next(&drq->rb_node); - dd->next_rq[READ] = NULL; - dd->next_rq[WRITE] = NULL; + dd->next_drq[READ] = NULL; + dd->next_drq[WRITE] = NULL; if (rbnext) - dd->next_rq[data_dir] = rb_entry_rq(rbnext); + dd->next_drq[data_dir] = rb_entry_drq(rbnext); - dd->last_sector = rq->sector + rq->nr_sectors; + dd->last_sector = drq->request->sector + drq->request->nr_sectors; /* * take it off the sort and fifo list, move * to dispatch queue */ - deadline_move_to_dispatch(dd, rq); + deadline_move_to_dispatch(dd, drq); } +#define list_entry_fifo(ptr) list_entry((ptr), struct deadline_rq, fifo) + /* * deadline_check_fifo returns 0 if there are no expired reads on the fifo, * 1 otherwise. Requires !list_empty(&dd->fifo_list[data_dir]) */ static inline int deadline_check_fifo(struct deadline_data *dd, int ddir) { - struct request *rq = rq_entry_fifo(dd->fifo_list[ddir].next); + struct deadline_rq *drq = list_entry_fifo(dd->fifo_list[ddir].next); /* - * rq is expired! + * drq is expired! */ - if (time_after(jiffies, rq_fifo_time(rq))) + if (time_after(jiffies, drq->expires)) return 1; return 0; @@ -241,21 +463,21 @@ static int deadline_dispatch_requests(request_queue_t *q, int force) struct deadline_data *dd = q->elevator->elevator_data; const int reads = !list_empty(&dd->fifo_list[READ]); const int writes = !list_empty(&dd->fifo_list[WRITE]); - struct request *rq; + struct deadline_rq *drq; int data_dir; /* * batches are currently reads XOR writes */ - if (dd->next_rq[WRITE]) - rq = dd->next_rq[WRITE]; + if (dd->next_drq[WRITE]) + drq = dd->next_drq[WRITE]; else - rq = dd->next_rq[READ]; + drq = dd->next_drq[READ]; - if (rq) { + if (drq) { /* we have a "next request" */ - if (dd->last_sector != rq->sector) + if (dd->last_sector != drq->request->sector) /* end the batch on a non sequential request */ dd->batching += dd->fifo_batch; @@ -304,33 +526,30 @@ static int deadline_dispatch_requests(request_queue_t *q, int force) if (deadline_check_fifo(dd, data_dir)) { /* An expired request exists - satisfy it */ dd->batching = 0; - rq = rq_entry_fifo(dd->fifo_list[data_dir].next); + drq = list_entry_fifo(dd->fifo_list[data_dir].next); - } else if (dd->next_rq[data_dir]) { + } else if (dd->next_drq[data_dir]) { /* * The last req was the same dir and we have a next request in * sort order. No expired requests so continue on from here. */ - rq = dd->next_rq[data_dir]; + drq = dd->next_drq[data_dir]; } else { - struct rb_node *node; /* * The last req was the other direction or we have run out of * higher-sectored requests. Go back to the lowest sectored * request (1 way elevator) and start a new batch. */ dd->batching = 0; - node = rb_first(&dd->sort_list[data_dir]); - if (node) - rq = rb_entry_rq(node); + drq = deadline_find_first_drq(dd, data_dir); } dispatch_request: /* - * rq is the selected appropriate request. + * drq is the selected appropriate request. */ dd->batching++; - deadline_move_request(dd, rq); + deadline_move_request(dd, drq); return 1; } @@ -343,6 +562,30 @@ static int deadline_queue_empty(request_queue_t *q) && list_empty(&dd->fifo_list[READ]); } +static struct request * +deadline_former_request(request_queue_t *q, struct request *rq) +{ + struct deadline_rq *drq = RQ_DATA(rq); + struct rb_node *rbprev = rb_prev(&drq->rb_node); + + if (rbprev) + return rb_entry_drq(rbprev)->request; + + return NULL; +} + +static struct request * +deadline_latter_request(request_queue_t *q, struct request *rq) +{ + struct deadline_rq *drq = RQ_DATA(rq); + struct rb_node *rbnext = rb_next(&drq->rb_node); + + if (rbnext) + return rb_entry_drq(rbnext)->request; + + return NULL; +} + static void deadline_exit_queue(elevator_t *e) { struct deadline_data *dd = e->elevator_data; @@ -350,21 +593,46 @@ static void deadline_exit_queue(elevator_t *e) BUG_ON(!list_empty(&dd->fifo_list[READ])); BUG_ON(!list_empty(&dd->fifo_list[WRITE])); + mempool_destroy(dd->drq_pool); + kfree(dd->hash); kfree(dd); } /* - * initialize elevator private data (deadline_data). + * initialize elevator private data (deadline_data), and alloc a drq for + * each request on the free lists */ static void *deadline_init_queue(request_queue_t *q, elevator_t *e) { struct deadline_data *dd; + int i; + + if (!drq_pool) + return NULL; dd = kmalloc_node(sizeof(*dd), GFP_KERNEL, q->node); if (!dd) return NULL; memset(dd, 0, sizeof(*dd)); + dd->hash = kmalloc_node(sizeof(struct hlist_head)*DL_HASH_ENTRIES, + GFP_KERNEL, q->node); + if (!dd->hash) { + kfree(dd); + return NULL; + } + + dd->drq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, + mempool_free_slab, drq_pool, q->node); + if (!dd->drq_pool) { + kfree(dd->hash); + kfree(dd); + return NULL; + } + + for (i = 0; i < DL_HASH_ENTRIES; i++) + INIT_HLIST_HEAD(&dd->hash[i]); + INIT_LIST_HEAD(&dd->fifo_list[READ]); INIT_LIST_HEAD(&dd->fifo_list[WRITE]); dd->sort_list[READ] = RB_ROOT; @@ -377,6 +645,39 @@ static void *deadline_init_queue(request_queue_t *q, elevator_t *e) return dd; } +static void deadline_put_request(request_queue_t *q, struct request *rq) +{ + struct deadline_data *dd = q->elevator->elevator_data; + struct deadline_rq *drq = RQ_DATA(rq); + + mempool_free(drq, dd->drq_pool); + rq->elevator_private = NULL; +} + +static int +deadline_set_request(request_queue_t *q, struct request *rq, struct bio *bio, + gfp_t gfp_mask) +{ + struct deadline_data *dd = q->elevator->elevator_data; + struct deadline_rq *drq; + + drq = mempool_alloc(dd->drq_pool, gfp_mask); + if (drq) { + memset(drq, 0, sizeof(*drq)); + RB_CLEAR_NODE(&drq->rb_node); + drq->request = rq; + + INIT_HLIST_NODE(&drq->hash); + + INIT_LIST_HEAD(&drq->fifo); + + rq->elevator_private = drq; + return 0; + } + + return 1; +} + /* * sysfs parts below */ @@ -456,8 +757,10 @@ static struct elevator_type iosched_deadline = { .elevator_dispatch_fn = deadline_dispatch_requests, .elevator_add_req_fn = deadline_add_request, .elevator_queue_empty_fn = deadline_queue_empty, - .elevator_former_req_fn = elv_rb_former_request, - .elevator_latter_req_fn = elv_rb_latter_request, + .elevator_former_req_fn = deadline_former_request, + .elevator_latter_req_fn = deadline_latter_request, + .elevator_set_req_fn = deadline_set_request, + .elevator_put_req_fn = deadline_put_request, .elevator_init_fn = deadline_init_queue, .elevator_exit_fn = deadline_exit_queue, }, @@ -469,11 +772,24 @@ static struct elevator_type iosched_deadline = { static int __init deadline_init(void) { - return elv_register(&iosched_deadline); + int ret; + + drq_pool = kmem_cache_create("deadline_drq", sizeof(struct deadline_rq), + 0, 0, NULL, NULL); + + if (!drq_pool) + return -ENOMEM; + + ret = elv_register(&iosched_deadline); + if (ret) + kmem_cache_destroy(drq_pool); + + return ret; } static void __exit deadline_exit(void) { + kmem_cache_destroy(drq_pool); elv_unregister(&iosched_deadline); } diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 487dd3da8853..9b72dc7c8a5c 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -3,7 +3,7 @@ * * Copyright (C) 2000 Andrea Arcangeli SuSE * - * 30042000 Jens Axboe : + * 30042000 Jens Axboe : * * Split the elevator a bit so that it is possible to choose a different * one or even write a new "plug in". There are three pieces: @@ -33,23 +33,12 @@ #include #include #include -#include #include static DEFINE_SPINLOCK(elv_list_lock); static LIST_HEAD(elv_list); -/* - * Merge hash stuff. - */ -static const int elv_hash_shift = 6; -#define ELV_HASH_BLOCK(sec) ((sec) >> 3) -#define ELV_HASH_FN(sec) (hash_long(ELV_HASH_BLOCK((sec)), elv_hash_shift)) -#define ELV_HASH_ENTRIES (1 << elv_hash_shift) -#define rq_hash_key(rq) ((rq)->sector + (rq)->nr_sectors) -#define ELV_ON_HASH(rq) (!hlist_unhashed(&(rq)->hash)) - /* * can we safely merge with this request? */ @@ -67,7 +56,8 @@ inline int elv_rq_merge_ok(struct request *rq, struct bio *bio) /* * same device and no special stuff set, merge is ok */ - if (rq->rq_disk == bio->bi_bdev->bd_disk && !rq->special) + if (rq->rq_disk == bio->bi_bdev->bd_disk && + !rq->waiting && !rq->special) return 1; return 0; @@ -161,44 +151,27 @@ __setup("elevator=", elevator_setup); static struct kobj_type elv_ktype; -static elevator_t *elevator_alloc(request_queue_t *q, struct elevator_type *e) -{ - elevator_t *eq; - int i; - - eq = kmalloc_node(sizeof(elevator_t), GFP_KERNEL, q->node); - if (unlikely(!eq)) - goto err; - - memset(eq, 0, sizeof(*eq)); - eq->ops = &e->ops; - eq->elevator_type = e; - kobject_init(&eq->kobj); - snprintf(eq->kobj.name, KOBJ_NAME_LEN, "%s", "iosched"); - eq->kobj.ktype = &elv_ktype; - mutex_init(&eq->sysfs_lock); - - eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES, - GFP_KERNEL, q->node); - if (!eq->hash) - goto err; - - for (i = 0; i < ELV_HASH_ENTRIES; i++) - INIT_HLIST_HEAD(&eq->hash[i]); - +static elevator_t *elevator_alloc(struct elevator_type *e) +{ + elevator_t *eq = kmalloc(sizeof(elevator_t), GFP_KERNEL); + if (eq) { + memset(eq, 0, sizeof(*eq)); + eq->ops = &e->ops; + eq->elevator_type = e; + kobject_init(&eq->kobj); + snprintf(eq->kobj.name, KOBJ_NAME_LEN, "%s", "iosched"); + eq->kobj.ktype = &elv_ktype; + mutex_init(&eq->sysfs_lock); + } else { + elevator_put(e); + } return eq; -err: - kfree(eq); - elevator_put(e); - return NULL; } static void elevator_release(struct kobject *kobj) { elevator_t *e = container_of(kobj, elevator_t, kobj); - elevator_put(e->elevator_type); - kfree(e->hash); kfree(e); } @@ -225,7 +198,7 @@ int elevator_init(request_queue_t *q, char *name) e = elevator_get("noop"); } - eq = elevator_alloc(q, e); + eq = elevator_alloc(e); if (!eq) return -ENOMEM; @@ -239,8 +212,6 @@ int elevator_init(request_queue_t *q, char *name) return ret; } -EXPORT_SYMBOL(elevator_init); - void elevator_exit(elevator_t *e) { mutex_lock(&e->sysfs_lock); @@ -252,118 +223,10 @@ void elevator_exit(elevator_t *e) kobject_put(&e->kobj); } -EXPORT_SYMBOL(elevator_exit); - -static inline void __elv_rqhash_del(struct request *rq) -{ - hlist_del_init(&rq->hash); -} - -static void elv_rqhash_del(request_queue_t *q, struct request *rq) -{ - if (ELV_ON_HASH(rq)) - __elv_rqhash_del(rq); -} - -static void elv_rqhash_add(request_queue_t *q, struct request *rq) -{ - elevator_t *e = q->elevator; - - BUG_ON(ELV_ON_HASH(rq)); - hlist_add_head(&rq->hash, &e->hash[ELV_HASH_FN(rq_hash_key(rq))]); -} - -static void elv_rqhash_reposition(request_queue_t *q, struct request *rq) -{ - __elv_rqhash_del(rq); - elv_rqhash_add(q, rq); -} - -static struct request *elv_rqhash_find(request_queue_t *q, sector_t offset) -{ - elevator_t *e = q->elevator; - struct hlist_head *hash_list = &e->hash[ELV_HASH_FN(offset)]; - struct hlist_node *entry, *next; - struct request *rq; - - hlist_for_each_entry_safe(rq, entry, next, hash_list, hash) { - BUG_ON(!ELV_ON_HASH(rq)); - - if (unlikely(!rq_mergeable(rq))) { - __elv_rqhash_del(rq); - continue; - } - - if (rq_hash_key(rq) == offset) - return rq; - } - - return NULL; -} - -/* - * RB-tree support functions for inserting/lookup/removal of requests - * in a sorted RB tree. - */ -struct request *elv_rb_add(struct rb_root *root, struct request *rq) -{ - struct rb_node **p = &root->rb_node; - struct rb_node *parent = NULL; - struct request *__rq; - - while (*p) { - parent = *p; - __rq = rb_entry(parent, struct request, rb_node); - - if (rq->sector < __rq->sector) - p = &(*p)->rb_left; - else if (rq->sector > __rq->sector) - p = &(*p)->rb_right; - else - return __rq; - } - - rb_link_node(&rq->rb_node, parent, p); - rb_insert_color(&rq->rb_node, root); - return NULL; -} - -EXPORT_SYMBOL(elv_rb_add); - -void elv_rb_del(struct rb_root *root, struct request *rq) -{ - BUG_ON(RB_EMPTY_NODE(&rq->rb_node)); - rb_erase(&rq->rb_node, root); - RB_CLEAR_NODE(&rq->rb_node); -} - -EXPORT_SYMBOL(elv_rb_del); - -struct request *elv_rb_find(struct rb_root *root, sector_t sector) -{ - struct rb_node *n = root->rb_node; - struct request *rq; - - while (n) { - rq = rb_entry(n, struct request, rb_node); - - if (sector < rq->sector) - n = n->rb_left; - else if (sector > rq->sector) - n = n->rb_right; - else - return rq; - } - - return NULL; -} - -EXPORT_SYMBOL(elv_rb_find); - /* * Insert rq into dispatch queue of q. Queue lock must be held on - * entry. rq is sort insted into the dispatch queue. To be used by - * specific elevators. + * entry. If sort != 0, rq is sort-inserted; otherwise, rq will be + * appended to the dispatch queue. To be used by specific elevators. */ void elv_dispatch_sort(request_queue_t *q, struct request *rq) { @@ -372,9 +235,6 @@ void elv_dispatch_sort(request_queue_t *q, struct request *rq) if (q->last_merge == rq) q->last_merge = NULL; - - elv_rqhash_del(q, rq); - q->nr_sorted--; boundary = q->end_sector; @@ -382,7 +242,7 @@ void elv_dispatch_sort(request_queue_t *q, struct request *rq) list_for_each_prev(entry, &q->queue_head) { struct request *pos = list_entry_rq(entry); - if (pos->cmd_flags & (REQ_SOFTBARRIER|REQ_HARDBARRIER|REQ_STARTED)) + if (pos->flags & (REQ_SOFTBARRIER|REQ_HARDBARRIER|REQ_STARTED)) break; if (rq->sector >= boundary) { if (pos->sector < boundary) @@ -398,38 +258,11 @@ void elv_dispatch_sort(request_queue_t *q, struct request *rq) list_add(&rq->queuelist, entry); } -EXPORT_SYMBOL(elv_dispatch_sort); - -/* - * Insert rq into dispatch queue of q. Queue lock must be held on - * entry. rq is added to the back of the dispatch queue. To be used by - * specific elevators. - */ -void elv_dispatch_add_tail(struct request_queue *q, struct request *rq) -{ - if (q->last_merge == rq) - q->last_merge = NULL; - - elv_rqhash_del(q, rq); - - q->nr_sorted--; - - q->end_sector = rq_end_sector(rq); - q->boundary_rq = rq; - list_add_tail(&rq->queuelist, &q->queue_head); -} - -EXPORT_SYMBOL(elv_dispatch_add_tail); - int elv_merge(request_queue_t *q, struct request **req, struct bio *bio) { elevator_t *e = q->elevator; - struct request *__rq; int ret; - /* - * First try one-hit cache. - */ if (q->last_merge) { ret = elv_try_merge(q->last_merge, bio); if (ret != ELEVATOR_NO_MERGE) { @@ -438,30 +271,18 @@ int elv_merge(request_queue_t *q, struct request **req, struct bio *bio) } } - /* - * See if our hash lookup can find a potential backmerge. - */ - __rq = elv_rqhash_find(q, bio->bi_sector); - if (__rq && elv_rq_merge_ok(__rq, bio)) { - *req = __rq; - return ELEVATOR_BACK_MERGE; - } - if (e->ops->elevator_merge_fn) return e->ops->elevator_merge_fn(q, req, bio); return ELEVATOR_NO_MERGE; } -void elv_merged_request(request_queue_t *q, struct request *rq, int type) +void elv_merged_request(request_queue_t *q, struct request *rq) { elevator_t *e = q->elevator; if (e->ops->elevator_merged_fn) - e->ops->elevator_merged_fn(q, rq, type); - - if (type == ELEVATOR_BACK_MERGE) - elv_rqhash_reposition(q, rq); + e->ops->elevator_merged_fn(q, rq); q->last_merge = rq; } @@ -473,11 +294,8 @@ void elv_merge_requests(request_queue_t *q, struct request *rq, if (e->ops->elevator_merge_req_fn) e->ops->elevator_merge_req_fn(q, rq, next); - - elv_rqhash_reposition(q, rq); - elv_rqhash_del(q, next); - q->nr_sorted--; + q->last_merge = rq; } @@ -495,7 +313,7 @@ void elv_requeue_request(request_queue_t *q, struct request *rq) e->ops->elevator_deactivate_req_fn(q, rq); } - rq->cmd_flags &= ~REQ_STARTED; + rq->flags &= ~REQ_STARTED; elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE); } @@ -526,13 +344,13 @@ void elv_insert(request_queue_t *q, struct request *rq, int where) switch (where) { case ELEVATOR_INSERT_FRONT: - rq->cmd_flags |= REQ_SOFTBARRIER; + rq->flags |= REQ_SOFTBARRIER; list_add(&rq->queuelist, &q->queue_head); break; case ELEVATOR_INSERT_BACK: - rq->cmd_flags |= REQ_SOFTBARRIER; + rq->flags |= REQ_SOFTBARRIER; elv_drain_elevator(q); list_add_tail(&rq->queuelist, &q->queue_head); /* @@ -551,14 +369,10 @@ void elv_insert(request_queue_t *q, struct request *rq, int where) case ELEVATOR_INSERT_SORT: BUG_ON(!blk_fs_request(rq)); - rq->cmd_flags |= REQ_SORTED; + rq->flags |= REQ_SORTED; q->nr_sorted++; - if (rq_mergeable(rq)) { - elv_rqhash_add(q, rq); - if (!q->last_merge) - q->last_merge = rq; - } - + if (q->last_merge == NULL && rq_mergeable(rq)) + q->last_merge = rq; /* * Some ioscheds (cfq) run q->request_fn directly, so * rq cannot be accessed after calling @@ -573,7 +387,7 @@ void elv_insert(request_queue_t *q, struct request *rq, int where) * insertion; otherwise, requests should be requeued * in ordseq order. */ - rq->cmd_flags |= REQ_SOFTBARRIER; + rq->flags |= REQ_SOFTBARRIER; if (q->ordseq == 0) { list_add(&rq->queuelist, &q->queue_head); @@ -615,9 +429,9 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where, int plug) { if (q->ordcolor) - rq->cmd_flags |= REQ_ORDERED_COLOR; + rq->flags |= REQ_ORDERED_COLOR; - if (rq->cmd_flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { + if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { /* * toggle ordered color */ @@ -638,7 +452,7 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where, q->end_sector = rq_end_sector(rq); q->boundary_rq = rq; } - } else if (!(rq->cmd_flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT) + } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT) where = ELEVATOR_INSERT_BACK; if (plug) @@ -647,8 +461,6 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where, elv_insert(q, rq, where); } -EXPORT_SYMBOL(__elv_add_request); - void elv_add_request(request_queue_t *q, struct request *rq, int where, int plug) { @@ -659,8 +471,6 @@ void elv_add_request(request_queue_t *q, struct request *rq, int where, spin_unlock_irqrestore(q->queue_lock, flags); } -EXPORT_SYMBOL(elv_add_request); - static inline struct request *__elv_next_request(request_queue_t *q) { struct request *rq; @@ -683,7 +493,7 @@ struct request *elv_next_request(request_queue_t *q) int ret; while ((rq = __elv_next_request(q)) != NULL) { - if (!(rq->cmd_flags & REQ_STARTED)) { + if (!(rq->flags & REQ_STARTED)) { elevator_t *e = q->elevator; /* @@ -700,7 +510,7 @@ struct request *elv_next_request(request_queue_t *q) * it, a request that has been delayed should * not be passed by new incoming requests */ - rq->cmd_flags |= REQ_STARTED; + rq->flags |= REQ_STARTED; blk_add_trace_rq(q, rq, BLK_TA_ISSUE); } @@ -709,7 +519,7 @@ struct request *elv_next_request(request_queue_t *q) q->boundary_rq = NULL; } - if ((rq->cmd_flags & REQ_DONTPREP) || !q->prep_rq_fn) + if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn) break; ret = q->prep_rq_fn(q, rq); @@ -731,7 +541,7 @@ struct request *elv_next_request(request_queue_t *q) nr_bytes = rq->data_len; blkdev_dequeue_request(rq); - rq->cmd_flags |= REQ_QUIET; + rq->flags |= REQ_QUIET; end_that_request_chunk(rq, 0, nr_bytes); end_that_request_last(rq, 0); } else { @@ -744,12 +554,9 @@ struct request *elv_next_request(request_queue_t *q) return rq; } -EXPORT_SYMBOL(elv_next_request); - void elv_dequeue_request(request_queue_t *q, struct request *rq) { BUG_ON(list_empty(&rq->queuelist)); - BUG_ON(ELV_ON_HASH(rq)); list_del_init(&rq->queuelist); @@ -762,8 +569,6 @@ void elv_dequeue_request(request_queue_t *q, struct request *rq) q->in_flight++; } -EXPORT_SYMBOL(elv_dequeue_request); - int elv_queue_empty(request_queue_t *q) { elevator_t *e = q->elevator; @@ -777,8 +582,6 @@ int elv_queue_empty(request_queue_t *q) return 1; } -EXPORT_SYMBOL(elv_queue_empty); - struct request *elv_latter_request(request_queue_t *q, struct request *rq) { elevator_t *e = q->elevator; @@ -797,12 +600,13 @@ struct request *elv_former_request(request_queue_t *q, struct request *rq) return NULL; } -int elv_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask) +int elv_set_request(request_queue_t *q, struct request *rq, struct bio *bio, + gfp_t gfp_mask) { elevator_t *e = q->elevator; if (e->ops->elevator_set_req_fn) - return e->ops->elevator_set_req_fn(q, rq, gfp_mask); + return e->ops->elevator_set_req_fn(q, rq, bio, gfp_mask); rq->elevator_private = NULL; return 0; @@ -816,12 +620,12 @@ void elv_put_request(request_queue_t *q, struct request *rq) e->ops->elevator_put_req_fn(q, rq); } -int elv_may_queue(request_queue_t *q, int rw) +int elv_may_queue(request_queue_t *q, int rw, struct bio *bio) { elevator_t *e = q->elevator; if (e->ops->elevator_may_queue_fn) - return e->ops->elevator_may_queue_fn(q, rw); + return e->ops->elevator_may_queue_fn(q, rw, bio); return ELV_MQUEUE_MAY; } @@ -988,7 +792,7 @@ static int elevator_switch(request_queue_t *q, struct elevator_type *new_e) /* * Allocate new elevator */ - e = elevator_alloc(q, new_e); + e = elevator_alloc(new_e); if (!e) return 0; @@ -1104,26 +908,11 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name) return len; } -struct request *elv_rb_former_request(request_queue_t *q, struct request *rq) -{ - struct rb_node *rbprev = rb_prev(&rq->rb_node); - - if (rbprev) - return rb_entry_rq(rbprev); - - return NULL; -} - -EXPORT_SYMBOL(elv_rb_former_request); - -struct request *elv_rb_latter_request(request_queue_t *q, struct request *rq) -{ - struct rb_node *rbnext = rb_next(&rq->rb_node); - - if (rbnext) - return rb_entry_rq(rbnext); - - return NULL; -} - -EXPORT_SYMBOL(elv_rb_latter_request); +EXPORT_SYMBOL(elv_dispatch_sort); +EXPORT_SYMBOL(elv_add_request); +EXPORT_SYMBOL(__elv_add_request); +EXPORT_SYMBOL(elv_next_request); +EXPORT_SYMBOL(elv_dequeue_request); +EXPORT_SYMBOL(elv_queue_empty); +EXPORT_SYMBOL(elevator_exit); +EXPORT_SYMBOL(elevator_init); diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index 653919d50cd4..25d1f42568cc 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -295,15 +295,10 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data) static int __init genhd_device_init(void) { - int err; - bdev_map = kobj_map_init(base_probe, &block_subsys_lock); blk_dev_init(); - err = subsystem_register(&block_subsys); - if (err < 0) - printk(KERN_WARNING "%s: subsystem_register error: %d\n", - __FUNCTION__, err); - return err; + subsystem_register(&block_subsys); + return 0; } subsys_initcall(genhd_device_init); diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 83425fb3c8db..9c3a06bcb7ba 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -39,7 +39,6 @@ static void blk_unplug_timeout(unsigned long data); static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io); static void init_request_from_bio(struct request *req, struct bio *bio); static int __make_request(request_queue_t *q, struct bio *bio); -static struct io_context *current_io_context(gfp_t gfp_flags, int node); /* * For the allocated request tables @@ -278,19 +277,19 @@ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn) EXPORT_SYMBOL(blk_queue_make_request); -static void rq_init(request_queue_t *q, struct request *rq) +static inline void rq_init(request_queue_t *q, struct request *rq) { INIT_LIST_HEAD(&rq->queuelist); INIT_LIST_HEAD(&rq->donelist); rq->errors = 0; + rq->rq_status = RQ_ACTIVE; rq->bio = rq->biotail = NULL; - INIT_HLIST_NODE(&rq->hash); - RB_CLEAR_NODE(&rq->rb_node); rq->ioprio = 0; rq->buffer = NULL; rq->ref_count = 1; rq->q = q; + rq->waiting = NULL; rq->special = NULL; rq->data_len = 0; rq->data = NULL; @@ -383,8 +382,8 @@ unsigned blk_ordered_req_seq(struct request *rq) if (rq == &q->post_flush_rq) return QUEUE_ORDSEQ_POSTFLUSH; - if ((rq->cmd_flags & REQ_ORDERED_COLOR) == - (q->orig_bar_rq->cmd_flags & REQ_ORDERED_COLOR)) + if ((rq->flags & REQ_ORDERED_COLOR) == + (q->orig_bar_rq->flags & REQ_ORDERED_COLOR)) return QUEUE_ORDSEQ_DRAIN; else return QUEUE_ORDSEQ_DONE; @@ -447,11 +446,11 @@ static void queue_flush(request_queue_t *q, unsigned which) end_io = post_flush_end_io; } - rq->cmd_flags = REQ_HARDBARRIER; rq_init(q, rq); + rq->flags = REQ_HARDBARRIER; rq->elevator_private = NULL; - rq->elevator_private2 = NULL; rq->rq_disk = q->bar_rq.rq_disk; + rq->rl = NULL; rq->end_io = end_io; q->prepare_flush_fn(q, rq); @@ -472,13 +471,11 @@ static inline struct request *start_ordered(request_queue_t *q, blkdev_dequeue_request(rq); q->orig_bar_rq = rq; rq = &q->bar_rq; - rq->cmd_flags = 0; rq_init(q, rq); - if (bio_data_dir(q->orig_bar_rq->bio) == WRITE) - rq->cmd_flags |= REQ_RW; - rq->cmd_flags |= q->ordered & QUEUE_ORDERED_FUA ? REQ_FUA : 0; + rq->flags = bio_data_dir(q->orig_bar_rq->bio); + rq->flags |= q->ordered & QUEUE_ORDERED_FUA ? REQ_FUA : 0; rq->elevator_private = NULL; - rq->elevator_private2 = NULL; + rq->rl = NULL; init_request_from_bio(rq, q->orig_bar_rq->bio); rq->end_io = bar_end_io; @@ -590,8 +587,8 @@ static int flush_dry_bio_endio(struct bio *bio, unsigned int bytes, int error) return 0; } -static int ordered_bio_endio(struct request *rq, struct bio *bio, - unsigned int nbytes, int error) +static inline int ordered_bio_endio(struct request *rq, struct bio *bio, + unsigned int nbytes, int error) { request_queue_t *q = rq->q; bio_end_io_t *endio; @@ -1127,7 +1124,7 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq) } list_del_init(&rq->queuelist); - rq->cmd_flags &= ~REQ_QUEUED; + rq->flags &= ~REQ_QUEUED; rq->tag = -1; if (unlikely(bqt->tag_index[tag] == NULL)) @@ -1163,7 +1160,7 @@ int blk_queue_start_tag(request_queue_t *q, struct request *rq) struct blk_queue_tag *bqt = q->queue_tags; int tag; - if (unlikely((rq->cmd_flags & REQ_QUEUED))) { + if (unlikely((rq->flags & REQ_QUEUED))) { printk(KERN_ERR "%s: request %p for device [%s] already tagged %d", __FUNCTION__, rq, @@ -1171,18 +1168,13 @@ int blk_queue_start_tag(request_queue_t *q, struct request *rq) BUG(); } - /* - * Protect against shared tag maps, as we may not have exclusive - * access to the tag map. - */ - do { - tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth); - if (tag >= bqt->max_depth) - return 1; + tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth); + if (tag >= bqt->max_depth) + return 1; - } while (test_and_set_bit(tag, bqt->tag_map)); + __set_bit(tag, bqt->tag_map); - rq->cmd_flags |= REQ_QUEUED; + rq->flags |= REQ_QUEUED; rq->tag = tag; bqt->tag_index[tag] = rq; blkdev_dequeue_request(rq); @@ -1218,31 +1210,65 @@ void blk_queue_invalidate_tags(request_queue_t *q) printk(KERN_ERR "%s: bad tag found on list\n", __FUNCTION__); list_del_init(&rq->queuelist); - rq->cmd_flags &= ~REQ_QUEUED; + rq->flags &= ~REQ_QUEUED; } else blk_queue_end_tag(q, rq); - rq->cmd_flags &= ~REQ_STARTED; + rq->flags &= ~REQ_STARTED; __elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 0); } } EXPORT_SYMBOL(blk_queue_invalidate_tags); +static const char * const rq_flags[] = { + "REQ_RW", + "REQ_FAILFAST", + "REQ_SORTED", + "REQ_SOFTBARRIER", + "REQ_HARDBARRIER", + "REQ_FUA", + "REQ_CMD", + "REQ_NOMERGE", + "REQ_STARTED", + "REQ_DONTPREP", + "REQ_QUEUED", + "REQ_ELVPRIV", + "REQ_PC", + "REQ_BLOCK_PC", + "REQ_SENSE", + "REQ_FAILED", + "REQ_QUIET", + "REQ_SPECIAL", + "REQ_DRIVE_CMD", + "REQ_DRIVE_TASK", + "REQ_DRIVE_TASKFILE", + "REQ_PREEMPT", + "REQ_PM_SUSPEND", + "REQ_PM_RESUME", + "REQ_PM_SHUTDOWN", + "REQ_ORDERED_COLOR", +}; + void blk_dump_rq_flags(struct request *rq, char *msg) { int bit; - printk("%s: dev %s: type=%x, flags=%x\n", msg, - rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->cmd_type, - rq->cmd_flags); + printk("%s: dev %s: flags = ", msg, + rq->rq_disk ? rq->rq_disk->disk_name : "?"); + bit = 0; + do { + if (rq->flags & (1 << bit)) + printk("%s ", rq_flags[bit]); + bit++; + } while (bit < __REQ_NR_BITS); printk("\nsector %llu, nr/cnr %lu/%u\n", (unsigned long long)rq->sector, rq->nr_sectors, rq->current_nr_sectors); printk("bio %p, biotail %p, buffer %p, data %p, len %u\n", rq->bio, rq->biotail, rq->buffer, rq->data, rq->data_len); - if (blk_pc_request(rq)) { + if (rq->flags & (REQ_BLOCK_PC | REQ_PC)) { printk("cdb: "); for (bit = 0; bit < sizeof(rq->cmd); bit++) printk("%02x ", rq->cmd[bit]); @@ -1415,7 +1441,7 @@ static inline int ll_new_mergeable(request_queue_t *q, int nr_phys_segs = bio_phys_segments(q, bio); if (req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) { - req->cmd_flags |= REQ_NOMERGE; + req->flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; return 0; @@ -1438,7 +1464,7 @@ static inline int ll_new_hw_segment(request_queue_t *q, if (req->nr_hw_segments + nr_hw_segs > q->max_hw_segments || req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) { - req->cmd_flags |= REQ_NOMERGE; + req->flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; return 0; @@ -1465,7 +1491,7 @@ static int ll_back_merge_fn(request_queue_t *q, struct request *req, max_sectors = q->max_sectors; if (req->nr_sectors + bio_sectors(bio) > max_sectors) { - req->cmd_flags |= REQ_NOMERGE; + req->flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; return 0; @@ -1504,7 +1530,7 @@ static int ll_front_merge_fn(request_queue_t *q, struct request *req, if (req->nr_sectors + bio_sectors(bio) > max_sectors) { - req->cmd_flags |= REQ_NOMERGE; + req->flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; return 0; @@ -1821,7 +1847,8 @@ static void blk_release_queue(struct kobject *kobj) if (q->queue_tags) __blk_queue_free_tags(q); - blk_trace_shutdown(q); + if (q->blk_trace) + blk_trace_shutdown(q); kmem_cache_free(requestq_cachep, q); } @@ -2003,13 +2030,14 @@ EXPORT_SYMBOL(blk_get_queue); static inline void blk_free_request(request_queue_t *q, struct request *rq) { - if (rq->cmd_flags & REQ_ELVPRIV) + if (rq->flags & REQ_ELVPRIV) elv_put_request(q, rq); mempool_free(rq, q->rq.rq_pool); } -static struct request * -blk_alloc_request(request_queue_t *q, int rw, int priv, gfp_t gfp_mask) +static inline struct request * +blk_alloc_request(request_queue_t *q, int rw, struct bio *bio, + int priv, gfp_t gfp_mask) { struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask); @@ -2017,17 +2045,17 @@ blk_alloc_request(request_queue_t *q, int rw, int priv, gfp_t gfp_mask) return NULL; /* - * first three bits are identical in rq->cmd_flags and bio->bi_rw, + * first three bits are identical in rq->flags and bio->bi_rw, * see bio.h and blkdev.h */ - rq->cmd_flags = rw | REQ_ALLOCED; + rq->flags = rw; if (priv) { - if (unlikely(elv_set_request(q, rq, gfp_mask))) { + if (unlikely(elv_set_request(q, rq, bio, gfp_mask))) { mempool_free(rq, q->rq.rq_pool); return NULL; } - rq->cmd_flags |= REQ_ELVPRIV; + rq->flags |= REQ_ELVPRIV; } return rq; @@ -2114,13 +2142,13 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, struct io_context *ioc = NULL; int may_queue, priv; - may_queue = elv_may_queue(q, rw); + may_queue = elv_may_queue(q, rw, bio); if (may_queue == ELV_MQUEUE_NO) goto rq_starved; if (rl->count[rw]+1 >= queue_congestion_on_threshold(q)) { if (rl->count[rw]+1 >= q->nr_requests) { - ioc = current_io_context(GFP_ATOMIC, q->node); + ioc = current_io_context(GFP_ATOMIC); /* * The queue will fill after this allocation, so set * it as full, and mark this process as "batching". @@ -2162,7 +2190,7 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, spin_unlock_irq(q->queue_lock); - rq = blk_alloc_request(q, rw, priv, gfp_mask); + rq = blk_alloc_request(q, rw, bio, priv, gfp_mask); if (unlikely(!rq)) { /* * Allocation failed presumably due to memory. Undo anything @@ -2198,6 +2226,7 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, ioc->nr_batch_requests--; rq_init(q, rq); + rq->rl = rl; blk_add_trace_generic(q, bio, rw, BLK_TA_GETRQ); out: @@ -2240,7 +2269,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw, * up to a big batch of them for a small period time. * See ioc_batching, ioc_set_batching */ - ioc = current_io_context(GFP_NOIO, q->node); + ioc = current_io_context(GFP_NOIO); ioc_set_batching(q, ioc); spin_lock_irq(q->queue_lock); @@ -2271,25 +2300,6 @@ struct request *blk_get_request(request_queue_t *q, int rw, gfp_t gfp_mask) } EXPORT_SYMBOL(blk_get_request); -/** - * blk_start_queueing - initiate dispatch of requests to device - * @q: request queue to kick into gear - * - * This is basically a helper to remove the need to know whether a queue - * is plugged or not if someone just wants to initiate dispatch of requests - * for this queue. - * - * The queue lock must be held with interrupts disabled. - */ -void blk_start_queueing(request_queue_t *q) -{ - if (!blk_queue_plugged(q)) - q->request_fn(q); - else - __generic_unplug_device(q); -} -EXPORT_SYMBOL(blk_start_queueing); - /** * blk_requeue_request - put a request back on queue * @q: request queue where request should be inserted @@ -2342,8 +2352,7 @@ void blk_insert_request(request_queue_t *q, struct request *rq, * must not attempt merges on this) and that it acts as a soft * barrier */ - rq->cmd_type = REQ_TYPE_SPECIAL; - rq->cmd_flags |= REQ_SOFTBARRIER; + rq->flags |= REQ_SPECIAL | REQ_SOFTBARRIER; rq->special = data; @@ -2357,7 +2366,11 @@ void blk_insert_request(request_queue_t *q, struct request *rq, drive_stat_acct(rq, rq->nr_sectors, 1); __elv_add_request(q, rq, where, 0); - blk_start_queueing(q); + + if (blk_queue_plugged(q)) + __generic_unplug_device(q); + else + q->request_fn(q); spin_unlock_irqrestore(q->queue_lock, flags); } @@ -2546,7 +2559,7 @@ void blk_execute_rq_nowait(request_queue_t *q, struct gendisk *bd_disk, int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK; rq->rq_disk = bd_disk; - rq->cmd_flags |= REQ_NOMERGE; + rq->flags |= REQ_NOMERGE; rq->end_io = done; WARN_ON(irqs_disabled()); spin_lock_irq(q->queue_lock); @@ -2586,9 +2599,10 @@ int blk_execute_rq(request_queue_t *q, struct gendisk *bd_disk, rq->sense_len = 0; } - rq->end_io_data = &wait; + rq->waiting = &wait; blk_execute_rq_nowait(q, bd_disk, rq, at_head, blk_end_sync_rq); wait_for_completion(&wait); + rq->waiting = NULL; if (rq->errors) err = -EIO; @@ -2697,6 +2711,8 @@ EXPORT_SYMBOL_GPL(disk_round_stats); */ void __blk_put_request(request_queue_t *q, struct request *req) { + struct request_list *rl = req->rl; + if (unlikely(!q)) return; if (unlikely(--req->ref_count)) @@ -2704,16 +2720,18 @@ void __blk_put_request(request_queue_t *q, struct request *req) elv_completed_request(q, req); + req->rq_status = RQ_INACTIVE; + req->rl = NULL; + /* * Request may not have originated from ll_rw_blk. if not, * it didn't come out of our reserved rq pools */ - if (req->cmd_flags & REQ_ALLOCED) { + if (rl) { int rw = rq_data_dir(req); - int priv = req->cmd_flags & REQ_ELVPRIV; + int priv = req->flags & REQ_ELVPRIV; BUG_ON(!list_empty(&req->queuelist)); - BUG_ON(!hlist_unhashed(&req->hash)); blk_free_request(q, req); freed_request(q, rw, priv); @@ -2747,9 +2765,9 @@ EXPORT_SYMBOL(blk_put_request); */ void blk_end_sync_rq(struct request *rq, int error) { - struct completion *waiting = rq->end_io_data; + struct completion *waiting = rq->waiting; - rq->end_io_data = NULL; + rq->waiting = NULL; __blk_put_request(rq->q, rq); /* @@ -2812,7 +2830,7 @@ static int attempt_merge(request_queue_t *q, struct request *req, if (rq_data_dir(req) != rq_data_dir(next) || req->rq_disk != next->rq_disk - || next->special) + || next->waiting || next->special) return 0; /* @@ -2873,24 +2891,22 @@ static inline int attempt_front_merge(request_queue_t *q, struct request *rq) static void init_request_from_bio(struct request *req, struct bio *bio) { - req->cmd_type = REQ_TYPE_FS; + req->flags |= REQ_CMD; /* * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST) */ if (bio_rw_ahead(bio) || bio_failfast(bio)) - req->cmd_flags |= REQ_FAILFAST; + req->flags |= REQ_FAILFAST; /* * REQ_BARRIER implies no merging, but lets make it explicit */ if (unlikely(bio_barrier(bio))) - req->cmd_flags |= (REQ_HARDBARRIER | REQ_NOMERGE); + req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE); if (bio_sync(bio)) - req->cmd_flags |= REQ_RW_SYNC; - if (bio_rw_meta(bio)) - req->cmd_flags |= REQ_RW_META; + req->flags |= REQ_RW_SYNC; req->errors = 0; req->hard_sector = req->sector = bio->bi_sector; @@ -2899,6 +2915,7 @@ static void init_request_from_bio(struct request *req, struct bio *bio) req->nr_phys_segments = bio_phys_segments(req->q, bio); req->nr_hw_segments = bio_hw_segments(req->q, bio); req->buffer = bio_data(bio); /* see ->buffer comment above */ + req->waiting = NULL; req->bio = req->biotail = bio; req->ioprio = bio_prio(bio); req->rq_disk = bio->bi_bdev->bd_disk; @@ -2908,11 +2925,17 @@ static void init_request_from_bio(struct request *req, struct bio *bio) static int __make_request(request_queue_t *q, struct bio *bio) { struct request *req; - int el_ret, nr_sectors, barrier, err; - const unsigned short prio = bio_prio(bio); - const int sync = bio_sync(bio); + int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync; + unsigned short prio; + sector_t sector; + sector = bio->bi_sector; nr_sectors = bio_sectors(bio); + cur_nr_sectors = bio_cur_sectors(bio); + prio = bio_prio(bio); + + rw = bio_data_dir(bio); + sync = bio_sync(bio); /* * low level driver can indicate that it wants pages above a @@ -2921,6 +2944,8 @@ static int __make_request(request_queue_t *q, struct bio *bio) */ blk_queue_bounce(q, &bio); + spin_lock_prefetch(q->queue_lock); + barrier = bio_barrier(bio); if (unlikely(barrier) && (q->next_ordered == QUEUE_ORDERED_NONE)) { err = -EOPNOTSUPP; @@ -2948,7 +2973,7 @@ static int __make_request(request_queue_t *q, struct bio *bio) req->ioprio = ioprio_best(req->ioprio, prio); drive_stat_acct(req, nr_sectors, 0); if (!attempt_back_merge(q, req)) - elv_merged_request(q, req, el_ret); + elv_merged_request(q, req); goto out; case ELEVATOR_FRONT_MERGE: @@ -2968,14 +2993,14 @@ static int __make_request(request_queue_t *q, struct bio *bio) * not touch req->buffer either... */ req->buffer = bio_data(bio); - req->current_nr_sectors = bio_cur_sectors(bio); - req->hard_cur_sectors = req->current_nr_sectors; - req->sector = req->hard_sector = bio->bi_sector; + req->current_nr_sectors = cur_nr_sectors; + req->hard_cur_sectors = cur_nr_sectors; + req->sector = req->hard_sector = sector; req->nr_sectors = req->hard_nr_sectors += nr_sectors; req->ioprio = ioprio_best(req->ioprio, prio); drive_stat_acct(req, nr_sectors, 0); if (!attempt_front_merge(q, req)) - elv_merged_request(q, req, el_ret); + elv_merged_request(q, req); goto out; /* ELV_NO_MERGE: elevator says don't/can't merge. */ @@ -2988,7 +3013,7 @@ static int __make_request(request_queue_t *q, struct bio *bio) * Grab a free request. This is might sleep but can not fail. * Returns with the queue unlocked. */ - req = get_request_wait(q, bio_data_dir(bio), bio); + req = get_request_wait(q, rw, bio); /* * After dropping the lock and possibly sleeping here, our request @@ -3282,7 +3307,7 @@ static int __end_that_request_first(struct request *req, int uptodate, req->errors = 0; if (!uptodate) { - if (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET)) + if (blk_fs_request(req) && !(req->flags & REQ_QUIET)) printk("end_request: I/O error, dev %s, sector %llu\n", req->rq_disk ? req->rq_disk->disk_name : "?", (unsigned long long)req->sector); @@ -3545,8 +3570,8 @@ EXPORT_SYMBOL(end_request); void blk_rq_bio_prep(request_queue_t *q, struct request *rq, struct bio *bio) { - /* first two bits are identical in rq->cmd_flags and bio->bi_rw */ - rq->cmd_flags |= (bio->bi_rw & 3); + /* first two bits are identical in rq->flags and bio->bi_rw */ + rq->flags |= (bio->bi_rw & 3); rq->nr_phys_segments = bio_phys_segments(q, bio); rq->nr_hw_segments = bio_hw_segments(q, bio); @@ -3634,22 +3659,25 @@ EXPORT_SYMBOL(put_io_context); /* Called by the exitting task */ void exit_io_context(void) { + unsigned long flags; struct io_context *ioc; struct cfq_io_context *cic; + local_irq_save(flags); task_lock(current); ioc = current->io_context; current->io_context = NULL; + ioc->task = NULL; task_unlock(current); + local_irq_restore(flags); - ioc->task = NULL; if (ioc->aic && ioc->aic->exit) ioc->aic->exit(ioc->aic); if (ioc->cic_root.rb_node != NULL) { cic = rb_entry(rb_first(&ioc->cic_root), struct cfq_io_context, rb_node); cic->exit(ioc); } - + put_io_context(ioc); } @@ -3661,7 +3689,7 @@ void exit_io_context(void) * but since the current task itself holds a reference, the context can be * used in general code, so long as it stays within `current` context. */ -static struct io_context *current_io_context(gfp_t gfp_flags, int node) +struct io_context *current_io_context(gfp_t gfp_flags) { struct task_struct *tsk = current; struct io_context *ret; @@ -3670,11 +3698,11 @@ static struct io_context *current_io_context(gfp_t gfp_flags, int node) if (likely(ret)) return ret; - ret = kmem_cache_alloc_node(iocontext_cachep, gfp_flags, node); + ret = kmem_cache_alloc(iocontext_cachep, gfp_flags); if (ret) { atomic_set(&ret->refcount, 1); ret->task = current; - ret->ioprio_changed = 0; + ret->set_ioprio = NULL; ret->last_waited = jiffies; /* doesn't matter... */ ret->nr_batch_requests = 0; /* because this is 0 */ ret->aic = NULL; @@ -3694,10 +3722,10 @@ EXPORT_SYMBOL(current_io_context); * * This is always called in the context of the task which submitted the I/O. */ -struct io_context *get_io_context(gfp_t gfp_flags, int node) +struct io_context *get_io_context(gfp_t gfp_flags) { struct io_context *ret; - ret = current_io_context(gfp_flags, node); + ret = current_io_context(gfp_flags); if (likely(ret)) atomic_inc(&ret->refcount); return ret; @@ -3810,6 +3838,9 @@ queue_ra_store(struct request_queue *q, const char *page, size_t count) ssize_t ret = queue_var_store(&ra_kb, page, count); spin_lock_irq(q->queue_lock); + if (ra_kb > (q->max_sectors >> 1)) + ra_kb = (q->max_sectors >> 1); + q->backing_dev_info.ra_pages = ra_kb >> (PAGE_CACHE_SHIFT - 10); spin_unlock_irq(q->queue_lock); diff --git a/trunk/block/noop-iosched.c b/trunk/block/noop-iosched.c index 79af43179421..56a7c620574f 100644 --- a/trunk/block/noop-iosched.c +++ b/trunk/block/noop-iosched.c @@ -69,7 +69,7 @@ static void *noop_init_queue(request_queue_t *q, elevator_t *e) { struct noop_data *nd; - nd = kmalloc_node(sizeof(*nd), GFP_KERNEL, q->node); + nd = kmalloc(sizeof(*nd), GFP_KERNEL); if (!nd) return NULL; INIT_LIST_HEAD(&nd->queue); diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index 2dc326421a24..b33eda26e205 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -294,7 +294,7 @@ static int sg_io(struct file *file, request_queue_t *q, rq->sense = sense; rq->sense_len = 0; - rq->cmd_type = REQ_TYPE_BLOCK_PC; + rq->flags |= REQ_BLOCK_PC; bio = rq->bio; /* @@ -470,7 +470,7 @@ int sg_scsi_ioctl(struct file *file, struct request_queue *q, memset(sense, 0, sizeof(sense)); rq->sense = sense; rq->sense_len = 0; - rq->cmd_type = REQ_TYPE_BLOCK_PC; + rq->flags |= REQ_BLOCK_PC; blk_execute_rq(q, disk, rq, 0); @@ -502,7 +502,7 @@ static int __blk_send_generic(request_queue_t *q, struct gendisk *bd_disk, int c int err; rq = blk_get_request(q, WRITE, __GFP_WAIT); - rq->cmd_type = REQ_TYPE_BLOCK_PC; + rq->flags |= REQ_BLOCK_PC; rq->data = NULL; rq->data_len = 0; rq->timeout = BLK_DEFAULT_TIMEOUT; diff --git a/trunk/drivers/acorn/char/i2c.c b/trunk/drivers/acorn/char/i2c.c index bdb9c8b78ed8..c26c08b36829 100644 --- a/trunk/drivers/acorn/char/i2c.c +++ b/trunk/drivers/acorn/char/i2c.c @@ -308,6 +308,7 @@ static struct i2c_algo_bit_data ioc_data = { .getsda = ioc_getsda, .getscl = ioc_getscl, .udelay = 80, + .mdelay = 80, .timeout = 100 }; diff --git a/trunk/drivers/acpi/acpi_memhotplug.c b/trunk/drivers/acpi/acpi_memhotplug.c index 98099de59b45..1dda370f402b 100644 --- a/trunk/drivers/acpi/acpi_memhotplug.c +++ b/trunk/drivers/acpi/acpi_memhotplug.c @@ -238,10 +238,6 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) num_enabled++; continue; } - - if (node < 0) - node = memory_add_physaddr_to_nid(info->start_addr); - result = add_memory(node, info->start_addr, info->length); if (result) continue; diff --git a/trunk/drivers/acpi/i2c_ec.c b/trunk/drivers/acpi/i2c_ec.c index 6342e612c203..6809c283ec58 100644 --- a/trunk/drivers/acpi/i2c_ec.c +++ b/trunk/drivers/acpi/i2c_ec.c @@ -293,7 +293,7 @@ static u32 acpi_ec_smb_func(struct i2c_adapter *adapter) I2C_FUNC_SMBUS_I2C_BLOCK | I2C_FUNC_SMBUS_HWPEC_CALC); } -static const struct i2c_algorithm acpi_ec_smbus_algorithm = { +static struct i2c_algorithm acpi_ec_smbus_algorithm = { .smbus_xfer = acpi_ec_smb_access, .functionality = acpi_ec_smb_func, }; diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 20beea778ea2..507f051d1cef 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -1079,7 +1079,7 @@ acpi_status acpi_os_purge_cache(acpi_cache_t * cache) acpi_status acpi_os_delete_cache(acpi_cache_t * cache) { - kmem_cache_destroy(cache); + (void)kmem_cache_destroy(cache); return (AE_OK); } diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 0a395fca843b..71066066d626 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -38,7 +38,6 @@ #include #include #include /* need_resched() */ -#include #include #include @@ -454,8 +453,7 @@ static void acpi_processor_idle(void) */ if (cx->promotion.state && ((cx->promotion.state - pr->power.states) <= max_cstate)) { - if (sleep_ticks > cx->promotion.threshold.ticks && - cx->promotion.state->latency <= system_latency_constraint()) { + if (sleep_ticks > cx->promotion.threshold.ticks) { cx->promotion.count++; cx->demotion.count = 0; if (cx->promotion.count >= @@ -496,10 +494,8 @@ static void acpi_processor_idle(void) end: /* * Demote if current state exceeds max_cstate - * or if the latency of the current state is unacceptable */ - if ((pr->power.state - pr->power.states) > max_cstate || - pr->power.state->latency > system_latency_constraint()) { + if ((pr->power.state - pr->power.states) > max_cstate) { if (cx->demotion.state) next_state = cx->demotion.state; } @@ -1013,11 +1009,9 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) seq_printf(seq, "active state: C%zd\n" "max_cstate: C%d\n" - "bus master activity: %08x\n" - "maximum allowed latency: %d usec\n", + "bus master activity: %08x\n", pr->power.state ? pr->power.state - pr->power.states : 0, - max_cstate, (unsigned)pr->power.bm_activity, - system_latency_constraint()); + max_cstate, (unsigned)pr->power.bm_activity); seq_puts(seq, "states:\n"); @@ -1083,28 +1077,6 @@ static const struct file_operations acpi_processor_power_fops = { .release = single_release, }; -static void smp_callback(void *v) -{ - /* we already woke the CPU up, nothing more to do */ -} - -/* - * This function gets called when a part of the kernel has a new latency - * requirement. This means we need to get all processors out of their C-state, - * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that - * wakes them all right up. - */ -static int acpi_processor_latency_notify(struct notifier_block *b, - unsigned long l, void *v) -{ - smp_call_function(smp_callback, NULL, 0, 1); - return NOTIFY_OK; -} - -static struct notifier_block acpi_processor_latency_notifier = { - .notifier_call = acpi_processor_latency_notify, -}; - int acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device) { @@ -1121,7 +1093,6 @@ int acpi_processor_power_init(struct acpi_processor *pr, "ACPI: processor limited to max C-state %d\n", max_cstate); first_run++; - register_latency_notifier(&acpi_processor_latency_notifier); } if (!pr) @@ -1193,7 +1164,6 @@ int acpi_processor_power_exit(struct acpi_processor *pr, * copies of pm_idle before proceeding. */ cpu_idle_wait(); - unregister_latency_notifier(&acpi_processor_latency_notifier); } return 0; diff --git a/trunk/drivers/ata/Kconfig b/trunk/drivers/ata/Kconfig index 3f4aa0c99ee4..99837d932f36 100644 --- a/trunk/drivers/ata/Kconfig +++ b/trunk/drivers/ata/Kconfig @@ -311,7 +311,7 @@ config PATA_JMICRON config PATA_LEGACY tristate "Legacy ISA PATA support (Experimental)" - depends on ISA && EXPERIMENTAL + depends on PCI && EXPERIMENTAL help This option enables support for ISA/VLB bus legacy PATA ports and allows them to be accessed via the new ATA layer. @@ -400,7 +400,6 @@ config PATA_PDC_OLD config PATA_QDI tristate "QDI VLB PATA support" - depends on ISA help Support for QDI 6500 and 6580 PATA controllers on VESA local bus. diff --git a/trunk/drivers/ata/ata_generic.c b/trunk/drivers/ata/ata_generic.c index 377425e71391..1d1c30a2fcd0 100644 --- a/trunk/drivers/ata/ata_generic.c +++ b/trunk/drivers/ata/ata_generic.c @@ -143,7 +143,7 @@ static struct ata_port_operations generic_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, diff --git a/trunk/drivers/ata/ata_piix.c b/trunk/drivers/ata/ata_piix.c index 5719704eb0ee..ffa111eea9da 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -643,9 +643,11 @@ static int piix_pata_prereset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); - if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) - return -ENOENT; - + if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) { + ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n"); + ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; + return 0; + } ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index b4abd6850367..753b0152afd1 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -5453,11 +5453,6 @@ int ata_device_add(const struct ata_probe_ent *ent) int rc; DPRINTK("ENTER\n"); - - if (ent->irq == 0) { - dev_printk(KERN_ERR, dev, "is not available: No interrupt assigned.\n"); - return 0; - } /* alloc a container for our list of ATA ports (buses) */ host = kzalloc(sizeof(struct ata_host) + (ent->n_ports * sizeof(void *)), GFP_KERNEL); diff --git a/trunk/drivers/ata/libata-eh.c b/trunk/drivers/ata/libata-eh.c index 02b2b2787d9b..3fa80f09f2ae 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -1515,11 +1515,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, if (prereset) { rc = prereset(ap); if (rc) { - if (rc == -ENOENT) { - ata_port_printk(ap, KERN_DEBUG, "port disabled. ignoring.\n"); - ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; - } else - ata_port_printk(ap, KERN_ERR, + ata_port_printk(ap, KERN_ERR, "prereset failed (errno=%d)\n", rc); return rc; } diff --git a/trunk/drivers/ata/libata-sff.c b/trunk/drivers/ata/libata-sff.c index 08b3a407473e..688bb55e197a 100644 --- a/trunk/drivers/ata/libata-sff.c +++ b/trunk/drivers/ata/libata-sff.c @@ -881,7 +881,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, probe_ent->private_data = port[0]->private_data; if (port_mask & ATA_PORT_PRIMARY) { - probe_ent->irq = ATA_PRIMARY_IRQ; + probe_ent->irq = 14; probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD; probe_ent->port[0].altstatus_addr = probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL; @@ -896,9 +896,9 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, if (port_mask & ATA_PORT_SECONDARY) { if (probe_ent->irq) - probe_ent->irq2 = ATA_SECONDARY_IRQ; + probe_ent->irq2 = 15; else - probe_ent->irq = ATA_SECONDARY_IRQ; + probe_ent->irq = 15; probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD; probe_ent->port[1].altstatus_addr = probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL; diff --git a/trunk/drivers/ata/pata_ali.c b/trunk/drivers/ata/pata_ali.c index 87af3b5861ab..8448ee6e0eed 100644 --- a/trunk/drivers/ata/pata_ali.c +++ b/trunk/drivers/ata/pata_ali.c @@ -369,7 +369,7 @@ static struct ata_port_operations ali_early_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -410,7 +410,7 @@ static struct ata_port_operations ali_20_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -448,7 +448,7 @@ static struct ata_port_operations ali_c2_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -485,7 +485,7 @@ static struct ata_port_operations ali_c5_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_amd.c b/trunk/drivers/ata/pata_amd.c index 599ee266722c..3293cf9a7eb5 100644 --- a/trunk/drivers/ata/pata_amd.c +++ b/trunk/drivers/ata/pata_amd.c @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_amd" -#define DRV_VERSION "0.2.4" +#define DRV_VERSION "0.2.3" /** * timing_setup - shared timing computation and load @@ -137,8 +137,11 @@ static int amd_pre_reset(struct ata_port *ap) struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 ata66; - if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no])) - return -ENOENT; + if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } pci_read_config_byte(pdev, 0x42, &ata66); if (ata66 & bitmask[ap->port_no]) @@ -164,9 +167,11 @@ static int amd_early_pre_reset(struct ata_port *ap) { 0x40, 1, 0x01, 0x01 } }; - if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no])) - return -ENOENT; - + if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } /* No host side cable detection */ ap->cbl = ATA_CBL_PATA80; return ata_std_prereset(ap); @@ -257,8 +262,12 @@ static int nv_pre_reset(struct ata_port *ap) { u8 ata66; u16 udma; - if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no])) - return -ENOENT; + if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } + pci_read_config_byte(pdev, 0x52, &ata66); if (ata66 & bitmask[ap->port_no]) @@ -359,7 +368,7 @@ static struct ata_port_operations amd33_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -393,7 +402,7 @@ static struct ata_port_operations amd66_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -427,7 +436,7 @@ static struct ata_port_operations amd100_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -461,7 +470,7 @@ static struct ata_port_operations amd133_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -495,7 +504,7 @@ static struct ata_port_operations nv100_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -529,7 +538,7 @@ static struct ata_port_operations nv133_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_artop.c b/trunk/drivers/ata/pata_artop.c index c4ccb75a4f1d..d6ef3bf1bac7 100644 --- a/trunk/drivers/ata/pata_artop.c +++ b/trunk/drivers/ata/pata_artop.c @@ -28,7 +28,7 @@ #include #define DRV_NAME "pata_artop" -#define DRV_VERSION "0.4.2" +#define DRV_VERSION "0.4.1" /* * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we @@ -47,9 +47,11 @@ static int artop6210_pre_reset(struct ata_port *ap) { 0x4AU, 1U, 0x04UL, 0x04UL }, /* port 1 */ }; - if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no])) - return -ENOENT; - + if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -88,9 +90,11 @@ static int artop6260_pre_reset(struct ata_port *ap) u8 tmp; /* Odd numbered device ids are the units with enable bits (the -R cards) */ - if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no])) - return -ENOENT; - + if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } pci_read_config_byte(pdev, 0x49, &tmp); if (tmp & (1 >> ap->port_no)) ap->cbl = ATA_CBL_PATA40; @@ -340,7 +344,7 @@ static const struct ata_port_operations artop6210_ops = { .bmdma_status = ata_bmdma_status, .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -375,6 +379,8 @@ static const struct ata_port_operations artop6260_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, + .eng_timeout = ata_eng_timeout, + .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, diff --git a/trunk/drivers/ata/pata_atiixp.c b/trunk/drivers/ata/pata_atiixp.c index 6c2269b6bd3c..3f78a1e54a75 100644 --- a/trunk/drivers/ata/pata_atiixp.c +++ b/trunk/drivers/ata/pata_atiixp.c @@ -22,7 +22,7 @@ #include #define DRV_NAME "pata_atiixp" -#define DRV_VERSION "0.4.3" +#define DRV_VERSION "0.4.2" enum { ATIIXP_IDE_PIO_TIMING = 0x40, @@ -41,9 +41,11 @@ static int atiixp_pre_reset(struct ata_port *ap) { 0x48, 1, 0x08, 0x00 } }; - if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no])) - return -ENOENT; - + if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } ap->cbl = ATA_CBL_PATA80; return ata_std_prereset(ap); } @@ -242,7 +244,7 @@ static struct ata_port_operations atiixp_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_cmd64x.c b/trunk/drivers/ata/pata_cmd64x.c index e92b0ef43ec5..abf1bb7bd322 100644 --- a/trunk/drivers/ata/pata_cmd64x.c +++ b/trunk/drivers/ata/pata_cmd64x.c @@ -301,7 +301,7 @@ static struct ata_port_operations cmd64x_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -335,7 +335,7 @@ static struct ata_port_operations cmd646r1_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -369,7 +369,7 @@ static struct ata_port_operations cmd648_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_cs5520.c b/trunk/drivers/ata/pata_cs5520.c index a6c6cebd0dae..792ce4828510 100644 --- a/trunk/drivers/ata/pata_cs5520.c +++ b/trunk/drivers/ata/pata_cs5520.c @@ -193,6 +193,8 @@ static struct ata_port_operations cs5520_port_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, + .eng_timeout = ata_eng_timeout, + .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, diff --git a/trunk/drivers/ata/pata_cs5530.c b/trunk/drivers/ata/pata_cs5530.c index 7bba4d954e9c..f3d8a3bc1e78 100644 --- a/trunk/drivers/ata/pata_cs5530.c +++ b/trunk/drivers/ata/pata_cs5530.c @@ -207,7 +207,7 @@ static struct ata_port_operations cs5530_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = cs5530_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_cs5535.c b/trunk/drivers/ata/pata_cs5535.c index d64fcdceaf01..69d6b4258724 100644 --- a/trunk/drivers/ata/pata_cs5535.c +++ b/trunk/drivers/ata/pata_cs5535.c @@ -211,7 +211,7 @@ static struct ata_port_operations cs5535_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_cypress.c b/trunk/drivers/ata/pata_cypress.c index dfa5ac539048..fd55474e0d15 100644 --- a/trunk/drivers/ata/pata_cypress.c +++ b/trunk/drivers/ata/pata_cypress.c @@ -162,7 +162,7 @@ static struct ata_port_operations cy82c693_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_efar.c b/trunk/drivers/ata/pata_efar.c index 95cd1ca181f5..c30bc181304f 100644 --- a/trunk/drivers/ata/pata_efar.c +++ b/trunk/drivers/ata/pata_efar.c @@ -22,7 +22,7 @@ #include #define DRV_NAME "pata_efar" -#define DRV_VERSION "0.4.2" +#define DRV_VERSION "0.4.1" /** * efar_pre_reset - check for 40/80 pin @@ -42,9 +42,11 @@ static int efar_pre_reset(struct ata_port *ap) struct pci_dev *pdev = to_pci_dev(ap->host->dev); u8 tmp; - if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->port_no])) - return -ENOENT; - + if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } pci_read_config_byte(pdev, 0x47, &tmp); if (tmp & (2 >> ap->port_no)) ap->cbl = ATA_CBL_PATA40; @@ -261,6 +263,8 @@ static const struct ata_port_operations efar_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, + .eng_timeout = ata_eng_timeout, + .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, diff --git a/trunk/drivers/ata/pata_hpt366.c b/trunk/drivers/ata/pata_hpt366.c index cf656ecbe507..94bb1dfc3f19 100644 --- a/trunk/drivers/ata/pata_hpt366.c +++ b/trunk/drivers/ata/pata_hpt366.c @@ -360,7 +360,7 @@ static struct ata_port_operations hpt366_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_hpt37x.c b/trunk/drivers/ata/pata_hpt37x.c index 10318c0012ef..532a7928f803 100644 --- a/trunk/drivers/ata/pata_hpt37x.c +++ b/trunk/drivers/ata/pata_hpt37x.c @@ -793,7 +793,7 @@ static struct ata_port_operations hpt370_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -832,7 +832,7 @@ static struct ata_port_operations hpt370a_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -872,7 +872,7 @@ static struct ata_port_operations hpt372_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -912,7 +912,7 @@ static struct ata_port_operations hpt374_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_hpt3x2n.c b/trunk/drivers/ata/pata_hpt3x2n.c index 5c5d4f6ab901..06c8db079b91 100644 --- a/trunk/drivers/ata/pata_hpt3x2n.c +++ b/trunk/drivers/ata/pata_hpt3x2n.c @@ -372,7 +372,7 @@ static struct ata_port_operations hpt3x2n_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = hpt3x2n_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_hpt3x3.c b/trunk/drivers/ata/pata_hpt3x3.c index 1f084ab1ccc6..152770133ab1 100644 --- a/trunk/drivers/ata/pata_hpt3x3.c +++ b/trunk/drivers/ata/pata_hpt3x3.c @@ -145,7 +145,7 @@ static struct ata_port_operations hpt3x3_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_isapnp.c b/trunk/drivers/ata/pata_isapnp.c index 640b8b0954f5..73948c8b7270 100644 --- a/trunk/drivers/ata/pata_isapnp.c +++ b/trunk/drivers/ata/pata_isapnp.c @@ -52,7 +52,7 @@ static struct ata_port_operations isapnp_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_it821x.c b/trunk/drivers/ata/pata_it821x.c index 82a46ff40000..af39097d8081 100644 --- a/trunk/drivers/ata/pata_it821x.c +++ b/trunk/drivers/ata/pata_it821x.c @@ -703,7 +703,7 @@ static struct ata_port_operations it821x_smart_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = it821x_smart_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -739,7 +739,7 @@ static struct ata_port_operations it821x_passthru_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = it821x_passthru_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_clear = ata_bmdma_irq_clear, diff --git a/trunk/drivers/ata/pata_jmicron.c b/trunk/drivers/ata/pata_jmicron.c index be3a866b111f..6832a643a9eb 100644 --- a/trunk/drivers/ata/pata_jmicron.c +++ b/trunk/drivers/ata/pata_jmicron.c @@ -51,7 +51,7 @@ static int jmicron_pre_reset(struct ata_port *ap) /* Check if our port is enabled */ pci_read_config_dword(pdev, 0x40, &control); if ((control & port_mask) == 0) - return -ENOENT; + return 0; /* There are two basic mappings. One has the two SATA ports merged as master/slave and the secondary as PATA, the other has only the @@ -164,7 +164,8 @@ static const struct ata_port_operations jmicron_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, - /* IRQ-related hooks */ + /* Timeout handling. Special recovery hooks here */ + .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, diff --git a/trunk/drivers/ata/pata_legacy.c b/trunk/drivers/ata/pata_legacy.c index 10231ef731d1..ad37c220bb2c 100644 --- a/trunk/drivers/ata/pata_legacy.c +++ b/trunk/drivers/ata/pata_legacy.c @@ -161,7 +161,7 @@ static struct ata_port_operations simple_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer_noirq, .irq_handler = ata_interrupt, @@ -186,7 +186,7 @@ static struct ata_port_operations legacy_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer_noirq, .irq_handler = ata_interrupt, @@ -296,7 +296,7 @@ static struct ata_port_operations pdc20230_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = pdc_data_xfer_vlb, .irq_handler = ata_interrupt, @@ -348,7 +348,7 @@ static struct ata_port_operations ht6560a_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, /* Check vlb/noirq */ .irq_handler = ata_interrupt, @@ -411,7 +411,7 @@ static struct ata_port_operations ht6560b_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, /* FIXME: Check 32bit and noirq */ .irq_handler = ata_interrupt, @@ -529,7 +529,7 @@ static struct ata_port_operations opti82c611a_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -659,7 +659,7 @@ static struct ata_port_operations opti82c46x_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = opti82c46x_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_mpiix.c b/trunk/drivers/ata/pata_mpiix.c index 3c65393c1f01..1958c4ed09a8 100644 --- a/trunk/drivers/ata/pata_mpiix.c +++ b/trunk/drivers/ata/pata_mpiix.c @@ -18,7 +18,7 @@ * The driver conciously keeps this logic internally to avoid pushing quirky * PATA history into the clean libata layer. * - * Thinkpad specific note: If you boot an MPIIX using a thinkpad with a PCMCIA + * Thinkpad specific note: If you boot an MPIIX using thinkpad with a PCMCIA * hard disk present this driver will not detect it. This is not a bug. In this * configuration the secondary port of the MPIIX is disabled and the addresses * are decoded by the PCMCIA bridge and therefore are for a generic IDE driver @@ -35,7 +35,7 @@ #include #define DRV_NAME "pata_mpiix" -#define DRV_VERSION "0.7.2" +#define DRV_VERSION "0.7.1" enum { IDETIM = 0x6C, /* IDE control register */ @@ -54,8 +54,11 @@ static int mpiix_pre_reset(struct ata_port *ap) { 0x6F, 1, 0x80, 0x80 } }; - if (!pci_test_config_bits(pdev, &mpiix_enable_bits[ap->port_no])) - return -ENOENT; + if (!pci_test_config_bits(pdev, &mpiix_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } diff --git a/trunk/drivers/ata/pata_netcell.c b/trunk/drivers/ata/pata_netcell.c index 76eb9c90bee1..16cb254cb973 100644 --- a/trunk/drivers/ata/pata_netcell.c +++ b/trunk/drivers/ata/pata_netcell.c @@ -90,7 +90,8 @@ static const struct ata_port_operations netcell_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, - /* IRQ-related hooks */ + /* Timeout handling. Special recovery hooks here */ + .eng_timeout = ata_eng_timeout, .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, diff --git a/trunk/drivers/ata/pata_ns87410.c b/trunk/drivers/ata/pata_ns87410.c index 2005a95f48f6..93d6646d2954 100644 --- a/trunk/drivers/ata/pata_ns87410.c +++ b/trunk/drivers/ata/pata_ns87410.c @@ -45,8 +45,11 @@ static int ns87410_pre_reset(struct ata_port *ap) { 0x47, 1, 0x08, 0x08 } }; - if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->port_no])) - return -ENOENT; + if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -176,7 +179,7 @@ static struct ata_port_operations ns87410_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ns87410_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_oldpiix.c b/trunk/drivers/ata/pata_oldpiix.c index 31a285ca88dc..04c618a2664b 100644 --- a/trunk/drivers/ata/pata_oldpiix.c +++ b/trunk/drivers/ata/pata_oldpiix.c @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_oldpiix" -#define DRV_VERSION "0.5.2" +#define DRV_VERSION "0.5.1" /** * oldpiix_pre_reset - probe begin @@ -42,8 +42,11 @@ static int oldpiix_pre_reset(struct ata_port *ap) { 0x43U, 1U, 0x80UL, 0x80UL }, /* port 1 */ }; - if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->port_no])) - return -ENOENT; + if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } diff --git a/trunk/drivers/ata/pata_opti.c b/trunk/drivers/ata/pata_opti.c index 57fe21f3a975..c3d01325e0e2 100644 --- a/trunk/drivers/ata/pata_opti.c +++ b/trunk/drivers/ata/pata_opti.c @@ -34,7 +34,7 @@ #include #define DRV_NAME "pata_opti" -#define DRV_VERSION "0.2.5" +#define DRV_VERSION "0.2.4" enum { READ_REG = 0, /* index of Read cycle timing register */ @@ -59,9 +59,11 @@ static int opti_pre_reset(struct ata_port *ap) { 0x40, 1, 0x08, 0x00 } }; - if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->port_no])) - return -ENOENT; - + if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -227,7 +229,7 @@ static struct ata_port_operations opti_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_optidma.c b/trunk/drivers/ata/pata_optidma.c index 7296a20cd107..177a455f4251 100644 --- a/trunk/drivers/ata/pata_optidma.c +++ b/trunk/drivers/ata/pata_optidma.c @@ -33,7 +33,7 @@ #include #define DRV_NAME "pata_optidma" -#define DRV_VERSION "0.2.2" +#define DRV_VERSION "0.2.1" enum { READ_REG = 0, /* index of Read cycle timing register */ @@ -59,9 +59,11 @@ static int optidma_pre_reset(struct ata_port *ap) 0x40, 1, 0x08, 0x00 }; - if (ap->port_no && !pci_test_config_bits(pdev, &optidma_enable_bits)) - return -ENOENT; - + if (ap->port_no && !pci_test_config_bits(pdev, &optidma_enable_bits)) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -386,7 +388,7 @@ static struct ata_port_operations optidma_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -421,7 +423,7 @@ static struct ata_port_operations optiplus_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_pcmcia.c b/trunk/drivers/ata/pata_pcmcia.c index cb501e145a42..62b25cda409b 100644 --- a/trunk/drivers/ata/pata_pcmcia.c +++ b/trunk/drivers/ata/pata_pcmcia.c @@ -87,7 +87,7 @@ static struct ata_port_operations pcmcia_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer_noirq, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_pdc2027x.c b/trunk/drivers/ata/pata_pdc2027x.c index bd4ed6734edc..31ab9c886209 100644 --- a/trunk/drivers/ata/pata_pdc2027x.c +++ b/trunk/drivers/ata/pata_pdc2027x.c @@ -36,7 +36,7 @@ #include #define DRV_NAME "pata_pdc2027x" -#define DRV_VERSION "0.74-ac5" +#define DRV_VERSION "0.74-ac3" #undef PDC_DEBUG #ifdef PDC_DEBUG @@ -311,8 +311,10 @@ static inline int pdc2027x_port_enabled(struct ata_port *ap) static int pdc2027x_prereset(struct ata_port *ap) { /* Check whether port enabled */ - if (!pdc2027x_port_enabled(ap)) - return -ENOENT; + if (!pdc2027x_port_enabled(ap)) { + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } pdc2027x_cbl_detect(ap); return ata_std_prereset(ap); } diff --git a/trunk/drivers/ata/pata_qdi.c b/trunk/drivers/ata/pata_qdi.c index 7977f471d5e9..35cfdf0ac3f0 100644 --- a/trunk/drivers/ata/pata_qdi.c +++ b/trunk/drivers/ata/pata_qdi.c @@ -184,7 +184,7 @@ static struct ata_port_operations qdi6500_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = qdi_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = qdi_data_xfer, .irq_handler = ata_interrupt, @@ -212,7 +212,7 @@ static struct ata_port_operations qdi6580_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = qdi_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = qdi_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_radisys.c b/trunk/drivers/ata/pata_radisys.c index c20bcf43ed6d..277f8411b521 100644 --- a/trunk/drivers/ata/pata_radisys.c +++ b/trunk/drivers/ata/pata_radisys.c @@ -255,6 +255,8 @@ static const struct ata_port_operations radisys_pata_ops = { .qc_issue = radisys_qc_issue_prot, .data_xfer = ata_pio_data_xfer, + .eng_timeout = ata_eng_timeout, + .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, diff --git a/trunk/drivers/ata/pata_rz1000.c b/trunk/drivers/ata/pata_rz1000.c index eccc6fd45032..3c6d84fd4312 100644 --- a/trunk/drivers/ata/pata_rz1000.c +++ b/trunk/drivers/ata/pata_rz1000.c @@ -112,7 +112,7 @@ static struct ata_port_operations rz1000_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .freeze = ata_bmdma_freeze, diff --git a/trunk/drivers/ata/pata_sc1200.c b/trunk/drivers/ata/pata_sc1200.c index 107e6cd3dc0d..4166c1a8a9e8 100644 --- a/trunk/drivers/ata/pata_sc1200.c +++ b/trunk/drivers/ata/pata_sc1200.c @@ -217,7 +217,7 @@ static struct ata_port_operations sc1200_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = sc1200_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_serverworks.c b/trunk/drivers/ata/pata_serverworks.c index a5c8d7e121d1..af456113c55d 100644 --- a/trunk/drivers/ata/pata_serverworks.c +++ b/trunk/drivers/ata/pata_serverworks.c @@ -41,7 +41,7 @@ #include #define DRV_NAME "pata_serverworks" -#define DRV_VERSION "0.3.7" +#define DRV_VERSION "0.3.6" #define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */ #define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */ @@ -128,7 +128,7 @@ static struct sv_cable_table cable_detect[] = { { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_DELL, dell_cable }, { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_VENDOR_ID_DELL, dell_cable }, { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_VENDOR_ID_SUN, sun_cable }, - { PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, osb4_cable }, + { PCI_DEVICE_ID_SERVERWORKS_OSB4, PCI_ANY_ID, osb4_cable }, { PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, csb_cable }, { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, csb_cable }, { PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, csb_cable }, @@ -352,12 +352,10 @@ static struct ata_port_operations serverworks_osb4_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, - .irq_clear = ata_bmdma_irq_clear, - .port_start = ata_port_start, .port_stop = ata_port_stop, .host_stop = ata_host_stop @@ -387,12 +385,10 @@ static struct ata_port_operations serverworks_csb_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, - .irq_clear = ata_bmdma_irq_clear, - .port_start = ata_port_start, .port_stop = ata_port_stop, .host_stop = ata_host_stop diff --git a/trunk/drivers/ata/pata_sil680.c b/trunk/drivers/ata/pata_sil680.c index c8b2e26db70d..8f7db9638d0a 100644 --- a/trunk/drivers/ata/pata_sil680.c +++ b/trunk/drivers/ata/pata_sil680.c @@ -251,7 +251,7 @@ static struct ata_port_operations sil680_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_sis.c b/trunk/drivers/ata/pata_sis.c index 17791e2785f9..2e555168b431 100644 --- a/trunk/drivers/ata/pata_sis.c +++ b/trunk/drivers/ata/pata_sis.c @@ -34,7 +34,7 @@ #include #define DRV_NAME "pata_sis" -#define DRV_VERSION "0.4.4" +#define DRV_VERSION "0.4.3" struct sis_chipset { u16 device; /* PCI host ID */ @@ -74,9 +74,11 @@ static int sis_133_pre_reset(struct ata_port *ap) struct pci_dev *pdev = to_pci_dev(ap->host->dev); u16 tmp; - if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) - return -ENOENT; - + if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } /* The top bit of this register is the cable detect bit */ pci_read_config_word(pdev, 0x50 + 2 * ap->port_no, &tmp); if (tmp & 0x8000) @@ -573,6 +575,8 @@ static const struct ata_port_operations sis_133_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, + .eng_timeout = ata_eng_timeout, + .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, @@ -606,6 +610,8 @@ static const struct ata_port_operations sis_133_early_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, + .eng_timeout = ata_eng_timeout, + .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, @@ -640,6 +646,8 @@ static const struct ata_port_operations sis_100_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, + .eng_timeout = ata_eng_timeout, + .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, @@ -673,6 +681,8 @@ static const struct ata_port_operations sis_66_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, + .eng_timeout = ata_eng_timeout, + .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, @@ -706,6 +716,8 @@ static const struct ata_port_operations sis_old_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, + .eng_timeout = ata_eng_timeout, + .irq_handler = ata_interrupt, .irq_clear = ata_bmdma_irq_clear, diff --git a/trunk/drivers/ata/pata_sl82c105.c b/trunk/drivers/ata/pata_sl82c105.c index 5b762acc5687..f8499786917a 100644 --- a/trunk/drivers/ata/pata_sl82c105.c +++ b/trunk/drivers/ata/pata_sl82c105.c @@ -19,7 +19,7 @@ #include #define DRV_NAME "pata_sl82c105" -#define DRV_VERSION "0.2.3" +#define DRV_VERSION "0.2.2" enum { /* @@ -49,8 +49,11 @@ static int sl82c105_pre_reset(struct ata_port *ap) }; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no])) - return -ENOENT; + if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no])) { + ata_port_disable(ap); + dev_printk(KERN_INFO, &pdev->dev, "port disabled. ignoring.\n"); + return 0; + } ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -261,7 +264,7 @@ static struct ata_port_operations sl82c105_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_triflex.c b/trunk/drivers/ata/pata_triflex.c index a954ed93a40c..36f788728f3f 100644 --- a/trunk/drivers/ata/pata_triflex.c +++ b/trunk/drivers/ata/pata_triflex.c @@ -46,13 +46,13 @@ #define DRV_VERSION "0.2.5" /** - * triflex_prereset - probe begin + * triflex_probe_init - probe begin * @ap: ATA port * * Set up cable type and use generic probe init */ -static int triflex_prereset(struct ata_port *ap) +static int triflex_probe_init(struct ata_port *ap) { static const struct pci_bits triflex_enable_bits[] = { { 0x80, 1, 0x01, 0x01 }, @@ -61,8 +61,11 @@ static int triflex_prereset(struct ata_port *ap) struct pci_dev *pdev = to_pci_dev(ap->host->dev); - if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no])) - return -ENOENT; + if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -71,7 +74,7 @@ static int triflex_prereset(struct ata_port *ap) static void triflex_error_handler(struct ata_port *ap) { - ata_bmdma_drive_eh(ap, triflex_prereset, ata_std_softreset, NULL, ata_std_postreset); + ata_bmdma_drive_eh(ap, triflex_probe_init, ata_std_softreset, NULL, ata_std_postreset); } /** @@ -218,7 +221,7 @@ static struct ata_port_operations triflex_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/pata_via.c b/trunk/drivers/ata/pata_via.c index 7b5dd2343b9a..1b2ff133b163 100644 --- a/trunk/drivers/ata/pata_via.c +++ b/trunk/drivers/ata/pata_via.c @@ -60,7 +60,7 @@ #include #define DRV_NAME "pata_via" -#define DRV_VERSION "0.1.14" +#define DRV_VERSION "0.1.13" /* * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx @@ -155,8 +155,11 @@ static int via_pre_reset(struct ata_port *ap) struct pci_dev *pdev = to_pci_dev(ap->host->dev); - if (!pci_test_config_bits(pdev, &via_enable_bits[ap->port_no])) - return -ENOENT; + if (!pci_test_config_bits(pdev, &via_enable_bits[ap->port_no])) { + ata_port_disable(ap); + printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); + return 0; + } } if ((config->flags & VIA_UDMA) >= VIA_UDMA_66) @@ -322,7 +325,7 @@ static struct ata_port_operations via_port_ops = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer, .irq_handler = ata_interrupt, @@ -357,7 +360,7 @@ static struct ata_port_operations via_port_ops_noirq = { .qc_prep = ata_qc_prep, .qc_issue = ata_qc_issue_prot, - + .eng_timeout = ata_eng_timeout, .data_xfer = ata_pio_data_xfer_noirq, .irq_handler = ata_interrupt, diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index c01496df4a99..fdce6e07ecd2 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -463,7 +463,6 @@ static const struct ata_port_operations mv_iie_ops = { .qc_prep = mv_qc_prep_iie, .qc_issue = mv_qc_issue, - .data_xfer = ata_mmio_data_xfer, .eng_timeout = mv_eng_timeout, diff --git a/trunk/drivers/base/Makefile b/trunk/drivers/base/Makefile index 7bbb9eeda235..b539e5e75b56 100644 --- a/trunk/drivers/base/Makefile +++ b/trunk/drivers/base/Makefile @@ -8,7 +8,7 @@ obj-y += power/ obj-$(CONFIG_ISA) += isa.o obj-$(CONFIG_FW_LOADER) += firmware_class.o obj-$(CONFIG_NUMA) += node.o -obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o +obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o obj-$(CONFIG_SMP) += topology.o obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o diff --git a/trunk/drivers/base/base.h b/trunk/drivers/base/base.h index d26644a59537..c3b8dc98b8a7 100644 --- a/trunk/drivers/base/base.h +++ b/trunk/drivers/base/base.h @@ -16,7 +16,7 @@ extern int cpu_dev_init(void); extern int attribute_container_init(void); extern int bus_add_device(struct device * dev); -extern int bus_attach_device(struct device * dev); +extern void bus_attach_device(struct device * dev); extern void bus_remove_device(struct device * dev); extern struct bus_type *get_bus(struct bus_type * bus); extern void put_bus(struct bus_type * bus); diff --git a/trunk/drivers/base/bus.c b/trunk/drivers/base/bus.c index 12173d16bea7..2e954d07175a 100644 --- a/trunk/drivers/base/bus.c +++ b/trunk/drivers/base/bus.c @@ -371,20 +371,12 @@ int bus_add_device(struct device * dev) if (bus) { pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id); error = device_add_attrs(bus, dev); - if (error) - goto out; - error = sysfs_create_link(&bus->devices.kobj, - &dev->kobj, dev->bus_id); - if (error) - goto out; - error = sysfs_create_link(&dev->kobj, - &dev->bus->subsys.kset.kobj, "subsystem"); - if (error) - goto out; - error = sysfs_create_link(&dev->kobj, - &dev->bus->subsys.kset.kobj, "bus"); + if (!error) { + sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); + sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "subsystem"); + sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus"); + } } -out: return error; } @@ -392,24 +384,16 @@ int bus_add_device(struct device * dev) * bus_attach_device - add device to bus * @dev: device tried to attach to a driver * - * - Add device to bus's list of devices. * - Try to attach to driver. */ -int bus_attach_device(struct device * dev) +void bus_attach_device(struct device * dev) { - struct bus_type *bus = dev->bus; - int ret = 0; + struct bus_type * bus = dev->bus; if (bus) { - dev->is_registered = 1; - ret = device_attach(dev); - if (ret >= 0) { - klist_add_tail(&dev->knode_bus, &bus->klist_devices); - ret = 0; - } else - dev->is_registered = 0; + device_attach(dev); + klist_add_tail(&dev->knode_bus, &bus->klist_devices); } - return ret; } /** @@ -428,8 +412,7 @@ void bus_remove_device(struct device * dev) sysfs_remove_link(&dev->kobj, "bus"); sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); device_remove_attrs(dev->bus, dev); - dev->is_registered = 0; - klist_del(&dev->knode_bus); + klist_remove(&dev->knode_bus); pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); device_release_driver(dev); put_bus(dev->bus); @@ -472,17 +455,10 @@ static void driver_remove_attrs(struct bus_type * bus, struct device_driver * dr * Thanks to drivers making their tables __devinit, we can't allow manual * bind and unbind from userspace unless CONFIG_HOTPLUG is enabled. */ -static int __must_check add_bind_files(struct device_driver *drv) +static void add_bind_files(struct device_driver *drv) { - int ret; - - ret = driver_create_file(drv, &driver_attr_unbind); - if (ret == 0) { - ret = driver_create_file(drv, &driver_attr_bind); - if (ret) - driver_remove_file(drv, &driver_attr_unbind); - } - return ret; + driver_create_file(drv, &driver_attr_unbind); + driver_create_file(drv, &driver_attr_bind); } static void remove_bind_files(struct device_driver *drv) @@ -491,7 +467,7 @@ static void remove_bind_files(struct device_driver *drv) driver_remove_file(drv, &driver_attr_unbind); } #else -static inline int add_bind_files(struct device_driver *drv) { return 0; } +static inline void add_bind_files(struct device_driver *drv) {} static inline void remove_bind_files(struct device_driver *drv) {} #endif @@ -500,7 +476,7 @@ static inline void remove_bind_files(struct device_driver *drv) {} * @drv: driver. * */ -int bus_add_driver(struct device_driver *drv) +int bus_add_driver(struct device_driver * drv) { struct bus_type * bus = get_bus(drv->bus); int error = 0; @@ -508,39 +484,27 @@ int bus_add_driver(struct device_driver *drv) if (bus) { pr_debug("bus %s: add driver %s\n", bus->name, drv->name); error = kobject_set_name(&drv->kobj, "%s", drv->name); - if (error) - goto out_put_bus; + if (error) { + put_bus(bus); + return error; + } drv->kobj.kset = &bus->drivers; - if ((error = kobject_register(&drv->kobj))) - goto out_put_bus; + if ((error = kobject_register(&drv->kobj))) { + put_bus(bus); + return error; + } - error = driver_attach(drv); - if (error) - goto out_unregister; + driver_attach(drv); klist_add_tail(&drv->knode_bus, &bus->klist_drivers); module_add_driver(drv->owner, drv); - error = driver_add_attrs(bus, drv); - if (error) { - /* How the hell do we get out of this pickle? Give up */ - printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", - __FUNCTION__, drv->name); - } - error = add_bind_files(drv); - if (error) { - /* Ditto */ - printk(KERN_ERR "%s: add_bind_files(%s) failed\n", - __FUNCTION__, drv->name); - } + driver_add_attrs(bus, drv); + add_bind_files(drv); } return error; -out_unregister: - kobject_unregister(&drv->kobj); -out_put_bus: - put_bus(bus); - return error; } + /** * bus_remove_driver - delete driver from bus's knowledge. * @drv: driver. @@ -566,21 +530,16 @@ void bus_remove_driver(struct device_driver * drv) /* Helper for bus_rescan_devices's iter */ -static int __must_check bus_rescan_devices_helper(struct device *dev, - void *data) +static int bus_rescan_devices_helper(struct device *dev, void *data) { - int ret = 0; - if (!dev->driver) { if (dev->parent) /* Needed for USB */ down(&dev->parent->sem); - ret = device_attach(dev); + device_attach(dev); if (dev->parent) up(&dev->parent->sem); - if (ret > 0) - ret = 0; } - return ret < 0 ? ret : 0; + return 0; } /** @@ -591,9 +550,9 @@ static int __must_check bus_rescan_devices_helper(struct device *dev, * attached and rescan it against existing drivers to see if it matches * any by calling device_attach() for the unbound devices. */ -int bus_rescan_devices(struct bus_type * bus) +void bus_rescan_devices(struct bus_type * bus) { - return bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); + bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); } /** @@ -605,7 +564,7 @@ int bus_rescan_devices(struct bus_type * bus) * to use if probing criteria changed during a devices lifetime and * driver attachment should change accordingly. */ -int device_reprobe(struct device *dev) +void device_reprobe(struct device *dev) { if (dev->driver) { if (dev->parent) /* Needed for USB */ @@ -614,14 +573,14 @@ int device_reprobe(struct device *dev) if (dev->parent) up(&dev->parent->sem); } - return bus_rescan_devices_helper(dev, NULL); + + bus_rescan_devices_helper(dev, NULL); } EXPORT_SYMBOL_GPL(device_reprobe); -struct bus_type *get_bus(struct bus_type *bus) +struct bus_type * get_bus(struct bus_type * bus) { - return bus ? container_of(subsys_get(&bus->subsys), - struct bus_type, subsys) : NULL; + return bus ? container_of(subsys_get(&bus->subsys), struct bus_type, subsys) : NULL; } void put_bus(struct bus_type * bus) @@ -696,6 +655,22 @@ static void klist_devices_put(struct klist_node *n) put_device(dev); } +static void klist_drivers_get(struct klist_node *n) +{ + struct device_driver *drv = container_of(n, struct device_driver, + knode_bus); + + get_driver(drv); +} + +static void klist_drivers_put(struct klist_node *n) +{ + struct device_driver *drv = container_of(n, struct device_driver, + knode_bus); + + put_driver(drv); +} + /** * bus_register - register a bus with the system. * @bus: bus. @@ -731,7 +706,7 @@ int bus_register(struct bus_type * bus) goto bus_drivers_fail; klist_init(&bus->klist_devices, klist_devices_get, klist_devices_put); - klist_init(&bus->klist_drivers, NULL, NULL); + klist_init(&bus->klist_drivers, klist_drivers_get, klist_drivers_put); bus_add_attrs(bus); pr_debug("bus type '%s' registered\n", bus->name); diff --git a/trunk/drivers/base/class.c b/trunk/drivers/base/class.c index b32b77ff2dcd..de8908320f23 100644 --- a/trunk/drivers/base/class.c +++ b/trunk/drivers/base/class.c @@ -19,8 +19,6 @@ #include #include "base.h" -extern struct subsystem devices_subsys; - #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) #define to_class(obj) container_of(obj, struct class, subsys.kset.kobj) @@ -199,7 +197,7 @@ static int class_device_create_uevent(struct class_device *class_dev, * Note, the pointer created here is to be destroyed when finished by * making a call to class_destroy(). */ -struct class *class_create(struct module *owner, const char *name) +struct class *class_create(struct module *owner, char *name) { struct class *cls; int retval; @@ -228,7 +226,7 @@ struct class *class_create(struct module *owner, const char *name) /** * class_destroy - destroys a struct class structure - * @cls: pointer to the struct class that is to be destroyed + * @cs: pointer to the struct class that is to be destroyed * * Note, the pointer to be destroyed must have been created with a call * to class_create(). @@ -363,7 +361,7 @@ static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); if (class_dev->dev) { - /* add device, backing this class device (deprecated) */ + /* add physical device, backing this device */ struct device *dev = class_dev->dev; char *path = kobject_get_path(&dev->kobj, GFP_KERNEL); @@ -658,9 +656,9 @@ int class_device_register(struct class_device *class_dev) /** * class_device_create - creates a class device and registers it with sysfs - * @cls: pointer to the struct class that this device should be registered to. + * @cs: pointer to the struct class that this device should be registered to. * @parent: pointer to the parent struct class_device of this new device, if any. - * @devt: the dev_t for the char device to be added. + * @dev: the dev_t for the char device to be added. * @device: a pointer to a struct device that is assiociated with this class device. * @fmt: string for the class device's name * @@ -681,8 +679,7 @@ int class_device_register(struct class_device *class_dev) struct class_device *class_device_create(struct class *cls, struct class_device *parent, dev_t devt, - struct device *device, - const char *fmt, ...) + struct device *device, char *fmt, ...) { va_list args; struct class_device *class_dev = NULL; @@ -766,7 +763,7 @@ void class_device_unregister(struct class_device *class_dev) /** * class_device_destroy - removes a class device that was created with class_device_create() * @cls: the pointer to the struct class that this device was registered * with. - * @devt: the dev_t of the device that was previously registered. + * @dev: the dev_t of the device that was previously registered. * * This call unregisters and cleans up a class device that was created with a * call to class_device_create() @@ -842,7 +839,6 @@ int class_interface_register(struct class_interface *class_intf) { struct class *parent; struct class_device *class_dev; - struct device *dev; if (!class_intf || !class_intf->class) return -ENODEV; @@ -857,10 +853,6 @@ int class_interface_register(struct class_interface *class_intf) list_for_each_entry(class_dev, &parent->children, node) class_intf->add(class_dev, class_intf); } - if (class_intf->add_dev) { - list_for_each_entry(dev, &parent->devices, node) - class_intf->add_dev(dev, class_intf); - } up(&parent->sem); return 0; @@ -870,7 +862,6 @@ void class_interface_unregister(struct class_interface *class_intf) { struct class * parent = class_intf->class; struct class_device *class_dev; - struct device *dev; if (!parent) return; @@ -881,31 +872,12 @@ void class_interface_unregister(struct class_interface *class_intf) list_for_each_entry(class_dev, &parent->children, node) class_intf->remove(class_dev, class_intf); } - if (class_intf->remove_dev) { - list_for_each_entry(dev, &parent->devices, node) - class_intf->remove_dev(dev, class_intf); - } up(&parent->sem); class_put(parent); } -int virtual_device_parent(struct device *dev) -{ - if (!dev->class) - return -ENODEV; - - if (!dev->class->virtual_dir) { - static struct kobject *virtual_dir = NULL; - - if (!virtual_dir) - virtual_dir = kobject_add_dir(&devices_subsys.kset.kobj, "virtual"); - dev->class->virtual_dir = kobject_add_dir(virtual_dir, dev->class->name); - } - dev->kobj.parent = dev->class->virtual_dir; - return 0; -} int __init classes_init(void) { diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index b224bb43ff63..be6b5bc0677d 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -3,8 +3,6 @@ * * Copyright (c) 2002-3 Patrick Mochel * Copyright (c) 2002-3 Open Source Development Labs - * Copyright (c) 2006 Greg Kroah-Hartman - * Copyright (c) 2006 Novell, Inc. * * This file is released under the GPLv2 * @@ -94,8 +92,6 @@ static void device_release(struct kobject * kobj) if (dev->release) dev->release(dev); - else if (dev->class && dev->class->dev_release) - dev->class->dev_release(dev); else { printk(KERN_ERR "Device '%s' does not have a release() function, " "it is broken and must be fixed.\n", @@ -153,21 +149,17 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, "MINOR=%u", MINOR(dev->devt)); } - /* add bus name (same as SUBSYSTEM, deprecated) */ + /* add bus name of physical device */ if (dev->bus) add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, "PHYSDEVBUS=%s", dev->bus->name); - /* add driver name (PHYSDEV* values are deprecated)*/ - if (dev->driver) { - add_uevent_var(envp, num_envp, &i, - buffer, buffer_size, &length, - "DRIVER=%s", dev->driver->name); + /* add driver name of physical device */ + if (dev->driver) add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, "PHYSDEVDRIVER=%s", dev->driver->name); - } /* terminate, set to next free slot, shrink available space */ envp[i] = NULL; @@ -185,15 +177,6 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp, } } - if (dev->class && dev->class->dev_uevent) { - /* have the class specific function add its stuff */ - retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size); - if (retval) { - pr_debug("%s - dev_uevent() returned %d\n", - __FUNCTION__, retval); - } - } - return retval; } @@ -210,72 +193,6 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, return count; } -static int device_add_groups(struct device *dev) -{ - int i; - int error = 0; - - if (dev->groups) { - for (i = 0; dev->groups[i]; i++) { - error = sysfs_create_group(&dev->kobj, dev->groups[i]); - if (error) { - while (--i >= 0) - sysfs_remove_group(&dev->kobj, dev->groups[i]); - goto out; - } - } - } -out: - return error; -} - -static void device_remove_groups(struct device *dev) -{ - int i; - if (dev->groups) { - for (i = 0; dev->groups[i]; i++) { - sysfs_remove_group(&dev->kobj, dev->groups[i]); - } - } -} - -static int device_add_attrs(struct device *dev) -{ - struct class *class = dev->class; - int error = 0; - int i; - - if (!class) - return 0; - - if (class->dev_attrs) { - for (i = 0; attr_name(class->dev_attrs[i]); i++) { - error = device_create_file(dev, &class->dev_attrs[i]); - if (error) - break; - } - } - if (error) - while (--i >= 0) - device_remove_file(dev, &class->dev_attrs[i]); - return error; -} - -static void device_remove_attrs(struct device *dev) -{ - struct class *class = dev->class; - int i; - - if (!class) - return; - - if (class->dev_attrs) { - for (i = 0; attr_name(class->dev_attrs[i]); i++) - device_remove_file(dev, &class->dev_attrs[i]); - } -} - - static ssize_t show_dev(struct device *dev, struct device_attribute *attr, char *buf) { @@ -319,32 +236,6 @@ void device_remove_file(struct device * dev, struct device_attribute * attr) } } -/** - * device_create_bin_file - create sysfs binary attribute file for device. - * @dev: device. - * @attr: device binary attribute descriptor. - */ -int device_create_bin_file(struct device *dev, struct bin_attribute *attr) -{ - int error = -EINVAL; - if (dev) - error = sysfs_create_bin_file(&dev->kobj, attr); - return error; -} -EXPORT_SYMBOL_GPL(device_create_bin_file); - -/** - * device_remove_bin_file - remove sysfs binary attribute file - * @dev: device. - * @attr: device binary attribute descriptor. - */ -void device_remove_bin_file(struct device *dev, struct bin_attribute *attr) -{ - if (dev) - sysfs_remove_bin_file(&dev->kobj, attr); -} -EXPORT_SYMBOL_GPL(device_remove_bin_file); - static void klist_children_get(struct klist_node *n) { struct device *dev = container_of(n, struct device, knode_parent); @@ -398,20 +289,12 @@ int device_add(struct device *dev) { struct device *parent = NULL; char *class_name = NULL; - struct class_interface *class_intf; int error = -EINVAL; dev = get_device(dev); if (!dev || !strlen(dev->bus_id)) goto Error; - /* if this is a class device, and has no parent, create one */ - if ((dev->class) && (dev->parent == NULL)) { - error = virtual_device_parent(dev); - if (error) - goto Error; - } - parent = get_device(dev->parent); pr_debug("DEV: registering device: ID = '%s'\n", dev->bus_id); @@ -424,10 +307,6 @@ int device_add(struct device *dev) if ((error = kobject_add(&dev->kobj))) goto Error; - /* notify platform of device entry */ - if (platform_notify) - platform_notify(dev); - dev->uevent_attr.attr.name = "uevent"; dev->uevent_attr.attr.mode = S_IWUSR; if (dev->driver) @@ -461,17 +340,12 @@ int device_add(struct device *dev) "subsystem"); sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj, dev->bus_id); - if (parent) { - sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); - class_name = make_class_name(dev->class->name, &dev->kobj); - sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name); - } + + sysfs_create_link(&dev->kobj, &dev->parent->kobj, "device"); + class_name = make_class_name(dev->class->name, &dev->kobj); + sysfs_create_link(&dev->parent->kobj, &dev->kobj, class_name); } - if ((error = device_add_attrs(dev))) - goto AttrsError; - if ((error = device_add_groups(dev))) - goto GroupError; if ((error = device_pm_add(dev))) goto PMError; if ((error = bus_add_device(dev))) @@ -482,16 +356,15 @@ int device_add(struct device *dev) klist_add_tail(&dev->knode_parent, &parent->klist_children); if (dev->class) { - down(&dev->class->sem); /* tie the class to the device */ + down(&dev->class->sem); list_add_tail(&dev->node, &dev->class->devices); - - /* notify any interfaces that the device is here */ - list_for_each_entry(class_intf, &dev->class->interfaces, node) - if (class_intf->add_dev) - class_intf->add_dev(dev, class_intf); up(&dev->class->sem); } + + /* notify platform of device entry */ + if (platform_notify) + platform_notify(dev); Done: kfree(class_name); put_device(dev); @@ -499,10 +372,6 @@ int device_add(struct device *dev) BusError: device_pm_remove(dev); PMError: - device_remove_groups(dev); - GroupError: - device_remove_attrs(dev); - AttrsError: if (dev->devt_attr) { device_remove_file(dev, dev->devt_attr); kfree(dev->devt_attr); @@ -580,7 +449,6 @@ void device_del(struct device * dev) { struct device * parent = dev->parent; char *class_name = NULL; - struct class_interface *class_intf; if (parent) klist_del(&dev->knode_parent); @@ -590,23 +458,14 @@ void device_del(struct device * dev) sysfs_remove_link(&dev->kobj, "subsystem"); sysfs_remove_link(&dev->class->subsys.kset.kobj, dev->bus_id); class_name = make_class_name(dev->class->name, &dev->kobj); - if (parent) { - sysfs_remove_link(&dev->kobj, "device"); - sysfs_remove_link(&dev->parent->kobj, class_name); - } + sysfs_remove_link(&dev->kobj, "device"); + sysfs_remove_link(&dev->parent->kobj, class_name); kfree(class_name); down(&dev->class->sem); - /* notify any interfaces that the device is now gone */ - list_for_each_entry(class_intf, &dev->class->interfaces, node) - if (class_intf->remove_dev) - class_intf->remove_dev(dev, class_intf); - /* remove the device from the class list */ list_del_init(&dev->node); up(&dev->class->sem); } device_remove_file(dev, &dev->uevent_attr); - device_remove_groups(dev); - device_remove_attrs(dev); /* Notify the platform of the removal, in case they * need to do anything... @@ -720,7 +579,7 @@ static void device_create_release(struct device *dev) * been created with a call to class_create(). */ struct device *device_create(struct class *class, struct device *parent, - dev_t devt, const char *fmt, ...) + dev_t devt, char *fmt, ...) { va_list args; struct device *dev = NULL; @@ -728,6 +587,10 @@ struct device *device_create(struct class *class, struct device *parent, if (class == NULL || IS_ERR(class)) goto error; + if (parent == NULL) { + printk(KERN_WARNING "%s does not work yet for NULL parents\n", __FUNCTION__); + goto error; + } dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { @@ -781,58 +644,3 @@ void device_destroy(struct class *class, dev_t devt) device_unregister(dev); } EXPORT_SYMBOL_GPL(device_destroy); - -/** - * device_rename - renames a device - * @dev: the pointer to the struct device to be renamed - * @new_name: the new name of the device - */ -int device_rename(struct device *dev, char *new_name) -{ - char *old_class_name = NULL; - char *new_class_name = NULL; - char *old_symlink_name = NULL; - int error; - - dev = get_device(dev); - if (!dev) - return -EINVAL; - - pr_debug("DEVICE: renaming '%s' to '%s'\n", dev->bus_id, new_name); - - if ((dev->class) && (dev->parent)) - old_class_name = make_class_name(dev->class->name, &dev->kobj); - - if (dev->class) { - old_symlink_name = kmalloc(BUS_ID_SIZE, GFP_KERNEL); - if (!old_symlink_name) - return -ENOMEM; - strlcpy(old_symlink_name, dev->bus_id, BUS_ID_SIZE); - } - - strlcpy(dev->bus_id, new_name, BUS_ID_SIZE); - - error = kobject_rename(&dev->kobj, new_name); - - if (old_class_name) { - new_class_name = make_class_name(dev->class->name, &dev->kobj); - if (new_class_name) { - sysfs_create_link(&dev->parent->kobj, &dev->kobj, - new_class_name); - sysfs_remove_link(&dev->parent->kobj, old_class_name); - } - } - if (dev->class) { - sysfs_remove_link(&dev->class->subsys.kset.kobj, - old_symlink_name); - sysfs_create_link(&dev->class->subsys.kset.kobj, &dev->kobj, - dev->bus_id); - } - put_device(dev); - - kfree(old_class_name); - kfree(new_class_name); - kfree(old_symlink_name); - - return error; -} diff --git a/trunk/drivers/base/dd.c b/trunk/drivers/base/dd.c index b5f43c3e44fa..889c71111239 100644 --- a/trunk/drivers/base/dd.c +++ b/trunk/drivers/base/dd.c @@ -17,7 +17,6 @@ #include #include -#include #include "base.h" #include "power/power.h" @@ -39,73 +38,66 @@ * * This function must be called with @dev->sem held. */ -int device_bind_driver(struct device *dev) +void device_bind_driver(struct device * dev) { - int ret; - - if (klist_node_attached(&dev->knode_driver)) { - printk(KERN_WARNING "%s: device %s already bound\n", - __FUNCTION__, kobject_name(&dev->kobj)); - return 0; - } + if (klist_node_attached(&dev->knode_driver)) + return; pr_debug("bound device '%s' to driver '%s'\n", dev->bus_id, dev->driver->name); klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices); - ret = sysfs_create_link(&dev->driver->kobj, &dev->kobj, + sysfs_create_link(&dev->driver->kobj, &dev->kobj, kobject_name(&dev->kobj)); - if (ret == 0) { - ret = sysfs_create_link(&dev->kobj, &dev->driver->kobj, - "driver"); - if (ret) - sysfs_remove_link(&dev->driver->kobj, - kobject_name(&dev->kobj)); - } - return ret; + sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver"); } -struct stupid_thread_structure { - struct device_driver *drv; - struct device *dev; -}; - -static atomic_t probe_count = ATOMIC_INIT(0); -static int really_probe(void *void_data) +/** + * driver_probe_device - attempt to bind device & driver. + * @drv: driver. + * @dev: device. + * + * First, we call the bus's match function, if one present, which + * should compare the device IDs the driver supports with the + * device IDs of the device. Note we don't do this ourselves + * because we don't know the format of the ID structures, nor what + * is to be considered a match and what is not. + * + * This function returns 1 if a match is found, an error if one + * occurs (that is not -ENODEV or -ENXIO), and 0 otherwise. + * + * This function must be called with @dev->sem held. When called + * for a USB interface, @dev->parent->sem must be held as well. + */ +int driver_probe_device(struct device_driver * drv, struct device * dev) { - struct stupid_thread_structure *data = void_data; - struct device_driver *drv = data->drv; - struct device *dev = data->dev; int ret = 0; - atomic_inc(&probe_count); - pr_debug("%s: Probing driver %s with device %s\n", - drv->bus->name, drv->name, dev->bus_id); + if (drv->bus->match && !drv->bus->match(dev, drv)) + goto Done; + pr_debug("%s: Matched Device %s with Driver %s\n", + drv->bus->name, dev->bus_id, drv->name); dev->driver = drv; if (dev->bus->probe) { ret = dev->bus->probe(dev); if (ret) { dev->driver = NULL; - goto probe_failed; + goto ProbeFailed; } } else if (drv->probe) { ret = drv->probe(dev); if (ret) { dev->driver = NULL; - goto probe_failed; + goto ProbeFailed; } } - if (device_bind_driver(dev)) { - printk(KERN_ERR "%s: device_bind_driver(%s) failed\n", - __FUNCTION__, dev->bus_id); - /* How does undo a ->probe? We're screwed. */ - } + device_bind_driver(dev); ret = 1; pr_debug("%s: Bound Device %s to Driver %s\n", drv->bus->name, dev->bus_id, drv->name); - goto done; + goto Done; -probe_failed: + ProbeFailed: if (ret == -ENODEV || ret == -ENXIO) { /* Driver matched, but didn't support device * or device not found. @@ -118,71 +110,7 @@ static int really_probe(void *void_data) "%s: probe of %s failed with error %d\n", drv->name, dev->bus_id, ret); } -done: - kfree(data); - atomic_dec(&probe_count); - return ret; -} - -/** - * driver_probe_done - * Determine if the probe sequence is finished or not. - * - * Should somehow figure out how to use a semaphore, not an atomic variable... - */ -int driver_probe_done(void) -{ - pr_debug("%s: probe_count = %d\n", __FUNCTION__, - atomic_read(&probe_count)); - if (atomic_read(&probe_count)) - return -EBUSY; - return 0; -} - -/** - * driver_probe_device - attempt to bind device & driver together - * @drv: driver to bind a device to - * @dev: device to try to bind to the driver - * - * First, we call the bus's match function, if one present, which should - * compare the device IDs the driver supports with the device IDs of the - * device. Note we don't do this ourselves because we don't know the - * format of the ID structures, nor what is to be considered a match and - * what is not. - * - * This function returns 1 if a match is found, an error if one occurs - * (that is not -ENODEV or -ENXIO), and 0 otherwise. - * - * This function must be called with @dev->sem held. When called for a - * USB interface, @dev->parent->sem must be held as well. - */ -int driver_probe_device(struct device_driver * drv, struct device * dev) -{ - struct stupid_thread_structure *data; - struct task_struct *probe_task; - int ret = 0; - - if (!device_is_registered(dev)) - return -ENODEV; - if (drv->bus->match && !drv->bus->match(dev, drv)) - goto done; - - pr_debug("%s: Matched Device %s with Driver %s\n", - drv->bus->name, dev->bus_id, drv->name); - - data = kmalloc(sizeof(*data), GFP_KERNEL); - data->drv = drv; - data->dev = dev; - - if (drv->multithread_probe) { - probe_task = kthread_run(really_probe, data, - "probe-%s", dev->bus_id); - if (IS_ERR(probe_task)) - ret = PTR_ERR(probe_task); - } else - ret = really_probe(data); - -done: + Done: return ret; } @@ -211,9 +139,8 @@ int device_attach(struct device * dev) down(&dev->sem); if (dev->driver) { - ret = device_bind_driver(dev); - if (ret == 0) - ret = 1; + device_bind_driver(dev); + ret = 1; } else ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); up(&dev->sem); @@ -255,9 +182,9 @@ static int __driver_attach(struct device * dev, void * data) * returns 0 and the @dev->driver is set, we've found a * compatible pair. */ -int driver_attach(struct device_driver * drv) +void driver_attach(struct device_driver * drv) { - return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); + bus_for_each_dev(drv->bus, NULL, drv, __driver_attach); } /** diff --git a/trunk/drivers/base/driver.c b/trunk/drivers/base/driver.c index 1214cbd17d86..562600dd540a 100644 --- a/trunk/drivers/base/driver.c +++ b/trunk/drivers/base/driver.c @@ -142,6 +142,20 @@ void put_driver(struct device_driver * drv) kobject_put(&drv->kobj); } +static void klist_devices_get(struct klist_node *n) +{ + struct device *dev = container_of(n, struct device, knode_driver); + + get_device(dev); +} + +static void klist_devices_put(struct klist_node *n) +{ + struct device *dev = container_of(n, struct device, knode_driver); + + put_device(dev); +} + /** * driver_register - register driver with bus * @drv: driver to register @@ -161,7 +175,7 @@ int driver_register(struct device_driver * drv) (drv->bus->shutdown && drv->shutdown)) { printk(KERN_WARNING "Driver '%s' needs updating - please use bus_type methods\n", drv->name); } - klist_init(&drv->klist_devices, NULL, NULL); + klist_init(&drv->klist_devices, klist_devices_get, klist_devices_put); init_completion(&drv->unloaded); return bus_add_driver(drv); } diff --git a/trunk/drivers/base/firmware_class.c b/trunk/drivers/base/firmware_class.c index 14615694ae9a..5d6c011183f5 100644 --- a/trunk/drivers/base/firmware_class.c +++ b/trunk/drivers/base/firmware_class.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include "base.h" @@ -512,6 +511,7 @@ request_firmware_work_func(void *arg) WARN_ON(1); return 0; } + daemonize("%s/%s", "firmware", fw_work->name); ret = _request_firmware(&fw, fw_work->name, fw_work->device, fw_work->uevent); if (ret < 0) @@ -546,9 +546,9 @@ request_firmware_nowait( const char *name, struct device *device, void *context, void (*cont)(const struct firmware *fw, void *context)) { - struct task_struct *task; struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work), GFP_ATOMIC); + int ret; if (!fw_work) return -ENOMEM; @@ -566,14 +566,14 @@ request_firmware_nowait( .uevent = uevent, }; - task = kthread_run(request_firmware_work_func, fw_work, - "firmware/%s", name); + ret = kernel_thread(request_firmware_work_func, fw_work, + CLONE_FS | CLONE_FILES); - if (IS_ERR(task)) { + if (ret < 0) { fw_work->cont(NULL, fw_work->context); module_put(fw_work->module); kfree(fw_work); - return PTR_ERR(task); + return ret; } return 0; } @@ -602,7 +602,7 @@ firmware_class_exit(void) class_unregister(&firmware_class); } -fs_initcall(firmware_class_init); +module_init(firmware_class_init); module_exit(firmware_class_exit); EXPORT_SYMBOL(release_firmware); diff --git a/trunk/drivers/base/platform.c b/trunk/drivers/base/platform.c index 940ce41f1887..2b8755db76c6 100644 --- a/trunk/drivers/base/platform.c +++ b/trunk/drivers/base/platform.c @@ -505,36 +505,12 @@ static int platform_match(struct device * dev, struct device_driver * drv) return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0); } -static int platform_suspend(struct device *dev, pm_message_t mesg) +static int platform_suspend(struct device * dev, pm_message_t state) { int ret = 0; if (dev->driver && dev->driver->suspend) - ret = dev->driver->suspend(dev, mesg); - - return ret; -} - -static int platform_suspend_late(struct device *dev, pm_message_t mesg) -{ - struct platform_driver *drv = to_platform_driver(dev->driver); - struct platform_device *pdev = container_of(dev, struct platform_device, dev); - int ret = 0; - - if (dev->driver && drv->suspend_late) - ret = drv->suspend_late(pdev, mesg); - - return ret; -} - -static int platform_resume_early(struct device *dev) -{ - struct platform_driver *drv = to_platform_driver(dev->driver); - struct platform_device *pdev = container_of(dev, struct platform_device, dev); - int ret = 0; - - if (dev->driver && drv->resume_early) - ret = drv->resume_early(pdev); + ret = dev->driver->suspend(dev, state); return ret; } @@ -555,8 +531,6 @@ struct bus_type platform_bus_type = { .match = platform_match, .uevent = platform_uevent, .suspend = platform_suspend, - .suspend_late = platform_suspend_late, - .resume_early = platform_resume_early, .resume = platform_resume, }; EXPORT_SYMBOL_GPL(platform_bus_type); diff --git a/trunk/drivers/base/power/resume.c b/trunk/drivers/base/power/resume.c index 020be36705a6..826093ef4c7e 100644 --- a/trunk/drivers/base/power/resume.c +++ b/trunk/drivers/base/power/resume.c @@ -38,35 +38,13 @@ int resume_device(struct device * dev) dev_dbg(dev,"resuming\n"); error = dev->bus->resume(dev); } - if (dev->class && dev->class->resume) { - dev_dbg(dev,"class resume\n"); - error = dev->class->resume(dev); - } up(&dev->sem); TRACE_RESUME(error); return error; } -static int resume_device_early(struct device * dev) -{ - int error = 0; - TRACE_DEVICE(dev); - TRACE_RESUME(0); - if (dev->bus && dev->bus->resume_early) { - dev_dbg(dev,"EARLY resume\n"); - error = dev->bus->resume_early(dev); - } - TRACE_RESUME(error); - return error; -} - -/* - * Resume the devices that have either not gone through - * the late suspend, or that did go through it but also - * went through the early resume - */ void dpm_resume(void) { down(&dpm_list_sem); @@ -96,7 +74,6 @@ void dpm_resume(void) void device_resume(void) { - might_sleep(); down(&dpm_sem); dpm_resume(); up(&dpm_sem); @@ -106,12 +83,12 @@ EXPORT_SYMBOL_GPL(device_resume); /** - * dpm_power_up - Power on some devices. + * device_power_up_irq - Power on some devices. * * Walk the dpm_off_irq list and power each device up. This * is used for devices that required they be powered down with - * interrupts disabled. As devices are powered on, they are moved - * to the dpm_active list. + * interrupts disabled. As devices are powered on, they are moved to + * the dpm_suspended list. * * Interrupts must be disabled when calling this. */ @@ -122,14 +99,16 @@ void dpm_power_up(void) struct list_head * entry = dpm_off_irq.next; struct device * dev = to_device(entry); - list_move_tail(entry, &dpm_off); - resume_device_early(dev); + get_device(dev); + list_move_tail(entry, &dpm_active); + resume_device(dev); + put_device(dev); } } /** - * device_power_up - Turn on all devices that need special attention. + * device_pm_power_up - Turn on all devices that need special attention. * * Power on system devices then devices that required we shut them down * with interrupts disabled. diff --git a/trunk/drivers/base/power/suspend.c b/trunk/drivers/base/power/suspend.c index ece136bf97e3..69509e02f703 100644 --- a/trunk/drivers/base/power/suspend.c +++ b/trunk/drivers/base/power/suspend.c @@ -34,7 +34,6 @@ static inline char *suspend_verb(u32 event) switch (event) { case PM_EVENT_SUSPEND: return "suspend"; case PM_EVENT_FREEZE: return "freeze"; - case PM_EVENT_PRETHAW: return "prethaw"; default: return "(unknown suspend event)"; } } @@ -66,19 +65,7 @@ int suspend_device(struct device * dev, pm_message_t state) dev->power.prev_state = dev->power.power_state; - if (dev->class && dev->class->suspend && !dev->power.power_state.event) { - dev_dbg(dev, "class %s%s\n", - suspend_verb(state.event), - ((state.event == PM_EVENT_SUSPEND) - && device_may_wakeup(dev)) - ? ", may wakeup" - : "" - ); - error = dev->class->suspend(dev, state); - suspend_report_result(dev->class->suspend, error); - } - - if (!error && dev->bus && dev->bus->suspend && !dev->power.power_state.event) { + if (dev->bus && dev->bus->suspend && !dev->power.power_state.event) { dev_dbg(dev, "%s%s\n", suspend_verb(state.event), ((state.event == PM_EVENT_SUSPEND) @@ -94,42 +81,15 @@ int suspend_device(struct device * dev, pm_message_t state) } -/* - * This is called with interrupts off, only a single CPU - * running. We can't do down() on a semaphore (and we don't - * need the protection) - */ -static int suspend_device_late(struct device *dev, pm_message_t state) -{ - int error = 0; - - if (dev->bus && dev->bus->suspend_late && !dev->power.power_state.event) { - dev_dbg(dev, "LATE %s%s\n", - suspend_verb(state.event), - ((state.event == PM_EVENT_SUSPEND) - && device_may_wakeup(dev)) - ? ", may wakeup" - : "" - ); - error = dev->bus->suspend_late(dev, state); - suspend_report_result(dev->bus->suspend_late, error); - } - return error; -} - /** * device_suspend - Save state and stop all devices in system. * @state: Power state to put each device in. * * Walk the dpm_active list, call ->suspend() for each device, and move - * it to the dpm_off list. - * - * (For historical reasons, if it returns -EAGAIN, that used to mean - * that the device would be called again with interrupts disabled. - * These days, we use the "suspend_late()" callback for that, so we - * print a warning and consider it an error). - * - * If we get a different error, try and back out. + * it to dpm_off. + * Check the return value for each. If it returns 0, then we move the + * the device to the dpm_off list. If it returns -EAGAIN, we move it to + * the dpm_off_irq list. If we get a different error, try and back out. * * If we hit a failure with any of the devices, call device_resume() * above to bring the suspended devices back to life. @@ -140,7 +100,6 @@ int device_suspend(pm_message_t state) { int error = 0; - might_sleep(); down(&dpm_sem); down(&dpm_list_sem); while (!list_empty(&dpm_active) && error == 0) { @@ -156,27 +115,39 @@ int device_suspend(pm_message_t state) /* Check if the device got removed */ if (!list_empty(&dev->power.entry)) { - /* Move it to the dpm_off list */ + /* Move it to the dpm_off or dpm_off_irq list */ if (!error) list_move(&dev->power.entry, &dpm_off); + else if (error == -EAGAIN) { + list_move(&dev->power.entry, &dpm_off_irq); + error = 0; + } } if (error) printk(KERN_ERR "Could not suspend device %s: " - "error %d%s\n", - kobject_name(&dev->kobj), error, - error == -EAGAIN ? " (please convert to suspend_late)" : ""); + "error %d\n", kobject_name(&dev->kobj), error); put_device(dev); } up(&dpm_list_sem); - if (error) + if (error) { + /* we failed... before resuming, bring back devices from + * dpm_off_irq list back to main dpm_off list, we do want + * to call resume() on them, in case they partially suspended + * despite returning -EAGAIN + */ + while (!list_empty(&dpm_off_irq)) { + struct list_head * entry = dpm_off_irq.next; + list_move(entry, &dpm_off); + } dpm_resume(); - + } up(&dpm_sem); return error; } EXPORT_SYMBOL_GPL(device_suspend); + /** * device_power_down - Shut down special devices. * @state: Power state to enter. @@ -191,17 +162,14 @@ int device_power_down(pm_message_t state) int error = 0; struct device * dev; - while (!list_empty(&dpm_off)) { - struct list_head * entry = dpm_off.prev; - - dev = to_device(entry); - error = suspend_device_late(dev, state); - if (error) - goto Error; - list_move(&dev->power.entry, &dpm_off_irq); + list_for_each_entry_reverse(dev, &dpm_off_irq, power.entry) { + if ((error = suspend_device(dev, state))) + break; } - - error = sysdev_suspend(state); + if (error) + goto Error; + if ((error = sysdev_suspend(state))) + goto Error; Done: return error; Error: diff --git a/trunk/drivers/base/power/sysfs.c b/trunk/drivers/base/power/sysfs.c index 2d47517dbe32..40d7242a07c1 100644 --- a/trunk/drivers/base/power/sysfs.c +++ b/trunk/drivers/base/power/sysfs.c @@ -7,29 +7,22 @@ #include "power.h" -#ifdef CONFIG_PM_SYSFS_DEPRECATED - /** * state - Control current power state of device * * show() returns the current power state of the device. '0' indicates - * the device is on. Other values (2) indicate the device is in some low + * the device is on. Other values (1-3) indicate the device is in a low * power state. * - * store() sets the current power state, which is an integer valued - * 0, 2, or 3. Devices with bus.suspend_late(), or bus.resume_early() - * methods fail this operation; those methods couldn't be called. - * Otherwise, - * - * - If the recorded dev->power.power_state.event matches the - * target value, nothing is done. - * - If the recorded event code is nonzero, the device is reactivated - * by calling bus.resume() and/or class.resume(). - * - If the target value is nonzero, the device is suspended by - * calling class.suspend() and/or bus.suspend() with event code - * PM_EVENT_SUSPEND. - * - * This mechanism is DEPRECATED and should only be used for testing. + * store() sets the current power state, which is an integer value + * between 0-3. If the device is on ('0'), and the value written is + * greater than 0, then the device is placed directly into the low-power + * state (via its driver's ->suspend() method). + * If the device is currently in a low-power state, and the value is 0, + * the device is powered back on (via the ->resume() method). + * If the device is in a low-power state, and a different low-power state + * is requested, the device is first resumed, then suspended into the new + * low-power state. */ static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) @@ -45,10 +38,6 @@ static ssize_t state_store(struct device * dev, struct device_attribute *attr, c pm_message_t state; int error = -EINVAL; - /* disallow incomplete suspend sequences */ - if (dev->bus && (dev->bus->suspend_late || dev->bus->resume_early)) - return error; - state.event = PM_EVENT_SUSPEND; /* Older apps expected to write "3" here - confused with PCI D3 */ if ((n == 1) && !strcmp(buf, "3")) @@ -68,8 +57,6 @@ static ssize_t state_store(struct device * dev, struct device_attribute *attr, c static DEVICE_ATTR(state, 0644, state_show, state_store); -#endif /* CONFIG_PM_SYSFS_DEPRECATED */ - /* * wakeup - Report/change current wakeup option for device * @@ -143,9 +130,7 @@ static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store); static struct attribute * power_attrs[] = { -#ifdef CONFIG_PM_SYSFS_DEPRECATED &dev_attr_state.attr, -#endif &dev_attr_wakeup.attr, NULL, }; diff --git a/trunk/drivers/block/DAC960.c b/trunk/drivers/block/DAC960.c index b3f639fbf220..a360215dbce7 100644 --- a/trunk/drivers/block/DAC960.c +++ b/trunk/drivers/block/DAC960.c @@ -770,7 +770,7 @@ static void DAC960_P_QueueCommand(DAC960_Command_T *Command) static void DAC960_ExecuteCommand(DAC960_Command_T *Command) { DAC960_Controller_T *Controller = Command->Controller; - DECLARE_COMPLETION_ONSTACK(Completion); + DECLARE_COMPLETION(Completion); unsigned long flags; Command->Completion = &Completion; @@ -3331,7 +3331,7 @@ static int DAC960_process_queue(DAC960_Controller_T *Controller, struct request_ Command->DmaDirection = PCI_DMA_TODEVICE; Command->CommandType = DAC960_WriteCommand; } - Command->Completion = Request->end_io_data; + Command->Completion = Request->waiting; Command->LogicalDriveNumber = (long)Request->rq_disk->private_data; Command->BlockNumber = Request->sector; Command->BlockCount = Request->nr_sectors; diff --git a/trunk/drivers/block/DAC960.h b/trunk/drivers/block/DAC960.h index f9217c34bc2b..a82f37f749a5 100644 --- a/trunk/drivers/block/DAC960.h +++ b/trunk/drivers/block/DAC960.h @@ -71,7 +71,7 @@ Define a Boolean data type. */ -typedef bool boolean; +typedef enum { false, true } __attribute__ ((packed)) boolean; /* diff --git a/trunk/drivers/block/Kconfig b/trunk/drivers/block/Kconfig index 422e31d5f8e5..b5382cedf0c0 100644 --- a/trunk/drivers/block/Kconfig +++ b/trunk/drivers/block/Kconfig @@ -2,8 +2,6 @@ # Block device driver configuration # -if BLOCK - menu "Block devices" config BLK_DEV_FD @@ -470,5 +468,3 @@ config ATA_OVER_ETH devices like the Coraid EtherDrive (R) Storage Blade. endmenu - -endif diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index 99f87efe0f58..2cd3391ff878 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -144,13 +144,13 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk); static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, int clear_all); -static void cciss_read_capacity(int ctlr, int logvol, int withirq, - sector_t *total_size, unsigned int *block_size); -static void cciss_read_capacity_16(int ctlr, int logvol, int withirq, - sector_t *total_size, unsigned int *block_size); -static void cciss_geometry_inquiry(int ctlr, int logvol, - int withirq, sector_t total_size, - unsigned int block_size, InquiryData_struct *inq_buff, +static void cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf, + int withirq, unsigned int *total_size, + unsigned int *block_size); +static void cciss_geometry_inquiry(int ctlr, int logvol, int withirq, + unsigned int total_size, + unsigned int block_size, + InquiryData_struct *inq_buff, drive_info_struct *drv); static void cciss_getgeometry(int cntl_num); static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, @@ -879,7 +879,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, char *buff = NULL; u64bit temp64; unsigned long flags; - DECLARE_COMPLETION_ONSTACK(wait); + DECLARE_COMPLETION(wait); if (!arg) return -EINVAL; @@ -997,7 +997,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, BYTE sg_used = 0; int status = 0; int i; - DECLARE_COMPLETION_ONSTACK(wait); + DECLARE_COMPLETION(wait); __u32 left; __u32 sz; BYTE __user *data_ptr; @@ -1229,6 +1229,7 @@ static inline void complete_buffers(struct bio *bio, int status) int nr_sectors = bio_sectors(bio); bio->bi_next = NULL; + blk_finished_io(len); bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO); bio = xbh; } @@ -1325,9 +1326,10 @@ static void cciss_update_drive_info(int ctlr, int drv_index) { ctlr_info_t *h = hba[ctlr]; struct gendisk *disk; + ReadCapdata_struct *size_buff = NULL; InquiryData_struct *inq_buff = NULL; unsigned int block_size; - sector_t total_size; + unsigned int total_size; unsigned long flags = 0; int ret = 0; @@ -1346,25 +1348,15 @@ static void cciss_update_drive_info(int ctlr, int drv_index) return; /* Get information about the disk and modify the driver structure */ + size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); + if (size_buff == NULL) + goto mem_msg; inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); if (inq_buff == NULL) goto mem_msg; - cciss_read_capacity(ctlr, drv_index, 1, + cciss_read_capacity(ctlr, drv_index, size_buff, 1, &total_size, &block_size); - - /* total size = last LBA + 1 */ - /* FFFFFFFF + 1 = 0, cannot have a logical volume of size 0 */ - /* so we assume this volume this must be >2TB in size */ - if (total_size == (__u32) 0) { - cciss_read_capacity_16(ctlr, drv_index, 1, - &total_size, &block_size); - h->cciss_read = CCISS_READ_16; - h->cciss_write = CCISS_WRITE_16; - } else { - h->cciss_read = CCISS_READ_10; - h->cciss_write = CCISS_WRITE_10; - } cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, inq_buff, &h->drv[drv_index]); @@ -1400,6 +1392,7 @@ static void cciss_update_drive_info(int ctlr, int drv_index) } freeret: + kfree(size_buff); kfree(inq_buff); return; mem_msg: @@ -1724,22 +1717,6 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_ c->Request.Timeout = 0; c->Request.CDB[0] = cmd; break; - case CCISS_READ_CAPACITY_16: - c->Header.LUN.LogDev.VolId = h->drv[log_unit].LunID; - c->Header.LUN.LogDev.Mode = 1; - c->Request.CDBLen = 16; - c->Request.Type.Attribute = ATTR_SIMPLE; - c->Request.Type.Direction = XFER_READ; - c->Request.Timeout = 0; - c->Request.CDB[0] = cmd; - c->Request.CDB[1] = 0x10; - c->Request.CDB[10] = (size >> 24) & 0xFF; - c->Request.CDB[11] = (size >> 16) & 0xFF; - c->Request.CDB[12] = (size >> 8) & 0xFF; - c->Request.CDB[13] = size & 0xFF; - c->Request.Timeout = 0; - c->Request.CDB[0] = cmd; - break; case CCISS_CACHE_FLUSH: c->Request.CDBLen = 12; c->Request.Type.Attribute = ATTR_SIMPLE; @@ -1773,7 +1750,6 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, size_ memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB)); c->Request.CDB[0] = cmd; /* reset */ c->Request.CDB[1] = 0x04; /* reset a LUN */ - break; case 3: /* No-Op message */ c->Request.CDBLen = 1; c->Request.Type.Attribute = ATTR_SIMPLE; @@ -1816,7 +1792,7 @@ static int sendcmd_withirq(__u8 cmd, u64bit buff_dma_handle; unsigned long flags; int return_status; - DECLARE_COMPLETION_ONSTACK(wait); + DECLARE_COMPLETION(wait); if ((c = cmd_alloc(h, 0)) == NULL) return -ENOMEM; @@ -1917,15 +1893,12 @@ static int sendcmd_withirq(__u8 cmd, } static void cciss_geometry_inquiry(int ctlr, int logvol, - int withirq, sector_t total_size, + int withirq, unsigned int total_size, unsigned int block_size, InquiryData_struct *inq_buff, drive_info_struct *drv) { int return_code; - unsigned long t; - unsigned long rem; - memset(inq_buff, 0, sizeof(InquiryData_struct)); if (withirq) return_code = sendcmd_withirq(CISS_INQUIRY, ctlr, @@ -1944,10 +1917,10 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, drv->nr_blocks = total_size; drv->heads = 255; drv->sectors = 32; // Sectors per track - t = drv->heads * drv->sectors; - drv->cylinders = total_size; - rem = do_div(drv->cylinders, t); + drv->cylinders = total_size / 255 / 32; } else { + unsigned int t; + drv->block_size = block_size; drv->nr_blocks = total_size; drv->heads = inq_buff->data_byte[6]; @@ -1957,84 +1930,42 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, drv->raid_level = inq_buff->data_byte[8]; t = drv->heads * drv->sectors; if (t > 1) { - drv->cylinders = total_size; - rem = do_div(drv->cylinders, t); + drv->cylinders = total_size / t; } } } else { /* Get geometry failed */ printk(KERN_WARNING "cciss: reading geometry failed\n"); } - printk(KERN_INFO " heads=%d, sectors=%d, cylinders=%d\n\n", + printk(KERN_INFO " heads= %d, sectors= %d, cylinders= %d\n\n", drv->heads, drv->sectors, drv->cylinders); } static void -cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, +cciss_read_capacity(int ctlr, int logvol, ReadCapdata_struct *buf, + int withirq, unsigned int *total_size, unsigned int *block_size) { - ReadCapdata_struct *buf; int return_code; - buf = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); - if (buf == NULL) { - printk(KERN_WARNING "cciss: out of memory\n"); - return; - } - memset(buf, 0, sizeof(ReadCapdata_struct)); + memset(buf, 0, sizeof(*buf)); if (withirq) return_code = sendcmd_withirq(CCISS_READ_CAPACITY, - ctlr, buf, sizeof(ReadCapdata_struct), - 1, logvol, 0, TYPE_CMD); + ctlr, buf, sizeof(*buf), 1, + logvol, 0, TYPE_CMD); else return_code = sendcmd(CCISS_READ_CAPACITY, - ctlr, buf, sizeof(ReadCapdata_struct), - 1, logvol, 0, NULL, TYPE_CMD); + ctlr, buf, sizeof(*buf), 1, logvol, 0, + NULL, TYPE_CMD); if (return_code == IO_OK) { - *total_size = be32_to_cpu(*(__u32 *) buf->total_size)+1; - *block_size = be32_to_cpu(*(__u32 *) buf->block_size); + *total_size = + be32_to_cpu(*((__be32 *) & buf->total_size[0])) + 1; + *block_size = be32_to_cpu(*((__be32 *) & buf->block_size[0])); } else { /* read capacity command failed */ printk(KERN_WARNING "cciss: read capacity failed\n"); *total_size = 0; *block_size = BLOCK_SIZE; } - if (*total_size != (__u32) 0) - printk(KERN_INFO " blocks= %lld block_size= %d\n", - *total_size, *block_size); - kfree(buf); - return; -} - -static void -cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, unsigned int *block_size) -{ - ReadCapdata_struct_16 *buf; - int return_code; - buf = kmalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL); - if (buf == NULL) { - printk(KERN_WARNING "cciss: out of memory\n"); - return; - } - memset(buf, 0, sizeof(ReadCapdata_struct_16)); - if (withirq) { - return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16, - ctlr, buf, sizeof(ReadCapdata_struct_16), - 1, logvol, 0, TYPE_CMD); - } - else { - return_code = sendcmd(CCISS_READ_CAPACITY_16, - ctlr, buf, sizeof(ReadCapdata_struct_16), - 1, logvol, 0, NULL, TYPE_CMD); - } - if (return_code == IO_OK) { - *total_size = be64_to_cpu(*(__u64 *) buf->total_size)+1; - *block_size = be32_to_cpu(*(__u32 *) buf->block_size); - } else { /* read capacity command failed */ - printk(KERN_WARNING "cciss: read capacity failed\n"); - *total_size = 0; - *block_size = BLOCK_SIZE; - } - printk(KERN_INFO " blocks= %lld block_size= %d\n", + printk(KERN_INFO " blocks= %u block_size= %d\n", *total_size, *block_size); - kfree(buf); return; } @@ -2045,7 +1976,8 @@ static int cciss_revalidate(struct gendisk *disk) int logvol; int FOUND = 0; unsigned int block_size; - sector_t total_size; + unsigned int total_size; + ReadCapdata_struct *size_buff = NULL; InquiryData_struct *inq_buff = NULL; for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { @@ -2058,24 +1990,27 @@ static int cciss_revalidate(struct gendisk *disk) if (!FOUND) return 1; + size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); + if (size_buff == NULL) { + printk(KERN_WARNING "cciss: out of memory\n"); + return 1; + } inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); if (inq_buff == NULL) { printk(KERN_WARNING "cciss: out of memory\n"); + kfree(size_buff); return 1; } - if (h->cciss_read == CCISS_READ_10) { - cciss_read_capacity(h->ctlr, logvol, 1, - &total_size, &block_size); - } else { - cciss_read_capacity_16(h->ctlr, logvol, 1, - &total_size, &block_size); - } + + cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, + &block_size); cciss_geometry_inquiry(h->ctlr, logvol, 1, total_size, block_size, inq_buff, drv); blk_queue_hardsect_size(drv->queue, drv->block_size); set_capacity(disk, drv->nr_blocks); + kfree(size_buff); kfree(inq_buff); return 0; } @@ -2484,8 +2419,7 @@ static void do_cciss_request(request_queue_t *q) { ctlr_info_t *h = q->queuedata; CommandList_struct *c; - sector_t start_blk; - int seg; + int start_blk, seg; struct request *creq; u64bit temp64; struct scatterlist tmp_sg[MAXSGENTRIES]; @@ -2529,10 +2463,10 @@ static void do_cciss_request(request_queue_t *q) c->Request.Type.Type = TYPE_CMD; // It is a command. c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = - (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; + (rq_data_dir(creq) == READ) ? XFER_READ : XFER_WRITE; c->Request.Timeout = 0; // Don't time out c->Request.CDB[0] = - (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; + (rq_data_dir(creq) == READ) ? CCISS_READ : CCISS_WRITE; start_blk = creq->sector; #ifdef CCISS_DEBUG printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n", (int)creq->sector, @@ -2566,33 +2500,15 @@ static void do_cciss_request(request_queue_t *q) #endif /* CCISS_DEBUG */ c->Header.SGList = c->Header.SGTotal = seg; - if(h->cciss_read == CCISS_READ_10) { - c->Request.CDB[1] = 0; - c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB - c->Request.CDB[3] = (start_blk >> 16) & 0xff; - c->Request.CDB[4] = (start_blk >> 8) & 0xff; - c->Request.CDB[5] = start_blk & 0xff; - c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB - c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff; - c->Request.CDB[8] = creq->nr_sectors & 0xff; - c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; - } else { - c->Request.CDBLen = 16; - c->Request.CDB[1]= 0; - c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB - c->Request.CDB[3]= (start_blk >> 48) & 0xff; - c->Request.CDB[4]= (start_blk >> 40) & 0xff; - c->Request.CDB[5]= (start_blk >> 32) & 0xff; - c->Request.CDB[6]= (start_blk >> 24) & 0xff; - c->Request.CDB[7]= (start_blk >> 16) & 0xff; - c->Request.CDB[8]= (start_blk >> 8) & 0xff; - c->Request.CDB[9]= start_blk & 0xff; - c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff; - c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff; - c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff; - c->Request.CDB[13]= creq->nr_sectors & 0xff; - c->Request.CDB[14] = c->Request.CDB[15] = 0; - } + c->Request.CDB[1] = 0; + c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB + c->Request.CDB[3] = (start_blk >> 16) & 0xff; + c->Request.CDB[4] = (start_blk >> 8) & 0xff; + c->Request.CDB[5] = start_blk & 0xff; + c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB + c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff; + c->Request.CDB[8] = creq->nr_sectors & 0xff; + c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; spin_lock_irq(q->queue_lock); @@ -2602,9 +2518,9 @@ static void do_cciss_request(request_queue_t *q) h->maxQsinceinit = h->Qdepth; goto queue; -full: + full: blk_stop_queue(q); -startio: + startio: /* We will already have the driver lock here so not need * to lock it. */ @@ -3032,23 +2948,31 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) static void cciss_getgeometry(int cntl_num) { ReportLunData_struct *ld_buff; + ReadCapdata_struct *size_buff; InquiryData_struct *inq_buff; int return_code; int i; int listlength = 0; __u32 lunid = 0; int block_size; - sector_t total_size; + int total_size; ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); if (ld_buff == NULL) { printk(KERN_ERR "cciss: out of memory\n"); return; } + size_buff = kmalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); + if (size_buff == NULL) { + printk(KERN_ERR "cciss: out of memory\n"); + kfree(ld_buff); + return; + } inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); if (inq_buff == NULL) { printk(KERN_ERR "cciss: out of memory\n"); kfree(ld_buff); + kfree(size_buff); return; } /* Get the firmware version */ @@ -3103,6 +3027,7 @@ static void cciss_getgeometry(int cntl_num) #endif /* CCISS_DEBUG */ hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1; +// for(i=0; i< hba[cntl_num]->num_luns; i++) for (i = 0; i < CISS_MAX_LUN; i++) { if (i < hba[cntl_num]->num_luns) { lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) @@ -3121,26 +3046,8 @@ static void cciss_getgeometry(int cntl_num) ld_buff->LUN[i][2], ld_buff->LUN[i][3], hba[cntl_num]->drv[i].LunID); #endif /* CCISS_DEBUG */ - - /* testing to see if 16-byte CDBs are already being used */ - if(hba[cntl_num]->cciss_read == CCISS_READ_16) { - cciss_read_capacity_16(cntl_num, i, 0, + cciss_read_capacity(cntl_num, i, size_buff, 0, &total_size, &block_size); - goto geo_inq; - } - cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size); - - /* total_size = last LBA + 1 */ - if(total_size == (__u32) 0) { - cciss_read_capacity_16(cntl_num, i, 0, - &total_size, &block_size); - hba[cntl_num]->cciss_read = CCISS_READ_16; - hba[cntl_num]->cciss_write = CCISS_WRITE_16; - } else { - hba[cntl_num]->cciss_read = CCISS_READ_10; - hba[cntl_num]->cciss_write = CCISS_WRITE_10; - } -geo_inq: cciss_geometry_inquiry(cntl_num, i, 0, total_size, block_size, inq_buff, &hba[cntl_num]->drv[i]); @@ -3150,6 +3057,7 @@ static void cciss_getgeometry(int cntl_num) } } kfree(ld_buff); + kfree(size_buff); kfree(inq_buff); } diff --git a/trunk/drivers/block/cciss.h b/trunk/drivers/block/cciss.h index 562235c1445a..868e0d862b0d 100644 --- a/trunk/drivers/block/cciss.h +++ b/trunk/drivers/block/cciss.h @@ -76,9 +76,6 @@ struct ctlr_info unsigned int intr[4]; unsigned int msix_vector; unsigned int msi_vector; - BYTE cciss_read; - BYTE cciss_write; - BYTE cciss_read_capacity; // information about each logical volume drive_info_struct drv[CISS_MAX_LUN]; diff --git a/trunk/drivers/block/cciss_cmd.h b/trunk/drivers/block/cciss_cmd.h index 4af7c4c0c7af..53fea549ba8b 100644 --- a/trunk/drivers/block/cciss_cmd.h +++ b/trunk/drivers/block/cciss_cmd.h @@ -118,34 +118,11 @@ typedef struct _ReadCapdata_struct BYTE block_size[4]; // Size of blocks in bytes } ReadCapdata_struct; -#define CCISS_READ_CAPACITY_16 0x9e /* Read Capacity 16 */ - -/* service action to differentiate a 16 byte read capacity from - other commands that use the 0x9e SCSI op code */ - -#define CCISS_READ_CAPACITY_16_SERVICE_ACT 0x10 - -typedef struct _ReadCapdata_struct_16 -{ - BYTE total_size[8]; /* Total size in blocks */ - BYTE block_size[4]; /* Size of blocks in bytes */ - BYTE prot_en:1; /* protection enable bit */ - BYTE rto_en:1; /* reference tag own enable bit */ - BYTE reserved:6; /* reserved bits */ - BYTE reserved2[18]; /* reserved bytes per spec */ -} ReadCapdata_struct_16; - -/* Define the supported read/write commands for cciss based controllers */ - -#define CCISS_READ_10 0x28 /* Read(10) */ -#define CCISS_WRITE_10 0x2a /* Write(10) */ -#define CCISS_READ_16 0x88 /* Read(16) */ -#define CCISS_WRITE_16 0x8a /* Write(16) */ - -/* Define the CDB lengths supported by cciss based controllers */ - -#define CDB_LEN10 10 -#define CDB_LEN16 16 +// 12 byte commands not implemented in firmware yet. +// #define CCISS_READ 0xa8 // Read(12) +// #define CCISS_WRITE 0xaa // Write(12) + #define CCISS_READ 0x28 // Read(10) + #define CCISS_WRITE 0x2a // Write(10) // BMIC commands #define BMIC_READ 0x26 diff --git a/trunk/drivers/block/cciss_scsi.c b/trunk/drivers/block/cciss_scsi.c index bb15051ffbe0..05f79d7393f7 100644 --- a/trunk/drivers/block/cciss_scsi.c +++ b/trunk/drivers/block/cciss_scsi.c @@ -766,7 +766,7 @@ cciss_scsi_do_simple_cmd(ctlr_info_t *c, int direction) { unsigned long flags; - DECLARE_COMPLETION_ONSTACK(wait); + DECLARE_COMPLETION(wait); cp->cmd_type = CMD_IOCTL_PEND; // treat this like an ioctl cp->scsi_cmd = NULL; diff --git a/trunk/drivers/block/cpqarray.c b/trunk/drivers/block/cpqarray.c index 4abc193314ee..78082edc14b4 100644 --- a/trunk/drivers/block/cpqarray.c +++ b/trunk/drivers/block/cpqarray.c @@ -989,6 +989,7 @@ static inline void complete_buffers(struct bio *bio, int ok) xbh = bio->bi_next; bio->bi_next = NULL; + blk_finished_io(nr_sectors); bio_endio(bio, nr_sectors << 9, ok ? 0 : -EIO); bio = xbh; diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 629c5769d994..ad1d7065a1b2 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -2991,8 +2991,8 @@ static void do_fd_request(request_queue_t * q) if (usage_count == 0) { printk("warning: usage count=0, current_req=%p exiting\n", current_req); - printk("sect=%ld type=%x flags=%x\n", (long)current_req->sector, - current_req->cmd_type, current_req->cmd_flags); + printk("sect=%ld flags=%lx\n", (long)current_req->sector, + current_req->flags); return; } if (test_bit(0, &fdc_busy)) { diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index d6bb8da955a2..7b3b94ddddcc 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -66,14 +66,12 @@ #include #include #include -#include #include #include #include /* for invalidate_bdev() */ #include #include #include -#include #include @@ -524,12 +522,15 @@ static int loop_make_request(request_queue_t *q, struct bio *old_bio) goto out; if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY))) goto out; + lo->lo_pending++; loop_add_bio(lo, old_bio); - wake_up(&lo->lo_event); spin_unlock_irq(&lo->lo_lock); + complete(&lo->lo_bh_done); return 0; out: + if (lo->lo_pending == 0) + complete(&lo->lo_bh_done); spin_unlock_irq(&lo->lo_lock); bio_io_error(old_bio, old_bio->bi_size); return 0; @@ -569,18 +570,14 @@ static inline void loop_handle_bio(struct loop_device *lo, struct bio *bio) * to avoid blocking in our make_request_fn. it also does loop decrypting * on reads for block backed loop, as that is too heavy to do from * b_end_io context where irqs may be disabled. - * - * Loop explanation: loop_clr_fd() sets lo_state to Lo_rundown before - * calling kthread_stop(). Therefore once kthread_should_stop() is - * true, make_request will not place any more requests. Therefore - * once kthread_should_stop() is true and lo_bio is NULL, we are - * done with the loop. */ static int loop_thread(void *data) { struct loop_device *lo = data; struct bio *bio; + daemonize("loop%d", lo->lo_number); + /* * loop can be used in an encrypted device, * hence, it mustn't be stopped at all @@ -590,21 +587,47 @@ static int loop_thread(void *data) set_user_nice(current, -20); - while (!kthread_should_stop() || lo->lo_bio) { + lo->lo_state = Lo_bound; + lo->lo_pending = 1; - wait_event_interruptible(lo->lo_event, - lo->lo_bio || kthread_should_stop()); + /* + * complete it, we are running + */ + complete(&lo->lo_done); + + for (;;) { + int pending; - if (!lo->lo_bio) + if (wait_for_completion_interruptible(&lo->lo_bh_done)) continue; + spin_lock_irq(&lo->lo_lock); + + /* + * could be completed because of tear-down, not pending work + */ + if (unlikely(!lo->lo_pending)) { + spin_unlock_irq(&lo->lo_lock); + break; + } + bio = loop_get_bio(lo); + lo->lo_pending--; + pending = lo->lo_pending; spin_unlock_irq(&lo->lo_lock); BUG_ON(!bio); loop_handle_bio(lo, bio); + + /* + * upped both for pending work and tear-down, lo_pending + * will hit zero then + */ + if (unlikely(!pending)) + break; } + complete(&lo->lo_done); return 0; } @@ -639,8 +662,7 @@ static void do_loop_switch(struct loop_device *lo, struct switch_request *p) mapping_set_gfp_mask(old_file->f_mapping, lo->old_gfp_mask); lo->lo_backing_file = file; - lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ? - mapping->host->i_bdev->bd_block_size : PAGE_SIZE; + lo->lo_blocksize = mapping->host->i_blksize; lo->old_gfp_mask = mapping_gfp_mask(mapping); mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); complete(&p->wait); @@ -772,9 +794,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write) lo_flags |= LO_FLAGS_READ_ONLY; - lo_blocksize = S_ISBLK(inode->i_mode) ? - inode->i_bdev->bd_block_size : PAGE_SIZE; - + lo_blocksize = inode->i_blksize; error = 0; } else { goto out_putf; @@ -817,26 +837,12 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, set_blocksize(bdev, lo_blocksize); - lo->lo_thread = kthread_create(loop_thread, lo, "loop%d", - lo->lo_number); - if (IS_ERR(lo->lo_thread)) { - error = PTR_ERR(lo->lo_thread); - goto out_clr; - } - lo->lo_state = Lo_bound; - wake_up_process(lo->lo_thread); + error = kernel_thread(loop_thread, lo, CLONE_KERNEL); + if (error < 0) + goto out_putf; + wait_for_completion(&lo->lo_done); return 0; -out_clr: - lo->lo_thread = NULL; - lo->lo_device = NULL; - lo->lo_backing_file = NULL; - lo->lo_flags = 0; - set_capacity(disks[lo->lo_number], 0); - invalidate_bdev(bdev, 0); - bd_set_size(bdev, 0); - mapping_set_gfp_mask(mapping, lo->old_gfp_mask); - lo->lo_state = Lo_unbound; out_putf: fput(file); out: @@ -898,9 +904,12 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) spin_lock_irq(&lo->lo_lock); lo->lo_state = Lo_rundown; + lo->lo_pending--; + if (!lo->lo_pending) + complete(&lo->lo_bh_done); spin_unlock_irq(&lo->lo_lock); - kthread_stop(lo->lo_thread); + wait_for_completion(&lo->lo_done); lo->lo_backing_file = NULL; @@ -913,7 +922,6 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) lo->lo_sizelimit = 0; lo->lo_encrypt_key_size = 0; lo->lo_flags = 0; - lo->lo_thread = NULL; memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); memset(lo->lo_file_name, 0, LO_NAME_SIZE); @@ -1166,162 +1174,6 @@ static int lo_ioctl(struct inode * inode, struct file * file, return err; } -#ifdef CONFIG_COMPAT -struct compat_loop_info { - compat_int_t lo_number; /* ioctl r/o */ - compat_dev_t lo_device; /* ioctl r/o */ - compat_ulong_t lo_inode; /* ioctl r/o */ - compat_dev_t lo_rdevice; /* ioctl r/o */ - compat_int_t lo_offset; - compat_int_t lo_encrypt_type; - compat_int_t lo_encrypt_key_size; /* ioctl w/o */ - compat_int_t lo_flags; /* ioctl r/o */ - char lo_name[LO_NAME_SIZE]; - unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ - compat_ulong_t lo_init[2]; - char reserved[4]; -}; - -/* - * Transfer 32-bit compatibility structure in userspace to 64-bit loop info - * - noinlined to reduce stack space usage in main part of driver - */ -static noinline int -loop_info64_from_compat(const struct compat_loop_info *arg, - struct loop_info64 *info64) -{ - struct compat_loop_info info; - - if (copy_from_user(&info, arg, sizeof(info))) - return -EFAULT; - - memset(info64, 0, sizeof(*info64)); - info64->lo_number = info.lo_number; - info64->lo_device = info.lo_device; - info64->lo_inode = info.lo_inode; - info64->lo_rdevice = info.lo_rdevice; - info64->lo_offset = info.lo_offset; - info64->lo_sizelimit = 0; - info64->lo_encrypt_type = info.lo_encrypt_type; - info64->lo_encrypt_key_size = info.lo_encrypt_key_size; - info64->lo_flags = info.lo_flags; - info64->lo_init[0] = info.lo_init[0]; - info64->lo_init[1] = info.lo_init[1]; - if (info.lo_encrypt_type == LO_CRYPT_CRYPTOAPI) - memcpy(info64->lo_crypt_name, info.lo_name, LO_NAME_SIZE); - else - memcpy(info64->lo_file_name, info.lo_name, LO_NAME_SIZE); - memcpy(info64->lo_encrypt_key, info.lo_encrypt_key, LO_KEY_SIZE); - return 0; -} - -/* - * Transfer 64-bit loop info to 32-bit compatibility structure in userspace - * - noinlined to reduce stack space usage in main part of driver - */ -static noinline int -loop_info64_to_compat(const struct loop_info64 *info64, - struct compat_loop_info __user *arg) -{ - struct compat_loop_info info; - - memset(&info, 0, sizeof(info)); - info.lo_number = info64->lo_number; - info.lo_device = info64->lo_device; - info.lo_inode = info64->lo_inode; - info.lo_rdevice = info64->lo_rdevice; - info.lo_offset = info64->lo_offset; - info.lo_encrypt_type = info64->lo_encrypt_type; - info.lo_encrypt_key_size = info64->lo_encrypt_key_size; - info.lo_flags = info64->lo_flags; - info.lo_init[0] = info64->lo_init[0]; - info.lo_init[1] = info64->lo_init[1]; - if (info.lo_encrypt_type == LO_CRYPT_CRYPTOAPI) - memcpy(info.lo_name, info64->lo_crypt_name, LO_NAME_SIZE); - else - memcpy(info.lo_name, info64->lo_file_name, LO_NAME_SIZE); - memcpy(info.lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE); - - /* error in case values were truncated */ - if (info.lo_device != info64->lo_device || - info.lo_rdevice != info64->lo_rdevice || - info.lo_inode != info64->lo_inode || - info.lo_offset != info64->lo_offset || - info.lo_init[0] != info64->lo_init[0] || - info.lo_init[1] != info64->lo_init[1]) - return -EOVERFLOW; - - if (copy_to_user(arg, &info, sizeof(info))) - return -EFAULT; - return 0; -} - -static int -loop_set_status_compat(struct loop_device *lo, - const struct compat_loop_info __user *arg) -{ - struct loop_info64 info64; - int ret; - - ret = loop_info64_from_compat(arg, &info64); - if (ret < 0) - return ret; - return loop_set_status(lo, &info64); -} - -static int -loop_get_status_compat(struct loop_device *lo, - struct compat_loop_info __user *arg) -{ - struct loop_info64 info64; - int err = 0; - - if (!arg) - err = -EINVAL; - if (!err) - err = loop_get_status(lo, &info64); - if (!err) - err = loop_info64_to_compat(&info64, arg); - return err; -} - -static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct inode *inode = file->f_dentry->d_inode; - struct loop_device *lo = inode->i_bdev->bd_disk->private_data; - int err; - - lock_kernel(); - switch(cmd) { - case LOOP_SET_STATUS: - mutex_lock(&lo->lo_ctl_mutex); - err = loop_set_status_compat( - lo, (const struct compat_loop_info __user *) arg); - mutex_unlock(&lo->lo_ctl_mutex); - break; - case LOOP_GET_STATUS: - mutex_lock(&lo->lo_ctl_mutex); - err = loop_get_status_compat( - lo, (struct compat_loop_info __user *) arg); - mutex_unlock(&lo->lo_ctl_mutex); - break; - case LOOP_CLR_FD: - case LOOP_GET_STATUS64: - case LOOP_SET_STATUS64: - arg = (unsigned long) compat_ptr(arg); - case LOOP_SET_FD: - case LOOP_CHANGE_FD: - err = lo_ioctl(inode, file, cmd, arg); - break; - default: - err = -ENOIOCTLCMD; - break; - } - unlock_kernel(); - return err; -} -#endif - static int lo_open(struct inode *inode, struct file *file) { struct loop_device *lo = inode->i_bdev->bd_disk->private_data; @@ -1349,9 +1201,6 @@ static struct block_device_operations lo_fops = { .open = lo_open, .release = lo_release, .ioctl = lo_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = lo_compat_ioctl, -#endif }; /* @@ -1435,9 +1284,9 @@ static int __init loop_init(void) if (!lo->lo_queue) goto out_mem4; mutex_init(&lo->lo_ctl_mutex); + init_completion(&lo->lo_done); + init_completion(&lo->lo_bh_done); lo->lo_number = i; - lo->lo_thread = NULL; - init_waitqueue_head(&lo->lo_event); spin_lock_init(&lo->lo_lock); disk->major = LOOP_MAJOR; disk->first_minor = i; diff --git a/trunk/drivers/block/nbd.c b/trunk/drivers/block/nbd.c index 9d1035e8d9d8..bdbade9a5cf5 100644 --- a/trunk/drivers/block/nbd.c +++ b/trunk/drivers/block/nbd.c @@ -407,10 +407,10 @@ static void do_nbd_request(request_queue_t * q) struct nbd_device *lo; blkdev_dequeue_request(req); - dprintk(DBG_BLKDEV, "%s: request %p: dequeued (flags=%x)\n", - req->rq_disk->disk_name, req, req->cmd_type); + dprintk(DBG_BLKDEV, "%s: request %p: dequeued (flags=%lx)\n", + req->rq_disk->disk_name, req, req->flags); - if (!blk_fs_request(req)) + if (!(req->flags & REQ_CMD)) goto error_out; lo = req->rq_disk->private_data; @@ -489,7 +489,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file, switch (cmd) { case NBD_DISCONNECT: printk(KERN_INFO "%s: NBD_DISCONNECT\n", lo->disk->disk_name); - sreq.cmd_type = REQ_TYPE_SPECIAL; + sreq.flags = REQ_SPECIAL; nbd_cmd(&sreq) = NBD_CMD_DISC; /* * Set these to sane values in case server implementation diff --git a/trunk/drivers/block/paride/pd.c b/trunk/drivers/block/paride/pd.c index 40a11e567970..2403721f9db1 100644 --- a/trunk/drivers/block/paride/pd.c +++ b/trunk/drivers/block/paride/pd.c @@ -437,7 +437,7 @@ static char *pd_buf; /* buffer for request in progress */ static enum action do_pd_io_start(void) { - if (blk_special_request(pd_req)) { + if (pd_req->flags & REQ_SPECIAL) { phase = pd_special; return pd_special(); } @@ -713,18 +713,20 @@ static void do_pd_request(request_queue_t * q) static int pd_special_command(struct pd_unit *disk, enum action (*func)(struct pd_unit *disk)) { - DECLARE_COMPLETION_ONSTACK(wait); + DECLARE_COMPLETION(wait); struct request rq; int err = 0; memset(&rq, 0, sizeof(rq)); rq.errors = 0; + rq.rq_status = RQ_ACTIVE; rq.rq_disk = disk->gd; rq.ref_count = 1; - rq.end_io_data = &wait; + rq.waiting = &wait; rq.end_io = blk_end_sync_rq; blk_insert_request(disk->gd->queue, &rq, 0, func); wait_for_completion(&wait); + rq.waiting = NULL; if (rq.errors) err = -EIO; blk_put_request(&rq); diff --git a/trunk/drivers/block/pktcdvd.c b/trunk/drivers/block/pktcdvd.c index a6b2aa67c9b2..451b996bba91 100644 --- a/trunk/drivers/block/pktcdvd.c +++ b/trunk/drivers/block/pktcdvd.c @@ -348,7 +348,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command * char sense[SCSI_SENSE_BUFFERSIZE]; request_queue_t *q; struct request *rq; - DECLARE_COMPLETION_ONSTACK(wait); + DECLARE_COMPLETION(wait); int err = 0; q = bdev_get_queue(pd->bdev); @@ -365,17 +365,17 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command * rq->sense = sense; memset(sense, 0, sizeof(sense)); rq->sense_len = 0; - rq->cmd_type = REQ_TYPE_BLOCK_PC; - rq->cmd_flags |= REQ_HARDBARRIER; + rq->flags |= REQ_BLOCK_PC | REQ_HARDBARRIER; if (cgc->quiet) - rq->cmd_flags |= REQ_QUIET; + rq->flags |= REQ_QUIET; memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE); if (sizeof(rq->cmd) > CDROM_PACKET_SIZE) memset(rq->cmd + CDROM_PACKET_SIZE, 0, sizeof(rq->cmd) - CDROM_PACKET_SIZE); rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); rq->ref_count++; - rq->end_io_data = &wait; + rq->flags |= REQ_NOMERGE; + rq->waiting = &wait; rq->end_io = blk_end_sync_rq; elv_add_request(q, rq, ELEVATOR_INSERT_BACK, 1); generic_unplug_device(q); diff --git a/trunk/drivers/block/swim3.c b/trunk/drivers/block/swim3.c index f2305ee792a1..cc42e762396f 100644 --- a/trunk/drivers/block/swim3.c +++ b/trunk/drivers/block/swim3.c @@ -319,8 +319,8 @@ static void start_request(struct floppy_state *fs) printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n", req->rq_disk->disk_name, req->cmd, (long)req->sector, req->nr_sectors, req->buffer); - printk(" errors=%d current_nr_sectors=%ld\n", - req->errors, req->current_nr_sectors); + printk(" rq_status=%d errors=%d current_nr_sectors=%ld\n", + req->rq_status, req->errors, req->current_nr_sectors); #endif if (req->sector < 0 || req->sector >= fs->total_secs) { diff --git a/trunk/drivers/block/swim_iop.c b/trunk/drivers/block/swim_iop.c index dfda796eba56..89e3c2f8b776 100644 --- a/trunk/drivers/block/swim_iop.c +++ b/trunk/drivers/block/swim_iop.c @@ -529,8 +529,8 @@ static void start_request(struct floppy_state *fs) printk("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%ld buf=%p\n", CURRENT->rq_disk->disk_name, CURRENT->cmd, CURRENT->sector, CURRENT->nr_sectors, CURRENT->buffer); - printk(" errors=%d current_nr_sectors=%ld\n", - CURRENT->errors, CURRENT->current_nr_sectors); + printk(" rq_status=%d errors=%d current_nr_sectors=%ld\n", + CURRENT->rq_status, CURRENT->errors, CURRENT->current_nr_sectors); #endif if (CURRENT->sector < 0 || CURRENT->sector >= fs->total_secs) { diff --git a/trunk/drivers/block/ub.c b/trunk/drivers/block/ub.c index 45a8f402b07b..d62b49fbf10c 100644 --- a/trunk/drivers/block/ub.c +++ b/trunk/drivers/block/ub.c @@ -358,7 +358,7 @@ static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun, struct ub_scsi_cmd *cmd, struct ub_request *urq); static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd); -static void ub_end_rq(struct request *rq, unsigned int status); +static void ub_end_rq(struct request *rq, int uptodate); static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun, struct ub_request *urq, struct ub_scsi_cmd *cmd); static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd); @@ -639,15 +639,9 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) struct ub_request *urq; int n_elem; - if (atomic_read(&sc->poison)) { - blkdev_dequeue_request(rq); - ub_end_rq(rq, DID_NO_CONNECT << 16); - return 0; - } - - if (lun->changed && !blk_pc_request(rq)) { + if (atomic_read(&sc->poison) || lun->changed) { blkdev_dequeue_request(rq); - ub_end_rq(rq, SAM_STAT_CHECK_CONDITION); + ub_end_rq(rq, 0); return 0; } @@ -699,7 +693,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) drop: ub_put_cmd(lun, cmd); - ub_end_rq(rq, DID_ERROR << 16); + ub_end_rq(rq, 0); return 0; } @@ -767,53 +761,47 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) struct ub_lun *lun = cmd->lun; struct ub_request *urq = cmd->back; struct request *rq; - unsigned int scsi_status; + int uptodate; rq = urq->rq; if (cmd->error == 0) { + uptodate = 1; + if (blk_pc_request(rq)) { if (cmd->act_len >= rq->data_len) rq->data_len = 0; else rq->data_len -= cmd->act_len; } - scsi_status = 0; } else { + uptodate = 0; + if (blk_pc_request(rq)) { /* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */ memcpy(rq->sense, sc->top_sense, UB_SENSE_SIZE); rq->sense_len = UB_SENSE_SIZE; if (sc->top_sense[0] != 0) - scsi_status = SAM_STAT_CHECK_CONDITION; + rq->errors = SAM_STAT_CHECK_CONDITION; else - scsi_status = DID_ERROR << 16; + rq->errors = DID_ERROR << 16; } else { if (cmd->error == -EIO) { if (ub_rw_cmd_retry(sc, lun, urq, cmd) == 0) return; } - scsi_status = SAM_STAT_CHECK_CONDITION; } } urq->rq = NULL; ub_put_cmd(lun, cmd); - ub_end_rq(rq, scsi_status); + ub_end_rq(rq, uptodate); blk_start_queue(lun->disk->queue); } -static void ub_end_rq(struct request *rq, unsigned int scsi_status) +static void ub_end_rq(struct request *rq, int uptodate) { - int uptodate; - - if (scsi_status == 0) { - uptodate = 1; - } else { - uptodate = 0; - rq->errors = scsi_status; - } end_that_request_first(rq, uptodate, rq->hard_nr_sectors); end_that_request_last(rq, uptodate); } diff --git a/trunk/drivers/block/xd.c b/trunk/drivers/block/xd.c index ebf3025721d1..e828e4cbd3e1 100644 --- a/trunk/drivers/block/xd.c +++ b/trunk/drivers/block/xd.c @@ -313,7 +313,7 @@ static void do_xd_request (request_queue_t * q) int res = 0; int retry; - if (!blk_fs_request(req)) { + if (!(req->flags & REQ_CMD)) { end_request(req, 0); continue; } diff --git a/trunk/drivers/bluetooth/bfusb.c b/trunk/drivers/bluetooth/bfusb.c index efcc28ec9d9a..23f96213f4ac 100644 --- a/trunk/drivers/bluetooth/bfusb.c +++ b/trunk/drivers/bluetooth/bfusb.c @@ -2,7 +2,7 @@ * * AVM BlueFRITZ! USB driver * - * Copyright (C) 2003-2006 Marcel Holtmann + * Copyright (C) 2003 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -59,6 +59,7 @@ static struct usb_device_id bfusb_table[] = { MODULE_DEVICE_TABLE(usb, bfusb_table); + #define BFUSB_MAX_BLOCK_SIZE 256 #define BFUSB_BLOCK_TIMEOUT 3000 @@ -69,7 +70,7 @@ MODULE_DEVICE_TABLE(usb, bfusb_table); #define BFUSB_MAX_BULK_TX 2 #define BFUSB_MAX_BULK_RX 2 -struct bfusb_data { +struct bfusb { struct hci_dev *hdev; unsigned long state; @@ -91,136 +92,137 @@ struct bfusb_data { struct sk_buff_head completed_q; }; -struct bfusb_data_scb { +struct bfusb_scb { struct urb *urb; }; static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs); static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs); -static struct urb *bfusb_get_completed(struct bfusb_data *data) +static struct urb *bfusb_get_completed(struct bfusb *bfusb) { struct sk_buff *skb; struct urb *urb = NULL; - BT_DBG("bfusb %p", data); + BT_DBG("bfusb %p", bfusb); - skb = skb_dequeue(&data->completed_q); + skb = skb_dequeue(&bfusb->completed_q); if (skb) { - urb = ((struct bfusb_data_scb *) skb->cb)->urb; + urb = ((struct bfusb_scb *) skb->cb)->urb; kfree_skb(skb); } return urb; } -static void bfusb_unlink_urbs(struct bfusb_data *data) +static void bfusb_unlink_urbs(struct bfusb *bfusb) { struct sk_buff *skb; struct urb *urb; - BT_DBG("bfusb %p", data); + BT_DBG("bfusb %p", bfusb); - while ((skb = skb_dequeue(&data->pending_q))) { - urb = ((struct bfusb_data_scb *) skb->cb)->urb; + while ((skb = skb_dequeue(&bfusb->pending_q))) { + urb = ((struct bfusb_scb *) skb->cb)->urb; usb_kill_urb(urb); - skb_queue_tail(&data->completed_q, skb); + skb_queue_tail(&bfusb->completed_q, skb); } - while ((urb = bfusb_get_completed(data))) + while ((urb = bfusb_get_completed(bfusb))) usb_free_urb(urb); } -static int bfusb_send_bulk(struct bfusb_data *data, struct sk_buff *skb) + +static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb) { - struct bfusb_data_scb *scb = (void *) skb->cb; - struct urb *urb = bfusb_get_completed(data); + struct bfusb_scb *scb = (void *) skb->cb; + struct urb *urb = bfusb_get_completed(bfusb); int err, pipe; - BT_DBG("bfusb %p skb %p len %d", data, skb, skb->len); + BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len); if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC))) return -ENOMEM; - pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep); + pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep); - usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len, + usb_fill_bulk_urb(urb, bfusb->udev, pipe, skb->data, skb->len, bfusb_tx_complete, skb); scb->urb = urb; - skb_queue_tail(&data->pending_q, skb); + skb_queue_tail(&bfusb->pending_q, skb); err = usb_submit_urb(urb, GFP_ATOMIC); if (err) { BT_ERR("%s bulk tx submit failed urb %p err %d", - data->hdev->name, urb, err); - skb_unlink(skb, &data->pending_q); + bfusb->hdev->name, urb, err); + skb_unlink(skb, &bfusb->pending_q); usb_free_urb(urb); } else - atomic_inc(&data->pending_tx); + atomic_inc(&bfusb->pending_tx); return err; } -static void bfusb_tx_wakeup(struct bfusb_data *data) +static void bfusb_tx_wakeup(struct bfusb *bfusb) { struct sk_buff *skb; - BT_DBG("bfusb %p", data); + BT_DBG("bfusb %p", bfusb); - if (test_and_set_bit(BFUSB_TX_PROCESS, &data->state)) { - set_bit(BFUSB_TX_WAKEUP, &data->state); + if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) { + set_bit(BFUSB_TX_WAKEUP, &bfusb->state); return; } do { - clear_bit(BFUSB_TX_WAKEUP, &data->state); + clear_bit(BFUSB_TX_WAKEUP, &bfusb->state); - while ((atomic_read(&data->pending_tx) < BFUSB_MAX_BULK_TX) && - (skb = skb_dequeue(&data->transmit_q))) { - if (bfusb_send_bulk(data, skb) < 0) { - skb_queue_head(&data->transmit_q, skb); + while ((atomic_read(&bfusb->pending_tx) < BFUSB_MAX_BULK_TX) && + (skb = skb_dequeue(&bfusb->transmit_q))) { + if (bfusb_send_bulk(bfusb, skb) < 0) { + skb_queue_head(&bfusb->transmit_q, skb); break; } } - } while (test_bit(BFUSB_TX_WAKEUP, &data->state)); + } while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state)); - clear_bit(BFUSB_TX_PROCESS, &data->state); + clear_bit(BFUSB_TX_PROCESS, &bfusb->state); } static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs) { struct sk_buff *skb = (struct sk_buff *) urb->context; - struct bfusb_data *data = (struct bfusb_data *) skb->dev; + struct bfusb *bfusb = (struct bfusb *) skb->dev; - BT_DBG("bfusb %p urb %p skb %p len %d", data, urb, skb, skb->len); + BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len); - atomic_dec(&data->pending_tx); + atomic_dec(&bfusb->pending_tx); - if (!test_bit(HCI_RUNNING, &data->hdev->flags)) + if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags)) return; if (!urb->status) - data->hdev->stat.byte_tx += skb->len; + bfusb->hdev->stat.byte_tx += skb->len; else - data->hdev->stat.err_tx++; + bfusb->hdev->stat.err_tx++; - read_lock(&data->lock); + read_lock(&bfusb->lock); - skb_unlink(skb, &data->pending_q); - skb_queue_tail(&data->completed_q, skb); + skb_unlink(skb, &bfusb->pending_q); + skb_queue_tail(&bfusb->completed_q, skb); - bfusb_tx_wakeup(data); + bfusb_tx_wakeup(bfusb); - read_unlock(&data->lock); + read_unlock(&bfusb->lock); } -static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb) +static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb) { - struct bfusb_data_scb *scb; + struct bfusb_scb *scb; struct sk_buff *skb; int err, pipe, size = HCI_MAX_FRAME_SIZE + 32; @@ -229,29 +231,28 @@ static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb) if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC))) return -ENOMEM; - skb = bt_skb_alloc(size, GFP_ATOMIC); - if (!skb) { + if (!(skb = bt_skb_alloc(size, GFP_ATOMIC))) { usb_free_urb(urb); return -ENOMEM; } - skb->dev = (void *) data; + skb->dev = (void *) bfusb; - scb = (struct bfusb_data_scb *) skb->cb; + scb = (struct bfusb_scb *) skb->cb; scb->urb = urb; - pipe = usb_rcvbulkpipe(data->udev, data->bulk_in_ep); + pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep); - usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, size, + usb_fill_bulk_urb(urb, bfusb->udev, pipe, skb->data, size, bfusb_rx_complete, skb); - skb_queue_tail(&data->pending_q, skb); + skb_queue_tail(&bfusb->pending_q, skb); err = usb_submit_urb(urb, GFP_ATOMIC); if (err) { BT_ERR("%s bulk rx submit failed urb %p err %d", - data->hdev->name, urb, err); - skb_unlink(skb, &data->pending_q); + bfusb->hdev->name, urb, err); + skb_unlink(skb, &bfusb->pending_q); kfree_skb(skb); usb_free_urb(urb); } @@ -259,15 +260,15 @@ static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb) return err; } -static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned char *buf, int len) +static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len) { - BT_DBG("bfusb %p hdr 0x%02x data %p len %d", data, hdr, buf, len); + BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len); if (hdr & 0x10) { - BT_ERR("%s error in block", data->hdev->name); - if (data->reassembly) - kfree_skb(data->reassembly); - data->reassembly = NULL; + BT_ERR("%s error in block", bfusb->hdev->name); + if (bfusb->reassembly) + kfree_skb(bfusb->reassembly); + bfusb->reassembly = NULL; return -EIO; } @@ -276,46 +277,46 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch unsigned char pkt_type; int pkt_len = 0; - if (data->reassembly) { - BT_ERR("%s unexpected start block", data->hdev->name); - kfree_skb(data->reassembly); - data->reassembly = NULL; + if (bfusb->reassembly) { + BT_ERR("%s unexpected start block", bfusb->hdev->name); + kfree_skb(bfusb->reassembly); + bfusb->reassembly = NULL; } if (len < 1) { - BT_ERR("%s no packet type found", data->hdev->name); + BT_ERR("%s no packet type found", bfusb->hdev->name); return -EPROTO; } - pkt_type = *buf++; len--; + pkt_type = *data++; len--; switch (pkt_type) { case HCI_EVENT_PKT: if (len >= HCI_EVENT_HDR_SIZE) { - struct hci_event_hdr *hdr = (struct hci_event_hdr *) buf; + struct hci_event_hdr *hdr = (struct hci_event_hdr *) data; pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen; } else { - BT_ERR("%s event block is too short", data->hdev->name); + BT_ERR("%s event block is too short", bfusb->hdev->name); return -EILSEQ; } break; case HCI_ACLDATA_PKT: if (len >= HCI_ACL_HDR_SIZE) { - struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) buf; + struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) data; pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen); } else { - BT_ERR("%s data block is too short", data->hdev->name); + BT_ERR("%s data block is too short", bfusb->hdev->name); return -EILSEQ; } break; case HCI_SCODATA_PKT: if (len >= HCI_SCO_HDR_SIZE) { - struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) buf; + struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) data; pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen; } else { - BT_ERR("%s audio block is too short", data->hdev->name); + BT_ERR("%s audio block is too short", bfusb->hdev->name); return -EILSEQ; } break; @@ -323,27 +324,27 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch skb = bt_skb_alloc(pkt_len, GFP_ATOMIC); if (!skb) { - BT_ERR("%s no memory for the packet", data->hdev->name); + BT_ERR("%s no memory for the packet", bfusb->hdev->name); return -ENOMEM; } - skb->dev = (void *) data->hdev; + skb->dev = (void *) bfusb->hdev; bt_cb(skb)->pkt_type = pkt_type; - data->reassembly = skb; + bfusb->reassembly = skb; } else { - if (!data->reassembly) { - BT_ERR("%s unexpected continuation block", data->hdev->name); + if (!bfusb->reassembly) { + BT_ERR("%s unexpected continuation block", bfusb->hdev->name); return -EIO; } } if (len > 0) - memcpy(skb_put(data->reassembly, len), buf, len); + memcpy(skb_put(bfusb->reassembly, len), data, len); if (hdr & 0x08) { - hci_recv_frame(data->reassembly); - data->reassembly = NULL; + hci_recv_frame(bfusb->reassembly); + bfusb->reassembly = NULL; } return 0; @@ -352,22 +353,22 @@ static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned ch static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs) { struct sk_buff *skb = (struct sk_buff *) urb->context; - struct bfusb_data *data = (struct bfusb_data *) skb->dev; + struct bfusb *bfusb = (struct bfusb *) skb->dev; unsigned char *buf = urb->transfer_buffer; int count = urb->actual_length; int err, hdr, len; BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len); - read_lock(&data->lock); + read_lock(&bfusb->lock); - if (!test_bit(HCI_RUNNING, &data->hdev->flags)) + if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags)) goto unlock; if (urb->status || !count) goto resubmit; - data->hdev->stat.byte_rx += count; + bfusb->hdev->stat.byte_rx += count; skb_put(skb, count); @@ -386,89 +387,90 @@ static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs) if (count < len) { BT_ERR("%s block extends over URB buffer ranges", - data->hdev->name); + bfusb->hdev->name); } if ((hdr & 0xe1) == 0xc1) - bfusb_recv_block(data, hdr, buf, len); + bfusb_recv_block(bfusb, hdr, buf, len); count -= len; buf += len; } - skb_unlink(skb, &data->pending_q); + skb_unlink(skb, &bfusb->pending_q); kfree_skb(skb); - bfusb_rx_submit(data, urb); + bfusb_rx_submit(bfusb, urb); - read_unlock(&data->lock); + read_unlock(&bfusb->lock); return; resubmit: - urb->dev = data->udev; + urb->dev = bfusb->udev; err = usb_submit_urb(urb, GFP_ATOMIC); if (err) { BT_ERR("%s bulk resubmit failed urb %p err %d", - data->hdev->name, urb, err); + bfusb->hdev->name, urb, err); } unlock: - read_unlock(&data->lock); + read_unlock(&bfusb->lock); } + static int bfusb_open(struct hci_dev *hdev) { - struct bfusb_data *data = hdev->driver_data; + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; unsigned long flags; int i, err; - BT_DBG("hdev %p bfusb %p", hdev, data); + BT_DBG("hdev %p bfusb %p", hdev, bfusb); if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) return 0; - write_lock_irqsave(&data->lock, flags); + write_lock_irqsave(&bfusb->lock, flags); - err = bfusb_rx_submit(data, NULL); + err = bfusb_rx_submit(bfusb, NULL); if (!err) { for (i = 1; i < BFUSB_MAX_BULK_RX; i++) - bfusb_rx_submit(data, NULL); + bfusb_rx_submit(bfusb, NULL); } else { clear_bit(HCI_RUNNING, &hdev->flags); } - write_unlock_irqrestore(&data->lock, flags); + write_unlock_irqrestore(&bfusb->lock, flags); return err; } static int bfusb_flush(struct hci_dev *hdev) { - struct bfusb_data *data = hdev->driver_data; + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; - BT_DBG("hdev %p bfusb %p", hdev, data); + BT_DBG("hdev %p bfusb %p", hdev, bfusb); - skb_queue_purge(&data->transmit_q); + skb_queue_purge(&bfusb->transmit_q); return 0; } static int bfusb_close(struct hci_dev *hdev) { - struct bfusb_data *data = hdev->driver_data; + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; unsigned long flags; - BT_DBG("hdev %p bfusb %p", hdev, data); + BT_DBG("hdev %p bfusb %p", hdev, bfusb); if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; - write_lock_irqsave(&data->lock, flags); - write_unlock_irqrestore(&data->lock, flags); + write_lock_irqsave(&bfusb->lock, flags); + write_unlock_irqrestore(&bfusb->lock, flags); - bfusb_unlink_urbs(data); + bfusb_unlink_urbs(bfusb); bfusb_flush(hdev); return 0; @@ -477,7 +479,7 @@ static int bfusb_close(struct hci_dev *hdev) static int bfusb_send_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *) skb->dev; - struct bfusb_data *data; + struct bfusb *bfusb; struct sk_buff *nskb; unsigned char buf[3]; int sent = 0, size, count; @@ -492,7 +494,7 @@ static int bfusb_send_frame(struct sk_buff *skb) if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; - data = hdev->driver_data; + bfusb = (struct bfusb *) hdev->driver_data; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: @@ -512,13 +514,12 @@ static int bfusb_send_frame(struct sk_buff *skb) count = skb->len; /* Max HCI frame size seems to be 1511 + 1 */ - nskb = bt_skb_alloc(count + 32, GFP_ATOMIC); - if (!nskb) { + if (!(nskb = bt_skb_alloc(count + 32, GFP_ATOMIC))) { BT_ERR("Can't allocate memory for new packet"); return -ENOMEM; } - nskb->dev = (void *) data; + nskb->dev = (void *) bfusb; while (count) { size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE); @@ -535,18 +536,18 @@ static int bfusb_send_frame(struct sk_buff *skb) } /* Don't send frame with multiple size of bulk max packet */ - if ((nskb->len % data->bulk_pkt_size) == 0) { + if ((nskb->len % bfusb->bulk_pkt_size) == 0) { buf[0] = 0xdd; buf[1] = 0x00; memcpy(skb_put(nskb, 2), buf, 2); } - read_lock(&data->lock); + read_lock(&bfusb->lock); - skb_queue_tail(&data->transmit_q, nskb); - bfusb_tx_wakeup(data); + skb_queue_tail(&bfusb->transmit_q, nskb); + bfusb_tx_wakeup(bfusb); - read_unlock(&data->lock); + read_unlock(&bfusb->lock); kfree_skb(skb); @@ -555,11 +556,11 @@ static int bfusb_send_frame(struct sk_buff *skb) static void bfusb_destruct(struct hci_dev *hdev) { - struct bfusb_data *data = hdev->driver_data; + struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; - BT_DBG("hdev %p bfusb %p", hdev, data); + BT_DBG("hdev %p bfusb %p", hdev, bfusb); - kfree(data); + kfree(bfusb); } static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg) @@ -567,24 +568,25 @@ static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg return -ENOIOCTLCMD; } -static int bfusb_load_firmware(struct bfusb_data *data, unsigned char *firmware, int count) + +static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count) { unsigned char *buf; int err, pipe, len, size, sent = 0; - BT_DBG("bfusb %p udev %p", data, data->udev); + BT_DBG("bfusb %p udev %p", bfusb, bfusb->udev); BT_INFO("BlueFRITZ! USB loading firmware"); - pipe = usb_sndctrlpipe(data->udev, 0); + pipe = usb_sndctrlpipe(bfusb->udev, 0); - if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION, + if (usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION, 0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) { BT_ERR("Can't change to loading configuration"); return -EBUSY; } - data->udev->toggle[0] = data->udev->toggle[1] = 0; + bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0; buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC); if (!buf) { @@ -592,14 +594,14 @@ static int bfusb_load_firmware(struct bfusb_data *data, unsigned char *firmware, return -ENOMEM; } - pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep); + pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep); while (count) { size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3); memcpy(buf, firmware + sent, size); - err = usb_bulk_msg(data->udev, pipe, buf, size, + err = usb_bulk_msg(bfusb->udev, pipe, buf, size, &len, BFUSB_BLOCK_TIMEOUT); if (err || (len != size)) { @@ -611,23 +613,21 @@ static int bfusb_load_firmware(struct bfusb_data *data, unsigned char *firmware, count -= size; } - err = usb_bulk_msg(data->udev, pipe, NULL, 0, - &len, BFUSB_BLOCK_TIMEOUT); - if (err < 0) { + if ((err = usb_bulk_msg(bfusb->udev, pipe, NULL, 0, + &len, BFUSB_BLOCK_TIMEOUT)) < 0) { BT_ERR("Error in null packet request"); goto error; } - pipe = usb_sndctrlpipe(data->udev, 0); + pipe = usb_sndctrlpipe(bfusb->udev, 0); - err = usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION, - 0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); - if (err < 0) { + if ((err = usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION, + 0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) { BT_ERR("Can't change to running configuration"); goto error; } - data->udev->toggle[0] = data->udev->toggle[1] = 0; + bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0; BT_INFO("BlueFRITZ! USB device ready"); @@ -637,9 +637,9 @@ static int bfusb_load_firmware(struct bfusb_data *data, unsigned char *firmware, error: kfree(buf); - pipe = usb_sndctrlpipe(data->udev, 0); + pipe = usb_sndctrlpipe(bfusb->udev, 0); - usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION, + usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION, 0, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); return err; @@ -652,7 +652,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i struct usb_host_endpoint *bulk_out_ep; struct usb_host_endpoint *bulk_in_ep; struct hci_dev *hdev; - struct bfusb_data *data; + struct bfusb *bfusb; BT_DBG("intf %p id %p", intf, id); @@ -672,24 +672,23 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i } /* Initialize control structure and load firmware */ - data = kzalloc(sizeof(struct bfusb_data), GFP_KERNEL); - if (!data) { + if (!(bfusb = kzalloc(sizeof(struct bfusb), GFP_KERNEL))) { BT_ERR("Can't allocate memory for control structure"); goto done; } - data->udev = udev; - data->bulk_in_ep = bulk_in_ep->desc.bEndpointAddress; - data->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress; - data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize); + bfusb->udev = udev; + bfusb->bulk_in_ep = bulk_in_ep->desc.bEndpointAddress; + bfusb->bulk_out_ep = bulk_out_ep->desc.bEndpointAddress; + bfusb->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize); - rwlock_init(&data->lock); + rwlock_init(&bfusb->lock); - data->reassembly = NULL; + bfusb->reassembly = NULL; - skb_queue_head_init(&data->transmit_q); - skb_queue_head_init(&data->pending_q); - skb_queue_head_init(&data->completed_q); + skb_queue_head_init(&bfusb->transmit_q); + skb_queue_head_init(&bfusb->pending_q); + skb_queue_head_init(&bfusb->completed_q); if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) { BT_ERR("Firmware request failed"); @@ -698,7 +697,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i BT_DBG("firmware data %p size %d", firmware->data, firmware->size); - if (bfusb_load_firmware(data, firmware->data, firmware->size) < 0) { + if (bfusb_load_firmware(bfusb, firmware->data, firmware->size) < 0) { BT_ERR("Firmware loading failed"); goto release; } @@ -712,10 +711,10 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i goto error; } - data->hdev = hdev; + bfusb->hdev = hdev; hdev->type = HCI_USB; - hdev->driver_data = data; + hdev->driver_data = bfusb; SET_HCIDEV_DEV(hdev, &intf->dev); hdev->open = bfusb_open; @@ -733,7 +732,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i goto error; } - usb_set_intfdata(intf, data); + usb_set_intfdata(intf, bfusb); return 0; @@ -741,7 +740,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i release_firmware(firmware); error: - kfree(data); + kfree(bfusb); done: return -EIO; @@ -749,8 +748,8 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i static void bfusb_disconnect(struct usb_interface *intf) { - struct bfusb_data *data = usb_get_intfdata(intf); - struct hci_dev *hdev = data->hdev; + struct bfusb *bfusb = usb_get_intfdata(intf); + struct hci_dev *hdev = bfusb->hdev; BT_DBG("intf %p", intf); @@ -780,8 +779,7 @@ static int __init bfusb_init(void) BT_INFO("BlueFRITZ! USB driver ver %s", VERSION); - err = usb_register(&bfusb_driver); - if (err < 0) + if ((err = usb_register(&bfusb_driver)) < 0) BT_ERR("Failed to register BlueFRITZ! USB driver"); return err; diff --git a/trunk/drivers/bluetooth/hci_ldisc.c b/trunk/drivers/bluetooth/hci_ldisc.c index 420b645c4c9f..93ba25b7ea32 100644 --- a/trunk/drivers/bluetooth/hci_ldisc.c +++ b/trunk/drivers/bluetooth/hci_ldisc.c @@ -241,11 +241,15 @@ static int hci_uart_send_frame(struct sk_buff *skb) static void hci_uart_destruct(struct hci_dev *hdev) { + struct hci_uart *hu; + if (!hdev) return; BT_DBG("%s", hdev->name); - kfree(hdev->driver_data); + + hu = (struct hci_uart *) hdev->driver_data; + kfree(hu); } /* ------ LDISC part ------ */ @@ -268,7 +272,7 @@ static int hci_uart_tty_open(struct tty_struct *tty) return -EEXIST; if (!(hu = kzalloc(sizeof(struct hci_uart), GFP_KERNEL))) { - BT_ERR("Can't allocate control structure"); + BT_ERR("Can't allocate controll structure"); return -ENFILE; } @@ -356,7 +360,7 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty) * * Return Value: None */ -static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count) +static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count) { struct hci_uart *hu = (void *)tty->disc_data; @@ -371,8 +375,7 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *f hu->hdev->stat.byte_rx += count; spin_unlock(&hu->rx_lock); - if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) && - tty->driver->unthrottle) + if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver->unthrottle) tty->driver->unthrottle(tty); } diff --git a/trunk/drivers/bluetooth/hci_usb.c b/trunk/drivers/bluetooth/hci_usb.c index 0801af4ad2b9..e2d4beac7420 100644 --- a/trunk/drivers/bluetooth/hci_usb.c +++ b/trunk/drivers/bluetooth/hci_usb.c @@ -96,9 +96,6 @@ static struct usb_device_id bluetooth_ids[] = { /* Ericsson with non-standard id */ { USB_DEVICE(0x0bdb, 0x1002) }, - /* Canyon CN-BTU1 with HID interfaces */ - { USB_DEVICE(0x0c10, 0x0000), .driver_info = HCI_RESET }, - { } /* Terminating entry */ }; diff --git a/trunk/drivers/bluetooth/hci_vhci.c b/trunk/drivers/bluetooth/hci_vhci.c index a278d98a9151..aac67a3a6019 100644 --- a/trunk/drivers/bluetooth/hci_vhci.c +++ b/trunk/drivers/bluetooth/hci_vhci.c @@ -2,9 +2,9 @@ * * Bluetooth virtual HCI driver * - * Copyright (C) 2000-2001 Qualcomm Incorporated - * Copyright (C) 2002-2003 Maxim Krasnyansky - * Copyright (C) 2004-2006 Marcel Holtmann + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2004-2005 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -72,21 +72,21 @@ static int vhci_open_dev(struct hci_dev *hdev) static int vhci_close_dev(struct hci_dev *hdev) { - struct vhci_data *data = hdev->driver_data; + struct vhci_data *vhci = hdev->driver_data; if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; - skb_queue_purge(&data->readq); + skb_queue_purge(&vhci->readq); return 0; } static int vhci_flush(struct hci_dev *hdev) { - struct vhci_data *data = hdev->driver_data; + struct vhci_data *vhci = hdev->driver_data; - skb_queue_purge(&data->readq); + skb_queue_purge(&vhci->readq); return 0; } @@ -94,7 +94,7 @@ static int vhci_flush(struct hci_dev *hdev) static int vhci_send_frame(struct sk_buff *skb) { struct hci_dev* hdev = (struct hci_dev *) skb->dev; - struct vhci_data *data; + struct vhci_data *vhci; if (!hdev) { BT_ERR("Frame for unknown HCI device (hdev=NULL)"); @@ -104,15 +104,15 @@ static int vhci_send_frame(struct sk_buff *skb) if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; - data = hdev->driver_data; + vhci = hdev->driver_data; memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); - skb_queue_tail(&data->readq, skb); + skb_queue_tail(&vhci->readq, skb); - if (data->flags & VHCI_FASYNC) - kill_fasync(&data->fasync, SIGIO, POLL_IN); + if (vhci->flags & VHCI_FASYNC) + kill_fasync(&vhci->fasync, SIGIO, POLL_IN); - wake_up_interruptible(&data->read_wait); + wake_up_interruptible(&vhci->read_wait); return 0; } @@ -122,7 +122,7 @@ static void vhci_destruct(struct hci_dev *hdev) kfree(hdev->driver_data); } -static inline ssize_t vhci_get_user(struct vhci_data *data, +static inline ssize_t vhci_get_user(struct vhci_data *vhci, const char __user *buf, size_t count) { struct sk_buff *skb; @@ -139,7 +139,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data, return -EFAULT; } - skb->dev = (void *) data->hdev; + skb->dev = (void *) vhci->hdev; bt_cb(skb)->pkt_type = *((__u8 *) skb->data); skb_pull(skb, 1); @@ -148,7 +148,7 @@ static inline ssize_t vhci_get_user(struct vhci_data *data, return count; } -static inline ssize_t vhci_put_user(struct vhci_data *data, +static inline ssize_t vhci_put_user(struct vhci_data *vhci, struct sk_buff *skb, char __user *buf, int count) { char __user *ptr = buf; @@ -161,43 +161,42 @@ static inline ssize_t vhci_put_user(struct vhci_data *data, total += len; - data->hdev->stat.byte_tx += len; + vhci->hdev->stat.byte_tx += len; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: - data->hdev->stat.cmd_tx++; + vhci->hdev->stat.cmd_tx++; break; case HCI_ACLDATA_PKT: - data->hdev->stat.acl_tx++; + vhci->hdev->stat.acl_tx++; break; case HCI_SCODATA_PKT: - data->hdev->stat.cmd_tx++; + vhci->hdev->stat.cmd_tx++; break; }; return total; } -static loff_t vhci_llseek(struct file *file, loff_t offset, int origin) +static loff_t vhci_llseek(struct file * file, loff_t offset, int origin) { return -ESPIPE; } -static ssize_t vhci_read(struct file *file, - char __user *buf, size_t count, loff_t *pos) +static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, loff_t *pos) { DECLARE_WAITQUEUE(wait, current); - struct vhci_data *data = file->private_data; + struct vhci_data *vhci = file->private_data; struct sk_buff *skb; ssize_t ret = 0; - add_wait_queue(&data->read_wait, &wait); + add_wait_queue(&vhci->read_wait, &wait); while (count) { set_current_state(TASK_INTERRUPTIBLE); - skb = skb_dequeue(&data->readq); + skb = skb_dequeue(&vhci->readq); if (!skb) { if (file->f_flags & O_NONBLOCK) { ret = -EAGAIN; @@ -214,7 +213,7 @@ static ssize_t vhci_read(struct file *file, } if (access_ok(VERIFY_WRITE, buf, count)) - ret = vhci_put_user(data, skb, buf, count); + ret = vhci_put_user(vhci, skb, buf, count); else ret = -EFAULT; @@ -222,7 +221,7 @@ static ssize_t vhci_read(struct file *file, break; } set_current_state(TASK_RUNNING); - remove_wait_queue(&data->read_wait, &wait); + remove_wait_queue(&vhci->read_wait, &wait); return ret; } @@ -230,21 +229,21 @@ static ssize_t vhci_read(struct file *file, static ssize_t vhci_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { - struct vhci_data *data = file->private_data; + struct vhci_data *vhci = file->private_data; if (!access_ok(VERIFY_READ, buf, count)) return -EFAULT; - return vhci_get_user(data, buf, count); + return vhci_get_user(vhci, buf, count); } static unsigned int vhci_poll(struct file *file, poll_table *wait) { - struct vhci_data *data = file->private_data; + struct vhci_data *vhci = file->private_data; - poll_wait(file, &data->read_wait, wait); + poll_wait(file, &vhci->read_wait, wait); - if (!skb_queue_empty(&data->readq)) + if (!skb_queue_empty(&vhci->readq)) return POLLIN | POLLRDNORM; return POLLOUT | POLLWRNORM; @@ -258,26 +257,26 @@ static int vhci_ioctl(struct inode *inode, struct file *file, static int vhci_open(struct inode *inode, struct file *file) { - struct vhci_data *data; + struct vhci_data *vhci; struct hci_dev *hdev; - data = kzalloc(sizeof(struct vhci_data), GFP_KERNEL); - if (!data) + vhci = kzalloc(sizeof(struct vhci_data), GFP_KERNEL); + if (!vhci) return -ENOMEM; - skb_queue_head_init(&data->readq); - init_waitqueue_head(&data->read_wait); + skb_queue_head_init(&vhci->readq); + init_waitqueue_head(&vhci->read_wait); hdev = hci_alloc_dev(); if (!hdev) { - kfree(data); + kfree(vhci); return -ENOMEM; } - data->hdev = hdev; + vhci->hdev = hdev; - hdev->type = HCI_VIRTUAL; - hdev->driver_data = data; + hdev->type = HCI_VHCI; + hdev->driver_data = vhci; hdev->open = vhci_open_dev; hdev->close = vhci_close_dev; @@ -289,20 +288,20 @@ static int vhci_open(struct inode *inode, struct file *file) if (hci_register_dev(hdev) < 0) { BT_ERR("Can't register HCI device"); - kfree(data); + kfree(vhci); hci_free_dev(hdev); return -EBUSY; } - file->private_data = data; + file->private_data = vhci; return nonseekable_open(inode, file); } static int vhci_release(struct inode *inode, struct file *file) { - struct vhci_data *data = file->private_data; - struct hci_dev *hdev = data->hdev; + struct vhci_data *vhci = file->private_data; + struct hci_dev *hdev = vhci->hdev; if (hci_unregister_dev(hdev) < 0) { BT_ERR("Can't unregister HCI device %s", hdev->name); @@ -317,17 +316,17 @@ static int vhci_release(struct inode *inode, struct file *file) static int vhci_fasync(int fd, struct file *file, int on) { - struct vhci_data *data = file->private_data; + struct vhci_data *vhci = file->private_data; int err; - err = fasync_helper(fd, file, on, &data->fasync); + err = fasync_helper(fd, file, on, &vhci->fasync); if (err < 0) return err; if (on) - data->flags |= VHCI_FASYNC; + vhci->flags |= VHCI_FASYNC; else - data->flags &= ~VHCI_FASYNC; + vhci->flags &= ~VHCI_FASYNC; return 0; } diff --git a/trunk/drivers/cdrom/Kconfig b/trunk/drivers/cdrom/Kconfig index 4b12e9031fb3..ff5652d40619 100644 --- a/trunk/drivers/cdrom/Kconfig +++ b/trunk/drivers/cdrom/Kconfig @@ -3,7 +3,7 @@ # menu "Old CD-ROM drivers (not SCSI, not IDE)" - depends on ISA && BLOCK + depends on ISA config CD_NO_IDESCSI bool "Support non-SCSI/IDE/ATAPI CDROM drives" diff --git a/trunk/drivers/cdrom/cdrom.c b/trunk/drivers/cdrom/cdrom.c index b38c84a7a8e3..d239cf8b20bd 100644 --- a/trunk/drivers/cdrom/cdrom.c +++ b/trunk/drivers/cdrom/cdrom.c @@ -2129,7 +2129,7 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf, rq->cmd[9] = 0xf8; rq->cmd_len = 12; - rq->cmd_type = REQ_TYPE_BLOCK_PC; + rq->flags |= REQ_BLOCK_PC; rq->timeout = 60 * HZ; bio = rq->bio; diff --git a/trunk/drivers/cdrom/cdu31a.c b/trunk/drivers/cdrom/cdu31a.c index ccd91c1a84bd..37bdb0163f0d 100644 --- a/trunk/drivers/cdrom/cdu31a.c +++ b/trunk/drivers/cdrom/cdu31a.c @@ -1338,10 +1338,8 @@ static void do_cdu31a_request(request_queue_t * q) } /* WTF??? */ - if (!blk_fs_request(req)) { - end_request(req, 0); + if (!(req->flags & REQ_CMD)) continue; - } if (rq_data_dir(req) == WRITE) { end_request(req, 0); continue; diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index bde1c665d9f4..52ea94b891f5 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -439,14 +439,6 @@ config SGI_MBCS If you have an SGI Altix with an attached SABrick say Y or M here, otherwise say N. -config MSPEC - tristate "Memory special operations driver" - depends on IA64 - help - If you have an ia64 and you want to enable memory special - operations support (formerly known as fetchop), say Y here, - otherwise say N. - source "drivers/serial/Kconfig" config UNIX98_PTYS @@ -747,7 +739,7 @@ config NVRAM config RTC tristate "Enhanced Real Time Clock Support" - depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM && !SUPERH + depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM ---help--- If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you @@ -831,6 +823,14 @@ config DS1302 will get access to the real time clock (or hardware clock) built into your computer. +config S3C2410_RTC + bool "S3C2410 RTC Driver" + depends on ARCH_S3C2410 + help + RTC (Realtime Clock) driver for the clock inbuilt into the + Samsung S3C2410. This can provide periodic interrupt rates + from 1Hz to 64Hz for user programs, and wakeup from Alarm. + config COBALT_LCD bool "Support for Cobalt LCD" depends on MIPS_COBALT @@ -1006,7 +1006,6 @@ config GPIO_VR41XX config RAW_DRIVER tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)" - depends on BLOCK help The raw driver permits block devices to be bound to /dev/raw/rawN. Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O. diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index 19114df59bbd..8c6dfc621520 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -47,7 +47,6 @@ obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o obj-$(CONFIG_HVC_DRIVER) += hvc_console.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o -obj-$(CONFIG_MSPEC) += mspec.o obj-$(CONFIG_MMTIMER) += mmtimer.o obj-$(CONFIG_VIOCONS) += viocons.o obj-$(CONFIG_VIOTAPE) += viotape.o @@ -69,6 +68,7 @@ obj-$(CONFIG_EFI_RTC) += efirtc.o obj-$(CONFIG_SGI_DS1286) += ds1286.o obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o obj-$(CONFIG_DS1302) += ds1302.o +obj-$(CONFIG_S3C2410_RTC) += s3c2410-rtc.o ifeq ($(CONFIG_GENERIC_NVRAM),y) obj-$(CONFIG_NVRAM) += generic_nvram.o else diff --git a/trunk/drivers/char/agp/amd64-agp.c b/trunk/drivers/char/agp/amd64-agp.c index 00b17ae39736..8cd52984cda5 100644 --- a/trunk/drivers/char/agp/amd64-agp.c +++ b/trunk/drivers/char/agp/amd64-agp.c @@ -409,7 +409,7 @@ static int __devinit uli_agp_init(struct pci_dev *pdev) int i; unsigned size = amd64_fetch_size(); printk(KERN_INFO "Setting up ULi AGP.\n"); - dev1 = pci_get_slot (pdev->bus,PCI_DEVFN(0,0)); + dev1 = pci_find_slot ((unsigned int)pdev->bus->number,PCI_DEVFN(0,0)); if (dev1 == NULL) { printk(KERN_INFO PFX "Detected a ULi chipset, " "but could not fine the secondary device.\n"); @@ -442,8 +442,6 @@ static int __devinit uli_agp_init(struct pci_dev *pdev) enuscr= httfea+ (size * 1024 * 1024) - 1; pci_write_config_dword(dev1, ULI_X86_64_HTT_FEA_REG, httfea); pci_write_config_dword(dev1, ULI_X86_64_ENU_SCR_REG, enuscr); - - pci_dev_put(dev1); return 0; } @@ -468,7 +466,7 @@ static int __devinit nforce3_agp_init(struct pci_dev *pdev) printk(KERN_INFO PFX "Setting up Nforce3 AGP.\n"); - dev1 = pci_get_slot(pdev->bus, PCI_DEVFN(11, 0)); + dev1 = pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(11, 0)); if (dev1 == NULL) { printk(KERN_INFO PFX "agpgart: Detected an NVIDIA " "nForce3 chipset, but could not find " @@ -512,8 +510,6 @@ static int __devinit nforce3_agp_init(struct pci_dev *pdev) pci_write_config_dword(dev1, NVIDIA_X86_64_1_APBASE2, apbase); pci_write_config_dword(dev1, NVIDIA_X86_64_1_APLIMIT2, aplimit); - pci_dev_put(dev1); - return 0; } diff --git a/trunk/drivers/char/agp/generic.c b/trunk/drivers/char/agp/generic.c index c39200161688..0dcdb363923f 100644 --- a/trunk/drivers/char/agp/generic.c +++ b/trunk/drivers/char/agp/generic.c @@ -581,21 +581,18 @@ static void agp_v3_parse_one(u32 *requested_mode, u32 *bridge_agpstat, u32 *vga_ * If not, we fall back to x4 mode. */ if ((*bridge_agpstat & AGPSTAT3_8X) && (*vga_agpstat & AGPSTAT3_8X)) { - printk(KERN_INFO PFX "No AGP mode specified. Setting to highest mode " - "supported by bridge & card (x8).\n"); + printk(KERN_INFO PFX "No AGP mode specified. Setting to highest mode supported by bridge & card (x8).\n"); *bridge_agpstat &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD); *vga_agpstat &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD); } else { printk(KERN_INFO PFX "Fell back to AGPx4 mode because"); if (!(*bridge_agpstat & AGPSTAT3_8X)) { - printk(KERN_INFO PFX "bridge couldn't do x8. bridge_agpstat:%x (orig=%x)\n", - *bridge_agpstat, origbridge); + printk("bridge couldn't do x8. bridge_agpstat:%x (orig=%x)\n", *bridge_agpstat, origbridge); *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD); *bridge_agpstat |= AGPSTAT3_4X; } if (!(*vga_agpstat & AGPSTAT3_8X)) { - printk(KERN_INFO PFX "graphics card couldn't do x8. vga_agpstat:%x (orig=%x)\n", - *vga_agpstat, origvga); + printk("graphics card couldn't do x8. vga_agpstat:%x (orig=%x)\n", *vga_agpstat, origvga); *vga_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD); *vga_agpstat |= AGPSTAT3_4X; } diff --git a/trunk/drivers/char/amiserial.c b/trunk/drivers/char/amiserial.c index d0e92ed0a367..9d6713a93ed7 100644 --- a/trunk/drivers/char/amiserial.c +++ b/trunk/drivers/char/amiserial.c @@ -1958,7 +1958,7 @@ static void show_serial_version(void) } -static const struct tty_operations serial_ops = { +static struct tty_operations serial_ops = { .open = rs_open, .close = rs_close, .write = rs_write, diff --git a/trunk/drivers/char/cyclades.c b/trunk/drivers/char/cyclades.c index f85b4eb16618..c1c67281750d 100644 --- a/trunk/drivers/char/cyclades.c +++ b/trunk/drivers/char/cyclades.c @@ -5205,7 +5205,7 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, extra ports are ignored. */ -static const struct tty_operations cy_ops = { +static struct tty_operations cy_ops = { .open = cy_open, .close = cy_close, .write = cy_write, diff --git a/trunk/drivers/char/drm/Kconfig b/trunk/drivers/char/drm/Kconfig index ef833a1c27eb..5278c388d3e7 100644 --- a/trunk/drivers/char/drm/Kconfig +++ b/trunk/drivers/char/drm/Kconfig @@ -60,9 +60,7 @@ config DRM_I830 Choose this option if you have a system that has Intel 830M, 845G, 852GM, 855GM or 865G integrated graphics. If M is selected, the module will be called i830. AGP support is required for this driver - to work. This driver is used by the older X releases X.org 6.7 and - XFree86 4.3. If unsure, build this and i915 as modules and the X server - will load the correct one. + to work. This driver will eventually be replaced by the i915 one. config DRM_I915 tristate "i915 driver" @@ -70,9 +68,8 @@ config DRM_I915 Choose this option if you have a system that has Intel 830M, 845G, 852GM, 855GM 865G or 915G integrated graphics. If M is selected, the module will be called i915. AGP support is required for this driver - to work. This driver is used by the Intel driver in X.org 6.8 and - XFree86 4.4 and above. If unsure, build this and i830 as modules and - the X server will load the correct one. + to work. This driver will eventually replace the I830 driver, when + later release of X start to use the new DDX and DRI. endchoice diff --git a/trunk/drivers/char/drm/Makefile b/trunk/drivers/char/drm/Makefile index 3ad0f648c6b2..9d180c42816c 100644 --- a/trunk/drivers/char/drm/Makefile +++ b/trunk/drivers/char/drm/Makefile @@ -6,7 +6,7 @@ drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \ drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \ drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ - drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o + drm_sysfs.o tdfx-objs := tdfx_drv.o r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o @@ -16,9 +16,9 @@ i830-objs := i830_drv.o i830_dma.o i830_irq.o i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o ffb-objs := ffb_drv.o ffb_context.o -sis-objs := sis_drv.o sis_mm.o +sis-objs := sis_drv.o sis_ds.o sis_mm.o savage-objs := savage_drv.o savage_bci.o savage_state.o -via-objs := via_irq.o via_drv.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o +via-objs := via_irq.o via_drv.o via_ds.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o ifeq ($(CONFIG_COMPAT),y) drm-objs += drm_ioc32.o diff --git a/trunk/drivers/char/drm/drmP.h b/trunk/drivers/char/drm/drmP.h index 7690a59ace04..d2a56182bc35 100644 --- a/trunk/drivers/char/drm/drmP.h +++ b/trunk/drivers/char/drm/drmP.h @@ -79,7 +79,6 @@ #define __OS_HAS_MTRR (defined(CONFIG_MTRR)) #include "drm_os_linux.h" -#include "drm_hashtab.h" /***********************************************************************/ /** \name DRM template customization defaults */ @@ -105,7 +104,7 @@ #define DRM_DEBUG_CODE 2 /**< Include debugging code if > 1, then also include looping detection. */ -#define DRM_MAGIC_HASH_ORDER 4 /**< Size of key hash table. Must be power of 2. */ +#define DRM_HASH_SIZE 16 /**< Size of key hash table. Must be power of 2. */ #define DRM_KERNEL_CONTEXT 0 /**< Change drm_resctx if changed */ #define DRM_RESERVED_CONTEXTS 1 /**< Change drm_resctx if changed */ #define DRM_LOOPING_LIMIT 5000000 @@ -135,12 +134,19 @@ #define DRM_MEM_CTXBITMAP 18 #define DRM_MEM_STUB 19 #define DRM_MEM_SGLISTS 20 -#define DRM_MEM_CTXLIST 21 -#define DRM_MEM_MM 22 -#define DRM_MEM_HASHTAB 23 +#define DRM_MEM_CTXLIST 21 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) -#define DRM_MAP_HASH_OFFSET 0x10000000 + +/*@}*/ + +/***********************************************************************/ +/** \name Backward compatibility section */ +/*@{*/ + +#define DRM_RPR_ARG(vma) vma, + +#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) /*@}*/ @@ -205,6 +211,8 @@ /*@{*/ #define DRM_ARRAY_SIZE(x) ARRAY_SIZE(x) +#define DRM_MIN(a,b) min(a,b) +#define DRM_MAX(a,b) max(a,b) #define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1)) #define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x)) @@ -278,8 +286,7 @@ typedef struct drm_devstate { } drm_devstate_t; typedef struct drm_magic_entry { - drm_hash_item_t hash_item; - struct list_head head; + drm_magic_t magic; struct drm_file *priv; struct drm_magic_entry *next; } drm_magic_entry_t; @@ -486,7 +493,6 @@ typedef struct drm_sigdata { */ typedef struct drm_map_list { struct list_head head; /**< list head */ - drm_hash_item_t hash; drm_map_t *map; /**< mapping */ unsigned int user_token; } drm_map_list_t; @@ -521,22 +527,6 @@ typedef struct ati_pcigart_info { drm_local_map_t mapping; } drm_ati_pcigart_info; -/* - * Generic memory manager structs - */ -typedef struct drm_mm_node { - struct list_head fl_entry; - struct list_head ml_entry; - int free; - unsigned long start; - unsigned long size; - void *private; -} drm_mm_node_t; - -typedef struct drm_mm { - drm_mm_node_t root_node; -} drm_mm_t; - /** * DRM driver structure. This structure represent the common code for * a family of cards. There will one drm_device for each card present @@ -656,15 +646,13 @@ typedef struct drm_device { /*@{ */ drm_file_t *file_first; /**< file list head */ drm_file_t *file_last; /**< file list tail */ - drm_open_hash_t magiclist; /**< magic hash table */ - struct list_head magicfree; + drm_magic_head_t magiclist[DRM_HASH_SIZE]; /**< magic hash table */ /*@} */ /** \name Memory management */ /*@{ */ drm_map_list_t *maplist; /**< Linked list of regions */ int map_count; /**< Number of mappable regions */ - drm_open_hash_t map_hash; /**< User token hash table for maps */ /** \name Context handle management */ /*@{ */ @@ -723,8 +711,10 @@ typedef struct drm_device { drm_agp_head_t *agp; /**< AGP data */ struct pci_dev *pdev; /**< PCI device structure */ - int pci_vendor; /**< PCI vendor id */ - int pci_device; /**< PCI device id */ + int pci_domain; /**< PCI bus domain number */ + int pci_bus; /**< PCI bus number */ + int pci_slot; /**< PCI slot number */ + int pci_func; /**< PCI function number */ #ifdef __alpha__ struct pci_controller *hose; #endif @@ -746,12 +736,6 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev, return ((dev->driver->driver_features & feature) ? 1 : 0); } -#ifdef __alpha__ -#define drm_get_pci_domain(dev) dev->hose->bus->number -#else -#define drm_get_pci_domain(dev) 0 -#endif - #if __OS_HAS_AGP static inline int drm_core_has_AGP(struct drm_device *dev) { @@ -1027,18 +1011,6 @@ extern struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head); extern void drm_sysfs_device_remove(struct class_device *class_dev); -/* - * Basic memory manager support (drm_mm.c) - */ -extern drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, - unsigned long size, - unsigned alignment); -extern void drm_mm_put_block(drm_mm_t *mm, drm_mm_node_t *cur); -extern drm_mm_node_t *drm_mm_search_free(const drm_mm_t *mm, unsigned long size, - unsigned alignment, int best_match); -extern int drm_mm_init(drm_mm_t *mm, unsigned long start, unsigned long size); -extern void drm_mm_takedown(drm_mm_t *mm); - /* Inline replacements for DRM_IOREMAP macros */ static __inline__ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev) diff --git a/trunk/drivers/char/drm/drm_auth.c b/trunk/drivers/char/drm/drm_auth.c index c7b19d35bcd6..2a37586a7ee8 100644 --- a/trunk/drivers/char/drm/drm_auth.c +++ b/trunk/drivers/char/drm/drm_auth.c @@ -35,6 +35,20 @@ #include "drmP.h" +/** + * Generate a hash key from a magic. + * + * \param magic magic. + * \return hash key. + * + * The key is the modulus of the hash table size, #DRM_HASH_SIZE, which must be + * a power of 2. + */ +static int drm_hash_magic(drm_magic_t magic) +{ + return magic & (DRM_HASH_SIZE - 1); +} + /** * Find the file with the given magic number. * @@ -49,12 +63,14 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic) { drm_file_t *retval = NULL; drm_magic_entry_t *pt; - drm_hash_item_t *hash; + int hash = drm_hash_magic(magic); mutex_lock(&dev->struct_mutex); - if (!drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) { - pt = drm_hash_entry(hash, drm_magic_entry_t, hash_item); - retval = pt->priv; + for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { + if (pt->magic == magic) { + retval = pt->priv; + break; + } } mutex_unlock(&dev->struct_mutex); return retval; @@ -74,20 +90,28 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic) static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, drm_magic_t magic) { + int hash; drm_magic_entry_t *entry; DRM_DEBUG("%d\n", magic); + hash = drm_hash_magic(magic); entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC); if (!entry) return -ENOMEM; memset(entry, 0, sizeof(*entry)); + entry->magic = magic; entry->priv = priv; + entry->next = NULL; - entry->hash_item.key = (unsigned long)magic; mutex_lock(&dev->struct_mutex); - drm_ht_insert_item(&dev->magiclist, &entry->hash_item); - list_add_tail(&entry->head, &dev->magicfree); + if (dev->magiclist[hash].tail) { + dev->magiclist[hash].tail->next = entry; + dev->magiclist[hash].tail = entry; + } else { + dev->magiclist[hash].head = entry; + dev->magiclist[hash].tail = entry; + } mutex_unlock(&dev->struct_mutex); return 0; @@ -104,24 +128,34 @@ static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, */ static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic) { + drm_magic_entry_t *prev = NULL; drm_magic_entry_t *pt; - drm_hash_item_t *hash; + int hash; DRM_DEBUG("%d\n", magic); + hash = drm_hash_magic(magic); mutex_lock(&dev->struct_mutex); - if (drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; + for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) { + if (pt->magic == magic) { + if (dev->magiclist[hash].head == pt) { + dev->magiclist[hash].head = pt->next; + } + if (dev->magiclist[hash].tail == pt) { + dev->magiclist[hash].tail = prev; + } + if (prev) { + prev->next = pt->next; + } + mutex_unlock(&dev->struct_mutex); + return 0; + } } - pt = drm_hash_entry(hash, drm_magic_entry_t, hash_item); - drm_ht_remove_item(&dev->magiclist, hash); - list_del(&pt->head); mutex_unlock(&dev->struct_mutex); drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); - return 0; + return -EINVAL; } /** diff --git a/trunk/drivers/char/drm/drm_bufs.c b/trunk/drivers/char/drm/drm_bufs.c index 029baea33b62..006b06d29727 100644 --- a/trunk/drivers/char/drm/drm_bufs.c +++ b/trunk/drivers/char/drm/drm_bufs.c @@ -65,29 +65,43 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, return NULL; } -static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash, - unsigned long user_token, int hashed_handle) +/* + * Used to allocate 32-bit handles for mappings. + */ +#define START_RANGE 0x10000000 +#define END_RANGE 0x40000000 + +#ifdef _LP64 +static __inline__ unsigned int HandleID(unsigned long lhandle, + drm_device_t *dev) { - int use_hashed_handle; -#if (BITS_PER_LONG == 64) - use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle); -#elif (BITS_PER_LONG == 32) - use_hashed_handle = hashed_handle; -#else -#error Unsupported long size. Neither 64 nor 32 bits. -#endif + static unsigned int map32_handle = START_RANGE; + unsigned int hash; + + if (lhandle & 0xffffffff00000000) { + hash = map32_handle; + map32_handle += PAGE_SIZE; + if (map32_handle > END_RANGE) + map32_handle = START_RANGE; + } else + hash = lhandle; + + while (1) { + drm_map_list_t *_entry; + list_for_each_entry(_entry, &dev->maplist->head, head) { + if (_entry->user_token == hash) + break; + } + if (&_entry->head == &dev->maplist->head) + return hash; - if (!use_hashed_handle) { - int ret; - hash->key = user_token; - ret = drm_ht_insert_item(&dev->map_hash, hash); - if (ret != -EINVAL) - return ret; + hash += PAGE_SIZE; + map32_handle += PAGE_SIZE; } - return drm_ht_just_insert_please(&dev->map_hash, hash, - user_token, 32 - PAGE_SHIFT - 3, - PAGE_SHIFT, DRM_MAP_HASH_OFFSET); } +#else +# define HandleID(x,dev) (unsigned int)(x) +#endif /** * Ioctl to specify a range of memory that is available for mapping by a non-root process. @@ -109,8 +123,6 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, drm_map_t *map; drm_map_list_t *list; drm_dma_handle_t *dmah; - unsigned long user_token; - int ret; map = drm_alloc(sizeof(*map), DRM_MEM_MAPS); if (!map) @@ -245,20 +257,11 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, mutex_lock(&dev->struct_mutex); list_add(&list->head, &dev->maplist->head); - /* Assign a 32-bit handle */ /* We do it here so that dev->struct_mutex protects the increment */ - user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle : - map->offset; - ret = drm_map_handle(dev, &list->hash, user_token, 0); - if (ret) { - drm_free(map, sizeof(*map), DRM_MEM_MAPS); - drm_free(list, sizeof(*list), DRM_MEM_MAPS); - mutex_unlock(&dev->struct_mutex); - return ret; - } - - list->user_token = list->hash.key; + list->user_token = HandleID(map->type == _DRM_SHM + ? (unsigned long)map->handle + : map->offset, dev); mutex_unlock(&dev->struct_mutex); *maplist = list; @@ -343,7 +346,6 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) if (r_list->map == map) { list_del(list); - drm_ht_remove_key(&dev->map_hash, r_list->user_token); drm_free(list, sizeof(*list), DRM_MEM_MAPS); break; } @@ -439,10 +441,8 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, return -EINVAL; } - if (!map) { - mutex_unlock(&dev->struct_mutex); + if (!map) return -EINVAL; - } /* Register and framebuffer maps are permanent */ if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { diff --git a/trunk/drivers/char/drm/drm_drv.c b/trunk/drivers/char/drm/drm_drv.c index b366c5b1bd16..3c0b882a8e72 100644 --- a/trunk/drivers/char/drm/drm_drv.c +++ b/trunk/drivers/char/drm/drm_drv.c @@ -118,7 +118,7 @@ static drm_ioctl_desc_t drm_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK)] = {drm_wait_vblank, 0}, }; -#define DRIVER_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) +#define DRIVER_IOCTL_COUNT DRM_ARRAY_SIZE( drm_ioctls ) /** * Take down the DRM device. @@ -155,13 +155,12 @@ int drm_lastclose(drm_device_t * dev) del_timer(&dev->timer); /* Clear pid list */ - if (dev->magicfree.next) { - list_for_each_entry_safe(pt, next, &dev->magicfree, head) { - list_del(&pt->head); - drm_ht_remove_item(&dev->magiclist, &pt->hash_item); + for (i = 0; i < DRM_HASH_SIZE; i++) { + for (pt = dev->magiclist[i].head; pt; pt = next) { + next = pt->next; drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); } - drm_ht_remove(&dev->magiclist); + dev->magiclist[i].head = dev->magiclist[i].tail = NULL; } /* Clear AGP information */ @@ -300,7 +299,6 @@ static void drm_cleanup(drm_device_t * dev) if (dev->maplist) { drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); dev->maplist = NULL; - drm_ht_remove(&dev->map_hash); } drm_ctxbitmap_cleanup(dev); diff --git a/trunk/drivers/char/drm/drm_fops.c b/trunk/drivers/char/drm/drm_fops.c index 898f47dafec0..b7f7951c4587 100644 --- a/trunk/drivers/char/drm/drm_fops.c +++ b/trunk/drivers/char/drm/drm_fops.c @@ -53,8 +53,6 @@ static int drm_setup(drm_device_t * dev) return ret; } - dev->magicfree.next = NULL; - /* prebuild the SAREA */ i = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM, _DRM_CONTAINS_LOCK, &map); if (i != 0) @@ -71,11 +69,13 @@ static int drm_setup(drm_device_t * dev) return i; } - for (i = 0; i < ARRAY_SIZE(dev->counts); i++) + for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++) atomic_set(&dev->counts[i], 0); - drm_ht_create(&dev->magiclist, DRM_MAGIC_HASH_ORDER); - INIT_LIST_HEAD(&dev->magicfree); + for (i = 0; i < DRM_HASH_SIZE; i++) { + dev->magiclist[i].head = NULL; + dev->magiclist[i].tail = NULL; + } dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), DRM_MEM_CTXLIST); if (dev->ctxlist == NULL) diff --git a/trunk/drivers/char/drm/drm_hashtab.c b/trunk/drivers/char/drm/drm_hashtab.c deleted file mode 100644 index a0b2d6802ae4..000000000000 --- a/trunk/drivers/char/drm/drm_hashtab.c +++ /dev/null @@ -1,190 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ -/* - * Simple open hash tab implementation. - * - * Authors: - * Thomas Hellström - */ - -#include "drmP.h" -#include "drm_hashtab.h" -#include - -int drm_ht_create(drm_open_hash_t *ht, unsigned int order) -{ - unsigned int i; - - ht->size = 1 << order; - ht->order = order; - ht->fill = 0; - ht->table = vmalloc(ht->size*sizeof(*ht->table)); - if (!ht->table) { - DRM_ERROR("Out of memory for hash table\n"); - return -ENOMEM; - } - for (i=0; i< ht->size; ++i) { - INIT_HLIST_HEAD(&ht->table[i]); - } - return 0; -} - -void drm_ht_verbose_list(drm_open_hash_t *ht, unsigned long key) -{ - drm_hash_item_t *entry; - struct hlist_head *h_list; - struct hlist_node *list; - unsigned int hashed_key; - int count = 0; - - hashed_key = hash_long(key, ht->order); - DRM_DEBUG("Key is 0x%08lx, Hashed key is 0x%08x\n", key, hashed_key); - h_list = &ht->table[hashed_key]; - hlist_for_each(list, h_list) { - entry = hlist_entry(list, drm_hash_item_t, head); - DRM_DEBUG("count %d, key: 0x%08lx\n", count++, entry->key); - } -} - -static struct hlist_node *drm_ht_find_key(drm_open_hash_t *ht, - unsigned long key) -{ - drm_hash_item_t *entry; - struct hlist_head *h_list; - struct hlist_node *list; - unsigned int hashed_key; - - hashed_key = hash_long(key, ht->order); - h_list = &ht->table[hashed_key]; - hlist_for_each(list, h_list) { - entry = hlist_entry(list, drm_hash_item_t, head); - if (entry->key == key) - return list; - if (entry->key > key) - break; - } - return NULL; -} - - -int drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item) -{ - drm_hash_item_t *entry; - struct hlist_head *h_list; - struct hlist_node *list, *parent; - unsigned int hashed_key; - unsigned long key = item->key; - - hashed_key = hash_long(key, ht->order); - h_list = &ht->table[hashed_key]; - parent = NULL; - hlist_for_each(list, h_list) { - entry = hlist_entry(list, drm_hash_item_t, head); - if (entry->key == key) - return -EINVAL; - if (entry->key > key) - break; - parent = list; - } - if (parent) { - hlist_add_after(parent, &item->head); - } else { - hlist_add_head(&item->head, h_list); - } - return 0; -} - -/* - * Just insert an item and return any "bits" bit key that hasn't been - * used before. - */ -int drm_ht_just_insert_please(drm_open_hash_t *ht, drm_hash_item_t *item, - unsigned long seed, int bits, int shift, - unsigned long add) -{ - int ret; - unsigned long mask = (1 << bits) - 1; - unsigned long first, unshifted_key; - - unshifted_key = hash_long(seed, bits); - first = unshifted_key; - do { - item->key = (unshifted_key << shift) + add; - ret = drm_ht_insert_item(ht, item); - if (ret) - unshifted_key = (unshifted_key + 1) & mask; - } while(ret && (unshifted_key != first)); - - if (ret) { - DRM_ERROR("Available key bit space exhausted\n"); - return -EINVAL; - } - return 0; -} - -int drm_ht_find_item(drm_open_hash_t *ht, unsigned long key, - drm_hash_item_t **item) -{ - struct hlist_node *list; - - list = drm_ht_find_key(ht, key); - if (!list) - return -EINVAL; - - *item = hlist_entry(list, drm_hash_item_t, head); - return 0; -} - -int drm_ht_remove_key(drm_open_hash_t *ht, unsigned long key) -{ - struct hlist_node *list; - - list = drm_ht_find_key(ht, key); - if (list) { - hlist_del_init(list); - ht->fill--; - return 0; - } - return -EINVAL; -} - -int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item) -{ - hlist_del_init(&item->head); - ht->fill--; - return 0; -} - -void drm_ht_remove(drm_open_hash_t *ht) -{ - if (ht->table) { - vfree(ht->table); - ht->table = NULL; - } -} - diff --git a/trunk/drivers/char/drm/drm_hashtab.h b/trunk/drivers/char/drm/drm_hashtab.h deleted file mode 100644 index 40afec05bff8..000000000000 --- a/trunk/drivers/char/drm/drm_hashtab.h +++ /dev/null @@ -1,67 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismack, ND. USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ -/* - * Simple open hash tab implementation. - * - * Authors: - * Thomas Hellström - */ - -#ifndef DRM_HASHTAB_H -#define DRM_HASHTAB_H - -#define drm_hash_entry(_ptr, _type, _member) container_of(_ptr, _type, _member) - -typedef struct drm_hash_item{ - struct hlist_node head; - unsigned long key; -} drm_hash_item_t; - -typedef struct drm_open_hash{ - unsigned int size; - unsigned int order; - unsigned int fill; - struct hlist_head *table; -} drm_open_hash_t; - - -extern int drm_ht_create(drm_open_hash_t *ht, unsigned int order); -extern int drm_ht_insert_item(drm_open_hash_t *ht, drm_hash_item_t *item); -extern int drm_ht_just_insert_please(drm_open_hash_t *ht, drm_hash_item_t *item, - unsigned long seed, int bits, int shift, - unsigned long add); -extern int drm_ht_find_item(drm_open_hash_t *ht, unsigned long key, drm_hash_item_t **item); - -extern void drm_ht_verbose_list(drm_open_hash_t *ht, unsigned long key); -extern int drm_ht_remove_key(drm_open_hash_t *ht, unsigned long key); -extern int drm_ht_remove_item(drm_open_hash_t *ht, drm_hash_item_t *item); -extern void drm_ht_remove(drm_open_hash_t *ht); - - -#endif - diff --git a/trunk/drivers/char/drm/drm_ioc32.c b/trunk/drivers/char/drm/drm_ioc32.c index d4f874520082..e9e2db18952d 100644 --- a/trunk/drivers/char/drm/drm_ioc32.c +++ b/trunk/drivers/char/drm/drm_ioc32.c @@ -1051,7 +1051,7 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) drm_ioctl_compat_t *fn; int ret; - if (nr >= ARRAY_SIZE(drm_compat_ioctls)) + if (nr >= DRM_ARRAY_SIZE(drm_compat_ioctls)) return -ENOTTY; fn = drm_compat_ioctls[nr]; diff --git a/trunk/drivers/char/drm/drm_ioctl.c b/trunk/drivers/char/drm/drm_ioctl.c index 565895547d75..555f323b8a32 100644 --- a/trunk/drivers/char/drm/drm_ioctl.c +++ b/trunk/drivers/char/drm/drm_ioctl.c @@ -127,10 +127,9 @@ int drm_setunique(struct inode *inode, struct file *filp, domain = bus >> 8; bus &= 0xff; - if ((domain != drm_get_pci_domain(dev)) || - (bus != dev->pdev->bus->number) || - (slot != PCI_SLOT(dev->pdev->devfn)) || - (func != PCI_FUNC(dev->pdev->devfn))) + if ((domain != dev->pci_domain) || + (bus != dev->pci_bus) || + (slot != dev->pci_slot) || (func != dev->pci_func)) return -EINVAL; return 0; @@ -141,17 +140,15 @@ static int drm_set_busid(drm_device_t * dev) int len; if (dev->unique != NULL) - return 0; + return EBUSY; dev->unique_len = 40; dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER); if (dev->unique == NULL) - return -ENOMEM; + return ENOMEM; len = snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d", - drm_get_pci_domain(dev), dev->pdev->bus->number, - PCI_SLOT(dev->pdev->devfn), - PCI_FUNC(dev->pdev->devfn)); + dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); if (len > dev->unique_len) DRM_ERROR("Unique buffer overflowed\n"); @@ -160,7 +157,7 @@ static int drm_set_busid(drm_device_t * dev) drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len + 2, DRM_MEM_DRIVER); if (dev->devname == NULL) - return -ENOMEM; + return ENOMEM; sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name, dev->unique); @@ -333,32 +330,27 @@ int drm_setversion(DRM_IOCTL_ARGS) drm_set_version_t retv; int if_version; drm_set_version_t __user *argp = (void __user *)data; - int ret; - if (copy_from_user(&sv, argp, sizeof(sv))) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv)); retv.drm_di_major = DRM_IF_MAJOR; retv.drm_di_minor = DRM_IF_MINOR; retv.drm_dd_major = dev->driver->major; retv.drm_dd_minor = dev->driver->minor; - if (copy_to_user(argp, &retv, sizeof(retv))) - return -EFAULT; + DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv)); if (sv.drm_di_major != -1) { if (sv.drm_di_major != DRM_IF_MAJOR || sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR) - return -EINVAL; + return EINVAL; if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_di_minor); - dev->if_version = max(if_version, dev->if_version); + dev->if_version = DRM_MAX(if_version, dev->if_version); if (sv.drm_di_minor >= 1) { /* * Version 1.1 includes tying of DRM to specific device */ - ret = drm_set_busid(dev); - if (ret) - return ret; + drm_set_busid(dev); } } @@ -366,7 +358,7 @@ int drm_setversion(DRM_IOCTL_ARGS) if (sv.drm_dd_major != dev->driver->major || sv.drm_dd_minor < 0 || sv.drm_dd_minor > dev->driver->minor) - return -EINVAL; + return EINVAL; if (dev->driver->set_version) dev->driver->set_version(dev, &sv); diff --git a/trunk/drivers/char/drm/drm_irq.c b/trunk/drivers/char/drm/drm_irq.c index 4553a3a1e496..ebdb7182c4fd 100644 --- a/trunk/drivers/char/drm/drm_irq.c +++ b/trunk/drivers/char/drm/drm_irq.c @@ -64,9 +64,9 @@ int drm_irq_by_busid(struct inode *inode, struct file *filp, if (copy_from_user(&p, argp, sizeof(p))) return -EFAULT; - if ((p.busnum >> 8) != drm_get_pci_domain(dev) || - (p.busnum & 0xff) != dev->pdev->bus->number || - p.devnum != PCI_SLOT(dev->pdev->devfn) || p.funcnum != PCI_FUNC(dev->pdev->devfn)) + if ((p.busnum >> 8) != dev->pci_domain || + (p.busnum & 0xff) != dev->pci_bus || + p.devnum != dev->pci_slot || p.funcnum != dev->pci_func) return -EINVAL; p.irq = dev->irq; @@ -255,8 +255,7 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) if (!dev->irq) return -EINVAL; - if (copy_from_user(&vblwait, argp, sizeof(vblwait))) - return -EFAULT; + DRM_COPY_FROM_USER_IOCTL(vblwait, argp, sizeof(vblwait)); switch (vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK) { case _DRM_VBLANK_RELATIVE: @@ -330,8 +329,7 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) } done: - if (copy_to_user(argp, &vblwait, sizeof(vblwait))) - return -EFAULT; + DRM_COPY_TO_USER_IOCTL(argp, vblwait, sizeof(vblwait)); return ret; } diff --git a/trunk/drivers/char/drm/drm_mm.c b/trunk/drivers/char/drm/drm_mm.c deleted file mode 100644 index 617526bd5b0c..000000000000 --- a/trunk/drivers/char/drm/drm_mm.c +++ /dev/null @@ -1,201 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ - -/* - * Generic simple memory manager implementation. Intended to be used as a base - * class implementation for more advanced memory managers. - * - * Note that the algorithm used is quite simple and there might be substantial - * performance gains if a smarter free list is implemented. Currently it is just an - * unordered stack of free regions. This could easily be improved if an RB-tree - * is used instead. At least if we expect heavy fragmentation. - * - * Aligned allocations can also see improvement. - * - * Authors: - * Thomas Hellström - */ - -#include "drmP.h" - -drm_mm_node_t *drm_mm_get_block(drm_mm_node_t * parent, - unsigned long size, unsigned alignment) -{ - - drm_mm_node_t *child; - - if (alignment) - size += alignment - 1; - - if (parent->size == size) { - list_del_init(&parent->fl_entry); - parent->free = 0; - return parent; - } else { - child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM); - if (!child) - return NULL; - - INIT_LIST_HEAD(&child->ml_entry); - INIT_LIST_HEAD(&child->fl_entry); - - child->free = 0; - child->size = size; - child->start = parent->start; - - list_add_tail(&child->ml_entry, &parent->ml_entry); - parent->size -= size; - parent->start += size; - } - return child; -} - -/* - * Put a block. Merge with the previous and / or next block if they are free. - * Otherwise add to the free stack. - */ - -void drm_mm_put_block(drm_mm_t * mm, drm_mm_node_t * cur) -{ - - drm_mm_node_t *list_root = &mm->root_node; - struct list_head *cur_head = &cur->ml_entry; - struct list_head *root_head = &list_root->ml_entry; - drm_mm_node_t *prev_node = NULL; - drm_mm_node_t *next_node; - - int merged = 0; - - if (cur_head->prev != root_head) { - prev_node = list_entry(cur_head->prev, drm_mm_node_t, ml_entry); - if (prev_node->free) { - prev_node->size += cur->size; - merged = 1; - } - } - if (cur_head->next != root_head) { - next_node = list_entry(cur_head->next, drm_mm_node_t, ml_entry); - if (next_node->free) { - if (merged) { - prev_node->size += next_node->size; - list_del(&next_node->ml_entry); - list_del(&next_node->fl_entry); - drm_free(next_node, sizeof(*next_node), - DRM_MEM_MM); - } else { - next_node->size += cur->size; - next_node->start = cur->start; - merged = 1; - } - } - } - if (!merged) { - cur->free = 1; - list_add(&cur->fl_entry, &list_root->fl_entry); - } else { - list_del(&cur->ml_entry); - drm_free(cur, sizeof(*cur), DRM_MEM_MM); - } -} - -drm_mm_node_t *drm_mm_search_free(const drm_mm_t * mm, - unsigned long size, - unsigned alignment, int best_match) -{ - struct list_head *list; - const struct list_head *free_stack = &mm->root_node.fl_entry; - drm_mm_node_t *entry; - drm_mm_node_t *best; - unsigned long best_size; - - best = NULL; - best_size = ~0UL; - - if (alignment) - size += alignment - 1; - - list_for_each(list, free_stack) { - entry = list_entry(list, drm_mm_node_t, fl_entry); - if (entry->size >= size) { - if (!best_match) - return entry; - if (size < best_size) { - best = entry; - best_size = entry->size; - } - } - } - - return best; -} - -int drm_mm_init(drm_mm_t * mm, unsigned long start, unsigned long size) -{ - drm_mm_node_t *child; - - INIT_LIST_HEAD(&mm->root_node.ml_entry); - INIT_LIST_HEAD(&mm->root_node.fl_entry); - child = (drm_mm_node_t *) drm_alloc(sizeof(*child), DRM_MEM_MM); - if (!child) - return -ENOMEM; - - INIT_LIST_HEAD(&child->ml_entry); - INIT_LIST_HEAD(&child->fl_entry); - - child->start = start; - child->size = size; - child->free = 1; - - list_add(&child->fl_entry, &mm->root_node.fl_entry); - list_add(&child->ml_entry, &mm->root_node.ml_entry); - - return 0; -} - -EXPORT_SYMBOL(drm_mm_init); - -void drm_mm_takedown(drm_mm_t * mm) -{ - struct list_head *bnode = mm->root_node.fl_entry.next; - drm_mm_node_t *entry; - - entry = list_entry(bnode, drm_mm_node_t, fl_entry); - - if (entry->ml_entry.next != &mm->root_node.ml_entry || - entry->fl_entry.next != &mm->root_node.fl_entry) { - DRM_ERROR("Memory manager not clean. Delaying takedown\n"); - return; - } - - list_del(&entry->fl_entry); - list_del(&entry->ml_entry); - - drm_free(entry, sizeof(*entry), DRM_MEM_MM); -} - -EXPORT_SYMBOL(drm_mm_takedown); diff --git a/trunk/drivers/char/drm/drm_pciids.h b/trunk/drivers/char/drm/drm_pciids.h index 09398d5fbd3f..b1bb3c7b568d 100644 --- a/trunk/drivers/char/drm/drm_pciids.h +++ b/trunk/drivers/char/drm/drm_pciids.h @@ -3,13 +3,13 @@ Please contact dri-devel@lists.sf.net to add new cards to this list */ #define radeon_PCI_IDS \ - {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ - {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP}, \ - {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP}, \ + {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ + {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \ + {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ {0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ {0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ @@ -25,35 +25,35 @@ {0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ {0x1002, 0x4155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \ - {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP}, \ + {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ {0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ - {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ + {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \ {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \ - {0x1002, 0x4A48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4B4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \ + {0x1002, 0x4A48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A4D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A4E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4B4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|CHIP_IS_MOBILITY}, \ {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ @@ -62,16 +62,16 @@ {0x1002, 0x4E49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ {0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ {0x1002, 0x4E4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \ - {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \ - {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \ - {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \ - {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \ + {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4E52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4E53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ + {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ + {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ + {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ + {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|CHIP_SINGLE_CRTC}, \ {0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ {0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ {0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \ @@ -80,59 +80,59 @@ {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ - {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \ - {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \ + {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP}, \ + {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY}, \ {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \ {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \ - {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5b64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \ - {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \ - {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ + {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5b64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|CHIP_IS_MOBILITY}, \ + {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_NEW_MEMMAP}, \ + {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|CHIP_IS_IGP|CHIP_IS_MOBILITY|CHIP_NEW_MEMMAP}, \ {0, 0, 0} #define r128_PCI_IDS \ @@ -209,7 +209,6 @@ {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \ {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} @@ -228,10 +227,6 @@ {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3304, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} #define i810_PCI_IDS \ @@ -290,9 +285,5 @@ {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x27a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2972, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ - {0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} diff --git a/trunk/drivers/char/drm/drm_proc.c b/trunk/drivers/char/drm/drm_proc.c index 62d5fe15f046..362a270af0f1 100644 --- a/trunk/drivers/char/drm/drm_proc.c +++ b/trunk/drivers/char/drm/drm_proc.c @@ -510,7 +510,7 @@ static int drm__vma_info(char *buf, char **start, off_t offset, int request, vma->vm_flags & VM_MAYSHARE ? 's' : 'p', vma->vm_flags & VM_LOCKED ? 'l' : '-', vma->vm_flags & VM_IO ? 'i' : '-', - vma->vm_pgoff << PAGE_SHIFT); + VM_OFFSET(vma)); #if defined(__i386__) pgprot = pgprot_val(vma->vm_page_prot); diff --git a/trunk/drivers/char/drm/drm_sman.c b/trunk/drivers/char/drm/drm_sman.c deleted file mode 100644 index 425c82336ee0..000000000000 --- a/trunk/drivers/char/drm/drm_sman.c +++ /dev/null @@ -1,352 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck., ND., USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * - **************************************************************************/ -/* - * Simple memory manager interface that keeps track on allocate regions on a - * per "owner" basis. All regions associated with an "owner" can be released - * with a simple call. Typically if the "owner" exists. The owner is any - * "unsigned long" identifier. Can typically be a pointer to a file private - * struct or a context identifier. - * - * Authors: - * Thomas Hellström - */ - -#include "drm_sman.h" - -typedef struct drm_owner_item { - drm_hash_item_t owner_hash; - struct list_head sman_list; - struct list_head mem_blocks; -} drm_owner_item_t; - -void drm_sman_takedown(drm_sman_t * sman) -{ - drm_ht_remove(&sman->user_hash_tab); - drm_ht_remove(&sman->owner_hash_tab); - if (sman->mm) - drm_free(sman->mm, sman->num_managers * sizeof(*sman->mm), - DRM_MEM_MM); -} - -EXPORT_SYMBOL(drm_sman_takedown); - -int -drm_sman_init(drm_sman_t * sman, unsigned int num_managers, - unsigned int user_order, unsigned int owner_order) -{ - int ret = 0; - - sman->mm = (drm_sman_mm_t *) drm_calloc(num_managers, sizeof(*sman->mm), - DRM_MEM_MM); - if (!sman->mm) { - ret = -ENOMEM; - goto out; - } - sman->num_managers = num_managers; - INIT_LIST_HEAD(&sman->owner_items); - ret = drm_ht_create(&sman->owner_hash_tab, owner_order); - if (ret) - goto out1; - ret = drm_ht_create(&sman->user_hash_tab, user_order); - if (!ret) - goto out; - - drm_ht_remove(&sman->owner_hash_tab); -out1: - drm_free(sman->mm, num_managers * sizeof(*sman->mm), DRM_MEM_MM); -out: - return ret; -} - -EXPORT_SYMBOL(drm_sman_init); - -static void *drm_sman_mm_allocate(void *private, unsigned long size, - unsigned alignment) -{ - drm_mm_t *mm = (drm_mm_t *) private; - drm_mm_node_t *tmp; - - tmp = drm_mm_search_free(mm, size, alignment, 1); - if (!tmp) { - return NULL; - } - tmp = drm_mm_get_block(tmp, size, alignment); - return tmp; -} - -static void drm_sman_mm_free(void *private, void *ref) -{ - drm_mm_t *mm = (drm_mm_t *) private; - drm_mm_node_t *node = (drm_mm_node_t *) ref; - - drm_mm_put_block(mm, node); -} - -static void drm_sman_mm_destroy(void *private) -{ - drm_mm_t *mm = (drm_mm_t *) private; - drm_mm_takedown(mm); - drm_free(mm, sizeof(*mm), DRM_MEM_MM); -} - -static unsigned long drm_sman_mm_offset(void *private, void *ref) -{ - drm_mm_node_t *node = (drm_mm_node_t *) ref; - return node->start; -} - -int -drm_sman_set_range(drm_sman_t * sman, unsigned int manager, - unsigned long start, unsigned long size) -{ - drm_sman_mm_t *sman_mm; - drm_mm_t *mm; - int ret; - - BUG_ON(manager >= sman->num_managers); - - sman_mm = &sman->mm[manager]; - mm = drm_calloc(1, sizeof(*mm), DRM_MEM_MM); - if (!mm) { - return -ENOMEM; - } - sman_mm->private = mm; - ret = drm_mm_init(mm, start, size); - - if (ret) { - drm_free(mm, sizeof(*mm), DRM_MEM_MM); - return ret; - } - - sman_mm->allocate = drm_sman_mm_allocate; - sman_mm->free = drm_sman_mm_free; - sman_mm->destroy = drm_sman_mm_destroy; - sman_mm->offset = drm_sman_mm_offset; - - return 0; -} - -EXPORT_SYMBOL(drm_sman_set_range); - -int -drm_sman_set_manager(drm_sman_t * sman, unsigned int manager, - drm_sman_mm_t * allocator) -{ - BUG_ON(manager >= sman->num_managers); - sman->mm[manager] = *allocator; - - return 0; -} - -static drm_owner_item_t *drm_sman_get_owner_item(drm_sman_t * sman, - unsigned long owner) -{ - int ret; - drm_hash_item_t *owner_hash_item; - drm_owner_item_t *owner_item; - - ret = drm_ht_find_item(&sman->owner_hash_tab, owner, &owner_hash_item); - if (!ret) { - return drm_hash_entry(owner_hash_item, drm_owner_item_t, - owner_hash); - } - - owner_item = drm_calloc(1, sizeof(*owner_item), DRM_MEM_MM); - if (!owner_item) - goto out; - - INIT_LIST_HEAD(&owner_item->mem_blocks); - owner_item->owner_hash.key = owner; - if (drm_ht_insert_item(&sman->owner_hash_tab, &owner_item->owner_hash)) - goto out1; - - list_add_tail(&owner_item->sman_list, &sman->owner_items); - return owner_item; - -out1: - drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM); -out: - return NULL; -} - -drm_memblock_item_t *drm_sman_alloc(drm_sman_t *sman, unsigned int manager, - unsigned long size, unsigned alignment, - unsigned long owner) -{ - void *tmp; - drm_sman_mm_t *sman_mm; - drm_owner_item_t *owner_item; - drm_memblock_item_t *memblock; - - BUG_ON(manager >= sman->num_managers); - - sman_mm = &sman->mm[manager]; - tmp = sman_mm->allocate(sman_mm->private, size, alignment); - - if (!tmp) { - return NULL; - } - - memblock = drm_calloc(1, sizeof(*memblock), DRM_MEM_MM); - - if (!memblock) - goto out; - - memblock->mm_info = tmp; - memblock->mm = sman_mm; - memblock->sman = sman; - - if (drm_ht_just_insert_please - (&sman->user_hash_tab, &memblock->user_hash, - (unsigned long)memblock, 32, 0, 0)) - goto out1; - - owner_item = drm_sman_get_owner_item(sman, owner); - if (!owner_item) - goto out2; - - list_add_tail(&memblock->owner_list, &owner_item->mem_blocks); - - return memblock; - -out2: - drm_ht_remove_item(&sman->user_hash_tab, &memblock->user_hash); -out1: - drm_free(memblock, sizeof(*memblock), DRM_MEM_MM); -out: - sman_mm->free(sman_mm->private, tmp); - - return NULL; -} - -EXPORT_SYMBOL(drm_sman_alloc); - -static void drm_sman_free(drm_memblock_item_t *item) -{ - drm_sman_t *sman = item->sman; - - list_del(&item->owner_list); - drm_ht_remove_item(&sman->user_hash_tab, &item->user_hash); - item->mm->free(item->mm->private, item->mm_info); - drm_free(item, sizeof(*item), DRM_MEM_MM); -} - -int drm_sman_free_key(drm_sman_t *sman, unsigned int key) -{ - drm_hash_item_t *hash_item; - drm_memblock_item_t *memblock_item; - - if (drm_ht_find_item(&sman->user_hash_tab, key, &hash_item)) - return -EINVAL; - - memblock_item = drm_hash_entry(hash_item, drm_memblock_item_t, user_hash); - drm_sman_free(memblock_item); - return 0; -} - -EXPORT_SYMBOL(drm_sman_free_key); - -static void drm_sman_remove_owner(drm_sman_t *sman, - drm_owner_item_t *owner_item) -{ - list_del(&owner_item->sman_list); - drm_ht_remove_item(&sman->owner_hash_tab, &owner_item->owner_hash); - drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM); -} - -int drm_sman_owner_clean(drm_sman_t *sman, unsigned long owner) -{ - - drm_hash_item_t *hash_item; - drm_owner_item_t *owner_item; - - if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) { - return -1; - } - - owner_item = drm_hash_entry(hash_item, drm_owner_item_t, owner_hash); - if (owner_item->mem_blocks.next == &owner_item->mem_blocks) { - drm_sman_remove_owner(sman, owner_item); - return -1; - } - - return 0; -} - -EXPORT_SYMBOL(drm_sman_owner_clean); - -static void drm_sman_do_owner_cleanup(drm_sman_t *sman, - drm_owner_item_t *owner_item) -{ - drm_memblock_item_t *entry, *next; - - list_for_each_entry_safe(entry, next, &owner_item->mem_blocks, - owner_list) { - drm_sman_free(entry); - } - drm_sman_remove_owner(sman, owner_item); -} - -void drm_sman_owner_cleanup(drm_sman_t *sman, unsigned long owner) -{ - - drm_hash_item_t *hash_item; - drm_owner_item_t *owner_item; - - if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) { - - return; - } - - owner_item = drm_hash_entry(hash_item, drm_owner_item_t, owner_hash); - drm_sman_do_owner_cleanup(sman, owner_item); -} - -EXPORT_SYMBOL(drm_sman_owner_cleanup); - -void drm_sman_cleanup(drm_sman_t *sman) -{ - drm_owner_item_t *entry, *next; - unsigned int i; - drm_sman_mm_t *sman_mm; - - list_for_each_entry_safe(entry, next, &sman->owner_items, sman_list) { - drm_sman_do_owner_cleanup(sman, entry); - } - if (sman->mm) { - for (i = 0; i < sman->num_managers; ++i) { - sman_mm = &sman->mm[i]; - if (sman_mm->private) { - sman_mm->destroy(sman_mm->private); - sman_mm->private = NULL; - } - } - } -} - -EXPORT_SYMBOL(drm_sman_cleanup); diff --git a/trunk/drivers/char/drm/drm_sman.h b/trunk/drivers/char/drm/drm_sman.h deleted file mode 100644 index ddc732a1bf27..000000000000 --- a/trunk/drivers/char/drm/drm_sman.h +++ /dev/null @@ -1,176 +0,0 @@ -/************************************************************************** - * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - **************************************************************************/ -/* - * Simple memory MANager interface that keeps track on allocate regions on a - * per "owner" basis. All regions associated with an "owner" can be released - * with a simple call. Typically if the "owner" exists. The owner is any - * "unsigned long" identifier. Can typically be a pointer to a file private - * struct or a context identifier. - * - * Authors: - * Thomas Hellström - */ - -#ifndef DRM_SMAN_H -#define DRM_SMAN_H - -#include "drmP.h" -#include "drm_hashtab.h" - -/* - * A class that is an abstration of a simple memory allocator. - * The sman implementation provides a default such allocator - * using the drm_mm.c implementation. But the user can replace it. - * See the SiS implementation, which may use the SiS FB kernel module - * for memory management. - */ - -typedef struct drm_sman_mm { - /* private info. If allocated, needs to be destroyed by the destroy - function */ - void *private; - - /* Allocate a memory block with given size and alignment. - Return an opaque reference to the memory block */ - - void *(*allocate) (void *private, unsigned long size, - unsigned alignment); - - /* Free a memory block. "ref" is the opaque reference that we got from - the "alloc" function */ - - void (*free) (void *private, void *ref); - - /* Free all resources associated with this allocator */ - - void (*destroy) (void *private); - - /* Return a memory offset from the opaque reference returned from the - "alloc" function */ - - unsigned long (*offset) (void *private, void *ref); -} drm_sman_mm_t; - -typedef struct drm_memblock_item { - struct list_head owner_list; - drm_hash_item_t user_hash; - void *mm_info; - drm_sman_mm_t *mm; - struct drm_sman *sman; -} drm_memblock_item_t; - -typedef struct drm_sman { - drm_sman_mm_t *mm; - int num_managers; - drm_open_hash_t owner_hash_tab; - drm_open_hash_t user_hash_tab; - struct list_head owner_items; -} drm_sman_t; - -/* - * Take down a memory manager. This function should only be called after a - * successful init and after a call to drm_sman_cleanup. - */ - -extern void drm_sman_takedown(drm_sman_t * sman); - -/* - * Allocate structures for a manager. - * num_managers are the number of memory pools to manage. (VRAM, AGP, ....) - * user_order is the log2 of the number of buckets in the user hash table. - * set this to approximately log2 of the max number of memory regions - * that will be allocated for _all_ pools together. - * owner_order is the log2 of the number of buckets in the owner hash table. - * set this to approximately log2 of - * the number of client file connections that will - * be using the manager. - * - */ - -extern int drm_sman_init(drm_sman_t * sman, unsigned int num_managers, - unsigned int user_order, unsigned int owner_order); - -/* - * Initialize a drm_mm.c allocator. Should be called only once for each - * manager unless a customized allogator is used. - */ - -extern int drm_sman_set_range(drm_sman_t * sman, unsigned int manager, - unsigned long start, unsigned long size); - -/* - * Initialize a customized allocator for one of the managers. - * (See the SiS module). The object pointed to by "allocator" is copied, - * so it can be destroyed after this call. - */ - -extern int drm_sman_set_manager(drm_sman_t * sman, unsigned int mananger, - drm_sman_mm_t * allocator); - -/* - * Allocate a memory block. Aligment is not implemented yet. - */ - -extern drm_memblock_item_t *drm_sman_alloc(drm_sman_t * sman, - unsigned int manager, - unsigned long size, - unsigned alignment, - unsigned long owner); -/* - * Free a memory block identified by its user hash key. - */ - -extern int drm_sman_free_key(drm_sman_t * sman, unsigned int key); - -/* - * returns 1 iff there are no stale memory blocks associated with this owner. - * Typically called to determine if we need to idle the hardware and call - * drm_sman_owner_cleanup. If there are no stale memory blocks, it removes all - * resources associated with owner. - */ - -extern int drm_sman_owner_clean(drm_sman_t * sman, unsigned long owner); - -/* - * Frees all stale memory blocks associated with this owner. Note that this - * requires that the hardware is finished with all blocks, so the graphics engine - * should be idled before this call is made. This function also frees - * any resources associated with "owner" and should be called when owner - * is not going to be referenced anymore. - */ - -extern void drm_sman_owner_cleanup(drm_sman_t * sman, unsigned long owner); - -/* - * Frees all stale memory blocks associated with the memory manager. - * See idling above. - */ - -extern void drm_sman_cleanup(drm_sman_t * sman); - -#endif diff --git a/trunk/drivers/char/drm/drm_stub.c b/trunk/drivers/char/drm/drm_stub.c index 7b1d4e8659ba..9a842a36bb27 100644 --- a/trunk/drivers/char/drm/drm_stub.c +++ b/trunk/drivers/char/drm/drm_stub.c @@ -65,22 +65,22 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, mutex_init(&dev->ctxlist_mutex); dev->pdev = pdev; - dev->pci_device = pdev->device; - dev->pci_vendor = pdev->vendor; #ifdef __alpha__ dev->hose = pdev->sysdata; + dev->pci_domain = dev->hose->bus->number; +#else + dev->pci_domain = 0; #endif + dev->pci_bus = pdev->bus->number; + dev->pci_slot = PCI_SLOT(pdev->devfn); + dev->pci_func = PCI_FUNC(pdev->devfn); dev->irq = pdev->irq; dev->maplist = drm_calloc(1, sizeof(*dev->maplist), DRM_MEM_MAPS); if (dev->maplist == NULL) return -ENOMEM; INIT_LIST_HEAD(&dev->maplist->head); - if (drm_ht_create(&dev->map_hash, 12)) { - drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); - return -ENOMEM; - } /* the DRM has 6 basic counters */ dev->counters = 6; diff --git a/trunk/drivers/char/drm/drm_vm.c b/trunk/drivers/char/drm/drm_vm.c index b40ae438f531..ffd0800ed601 100644 --- a/trunk/drivers/char/drm/drm_vm.c +++ b/trunk/drivers/char/drm/drm_vm.c @@ -59,7 +59,7 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, drm_device_t *dev = priv->head->dev; drm_map_t *map = NULL; drm_map_list_t *r_list; - drm_hash_item_t *hash; + struct list_head *list; /* * Find the right map @@ -70,11 +70,14 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma, if (!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error; - if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) - goto vm_nopage_error; - - r_list = drm_hash_entry(hash, drm_map_list_t, hash); - map = r_list->map; + list_for_each(list, &dev->maplist->head) { + r_list = list_entry(list, drm_map_list_t, head); + map = r_list->map; + if (!map) + continue; + if (r_list->user_token == VM_OFFSET(vma)) + break; + } if (map && map->type == _DRM_AGP) { unsigned long offset = address - vma->vm_start; @@ -464,7 +467,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) dev = priv->head->dev; dma = dev->dma; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", - vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT); + vma->vm_start, vma->vm_end, VM_OFFSET(vma)); /* Length must match exact page count */ if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { @@ -518,11 +521,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->head->dev; drm_map_t *map = NULL; + drm_map_list_t *r_list; unsigned long offset = 0; - drm_hash_item_t *hash; + struct list_head *list; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", - vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT); + vma->vm_start, vma->vm_end, VM_OFFSET(vma)); if (!priv->authenticated) return -EACCES; @@ -531,7 +535,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) * the AGP mapped at physical address 0 * --BenH. */ - if (!(vma->vm_pgoff << PAGE_SHIFT) + if (!VM_OFFSET(vma) #if __OS_HAS_AGP && (!dev->agp || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE) @@ -539,12 +543,23 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) ) return drm_mmap_dma(filp, vma); - if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) { - DRM_ERROR("Could not find map\n"); - return -EINVAL; + /* A sequential search of a linked list is + fine here because: 1) there will only be + about 5-10 entries in the list and, 2) a + DRI client only has to do this mapping + once, so it doesn't have to be optimized + for performance, even if the list was a + bit longer. */ + list_for_each(list, &dev->maplist->head) { + + r_list = list_entry(list, drm_map_list_t, head); + map = r_list->map; + if (!map) + continue; + if (r_list->user_token == VM_OFFSET(vma)) + break; } - map = drm_hash_entry(hash, drm_map_list_t, hash)->map; if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) return -EPERM; @@ -605,7 +620,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) offset = dev->driver->get_reg_ofs(dev); #ifdef __sparc__ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - if (io_remap_pfn_range(vma, vma->vm_start, + if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start, (map->offset + offset) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) diff --git a/trunk/drivers/char/drm/i810_dma.c b/trunk/drivers/char/drm/i810_dma.c index fa2de70f7401..c658dde3633b 100644 --- a/trunk/drivers/char/drm/i810_dma.c +++ b/trunk/drivers/char/drm/i810_dma.c @@ -106,7 +106,7 @@ static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma) unlock_kernel(); if (io_remap_pfn_range(vma, vma->vm_start, - vma->vm_pgoff, + VM_OFFSET(vma) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; @@ -141,10 +141,10 @@ static int i810_map_buffer(drm_buf_t * buf, struct file *filp) MAP_SHARED, buf->bus_address); dev_priv->mmap_buffer = NULL; filp->f_op = old_fops; - if (IS_ERR(buf_priv->virtual)) { + if ((unsigned long)buf_priv->virtual > -1024UL) { /* Real error */ DRM_ERROR("mmap error\n"); - retcode = PTR_ERR(buf_priv->virtual); + retcode = (signed int)buf_priv->virtual; buf_priv->virtual = NULL; } up_write(¤t->mm->mmap_sem); @@ -808,7 +808,7 @@ static void i810_dma_dispatch_vertex(drm_device_t * dev, ((GFX_OP_PRIMITIVE | prim | ((used / 4) - 2))); if (used & 4) { - *(u32 *) ((char *) buf_priv->kernel_virtual + used) = 0; + *(u32 *) ((u32) buf_priv->kernel_virtual + used) = 0; used += 4; } @@ -1166,7 +1166,7 @@ static void i810_dma_dispatch_mc(drm_device_t * dev, drm_buf_t * buf, int used, if (buf_priv->currently_mapped == I810_BUF_MAPPED) { if (used & 4) { - *(u32 *) ((char *) buf_priv->virtual + used) = 0; + *(u32 *) ((u32) buf_priv->virtual + used) = 0; used += 4; } diff --git a/trunk/drivers/char/drm/i830_dma.c b/trunk/drivers/char/drm/i830_dma.c index 4f0e5746ab33..b0f815d8cea8 100644 --- a/trunk/drivers/char/drm/i830_dma.c +++ b/trunk/drivers/char/drm/i830_dma.c @@ -108,7 +108,7 @@ static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma) unlock_kernel(); if (io_remap_pfn_range(vma, vma->vm_start, - vma->vm_pgoff, + VM_OFFSET(vma) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; @@ -146,7 +146,7 @@ static int i830_map_buffer(drm_buf_t * buf, struct file *filp) if (IS_ERR((void *)virtual)) { /* ugh */ /* Real error */ DRM_ERROR("mmap error\n"); - retcode = PTR_ERR((void *)virtual); + retcode = virtual; buf_priv->virtual = NULL; } else { buf_priv->virtual = (void __user *)virtual; diff --git a/trunk/drivers/char/drm/i915_dma.c b/trunk/drivers/char/drm/i915_dma.c index fb7913ff5286..a94233bdbc0e 100644 --- a/trunk/drivers/char/drm/i915_dma.c +++ b/trunk/drivers/char/drm/i915_dma.c @@ -31,11 +31,6 @@ #include "i915_drm.h" #include "i915_drv.h" -#define IS_I965G(dev) (dev->pci_device == 0x2972 || \ - dev->pci_device == 0x2982 || \ - dev->pci_device == 0x2992 || \ - dev->pci_device == 0x29A2) - /* Really want an OS-independent resettable timer. Would like to have * this loop run for (eg) 3 sec, but have the timer reset every time * the head pointer changes, so that EBUSY only happens if the ring @@ -260,7 +255,7 @@ static int i915_dma_init(DRM_IOCTL_ARGS) retcode = i915_dma_resume(dev); break; default: - retcode = DRM_ERR(EINVAL); + retcode = -EINVAL; break; } @@ -352,7 +347,7 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) return DRM_ERR(EINVAL); - BEGIN_LP_RING((dwords+1)&~1); + BEGIN_LP_RING(((dwords+1)&~1)); for (i = 0; i < dwords;) { int cmd, sz; @@ -391,7 +386,7 @@ static int i915_emit_box(drm_device_t * dev, RING_LOCALS; if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) { - return DRM_ERR(EFAULT); + return EFAULT; } if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { @@ -400,40 +395,24 @@ static int i915_emit_box(drm_device_t * dev, return DRM_ERR(EINVAL); } - if (IS_I965G(dev)) { - BEGIN_LP_RING(4); - OUT_RING(GFX_OP_DRAWRECT_INFO_I965); - OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); - OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); - OUT_RING(DR4); - ADVANCE_LP_RING(); - } else { - BEGIN_LP_RING(6); - OUT_RING(GFX_OP_DRAWRECT_INFO); - OUT_RING(DR1); - OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); - OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); - OUT_RING(DR4); - OUT_RING(0); - ADVANCE_LP_RING(); - } + BEGIN_LP_RING(6); + OUT_RING(GFX_OP_DRAWRECT_INFO); + OUT_RING(DR1); + OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); + OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); + OUT_RING(DR4); + OUT_RING(0); + ADVANCE_LP_RING(); return 0; } -/* XXX: Emitting the counter should really be moved to part of the IRQ - * emit. For now, do it in both places: - */ - static void i915_emit_breadcrumb(drm_device_t *dev) { drm_i915_private_t *dev_priv = dev->dev_private; RING_LOCALS; - dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; - - if (dev_priv->counter > 0x7FFFFFFFUL) - dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; + dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; BEGIN_LP_RING(4); OUT_RING(CMD_STORE_DWORD_IDX); diff --git a/trunk/drivers/char/drm/i915_drm.h b/trunk/drivers/char/drm/i915_drm.h index 6af83e613f27..5aa3e0e3bb45 100644 --- a/trunk/drivers/char/drm/i915_drm.h +++ b/trunk/drivers/char/drm/i915_drm.h @@ -98,12 +98,6 @@ typedef struct _drm_i915_sarea { int rotated_size; int rotated_pitch; int virtualX, virtualY; - - unsigned int front_tiled; - unsigned int back_tiled; - unsigned int depth_tiled; - unsigned int rotated_tiled; - unsigned int rotated2_tiled; } drm_i915_sarea_t; /* Flags for perf_boxes diff --git a/trunk/drivers/char/drm/i915_drv.h b/trunk/drivers/char/drm/i915_drv.h index fdc2bf192714..2d565031c002 100644 --- a/trunk/drivers/char/drm/i915_drv.h +++ b/trunk/drivers/char/drm/i915_drv.h @@ -146,9 +146,9 @@ extern void i915_mem_release(drm_device_t * dev, #define BEGIN_LP_RING(n) do { \ if (I915_VERBOSE) \ DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \ - (n), __FUNCTION__); \ - if (dev_priv->ring.space < (n)*4) \ - i915_wait_ring(dev, (n)*4, __FUNCTION__); \ + n, __FUNCTION__); \ + if (dev_priv->ring.space < n*4) \ + i915_wait_ring(dev, n*4, __FUNCTION__); \ outcount = 0; \ outring = dev_priv->ring.tail; \ ringmask = dev_priv->ring.tail_mask; \ @@ -157,7 +157,7 @@ extern void i915_mem_release(drm_device_t * dev, #define OUT_RING(n) do { \ if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \ - *(volatile unsigned int *)(virt + outring) = (n); \ + *(volatile unsigned int *)(virt + outring) = n; \ outcount++; \ outring += 4; \ outring &= ringmask; \ @@ -254,8 +254,6 @@ extern int i915_wait_ring(drm_device_t * dev, int n, const char *caller); #define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) #define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) -#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2) - #define MI_BATCH_BUFFER ((0x30<<23)|1) #define MI_BATCH_BUFFER_START (0x31<<23) #define MI_BATCH_BUFFER_END (0xA<<23) diff --git a/trunk/drivers/char/drm/i915_irq.c b/trunk/drivers/char/drm/i915_irq.c index 0d4a162aa385..cd96cfa430db 100644 --- a/trunk/drivers/char/drm/i915_irq.c +++ b/trunk/drivers/char/drm/i915_irq.c @@ -71,27 +71,21 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) static int i915_emit_irq(drm_device_t * dev) { drm_i915_private_t *dev_priv = dev->dev_private; + u32 ret; RING_LOCALS; i915_kernel_lost_context(dev); DRM_DEBUG("%s\n", __FUNCTION__); - dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; + ret = dev_priv->counter; - if (dev_priv->counter > 0x7FFFFFFFUL) - dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; - - BEGIN_LP_RING(6); - OUT_RING(CMD_STORE_DWORD_IDX); - OUT_RING(20); - OUT_RING(dev_priv->counter); - OUT_RING(0); + BEGIN_LP_RING(2); OUT_RING(0); OUT_RING(GFX_OP_USER_INTERRUPT); ADVANCE_LP_RING(); - - return dev_priv->counter; + + return ret; } static int i915_wait_irq(drm_device_t * dev, int irq_nr) diff --git a/trunk/drivers/char/drm/radeon_cp.c b/trunk/drivers/char/drm/radeon_cp.c index 5ed965688293..5ad43ba7b5aa 100644 --- a/trunk/drivers/char/drm/radeon_cp.c +++ b/trunk/drivers/char/drm/radeon_cp.c @@ -864,13 +864,13 @@ static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv) dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT); - tmp |= RADEON_RB3D_DC_FLUSH_ALL; - RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp); + tmp = RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT); + tmp |= RADEON_RB2D_DC_FLUSH_ALL; + RADEON_WRITE(RADEON_RB2D_DSTCACHE_CTLSTAT, tmp); for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT) - & RADEON_RB3D_DC_BUSY)) { + if (!(RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT) + & RADEON_RB2D_DC_BUSY)) { return 0; } DRM_UDELAY(1); @@ -1130,7 +1130,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, | (dev_priv->fb_location >> 16)); #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base); RADEON_WRITE(RADEON_MC_AGP_LOCATION, (((dev_priv->gart_vm_start - 1 + @@ -1158,7 +1158,7 @@ static void radeon_cp_init_ring_buffer(drm_device_t * dev, dev_priv->ring.tail = cur_read_ptr; #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, dev_priv->ring_rptr->offset - dev->agp->base + dev_priv->gart_vm_start); @@ -1258,13 +1258,6 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) dev_priv->writeback_works = 0; DRM_INFO("writeback forced off\n"); } - - if (!dev_priv->writeback_works) { - /* Disable writeback to avoid unnecessary bus master transfer */ - RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) | - RADEON_RB_NO_UPDATE); - RADEON_WRITE(RADEON_SCRATCH_UMSK, 0); - } } /* Enable or disable PCI-E GART on the chip */ @@ -1302,7 +1295,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) { u32 tmp; - if (dev_priv->flags & RADEON_IS_PCIE) { + if (dev_priv->flags & CHIP_IS_PCIE) { radeon_set_pciegart(dev_priv, on); return; } @@ -1340,22 +1333,20 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) DRM_DEBUG("\n"); /* if we require new memory map but we don't have it fail */ - if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) { - DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n"); + if ((dev_priv->flags & CHIP_NEW_MEMMAP) && !dev_priv->new_memmap) + { + DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX\n"); radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } - if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { + if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP)) + { DRM_DEBUG("Forcing AGP card to PCI mode\n"); - dev_priv->flags &= ~RADEON_IS_AGP; - } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE)) - && !init->is_pci) { - DRM_DEBUG("Restoring AGP flag\n"); - dev_priv->flags |= RADEON_IS_AGP; + dev_priv->flags &= ~CHIP_IS_AGP; } - if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) { + if ((!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg) { DRM_ERROR("PCI GART memory not allocated!\n"); radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); @@ -1498,7 +1489,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) init->sarea_priv_offset); #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { drm_core_ioremap(dev_priv->cp_ring, dev); drm_core_ioremap(dev_priv->ring_rptr, dev); drm_core_ioremap(dev->agp_buffer_map, dev); @@ -1557,7 +1548,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) * align it down. */ #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { base = dev->agp->base; /* Check if valid */ if ((base + dev_priv->gart_size) > dev_priv->fb_location && @@ -1587,7 +1578,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) } #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) + if (dev_priv->flags & CHIP_IS_AGP) dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - dev->agp->base + dev_priv->gart_vm_start); @@ -1613,7 +1604,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK; #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); } else @@ -1633,7 +1624,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) dev_priv->gart_info.mapping.handle; dev_priv->gart_info.is_pcie = - !!(dev_priv->flags & RADEON_IS_PCIE); + !!(dev_priv->flags & CHIP_IS_PCIE); dev_priv->gart_info.gart_table_location = DRM_ATI_GART_FB; @@ -1645,7 +1636,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) DRM_ATI_GART_MAIN; dev_priv->gart_info.addr = NULL; dev_priv->gart_info.bus_addr = 0; - if (dev_priv->flags & RADEON_IS_PCIE) { + if (dev_priv->flags & CHIP_IS_PCIE) { DRM_ERROR ("Cannot use PCI Express without GART in FB memory\n"); radeon_do_cleanup_cp(dev); @@ -1687,7 +1678,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev) drm_irq_uninstall(dev); #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { if (dev_priv->cp_ring != NULL) { drm_core_ioremapfree(dev_priv->cp_ring, dev); dev_priv->cp_ring = NULL; @@ -1742,7 +1733,7 @@ static int radeon_do_resume_cp(drm_device_t * dev) DRM_DEBUG("Starting radeon_do_resume_cp()\n"); #if __OS_HAS_AGP - if (dev_priv->flags & RADEON_IS_AGP) { + if (dev_priv->flags & CHIP_IS_AGP) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); } else @@ -2186,15 +2177,13 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) dev->dev_private = (void *)dev_priv; dev_priv->flags = flags; - switch (flags & RADEON_FAMILY_MASK) { + switch (flags & CHIP_FAMILY_MASK) { case CHIP_R100: case CHIP_RV200: case CHIP_R200: case CHIP_R300: - case CHIP_R350: case CHIP_R420: - case CHIP_RV410: - dev_priv->flags |= RADEON_HAS_HIERZ; + dev_priv->flags |= CHIP_HAS_HIERZ; break; default: /* all other chips have no hierarchical z buffer */ @@ -2202,14 +2191,13 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) } if (drm_device_is_agp(dev)) - dev_priv->flags |= RADEON_IS_AGP; - else if (drm_device_is_pcie(dev)) - dev_priv->flags |= RADEON_IS_PCIE; - else - dev_priv->flags |= RADEON_IS_PCI; + dev_priv->flags |= CHIP_IS_AGP; + + if (drm_device_is_pcie(dev)) + dev_priv->flags |= CHIP_IS_PCIE; DRM_DEBUG("%s card detected\n", - ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); + ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : (((dev_priv->flags & CHIP_IS_PCIE) ? "PCIE" : "PCI")))); return ret; } diff --git a/trunk/drivers/char/drm/radeon_drv.c b/trunk/drivers/char/drm/radeon_drv.c index 2eb652ec6745..eb985c2a31e9 100644 --- a/trunk/drivers/char/drm/radeon_drv.c +++ b/trunk/drivers/char/drm/radeon_drv.c @@ -44,7 +44,7 @@ module_param_named(no_wb, radeon_no_wb, int, 0444); static int dri_library_name(struct drm_device *dev, char *buf) { drm_radeon_private_t *dev_priv = dev->dev_private; - int family = dev_priv->flags & RADEON_FAMILY_MASK; + int family = dev_priv->flags & CHIP_FAMILY_MASK; return snprintf(buf, PAGE_SIZE, "%s\n", (family < CHIP_R200) ? "radeon" : diff --git a/trunk/drivers/char/drm/radeon_drv.h b/trunk/drivers/char/drm/radeon_drv.h index f45cd7f147a5..e5a256f5429c 100644 --- a/trunk/drivers/char/drm/radeon_drv.h +++ b/trunk/drivers/char/drm/radeon_drv.h @@ -133,16 +133,15 @@ enum radeon_cp_microcode_version { * Chip flags */ enum radeon_chip_flags { - RADEON_FAMILY_MASK = 0x0000ffffUL, - RADEON_FLAGS_MASK = 0xffff0000UL, - RADEON_IS_MOBILITY = 0x00010000UL, - RADEON_IS_IGP = 0x00020000UL, - RADEON_SINGLE_CRTC = 0x00040000UL, - RADEON_IS_AGP = 0x00080000UL, - RADEON_HAS_HIERZ = 0x00100000UL, - RADEON_IS_PCIE = 0x00200000UL, - RADEON_NEW_MEMMAP = 0x00400000UL, - RADEON_IS_PCI = 0x00800000UL, + CHIP_FAMILY_MASK = 0x0000ffffUL, + CHIP_FLAGS_MASK = 0xffff0000UL, + CHIP_IS_MOBILITY = 0x00010000UL, + CHIP_IS_IGP = 0x00020000UL, + CHIP_SINGLE_CRTC = 0x00040000UL, + CHIP_IS_AGP = 0x00080000UL, + CHIP_HAS_HIERZ = 0x00100000UL, + CHIP_IS_PCIE = 0x00200000UL, + CHIP_NEW_MEMMAP = 0x00400000UL, }; #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ @@ -425,8 +424,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, #define RADEON_RB3D_COLOROFFSET 0x1c40 #define RADEON_RB3D_COLORPITCH 0x1c48 -#define RADEON_SRC_X_Y 0x1590 - #define RADEON_DP_GUI_MASTER_CNTL 0x146c # define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) # define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) @@ -444,7 +441,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, # define RADEON_ROP3_S 0x00cc0000 # define RADEON_ROP3_P 0x00f00000 #define RADEON_DP_WRITE_MASK 0x16cc -#define RADEON_SRC_PITCH_OFFSET 0x1428 #define RADEON_DST_PITCH_OFFSET 0x142c #define RADEON_DST_PITCH_OFFSET_C 0x1c80 # define RADEON_DST_TILE_LINEAR (0 << 30) @@ -549,11 +545,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, # define RADEON_RB3D_ZC_FREE (1 << 2) # define RADEON_RB3D_ZC_FLUSH_ALL 0x5 # define RADEON_RB3D_ZC_BUSY (1 << 31) -#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c -# define RADEON_RB3D_DC_FLUSH (3 << 0) -# define RADEON_RB3D_DC_FREE (3 << 2) -# define RADEON_RB3D_DC_FLUSH_ALL 0xf -# define RADEON_RB3D_DC_BUSY (1 << 31) #define RADEON_RB3D_ZSTENCILCNTL 0x1c2c # define RADEON_Z_TEST_MASK (7 << 4) # define RADEON_Z_TEST_ALWAYS (7 << 4) @@ -690,7 +681,6 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp, #define RADEON_CP_RB_BASE 0x0700 #define RADEON_CP_RB_CNTL 0x0704 # define RADEON_BUF_SWAP_32BIT (2 << 16) -# define RADEON_RB_NO_UPDATE (1 << 27) #define RADEON_CP_RB_RPTR_ADDR 0x070c #define RADEON_CP_RB_RPTR 0x0710 #define RADEON_CP_RB_WPTR 0x0714 @@ -996,13 +986,13 @@ do { \ } while (0) #define RADEON_FLUSH_CACHE() do { \ - OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB3D_DC_FLUSH ); \ + OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB2D_DC_FLUSH ); \ } while (0) #define RADEON_PURGE_CACHE() do { \ - OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB3D_DC_FLUSH_ALL ); \ + OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB2D_DC_FLUSH_ALL ); \ } while (0) #define RADEON_FLUSH_ZCACHE() do { \ diff --git a/trunk/drivers/char/drm/radeon_state.c b/trunk/drivers/char/drm/radeon_state.c index feac5f005d47..39a7f685e3fd 100644 --- a/trunk/drivers/char/drm/radeon_state.c +++ b/trunk/drivers/char/drm/radeon_state.c @@ -42,11 +42,7 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * drm_file_t * filp_priv, u32 *offset) { - u64 off = *offset; - u32 fb_start = dev_priv->fb_location; - u32 fb_end = fb_start + dev_priv->fb_size - 1; - u32 gart_start = dev_priv->gart_vm_start; - u32 gart_end = gart_start + dev_priv->gart_size - 1; + u32 off = *offset; struct drm_radeon_driver_file_fields *radeon_priv; /* Hrm ... the story of the offset ... So this function converts @@ -66,8 +62,10 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * /* First, the best case, the offset already lands in either the * framebuffer or the GART mapped space */ - if ((off >= fb_start && off <= fb_end) || - (off >= gart_start && off <= gart_end)) + if ((off >= dev_priv->fb_location && + off < (dev_priv->fb_location + dev_priv->fb_size)) || + (off >= dev_priv->gart_vm_start && + off < (dev_priv->gart_vm_start + dev_priv->gart_size))) return 0; /* Ok, that didn't happen... now check if we have a zero based @@ -80,13 +78,16 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * } /* Finally, assume we aimed at a GART offset if beyond the fb */ - if (off > fb_end) - off = off - fb_end - 1 + gart_start; + if (off > (dev_priv->fb_location + dev_priv->fb_size)) + off = off - (dev_priv->fb_location + dev_priv->fb_size) + + dev_priv->gart_vm_start; /* Now recheck and fail if out of bounds */ - if ((off >= fb_start && off <= fb_end) || - (off >= gart_start && off <= gart_end)) { - DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off); + if ((off >= dev_priv->fb_location && + off < (dev_priv->fb_location + dev_priv->fb_size)) || + (off >= dev_priv->gart_vm_start && + off < (dev_priv->gart_vm_start + dev_priv->gart_size))) { + DRM_DEBUG("offset fixed up to 0x%x\n", off); *offset = off; return 0; } @@ -868,7 +869,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev, */ dev_priv->sarea_priv->ctx_owner = 0; - if ((dev_priv->flags & RADEON_HAS_HIERZ) + if ((dev_priv->flags & CHIP_HAS_HIERZ) && (flags & RADEON_USE_HIERZ)) { /* FIXME : reverse engineer that for Rx00 cards */ /* FIXME : the mask supposedly contains low-res z values. So can't set @@ -913,7 +914,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev, for (i = 0; i < nbox; i++) { int tileoffset, nrtilesx, nrtilesy, j; /* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */ - if ((dev_priv->flags & RADEON_HAS_HIERZ) + if ((dev_priv->flags & CHIP_HAS_HIERZ) && !(dev_priv->microcode_version == UCODE_R200)) { /* FIXME : figure this out for r200 (when hierz is enabled). Or maybe r200 actually doesn't need to put the low-res z value into @@ -997,7 +998,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev, } /* TODO don't always clear all hi-level z tiles */ - if ((dev_priv->flags & RADEON_HAS_HIERZ) + if ((dev_priv->flags & CHIP_HAS_HIERZ) && (dev_priv->microcode_version == UCODE_R200) && (flags & RADEON_USE_HIERZ)) /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */ @@ -1269,9 +1270,9 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev) DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", x, y, w, h); - BEGIN_RING(9); + BEGIN_RING(7); - OUT_RING(CP_PACKET0(RADEON_DP_GUI_MASTER_CNTL, 0)); + OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5)); OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_NONE | @@ -1283,7 +1284,6 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev) /* Make this work even if front & back are flipped: */ - OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1)); if (dev_priv->current_page == 0) { OUT_RING(dev_priv->back_pitch_offset); OUT_RING(dev_priv->front_pitch_offset); @@ -1292,7 +1292,6 @@ static void radeon_cp_dispatch_swap(drm_device_t * dev) OUT_RING(dev_priv->back_pitch_offset); } - OUT_RING(CP_PACKET0(RADEON_SRC_X_Y, 2)); OUT_RING((x << 16) | y); OUT_RING((x << 16) | y); OUT_RING((w << 16) | h); @@ -2988,21 +2987,16 @@ static int radeon_cp_getparam(DRM_IOCTL_ARGS) case RADEON_PARAM_GART_TEX_HANDLE: value = dev_priv->gart_textures_offset; break; - case RADEON_PARAM_SCRATCH_OFFSET: - if (!dev_priv->writeback_works) - return DRM_ERR(EINVAL); - value = RADEON_SCRATCH_REG_OFFSET; - break; + case RADEON_PARAM_CARD_TYPE: - if (dev_priv->flags & RADEON_IS_PCIE) + if (dev_priv->flags & CHIP_IS_PCIE) value = RADEON_CARD_PCIE; - else if (dev_priv->flags & RADEON_IS_AGP) + else if (dev_priv->flags & CHIP_IS_AGP) value = RADEON_CARD_AGP; else value = RADEON_CARD_PCI; break; default: - DRM_DEBUG("Invalid parameter %d\n", param.param); return DRM_ERR(EINVAL); } diff --git a/trunk/drivers/char/drm/sis_drv.c b/trunk/drivers/char/drm/sis_drv.c index 3d5b3218b6ff..5e9dc86f2956 100644 --- a/trunk/drivers/char/drm/sis_drv.c +++ b/trunk/drivers/char/drm/sis_drv.c @@ -35,44 +35,11 @@ static struct pci_device_id pciidlist[] = { sisdrv_PCI_IDS }; -static int sis_driver_load(drm_device_t *dev, unsigned long chipset) -{ - drm_sis_private_t *dev_priv; - int ret; - - dev_priv = drm_calloc(1, sizeof(drm_sis_private_t), DRM_MEM_DRIVER); - if (dev_priv == NULL) - return DRM_ERR(ENOMEM); - - dev->dev_private = (void *)dev_priv; - dev_priv->chipset = chipset; - ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); - if (ret) { - drm_free(dev_priv, sizeof(dev_priv), DRM_MEM_DRIVER); - } - - return ret; -} - -static int sis_driver_unload(drm_device_t *dev) -{ - drm_sis_private_t *dev_priv = dev->dev_private; - - drm_sman_takedown(&dev_priv->sman); - drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); - - return 0; -} - static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, - .load = sis_driver_load, - .unload = sis_driver_unload, - .context_dtor = NULL, - .dma_quiescent = sis_idle, - .reclaim_buffers = NULL, - .reclaim_buffers_locked = sis_reclaim_buffers_locked, - .lastclose = sis_lastclose, + .context_ctor = sis_init_context, + .context_dtor = sis_final_context, + .reclaim_buffers = drm_core_reclaim_buffers, .get_map_ofs = drm_core_get_map_ofs, .get_reg_ofs = drm_core_get_reg_ofs, .ioctls = sis_ioctls, diff --git a/trunk/drivers/char/drm/sis_drv.h b/trunk/drivers/char/drm/sis_drv.h index 2b8d6f6ed7c0..e218e5269503 100644 --- a/trunk/drivers/char/drm/sis_drv.h +++ b/trunk/drivers/char/drm/sis_drv.h @@ -31,39 +31,23 @@ /* General customization: */ -#define DRIVER_AUTHOR "SIS, Tungsten Graphics" +#define DRIVER_AUTHOR "SIS" #define DRIVER_NAME "sis" #define DRIVER_DESC "SIS 300/630/540" -#define DRIVER_DATE "20060704" +#define DRIVER_DATE "20030826" #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 1 +#define DRIVER_MINOR 1 +#define DRIVER_PATCHLEVEL 0 -enum sis_family { - SIS_OTHER = 0, - SIS_CHIP_315 = 1, -}; - -#include "drm_sman.h" - -#define SIS_BASE (dev_priv->mmio) -#define SIS_READ(reg) DRM_READ32(SIS_BASE, reg); -#define SIS_WRITE(reg, val) DRM_WRITE32(SIS_BASE, reg, val); +#include "sis_ds.h" typedef struct drm_sis_private { - drm_local_map_t *mmio; - unsigned int idle_fault; - drm_sman_t sman; - unsigned int chipset; - int vram_initialized; - int agp_initialized; - unsigned long vram_offset; - unsigned long agp_offset; + memHeap_t *AGPHeap; + memHeap_t *FBHeap; } drm_sis_private_t; -extern int sis_idle(drm_device_t *dev); -extern void sis_reclaim_buffers_locked(drm_device_t *dev, struct file *filp); -extern void sis_lastclose(drm_device_t *dev); +extern int sis_init_context(drm_device_t * dev, int context); +extern int sis_final_context(drm_device_t * dev, int context); extern drm_ioctl_desc_t sis_ioctls[]; extern int sis_max_ioctl; diff --git a/trunk/drivers/char/drm/sis_ds.c b/trunk/drivers/char/drm/sis_ds.c new file mode 100644 index 000000000000..2e485d482943 --- /dev/null +++ b/trunk/drivers/char/drm/sis_ds.c @@ -0,0 +1,299 @@ +/* sis_ds.c -- Private header for Direct Rendering Manager -*- linux-c -*- + * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw + * + * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Sung-Ching Lin + * + */ + +#include "drmP.h" +#include "drm.h" +#include "sis_ds.h" + +/* Set Data Structure, not check repeated value + * temporarily used + */ + +set_t *setInit(void) +{ + int i; + set_t *set; + + set = (set_t *) drm_alloc(sizeof(set_t), DRM_MEM_DRIVER); + if (set != NULL) { + for (i = 0; i < SET_SIZE; i++) { + set->list[i].free_next = i + 1; + set->list[i].alloc_next = -1; + } + set->list[SET_SIZE - 1].free_next = -1; + set->free = 0; + set->alloc = -1; + set->trace = -1; + } + return set; +} + +int setAdd(set_t * set, ITEM_TYPE item) +{ + int free = set->free; + + if (free != -1) { + set->list[free].val = item; + set->free = set->list[free].free_next; + } else { + return 0; + } + + set->list[free].alloc_next = set->alloc; + set->alloc = free; + set->list[free].free_next = -1; + + return 1; +} + +int setDel(set_t * set, ITEM_TYPE item) +{ + int alloc = set->alloc; + int prev = -1; + + while (alloc != -1) { + if (set->list[alloc].val == item) { + if (prev != -1) + set->list[prev].alloc_next = + set->list[alloc].alloc_next; + else + set->alloc = set->list[alloc].alloc_next; + break; + } + prev = alloc; + alloc = set->list[alloc].alloc_next; + } + + if (alloc == -1) + return 0; + + set->list[alloc].free_next = set->free; + set->free = alloc; + set->list[alloc].alloc_next = -1; + + return 1; +} + +/* setFirst -> setAdd -> setNext is wrong */ + +int setFirst(set_t * set, ITEM_TYPE * item) +{ + if (set->alloc == -1) + return 0; + + *item = set->list[set->alloc].val; + set->trace = set->list[set->alloc].alloc_next; + + return 1; +} + +int setNext(set_t * set, ITEM_TYPE * item) +{ + if (set->trace == -1) + return 0; + + *item = set->list[set->trace].val; + set->trace = set->list[set->trace].alloc_next; + + return 1; +} + +int setDestroy(set_t * set) +{ + drm_free(set, sizeof(set_t), DRM_MEM_DRIVER); + + return 1; +} + +/* + * GLX Hardware Device Driver common code + * Copyright (C) 1999 Wittawat Yamwong + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#define ISFREE(bptr) ((bptr)->free) + +memHeap_t *mmInit(int ofs, int size) +{ + PMemBlock blocks; + + if (size <= 0) + return NULL; + + blocks = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), DRM_MEM_DRIVER); + if (blocks != NULL) { + blocks->ofs = ofs; + blocks->size = size; + blocks->free = 1; + return (memHeap_t *) blocks; + } else + return NULL; +} + +/* Checks if a pointer 'b' is part of the heap 'heap' */ +int mmBlockInHeap(memHeap_t * heap, PMemBlock b) +{ + TMemBlock *p; + + if (heap == NULL || b == NULL) + return 0; + + p = heap; + while (p != NULL && p != b) { + p = p->next; + } + if (p == b) + return 1; + else + return 0; +} + +static TMemBlock *SliceBlock(TMemBlock * p, + int startofs, int size, + int reserved, int alignment) +{ + TMemBlock *newblock; + + /* break left */ + if (startofs > p->ofs) { + newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), + DRM_MEM_DRIVER); + newblock->ofs = startofs; + newblock->size = p->size - (startofs - p->ofs); + newblock->free = 1; + newblock->next = p->next; + p->size -= newblock->size; + p->next = newblock; + p = newblock; + } + + /* break right */ + if (size < p->size) { + newblock = (TMemBlock *) drm_calloc(1, sizeof(TMemBlock), + DRM_MEM_DRIVER); + newblock->ofs = startofs + size; + newblock->size = p->size - size; + newblock->free = 1; + newblock->next = p->next; + p->size = size; + p->next = newblock; + } + + /* p = middle block */ + p->align = alignment; + p->free = 0; + p->reserved = reserved; + return p; +} + +PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch) +{ + int mask, startofs, endofs; + TMemBlock *p; + + if (heap == NULL || align2 < 0 || size <= 0) + return NULL; + + mask = (1 << align2) - 1; + startofs = 0; + p = (TMemBlock *) heap; + while (p != NULL) { + if (ISFREE(p)) { + startofs = (p->ofs + mask) & ~mask; + if (startofs < startSearch) { + startofs = startSearch; + } + endofs = startofs + size; + if (endofs <= (p->ofs + p->size)) + break; + } + p = p->next; + } + if (p == NULL) + return NULL; + p = SliceBlock(p, startofs, size, 0, mask + 1); + p->heap = heap; + return p; +} + +static __inline__ int Join2Blocks(TMemBlock * p) +{ + if (p->free && p->next && p->next->free) { + TMemBlock *q = p->next; + p->size += q->size; + p->next = q->next; + drm_free(q, sizeof(TMemBlock), DRM_MEM_DRIVER); + return 1; + } + return 0; +} + +int mmFreeMem(PMemBlock b) +{ + TMemBlock *p, *prev; + + if (b == NULL) + return 0; + if (b->heap == NULL) + return -1; + + p = b->heap; + prev = NULL; + while (p != NULL && p != b) { + prev = p; + p = p->next; + } + if (p == NULL || p->free || p->reserved) + return -1; + + p->free = 1; + Join2Blocks(p); + if (prev) + Join2Blocks(prev); + return 0; +} diff --git a/trunk/drivers/char/drm/sis_ds.h b/trunk/drivers/char/drm/sis_ds.h new file mode 100644 index 000000000000..94f2b4728b63 --- /dev/null +++ b/trunk/drivers/char/drm/sis_ds.h @@ -0,0 +1,146 @@ +/* sis_ds.h -- Private header for Direct Rendering Manager -*- linux-c -*- + * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw + */ +/* + * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Sung-Ching Lin + * + */ + +#ifndef __SIS_DS_H__ +#define __SIS_DS_H__ + +/* Set Data Structure */ + +#define SET_SIZE 5000 + +typedef unsigned long ITEM_TYPE; + +typedef struct { + ITEM_TYPE val; + int alloc_next, free_next; +} list_item_t; + +typedef struct { + int alloc; + int free; + int trace; + list_item_t list[SET_SIZE]; +} set_t; + +set_t *setInit(void); +int setAdd(set_t * set, ITEM_TYPE item); +int setDel(set_t * set, ITEM_TYPE item); +int setFirst(set_t * set, ITEM_TYPE * item); +int setNext(set_t * set, ITEM_TYPE * item); +int setDestroy(set_t * set); + +/* + * GLX Hardware Device Driver common code + * Copyright (C) 1999 Wittawat Yamwong + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +struct mem_block_t { + struct mem_block_t *next; + struct mem_block_t *heap; + int ofs, size; + int align; + unsigned int free:1; + unsigned int reserved:1; +}; +typedef struct mem_block_t TMemBlock; +typedef struct mem_block_t *PMemBlock; + +/* a heap is just the first block in a chain */ +typedef struct mem_block_t memHeap_t; + +static __inline__ int mmBlockSize(PMemBlock b) +{ + return b->size; +} + +static __inline__ int mmOffset(PMemBlock b) +{ + return b->ofs; +} + +static __inline__ void mmMarkReserved(PMemBlock b) +{ + b->reserved = 1; +} + +/* + * input: total size in bytes + * return: a heap pointer if OK, NULL if error + */ +memHeap_t *mmInit(int ofs, int size); + +/* + * Allocate 'size' bytes with 2^align2 bytes alignment, + * restrict the search to free memory after 'startSearch' + * depth and back buffers should be in different 4mb banks + * to get better page hits if possible + * input: size = size of block + * align2 = 2^align2 bytes alignment + * startSearch = linear offset from start of heap to begin search + * return: pointer to the allocated block, 0 if error + */ +PMemBlock mmAllocMem(memHeap_t * heap, int size, int align2, int startSearch); + +/* + * Returns 1 if the block 'b' is part of the heap 'heap' + */ +int mmBlockInHeap(PMemBlock heap, PMemBlock b); + +/* + * Free block starts at offset + * input: pointer to a block + * return: 0 if OK, -1 if error + */ +int mmFreeMem(PMemBlock b); + +/* For debuging purpose. */ +void mmDumpMemInfo(memHeap_t * mmInit); + +#endif /* __SIS_DS_H__ */ diff --git a/trunk/drivers/char/drm/sis_mm.c b/trunk/drivers/char/drm/sis_mm.c index d26f5dbb7853..5e9936bc307f 100644 --- a/trunk/drivers/char/drm/sis_mm.c +++ b/trunk/drivers/char/drm/sis_mm.c @@ -1,348 +1,414 @@ -/************************************************************************** +/* sis_mm.c -- Private header for Direct Rendering Manager -*- linux-c -*- + * Created: Mon Jan 4 10:05:05 1999 by sclin@sis.com.tw * - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA. - * All Rights Reserved. + * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. + * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * - * - **************************************************************************/ - -/* * Authors: - * Thomas Hellström + * Sung-Ching Lin + * */ #include "drmP.h" #include "sis_drm.h" #include "sis_drv.h" - +#include "sis_ds.h" +#if defined(__linux__) && defined(CONFIG_FB_SIS) #include