diff --git a/[refs] b/[refs] index 38edfac14d9e..95cb59f29f0d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bfeeb0f57940b143a55dcc7ee88e8842108d9145 +refs/heads/master: f0b364a13d7fba001c0571d954f165dfaf5f434a diff --git a/trunk/CREDITS b/trunk/CREDITS index cc3453a55fb9..66e82466dde8 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -1620,7 +1620,8 @@ D: fbdev hacking N: Jesper Juhl E: jesper.juhl@gmail.com -D: Various fixes, cleanups and minor features. +D: Various fixes, cleanups and minor features all over the tree. +D: Wrote initial version of the hdaps driver (since passed on to others). S: Lemnosvej 1, 3.tv S: 2300 Copenhagen S. S: Denmark @@ -2477,7 +2478,8 @@ S: Derbyshire DE4 3RL S: United Kingdom N: Ian S. Nelson -E: ian.nelson@echostar.com +E: nelsonis@earthlink.net +P: 1024D/00D3D983 3EFD 7B86 B888 D7E2 29B6 9E97 576F 1B97 00D3 D983 D: Minor mmap and ide hacks S: 1370 Atlantis Ave. S: Lafayette CO, 80026 diff --git a/trunk/Documentation/CodingStyle b/trunk/Documentation/CodingStyle index 6d2412ec91ed..29c18966b050 100644 --- a/trunk/Documentation/CodingStyle +++ b/trunk/Documentation/CodingStyle @@ -532,6 +532,40 @@ 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 f8fe882e33dc..6d4b1ef5b6f1 100644 --- a/trunk/Documentation/DocBook/kernel-api.tmpl +++ b/trunk/Documentation/DocBook/kernel-api.tmpl @@ -181,27 +181,6 @@ 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 @@ -234,6 +213,50 @@ 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 @@ -349,13 +372,6 @@ 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 @@ -386,6 +402,7 @@ 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 @@ -437,6 +454,11 @@ 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 320af25de3a2..3608472d7b74 100644 --- a/trunk/Documentation/DocBook/usb.tmpl +++ b/trunk/Documentation/DocBook/usb.tmpl @@ -43,59 +43,52 @@ 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 at the + devices. USB uses a tree structure, with the host as the root (the system's master), hubs as interior nodes, and - peripheral devices as leaves (and slaves). + peripherals 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 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. + 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. - 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, including high speed - transfers and transaction translating hubs (used for USB 1.1 + USB 2.0 was released in April 2000, adding high-speed + transfers and transaction-translating hubs (used for USB 1.1 and 1.0 backward compatibility). - 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. + 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. Linux can run inside USB devices as well as on the hosts that control the devices. - 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 + But USB device drivers running inside those peripherals don't do the same things as the ones running inside hosts, - and so they've been given a different name: - they're called gadget drivers. - This document does not present gadget drivers. + so they've been given a different name: + gadget drivers. + This document does not cover gadget drivers. @@ -103,17 +96,14 @@ USB Host-Side API Model - 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), + 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, which control individual busses. @@ -122,21 +112,21 @@ - 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) + 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) 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 that 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 which might be used. - Configurations have one or more "interface", each + Configurations have one or more "interfaces", each of which may have "alternate settings". Interfaces may be standardized by USB "Class" specifications, or may be specific to a vendor or device. @@ -162,7 +152,7 @@ The Linux USB API supports synchronous calls for - control and bulk messaging. + control and bulk messages. It also supports asynchnous calls for all kinds of data transfer, using request structures called "URBs" (USB Request Blocks). @@ -463,14 +453,25 @@ file in your Linux kernel sources. - 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. + 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. - diff --git a/trunk/Documentation/HOWTO b/trunk/Documentation/HOWTO index 1d6560413cc5..d6f3dd1a3464 100644 --- a/trunk/Documentation/HOWTO +++ b/trunk/Documentation/HOWTO @@ -375,6 +375,26 @@ 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 0256805b548f..7756e09ea759 100644 --- a/trunk/Documentation/IPMI.txt +++ b/trunk/Documentation/IPMI.txt @@ -326,9 +326,12 @@ 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. Only one user -may be registered for each netfn/cmd, but different users may register -for different commands. +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. From userland, equivalent IOCTLs are provided to do these functions. diff --git a/trunk/Documentation/SubmitChecklist b/trunk/Documentation/SubmitChecklist index a10bfb6ecd9f..7ac61f60037a 100644 --- a/trunk/Documentation/SubmitChecklist +++ b/trunk/Documentation/SubmitChecklist @@ -61,3 +61,8 @@ 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 6bd30fdd0786..58bead05eabb 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 copright owner. + the copyright 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,17 +116,13 @@ 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: @@ -145,11 +141,8 @@ KernelNewbies: Linux USB project: http://www.linux-usb.org/ -How to NOT write kernel driver by arjanv@redhat.com - http://people.redhat.com/arjanv/olspaper.pdf +How to NOT write kernel driver by Arjan van de Ven: + http://www.fenrus.org/how-to-not-write-a-device-driver-paper.pdf Kernel Janitor: http://janitor.kernelnewbies.org/ - --- -Last updated on 17 Nov 2005. diff --git a/trunk/Documentation/SubmittingPatches b/trunk/Documentation/SubmittingPatches index d42ab4c9e893..302d148c2e18 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,6 +209,19 @@ 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. @@ -245,13 +258,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 (See Figure 1) +* 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. When in doubt, solicit comments on linux-kernel mailing list. @@ -476,10 +489,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". @@ -488,9 +501,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 Torvald's mail on the canonical patch format: +Linus Torvalds's mail on the canonical patch format: -- diff --git a/trunk/Documentation/accounting/getdelays.c b/trunk/Documentation/accounting/getdelays.c index 795ca3911cc5..b11792abd6b6 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, sizeof(cpumask)); + &cpumask, strlen(cpumask) + 1); PRINTF("Sent register cpumask, retval %d\n", rc); if (rc < 0) { printf("error sending register cpumask\n"); @@ -315,7 +315,8 @@ int main(int argc, char *argv[]) } if (msg.n.nlmsg_type == NLMSG_ERROR || !NLMSG_OK((&msg.n), rep_len)) { - printf("fatal reply error, errno %d\n", errno); + struct nlmsgerr *err = NLMSG_DATA(&msg); + printf("fatal reply error, errno %d\n", err->error); goto done; } @@ -383,7 +384,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, sizeof(cpumask)); + &cpumask, strlen(cpumask) + 1); 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 new file mode 100644 index 000000000000..661c797eaf79 --- /dev/null +++ b/trunk/Documentation/accounting/taskstats-struct.txt @@ -0,0 +1,161 @@ +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 76b44290c154..842f0d1ab216 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 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. +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. 1.4 What are exclusive cpusets ? diff --git a/trunk/Documentation/devices.txt b/trunk/Documentation/devices.txt index 66c725f530f3..addc67b1d770 100644 --- a/trunk/Documentation/devices.txt +++ b/trunk/Documentation/devices.txt @@ -2543,6 +2543,9 @@ 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 c12d39a23c3d..aa0d322db171 100644 --- a/trunk/Documentation/fb/intelfb.txt +++ b/trunk/Documentation/fb/intelfb.txt @@ -1,16 +1,19 @@ -Intel 830M/845G/852GM/855GM/865G/915G Framebuffer driver +Intel 830M/845G/852GM/855GM/865G/915G/945G Framebuffer driver ================================================================ A. Introduction - This is a framebuffer driver for various Intel 810/815 compatible + This is a framebuffer driver for various Intel 8xx/9xx compatible graphics devices. These would include: Intel 830M - Intel 810E845G + Intel 845G Intel 852GM Intel 855GM Intel 865G Intel 915G + Intel 915GM + Intel 945G + Intel 945GM B. List of available options @@ -78,7 +81,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=i810fb:option1,option2=value2 +video=intelfb:option1,option2=value2 Sample Usage ------------ diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 611acc32fdf5..9364f47c7116 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -46,17 +46,8 @@ 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: July 2006 +When: December 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 @@ -70,6 +61,18 @@ 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 @@ -217,14 +220,6 @@ 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, @@ -321,3 +316,12 @@ Why: The stacking of class devices makes these values misleading and 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 247d7f619aa2..eb1a6cad21e6 100644 --- a/trunk/Documentation/filesystems/Locking +++ b/trunk/Documentation/filesystems/Locking @@ -356,10 +356,9 @@ 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_write) (struct kiocb *, 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); 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 7db71d6fba82..7240ee7515de 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -39,6 +39,8 @@ 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 @@ -1962,6 +1964,22 @@ 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 1cb7e8be927a..cd07c21b8400 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_write) (struct kiocb *, 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); 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 9555be1ed999..e783fd62e308 100644 --- a/trunk/Documentation/hwmon/it87 +++ b/trunk/Documentation/hwmon/it87 @@ -13,12 +13,25 @@ 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 -Author: Christophe Gauthron +Authors: + Christophe Gauthron + Jean Delvare Module Parameters @@ -43,26 +56,46 @@ Module Parameters Description ----------- -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. +This driver implements support for the IT8705F, IT8712F, IT8716F, +IT8718F and SiS950 chips. 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. 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. +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. 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 @@ -71,9 +104,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 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. +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. 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 new file mode 100644 index 000000000000..bab445ab0f52 --- /dev/null +++ b/trunk/Documentation/hwmon/k8temp @@ -0,0 +1,52 @@ +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 new file mode 100644 index 000000000000..77fa633b97a8 --- /dev/null +++ b/trunk/Documentation/hwmon/vt1211 @@ -0,0 +1,206 @@ +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 new file mode 100644 index 000000000000..fae3b781d82d --- /dev/null +++ b/trunk/Documentation/hwmon/w83627ehf @@ -0,0 +1,85 @@ +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 83a3836289c2..19b2ed739fa1 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/W83791Da.pdf + Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83791D_W83791Gb.pdf Author: Charles Spirakis @@ -20,6 +20,9 @@ Credits: Chunhao Huang , Rudolf Marek +Additional contributors: + Sven Anders + Module Parameters ----------------- @@ -46,7 +49,8 @@ Module Parameters Description ----------- -This driver implements support for the Winbond W83791D chip. +This driver implements support for the Winbond W83791D chip. The W83791G +chip appears to be the same as the W83791D but is lead free. 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 @@ -71,34 +75,36 @@ Voltage sensors (also known as IN sensors) report their values in millivolts. An alarm is triggered if the voltage has crossed a programmable minimum or maximum limit. -Alarms are provided as output from 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 +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. 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 @@ -109,5 +115,6 @@ often will do no harm, but will return 'old' values. W83791D TODO: --------------- -Provide a patch for per-file alarms as discussed on the mailing list +Provide a patch for per-file alarms and beep enables as defined in the hwmon + documentation (Documentation/hwmon/sysfs-interface) 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 16775663b9f5..25680346e0ac 100644 --- a/trunk/Documentation/i2c/busses/i2c-viapro +++ b/trunk/Documentation/i2c/busses/i2c-viapro @@ -7,9 +7,12 @@ Supported adapters: * VIA Technologies, Inc. VT82C686A/B Datasheet: Sometimes available at the VIA website - * VIA Technologies, Inc. VT8231, VT8233, VT8233A, VT8235, VT8237R + * VIA Technologies, Inc. VT8231, VT8233, VT8233A 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 , @@ -39,6 +42,8 @@ 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 d6dcb138abf5..9cc081e69764 100644 --- a/trunk/Documentation/i2c/i2c-stub +++ b/trunk/Documentation/i2c/i2c-stub @@ -6,9 +6,12 @@ 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 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 +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 also spam the kernel logs for every command it handles. A pointer register with auto-increment is implemented for all byte @@ -21,6 +24,11 @@ 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 @@ -33,6 +41,9 @@ 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/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index c918cc3f65fb..137e993f4329 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -110,6 +110,13 @@ 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. @@ -573,8 +580,6 @@ running once the system is up. gscd= [HW,CD] Format: - gt96100eth= [NET] MIPS GT96100 Advanced Communication Controller - gus= [HW,OSS] Format: ,,, @@ -1326,7 +1331,7 @@ running once the system is up. pt. [PARIDE] See Documentation/paride.txt. - quiet= [KNL] Disable log messages + quiet [KNL] Disable most log messages r128= [HW,DRM] @@ -1372,6 +1377,9 @@ running once the system is up. 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/lockdep-design.txt b/trunk/Documentation/lockdep-design.txt index 00d93605bfd3..55a7e4fa8cc2 100644 --- a/trunk/Documentation/lockdep-design.txt +++ b/trunk/Documentation/lockdep-design.txt @@ -36,6 +36,28 @@ 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/bonding.txt b/trunk/Documentation/networking/bonding.txt index afac780445cd..dc942eaf490f 100644 --- a/trunk/Documentation/networking/bonding.txt +++ b/trunk/Documentation/networking/bonding.txt @@ -192,6 +192,17 @@ or, for backwards compatibility, the option value. E.g., arp_interval Specifies the ARP link monitoring frequency in milliseconds. + + The ARP monitor works by periodically checking the slave + devices to determine whether they have sent or received + traffic recently (the precise criteria depends upon the + bonding mode, and the state of the slave). Regular traffic is + generated via ARP probes issued for the addresses specified by + the arp_ip_target option. + + This behavior can be modified by the arp_validate option, + below. + If ARP monitoring is used in an etherchannel compatible mode (modes 0 and 2), the switch should be configured in a mode that evenly distributes packets across all links. If the @@ -213,6 +224,54 @@ arp_ip_target maximum number of targets that can be specified is 16. The default value is no IP addresses. +arp_validate + + Specifies whether or not ARP probes and replies should be + validated in the active-backup mode. This causes the ARP + monitor to examine the incoming ARP requests and replies, and + only consider a slave to be up if it is receiving the + appropriate ARP traffic. + + Possible values are: + + none or 0 + + No validation is performed. This is the default. + + active or 1 + + Validation is performed only for the active slave. + + backup or 2 + + Validation is performed only for backup slaves. + + all or 3 + + Validation is performed for all slaves. + + For the active slave, the validation checks ARP replies to + confirm that they were generated by an arp_ip_target. Since + backup slaves do not typically receive these replies, the + validation performed for backup slaves is on the ARP request + sent out via the active slave. It is possible that some + switch or network configurations may result in situations + wherein the backup slaves do not receive the ARP requests; in + such a situation, validation of backup slaves must be + disabled. + + This option is useful in network configurations in which + multiple bonding hosts are concurrently issuing ARPs to one or + more targets beyond a common switch. Should the link between + the switch and target fail (but not the switch itself), the + probe traffic generated by the multiple bonding instances will + fool the standard ARP monitor into considering the links as + still up. Use of the arp_validate option can resolve this, as + the ARP monitor will only consider ARP requests and replies + associated with its own instance of bonding. + + This option was added in bonding version 3.1.0. + downdelay Specifies the time, in milliseconds, to wait before disabling diff --git a/trunk/Documentation/networking/pktgen.txt b/trunk/Documentation/networking/pktgen.txt index 44f2f769e865..18d385c068fc 100644 --- a/trunk/Documentation/networking/pktgen.txt +++ b/trunk/Documentation/networking/pktgen.txt @@ -100,6 +100,7 @@ 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. @@ -125,6 +126,21 @@ 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 b88ebe4d808c..7714f57caad5 100644 --- a/trunk/Documentation/nommu-mmap.txt +++ b/trunk/Documentation/nommu-mmap.txt @@ -116,6 +116,9 @@ 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. @@ -125,6 +128,49 @@ 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 new file mode 100644 index 000000000000..16c251230c82 --- /dev/null +++ b/trunk/Documentation/pcieaer-howto.txt @@ -0,0 +1,253 @@ + 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/rt-mutex-design.txt b/trunk/Documentation/rt-mutex-design.txt index c472ffacc2f6..4b736d24da7a 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 the mutex has no owner, there are no waiters and +be false, because if 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 than the mutex +owner still needs to make this check. If there are no waiters then 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 deleted file mode 100644 index 97274d122d0e..000000000000 --- a/trunk/Documentation/seclvl.txt +++ /dev/null @@ -1,97 +0,0 @@ -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 eb2dd2e6993b..73988e0d112b 100644 --- a/trunk/Documentation/sh/new-machine.txt +++ b/trunk/Documentation/sh/new-machine.txt @@ -41,11 +41,6 @@ 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 @@ -104,12 +99,13 @@ 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 -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. +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. 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 @@ -122,6 +118,7 @@ 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) { @@ -152,79 +149,57 @@ 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. 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. +to be of any use. machvec functions fall into a number of categories: - I/O functions to IO memory (inb etc) and PCI/main memory (readb etc). - - 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 + - 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 any machine specific IO functions prefixed with the machine name, for example vapor_inb. These will be needed when filling out the machine vector. - 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. + 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). 3. Hooking into the Build System ================================ @@ -303,4 +278,3 @@ 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 new file mode 100644 index 000000000000..a6719f2f6594 --- /dev/null +++ b/trunk/Documentation/sh/register-banks.txt @@ -0,0 +1,33 @@ + 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 867f4c38f356..39c68f8c4e6c 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. --ETIMEDOUT (**) No response packet received within the prescribed +-ETIME (**) No response packet received within the prescribed bus turn-around time. This error may instead be reported as -EPROTO or -EILSEQ. - Note that the synchronous USB message functions - also use this code to indicate timeout expired - before the transfer completed. +-ETIMEDOUT Synchronous USB message functions use this code + to indicate timeout expired before the transfer + completed, and no other error was reported by HC. -EPIPE (**) Endpoint stalled. For non-control endpoints, reset this status with usb_clear_halt(). @@ -163,6 +163,3 @@ 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 02b0f7beb6d1..a2dee6e6190d 100644 --- a/trunk/Documentation/usb/usb-serial.txt +++ b/trunk/Documentation/usb/usb-serial.txt @@ -433,6 +433,11 @@ 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 00d9a1f2a54c..669a09aa5bb4 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] + 9 -> Leadtek PVR 2000 [107d:663b,107d:663c,107d:6632] 10 -> IODATA GV-VCP3/PCI [10fc:d003] 11 -> Prolink PlayTV PVR - 12 -> ASUS PVR-416 [1043:4823] + 12 -> ASUS PVR-416 [1043:4823,1461:c111] 13 -> MSI TV-@nywhere 14 -> KWorld/VStream XPert DVB-T [17de:08a6] 15 -> DViCO FusionHDTV DVB-T1 [18ac:db00] @@ -51,3 +51,7 @@ 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 9068b669f5ee..94cf695b1378 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 FlyDVB-T Duo Cardbus [5168:0502,4e42:0502] + 60 -> LifeView/Typhoon/Genius FlyDVB-T Duo Cardbus [5168:0502,4e42:0502,1489: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] + 85 -> AverTV DVB-T 777 [1461:2c05,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,3 +94,6 @@ 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 fc94ff235ffa..bb7c2cac7917 100644 --- a/trunk/Documentation/video4linux/bttv/Insmod-options +++ b/trunk/Documentation/video4linux/bttv/Insmod-options @@ -54,6 +54,12 @@ 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 new file mode 100644 index 000000000000..0e213ed095e6 --- /dev/null +++ b/trunk/Documentation/video4linux/cx2341x/README.hm12 @@ -0,0 +1,116 @@ +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 new file mode 100644 index 000000000000..5807cf156173 --- /dev/null +++ b/trunk/Documentation/video4linux/cx2341x/README.vbi @@ -0,0 +1,45 @@ + +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 4303e0c12476..74b77f9e91bc 100644 --- a/trunk/Documentation/x86_64/boot-options.txt +++ b/trunk/Documentation/x86_64/boot-options.txt @@ -199,6 +199,11 @@ 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] diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 767a43434ae8..f0cd5a3f6de6 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -501,7 +501,7 @@ S: Maintained BLOCK LAYER P: Jens Axboe -M: axboe@suse.de +M: axboe@kernel.dk 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 +DEVICE-MAPPER (LVM) 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@suse.de +M: axboe@kernel.dk L: linux-kernel@vger.kernel.org W: http://www.kernel.dk S: Maintained @@ -1398,36 +1398,29 @@ 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: Jody McIntyre -M: scjody@modernduck.com +P: Stefan Richter +M: stefanr@s5r6.in-berlin.de L: linux1394-devel@lists.sourceforge.net W: http://www.linux1394.org/ -T: git kernel.org:/pub/scm/linux/kernel/git/scjody/ieee1394.git +T: git kernel.org:/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6.git S: Maintained -IEEE 1394 OHCI DRIVER -P: Ben Collins -M: bcollins@debian.org -P: Jody McIntyre -M: scjody@modernduck.com +IEEE 1394 IPV4 DRIVER (eth1394) +P: Stefan Richter +M: stefanr@s5r6.in-berlin.de L: linux1394-devel@lists.sourceforge.net -W: http://www.linux1394.org/ -S: Maintained +S: Odd Fixes 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 -W: http://www.linux1394.org/ -S: Maintained +S: Odd Fixes IEEE 1394 RAW I/O DRIVER P: Ben Collins @@ -1435,16 +1428,6 @@ 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 @@ -2062,7 +2045,7 @@ L: linux-hams@vger.kernel.org W: http://www.linux-ax25.org/ S: Maintained -NETWORK BLOCK DEVICE +NETWORK BLOCK DEVICE (NBD) P: Paul Clements M: Paul.Clements@steeleye.com S: Maintained @@ -2548,7 +2531,7 @@ S: Maintained SCSI CDROM DRIVER P: Jens Axboe -M: axboe@suse.de +M: axboe@kernel.dk L: linux-scsi@vger.kernel.org W: http://www.kernel.dk S: Maintained @@ -2679,7 +2662,6 @@ M: josejx@gentoo.org P: Daniel Drake M: dsd@gentoo.org W: http://softmac.sipsolutions.net/ -L: softmac-dev@sipsolutions.net L: netdev@vger.kernel.org S: Maintained @@ -2811,6 +2793,12 @@ 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 @@ -2835,12 +2823,9 @@ S: Maintained SUPERH (sh) P: Paul Mundt M: lethal@linux-sh.org -P: Kazumoto Kojima -M: kkojima@rr.iij4u.or.jp -L: linuxsh-dev@lists.sourceforge.net +L: linuxsh-dev@lists.sourceforge.net (subscribers-only) 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) @@ -2991,7 +2976,7 @@ S: Maintained UNIFORM CDROM DRIVER P: Jens Axboe -M: axboe@suse.de +M: axboe@kernel.dk L: linux-kernel@vger.kernel.org W: http://www.kernel.dk S: Maintained @@ -3310,6 +3295,12 @@ 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 80dac0245d66..4c6c5e32ef96 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1385,9 +1385,13 @@ 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 $(ARCH) + $(PERL) $(src)/scripts/checkstack.pl $(SUBARCH) kernelrelease: $(if $(wildcard include/config/kernel.release), $(Q)echo $(KERNELRELEASE), \ diff --git a/trunk/arch/alpha/kernel/proto.h b/trunk/arch/alpha/kernel/proto.h index 2a6e3da8144f..21f71287b6f5 100644 --- a/trunk/arch/alpha/kernel/proto.h +++ b/trunk/arch/alpha/kernel/proto.h @@ -1,5 +1,7 @@ #include +#include +#include /* Prototypes of functions used across modules here in this directory. */ @@ -181,9 +183,16 @@ extern void titan_dispatch_irqs(u64, struct pt_regs *); extern void switch_to_system_map(void); extern void srm_paging_stop(void); -/* ../mm/remap.c */ -extern int __alpha_remap_area_pages(unsigned long, unsigned long, - unsigned long, unsigned long); +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); +} /* irq.c */ diff --git a/trunk/arch/alpha/kernel/time.c b/trunk/arch/alpha/kernel/time.c index b191cc759737..581ddcc22fc5 100644 --- a/trunk/arch/alpha/kernel/time.c +++ b/trunk/arch/alpha/kernel/time.c @@ -54,8 +54,6 @@ #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); @@ -132,7 +130,7 @@ irqreturn_t timer_interrupt(int irq, void *dev, struct pt_regs * regs) nticks = delta >> FIX_SHIFT; while (nticks > 0) { - do_timer(regs); + do_timer(1); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -413,7 +411,7 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; - unsigned long sec, usec, lost, seq; + unsigned long sec, usec, seq; unsigned long delta_cycles, delta_usec, partial_tick; do { @@ -423,14 +421,13 @@ 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 = lost * (1000000 / HZ); + delta_usec = 0; #else /* * usec = cycles * ticks_per_cycle * 2**48 * 1e6 / (2**48 * ticks) @@ -446,8 +443,7 @@ do_gettimeofday(struct timeval *tv) */ delta_usec = (delta_cycles * state.scaled_ticks_per_cycle - + partial_tick - + (lost << FIX_SHIFT)) * 15625; + + partial_tick) * 15625; delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2; #endif @@ -480,12 +476,11 @@ do_settimeofday(struct timespec *tv) time. Without this, a full-tick error is possible. */ #ifdef CONFIG_SMP - delta_nsec = (jiffies - wall_jiffies) * (NSEC_PER_SEC / HZ); + delta_nsec = 0; #else delta_nsec = rpcc() - state.last_time; delta_nsec = (delta_nsec * state.scaled_ticks_per_cycle - + state.partial_tick - + ((jiffies - wall_jiffies) << FIX_SHIFT)) * 15625; + + state.partial_tick) * 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 6edd9a09ea4f..09399c5386cb 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 remap.o +obj-y := init.o fault.o extable.o obj-$(CONFIG_DISCONTIGMEM) += numa.o diff --git a/trunk/arch/alpha/mm/fault.c b/trunk/arch/alpha/mm/fault.c index 622dabd84680..8871529a34e2 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 (current->pid == 1) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/alpha/mm/remap.c b/trunk/arch/alpha/mm/remap.c deleted file mode 100644 index a78356c3ead5..000000000000 --- a/trunk/arch/alpha/mm/remap.c +++ /dev/null @@ -1,86 +0,0 @@ -#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 f81a62380add..f9362ee9955f 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -17,6 +17,10 @@ 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 @@ -51,6 +55,10 @@ config GENERIC_HARDIRQS bool default y +config TRACE_IRQFLAGS_SUPPORT + bool + default y + config HARDIRQS_SW_RESEND bool default y @@ -91,7 +99,7 @@ config ARCH_MTD_XIP config VECTORS_BASE hex - default 0xffff0000 if MMU + default 0xffff0000 if MMU || CPU_HIGH_VECTOR default DRAM_BASE if REMAP_VECTORS_TO_RAM default 0x00000000 help @@ -198,16 +206,27 @@ config ARCH_IMX help Support for Motorola's i.MX family of processors (MX1, MXL). -config ARCH_IOP3XX - bool "IOP3xx-based" +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" depends on MMU + select PLAT_IOP select PCI help - Support for Intel's IOP3XX (XScale) family of processors. + Support for Intel's IOP33X (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. @@ -308,7 +327,9 @@ source "arch/arm/mach-footbridge/Kconfig" source "arch/arm/mach-integrator/Kconfig" -source "arch/arm/mach-iop3xx/Kconfig" +source "arch/arm/mach-iop32x/Kconfig" + +source "arch/arm/mach-iop33x/Kconfig" source "arch/arm/mach-ixp4xx/Kconfig" @@ -348,6 +369,9 @@ 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 @@ -602,6 +626,7 @@ 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 @@ -633,11 +658,12 @@ config ZBOOT_ROM_BSS hex "Compressed ROM boot loader BSS address" default "0" help - 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. + 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. If ZBOOT_ROM is not enabled, this has no effect. @@ -832,7 +858,7 @@ source "drivers/base/Kconfig" source "drivers/connector/Kconfig" -if ALIGNMENT_TRAP +if ALIGNMENT_TRAP || !CPU_CP15_MMU source "drivers/mtd/Kconfig" endif @@ -844,7 +870,7 @@ source "drivers/block/Kconfig" source "drivers/acorn/block/Kconfig" -if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \ +if PCMCIA || ARCH_CLPS7500 || ARCH_IOP32X || ARCH_IOP33X || 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 e1574be2ded6..f087376748d1 100644 --- a/trunk/arch/arm/Kconfig-nommu +++ b/trunk/arch/arm/Kconfig-nommu @@ -25,6 +25,14 @@ 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 92873cdee31f..2a0b2c8a1fe0 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -55,7 +55,12 @@ 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 @@ -101,7 +106,8 @@ endif machine-$(CONFIG_ARCH_INTEGRATOR) := integrator textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 machine-$(CONFIG_ARCH_CLPS711X) := clps711x - machine-$(CONFIG_ARCH_IOP3XX) := iop3xx + machine-$(CONFIG_ARCH_IOP32X) := iop32x + machine-$(CONFIG_ARCH_IOP33X) := iop33x machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_IXP2000) := ixp2000 machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx @@ -157,6 +163,7 @@ 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 2adc1527e0eb..adddc7131685 100644 --- a/trunk/arch/arm/boot/compressed/Makefile +++ b/trunk/arch/arm/boot/compressed/Makefile @@ -51,7 +51,11 @@ 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 14a9ff9c68df..e5ab51b9cceb 100644 --- a/trunk/arch/arm/boot/compressed/head.S +++ b/trunk/arch/arm/boot/compressed/head.S @@ -20,11 +20,21 @@ #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 @@ -42,12 +52,6 @@ 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 @@ -78,9 +82,11 @@ 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 #'-' @@ -503,7 +509,11 @@ 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 ace3fb5835d9..283891c736c4 100644 --- a/trunk/arch/arm/boot/compressed/misc.c +++ b/trunk/arch/arm/boot/compressed/misc.c @@ -30,6 +30,25 @@ 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; @@ -44,6 +63,8 @@ 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 bafe8b19be82..6d094c157540 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 943ef88c0379..3d377c5bdef6 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 4e0dcaef6eb2..181ef1ead5b8 100644 --- a/trunk/arch/arm/common/locomo.c +++ b/trunk/arch/arm/common/locomo.c @@ -121,6 +121,13 @@ static struct locomo_dev_info locomo_devices[] = { .offset = 0, .length = 0, }, + { + .devid = LOCOMO_DEVID_SPI, + .irq = {}, + .name = "locomo-spi", + .offset = LOCOMO_SPI, + .length = 0x30, + }, }; @@ -374,7 +381,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_SPIIR) & 0x000F; + req = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIR) & 0x000F; if (req) { irq = LOCOMO_IRQ_SPI_START; d = irq_desc + irq; @@ -391,35 +398,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_SPIWE); + r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE); r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPIWE); + locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIWE); - r = locomo_readl(mapbase + LOCOMO_SPIIS); + r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIS); r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPIIS); + locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIS); - r = locomo_readl(mapbase + LOCOMO_SPIWE); + r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIWE); r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPIWE); + locomo_writel(r, mapbase + LOCOMO_SPI + 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_SPIIE); + r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE); r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPIIE); + locomo_writel(r, mapbase + LOCOMO_SPI + 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_SPIIE); + r = locomo_readl(mapbase + LOCOMO_SPI + LOCOMO_SPIIE); r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START)); - locomo_writel(r, mapbase + LOCOMO_SPIIE); + locomo_writel(r, mapbase + LOCOMO_SPI + LOCOMO_SPIIE); } static struct irq_chip locomo_spi_chip = { @@ -814,12 +821,15 @@ 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 locomo_dev *ldev, unsigned int bits, unsigned int dir) +void locomo_gpio_set_dir(struct device *dev, unsigned int bits, unsigned int dir) { - struct locomo *lchip = locomo_chip_driver(ldev); + struct locomo *lchip = dev_get_drvdata(dev); unsigned long flags; unsigned int r; + if (!lchip) + return; + spin_lock_irqsave(&lchip->lock, flags); r = locomo_readl(lchip->base + LOCOMO_GPD); @@ -836,12 +846,15 @@ void locomo_gpio_set_dir(struct locomo_dev *ldev, unsigned int bits, unsigned in spin_unlock_irqrestore(&lchip->lock, flags); } -unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits) +int locomo_gpio_read_level(struct device *dev, unsigned int bits) { - struct locomo *lchip = locomo_chip_driver(ldev); + struct locomo *lchip = dev_get_drvdata(dev); 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); @@ -850,12 +863,15 @@ unsigned int locomo_gpio_read_level(struct locomo_dev *ldev, unsigned int bits) return ret; } -unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits) +int locomo_gpio_read_output(struct device *dev, unsigned int bits) { - struct locomo *lchip = locomo_chip_driver(ldev); + struct locomo *lchip = dev_get_drvdata(dev); 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); @@ -864,12 +880,15 @@ unsigned int locomo_gpio_read_output(struct locomo_dev *ldev, unsigned int bits) return ret; } -void locomo_gpio_write(struct locomo_dev *ldev, unsigned int bits, unsigned int set) +void locomo_gpio_write(struct device *dev, unsigned int bits, unsigned int set) { - struct locomo *lchip = locomo_chip_driver(ldev); + struct locomo *lchip = dev_get_drvdata(dev); unsigned long flags; unsigned int r; + if (!lchip) + return; + spin_lock_irqsave(&lchip->lock, flags); r = locomo_readl(lchip->base + LOCOMO_GPO); @@ -1058,9 +1077,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, LOCOMO_GPIO_FL_VR, 1); + locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 1); else - locomo_gpio_write(dev, LOCOMO_GPIO_FL_VR, 0); + locomo_gpio_write(dev->dev.parent, 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 59b5ddec480f..f412dedda684 100644 --- a/trunk/arch/arm/common/sharpsl_pm.c +++ b/trunk/arch/arm/common/sharpsl_pm.c @@ -40,6 +40,7 @@ #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 */ @@ -575,6 +576,9 @@ 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/ep93xx_defconfig b/trunk/arch/arm/configs/ep93xx_defconfig index 2948b4589a8b..3b4802a849e4 100644 --- a/trunk/arch/arm/configs/ep93xx_defconfig +++ b/trunk/arch/arm/configs/ep93xx_defconfig @@ -126,6 +126,7 @@ 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/ep80219_defconfig b/trunk/arch/arm/configs/iop32x_defconfig similarity index 66% rename from trunk/arch/arm/configs/ep80219_defconfig rename to trunk/arch/arm/configs/iop32x_defconfig index 3c73b707c2f3..0d67f66e78c2 100644 --- a/trunk/arch/arm/configs/ep80219_defconfig +++ b/trunk/arch/arm/configs/iop32x_defconfig @@ -1,50 +1,63 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 22:34:12 2005 +# Linux kernel version: 2.6.18-rc7 +# Tue Sep 19 00:30:18 2006 # CONFIG_ARM=y CONFIG_MMU=y -CONFIG_UID16=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_GENERIC_IOMAP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # 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_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_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set # # Loadable module support @@ -52,24 +65,52 @@ 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_INTEGRATOR is not set -CONFIG_ARCH_IOP3XX=y +# 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_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 @@ -77,28 +118,19 @@ CONFIG_ARCH_IOP3XX=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 # -# IOP3xx Implementation Options +# IOP32x Implementation Options # # -# IOP3xx Platform Types +# IOP32x Platform Types # -# CONFIG_ARCH_IQ80321 is not set +CONFIG_MACH_GLANTANK=y +CONFIG_ARCH_IQ80321=y CONFIG_ARCH_IQ31244=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 -# +CONFIG_MACH_N2100=y +CONFIG_PLAT_IOP=y # # Processor Type @@ -109,7 +141,6 @@ 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 @@ -121,8 +152,7 @@ CONFIG_XSCALE_PMU=y # Bus support # CONFIG_PCI=y -# CONFIG_PCI_LEGACY_PROC is not set -CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support @@ -133,6 +163,19 @@ CONFIG_PCI_NAMES=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 # @@ -140,7 +183,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" +CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp" # CONFIG_XIP_KERNEL is not set # @@ -166,6 +209,93 @@ 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 @@ -177,6 +307,13 @@ CONFIG_BINFMT_AOUT=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) @@ -200,6 +337,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set # # RAM/ROM/Flash chip drivers @@ -225,18 +363,18 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_XIP is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0xf0000000 -CONFIG_MTD_PHYSMAP_LEN=0x00800000 -CONFIG_MTD_PHYSMAP_BANKWIDTH=2 +CONFIG_MTD_PHYSMAP_START=0x0 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers @@ -245,7 +383,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # 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 # @@ -260,6 +397,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # # CONFIG_MTD_NAND is not set +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + # # Parallel port support # @@ -272,7 +414,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 # # 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 @@ -284,17 +425,9 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 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_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y # 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 # @@ -305,6 +438,7 @@ CONFIG_IOSCHED_CFQ=y # # SCSI device support # +# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -316,6 +450,7 @@ 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 @@ -330,10 +465,12 @@ 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 @@ -344,25 +481,19 @@ 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_BUSLOGIC is not set +# CONFIG_SCSI_HPTIOP 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_QLA_FC 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 @@ -377,8 +508,7 @@ CONFIG_BLK_DEV_MD=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_RAID456 is not set # CONFIG_MD_MULTIPATH is not set # CONFIG_MD_FAULTY is not set CONFIG_BLK_DEV_DM=y @@ -392,6 +522,9 @@ 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 @@ -404,71 +537,8 @@ CONFIG_BLK_DEV_DM=y # 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 +# Network device support # -# 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 @@ -480,6 +550,11 @@ CONFIG_NETDEVICES=y # # CONFIG_ARCNET is not set +# +# PHY device support +# +# CONFIG_PHYLIB is not set + # # Ethernet (10 or 100Mbit) # @@ -487,8 +562,10 @@ 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 @@ -526,16 +603,23 @@ CONFIG_E1000_NAPI=y # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set -# CONFIG_R8169 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_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 @@ -558,6 +642,8 @@ 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 @@ -595,7 +681,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # # CONFIG_SERIO is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -603,6 +688,7 @@ CONFIG_SOUND_GAMEPORT=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 # @@ -610,7 +696,9 @@ 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 # @@ -618,6 +706,7 @@ CONFIG_SERIAL_8250_NR_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 @@ -631,8 +720,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 @@ -647,6 +736,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # TPM devices # # CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -671,14 +761,13 @@ 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 @@ -689,15 +778,45 @@ CONFIG_I2C_IOP3XX=y # CONFIG_I2C_PCA_ISA is not set # -# Hardware Sensors Chip support +# 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_I2C_SENSOR is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_ABITUGURU 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 @@ -712,36 +831,45 @@ CONFIG_I2C_IOP3XX=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 # -# Other I2C Chip support +# Misc devices # -# 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 +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers # # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -751,6 +879,7 @@ CONFIG_I2C_IOP3XX=y # # Graphics support # +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # @@ -758,6 +887,7 @@ CONFIG_I2C_IOP3XX=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -769,7 +899,125 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB is not set +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 +# # # USB Gadget Support @@ -781,11 +1029,18 @@ CONFIG_USB_ARCH_HAS_OHCI=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 @@ -795,22 +1050,22 @@ CONFIG_JBD=y CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set - -# -# XFS support -# +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=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 @@ -830,12 +1085,10 @@ 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 @@ -850,8 +1103,9 @@ CONFIG_RAMFS=y # CONFIG_JFFS_FS is not set CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 -# CONFIG_JFFS2_FS_NAND is not set -# CONFIG_JFFS2_FS_NOR_ECC is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y @@ -868,16 +1122,19 @@ 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 @@ -886,6 +1143,7 @@ CONFIG_SUNRPC=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -905,6 +1163,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # @@ -921,11 +1180,34 @@ CONFIG_MSDOS_PARTITION=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y 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 @@ -946,7 +1228,9 @@ CONFIG_DEBUG_USER=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/iq80332_defconfig b/trunk/arch/arm/configs/iop33x_defconfig similarity index 74% rename from trunk/arch/arm/configs/iq80332_defconfig rename to trunk/arch/arm/configs/iop33x_defconfig index 11959b705d82..2a8fc153969d 100644 --- a/trunk/arch/arm/configs/iq80332_defconfig +++ b/trunk/arch/arm/configs/iop33x_defconfig @@ -1,50 +1,63 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 17:33:39 2005 +# Linux kernel version: 2.6.18-rc7 +# Tue Sep 19 00:30:42 2006 # CONFIG_ARM=y CONFIG_MMU=y -CONFIG_UID16=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_GENERIC_IOMAP=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # # 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_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_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set # # Loadable module support @@ -52,24 +65,52 @@ 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_INTEGRATOR is not set -CONFIG_ARCH_IOP3XX=y +# 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_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 @@ -77,28 +118,17 @@ CONFIG_ARCH_IOP3XX=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 # -# IOP3xx Implementation Options +# IOP33x Implementation Options # # -# IOP3xx Platform Types +# IOP33x Platform Types # -# CONFIG_ARCH_IQ80321 is not set -# CONFIG_ARCH_IQ31244 is not set -# CONFIG_ARCH_IQ80331 is not set +CONFIG_ARCH_IQ80331=y CONFIG_MACH_IQ80332=y -# CONFIG_ARCH_EP80219 is not set -CONFIG_ARCH_IOP331=y - -# -# IOP3xx Chipset Features -# -# CONFIG_IOP331_STEPD is not set +CONFIG_PLAT_IOP=y # # Processor Type @@ -109,7 +139,6 @@ 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 @@ -121,8 +150,7 @@ CONFIG_XSCALE_PMU=y # Bus support # CONFIG_PCI=y -# CONFIG_PCI_LEGACY_PROC is not set -CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support @@ -133,6 +161,19 @@ CONFIG_PCI_NAMES=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 # @@ -140,7 +181,7 @@ CONFIG_ALIGNMENT_TRAP=y # CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="ip=boot root=nfs console=ttyS0,115200" +CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp" # CONFIG_XIP_KERNEL is not set # @@ -166,6 +207,93 @@ 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 @@ -177,6 +305,13 @@ CONFIG_BINFMT_AOUT=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) @@ -200,6 +335,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set # # RAM/ROM/Flash chip drivers @@ -222,6 +358,7 @@ 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 @@ -229,18 +366,18 @@ CONFIG_MTD_CFI_UTIL=y # CONFIG_MTD_RAM is not set # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_XIP is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0xc0000000 -CONFIG_MTD_PHYSMAP_LEN=0x00800000 +CONFIG_MTD_PHYSMAP_START=0x0 +CONFIG_MTD_PHYSMAP_LEN=0x0 CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # CONFIG_MTD_ARM_INTEGRATOR is not set -# CONFIG_MTD_EDB7312 is not set +# CONFIG_MTD_PLATRAM is not set # # Self-contained MTD device drivers @@ -249,7 +386,6 @@ 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 # @@ -264,6 +400,11 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 # # CONFIG_MTD_NAND is not set +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + # # Parallel port support # @@ -276,7 +417,6 @@ 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 @@ -288,17 +428,9 @@ 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_INITRD is not set -CONFIG_INITRAMFS_SOURCE="" +CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 +CONFIG_BLK_DEV_INITRD=y # 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 # @@ -309,6 +441,7 @@ CONFIG_IOSCHED_CFQ=y # # SCSI device support # +# CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_PROC_FS=y @@ -320,6 +453,7 @@ 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 @@ -334,10 +468,12 @@ 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 @@ -348,25 +484,19 @@ 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_BUSLOGIC is not set +# CONFIG_SCSI_HPTIOP 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_QLA_FC 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 @@ -381,8 +511,7 @@ 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_RAID456 is not set # CONFIG_MD_MULTIPATH is not set # CONFIG_MD_FAULTY is not set CONFIG_BLK_DEV_DM=y @@ -396,6 +525,9 @@ 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 @@ -408,71 +540,8 @@ CONFIG_BLK_DEV_DM=y # 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 - +# Network device support # -# 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 @@ -484,6 +553,10 @@ CONFIG_NETDEVICES=y # # CONFIG_ARCNET is not set +# +# PHY device support +# + # # Ethernet (10 or 100Mbit) # @@ -501,14 +574,20 @@ 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 @@ -531,6 +610,8 @@ 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 @@ -568,7 +649,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # # CONFIG_SERIO is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -576,6 +656,7 @@ CONFIG_SOUND_GAMEPORT=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 # @@ -583,7 +664,9 @@ 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 # @@ -591,6 +674,7 @@ CONFIG_SERIAL_8250_NR_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 @@ -604,8 +688,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 @@ -620,6 +704,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # TPM devices # # CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -644,14 +729,13 @@ 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 @@ -662,15 +746,45 @@ CONFIG_I2C_IOP3XX=y # CONFIG_I2C_PCA_ISA is not set # -# Hardware Sensors Chip support +# Miscellaneous I2C Chip support # -# CONFIG_I2C_SENSOR is not set +# 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_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 @@ -685,36 +799,45 @@ CONFIG_I2C_IOP3XX=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 # -# Other I2C Chip support +# Misc devices # -# 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 +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers # # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -724,6 +847,7 @@ CONFIG_I2C_IOP3XX=y # # Graphics support # +CONFIG_FIRMWARE_EDID=y # CONFIG_FB is not set # @@ -731,6 +855,7 @@ CONFIG_I2C_IOP3XX=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -742,8 +867,13 @@ 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 # @@ -754,11 +884,18 @@ CONFIG_USB_ARCH_HAS_OHCI=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 @@ -768,22 +905,22 @@ CONFIG_JBD=y CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set - -# -# XFS support -# +# CONFIG_FS_POSIX_ACL is not set CONFIG_XFS_FS=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 @@ -803,12 +940,10 @@ 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 @@ -834,16 +969,19 @@ 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 @@ -852,6 +990,7 @@ CONFIG_SUNRPC=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types @@ -871,6 +1010,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set # CONFIG_EFI_PARTITION is not set # @@ -887,11 +1027,34 @@ CONFIG_MSDOS_PARTITION=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_KERNEL=y 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 @@ -912,5 +1075,7 @@ CONFIG_DEBUG_USER=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/iq31244_defconfig b/trunk/arch/arm/configs/iq31244_defconfig deleted file mode 100644 index 32467160a6df..000000000000 --- a/trunk/arch/arm/configs/iq31244_defconfig +++ /dev/null @@ -1,922 +0,0 @@ -# -# 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 deleted file mode 100644 index b000da753c41..000000000000 --- a/trunk/arch/arm/configs/iq80321_defconfig +++ /dev/null @@ -1,843 +0,0 @@ -# -# 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/iq80331_defconfig b/trunk/arch/arm/configs/iq80331_defconfig deleted file mode 100644 index 46c79e1efe07..000000000000 --- a/trunk/arch/arm/configs/iq80331_defconfig +++ /dev/null @@ -1,916 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 15:13:37 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=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 -# -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 f20814e6f497..a83222641045 100644 --- a/trunk/arch/arm/configs/s3c2410_defconfig +++ b/trunk/arch/arm/configs/s3c2410_defconfig @@ -1,14 +1,19 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17-git9 -# Sun Jun 25 23:56:32 2006 +# Linux kernel version: 2.6.18 +# Wed Sep 20 20:27:31 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 @@ -26,14 +31,15 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +# CONFIG_TASKSTATS is not set # 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 @@ -46,6 +52,8 @@ 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 @@ -84,7 +92,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_AT91RM9200 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 @@ -94,7 +102,8 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # CONFIG_ARCH_NETX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_IOP3XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set # CONFIG_ARCH_IXP4XX is not set # CONFIG_ARCH_IXP2000 is not set # CONFIG_ARCH_IXP23XX is not set @@ -122,13 +131,18 @@ 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 @@ -156,7 +170,7 @@ CONFIG_S3C2410_LOWLEVEL_UART_PORT=0 CONFIG_CPU_32=y CONFIG_CPU_ARM920T=y CONFIG_CPU_ARM926T=y -CONFIG_CPU_32v4=y +CONFIG_CPU_32v4T=y CONFIG_CPU_32v5=y CONFIG_CPU_ABRT_EV4T=y CONFIG_CPU_ABRT_EV5TJ=y @@ -200,6 +214,7 @@ 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 # @@ -304,7 +319,6 @@ 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 @@ -460,6 +474,7 @@ 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 @@ -640,6 +655,7 @@ 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 @@ -716,6 +732,7 @@ 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 @@ -857,12 +874,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 @@ -995,7 +1012,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_CY7C63 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 @@ -1095,6 +1112,7 @@ 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 @@ -1202,14 +1220,19 @@ 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_MUTEXES=y +# 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_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 @@ -1251,3 +1274,4 @@ 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 33c55689f999..ecf4f9472d94 100644 --- a/trunk/arch/arm/kernel/apm.c +++ b/trunk/arch/arm/kernel/apm.c @@ -25,6 +25,7 @@ #include #include #include +#include #include /* apm_power_info */ #include @@ -80,7 +81,7 @@ struct apm_user { */ static int suspends_pending; static int apm_disabled; -static int arm_apm_active; +static struct task_struct *kapmd_tsk; static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); @@ -97,7 +98,6 @@ 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,16 +468,13 @@ 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) || !arm_apm_active); + !queue_empty(&kapmd_queue) || kthread_should_stop()); - if (!arm_apm_active) + if (kthread_should_stop()) break; spin_lock_irq(&kapmd_queue_lock); @@ -508,7 +505,7 @@ static int kapmd(void *arg) } } while (1); - complete_and_exit(&kapmd_exit, 0); + return 0; } static int __init apm_init(void) @@ -520,13 +517,14 @@ static int __init apm_init(void) return -ENODEV; } - arm_apm_active = 1; - - ret = kernel_thread(kapmd, NULL, CLONE_KERNEL); - if (ret < 0) { - arm_apm_active = 0; + kapmd_tsk = kthread_create(kapmd, NULL, "kapmd"); + if (IS_ERR(kapmd_tsk)) { + ret = PTR_ERR(kapmd_tsk); + kapmd_tsk = NULL; 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); @@ -535,10 +533,7 @@ static int __init apm_init(void) ret = misc_register(&apm_device); if (ret != 0) { remove_proc_entry("apm", NULL); - - arm_apm_active = 0; - wake_up(&kapmd_wait); - wait_for_completion(&kapmd_exit); + kthread_stop(kapmd_tsk); } return ret; @@ -549,9 +544,7 @@ static void __exit apm_exit(void) misc_deregister(&apm_device); remove_proc_entry("apm", NULL); - arm_apm_active = 0; - wake_up(&kapmd_wait); - wait_for_completion(&kapmd_exit); + kthread_stop(kapmd_tsk); } module_init(apm_init); diff --git a/trunk/arch/arm/kernel/debug.S b/trunk/arch/arm/kernel/debug.S index a5747e58a9dc..5617566477b4 100644 --- a/trunk/arch/arm/kernel/debug.S +++ b/trunk/arch/arm/kernel/debug.S @@ -21,6 +21,36 @@ #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 @@ -46,9 +76,12 @@ bne 1001b 1002: .endm + +#endif /* CONFIG_CPU_V6 */ + #else #include -#endif +#endif /* CONFIG_DEBUG_ICEDCC */ /* * Useful debugging routines diff --git a/trunk/arch/arm/kernel/ecard.c b/trunk/arch/arm/kernel/ecard.c index eca248d9eba4..3e14b1348c0b 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(completion); + DECLARE_COMPLETION_ONSTACK(completion); req->complete = &completion; diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index de4e33137901..bd623b73445f 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -191,6 +191,9 @@ __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 @@ -211,6 +214,10 @@ 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 @@ -398,6 +405,9 @@ __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 @@ -412,6 +422,9 @@ __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 ac9eb3d30518..f359a189dcf2 100644 --- a/trunk/arch/arm/kernel/head-nommu.S +++ b/trunk/arch/arm/kernel/head-nommu.S @@ -9,7 +9,6 @@ * 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 @@ -40,7 +39,11 @@ 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' @@ -58,6 +61,7 @@ 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 @@ -72,8 +76,14 @@ __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 298363d97047..1b061583408e 100644 --- a/trunk/arch/arm/kernel/module.c +++ b/trunk/arch/arm/kernel/module.c @@ -2,6 +2,7 @@ * 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 @@ -32,6 +33,7 @@ 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; @@ -46,6 +48,12 @@ 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 3079535afccd..bf35c178a877 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -221,16 +221,26 @@ 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, transbase, dac; + unsigned int ctrl; __asm__ ( " mrc p15, 0, %0, c1, c0\n" - " 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); + : "=r" (ctrl)); + printk("Control: %04X\n", ctrl); } +#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/time.c b/trunk/arch/arm/kernel/time.c index 09a67d771857..b030320b17c7 100644 --- a/trunk/arch/arm/kernel/time.c +++ b/trunk/arch/arm/kernel/time.c @@ -37,8 +37,6 @@ */ struct sys_timer *system_timer; -extern unsigned long wall_jiffies; - /* this needs a better home */ DEFINE_SPINLOCK(rtc_lock); @@ -69,10 +67,12 @@ 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,20 +230,16 @@ 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, lost; + unsigned long usec, sec; 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)); @@ -276,7 +272,6 @@ 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); @@ -291,6 +286,7 @@ 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 @@ -333,7 +329,7 @@ void timer_tick(struct pt_regs *regs) profile_tick(CPU_PROFILING, regs); do_leds(); do_set_rtc(); - do_timer(regs); + do_timer(1); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -500,8 +496,10 @@ 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 aeeed806f991..bede380c07a9 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)); + asm("mov %0, fp" : "=r" (fp) : : "cc"); c_backtrace(fp, 0x10); barrier(); diff --git a/trunk/arch/arm/mach-at91rm9200/at91rm9200.c b/trunk/arch/arm/mach-at91rm9200/at91rm9200.c index 0985b1c42c7c..dcf6136fedf9 100644 --- a/trunk/arch/arm/mach-at91rm9200/at91rm9200.c +++ b/trunk/arch/arm/mach-at91rm9200/at91rm9200.c @@ -17,6 +17,7 @@ #include #include "generic.h" +#include "clock.h" static struct map_desc at91rm9200_io_desc[] __initdata = { { @@ -26,87 +27,224 @@ static struct map_desc at91rm9200_io_desc[] __initdata = { .type = MT_DEVICE, }, { .virtual = AT91_VA_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), + .pfn = __phys_to_pfn(AT91RM9200_BASE_SPI), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_EMAC, - .pfn = __phys_to_pfn(AT91_BASE_EMAC), + .pfn = __phys_to_pfn(AT91RM9200_BASE_EMAC), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_TWI, - .pfn = __phys_to_pfn(AT91_BASE_TWI), + .pfn = __phys_to_pfn(AT91RM9200_BASE_TWI), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_MCI, - .pfn = __phys_to_pfn(AT91_BASE_MCI), + .pfn = __phys_to_pfn(AT91RM9200_BASE_MCI), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_VA_BASE_UDP, - .pfn = __phys_to_pfn(AT91_BASE_UDP), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_TCB1, - .pfn = __phys_to_pfn(AT91_BASE_TCB1), - .length = SZ_16K, - .type = MT_DEVICE, - }, { - .virtual = AT91_VA_BASE_TCB0, - .pfn = __phys_to_pfn(AT91_BASE_TCB0), + .pfn = __phys_to_pfn(AT91RM9200_BASE_UDP), .length = SZ_16K, .type = MT_DEVICE, }, { .virtual = AT91_SRAM_VIRT_BASE, - .pfn = __phys_to_pfn(AT91_SRAM_BASE), - .length = AT91_SRAM_SIZE, + .pfn = __phys_to_pfn(AT91RM9200_SRAM_BASE), + .length = AT91RM9200_SRAM_SIZE, .type = MT_DEVICE, }, }; -void __init at91rm9200_map_io(void) +/* -------------------------------------------------------------------- + * 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, + }, { + .id = AT91RM9200_ID_PIOD, + .offset = AT91_PIOD, + .clock = &pioD_clk, + } +}; + +/* -------------------------------------------------------------------- + * AT91RM9200 processor initialization + * -------------------------------------------------------------------- */ +void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks) +{ + /* 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). */ @@ -145,10 +283,14 @@ static unsigned int at91rm9200_default_irq_priority[NR_AIC_IRQS] __initdata = { 0 /* Advanced Interrupt Controller (IRQ6) */ }; -void __init at91rm9200_init_irq(unsigned int priority[NR_AIC_IRQS]) +void __init at91rm9200_init_interrupts(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 dc79e0992af7..36eecd7161f5 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-1arm.c +++ b/trunk/arch/arm/mach-at91rm9200/board-1arm.c @@ -34,20 +34,11 @@ #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. @@ -62,15 +53,18 @@ static struct at91_uart_config __initdata onearm_uart_config = { static void __init onearm_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 18.432 MHz crystal */ - at91_clock_init(18432000); + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000, AT91RM9200_PQFP); /* 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 2c138b542ebe..50e513681ae6 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-carmeva.c +++ b/trunk/arch/arm/mach-at91rm9200/board-carmeva.c @@ -35,20 +35,11 @@ #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. @@ -63,15 +54,19 @@ static struct at91_uart_config __initdata carmeva_uart_config = { static void __init carmeva_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 20.000 MHz crystal */ - at91_clock_init(20000000); + /* Initialize processor: 20.000 MHz crystal */ + at91rm9200_initialize(20000000, AT91RM9200_BGA); /* 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 794d3fbb449b..8eeae491ce71 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-csb337.c +++ b/trunk/arch/arm/mach-at91rm9200/board-csb337.c @@ -34,20 +34,11 @@ #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. @@ -62,10 +53,8 @@ static struct at91_uart_config __initdata csb337_uart_config = { static void __init csb337_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 3.6864 MHz crystal */ - at91_clock_init(3686400); + /* Initialize processor: 3.6864 MHz crystal */ + at91rm9200_initialize(3686400, AT91RM9200_BGA); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); @@ -74,6 +63,11 @@ 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 c8b6f334246a..a29fa0e822ce 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-csb637.c +++ b/trunk/arch/arm/mach-at91rm9200/board-csb637.c @@ -33,20 +33,11 @@ #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. @@ -61,10 +52,8 @@ static struct at91_uart_config __initdata csb637_uart_config = { static void __init csb637_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 3.6864 MHz crystal */ - at91_clock_init(3686400); + /* Initialize processor: 3.6864 MHz crystal */ + at91rm9200_initialize(3686400, AT91RM9200_BGA); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); @@ -73,6 +62,11 @@ 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 65873037e02a..c699f3984d4b 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-dk.c +++ b/trunk/arch/arm/mach-at91rm9200/board-dk.c @@ -37,20 +37,11 @@ #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. @@ -65,10 +56,8 @@ static struct at91_uart_config __initdata dk_uart_config = { static void __init dk_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 18.432 MHz crystal */ - at91_clock_init(18432000); + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000, AT91RM9200_BGA); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2); @@ -77,6 +66,11 @@ 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, @@ -128,6 +122,29 @@ 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 */ @@ -153,6 +170,8 @@ 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 a3e2df968a66..c6e0d51fbea0 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-eb9200.c +++ b/trunk/arch/arm/mach-at91rm9200/board-eb9200.c @@ -35,20 +35,11 @@ #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. @@ -63,15 +54,18 @@ static struct at91_uart_config __initdata eb9200_uart_config = { static void __init eb9200_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 18.432 MHz crystal */ - at91_clock_init(18432000); + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000, AT91RM9200_BGA); /* 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 868192351dda..830eb7932178 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-ek.c +++ b/trunk/arch/arm/mach-at91rm9200/board-ek.c @@ -37,20 +37,11 @@ #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. @@ -65,10 +56,8 @@ static struct at91_uart_config __initdata ek_uart_config = { static void __init ek_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 18.432 MHz crystal */ - at91_clock_init(18432000); + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000, AT91RM9200_BGA); /* Setup the LEDs */ at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2); @@ -77,6 +66,11 @@ 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 bf760c5e0c46..91e301924f2c 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-kafa.c +++ b/trunk/arch/arm/mach-at91rm9200/board-kafa.c @@ -34,20 +34,11 @@ #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. @@ -62,10 +53,8 @@ static struct at91_uart_config __initdata kafa_uart_config = { static void __init kafa_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 18.432 MHz crystal */ - at91_clock_init(18432000); + /* Initialize processor: 18.432 MHz crystal */ + at91rm9200_initialize(18432000, AT91RM9200_PQFP); /* Set up the LEDs */ at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4); @@ -74,6 +63,11 @@ 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 f06d2b54cc9a..272fe43bceca 100644 --- a/trunk/arch/arm/mach-at91rm9200/board-kb9202.c +++ b/trunk/arch/arm/mach-at91rm9200/board-kb9202.c @@ -35,20 +35,11 @@ #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. @@ -63,10 +54,8 @@ static struct at91_uart_config __initdata kb9202_uart_config = { static void __init kb9202_map_io(void) { - at91rm9200_map_io(); - - /* Initialize clocks: 10 MHz crystal */ - at91_clock_init(10000000); + /* Initialize processor: 10 MHz crystal */ + at91rm9200_initialize(10000000, AT91RM9200_PQFP); /* Set up the LEDs */ at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18); @@ -75,6 +64,11 @@ 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, @@ -95,6 +89,29 @@ 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 */ @@ -111,6 +128,8 @@ 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 edc2cc837ae6..a43b061a7c85 100644 --- a/trunk/arch/arm/mach-at91rm9200/clock.c +++ b/trunk/arch/arm/mach-at91rm9200/clock.c @@ -29,7 +29,7 @@ #include -#include "generic.h" +#include "clock.h" /* @@ -38,23 +38,15 @@ * PLLB be used at other rates (on boards that don't need USB), etc. */ -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; -}; +#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); -static spinlock_t clk_lock; -static u32 at91_pllb_usb_init; +static u32 at91_pllb_usb_init; /* * Four primary clock sources: two crystal oscillators (32K, main), and @@ -67,21 +59,20 @@ static struct clk clk32k = { .rate_hz = AT91_SLOW_CLOCK, .users = 1, /* always on */ .id = 0, - .primary = 1, + .type = CLK_TYPE_PRIMARY, }; static struct clk main_clk = { .name = "main", .pmc_mask = AT91_PMC_MOSCS, /* in PMC_SR */ .id = 1, - .primary = 1, + .type = CLK_TYPE_PRIMARY, }; static struct clk plla = { .name = "plla", .parent = &main_clk, .pmc_mask = AT91_PMC_LOCKA, /* in PMC_SR */ .id = 2, - .primary = 1, - .pll = 1, + .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, }; static void pllb_mode(struct clk *clk, int is_on) @@ -94,6 +85,7 @@ 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 { @@ -107,8 +99,7 @@ static struct clk pllb = { .pmc_mask = AT91_PMC_LOCKB, /* in PMC_SR */ .mode = pllb_mode, .id = 3, - .primary = 1, - .pll = 1, + .type = CLK_TYPE_PRIMARY | CLK_TYPE_PLL, }; static void pmc_sys_mode(struct clk *clk, int is_on) @@ -133,41 +124,6 @@ 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 @@ -187,131 +143,21 @@ static void pmc_periph_mode(struct clk *clk, int is_on) at91_sys_write(AT91_PMC_PCDR, clk->pmc_mask); } -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, -}; +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; + } + return NULL; +} /* * Associate a particular clock with a function (eg, "uart") and device. @@ -329,14 +175,12 @@ void __init at91_clock_associate(const char *id, struct device *dev, const char clk->dev = dev; } -/* clocks are all static for now; no refcounting necessary */ +/* clocks cannot be de-registered no refcounting necessary */ struct clk *clk_get(struct device *dev, const char *id) { - int i; - - for (i = 0; i < ARRAY_SIZE(clock_list); i++) { - struct clk *clk = clock_list[i]; + struct clk *clk; + 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) @@ -424,7 +268,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate) unsigned prescale; unsigned long actual; - if (!clk->programmable) + if (!clk_is_programmable(clk)) return -EINVAL; spin_lock_irqsave(&clk_lock, flags); @@ -446,7 +290,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) unsigned prescale; unsigned long actual; - if (!clk->programmable) + if (!clk_is_programmable(clk)) return -EINVAL; if (clk->users) return -EBUSY; @@ -484,7 +328,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent) if (clk->users) return -EBUSY; - if (!parent->primary || !clk->programmable) + if (!clk_is_primary(parent) || !clk_is_programmable(clk)) return -EINVAL; spin_lock_irqsave(&clk_lock, flags); @@ -497,6 +341,18 @@ 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 */ /*------------------------------------------------------------------------*/ @@ -506,6 +362,7 @@ EXPORT_SYMBOL(clk_set_parent); 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)); @@ -523,9 +380,8 @@ static int at91_clk_show(struct seq_file *s, void *unused) seq_printf(s, "\n"); - for (i = 0; i < ARRAY_SIZE(clock_list); i++) { - char *state; - struct clk *clk = clock_list[i]; + list_for_each_entry(clk, &clocks, node) { + char *state; if (clk->mode == pmc_sys_mode) state = (scsr & clk->pmc_mask) ? "on" : "off"; @@ -568,6 +424,28 @@ 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) @@ -640,20 +518,17 @@ 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 at91_periphclk_reset(void) +static void __init at91_periphclk_reset(void) { unsigned long reg; - int i; + struct clk *clk; reg = at91_sys_read(AT91_PMC_PCSR); - for (i = 0; i < ARRAY_SIZE(clock_list); i++) { - struct clk *clk = clock_list[i]; - + list_for_each_entry(clk, &clocks, node) { if (clk->mode != pmc_periph_mode) continue; @@ -664,11 +539,25 @@ static void 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; - - spin_lock_init(&clk_lock); + int i; /* * When the bootloader initialized the main oscillator correctly, @@ -709,11 +598,15 @@ 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 = clock_list[mckr & AT91_PMC_CSS]; + mck.parent = at91_css_to_clk(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); @@ -722,35 +615,8 @@ 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 new file mode 100644 index 000000000000..0592e662ab37 --- /dev/null +++ b/trunk/arch/arm/mach-at91rm9200/clock.h @@ -0,0 +1,30 @@ +/* + * 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 4352acb88178..01525530c287 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 = AT91_UHP_BASE, - .end = AT91_UHP_BASE + SZ_1M - 1, + .start = AT91RM9200_UHP_BASE, + .end = AT91RM9200_UHP_BASE + SZ_1M - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_UHP, - .end = AT91_ID_UHP, + .start = AT91RM9200_ID_UHP, + .end = AT91RM9200_ID_UHP, .flags = IORESOURCE_IRQ, }, }; @@ -80,13 +80,13 @@ static struct at91_udc_data udc_data; static struct resource at91_udc_resources[] = { [0] = { - .start = AT91_BASE_UDP, - .end = AT91_BASE_UDP + SZ_16K - 1, + .start = AT91RM9200_BASE_UDP, + .end = AT91RM9200_BASE_UDP + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_UDP, - .end = AT91_ID_UDP, + .start = AT91RM9200_ID_UDP, + .end = AT91RM9200_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_BASE_EMAC, - .end = AT91_BASE_EMAC + SZ_16K - 1, + .start = AT91_VA_BASE_EMAC, + .end = AT91_VA_BASE_EMAC + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_EMAC, - .end = AT91_ID_EMAC, + .start = AT91RM9200_ID_EMAC, + .end = AT91RM9200_ID_EMAC, .flags = IORESOURCE_IRQ, }, }; @@ -263,13 +263,13 @@ static struct at91_mmc_data mmc_data; static struct resource at91_mmc_resources[] = { [0] = { - .start = AT91_BASE_MCI, - .end = AT91_BASE_MCI + SZ_16K - 1, + .start = AT91RM9200_BASE_MCI, + .end = AT91RM9200_BASE_MCI + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_MCI, - .end = AT91_ID_MCI, + .start = AT91RM9200_ID_MCI, + .end = AT91RM9200_ID_MCI, .flags = IORESOURCE_IRQ, }, }; @@ -423,13 +423,13 @@ static u64 spi_dmamask = 0xffffffffUL; static struct resource at91_spi_resources[] = { [0] = { - .start = AT91_BASE_SPI, - .end = AT91_BASE_SPI + SZ_16K - 1, + .start = AT91RM9200_BASE_SPI, + .end = AT91RM9200_BASE_SPI + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_SPI, - .end = AT91_ID_SPI, + .start = AT91RM9200_ID_SPI, + .end = AT91RM9200_ID_SPI, .flags = IORESOURCE_IRQ, }, }; @@ -582,13 +582,13 @@ static inline void configure_dbgu_pins(void) static struct resource uart0_resources[] = { [0] = { - .start = AT91_BASE_US0, - .end = AT91_BASE_US0 + SZ_16K - 1, + .start = AT91RM9200_BASE_US0, + .end = AT91RM9200_BASE_US0 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_US0, - .end = AT91_ID_US0, + .start = AT91RM9200_ID_US0, + .end = AT91RM9200_ID_US0, .flags = IORESOURCE_IRQ, }, }; @@ -624,13 +624,13 @@ static inline void configure_usart0_pins(void) static struct resource uart1_resources[] = { [0] = { - .start = AT91_BASE_US1, - .end = AT91_BASE_US1 + SZ_16K - 1, + .start = AT91RM9200_BASE_US1, + .end = AT91RM9200_BASE_US1 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_US1, - .end = AT91_ID_US1, + .start = AT91RM9200_ID_US1, + .end = AT91RM9200_ID_US1, .flags = IORESOURCE_IRQ, }, }; @@ -665,13 +665,13 @@ static inline void configure_usart1_pins(void) static struct resource uart2_resources[] = { [0] = { - .start = AT91_BASE_US2, - .end = AT91_BASE_US2 + SZ_16K - 1, + .start = AT91RM9200_BASE_US2, + .end = AT91RM9200_BASE_US2 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_US2, - .end = AT91_ID_US2, + .start = AT91RM9200_ID_US2, + .end = AT91RM9200_ID_US2, .flags = IORESOURCE_IRQ, }, }; @@ -700,13 +700,13 @@ static inline void configure_usart2_pins(void) static struct resource uart3_resources[] = { [0] = { - .start = AT91_BASE_US3, - .end = AT91_BASE_US3 + SZ_16K - 1, + .start = AT91RM9200_BASE_US3, + .end = AT91RM9200_BASE_US3 + SZ_16K - 1, .flags = IORESOURCE_MEM, }, [1] = { - .start = AT91_ID_US3, - .end = AT91_ID_US3, + .start = AT91RM9200_ID_US3, + .end = AT91RM9200_ID_US3, .flags = IORESOURCE_IRQ, }, }; diff --git a/trunk/arch/arm/mach-at91rm9200/generic.h b/trunk/arch/arm/mach-at91rm9200/generic.h index 7979d8ab7e07..694e411e285f 100644 --- a/trunk/arch/arm/mach-at91rm9200/generic.h +++ b/trunk/arch/arm/mach-at91rm9200/generic.h @@ -8,18 +8,17 @@ * 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_irq(unsigned int priority[]); +extern void __init at91rm9200_init_interrupts(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; @@ -29,3 +28,14 @@ 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 cec199fd6721..58c9bf5e9520 100644 --- a/trunk/arch/arm/mach-at91rm9200/gpio.c +++ b/trunk/arch/arm/mach-at91rm9200/gpio.c @@ -9,6 +9,7 @@ * (at your option) any later version. */ +#include #include #include #include @@ -20,12 +21,12 @@ #include #include -static const u32 pio_controller_offset[4] = { - AT91_PIOA, - AT91_PIOB, - AT91_PIOC, - AT91_PIOD, -}; +#include "generic.h" + + +static struct at91_gpio_bank *gpio; +static int gpio_banks; + static inline void __iomem *pin_to_controller(unsigned pin) { @@ -33,8 +34,8 @@ static inline void __iomem *pin_to_controller(unsigned pin) pin -= PIN_BASE; pin /= 32; - if (likely(pin < BGA_GPIO_BANKS)) - return sys_base + pio_controller_offset[pin]; + if (likely(pin < gpio_banks)) + return sys_base + gpio[pin].offset; return NULL; } @@ -179,7 +180,6 @@ 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[BGA_GPIO_BANKS]; -static u32 backups[BGA_GPIO_BANKS]; +static u32 wakeups[MAX_GPIO_BANKS]; +static u32 backups[MAX_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 >= BGA_GPIO_BANKS)) + if (unlikely(pin >= MAX_GPIO_BANKS)) return -EINVAL; if (state) @@ -241,8 +241,8 @@ void at91_gpio_suspend(void) { int i; - for (i = 0; i < BGA_GPIO_BANKS; i++) { - u32 pio = pio_controller_offset[i]; + for (i = 0; i < gpio_banks; i++) { + u32 pio = gpio[i].offset; /* * 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_controller_offset[i] + PIO_IDR, backups[i]); - at91_sys_write(pio_controller_offset[i] + PIO_IER, wakeups[i]); + at91_sys_write(pio + PIO_IDR, backups[i]); + at91_sys_write(pio + PIO_IER, wakeups[i]); if (!wakeups[i]) { - disable_irq_wake(AT91_ID_PIOA + i); - at91_sys_write(AT91_PMC_PCDR, 1 << (AT91_ID_PIOA + i)); + disable_irq_wake(gpio[i].id); + at91_sys_write(AT91_PMC_PCDR, 1 << gpio[i].id); } else { - enable_irq_wake(AT91_ID_PIOA + i); + enable_irq_wake(gpio[i].id); #ifdef CONFIG_PM_DEBUG printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", "ABCD"[i], wakeups[i]); #endif @@ -276,16 +276,13 @@ void at91_gpio_resume(void) { int i; - 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]); - } + for (i = 0; i < gpio_banks; i++) { + u32 pio = gpio[i].offset; - at91_sys_write(AT91_PMC_PCER, - (1 << AT91_ID_PIOA) - | (1 << AT91_ID_PIOB) - | (1 << AT91_ID_PIOC) - | (1 << AT91_ID_PIOD)); + 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); + } } #else @@ -377,20 +374,25 @@ static void gpio_irq_handler(unsigned irq, struct irqdesc *desc, struct pt_regs /* now it may re-trigger */ } -/* call this from board-specific init_irq */ -void __init at91_gpio_irq_setup(unsigned banks) +/*--------------------------------------------------------------------------*/ + +/* + * Called from the processor-specific init to enable GPIO interrupt support. + */ +void __init at91_gpio_irq_setup(void) { - unsigned pioc, pin, id; + unsigned pioc, pin; - if (banks > 4) - banks = 4; - for (pioc = 0, pin = PIN_BASE, id = AT91_ID_PIOA; - pioc < banks; - pioc++, id++) { + for (pioc = 0, pin = PIN_BASE; + pioc < gpio_banks; + pioc++) { void __iomem *controller; + unsigned id = gpio[pioc].id; unsigned i; - controller = (void __iomem *) AT91_VA_BASE_SYS + pio_controller_offset[pioc]; + clk_enable(gpio[pioc].clock); /* enable PIO controller's clock */ + + controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset; __raw_writel(~0, controller + PIO_IDR); set_irq_data(id, (void *) pin); @@ -408,5 +410,16 @@ void __init at91_gpio_irq_setup(unsigned banks) set_irq_chained_handler(id, gpio_irq_handler); } - pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, banks); + 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; } diff --git a/trunk/arch/arm/mach-at91rm9200/irq.c b/trunk/arch/arm/mach-at91rm9200/irq.c index c3a5e777f9f8..3e488117ca91 100644 --- a/trunk/arch/arm/mach-at91rm9200/irq.c +++ b/trunk/arch/arm/mach-at91rm9200/irq.c @@ -34,8 +34,6 @@ #include #include -#include "generic.h" - static void at91_aic_mask_irq(unsigned int irq) { @@ -61,12 +59,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 < AT91_ID_IRQ0)) /* only supported on external interrupts */ + if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_ID_IRQ0)) /* only supported on external interrupts */ return -EINVAL; srctype = AT91_AIC_SRCTYPE_LOW; break; case IRQT_FALLING: - if ((irq > AT91_ID_FIQ) && (irq < AT91_ID_IRQ0)) /* only supported on external interrupts */ + if ((irq > AT91_ID_FIQ) && (irq < AT91RM9200_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 47e5480feb7e..32c95d8eaacf 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 << 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)) + | (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)) & at91_sys_read(AT91_AIC_IMR), state); diff --git a/trunk/arch/arm/mach-ep93xx/Kconfig b/trunk/arch/arm/mach-ep93xx/Kconfig index f1b740083aee..e346b03cd921 100644 --- a/trunk/arch/arm/mach-ep93xx/Kconfig +++ b/trunk/arch/arm/mach-ep93xx/Kconfig @@ -15,6 +15,12 @@ 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 1f5a6b0487ee..c2eb18b530c2 100644 --- a/trunk/arch/arm/mach-ep93xx/Makefile +++ b/trunk/arch/arm/mach-ep93xx/Makefile @@ -7,6 +7,7 @@ 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 new file mode 100644 index 000000000000..9e399211108c --- /dev/null +++ b/trunk/arch/arm/mach-ep93xx/edb9312.c @@ -0,0 +1,63 @@ +/* + * 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 823e25d4547e..a1ae49df5c3b 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("ldr%?b %0, [%1, %2]" - : "=r" (v) : "r" (addr), "r" (where)); + asm("ldrb %0, [%1, %2]" + : "=r" (v) : "r" (addr), "r" (where) : "cc"); break; case 2: - asm("ldr%?h %0, [%1, %2]" - : "=r" (v) : "r" (addr), "r" (where)); + asm("ldrh %0, [%1, %2]" + : "=r" (v) : "r" (addr), "r" (where) : "cc"); break; case 4: - asm("ldr%? %0, [%1, %2]" - : "=r" (v) : "r" (addr), "r" (where)); + asm("ldr %0, [%1, %2]" + : "=r" (v) : "r" (addr), "r" (where) : "cc"); break; } @@ -103,16 +103,19 @@ dc21285_write_config(struct pci_bus *bus, unsigned int devfn, int where, if (addr) switch (size) { case 1: - asm("str%?b %0, [%1, %2]" - : : "r" (value), "r" (addr), "r" (where)); + asm("strb %0, [%1, %2]" + : : "r" (value), "r" (addr), "r" (where) + : "cc"); break; case 2: - asm("str%?h %0, [%1, %2]" - : : "r" (value), "r" (addr), "r" (where)); + asm("strh %0, [%1, %2]" + : : "r" (value), "r" (addr), "r" (where) + : "cc"); break; case 4: - asm("str%? %0, [%1, %2]" - : : "r" (value), "r" (addr), "r" (where)); + asm("str %0, [%1, %2]" + : : "r" (value), "r" (addr), "r" (where) + : "cc"); break; } diff --git a/trunk/arch/arm/mach-iop32x/Kconfig b/trunk/arch/arm/mach-iop32x/Kconfig new file mode 100644 index 000000000000..c072d94070da --- /dev/null +++ b/trunk/arch/arm/mach-iop32x/Kconfig @@ -0,0 +1,35 @@ +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 new file mode 100644 index 000000000000..7b05b37e1f94 --- /dev/null +++ b/trunk/arch/arm/mach-iop32x/Makefile @@ -0,0 +1,13 @@ +# +# 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 new file mode 100644 index 000000000000..47000dccd61f --- /dev/null +++ b/trunk/arch/arm/mach-iop32x/Makefile.boot @@ -0,0 +1,3 @@ + 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 new file mode 100644 index 000000000000..b9b765057dbe --- /dev/null +++ b/trunk/arch/arm/mach-iop32x/glantank.c @@ -0,0 +1,195 @@ +/* + * 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 new file mode 100644 index 000000000000..be4aedfa0de6 --- /dev/null +++ b/trunk/arch/arm/mach-iop32x/iq31244.c @@ -0,0 +1,293 @@ +/* + * 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 new file mode 100644 index 000000000000..1f37b5501888 --- /dev/null +++ b/trunk/arch/arm/mach-iop32x/iq80321.c @@ -0,0 +1,193 @@ +/* + * 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 new file mode 100644 index 000000000000..69d6302f40cf --- /dev/null +++ b/trunk/arch/arm/mach-iop32x/irq.c @@ -0,0 +1,76 @@ +/* + * 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 new file mode 100644 index 000000000000..a2c94a47b2b2 --- /dev/null +++ b/trunk/arch/arm/mach-iop32x/n2100.c @@ -0,0 +1,251 @@ +/* + * 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 new file mode 100644 index 000000000000..9aa016bb18f9 --- /dev/null +++ b/trunk/arch/arm/mach-iop33x/Kconfig @@ -0,0 +1,21 @@ +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 new file mode 100644 index 000000000000..90081d8c9d16 --- /dev/null +++ b/trunk/arch/arm/mach-iop33x/Makefile @@ -0,0 +1,11 @@ +# +# 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 new file mode 100644 index 000000000000..67039c3e0c48 --- /dev/null +++ b/trunk/arch/arm/mach-iop33x/Makefile.boot @@ -0,0 +1,3 @@ + 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 new file mode 100644 index 000000000000..97a7b7488264 --- /dev/null +++ b/trunk/arch/arm/mach-iop33x/iq80331.c @@ -0,0 +1,148 @@ +/* + * 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 new file mode 100644 index 000000000000..9887bfc1c078 --- /dev/null +++ b/trunk/arch/arm/mach-iop33x/iq80332.c @@ -0,0 +1,148 @@ +/* + * 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 new file mode 100644 index 000000000000..63304b3d0d76 --- /dev/null +++ b/trunk/arch/arm/mach-iop33x/irq.c @@ -0,0 +1,127 @@ +/* + * 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 new file mode 100644 index 000000000000..ac297cd0276c --- /dev/null +++ b/trunk/arch/arm/mach-iop33x/uart.c @@ -0,0 +1,105 @@ +/* + * 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 deleted file mode 100644 index 4422f2388607..000000000000 --- a/trunk/arch/arm/mach-iop3xx/Kconfig +++ /dev/null @@ -1,66 +0,0 @@ -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 deleted file mode 100644 index b17eb1f46102..000000000000 --- a/trunk/arch/arm/mach-iop3xx/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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 deleted file mode 100644 index 6387aa20461b..000000000000 --- a/trunk/arch/arm/mach-iop3xx/Makefile.boot +++ /dev/null @@ -1,9 +0,0 @@ - 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 deleted file mode 100644 index d7f50e57e753..000000000000 --- a/trunk/arch/arm/mach-iop3xx/common.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 deleted file mode 100644 index 88ac333472c8..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iop321-irq.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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 deleted file mode 100644 index 8ba6a0e23134..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iop321-pci.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * 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 deleted file mode 100644 index b6d096903c4a..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iop321-setup.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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 deleted file mode 100644 index 04b1a6f7ebae..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iop321-time.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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 deleted file mode 100644 index cab11722ced2..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iop331-irq.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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 deleted file mode 100644 index 44dd213b48a3..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iop331-pci.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * 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 deleted file mode 100644 index 3cc98d892ad4..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iop331-setup.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * 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 deleted file mode 100644 index 0c09e74c5740..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iop331-time.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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 deleted file mode 100644 index e874b54eefe3..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iq31244-mm.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 deleted file mode 100644 index f3c6413fa5bd..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iq31244-pci.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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 deleted file mode 100644 index d9cac5e1fc3d..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iq80321-mm.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 deleted file mode 100644 index d9758d3f6e7f..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iq80321-pci.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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 deleted file mode 100644 index 129eb49b0670..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iq80331-mm.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 deleted file mode 100644 index 40d861002492..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iq80331-pci.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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 deleted file mode 100644 index 2feaf7591f53..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iq80332-mm.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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 deleted file mode 100644 index afc0676318e4..000000000000 --- a/trunk/arch/arm/mach-iop3xx/iq80332-pci.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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 7c25dbd5a181..35dd8b3824b0 100644 --- a/trunk/arch/arm/mach-ixp4xx/common.c +++ b/trunk/arch/arm/mach-ixp4xx/common.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -255,16 +256,6 @@ 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); @@ -309,7 +300,6 @@ 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[] = { @@ -365,3 +355,29 @@ 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 749a337494d3..162c266e5f8f 100644 --- a/trunk/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/trunk/arch/arm/mach-ixp4xx/nslu2-setup.c @@ -159,6 +159,8 @@ 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 c753a3c5aadd..62e42c7a628e 100644 --- a/trunk/arch/arm/mach-omap1/board-fsample.c +++ b/trunk/arch/arm/mach-omap1/board-fsample.c @@ -172,9 +172,11 @@ static struct resource kp_resources[] = { }; static struct omap_kp_platform_data kp_data = { - .rows = 8, - .cols = 8, - .keymap = fsample_keymap, + .rows = 8, + .cols = 8, + .keymap = fsample_keymap, + .keymapsize = ARRAY_SIZE(fsample_keymap), + .delay = 4, }; 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 cd3a06dfc0a8..6e113078f7ab 100644 --- a/trunk/arch/arm/mach-omap1/board-h2.c +++ b/trunk/arch/arm/mach-omap1/board-h2.c @@ -167,10 +167,13 @@ static struct resource h2_kp_resources[] = { }; static struct omap_kp_platform_data h2_kp_data = { - .rows = 8, - .cols = 8, - .keymap = h2_keymap, - .rep = 1, + .rows = 8, + .cols = 8, + .keymap = h2_keymap, + .keymapsize = ARRAY_SIZE(h2_keymap), + .rep = 1, + .delay = 9, + .dbounce = 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 7b206116cd03..f225a083dee1 100644 --- a/trunk/arch/arm/mach-omap1/board-h3.c +++ b/trunk/arch/arm/mach-omap1/board-h3.c @@ -247,10 +247,13 @@ static struct resource h3_kp_resources[] = { }; static struct omap_kp_platform_data h3_kp_data = { - .rows = 8, - .cols = 8, - .keymap = h3_keymap, - .rep = 1, + .rows = 8, + .cols = 8, + .keymap = h3_keymap, + .keymapsize = ARRAY_SIZE(h3_keymap), + .rep = 1, + .delay = 9, + .dbounce = 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 4cbc62db5b5d..cb00530ad279 100644 --- a/trunk/arch/arm/mach-omap1/board-innovator.c +++ b/trunk/arch/arm/mach-omap1/board-innovator.c @@ -159,9 +159,11 @@ static struct resource innovator_kp_resources[] = { }; static struct omap_kp_platform_data innovator_kp_data = { - .rows = 8, - .cols = 8, - .keymap = innovator_keymap, + .rows = 8, + .cols = 8, + .keymap = innovator_keymap, + .keymapsize = ARRAY_SIZE(innovator_keymap), + .delay = 4, }; 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 02b980d77b12..dbc555d209ff 100644 --- a/trunk/arch/arm/mach-omap1/board-nokia770.c +++ b/trunk/arch/arm/mach-omap1/board-nokia770.c @@ -71,9 +71,11 @@ static struct resource nokia770_kp_resources[] = { }; static struct omap_kp_platform_data nokia770_kp_data = { - .rows = 8, - .cols = 8, - .keymap = nokia770_keymap + .rows = 8, + .cols = 8, + .keymap = nokia770_keymap, + .keymapsize = ARRAY_SIZE(nokia770_keymap) + .delay = 4, }; 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 b742261c97ad..6b05647a6c01 100644 --- a/trunk/arch/arm/mach-omap1/board-osk.c +++ b/trunk/arch/arm/mach-omap1/board-osk.c @@ -266,9 +266,11 @@ static const int osk_keymap[] = { }; static struct omap_kp_platform_data osk_kp_data = { - .rows = 8, - .cols = 8, - .keymap = (int *) osk_keymap, + .rows = 8, + .cols = 8, + .keymap = (int *) osk_keymap, + .keymapsize = ARRAY_SIZE(osk_keymap), + .delay = 9, }; 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 64b45d8ae357..fa4be962df67 100644 --- a/trunk/arch/arm/mach-omap1/board-perseus2.c +++ b/trunk/arch/arm/mach-omap1/board-perseus2.c @@ -171,9 +171,12 @@ static struct resource kp_resources[] = { }; static struct omap_kp_platform_data kp_data = { - .rows = 8, - .cols = 8, - .keymap = p2_keymap, + .rows = 8, + .cols = 8, + .keymap = p2_keymap, + .keymapsize = ARRAY_SIZE(p2_keymap), + .delay = 4, + .dbounce = 1, }; 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 f1958e882e86..638490e62d5f 100644 --- a/trunk/arch/arm/mach-omap1/clock.c +++ b/trunk/arch/arm/mach-omap1/clock.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -586,77 +587,53 @@ 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 int __init omap1_late_clk_reset(void) +static void __init omap1_clk_disable_unused(struct clk *clk) { - /* Turn off all unused clocks */ - struct clk *p; __u32 regval32; - /* 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); - - 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; - } + /* 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; + } - /* 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(p->enable_reg); - } else { - if (p->flags & VIRTUAL_IO_ADDRESS) - regval32 = __raw_readw(p->enable_reg); + /* Is the clock already disabled? */ + if (clk->flags & ENABLE_REG_32BIT) { + if (clk->flags & VIRTUAL_IO_ADDRESS) + regval32 = __raw_readl(clk->enable_reg); else - regval32 = omap_readw(p->enable_reg); - } - - if ((regval32 & (1 << p->enable_bit)) == 0) - continue; + 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); + } - /* 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; - } + if ((regval32 & (1 << clk->enable_bit)) == 0) + return; - printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name); - p->disable(p); - printk(" done\n"); + /* 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; } - return 0; + printk(KERN_INFO "Disabling unused clock \"%s\"... ", clk->name); + clk->disable(clk); + printk(" done\n"); } -late_initcall(omap1_late_clk_reset); #else -#define omap1_early_clk_reset() {} +#define omap1_clk_disable_unused NULL #endif static struct clk_functions omap1_clk_functions = { @@ -664,6 +641,7 @@ 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) @@ -671,8 +649,13 @@ 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 */ @@ -772,6 +755,12 @@ 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 b7c68819c4e7..f7df00205c4a 100644 --- a/trunk/arch/arm/mach-omap1/clock.h +++ b/trunk/arch/arm/mach-omap1/clock.h @@ -89,6 +89,7 @@ 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 */ @@ -741,6 +742,18 @@ 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, @@ -790,6 +803,7 @@ 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 fa74ef7af15f..5432335bc493 100644 --- a/trunk/arch/arm/mach-omap1/mux.c +++ b/trunk/arch/arm/mach-omap1/mux.c @@ -199,6 +199,17 @@ 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 7993b7bae2bd..2db6b732b084 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 = 0, - .wire4 = 0, + .enabled = 1, + .wire4 = 1, .wp_pin = -1, .power_pin = -1, .switch_pin = -1, @@ -257,6 +257,9 @@ 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 4933fce766c8..996aeda1285d 100644 --- a/trunk/arch/arm/mach-omap2/board-h4.c +++ b/trunk/arch/arm/mach-omap2/board-h4.c @@ -245,6 +245,7 @@ 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 d1b648a4efbf..0de201c3d50b 100644 --- a/trunk/arch/arm/mach-omap2/clock.c +++ b/trunk/arch/arm/mach-omap2/clock.c @@ -32,10 +32,14 @@ #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 @@ -79,6 +83,14 @@ 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) { @@ -101,12 +113,54 @@ 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) + 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); break; + } } + if (i) + pr_debug("Clock %s stable after %d loops\n", clk->name, i); } /* Enables clock without considering parent dependencies or use count @@ -119,6 +173,11 @@ 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); @@ -133,6 +192,9 @@ 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; } @@ -155,6 +217,11 @@ 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; @@ -166,6 +233,7 @@ 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) @@ -695,12 +763,14 @@ 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); @@ -836,10 +906,12 @@ 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); @@ -953,12 +1025,29 @@ 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) @@ -984,27 +1073,19 @@ static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys) sys->rate = sclk; } -#ifdef CONFIG_OMAP_RESET_CLOCKS -static void __init omap2_disable_unused_clocks(void) +/* + * Set clocks for bypass mode for reboot to work. + */ +void omap2_clk_prepare_for_reboot(void) { - struct clk *ck; - u32 regval32; + u32 rate; - 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; + if (vclk == NULL || sclk == NULL) + return; - printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name); - _omap2_clk_disable(ck); - } + rate = clk_get_rate(sclk); + clk_set_rate(vclk, rate); } -late_initcall(omap2_disable_unused_clocks); -#endif /* * Switch the MPU rate if specified on cmdline. @@ -1077,8 +1158,27 @@ 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 2781dfbc5164..8816f5a33a28 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 | ALWAYS_ENABLED | RATE_PROPAGATES, + RATE_FIXED | RATE_PROPAGATES, }; /* With out modem likely 12MHz, with modem likely 13MHz */ @@ -1368,7 +1368,8 @@ static struct clk mcbsp5_fck = { }; static struct clk mcspi1_ick = { - .name = "mcspi1_ick", + .name = "mcspi_ick", + .id = 1, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, @@ -1377,7 +1378,8 @@ static struct clk mcspi1_ick = { }; static struct clk mcspi1_fck = { - .name = "mcspi1_fck", + .name = "mcspi_fck", + .id = 1, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, @@ -1386,7 +1388,8 @@ static struct clk mcspi1_fck = { }; static struct clk mcspi2_ick = { - .name = "mcspi2_ick", + .name = "mcspi_ick", + .id = 2, .parent = &l4_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN1_CORE, @@ -1395,7 +1398,8 @@ static struct clk mcspi2_ick = { }; static struct clk mcspi2_fck = { - .name = "mcspi2_fck", + .name = "mcspi_fck", + .id = 2, .parent = &func_48m_ck, .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, @@ -1404,7 +1408,8 @@ static struct clk mcspi2_fck = { }; static struct clk mcspi3_ick = { - .name = "mcspi3_ick", + .name = "mcspi_ick", + .id = 3, .parent = &l4_ck, .flags = CLOCK_IN_OMAP243X, .enable_reg = (void __iomem *)&CM_ICLKEN2_CORE, @@ -1413,7 +1418,8 @@ static struct clk mcspi3_ick = { }; static struct clk mcspi3_fck = { - .name = "mcspi3_fck", + .name = "mcspi_fck", + .id = 3, .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 c7a48f921fef..f4f04d87df32 100644 --- a/trunk/arch/arm/mach-omap2/gpmc.c +++ b/trunk/arch/arm/mach-omap2/gpmc.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include @@ -41,6 +43,19 @@ #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 = @@ -187,9 +202,168 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) return 0; } -unsigned long gpmc_cs_get_base_addr(int cs) +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) { - return (gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7) & 0x1f) << 24; + 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(); + } } void __init gpmc_init(void) @@ -206,4 +380,6 @@ 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 dfc3b35cc1ff..1ed2fff4691a 100644 --- a/trunk/arch/arm/mach-omap2/irq.c +++ b/trunk/arch/arm/mach-omap2/irq.c @@ -41,18 +41,6 @@ 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 60ef084faffd..f538d0fdb13c 100644 --- a/trunk/arch/arm/mach-omap2/mux.c +++ b/trunk/arch/arm/mach-omap2/mux.c @@ -104,6 +104,20 @@ 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 c2bf57ef6825..90f530540c65 100644 --- a/trunk/arch/arm/mach-omap2/prcm.c +++ b/trunk/arch/arm/mach-omap2/prcm.c @@ -19,6 +19,8 @@ #include "prcm-regs.h" +extern void omap2_clk_prepare_for_reboot(void); + u32 omap_prcm_get_reset_sources(void) { return RM_RSTST_WKUP & 0x7f; @@ -28,12 +30,6 @@ 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) { - 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 */ + omap2_clk_prepare_for_reboot(); RM_RSTCTRL_WKUP |= 2; } diff --git a/trunk/arch/arm/mach-pxa/corgi.c b/trunk/arch/arm/mach-pxa/corgi.c index cce26576999e..337c01c4ac37 100644 --- a/trunk/arch/arm/mach-pxa/corgi.c +++ b/trunk/arch/arm/mach-pxa/corgi.c @@ -284,21 +284,9 @@ 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 */ - .udc_command = corgi_udc_command, + .gpio_pullup = CORGI_GPIO_USB_PULLUP, }; @@ -350,7 +338,6 @@ 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 bbd138be6a70..df37594c30f8 100644 --- a/trunk/arch/arm/mach-s3c2410/Kconfig +++ b/trunk/arch/arm/mach-s3c2410/Kconfig @@ -2,6 +2,13 @@ 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 @@ -126,6 +133,12 @@ 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 @@ -133,10 +146,24 @@ 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. @@ -149,6 +176,13 @@ 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 @@ -165,6 +199,7 @@ 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. @@ -173,6 +208,7 @@ 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. @@ -256,7 +292,7 @@ config S3C2410_PM_CHECK_CHUNKSIZE config PM_SIMTEC bool - depends on PM && (ARCH_BAST || MACH_VR1000) + depends on PM && (ARCH_BAST || MACH_VR1000 || MACH_AML_M5900) default y config S3C2410_LOWLEVEL_UART_PORT diff --git a/trunk/arch/arm/mach-s3c2410/Makefile b/trunk/arch/arm/mach-s3c2410/Makefile index 0eadec916214..d66013365b6b 100644 --- a/trunk/arch/arm/mach-s3c2410/Makefile +++ b/trunk/arch/arm/mach-s3c2410/Makefile @@ -9,6 +9,8 @@ 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 @@ -20,6 +22,10 @@ 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 @@ -30,6 +36,9 @@ 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 @@ -47,6 +56,7 @@ 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 @@ -57,8 +67,13 @@ 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 @@ -71,5 +86,6 @@ 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 def4441d2442..440e9aa0211a 100644 --- a/trunk/arch/arm/mach-s3c2410/bast-irq.c +++ b/trunk/arch/arm/mach-s3c2410/bast-irq.c @@ -18,10 +18,6 @@ * 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 1c3c6adae6c4..9d4899eddf1f 100644 --- a/trunk/arch/arm/mach-s3c2410/cpu.c +++ b/trunk/arch/arm/mach-s3c2410/cpu.c @@ -124,6 +124,15 @@ 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 726e2eaf8797..14fb0bade716 100644 --- a/trunk/arch/arm/mach-s3c2410/devs.h +++ b/trunk/arch/arm/mach-s3c2410/devs.h @@ -8,11 +8,6 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. - * - * Modifications: - * 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 cc92a7b2db88..d264bbbd8bef 100644 --- a/trunk/arch/arm/mach-s3c2410/dma.c +++ b/trunk/arch/arm/mach-s3c2410/dma.c @@ -1,35 +1,16 @@ -/* linux/arch/arm/mach-bast/dma.c +/* linux/arch/arm/mach-s3c2410/dma.c * - * (c) 2003-2005 Simtec Electronics + * (c) 2003-2005,2006 Simtec Electronics * Ben Dooks * * S3C2410 DMA core * - * http://www.simtec.co.uk/products/EB2410ITX/ + * 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. - * - * 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 @@ -55,10 +36,14 @@ #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]; @@ -79,7 +64,6 @@ 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)) @@ -151,12 +135,20 @@ dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan) #define dbg_showchan(chan) do { } while(0) #endif /* CONFIG_S3C2410_DMA_DEBUG */ -#define check_channel(chan) \ - do { if ((chan) >= S3C2410_DMA_CHANNELS) { \ - printk(KERN_ERR "%s: invalid channel %d\n", __FUNCTION__, (chan)); \ - return -EINVAL; \ - } } while(0) +static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX]; +/* 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 * @@ -321,8 +313,10 @@ 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); @@ -439,7 +433,6 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan) return 0; } - /* s3c2410_dma_enqueue * * queue an given buffer for dma transfer. @@ -460,11 +453,12 @@ 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 = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); struct s3c2410_dma_buf *buf; unsigned long flags; - check_channel(channel); + if (chan == NULL) + return -EINVAL; pr_debug("%s: id=%p, data=%08x, size=%d\n", __FUNCTION__, id, (unsigned int)data, size); @@ -562,8 +556,10 @@ 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: @@ -718,7 +714,8 @@ 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, S3C2410_DMAOP_STOP); + s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL, + S3C2410_DMAOP_STOP); } } @@ -726,37 +723,34 @@ 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 = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan; unsigned long flags; int err; pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n", channel, client->name, dev); - check_channel(channel); - 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 = s3c2410_dma_map_channel(channel); + if (chan == NULL) { + local_irq_restore(flags); + return -EBUSY; } + dbg_showchan(chan); + chan->client = client; chan->in_use = 1; @@ -809,14 +803,14 @@ EXPORT_SYMBOL(s3c2410_dma_request); int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); unsigned long flags; - check_channel(channel); + if (chan == NULL) + return -EINVAL; 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); @@ -837,8 +831,12 @@ 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; @@ -848,8 +846,8 @@ EXPORT_SYMBOL(s3c2410_dma_free); static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) { - unsigned long tmp; unsigned long flags; + unsigned long tmp; pr_debug("%s:\n", __FUNCTION__); @@ -997,9 +995,10 @@ 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 = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - check_channel(channel); + if (chan == NULL) + return -EINVAL; switch (op) { case S3C2410_DMAOP_START: @@ -1046,12 +1045,19 @@ int s3c2410_dma_config(dmach_t channel, int xferunit, int dcon) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n", __FUNCTION__, channel, xferunit, dcon); - check_channel(channel); + 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); switch (xferunit) { case 1: @@ -1086,9 +1092,10 @@ EXPORT_SYMBOL(s3c2410_dma_config); int s3c2410_dma_setflags(dmach_t channel, unsigned int flags) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - check_channel(channel); + if (chan == NULL) + return -EINVAL; pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags); @@ -1106,9 +1113,10 @@ EXPORT_SYMBOL(s3c2410_dma_setflags); int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - check_channel(channel); + if (chan == NULL) + return -EINVAL; pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn); @@ -1121,9 +1129,10 @@ 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 = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - check_channel(channel); + if (chan == NULL) + return -EINVAL; pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn); @@ -1153,9 +1162,10 @@ int s3c2410_dma_devconfig(int channel, int hwcfg, unsigned long devaddr) { - struct s3c2410_dma_chan *chan = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - check_channel(channel); + if (chan == NULL) + return -EINVAL; pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n", __FUNCTION__, (int)source, hwcfg, devaddr); @@ -1200,9 +1210,10 @@ 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 = &s3c2410_chans[channel]; + struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); - check_channel(channel); + if (chan == NULL) + return -EINVAL; if (src != NULL) *src = dma_rdreg(chan, S3C2410_DMA_DCSRC); @@ -1252,7 +1263,7 @@ static int s3c2410_dma_resume(struct sys_device *dev) #define s3c2410_dma_resume NULL #endif /* CONFIG_PM */ -static struct sysdev_class dma_sysclass = { +struct sysdev_class dma_sysclass = { set_kset_name("s3c24xx-dma"), .suspend = s3c2410_dma_suspend, .resume = s3c2410_dma_resume, @@ -1265,7 +1276,6 @@ 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) @@ -1274,7 +1284,7 @@ static int __init s3c2410_init_dma(void) int channel; int ret; - printk("S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics\n"); + printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n"); dma_base = ioremap(S3C24XX_PA_DMA, 0x200); if (dma_base == NULL) { @@ -1282,6 +1292,8 @@ 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"); @@ -1335,4 +1347,95 @@ static int __init s3c2410_init_dma(void) return ret; } -__initcall(s3c2410_init_dma); +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; +} diff --git a/trunk/arch/arm/mach-s3c2410/dma.h b/trunk/arch/arm/mach-s3c2410/dma.h new file mode 100644 index 000000000000..0ebfe0aab80b --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/dma.h @@ -0,0 +1,45 @@ +/* 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 cd39e8684584..db6393c99860 100644 --- a/trunk/arch/arm/mach-s3c2410/gpio.c +++ b/trunk/arch/arm/mach-s3c2410/gpio.c @@ -18,21 +18,7 @@ * 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 cd6139b35999..3e9f3462c61b 100644 --- a/trunk/arch/arm/mach-s3c2410/irq.c +++ b/trunk/arch/arm/mach-s3c2410/irq.c @@ -181,17 +181,19 @@ s3c_irq_unmask(unsigned int irqno) } struct irqchip s3c_irq_level_chip = { - .ack = s3c_irq_maskack, - .mask = s3c_irq_mask, - .unmask = s3c_irq_unmask, - .set_wake = s3c_irq_wake + .name = "s3c-level", + .ack = s3c_irq_maskack, + .mask = s3c_irq_mask, + .unmask = s3c_irq_unmask, + .set_wake = s3c_irq_wake }; static struct irqchip s3c_irq_chip = { - .ack = s3c_irq_ack, - .mask = s3c_irq_mask, - .unmask = s3c_irq_unmask, - .set_wake = s3c_irq_wake + .name = "s3c", + .ack = s3c_irq_ack, + .mask = s3c_irq_mask, + .unmask = s3c_irq_unmask, + .set_wake = s3c_irq_wake }; static void @@ -343,19 +345,21 @@ s3c_irqext_type(unsigned int irq, unsigned int type) } static struct irqchip s3c_irqext_chip = { - .mask = s3c_irqext_mask, - .unmask = s3c_irqext_unmask, - .ack = s3c_irqext_ack, - .set_type = s3c_irqext_type, - .set_wake = s3c_irqext_wake + .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 }; static struct irqchip s3c_irq_eint0t4 = { - .ack = s3c_irq_ack, - .mask = s3c_irq_mask, - .unmask = s3c_irq_unmask, - .set_wake = s3c_irq_wake, - .set_type = s3c_irqext_type, + .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, }; /* mask values for the parent registers for each of the interrupt types */ @@ -387,9 +391,10 @@ s3c_irq_uart0_ack(unsigned int irqno) } static struct irqchip s3c_irq_uart0 = { - .mask = s3c_irq_uart0_mask, - .unmask = s3c_irq_uart0_unmask, - .ack = s3c_irq_uart0_ack, + .name = "s3c-uart0", + .mask = s3c_irq_uart0_mask, + .unmask = s3c_irq_uart0_unmask, + .ack = s3c_irq_uart0_ack, }; /* UART1 */ @@ -413,9 +418,10 @@ s3c_irq_uart1_ack(unsigned int irqno) } static struct irqchip s3c_irq_uart1 = { - .mask = s3c_irq_uart1_mask, - .unmask = s3c_irq_uart1_unmask, - .ack = s3c_irq_uart1_ack, + .name = "s3c-uart1", + .mask = s3c_irq_uart1_mask, + .unmask = s3c_irq_uart1_unmask, + .ack = s3c_irq_uart1_ack, }; /* UART2 */ @@ -439,9 +445,10 @@ s3c_irq_uart2_ack(unsigned int irqno) } static struct irqchip s3c_irq_uart2 = { - .mask = s3c_irq_uart2_mask, - .unmask = s3c_irq_uart2_unmask, - .ack = s3c_irq_uart2_ack, + .name = "s3c-uart2", + .mask = s3c_irq_uart2_mask, + .unmask = s3c_irq_uart2_unmask, + .ack = s3c_irq_uart2_ack, }; /* ADC and Touchscreen */ @@ -465,9 +472,10 @@ s3c_irq_adc_ack(unsigned int irqno) } static struct irqchip s3c_irq_adc = { - .mask = s3c_irq_adc_mask, - .unmask = s3c_irq_adc_unmask, - .ack = s3c_irq_adc_ack, + .name = "s3c-adc", + .mask = s3c_irq_adc_mask, + .unmask = s3c_irq_adc_unmask, + .ack = s3c_irq_adc_ack, }; /* irq demux for adc */ @@ -569,23 +577,104 @@ s3c_irq_demux_uart2(unsigned int irq, } static void -s3c_irq_demux_extint(unsigned int irq, - struct irqdesc *desc, - struct pt_regs *regs) +s3c_irq_demux_extint8(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 */ - if (eintpnd) { - irq = fls(eintpnd); - irq += (IRQ_EINT4 - (4 + 1)); + /* we may as well handle all the pending IRQs here */ + 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 60641d452db3..e94cdcd96591 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-anubis.c +++ b/trunk/arch/arm/mach-s3c2410/mach-anubis.c @@ -4,15 +4,9 @@ * 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 d661c6b7ff56..e2205ff1b0ee 100644 --- a/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/trunk/arch/arm/mach-s3c2410/mach-smdk2440.c @@ -11,15 +11,6 @@ * 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 new file mode 100644 index 000000000000..ea554e7c006e --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/mach-vstms.c @@ -0,0 +1,168 @@ +/* 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 7b244566a436..42cd05e298f8 100644 --- a/trunk/arch/arm/mach-s3c2410/pm-simtec.c +++ b/trunk/arch/arm/mach-s3c2410/pm-simtec.c @@ -49,7 +49,8 @@ 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_anubis() && !machine_is_osiris() && + !machine_is_aml_m5900()) 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 a589fe76d915..b49a0b3b72b3 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 Simtec Electronics + * Copyright (c) 2004,2006 Simtec Electronics * Ben Dooks * - * S3C2410 Power Manager (Suspend-To-RAM) support + * S3C24XX Power Manager (Suspend-To-RAM) support * * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information * @@ -24,9 +24,6 @@ * 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 @@ -38,6 +35,7 @@ #include #include +#include #include #include @@ -55,14 +53,6 @@ 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[] = { @@ -92,19 +82,6 @@ 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), @@ -165,7 +142,7 @@ static struct sleep_save uart_save[] = { extern void printascii(const char *); -static void pm_dbg(const char *fmt, ...) +void pm_dbg(const char *fmt, ...) { va_list va; char buff[256]; @@ -509,6 +486,9 @@ 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 @@ -519,7 +499,6 @@ static void s3c2410_pm_configure_extint(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) */ @@ -527,6 +506,11 @@ 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; @@ -554,17 +538,9 @@ 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)); @@ -581,10 +557,16 @@ 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 */ - arm920_flush_kern_cache_all(); + flush_cache_all(); s3c2410_pm_check_store(); @@ -592,23 +574,23 @@ static int s3c2410_pm_enter(suspend_state_t state) __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */ - s3c2410_cpu_suspend(regs_save); + /* 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(); + } /* 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 7a5e714c7386..ffe197a119fb 100644 --- a/trunk/arch/arm/mach-s3c2410/pm.h +++ b/trunk/arch/arm/mach-s3c2410/pm.h @@ -34,13 +34,19 @@ 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 void s3c2410_cpu_suspend(unsigned long *saveblk); +extern int s3c2410_cpu_save(unsigned long *saveblk); +extern void s3c2410_cpu_suspend(void); extern void s3c2410_cpu_resume(void); extern unsigned long s3c2410_sleep_save_phys; @@ -57,3 +63,11 @@ 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 new file mode 100644 index 000000000000..51e5098b32e8 --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/s3c2410-dma.c @@ -0,0 +1,158 @@ +/* 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 new file mode 100644 index 000000000000..c796c9c76e78 --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/s3c2410-irq.c @@ -0,0 +1,48 @@ +/* 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 new file mode 100644 index 000000000000..e51d76669512 --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/s3c2410-pm.c @@ -0,0 +1,120 @@ +/* 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 new file mode 100644 index 000000000000..9179a1024588 --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/s3c2410-sleep.S @@ -0,0 +1,68 @@ +/* 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 a110cff9cf6b..183e4033ce61 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2410.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2410.c @@ -8,17 +8,6 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. - * - * Modifications: - * 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 new file mode 100644 index 000000000000..171f3706d36d --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/s3c2412-dma.c @@ -0,0 +1,160 @@ +/* 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 c80ec93dfea9..7f741547658f 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2412-irq.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2412-irq.c @@ -37,6 +37,7 @@ #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 @@ -120,6 +121,8 @@ 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 new file mode 100644 index 000000000000..19b63322d259 --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/s3c2412-pm.c @@ -0,0 +1,128 @@ +/* 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 2d163f7600be..e76431c41461 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2412.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2412.c @@ -8,17 +8,6 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. - * - * Modifications: - * 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 @@ -56,6 +45,13 @@ #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 */ @@ -76,6 +72,7 @@ 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"; } @@ -110,7 +107,7 @@ void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size) { /* move base of IO */ - s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10; + s3c2412_init_gpio2(); /* set our idle function */ @@ -161,48 +158,8 @@ 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 new file mode 100644 index 000000000000..11e109c84a15 --- /dev/null +++ b/trunk/arch/arm/mach-s3c2410/s3c2440-dma.c @@ -0,0 +1,164 @@ +/* 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 16fa2a3b38fa..c92ea66ba45e 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c2440-dsc.c +++ b/trunk/arch/arm/mach-s3c2410/s3c2440-dsc.c @@ -8,11 +8,6 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. - * - * Modifications: - * 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 1667ba1fa43d..fc08febe2e54 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 44c5affa9b89..0d13546c3500 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c244x-irq.c +++ b/trunk/arch/arm/mach-s3c2410/s3c244x-irq.c @@ -120,7 +120,9 @@ static int s3c244x_irq_add(struct sys_device *sysdev) } static struct sysdev_driver s3c2440_irq_driver = { - .add = s3c244x_irq_add, + .add = s3c244x_irq_add, + .suspend = s3c24xx_irq_suspend, + .resume = s3c24xx_irq_resume, }; static int s3c2440_irq_init(void) @@ -131,9 +133,12 @@ static int s3c2440_irq_init(void) arch_initcall(s3c2440_irq_init); static struct sysdev_driver s3c2442_irq_driver = { - .add = s3c244x_irq_add, + .add = s3c244x_irq_add, + .suspend = s3c24xx_irq_suspend, + .resume = s3c24xx_irq_resume, }; + 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 a7561a79fc82..2018c2e1dcc5 100644 --- a/trunk/arch/arm/mach-s3c2410/sleep.S +++ b/trunk/arch/arm/mach-s3c2410/sleep.S @@ -41,15 +41,25 @@ .text - /* s3c2410_cpu_suspend + /* s3c2410_cpu_save * - * put the cpu into sleep mode + * 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. * * entry: - * r0 = sleep save block + * r0 = pointer to save block + * + * exit: + * r0 = 0 => we stored everything + * 1 => resumed from sleep */ -ENTRY(s3c2410_cpu_suspend) +ENTRY(s3c2410_cpu_save) stmfd sp!, { r4 - r12, lr } @@ store co-processor registers @@ -62,44 +72,14 @@ ENTRY(s3c2410_cpu_suspend) stmia r0, { r4 - r13 } - @@ 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 + mov r0, #0 + ldmfd sp, { r4 - r12, pc } @@ 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 6b22d8f0a00d..c635efa7cd31 100644 --- a/trunk/arch/arm/mach-s3c2410/usb-simtec.c +++ b/trunk/arch/arm/mach-s3c2410/usb-simtec.c @@ -10,12 +10,6 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. - * - * Modifications: - * 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 a0dfa390e34b..6496eb645cee 100644 --- a/trunk/arch/arm/mach-sa1100/collie.c +++ b/trunk/arch/arm/mach-sa1100/collie.c @@ -91,30 +91,29 @@ static struct mcp_plat_data collie_mcp_data = { /* * low-level UART features. */ -static struct locomo_dev *uart_dev = NULL; +struct platform_device collie_locomo_device; static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl) { - if (!uart_dev) return; - if (mctrl & TIOCM_RTS) - locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 0); + locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0); else - locomo_gpio_write(uart_dev, LOCOMO_GPIO_RTS, 1); + locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1); if (mctrl & TIOCM_DTR) - locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 0); + locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0); else - locomo_gpio_write(uart_dev, LOCOMO_GPIO_DTR, 1); + locomo_gpio_write(&collie_locomo_device.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(uart_dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR); + r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR); + if (r == -ENODEV) + return ret; if (r & LOCOMO_GPIO_CTS) ret |= TIOCM_CTS; if (r & LOCOMO_GPIO_DSR) @@ -130,13 +129,11 @@ 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; } @@ -170,7 +167,7 @@ static struct resource locomo_resources[] = { }, }; -static struct platform_device locomo_device = { +struct platform_device collie_locomo_device = { .name = "locomo", .id = 0, .num_resources = ARRAY_SIZE(locomo_resources), @@ -178,7 +175,7 @@ static struct platform_device locomo_device = { }; static struct platform_device *devices[] __initdata = { - &locomo_device, + &collie_locomo_device, &colliescoop_device, }; diff --git a/trunk/arch/arm/mach-versatile/pci.c b/trunk/arch/arm/mach-versatile/pci.c index 41b370090b60..13bbd08ff841 100644 --- a/trunk/arch/arm/mach-versatile/pci.c +++ b/trunk/arch/arm/mach-versatile/pci.c @@ -117,7 +117,6 @@ 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 b4f220dd5eb8..c0bfb8212b77 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -15,6 +15,7 @@ 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 @@ -24,6 +25,20 @@ 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 @@ -31,6 +46,7 @@ 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 @@ -50,6 +66,7 @@ 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 @@ -59,6 +76,36 @@ 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" @@ -68,6 +115,7 @@ 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 @@ -89,6 +137,7 @@ 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 @@ -108,6 +157,7 @@ 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 @@ -126,6 +176,7 @@ 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 @@ -136,6 +187,39 @@ 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" @@ -144,6 +228,7 @@ 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 @@ -161,6 +246,7 @@ 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 @@ -172,6 +258,7 @@ 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 @@ -189,6 +276,7 @@ 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 @@ -207,6 +295,7 @@ 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 @@ -227,16 +316,18 @@ 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_IOP3XX || ARCH_PXA || ARCH_IXP4XX || ARCH_IXP2000 + depends on ARCH_IOP32X || ARCH_IOP33X || 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 @@ -247,6 +338,7 @@ 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 @@ -258,6 +350,7 @@ 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 @@ -299,6 +392,9 @@ config CPU_32v6 bool # The abort model +config CPU_ABRT_NOMMU + bool + config CPU_ABRT_EV4 bool @@ -380,6 +476,23 @@ 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 # @@ -390,7 +503,7 @@ comment "Processor Features" config ARM_THUMB bool "Support Thumb user binaries" - 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 + 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 default y help Say Y if you want to include kernel support for running user space @@ -411,23 +524,48 @@ 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" - depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6 + bool "Disable I-Cache (I-bit)" + depends on CPU_CP15 && !(CPU_ARM610 || CPU_ARM710 || CPU_ARM720T || CPU_ARM740T || CPU_XSCALE || CPU_XSC3) 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" - depends on CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6 + bool "Disable D-Cache (C-bit)" + depends on CPU_CP15 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_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM1020 || CPU_V6) && !CPU_DCACHE_DISABLE + depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || 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 @@ -435,7 +573,7 @@ config CPU_DCACHE_WRITETHROUGH config CPU_CACHE_ROUND_ROBIN bool "Round robin I and D cache replacement algorithm" - depends on (CPU_ARM926T || CPU_ARM1020) && (!CPU_ICACHE_DISABLE || !CPU_DCACHE_DISABLE) + depends on (CPU_ARM926T || CPU_ARM946E || 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 21a2770226ee..d2f5672ecf62 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 \ - mm-armv.o + pgd.o mmu.o ifneq ($(CONFIG_MMU),y) obj-y += nommu.o @@ -17,6 +17,7 @@ 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 @@ -33,7 +34,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 mmu.o +obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o context.o obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o @@ -46,11 +47,16 @@ 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 db743e510214..9fb7b0e25ea1 100644 --- a/trunk/arch/arm/mm/abort-lv4t.S +++ b/trunk/arch/arm/mm/abort-lv4t.S @@ -19,11 +19,16 @@ */ 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 new file mode 100644 index 000000000000..a7cc7f9ee45d --- /dev/null +++ b/trunk/arch/arm/mm/abort-nommu.S @@ -0,0 +1,19 @@ +#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 e0d21bbbe7d7..aa109f074dd9 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(current, current->mm, addr, fsr, regs); + do_bad_area(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 b8ad5d58ebe2..b2908063ed6a 100644 --- a/trunk/arch/arm/mm/cache-v4.S +++ b/trunk/arch/arm/mm/cache-v4.S @@ -29,9 +29,13 @@ 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) @@ -44,9 +48,13 @@ 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) @@ -108,8 +116,10 @@ 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 new file mode 100644 index 000000000000..79e800202424 --- /dev/null +++ b/trunk/arch/arm/mm/context.c @@ -0,0 +1,45 @@ +/* + * 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 fc69dccdace1..df1645e14b4c 100644 --- a/trunk/arch/arm/mm/copypage-v4mc.c +++ b/trunk/arch/arm/mm/copypage-v4mc.c @@ -20,6 +20,8 @@ #include #include +#include "mm.h" + /* * 0xffff8000 to 0xffffffff is reserved for any ARM architecture * specific hacks for copying pages efficiently. @@ -27,8 +29,6 @@ #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 269ce6913ee9..3d0d3a963d20 100644 --- a/trunk/arch/arm/mm/copypage-v6.c +++ b/trunk/arch/arm/mm/copypage-v6.c @@ -17,6 +17,8 @@ #include #include +#include "mm.h" + #if SHMLBA > 16384 #error FIX ME #endif @@ -24,8 +26,6 @@ #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 42a6ee255ce0..84ebe0aa379e 100644 --- a/trunk/arch/arm/mm/copypage-xscale.c +++ b/trunk/arch/arm/mm/copypage-xscale.c @@ -20,6 +20,8 @@ #include #include +#include "mm.h" + /* * 0xffff8000 to 0xffffffff is reserved for any ARM architecture * specific hacks for copying pages efficiently. @@ -29,8 +31,6 @@ #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 c5e0622c7765..5e658a874498 100644 --- a/trunk/arch/arm/mm/fault.c +++ b/trunk/arch/arm/mm/fault.c @@ -131,10 +131,11 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr, force_sig_info(sig, &si, tsk); } -void -do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr, - unsigned int fsr, struct pt_regs *regs) +void do_bad_area(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. @@ -170,7 +171,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; + mask = VM_READ|VM_EXEC|VM_WRITE; fault = VM_FAULT_BADACCESS; if (!(vma->vm_flags & mask)) @@ -197,7 +198,7 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, return fault; } - if (tsk->pid != 1) + if (!is_init(tsk)) goto out; /* @@ -319,7 +320,6 @@ 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,9 +351,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr, return 0; bad_area: - tsk = current; - - do_bad_area(tsk, tsk->active_mm, addr, fsr, regs); + do_bad_area(addr, fsr, regs); return 0; } @@ -364,8 +362,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr, static int do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { - struct task_struct *tsk = current; - do_bad_area(tsk, tsk->active_mm, addr, fsr, regs); + do_bad_area(addr, fsr, regs); return 0; } diff --git a/trunk/arch/arm/mm/fault.h b/trunk/arch/arm/mm/fault.h index 73b59e83227f..49e9e3804de4 100644 --- a/trunk/arch/arm/mm/fault.h +++ b/trunk/arch/arm/mm/fault.h @@ -1,6 +1,3 @@ -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); +void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs); 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 d438ce41cdd5..454205b789d5 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 fe3f7f625008..22217fe2650b 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -25,10 +25,9 @@ #include #include -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); +#include "mm.h" -extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; -extern void _stext, _text, _etext, __data_start, _end, __init_begin, __init_end; +extern void _text, _etext, __data_start, _end, __init_begin, __init_end; extern unsigned long phys_initrd_start; extern unsigned long phys_initrd_size; @@ -38,12 +37,6 @@ 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; @@ -83,16 +76,6 @@ 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) @@ -176,62 +159,20 @@ static int __init check_initrd(struct meminfo *mi) return initrd_node; } -/* - * Reserve the various regions of node 0 - */ -static __init void reserve_node_zero(pg_data_t *pgdat) +static inline void map_memory_bank(struct membank *bank) { - 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; +#ifdef CONFIG_MMU + struct map_desc map; - /* - * 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; + map.pfn = __phys_to_pfn(bank->start); + map.virtual = __phys_to_virt(bank->start); + map.length = bank->size; + map.type = MT_MEMORY; -#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; + create_mapping(&map); #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) { @@ -248,23 +189,18 @@ 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 = mi->bank[i].start >> PAGE_SHIFT; - end = (mi->bank[i].start + mi->bank[i].size) >> PAGE_SHIFT; + start = bank->start >> PAGE_SHIFT; + end = (bank->start + bank->size) >> PAGE_SHIFT; if (start_pfn > start) start_pfn = start; if (end_pfn < end) end_pfn = end; - 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); + map_memory_bank(bank); } /* @@ -346,9 +282,9 @@ bootmem_init_node(int node, int initrd_node, struct meminfo *mi) return end_pfn; } -static void __init bootmem_init(struct meminfo *mi) +void __init bootmem_init(struct meminfo *mi) { - unsigned long addr, memend_pfn = 0; + unsigned long memend_pfn = 0; int node, initrd_node, i; /* @@ -360,26 +296,6 @@ static 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. */ @@ -413,114 +329,6 @@ static 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 deleted file mode 100644 index 38769f5862bc..000000000000 --- a/trunk/arch/arm/mm/mm-armv.c +++ /dev/null @@ -1,663 +0,0 @@ -/* - * 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 new file mode 100644 index 000000000000..bb2bc9ab6bd3 --- /dev/null +++ b/trunk/arch/arm/mm/mm.h @@ -0,0 +1,22 @@ +/* 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 29e54807c5bc..b0b5f4694070 100644 --- a/trunk/arch/arm/mm/mmap.c +++ b/trunk/arch/arm/mm/mmap.c @@ -114,3 +114,25 @@ 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 0d90227a0a32..e566cbe4b222 100644 --- a/trunk/arch/arm/mm/mmu.c +++ b/trunk/arch/arm/mm/mmu.c @@ -1,45 +1,771 @@ /* * linux/arch/arm/mm/mmu.c * - * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved. + * Copyright (C) 1995-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 +#include +#include +#include -#include -#include +#include +#include +#include +#include -unsigned int cpu_last_asid = { 1 << ASID_BITS }; +#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; /* - * 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. + * The pmd table for the upper-most set of pages. */ -void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) +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) { - mm->context.id = 0; + cr_alignment &= ~CR_A; + cr_no_alignment &= ~CR_A; + set_cr(cr_alignment); + return 1; } +__setup("noalign", noalign_setup); + +struct mem_types { + unsigned int prot_pte; + unsigned int prot_l1; + unsigned int prot_sect; + unsigned int domain; +}; -void __new_context(struct mm_struct *mm) +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) { - unsigned int asid; + struct cachepolicy *cp; + unsigned int cr = get_cr(); + unsigned int user_pgprot, kern_pgprot; + int cpu_arch = cpu_architecture(); + int i; - asid = ++cpu_last_asid; - if (asid == 0) - asid = cpu_last_asid = 1 << ASID_BITS; +#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; /* - * If we've used up all our ASIDs, we need - * to start a new version and flush the TLB. + * ARMv5 and lower, excluding Xscale, bit 4 must be set for + * page tables. */ - if ((asid & ~ASID_MASK) == 0) - flush_tlb_all(); + 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; - mm->context.id = asid; + pmd = pmd_off(pgd, i << PGDIR_SHIFT); + pmd[0] = __pmd(pmdval); + pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); + flush_pmd_entry(pmd); + } } diff --git a/trunk/arch/arm/mm/nommu.c b/trunk/arch/arm/mm/nommu.c index 1464ed817b5d..d0e66424a597 100644 --- a/trunk/arch/arm/mm/nommu.c +++ b/trunk/arch/arm/mm/nommu.c @@ -11,6 +11,49 @@ #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 new file mode 100644 index 000000000000..20c1b0df75f2 --- /dev/null +++ b/trunk/arch/arm/mm/pgd.c @@ -0,0 +1,101 @@ +/* + * 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 new file mode 100644 index 000000000000..40713818a87b --- /dev/null +++ b/trunk/arch/arm/mm/proc-arm740.S @@ -0,0 +1,174 @@ +/* + * 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 new file mode 100644 index 000000000000..22d7e3100ea6 --- /dev/null +++ b/trunk/arch/arm/mm/proc-arm7tdmi.S @@ -0,0 +1,249 @@ +/* + * 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 new file mode 100644 index 000000000000..2397f4b6e151 --- /dev/null +++ b/trunk/arch/arm/mm/proc-arm940.S @@ -0,0 +1,369 @@ +/* + * 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 new file mode 100644 index 000000000000..e18617564421 --- /dev/null +++ b/trunk/arch/arm/mm/proc-arm946.S @@ -0,0 +1,424 @@ +/* + * 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 new file mode 100644 index 000000000000..918ebf65d4f6 --- /dev/null +++ b/trunk/arch/arm/mm/proc-arm9tdmi.S @@ -0,0 +1,134 @@ +/* + * 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 3ca0c92e98a2..e8b377d637f6 100644 --- a/trunk/arch/arm/mm/proc-xscale.S +++ b/trunk/arch/arm/mm/proc-xscale.S @@ -311,12 +311,6 @@ 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 @@ -375,6 +369,30 @@ 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 @@ -531,6 +549,11 @@ 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" @@ -595,6 +618,29 @@ 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 34fdc733743b..6576143f2559 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_IOP321 -#define XSCALE_PMU_IRQ IRQ_IOP321_CORE_PMU +#ifdef CONFIG_ARCH_IOP32X +#define XSCALE_PMU_IRQ IRQ_IOP32X_CORE_PMU #endif -#ifdef CONFIG_ARCH_IOP331 -#define XSCALE_PMU_IRQ IRQ_IOP331_CORE_PMU +#ifdef CONFIG_ARCH_IOP33X +#define XSCALE_PMU_IRQ IRQ_IOP33X_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. IOP321 is xsc1 whilst IOP331 is xsc2. + * e.g. IOP32x is xsc1 whilst IOP33x 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 new file mode 100644 index 000000000000..23da00b11517 --- /dev/null +++ b/trunk/arch/arm/plat-iop/Makefile @@ -0,0 +1,8 @@ +# +# 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 new file mode 100644 index 000000000000..eda436083417 --- /dev/null +++ b/trunk/arch/arm/plat-iop/gpio.c @@ -0,0 +1,48 @@ +/* + * 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 new file mode 100644 index 000000000000..e99909bdba71 --- /dev/null +++ b/trunk/arch/arm/plat-iop/i2c.c @@ -0,0 +1,81 @@ +/* + * 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 new file mode 100644 index 000000000000..e647812654f2 --- /dev/null +++ b/trunk/arch/arm/plat-iop/pci.c @@ -0,0 +1,247 @@ +/* + * 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 new file mode 100644 index 000000000000..4689db638e95 --- /dev/null +++ b/trunk/arch/arm/plat-iop/setup.c @@ -0,0 +1,38 @@ +/* + * 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 new file mode 100644 index 000000000000..06282dffbdc6 --- /dev/null +++ b/trunk/arch/arm/plat-iop/time.c @@ -0,0 +1,98 @@ +/* + * 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 7f45c7c3e673..f1179ad4be1b 100644 --- a/trunk/arch/arm/plat-omap/clock.c +++ b/trunk/arch/arm/plat-omap/clock.c @@ -100,6 +100,7 @@ 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); @@ -322,6 +323,31 @@ 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 1812f237d12f..dbc3f44e07a6 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 83 +#define OMAP_MMC1_INT INT_24XX_MMC_IRQ #else #define OMAP_MMC1_BASE 0xfffb7800 #define OMAP_MMC1_INT INT_MMC @@ -225,7 +225,14 @@ 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()) { + 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 { omap_cfg_reg(MMC_CMD); omap_cfg_reg(MMC_CLK); omap_cfg_reg(MMC_DAT0); @@ -236,7 +243,14 @@ static void __init omap_init_mmc(void) } } if (mmc->wire4) { - if (!cpu_is_omap24xx()) { + 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 { 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 9eddc9507147..1bbb431843ce 100644 --- a/trunk/arch/arm/plat-omap/dma.c +++ b/trunk/arch/arm/plat-omap/dma.c @@ -119,32 +119,41 @@ static void clear_lch_regs(int lch) omap_writew(0, lch_base + i); } -void omap_set_dma_priority(int dst_port, int priority) +void omap_set_dma_priority(int lch, int dst_port, int priority) { unsigned long reg; u32 l; - 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; + 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); } - 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, @@ -234,6 +243,14 @@ 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, @@ -697,6 +714,32 @@ 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 @@ -1339,6 +1382,14 @@ 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", @@ -1414,11 +1465,13 @@ 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 50524436de63..bcbb8d7392be 100644 --- a/trunk/arch/arm/plat-omap/dmtimer.c +++ b/trunk/arch/arm/plat-omap/dmtimer.c @@ -75,10 +75,14 @@ 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 }, @@ -92,6 +96,9 @@ 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 }, @@ -154,24 +161,28 @@ static void omap_dm_timer_reset(struct omap_dm_timer *timer) { u32 l; - if (timer != &dm_timers[0]) { + if (!cpu_class_is_omap2() || 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_SYS_CLK); + omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ); /* 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) { -#ifdef CONFIG_ARCH_OMAP2 - clk_enable(timer->iclk); - clk_enable(timer->fclk); -#endif + omap_dm_timer_enable(timer); omap_dm_timer_reset(timer); } @@ -223,15 +234,36 @@ 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); -#ifdef CONFIG_ARCH_OMAP2 - clk_disable(timer->iclk); - clk_disable(timer->fclk); -#endif + omap_dm_timer_disable(timer); + 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; @@ -276,7 +308,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) @@ -406,11 +438,16 @@ 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) { - return omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); + unsigned int l; + + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG); + + return l; } void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value) @@ -420,12 +457,16 @@ 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) { - return omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); + unsigned int l; + + l = omap_dm_timer_read_reg(timer, OMAP_TIMER_COUNTER_REG); + + return l; } void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value) { - return omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); + omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value); } int omap_dm_timers_active(void) @@ -436,9 +477,14 @@ 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 cd7f973fb286..f55f99ae58ae 100644 --- a/trunk/arch/arm/plat-omap/gpio.c +++ b/trunk/arch/arm/plat-omap/gpio.c @@ -94,6 +94,8 @@ #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 @@ -110,8 +112,6 @@ #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,11 +216,13 @@ 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_MPUIO_MASK) > 16) + if (gpio >= OMAP_MAX_GPIO_LINES + 16) return -1; return 0; } +#endif #ifdef CONFIG_ARCH_OMAP15XX if (cpu_is_omap15xx() && gpio < 16) return 0; @@ -529,6 +531,10 @@ 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) @@ -662,6 +668,14 @@ 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) { @@ -672,9 +686,7 @@ 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; } @@ -696,7 +708,9 @@ int omap_request_gpio(int gpio) } bank->reserved_map |= (1 << get_gpio_index(gpio)); - /* Set trigger to none. You need to enable the trigger after request_irq */ + /* Set trigger to none. You need to enable the desired trigger with + * request_irq() or set_irq_type(). + */ _set_gpio_triggering(bank, get_gpio_index(gpio), IRQT_NOEDGE); #ifdef CONFIG_ARCH_OMAP15XX @@ -756,9 +770,7 @@ void omap_free_gpio(int gpio) } #endif bank->reserved_map &= ~(1 << get_gpio_index(gpio)); - _set_gpio_direction(bank, get_gpio_index(gpio), 1); - _set_gpio_irqenable(bank, gpio, 0); - _clear_gpio_irqstatus(bank, gpio); + _reset_gpio(bank, gpio); spin_unlock(&bank->lock); } @@ -898,6 +910,14 @@ 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; @@ -946,6 +966,7 @@ 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, @@ -985,7 +1006,7 @@ static int __init _omap_gpio_init(void) else clk_enable(gpio_ick); gpio_fck = clk_get(NULL, "gpios_fck"); - if (IS_ERR(gpio_ick)) + if (IS_ERR(gpio_fck)) printk("Could not get gpios_fck\n"); else clk_enable(gpio_fck); @@ -1144,8 +1165,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 + OMAP1610_GPIO_CLEAR_WAKEUPENA; - wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA; + wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA; + wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA; break; default: continue; diff --git a/trunk/arch/arm/plat-omap/mcbsp.c b/trunk/arch/arm/plat-omap/mcbsp.c index 196aac3ac329..ade9a0fa6ef6 100644 --- a/trunk/arch/arm/plat-omap/mcbsp.c +++ b/trunk/arch/arm/plat-omap/mcbsp.c @@ -75,8 +75,6 @@ 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) @@ -232,7 +230,6 @@ 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 @@ -984,13 +981,7 @@ 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 deleted file mode 100644 index 04b4102727a8..000000000000 --- a/trunk/arch/arm/plat-omap/pm.c +++ /dev/null @@ -1,670 +0,0 @@ -/* - * 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 e75718301b0f..19014b2ff4c6 100644 --- a/trunk/arch/arm/plat-omap/sram.c +++ b/trunk/arch/arm/plat-omap/sram.c @@ -174,10 +174,7 @@ void __init omap_map_sram(void) if (cpu_is_omap24xx()) { omap_sram_io_desc[0].virtual = OMAP2_SRAM_VA; - if (is_sram_locked()) - base = OMAP2_SRAM_PUB_PA; - else - base = OMAP2_SRAM_PA; + 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 281ecc7fcdfc..cf6df3378d37 100644 --- a/trunk/arch/arm/plat-omap/timer32k.c +++ b/trunk/arch/arm/plat-omap/timer32k.c @@ -105,6 +105,8 @@ 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); } @@ -192,14 +194,11 @@ unsigned long long sched_clock(void) * issues with dynamic tick. In the dynamic tick case, we need to lock * with irqsave. */ -static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +static inline 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(); @@ -215,6 +214,23 @@ static 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; @@ -230,7 +246,15 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, */ void omap_32k_timer_reprogram(unsigned long next_tick) { - omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); + 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); } static struct irqaction omap_32k_timer_irq; @@ -252,7 +276,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_interrupt, + .handler = omap_32k_timer_handler, }; #endif /* CONFIG_NO_IDLE_HZ */ diff --git a/trunk/arch/arm/plat-omap/usb.c b/trunk/arch/arm/plat-omap/usb.c index 9b815327b6a5..7e8096809be2 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 e1372a25311d..b02af1d740fa 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: Mon Jun 26 22:26:08 2006 +# Last update: Sat Sep 23 13:20:43 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 -comcerto ARCH_M825XX M825XX 315 +m825xx 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_MX27 MX27 846 +mx27ads MACH_MX27ADS MX27ADS 846 ax8004 MACH_AX8004 AX8004 847 at91sam9261ek MACH_AT91SAM9261EK AT91SAM9261EK 848 loft MACH_LOFT LOFT 849 magpie MACH_MAGPIE MAGPIE 850 -mx21ads MACH_MX21 MX21 851 +mx21ads MACH_MX21ADS MX21ADS 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 -mod_270 MACH_MOD_270 MOD_270 1048 +mod272 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,3 +1093,67 @@ 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 96fdf30f6a3b..f2797896e6d5 100644 --- a/trunk/arch/arm/vfp/vfp.h +++ b/trunk/arch/arm/vfp/vfp.h @@ -355,3 +355,18 @@ 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 add48e36c2dc..4fc05ee0a2ef 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 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, +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 }, }; @@ -1108,16 +1108,16 @@ static u32 vfp_double_fdiv(int dd, int dn, int dm, u32 fpscr) return FPSCR_IOC; } -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, +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 }, }; #define FREG_BANK(x) ((x) & 0x0c) @@ -1131,69 +1131,60 @@ 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; - u32 (*fop)(int, int, s32, u32); + struct op *fop; - 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 ((inst & FEXT_MASK) == FEXT_FCVT) { - veclen = 0; + if (fop->flags & OP_SD) 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 (FREG_BANK(dest) == 0) + if ((fop->flags & OP_SCALAR) || (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); - fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)]; - if (!fop) + if (!fop->fn) goto invalid; for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { u32 except; + char type; - 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", + type = fop->flags & OP_SD ? 's' : 'd'; + if (op == FOP_EXT) + pr_debug("VFP: itr%d (%c%u) = op[%u] (d%u)\n", vecitr >> FPSCR_LENGTH_BIT, - dest, dn, dm); + type, dest, dn, dm); else - pr_debug("VFP: itr%d (d%u) = (d%u) op[%u] (d%u)\n", + pr_debug("VFP: itr%d (%c%u) = (d%u) op[%u] (d%u)\n", vecitr >> FPSCR_LENGTH_BIT, - dest, dn, FOP_TO_IDX(op), dm); + type, dest, dn, FOP_TO_IDX(op), dm); - except = fop(dest, dn, dm, fpscr); + except = fop->fn(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 6c819aeae006..7f343a4beca0 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)); \ + asm("mrc p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx %0, " #_vfp_ \ + : "=r" (__v) : : "cc"); \ __v; \ }) #define fmxr(_vfp_,_var_) \ - asm("mcr%? p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \ - : : "r" (_var_)) + asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \ + : : "r" (_var_) : "cc") 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 4178f6cc3d37..dedbb449632e 100644 --- a/trunk/arch/arm/vfp/vfpmodule.c +++ b/trunk/arch/arm/vfp/vfpmodule.c @@ -40,10 +40,19 @@ 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 = &thread->vfpstate; + union vfp_state *vfp; - switch (cmd) { - case THREAD_NOTIFY_FLUSH: + 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) { /* * Per-thread VFP initialisation. */ @@ -56,29 +65,12 @@ 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); - - /* - * 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; } + /* flush and release case: Per-thread VFP cleanup. */ + if (last_VFP_context == vfp) + last_VFP_context = NULL; + return NOTIFY_DONE; } diff --git a/trunk/arch/arm/vfp/vfpsingle.c b/trunk/arch/arm/vfp/vfpsingle.c index 8f6c179cafbe..ab5e9503bae5 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 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, +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 }, }; @@ -1151,16 +1151,16 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr) return FPSCR_IOC; } -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, +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 }, }; #define FREG_BANK(x) ((x) & 0x18) @@ -1174,70 +1174,63 @@ 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; - u32 (*fop)(int, int, s32, u32); + struct op *fop; - 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 ((inst & FEXT_MASK) == FEXT_FCVT) { - veclen = 0; + if (fop->flags & OP_DD) 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 (FREG_BANK(dest) == 0) + if ((fop->flags & OP_SCALAR) || 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); - fop = (op == FOP_EXT) ? fop_extfns[FEXT_TO_IDX(inst)] : fop_fns[FOP_TO_IDX(op)]; - if (!fop) + if (!fop->fn) goto invalid; for (vecitr = 0; vecitr <= veclen; vecitr += 1 << FPSCR_LENGTH_BIT) { s32 m = vfp_get_float(sm); u32 except; + char type; - 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); + 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); else - pr_debug("VFP: itr%d (s%u) = (s%u) op[%u] (s%u=%08x)\n", - vecitr >> FPSCR_LENGTH_BIT, dest, sn, + pr_debug("VFP: itr%d (%c%u) = (s%u) op[%u] (s%u=%08x)\n", + vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, FOP_TO_IDX(op), sm, m); - except = fop(dest, sn, m, fpscr); + except = fop->fn(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/time.c b/trunk/arch/arm26/kernel/time.c index db63d75d0715..1206469b2b86 100644 --- a/trunk/arch/arm26/kernel/time.c +++ b/trunk/arch/arm26/kernel/time.c @@ -33,8 +33,6 @@ #include #include -extern unsigned long wall_jiffies; - /* this needs a better home */ DEFINE_SPINLOCK(rtc_lock); @@ -136,16 +134,11 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; unsigned long seq; - unsigned long usec, sec, lost; + unsigned long usec, sec; 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)); @@ -174,8 +167,7 @@ int do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * done, and then undo it! */ - tv->tv_nsec -= 1000 * (gettimeoffset() + - (jiffies - wall_jiffies) * USECS_PER_JIFFY); + tv->tv_nsec -= 1000 * gettimeoffset(); while (tv->tv_nsec < 0) { tv->tv_nsec += NSEC_PER_SEC; @@ -194,7 +186,7 @@ EXPORT_SYMBOL(do_settimeofday); static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - do_timer(regs); + do_timer(1); #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 761938b56679..a1f6d8a9cc32 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; + mask = VM_READ|VM_EXEC|VM_WRITE; 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 (tsk->pid != 1) + if (!is_init(tsk)) goto out; /* diff --git a/trunk/arch/avr32/kernel/time.c b/trunk/arch/avr32/kernel/time.c index b0e6b5855a38..3e56b9f4358a 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(regs); + do_timer(1); write_sequnlock(&xtime_lock); /* diff --git a/trunk/arch/avr32/mm/ioremap.c b/trunk/arch/avr32/mm/ioremap.c index 536021877df6..8cfec65e37f7 100644 --- a/trunk/arch/avr32/mm/ioremap.c +++ b/trunk/arch/avr32/mm/ioremap.c @@ -7,119 +7,11 @@ */ #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 @@ -128,7 +20,7 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr, void __iomem *__ioremap(unsigned long phys_addr, size_t size, unsigned long flags) { - void *addr; + unsigned long addr; struct vm_struct *area; unsigned long offset, last_addr; pgprot_t prot; @@ -159,7 +51,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_RW | _PAGE_DIRTY + prot = __pgprot(_PAGE_PRESENT | _PAGE_GLOBAL | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_TYPE_SMALL | flags); /* @@ -169,9 +61,9 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size, if (!area) return NULL; area->phys_addr = phys_addr; - addr = area->addr; - if (remap_area_pages((unsigned long)addr, phys_addr, size, prot)) { - vunmap(addr); + addr = (unsigned long )area->addr; + if (ioremap_page_range(addr, addr + size, phys_addr, prot)) { + vunmap((void *)addr); return NULL; } diff --git a/trunk/arch/avr32/mm/tlb.c b/trunk/arch/avr32/mm/tlb.c index 5d0523bbe298..7b073052203d 100644 --- a/trunk/arch/avr32/mm/tlb.c +++ b/trunk/arch/avr32/mm/tlb.c @@ -15,7 +15,8 @@ void show_dtlb_entry(unsigned int index) { - unsigned int tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save, flags; + unsigned int tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save; + unsigned long flags; local_irq_save(flags); mmucr_save = sysreg_read(MMUCR); @@ -305,7 +306,8 @@ 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, flags; + unsigned int tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save; + unsigned long 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 9c22b76e129a..ebacf1457d91 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(regs); + do_timer(1); cris_do_profile(regs); /* Save profiling information */ diff --git a/trunk/arch/cris/arch-v32/kernel/time.c b/trunk/arch/cris/arch-v32/kernel/time.c index 50f3f93293d6..be0a01657d4f 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(regs); + do_timer(1); /* * If we have an externally synchronized Linux clock, then update diff --git a/trunk/arch/cris/kernel/time.c b/trunk/arch/cris/kernel/time.c index 66ba8898db07..0f9213cbd48e 100644 --- a/trunk/arch/cris/kernel/time.c +++ b/trunk/arch/cris/kernel/time.c @@ -37,7 +37,6 @@ 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; @@ -58,11 +57,6 @@ 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 @@ -103,7 +97,6 @@ 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 1780df3ed9e5..8b0b9348b574 100644 --- a/trunk/arch/cris/mm/ioremap.c +++ b/trunk/arch/cris/mm/ioremap.c @@ -10,93 +10,10 @@ */ #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): */ @@ -135,7 +52,8 @@ void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgpro if (!area) return NULL; addr = (void __iomem *)area->addr; - if (remap_area_pages((unsigned long) addr, phys_addr, size, prot)) { + if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, + phys_addr, prot)) { vfree((void __force *)addr); return NULL; } diff --git a/trunk/arch/frv/kernel/time.c b/trunk/arch/frv/kernel/time.c index 3d0284bccb94..7e55884135ed 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(regs); + do_timer(1); update_process_times(user_mode(regs)); profile_tick(CPU_PROFILING, regs); diff --git a/trunk/arch/h8300/kernel/time.c b/trunk/arch/h8300/kernel/time.c index 688a5100604c..e569d17b4ae6 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(regs); + do_timer(1); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index 758044f5e718..3fd2f256f2be 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -401,6 +401,7 @@ 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 @@ -416,6 +417,11 @@ 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 @@ -598,12 +604,10 @@ config ARCH_SELECT_MEMORY_MODEL def_bool y depends on ARCH_SPARSEMEM_ENABLE -source "mm/Kconfig" +config ARCH_POPULATES_NODE_MAP + def_bool y -config HAVE_ARCH_EARLY_PFN_TO_NID - bool - default y - depends on NUMA +source "mm/Kconfig" config HIGHPTE bool "Allocate 3rd-level pagetables from highmem" diff --git a/trunk/arch/i386/boot/video.S b/trunk/arch/i386/boot/video.S index 8c2a6faeeae5..2c5b5cc55f79 100644 --- a/trunk/arch/i386/boot/video.S +++ b/trunk/arch/i386/boot/video.S @@ -11,8 +11,6 @@ * */ -#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 1a29bfa26d0c..ee2d79bd8af7 100644 --- a/trunk/arch/i386/defconfig +++ b/trunk/arch/i386/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-git5 -# Tue Sep 26 09:30:47 2006 +# Linux kernel version: 2.6.18-git7 +# Wed Sep 27 21:53:10 2006 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y @@ -210,6 +210,7 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_PM=y CONFIG_PM_LEGACY=y # CONFIG_PM_DEBUG is not set +CONFIG_PM_SYSFS_DEPRECATED=y # # ACPI (Advanced Configuration and Power Interface) Support @@ -292,6 +293,7 @@ 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_ISA_DMA_API=y # CONFIG_ISA is not set @@ -1427,6 +1429,7 @@ 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 diff --git a/trunk/arch/i386/kernel/apm.c b/trunk/arch/i386/kernel/apm.c index ff9ce4b5eaa8..b42f2d914af3 100644 --- a/trunk/arch/i386/kernel/apm.c +++ b/trunk/arch/i386/kernel/apm.c @@ -225,6 +225,7 @@ #include #include #include +#include #include #include @@ -402,8 +403,6 @@ 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 @@ -419,6 +418,8 @@ 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 @@ -1423,7 +1424,7 @@ static void apm_mainloop(void) set_current_state(TASK_INTERRUPTIBLE); for (;;) { schedule_timeout(APM_CHECK_TIMEOUT); - if (exit_kapmd) + if (kthread_should_stop()) break; /* * Ok, check all events, check for idle (and mark us sleeping @@ -1706,12 +1707,6 @@ 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 @@ -1821,7 +1816,6 @@ static int apm(void *unused) console_blank_hook = NULL; #endif } - kapmd_running = 0; return 0; } @@ -2220,7 +2214,7 @@ static int __init apm_init(void) { struct proc_dir_entry *apm_proc; struct desc_struct *gdt; - int ret; + int err; dmi_check_system(apm_dmi_table); @@ -2329,12 +2323,17 @@ static int __init apm_init(void) if (apm_proc) apm_proc->owner = THIS_MODULE; - ret = kernel_thread(apm, NULL, CLONE_KERNEL | SIGCHLD); - if (ret < 0) { - printk(KERN_ERR "apm: disabled - Unable to start kernel thread.\n"); + 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; remove_proc_entry("apm", NULL); - return -ENOMEM; + return err; } + kapmd_task->flags |= PF_NOFREEZE; + wake_up_process(kapmd_task); if (num_online_cpus() > 1 && !smp ) { printk(KERN_NOTICE @@ -2384,9 +2383,10 @@ static void __exit apm_exit(void) remove_proc_entry("apm", NULL); if (power_off) pm_power_off = NULL; - exit_kapmd = 1; - while (kapmd_running) - schedule(); + if (kapmd_task) { + kthread_stop(kapmd_task); + kapmd_task = NULL; + } #ifdef CONFIG_PM_LEGACY pm_active = 0; #endif diff --git a/trunk/arch/i386/kernel/crash.c b/trunk/arch/i386/kernel/crash.c index 67d297dc1003..144b43288965 100644 --- a/trunk/arch/i386/kernel/crash.c +++ b/trunk/arch/i386/kernel/crash.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -88,7 +89,7 @@ static void crash_save_self(struct pt_regs *regs) { int cpu; - cpu = smp_processor_id(); + cpu = safe_smp_processor_id(); crash_save_this_cpu(regs, cpu); } @@ -133,7 +134,10 @@ static int crash_nmi_callback(struct notifier_block *self, static void smp_send_nmi_allbutself(void) { - send_IPI_allbutself(NMI_VECTOR); + cpumask_t mask = cpu_online_map; + cpu_clear(safe_smp_processor_id(), mask); + if (!cpus_empty(mask)) + send_IPI_mask(mask, NMI_VECTOR); } static struct notifier_block crash_nmi_nb = { @@ -185,7 +189,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 = smp_processor_id(); + crashing_cpu = safe_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 fe158042110b..f9436989473c 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) +static void efi_call_phys_prelog(void) __acquires(efi_rt_lock) { unsigned long cr4; unsigned long temp; @@ -109,7 +109,7 @@ static void efi_call_phys_prelog(void) load_gdt(cpu_gdt_descr); } -static void efi_call_phys_epilog(void) +static void efi_call_phys_epilog(void) __releases(efi_rt_lock) { unsigned long cr4; struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0); diff --git a/trunk/arch/i386/kernel/i8237.c b/trunk/arch/i386/kernel/i8237.c index c36d1c006c2f..6f508e8d7c57 100644 --- a/trunk/arch/i386/kernel/i8237.c +++ b/trunk/arch/i386/kernel/i8237.c @@ -2,6 +2,11 @@ * 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/microcode.c b/trunk/arch/i386/kernel/microcode.c index 40b44cc0d14b..9b9479768d5e 100644 --- a/trunk/arch/i386/kernel/microcode.c +++ b/trunk/arch/i386/kernel/microcode.c @@ -2,6 +2,7 @@ * 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, @@ -82,6 +83,9 @@ #include #include #include +#include +#include +#include #include #include @@ -91,9 +95,6 @@ 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 */ @@ -120,55 +121,40 @@ 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, orig_pf; + unsigned int 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 (void *unused) +static void collect_cpu_info(int cpu_num) { - 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]; - uci->sig = uci->pf = uci->rev = uci->cksum = 0; - uci->err = MC_NOTFOUND; + /* We should bind the task to the CPU */ + BUG_ON(raw_smp_processor_id() != cpu_num); + uci->pf = uci->rev = 0; 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); + printk(KERN_ERR "microcode: CPU%d not a capable Intel " + "processor\n", cpu_num); + uci->valid = 0; return; - } 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); - } - uci->orig_pf = uci->pf; + 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); } wrmsr(MSR_IA32_UCODE_REV, 0, 0); @@ -180,218 +166,159 @@ static void collect_cpu_info (void *unused) uci->sig, uci->pf, uci->rev); } -static inline void mark_microcode_update (int cpu_num, microcode_header_t *mc_header, int sig, int pf, int cksum) +static inline int microcode_update_match(int cpu_num, + microcode_header_t *mc_header, int sig, int pf) { struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; - 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; + if (!sigmatch(sig, uci->sig, pf, uci->pf) + || mc_header->rev <= uci->rev) + return 0; + return 1; } -static int find_matching_ucodes (void) +static int microcode_sanity_check(void *mc) { - int cursor = 0; - int error = 0; - - 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; + 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; + } - 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; + 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; } - - 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_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; } + ext_sigcount = ext_header->count; + } - 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; + /* 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; } + } - if (mc_header.ldrver != 1 || mc_header.hdrver != 1) { - printk(KERN_ERR "microcode: error! Unknown microcode update format\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; } + } + return 0; +} - 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); - } +/* + * 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; + } - 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; + /* free previous update file */ + vfree(uci->mc); - 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; + memcpy(new_mc, mc, total_size); + uci->mc = new_mc; + return 1; } -static void do_update_one (void * unused) +static void apply_microcode(int cpu) { unsigned long flags; unsigned int val[2]; - int cpu_num = smp_processor_id(); + int cpu_num = raw_smp_processor_id(); struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num; - 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); - } + /* We should bind the task to the CPU */ + BUG_ON(cpu_num != cpu); + + if (uci->mc == NULL) return; - } /* serialize access to the physical write to MSR 0x79 */ spin_lock_irqsave(µcode_update_lock, flags); @@ -408,68 +335,107 @@ static void do_update_one (void * unused) /* 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); - printk(KERN_INFO "microcode: CPU%d updated from revision " + 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 " "0x%x to 0x%x, date = %08x \n", cpu_num, uci->rev, val[1], uci->mc->hdr.date); - return; + uci->rev = val[1]; } -static int do_microcode_update (void) -{ - int i, error; +#ifdef CONFIG_MICROCODE_OLD_INTERFACE +static void __user *user_buffer; /* user area microcode data buffer */ +static unsigned int user_buffer_size; /* it's size */ - 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; +static long get_next_ucode(void **mc, long offset) +{ + 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; } - - if ((error = find_matching_ucodes())) { - printk(KERN_ERR "microcode: Error in the microcode data\n"); - goto out_free; + 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; } - - 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; + *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; } + return offset + total_size; +} + +static int do_microcode_update (void) +{ + long cursor = 0; + int error = 0; + void *new_mc; + int cpu; + cpumask_t old; + + old = current->cpus_allowed; -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; - } + 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); } - 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); + vfree(new_mc); } 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; @@ -480,6 +446,7 @@ 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; } @@ -496,7 +463,7 @@ static struct miscdevice microcode_dev = { .fops = µcode_fops, }; -static int __init microcode_init (void) +static int __init microcode_dev_init (void) { int error; @@ -508,6 +475,280 @@ static int __init microcode_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; @@ -515,9 +756,16 @@ static int __init microcode_init (void) static void __exit microcode_exit (void) { - misc_deregister(µcode_dev); + 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); } module_init(microcode_init) module_exit(microcode_exit) -MODULE_ALIAS_MISCDEV(MICROCODE_MINOR); diff --git a/trunk/arch/i386/kernel/nmi.c b/trunk/arch/i386/kernel/nmi.c index dbda706fdd14..3e8e3adb0489 100644 --- a/trunk/arch/i386/kernel/nmi.c +++ b/trunk/arch/i386/kernel/nmi.c @@ -13,7 +13,6 @@ * Mikael Pettersson : PM converted to driver model. Disable/enable API. */ -#include #include #include #include @@ -31,6 +30,9 @@ #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 diff --git a/trunk/arch/i386/kernel/process.c b/trunk/arch/i386/kernel/process.c index 8c190ca7ae44..96cd0232e1e0 100644 --- a/trunk/arch/i386/kernel/process.c +++ b/trunk/arch/i386/kernel/process.c @@ -425,13 +425,12 @@ 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 = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); + p->thread.io_bitmap_ptr = kmemdup(tsk->thread.io_bitmap_ptr, + 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); } diff --git a/trunk/arch/i386/kernel/setup.c b/trunk/arch/i386/kernel/setup.c index 76a524b4c90f..000cf03751fe 100644 --- a/trunk/arch/i386/kernel/setup.c +++ b/trunk/arch/i386/kernel/setup.c @@ -209,9 +209,6 @@ 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, @@ -273,9 +270,6 @@ 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) @@ -332,7 +326,7 @@ static void __init probe_roms(void) } /* check for adapter roms on 2k boundaries */ - for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) { + for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { rom = isa_bus_to_virt(start); if (!romsignature(rom)) continue; @@ -1089,22 +1083,20 @@ 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 - zones_size[ZONE_HIGHMEM] = highend_pfn - low; + 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); #endif - } - free_area_init(zones_size); + + free_area_init_nodes(max_zone_pfns); } #else extern unsigned long __init setup_memory(void); @@ -1274,7 +1266,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 < STANDARD_IO_RESOURCES; i++) + for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) request_resource(&ioport_resource, &standard_io_resources[i]); return 0; } diff --git a/trunk/arch/i386/kernel/smp.c b/trunk/arch/i386/kernel/smp.c index 465188e2d701..1b080ab8a49f 100644 --- a/trunk/arch/i386/kernel/smp.c +++ b/trunk/arch/i386/kernel/smp.c @@ -700,3 +700,30 @@ 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 020d873b7d21..0831f709f777 100644 --- a/trunk/arch/i386/kernel/smpboot.c +++ b/trunk/arch/i386/kernel/smpboot.c @@ -102,6 +102,8 @@ 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. */ @@ -645,7 +647,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(apicid); + int node = apicid_to_node(hard_smp_processor_id()); if (!node_online(node)) node = first_online_node; @@ -954,6 +956,7 @@ 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. @@ -1058,7 +1061,7 @@ static void __cpuinit do_warm_boot_cpu(void *p) static int __cpuinit __smp_prepare_cpu(int cpu) { - DECLARE_COMPLETION(done); + DECLARE_COMPLETION_ONSTACK(done); struct warm_boot_cpu_info info; struct work_struct task; int apicid, ret; diff --git a/trunk/arch/i386/kernel/srat.c b/trunk/arch/i386/kernel/srat.c index 83db411b3aa7..f7e735c077c3 100644 --- a/trunk/arch/i386/kernel/srat.c +++ b/trunk/arch/i386/kernel/srat.c @@ -30,6 +30,7 @@ #include #include #include +#include /* * proximity macros and definitions @@ -54,8 +55,7 @@ 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 int zholes_size_init; -static unsigned long zholes_size[MAX_NUMNODES * MAX_NR_ZONES]; +static u8 __initdata apicid_to_pxm[MAX_APICID]; extern void * boot_ioremap(unsigned long, unsigned long); @@ -71,6 +71,8 @@ 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); } @@ -135,47 +137,6 @@ 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 @@ -220,7 +181,6 @@ 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) { @@ -279,11 +239,15 @@ 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) { @@ -392,57 +356,7 @@ 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/time.c b/trunk/arch/i386/kernel/time.c index 86944acfb647..58a2d5582419 100644 --- a/trunk/arch/i386/kernel/time.c +++ b/trunk/arch/i386/kernel/time.c @@ -76,8 +76,6 @@ 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); @@ -329,7 +327,6 @@ 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/traps.c b/trunk/arch/i386/kernel/traps.c index 21aa1cd57773..6820b8d643c7 100644 --- a/trunk/arch/i386/kernel/traps.c +++ b/trunk/arch/i386/kernel/traps.c @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef CONFIG_EISA #include @@ -40,7 +41,6 @@ #include #include -#include #include #include #include @@ -57,6 +57,8 @@ #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 }, @@ -409,7 +411,7 @@ static void handle_BUG(struct pt_regs *regs) if (eip < PAGE_OFFSET) return; - if (__get_user(ud2, (unsigned short __user *)eip)) + if (probe_kernel_address((unsigned short __user *)eip, ud2)) return; if (ud2 != 0x0b0f) return; @@ -422,7 +424,8 @@ static void handle_BUG(struct pt_regs *regs) char *file; char c; - if (__get_user(line, (unsigned short __user *)(eip + 2))) + if (probe_kernel_address((unsigned short __user *)(eip + 2), + line)) break; if (__get_user(file, (char * __user *)(eip + 4)) || (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) diff --git a/trunk/arch/i386/lib/delay.c b/trunk/arch/i386/lib/delay.c index 3c0714c4b669..f6edb11364df 100644 --- a/trunk/arch/i386/lib/delay.c +++ b/trunk/arch/i386/lib/delay.c @@ -11,7 +11,6 @@ */ #include -#include #include #include diff --git a/trunk/arch/i386/lib/usercopy.c b/trunk/arch/i386/lib/usercopy.c index efc7e7d5f4d0..08502fc6d0cb 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 && current->pid == 1) { + if (retval == -ENOMEM && is_init(current)) { up_read(¤t->mm->mmap_sem); blk_congestion_wait(WRITE, HZ/50); goto survive; diff --git a/trunk/arch/i386/mach-voyager/voyager_smp.c b/trunk/arch/i386/mach-voyager/voyager_smp.c index 6c86575ffdcb..856c73fcb7e7 100644 --- a/trunk/arch/i386/mach-voyager/voyager_smp.c +++ b/trunk/arch/i386/mach-voyager/voyager_smp.c @@ -99,6 +99,7 @@ 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 @@ -1247,6 +1248,12 @@ 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 941d1a5ebabb..51e3739dd227 100644 --- a/trunk/arch/i386/mm/discontig.c +++ b/trunk/arch/i386/mm/discontig.c @@ -157,21 +157,6 @@ 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 @@ -227,6 +212,8 @@ 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. @@ -276,6 +263,7 @@ 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); @@ -369,45 +357,22 @@ void __init numa_kva_reserve(void) void __init zone_sizes_init(void) { int 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 - } - } + 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]); } - - zholes_size = get_zholes_size(nid); - - free_area_init_node(nid, NODE_DATA(nid), zones_size, start, - zholes_size); } + + free_area_init_nodes(max_zone_pfns); return; } diff --git a/trunk/arch/i386/mm/fault.c b/trunk/arch/i386/mm/fault.c index 5e17a3f43b41..2581575786c1 100644 --- a/trunk/arch/i386/mm/fault.c +++ b/trunk/arch/i386/mm/fault.c @@ -440,7 +440,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))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) goto bad_area; } @@ -589,7 +589,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, */ out_of_memory: up_read(&mm->mmap_sem); - if (tsk->pid == 1) { + if (is_init(tsk)) { 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 ba44000b9069..f9f647cdbc7b 100644 --- a/trunk/arch/i386/mm/highmem.c +++ b/trunk/arch/i386/mm/highmem.c @@ -38,22 +38,19 @@ 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) { dec_preempt_count(); preempt_check_resched(); @@ -62,14 +59,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 + * 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. */ - pte_clear(&init_mm, vaddr, kmap_pte-idx); - __flush_tlb_one(vaddr); -#endif + kpte_clear_flush(kmap_pte-idx, vaddr); dec_preempt_count(); preempt_check_resched(); @@ -88,7 +85,6 @@ 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 4a5a914b3432..90089c14c23d 100644 --- a/trunk/arch/i386/mm/init.c +++ b/trunk/arch/i386/mm/init.c @@ -493,6 +493,7 @@ 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; diff --git a/trunk/arch/i386/mm/ioremap.c b/trunk/arch/i386/mm/ioremap.c index 247fde76aaed..fff08ae7b5ed 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,82 +21,6 @@ #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): */ @@ -115,6 +39,7 @@ 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; @@ -142,6 +67,9 @@ 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 */ @@ -158,7 +86,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, flags)) { + (unsigned long) addr + size, phys_addr, prot)) { vunmap((void __force *) addr); return NULL; } diff --git a/trunk/arch/i386/oprofile/op_model_ppro.c b/trunk/arch/i386/oprofile/op_model_ppro.c index f88e05ba8eb3..ca2447e05e15 100644 --- a/trunk/arch/i386/oprofile/op_model_ppro.c +++ b/trunk/arch/i386/oprofile/op_model_ppro.c @@ -138,11 +138,14 @@ 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; - if (reset_value[0]) { - CTRL_READ(low, high, msrs, 0); - CTRL_SET_ACTIVE(low); - CTRL_WRITE(low, high, msrs, 0); + 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); + } } } @@ -150,11 +153,14 @@ static void ppro_start(struct op_msrs const * const msrs) static void ppro_stop(struct op_msrs const * const msrs) { unsigned int low,high; + int i; - if (reset_value[0]) { - CTRL_READ(low, high, msrs, 0); + 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, 0); + CTRL_WRITE(low, high, msrs, i); } } diff --git a/trunk/arch/i386/pci/mmconfig.c b/trunk/arch/i386/pci/mmconfig.c index 05be8db58a8c..d0c3da3aa2aa 100644 --- a/trunk/arch/i386/pci/mmconfig.c +++ b/trunk/arch/i386/pci/mmconfig.c @@ -67,7 +67,10 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) return 0; } -static inline void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) +/* + * This is always called under pci_config_lock + */ +static 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) { diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index f521f2f60a78..0b7f701d5cf7 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -356,6 +356,9 @@ 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 @@ -420,6 +423,14 @@ 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" diff --git a/trunk/arch/ia64/hp/sim/simeth.c b/trunk/arch/ia64/hp/sim/simeth.c index b5195be62818..e1a1b11473e2 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, htonl(ifa->ifa_local)); + dev->name, ntohl(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, htonl(ifa->ifa_local)): + netdev_attach(local->simfd, dev->irq, ntohl(ifa->ifa_local)): netdev_detach(local->simfd); printk(KERN_INFO "simeth: netdev_attach/detach: event=%s ->%d\n", diff --git a/trunk/arch/ia64/ia32/sys_ia32.c b/trunk/arch/ia64/ia32/sys_ia32.c index 6aa3c51619ca..bddbd22706ed 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 +#ifdef CONFIG_SYSCTL_SYSCALL asmlinkage long sys32_sysctl (struct sysctl32 __user *args) { diff --git a/trunk/arch/ia64/kernel/Makefile b/trunk/arch/ia64/kernel/Makefile index ad8215a3c586..31497496eb4b 100644 --- a/trunk/arch/ia64/kernel/Makefile +++ b/trunk/arch/ia64/kernel/Makefile @@ -32,6 +32,11 @@ 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 fef06571be99..12701cf32d99 100644 --- a/trunk/arch/ia64/kernel/entry.S +++ b/trunk/arch/ia64/kernel/entry.S @@ -1605,8 +1605,8 @@ sys_call_table: data8 sys_ni_syscall // 1295 reserved for ppoll data8 sys_unshare data8 sys_splice - data8 sys_ni_syscall // reserved for set_robust_list - data8 sys_ni_syscall // reserved for get_robust_list + data8 sys_set_robust_list + data8 sys_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 new file mode 100644 index 000000000000..ebf4e988e78c --- /dev/null +++ b/trunk/arch/ia64/kernel/esi.c @@ -0,0 +1,205 @@ +/* + * 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 new file mode 100644 index 000000000000..6b3d6c1f99b6 --- /dev/null +++ b/trunk/arch/ia64/kernel/esi_stub.S @@ -0,0 +1,96 @@ +/* + * 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 3ead20fb6f4b..879c1817bd1c 100644 --- a/trunk/arch/ia64/kernel/ia64_ksyms.c +++ b/trunk/arch/ia64/kernel/ia64_ksyms.c @@ -105,5 +105,9 @@ 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 781960f80b6f..169ec3a7156c 100644 --- a/trunk/arch/ia64/kernel/kprobes.c +++ b/trunk/arch/ia64/kernel/kprobes.c @@ -136,10 +136,8 @@ 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, - struct kprobe *p) + unsigned long addr) { - unsigned long addr = (unsigned long)p->addr; - if (bundle_encoding[template][slot] == I) { switch (major_opcode) { case 0x0: //I_UNIT_MISC_OPCODE: @@ -217,7 +215,7 @@ static void __kprobes prepare_break_inst(uint template, uint slot, struct kprobe *p) { unsigned long break_inst = BREAK_INST; - bundle_t *bundle = &p->ainsn.insn.bundle; + bundle_t *bundle = &p->opcode.bundle; /* * Copy the original kprobe_inst qualifying predicate(qp) @@ -423,11 +421,9 @@ 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 = &p->ainsn.insn.bundle; - - memcpy(&p->opcode.bundle, kprobe_addr, sizeof(bundle_t)); - memcpy(&p->ainsn.insn.bundle, kprobe_addr, sizeof(bundle_t)); + bundle_t *bundle; + bundle = &((kprobe_opcode_t *)kprobe_addr)->bundle; template = bundle->quad0.template; if(valid_kprobe_addr(template, slot, addr)) @@ -440,20 +436,19 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) /* 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, p)) + if (unsupported_inst(template, slot, major_opcode, kprobe_inst, addr)) return -EINVAL; - prepare_break_inst(template, slot, major_opcode, kprobe_inst, p); - return 0; -} + 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)); -void __kprobes flush_insn_slot(struct kprobe *p) -{ - unsigned long arm_addr; + prepare_break_inst(template, slot, major_opcode, kprobe_inst, p); - arm_addr = ((unsigned long)&p->opcode.bundle) & ~0xFULL; - flush_icache_range(arm_addr, arm_addr + sizeof(bundle_t)); + return 0; } void __kprobes arch_arm_kprobe(struct kprobe *p) @@ -461,9 +456,10 @@ void __kprobes arch_arm_kprobe(struct kprobe *p) unsigned long addr = (unsigned long)p->addr; unsigned long arm_addr = addr & ~0xFULL; - 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)); + 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)); } void __kprobes arch_disarm_kprobe(struct kprobe *p) @@ -471,11 +467,18 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) unsigned long addr = (unsigned long)p->addr; unsigned long arm_addr = addr & ~0xFULL; - /* 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)); + /* 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)); } +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 @@ -486,12 +489,12 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) */ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) { - unsigned long bundle_addr = ((unsigned long) (&p->opcode.bundle)) & ~0xFULL; + 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); - template = p->opcode.bundle.quad0.template; + template = p->ainsn.insn->bundle.quad0.template; if (slot == 1 && bundle_encoding[template][1] == L) slot = 2; @@ -553,7 +556,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) static void __kprobes prepare_ss(struct kprobe *p, struct pt_regs *regs) { - unsigned long bundle_addr = (unsigned long) &p->opcode.bundle; + unsigned long bundle_addr = (unsigned long) &p->ainsn.insn->bundle; unsigned long slot = (unsigned long)p->addr & 0xf; /* single step inline if break instruction */ @@ -768,6 +771,12 @@ 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. diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index 2fbe4536fe18..663230183254 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -54,6 +54,9 @@ * * 2005-10-07 Keith Owens * Add notify_die() hooks. + * + * 2006-09-15 Hidetoshi Seto + * Add printing support for MCA/INIT. */ #include #include @@ -136,11 +139,175 @@ 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) { - printk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func); + if (monarch_cpu == smp_processor_id()) + ia64_mlogbuf_finish(0); + mprintk(KERN_EMERG "%s: spinning here, not returning to SAL\n", func); while (1) cpu_relax(); } @@ -221,7 +388,7 @@ ia64_log_get(int sal_info_type, u8 **buffer, int irq_safe) { sal_log_record_header_t *log_buffer; u64 total_len = 0; - int s; + unsigned long s; IA64_LOG_LOCK(sal_info_type); @@ -344,9 +511,6 @@ 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) { @@ -375,7 +539,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 */ - return IRQ_HANDLED; + goto out; } else { cpe_history[index++] = now; if (index == CPE_HISTORY_LENGTH) @@ -383,6 +547,10 @@ 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; } @@ -988,18 +1156,22 @@ ia64_wait_for_slaves(int monarch, const char *type) } if (!missing) goto all_in; - printk(KERN_INFO "OS %s slave did not rendezvous on cpu", type); + /* + * Maybe slave(s) dead. Print buffered messages immediately. + */ + ia64_mlogbuf_finish(0); + mprintk(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) - printk(" %d", c); + mprintk(" %d", c); } - printk("\n"); + mprintk("\n"); return; all_in: - printk(KERN_INFO "All OS %s slaves have reached rendezvous\n", type); + mprintk(KERN_INFO "All OS %s slaves have reached rendezvous\n", type); return; } @@ -1027,10 +1199,8 @@ ia64_mca_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 */ - printk(KERN_INFO "Entered OS MCA handler. PSP=%lx cpu=%d monarch=%ld\n", - sos->proc_state_param, cpu, sos->monarch); + mprintk(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; @@ -1066,6 +1236,9 @@ 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) @@ -1106,9 +1279,6 @@ 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 */ @@ -1141,7 +1311,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 */ - return IRQ_HANDLED; + goto out; } else { cmc_history[index++] = now; if (index == CMC_HISTORY_LENGTH) @@ -1149,6 +1319,10 @@ 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; } @@ -1305,6 +1479,15 @@ 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; @@ -1326,6 +1509,8 @@ 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; } @@ -1357,12 +1542,9 @@ 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); - printk(KERN_INFO "Entered OS INIT handler. PSP=%lx cpu=%d monarch=%ld\n", + mprintk(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); @@ -1375,7 +1557,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()) { - printk(KERN_WARNING "%s: Promoting cpu %d to monarch.\n", + mprintk(KERN_WARNING "%s: Promoting cpu %d to monarch.\n", __FUNCTION__, cpu); atomic_dec(&slaves); sos->monarch = 1; @@ -1387,7 +1569,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) { - printk(KERN_WARNING "%s: Demoting cpu %d to slave.\n", + mprintk(KERN_WARNING "%s: Demoting cpu %d to slave.\n", __FUNCTION__, cpu); atomic_dec(&monarchs); sos->monarch = 0; @@ -1408,7 +1590,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__); - printk("Slave on cpu %d returning to normal service.\n", cpu); + mprintk("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); @@ -1426,7 +1608,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. */ - printk("Delaying for 5 seconds...\n"); + mprintk("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 @@ -1439,7 +1621,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__); - printk("\nINIT dump complete. Monarch on cpu %d returning to normal service.\n", cpu); + mprintk("\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 96047491d1b9..c6b607c00dee 100644 --- a/trunk/arch/ia64/kernel/mca_asm.S +++ b/trunk/arch/ia64/kernel/mca_asm.S @@ -1025,18 +1025,13 @@ 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) ;; @@ -1067,6 +1062,10 @@ 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 8db6e0cedadc..a45009d2bc90 100644 --- a/trunk/arch/ia64/kernel/mca_drv.c +++ b/trunk/arch/ia64/kernel/mca_drv.c @@ -79,14 +79,30 @@ static int fatal_mca(const char *fmt, ...) { va_list args; + char buf[256]; va_start(args, fmt); - vprintk(fmt, args); + vsnprintf(buf, sizeof(buf), 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 @@ -140,6 +156,7 @@ 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, @@ -440,7 +457,7 @@ recover_from_read_error(slidx_table_t *slidx, /* Is target address valid? */ if (!pbci->tv) - return fatal_mca(KERN_ALERT "MCA: target address not valid\n"); + return fatal_mca("target address not valid"); /* * cpu read or memory-mapped io read @@ -458,7 +475,7 @@ recover_from_read_error(slidx_table_t *slidx, /* Is minstate valid? */ if (!peidx_bottom(peidx) || !(peidx_bottom(peidx)->valid.minstate)) - return fatal_mca(KERN_ALERT "MCA: minstate not valid\n"); + return fatal_mca("minstate not valid"); psr1 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_ipsr); psr2 =(struct ia64_psr *)&(peidx_minstate_area(peidx)->pmsa_xpsr); @@ -492,13 +509,14 @@ recover_from_read_error(slidx_table_t *slidx, psr2->bn = 1; psr2->i = 0; - return MCA_RECOVERED; + return mca_recovered("user memory corruption. " + "kill affected process - recovered."); } } - return fatal_mca(KERN_ALERT "MCA: kernel context not recovered," - " iip 0x%lx\n", pmsa->pmsa_iip); + return fatal_mca("kernel context not recovered, iip 0x%lx\n", + pmsa->pmsa_iip); } /** @@ -584,13 +602,13 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, * The machine check is corrected. */ if (psp->cm == 1) - return MCA_RECOVERED; + return mca_recovered("machine check is already corrected."); /* * The error was not contained. Software must be reset. */ if (psp->us || psp->ci == 0) - return fatal_mca(KERN_ALERT "MCA: error not contained\n"); + return fatal_mca("error not contained"); /* * The cache check and bus check bits have four possible states @@ -601,22 +619,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(KERN_ALERT "MCA: No bus check\n"); + return fatal_mca("No bus check"); /* * Sorry, we cannot handle so many. */ if (peidx_bus_check_num(peidx) > 1) - return fatal_mca(KERN_ALERT "MCA: Too many bus checks\n"); + return fatal_mca("Too many bus checks"); /* * Well, here is only one bus error. */ if (pbci->ib) - return fatal_mca(KERN_ALERT "MCA: Internal Bus error\n"); + return fatal_mca("Internal Bus error"); if (pbci->cc) - return fatal_mca(KERN_ALERT "MCA: Cache-cache error\n"); + return fatal_mca("Cache-cache error"); if (pbci->eb && pbci->bsi > 0) - return fatal_mca(KERN_ALERT "MCA: External bus check fatal status\n"); + return fatal_mca("External bus check fatal status"); /* * This is a local MCA and estimated as recoverble external bus error. @@ -628,7 +646,7 @@ recover_from_processor_error(int platform, slidx_table_t *slidx, /* * On account of strange SAL error record, we cannot recover. */ - return fatal_mca(KERN_ALERT "MCA: Strange SAL record\n"); + return fatal_mca("Strange SAL record"); } /** @@ -657,10 +675,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(KERN_ALERT "MCA: Too Many Errors\n"); + return fatal_mca("Too Many Errors"); else if (n_proc_err == 0) - /* Weird SAL record ... We need not to recover */ - return fatal_mca(KERN_ALERT "MCA: Weird SAL record\n"); + /* Weird SAL record ... We can't do anything */ + return fatal_mca("Weird SAL record"); /* Make index of processor error section */ mca_make_peidx((sal_log_processor_info_t*) @@ -671,7 +689,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(KERN_ALERT "MCA: global MCA\n"); + return fatal_mca("global MCA"); /* 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 31a2e52bb16f..c85e943ba5fd 100644 --- a/trunk/arch/ia64/kernel/mca_drv.h +++ b/trunk/arch/ia64/kernel/mca_drv.h @@ -118,3 +118,7 @@ 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/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index 7bb7696e4ce2..281004ff7b00 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -63,6 +63,9 @@ #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 */ @@ -297,14 +300,17 @@ 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[IA64_NUM_PMC_REGS]; /* saved copies of PMC values */ + unsigned long ctx_pmcs[PFM_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[IA64_NUM_PMD_REGS]; /* software state for PMDS */ + 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 */ u64 ctx_saved_psr_up; /* only contains psr.up value */ @@ -868,7 +874,6 @@ 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; @@ -889,7 +894,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 thread->pmds[] array + * As a consequence to this call, the ctx->th_pmds[] array * contains stale information which must be ignored * when context is reloaded AND monitoring is active (see * pfm_restart). @@ -924,9 +929,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, th->pmcs[i] & ~0xfUL); - th->pmcs[i] &= ~0xfUL; - DPRINT_ovfl(("pmc[%d]=0x%lx\n", i, th->pmcs[i])); + 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])); } /* * make all of this visible @@ -943,7 +948,6 @@ 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; @@ -1009,9 +1013,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; - 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])); + 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])); } ia64_srlz_d(); @@ -1070,7 +1074,6 @@ 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; @@ -1092,11 +1095,11 @@ pfm_copy_pmds(struct task_struct *task, pfm_context_t *ctx) ctx->ctx_pmds[i].val = val & ~ovfl_val; val &= ovfl_val; } - thread->pmds[i] = val; + ctx->th_pmds[i] = val; DPRINT(("pmd[%d]=0x%lx soft_val=0x%lx\n", i, - thread->pmds[i], + ctx->th_pmds[i], ctx->ctx_pmds[i].val)); } } @@ -1107,7 +1110,6 @@ 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; @@ -1115,8 +1117,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 */ - thread->pmcs[i] = ctx->ctx_pmcs[i]; - DPRINT(("pmc[%d]=0x%lx\n", i, thread->pmcs[i])); + ctx->th_pmcs[i] = ctx->ctx_pmcs[i]; + DPRINT(("pmc[%d]=0x%lx\n", i, ctx->th_pmcs[i])); } } @@ -2860,7 +2862,6 @@ 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; @@ -2881,7 +2882,6 @@ 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 thread->pmcs[] may be modified on overflow, i.e., when + * The value in th_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) thread->pmcs[cnum] = value; + if (is_system == 0) ctx->th_pmcs[cnum] = value; /* * write hardware register if we can @@ -3102,7 +3102,6 @@ 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; @@ -3126,7 +3125,6 @@ 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. @@ -3234,7 +3232,7 @@ pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) /* * write thread state */ - if (is_system == 0) thread->pmds[cnum] = hw_value; + if (is_system == 0) ctx->th_pmds[cnum] = hw_value; /* * write hardware register if we can @@ -3300,7 +3298,6 @@ 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; @@ -3324,7 +3321,6 @@ 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. @@ -3386,7 +3382,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 ? thread->pmds[cnum] : 0UL; + val = is_loaded ? ctx->th_pmds[cnum] : 0UL; } rd_func = pmu_conf->pmd_desc[cnum].read_check; @@ -4355,8 +4351,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 = thread->pmcs; - pmds_source = thread->pmds; + pmcs_source = ctx->th_pmcs; + pmds_source = ctx->th_pmds; /* * always the case for system-wide @@ -5865,14 +5861,12 @@ 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 @@ -5930,19 +5924,19 @@ pfm_save_regs(struct task_struct *task) * guarantee we will be schedule at that same * CPU again. */ - pfm_save_pmds(t->pmds, ctx->ctx_used_pmds[0]); + pfm_save_pmds(ctx->th_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. */ - t->pmcs[0] = ia64_get_pmc(0); + ctx->th_pmcs[0] = ia64_get_pmc(0); /* * unfreeze PMU if had pending overflows */ - if (t->pmcs[0] & ~0x1UL) pfm_unfreeze_pmu(); + if (ctx->th_pmcs[0] & ~0x1UL) pfm_unfreeze_pmu(); /* * finally, allow context access. @@ -5987,7 +5981,6 @@ 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(); @@ -5995,7 +5988,6 @@ pfm_lazy_save_regs (struct task_struct *task) } ctx = PFM_GET_CTX(task); - t = &task->thread; /* * we need to mask PMU overflow here to @@ -6020,19 +6012,19 @@ pfm_lazy_save_regs (struct task_struct *task) /* * save all the pmds we use */ - pfm_save_pmds(t->pmds, ctx->ctx_used_pmds[0]); + pfm_save_pmds(ctx->th_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 */ - t->pmcs[0] = ia64_get_pmc(0); + ctx->th_pmcs[0] = ia64_get_pmc(0); /* * unfreeze PMU if had pending overflows */ - if (t->pmcs[0] & ~0x1UL) pfm_unfreeze_pmu(); + if (ctx->th_pmcs[0] & ~0x1UL) pfm_unfreeze_pmu(); /* * now get can unmask PMU interrupts, they will @@ -6051,7 +6043,6 @@ 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; @@ -6062,11 +6053,10 @@ pfm_load_regs (struct task_struct *task) BUG_ON(GET_PMU_OWNER()); - t = &task->thread; /* * possible on unload */ - if (unlikely((t->flags & IA64_THREAD_PM_VALID) == 0)) return; + if (unlikely((task->thread.flags & IA64_THREAD_PM_VALID) == 0)) return; /* * we always come here with interrupts ALREADY disabled by @@ -6148,21 +6138,21 @@ pfm_load_regs (struct task_struct *task) * * XXX: optimize here */ - if (pmd_mask) pfm_restore_pmds(t->pmds, pmd_mask); - if (pmc_mask) pfm_restore_pmcs(t->pmcs, pmc_mask); + if (pmd_mask) pfm_restore_pmds(ctx->th_pmds, pmd_mask); + if (pmc_mask) pfm_restore_pmcs(ctx->th_pmcs, pmc_mask); /* * check for pending overflow at the time the state * was saved. */ - if (unlikely(PMC0_HAS_OVFL(t->pmcs[0]))) { + if (unlikely(PMC0_HAS_OVFL(ctx->th_pmcs[0]))) { /* * reload pmc0 with the overflow information * On McKinley PMU, this will trigger a PMU interrupt */ - ia64_set_pmc(0, t->pmcs[0]); + ia64_set_pmc(0, ctx->th_pmcs[0]); ia64_srlz_d(); - t->pmcs[0] = 0UL; + ctx->th_pmcs[0] = 0UL; /* * will replay the PMU interrupt @@ -6215,7 +6205,6 @@ 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; @@ -6224,7 +6213,6 @@ 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)); @@ -6287,22 +6275,22 @@ pfm_load_regs (struct task_struct *task) */ pmc_mask = ctx->ctx_all_pmcs[0]; - pfm_restore_pmds(t->pmds, pmd_mask); - pfm_restore_pmcs(t->pmcs, pmc_mask); + pfm_restore_pmds(ctx->th_pmds, pmd_mask); + pfm_restore_pmcs(ctx->th_pmcs, pmc_mask); /* * check for pending overflow at the time the state * was saved. */ - if (unlikely(PMC0_HAS_OVFL(t->pmcs[0]))) { + if (unlikely(PMC0_HAS_OVFL(ctx->th_pmcs[0]))) { /* * reload pmc0 with the overflow information * On McKinley PMU, this will trigger a PMU interrupt */ - ia64_set_pmc(0, t->pmcs[0]); + ia64_set_pmc(0, ctx->th_pmcs[0]); ia64_srlz_d(); - t->pmcs[0] = 0UL; + ctx->th_pmcs[0] = 0UL; /* * will replay the PMU interrupt @@ -6377,11 +6365,11 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx) */ pfm_unfreeze_pmu(); } else { - pmc0 = task->thread.pmcs[0]; + pmc0 = ctx->th_pmcs[0]; /* * clear whatever overflow status bits there were */ - task->thread.pmcs[0] = 0; + ctx->th_pmcs[0] = 0; } ovfl_val = pmu_conf->ovfl_val; /* @@ -6402,7 +6390,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) : task->thread.pmds[i]; + val = pmd_val = can_access_pmu ? ia64_get_pmd(i) : ctx->th_pmds[i]; if (PMD_IS_COUNTING(i)) { DPRINT(("[%d] pmd[%d] ctx_pmd=0x%lx hw_pmd=0x%lx\n", @@ -6434,7 +6422,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) task->thread.pmds[i] = pmd_val; + if (is_self) ctx->th_pmds[i] = pmd_val; ctx->ctx_pmds[i].val = val; } @@ -6678,7 +6666,7 @@ pfm_init(void) ffz(pmu_conf->ovfl_val)); /* sanity check */ - if (pmu_conf->num_pmds >= IA64_NUM_PMD_REGS || pmu_conf->num_pmcs >= IA64_NUM_PMC_REGS) { + if (pmu_conf->num_pmds >= PFM_NUM_PMD_REGS || pmu_conf->num_pmcs >= PFM_NUM_PMC_REGS) { printk(KERN_ERR "perfmon: not enough pmc/pmd, perfmon disabled\n"); pmu_conf = NULL; return -1; @@ -6753,7 +6741,6 @@ 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; @@ -6798,16 +6785,14 @@ 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, t->pmcs[i]); + 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]); } 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, t->pmds[i]); + 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]); } if (ctx) { diff --git a/trunk/arch/ia64/kernel/salinfo.c b/trunk/arch/ia64/kernel/salinfo.c index 9065f0f01ba3..e63b8ca5344a 100644 --- a/trunk/arch/ia64/kernel/salinfo.c +++ b/trunk/arch/ia64/kernel/salinfo.c @@ -266,6 +266,7 @@ 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) @@ -283,6 +284,7 @@ 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; @@ -332,6 +334,8 @@ 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 7ad0d9cc6db6..84f93c0f2c66 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 family[32], features[128], *cp, sep; + char features[128], *cp, sep; struct cpuinfo_ia64 *c = v; unsigned long mask; unsigned long proc_freq; @@ -517,12 +517,6 @@ 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; @@ -553,8 +547,9 @@ show_cpuinfo (struct seq_file *m, void *v) "processor : %d\n" "vendor : %s\n" "arch : IA-64\n" - "family : %s\n" + "family : %u\n" "model : %u\n" + "model name : %s\n" "revision : %u\n" "archrev : %u\n" "features :%s\n" /* don't change this---it _is_ right! */ @@ -563,7 +558,8 @@ 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, family, c->model, c->revision, c->archrev, + cpunum, c->vendor, c->family, c->model, + c->model_name, c->revision, c->archrev, features, c->ppn, c->number, proc_freq / 1000, proc_freq % 1000, c->itc_freq / 1000000, c->itc_freq % 1000000, @@ -611,6 +607,31 @@ 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) { @@ -640,7 +661,6 @@ 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); @@ -663,6 +683,7 @@ 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 6203ed4ec8cf..f7d7f5668144 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -879,3 +879,27 @@ 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 6928ef0d64d8..62e07f906e05 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -29,8 +29,6 @@ #include #include -extern unsigned long wall_jiffies; - volatile int time_keeper_id = 0; /* smp_processor_id() of time-keeper */ #ifdef CONFIG_IA64_DEBUG_IRQ @@ -78,7 +76,7 @@ timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) * xtime_lock. */ write_seqlock(&xtime_lock); - do_timer(regs); + do_timer(1); 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 05bdf7affb43..5629b45e89c6 100644 --- a/trunk/arch/ia64/kernel/topology.c +++ b/trunk/arch/ia64/kernel/topology.c @@ -36,9 +36,7 @@ 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 5b0d5f64a9b1..b3b2e389d6b2 100644 --- a/trunk/arch/ia64/kernel/vmlinux.lds.S +++ b/trunk/arch/ia64/kernel/vmlinux.lds.S @@ -184,7 +184,9 @@ 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) } @@ -202,7 +204,9 @@ 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 e004143ba86b..daf977ff2920 100644 --- a/trunk/arch/ia64/mm/contig.c +++ b/trunk/arch/ia64/mm/contig.c @@ -26,7 +26,6 @@ #include #ifdef CONFIG_VIRTUAL_MEM_MAP -static unsigned long num_dma_physpages; static unsigned long max_gap; #endif @@ -41,10 +40,11 @@ show_mem (void) int i, total = 0, reserved = 0; int shared = 0, cached = 0; - printk("Mem-info:\n"); + printk(KERN_INFO "Mem-info:\n"); show_free_areas(); - printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + printk(KERN_INFO "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("%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()); + 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()); } /* physical address where the bootmem map is located */ @@ -218,18 +218,6 @@ 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. */ @@ -238,45 +226,22 @@ void __init paging_init (void) { unsigned long max_dma; - 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)); + unsigned long nid = 0; + unsigned long max_zone_pfns[MAX_NR_ZONES]; 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 - 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(register_active_ranges, &nid); efi_memmap_walk(find_largest_hole, (u64 *)&max_gap); if (max_gap < LARGE_GAP) { vmem_map = (struct page *) 0; - free_area_init_node(0, NODE_DATA(0), zones_size, 0, - zholes_size); + free_area_init_nodes(max_zone_pfns); } else { unsigned long map_size; @@ -288,20 +253,19 @@ paging_init (void) vmem_map = (struct page *) vmalloc_end; efi_memmap_walk(create_mem_map_page_table, NULL); - NODE_DATA(0)->node_mem_map = vmem_map; - free_area_init_node(0, NODE_DATA(0), zones_size, - 0, zholes_size); + /* + * 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); printk("Virtual mem_map starts at 0x%p\n", mem_map); } #else /* !CONFIG_VIRTUAL_MEM_MAP */ - 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); + add_active_range(0, 0, max_low_pfn); + free_area_init_nodes(max_zone_pfns); #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 d260bffa01ab..d497b6b0f5b2 100644 --- a/trunk/arch/ia64/mm/discontig.c +++ b/trunk/arch/ia64/mm/discontig.c @@ -547,15 +547,16 @@ void show_mem(void) unsigned long total_present = 0; pg_data_t *pgdat; - printk("Mem-info:\n"); + printk(KERN_INFO "Mem-info:\n"); show_free_areas(); - printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); + printk(KERN_INFO "Free swap: %6ldkB\n", + nr_swap_pages<<(PAGE_SHIFT-10)); + printk(KERN_INFO "Node memory in pages:\n"); 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++) { @@ -579,18 +580,17 @@ void show_mem(void) total_reserved += reserved; total_cached += cached; total_shared += shared; - 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 "Node %4d: RAM: %11ld, rsvd: %8d, " + "shrd: %10d, swpd: %10d\n", pgdat->node_id, + present, reserved, shared, cached); } - 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()); + 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()); } /** @@ -654,6 +654,7 @@ 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 += @@ -678,10 +679,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; @@ -698,47 +699,20 @@ 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 - free_area_init_node(node, NODE_DATA(node), zones_size, - pfn_offset, zholes_size); + if (mem_data[node].max_pfn > max_pfn) + max_pfn = mem_data[node].max_pfn; } + 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 14ef7cceb208..59f3ab937615 100644 --- a/trunk/arch/ia64/mm/fault.c +++ b/trunk/arch/ia64/mm/fault.c @@ -146,9 +146,11 @@ 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_R_BIT) & 1UL) << VM_READ_BIT)); + | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT)); if ((vma->vm_flags & mask) != mask) goto bad_area; @@ -278,7 +280,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re out_of_memory: up_read(&mm->mmap_sem); - if (current->pid == 1) { + if (is_init(current)) { 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 30617ccb4f7e..ff87a5cba399 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -593,6 +593,18 @@ 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 64e4c21f311c..7807fc5c0422 100644 --- a/trunk/arch/ia64/mm/numa.c +++ b/trunk/arch/ia64/mm/numa.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -69,4 +70,21 @@ 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 60b45e79f080..15c7c670da39 100644 --- a/trunk/arch/ia64/pci/pci.c +++ b/trunk/arch/ia64/pci/pci.c @@ -562,7 +562,8 @@ pcibios_enable_device (struct pci_dev *dev, int mask) void pcibios_disable_device (struct pci_dev *dev) { - acpi_pci_irq_disable(dev); + if (dev->is_enabled) + 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 27dee4584061..7f73ad4408aa 100644 --- a/trunk/arch/ia64/sn/kernel/bte.c +++ b/trunk/arch/ia64/sn/kernel/bte.c @@ -277,8 +277,7 @@ 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 | GFP_DMA); + bteBlock_unaligned = kmalloc(len + 3 * L1_CACHE_BYTES, GFP_KERNEL); if (bteBlock_unaligned == NULL) { return BTEFAIL_NOTAVAIL; } diff --git a/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/trunk/arch/ia64/sn/pci/pcibr/pcibr_ate.c index 1f0253bfe0a0..5eb1e1e078b4 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; - u64 flags; + unsigned long 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 a86c7b945962..1ee977fb6ebb 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; - u64 flags; + unsigned long flags; u64 itte; struct hubdev_info *hubinfo; struct sn_flush_device_kernel *p; diff --git a/trunk/arch/m32r/kernel/time.c b/trunk/arch/m32r/kernel/time.c index ded0be07a476..d8af155db984 100644 --- a/trunk/arch/m32r/kernel/time.c +++ b/trunk/arch/m32r/kernel/time.c @@ -38,7 +38,6 @@ 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) /* @@ -108,24 +107,17 @@ 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); @@ -158,7 +150,6 @@ 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); @@ -202,7 +193,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(regs); + do_timer(1); #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 dc18a33eefef..8d5f551b5754 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 (tsk->pid == 1) { + if (is_init(tsk)) { 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 a151849a605e..5152c4e6ac80 100644 --- a/trunk/arch/m32r/mm/ioremap.c +++ b/trunk/arch/m32r/mm/ioremap.c @@ -20,92 +20,8 @@ #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): @@ -129,6 +45,7 @@ __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; @@ -157,6 +74,9 @@ __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 */ @@ -172,7 +92,8 @@ __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags) return NULL; area->phys_addr = phys_addr; addr = (void __iomem *) area->addr; - if (remap_area_pages((unsigned long)addr, phys_addr, size, flags)) { + if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, + phys_addr, pgprot)) { vunmap((void __force *) addr); return NULL; } diff --git a/trunk/arch/m68k/kernel/time.c b/trunk/arch/m68k/kernel/time.c index 98e4b1adfa29..6cfc984380d9 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(regs); + do_timer(1); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -96,31 +96,23 @@ 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, lost; + unsigned long usec, sec; 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)); @@ -141,7 +133,6 @@ 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; @@ -153,8 +144,7 @@ int do_settimeofday(struct timespec *tv) * Discover what correction gettimeofday * would have done, and then undo it! */ - nsec -= 1000 * (mach_gettimeoffset() + - (jiffies - wall_jiffies) * (1000000 / HZ)); + nsec -= 1000 * mach_gettimeoffset(); 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 aec15270d334..911f2ce3f53e 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))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) 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 (current->pid == 1) { + if (is_init(current)) { 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 f18b9d3ef16d..dc4ea7e074a6 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(fp); + do_timer(1); #ifndef CONFIG_SMP update_process_times(user_mode(fp)); #endif diff --git a/trunk/arch/m68knommu/kernel/time.c b/trunk/arch/m68knommu/kernel/time.c index 1db987272220..c5667bdddd5e 100644 --- a/trunk/arch/m68knommu/kernel/time.c +++ b/trunk/arch/m68knommu/kernel/time.c @@ -26,8 +26,6 @@ #define TICK_SIZE (tick_nsec / 1000) -extern unsigned long wall_jiffies; - static inline int set_rtc_mmss(unsigned long nowtime) { @@ -51,7 +49,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs) write_seqlock(&xtime_lock); - do_timer(regs); + do_timer(1); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -124,15 +122,12 @@ void time_init(void) void do_gettimeofday(struct timeval *tv) { unsigned long flags; - unsigned long lost, seq; + unsigned long 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 330f6abc7703..30750c54bdf5 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 SERIAL_RM9000 + select MIPS_RM9122 select SYS_HAS_CPU_RM9000 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL @@ -203,26 +203,6 @@ 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 @@ -974,6 +954,12 @@ 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 @@ -1024,6 +1010,15 @@ 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. @@ -1054,10 +1049,6 @@ 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 @@ -1527,6 +1518,7 @@ 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. @@ -1538,6 +1530,7 @@ 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. @@ -1649,9 +1642,7 @@ 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. @@ -1719,6 +1710,7 @@ 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 diff --git a/trunk/arch/mips/Makefile b/trunk/arch/mips/Makefile index d333ce4ba26b..e521826b4234 100644 --- a/trunk/arch/mips/Makefile +++ b/trunk/arch/mips/Makefile @@ -279,13 +279,6 @@ 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) # @@ -330,6 +323,7 @@ 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 7fbea1bf7b48..0a067f3113a5 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(regs); + do_timer(1); #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(regs); + do_timer(1); #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(regs); /* increment jiffies by one */ + do_timer(1); /* 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 4c7d763f2113..51d62bd5d900 100644 --- a/trunk/arch/mips/au1000/db1x00/Makefile +++ b/trunk/arch/mips/au1000/db1x00/Makefile @@ -6,4 +6,3 @@ # 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 deleted file mode 100644 index 0942dcf69518..000000000000 --- a/trunk/arch/mips/au1000/db1x00/mirage_ts.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * 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 bbb4ea43da88..cc1ce77eab4a 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 = { + excite_ctr_resource __attribute__((unused)) = { .name = "GPI counters", .start = 0, .end = 5, @@ -77,7 +77,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_gpislice_resource = { + excite_gpislice_resource __attribute__((unused)) = { .name = "GPI slices", .start = 0, .end = 1, @@ -86,7 +86,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_mdio_channel_resource = { + excite_mdio_channel_resource __attribute__((unused)) = { .name = "MDIO channels", .start = 0, .end = 1, @@ -95,7 +95,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_fifomem_resource = { + excite_fifomem_resource __attribute__((unused)) = { .name = "FIFO memory", .start = 0, .end = 767, @@ -104,7 +104,7 @@ static struct resource .sibling = NULL, .child = NULL }, - excite_scram_resource = { + excite_scram_resource __attribute__((unused)) = { .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 = { + excite_fpga_resource __attribute__((unused)) = { .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 = { + excite_nand_resource __attribute__((unused)) = { .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 = { + excite_titan_resource __attribute__((unused)) = { .name = "TITAN registers", .start = EXCITE_PHYS_TITAN, .end = EXCITE_PHYS_TITAN + EXCITE_SIZE_TITAN - 1, diff --git a/trunk/arch/mips/configs/atlas_defconfig b/trunk/arch/mips/configs/atlas_defconfig index 54274065e9a5..d3705284de39 100644 --- a/trunk/arch/mips/configs/atlas_defconfig +++ b/trunk/arch/mips/configs/atlas_defconfig @@ -25,7 +25,6 @@ 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 @@ -1193,7 +1192,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/bigsur_defconfig b/trunk/arch/mips/configs/bigsur_defconfig index 887fd959482a..e12a475dcbf4 100644 --- a/trunk/arch/mips/configs/bigsur_defconfig +++ b/trunk/arch/mips/configs/bigsur_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/capcella_defconfig b/trunk/arch/mips/configs/capcella_defconfig index a01344f3a4c2..bfade9abb767 100644 --- a/trunk/arch/mips/configs/capcella_defconfig +++ b/trunk/arch/mips/configs/capcella_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/cobalt_defconfig b/trunk/arch/mips/configs/cobalt_defconfig index c95682445a28..4baf2ff1128a 100644 --- a/trunk/arch/mips/configs/cobalt_defconfig +++ b/trunk/arch/mips/configs/cobalt_defconfig @@ -25,7 +25,6 @@ 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 @@ -828,7 +827,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/db1000_defconfig b/trunk/arch/mips/configs/db1000_defconfig index c2f33d3af62c..93cca1585bc3 100644 --- a/trunk/arch/mips/configs/db1000_defconfig +++ b/trunk/arch/mips/configs/db1000_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/db1100_defconfig b/trunk/arch/mips/configs/db1100_defconfig index 8c44d16ae9a2..ffd99252a837 100644 --- a/trunk/arch/mips/configs/db1100_defconfig +++ b/trunk/arch/mips/configs/db1100_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/db1200_defconfig b/trunk/arch/mips/configs/db1200_defconfig index c13768e75ac5..63eac5e89b9c 100644 --- a/trunk/arch/mips/configs/db1200_defconfig +++ b/trunk/arch/mips/configs/db1200_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/db1500_defconfig b/trunk/arch/mips/configs/db1500_defconfig index 8aea73fae7fb..25a095f7dc4e 100644 --- a/trunk/arch/mips/configs/db1500_defconfig +++ b/trunk/arch/mips/configs/db1500_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/db1550_defconfig b/trunk/arch/mips/configs/db1550_defconfig index 90ccb7359630..dda469c842b3 100644 --- a/trunk/arch/mips/configs/db1550_defconfig +++ b/trunk/arch/mips/configs/db1550_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/ddb5477_defconfig b/trunk/arch/mips/configs/ddb5477_defconfig index b598cf08f156..fcd3dd19bc74 100644 --- a/trunk/arch/mips/configs/ddb5477_defconfig +++ b/trunk/arch/mips/configs/ddb5477_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/decstation_defconfig b/trunk/arch/mips/configs/decstation_defconfig index 597150b14077..8683e0df12e0 100644 --- a/trunk/arch/mips/configs/decstation_defconfig +++ b/trunk/arch/mips/configs/decstation_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/e55_defconfig b/trunk/arch/mips/configs/e55_defconfig index fa2996bb4b7c..4ace61c95778 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-rc1 -# Thu Jul 6 10:04:02 2006 +# Linux kernel version: 2.6.18-rc2 +# Tue Jul 25 23:15:03 2006 # CONFIG_MIPS=y @@ -25,7 +25,6 @@ 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 @@ -227,7 +226,6 @@ CONFIG_MMU=y # # PCCARD (PCMCIA/CardBus) support # -# CONFIG_PCCARD is not set # # PCI Hotplug Support @@ -254,7 +252,6 @@ CONFIG_TRAD_SIGNALS=y # CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set # CONFIG_SYS_HYPERVISOR is not set # @@ -284,6 +281,7 @@ 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,6 +641,7 @@ 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 @@ -650,7 +649,7 @@ CONFIG_MSDOS_PARTITION=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="console=ttyVR0,19200 mem=8M" +CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x1f0,0x3f6,40 mem=8M" # # Security options diff --git a/trunk/arch/mips/configs/emma2rh_defconfig b/trunk/arch/mips/configs/emma2rh_defconfig index 375b2ac24a49..5847c916c130 100644 --- a/trunk/arch/mips/configs/emma2rh_defconfig +++ b/trunk/arch/mips/configs/emma2rh_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/ev64120_defconfig b/trunk/arch/mips/configs/ev64120_defconfig index b0afc118bd5c..bc4c4f125c48 100644 --- a/trunk/arch/mips/configs/ev64120_defconfig +++ b/trunk/arch/mips/configs/ev64120_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/excite_defconfig b/trunk/arch/mips/configs/excite_defconfig index 045ebd089893..eb87cbbfd037 100644 --- a/trunk/arch/mips/configs/excite_defconfig +++ b/trunk/arch/mips/configs/excite_defconfig @@ -26,7 +26,6 @@ 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 diff --git a/trunk/arch/mips/configs/ip22_defconfig b/trunk/arch/mips/configs/ip22_defconfig index ef16d1fb5071..cc9b24eda9e8 100644 --- a/trunk/arch/mips/configs/ip22_defconfig +++ b/trunk/arch/mips/configs/ip22_defconfig @@ -25,7 +25,6 @@ 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 @@ -1013,7 +1012,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/ip27_defconfig b/trunk/arch/mips/configs/ip27_defconfig index 4bf1ee7f5f00..50092ba8aa71 100644 --- a/trunk/arch/mips/configs/ip27_defconfig +++ b/trunk/arch/mips/configs/ip27_defconfig @@ -25,7 +25,6 @@ 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 @@ -900,7 +899,7 @@ CONFIG_FUSE_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/ip32_defconfig b/trunk/arch/mips/configs/ip32_defconfig index f83dc09c3ca9..dec2ba6ba03f 100644 --- a/trunk/arch/mips/configs/ip32_defconfig +++ b/trunk/arch/mips/configs/ip32_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/it8172_defconfig b/trunk/arch/mips/configs/it8172_defconfig index a91d72a9ca86..37f9dd7187b1 100644 --- a/trunk/arch/mips/configs/it8172_defconfig +++ b/trunk/arch/mips/configs/it8172_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/ivr_defconfig b/trunk/arch/mips/configs/ivr_defconfig index cebc67212d06..18874a4c24fe 100644 --- a/trunk/arch/mips/configs/ivr_defconfig +++ b/trunk/arch/mips/configs/ivr_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/jaguar-atx_defconfig b/trunk/arch/mips/configs/jaguar-atx_defconfig index 5d9eb11aba3d..9f1e3048d623 100644 --- a/trunk/arch/mips/configs/jaguar-atx_defconfig +++ b/trunk/arch/mips/configs/jaguar-atx_defconfig @@ -25,7 +25,6 @@ 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 @@ -731,7 +730,7 @@ CONFIG_FUSE_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y diff --git a/trunk/arch/mips/configs/jmr3927_defconfig b/trunk/arch/mips/configs/jmr3927_defconfig index be45a9044d06..fded3f73815f 100644 --- a/trunk/arch/mips/configs/jmr3927_defconfig +++ b/trunk/arch/mips/configs/jmr3927_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/lasat200_defconfig b/trunk/arch/mips/configs/lasat200_defconfig index 64dc9f45a19c..320b8cdd6e58 100644 --- a/trunk/arch/mips/configs/lasat200_defconfig +++ b/trunk/arch/mips/configs/lasat200_defconfig @@ -25,7 +25,6 @@ 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 @@ -905,7 +904,7 @@ CONFIG_FUSE_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/malta_defconfig b/trunk/arch/mips/configs/malta_defconfig index 2690baf15a85..0ba1ef5048fb 100644 --- a/trunk/arch/mips/configs/malta_defconfig +++ b/trunk/arch/mips/configs/malta_defconfig @@ -25,7 +25,6 @@ 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 @@ -1230,7 +1229,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/mipssim_defconfig b/trunk/arch/mips/configs/mipssim_defconfig index c298979c18ae..adbeeadddb8f 100644 --- a/trunk/arch/mips/configs/mipssim_defconfig +++ b/trunk/arch/mips/configs/mipssim_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/mpc30x_defconfig b/trunk/arch/mips/configs/mpc30x_defconfig index 938b38ab5239..79fd544fcb2a 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-rc1 -# Thu Jul 6 10:04:15 2006 +# Linux kernel version: 2.6.18-rc2 +# Tue Jul 25 23:16:46 2006 # CONFIG_MIPS=y @@ -25,7 +25,6 @@ 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 @@ -71,7 +70,6 @@ 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 @@ -168,6 +166,7 @@ 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 @@ -841,7 +840,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_CY7C63 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 @@ -982,7 +981,6 @@ 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,6 +1005,7 @@ 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 @@ -1014,7 +1013,7 @@ CONFIG_MSDOS_PARTITION=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="mem=32M console=ttyVR0,19200" +CONFIG_CMDLINE="mem=32M console=ttyVR0,19200 ide0=0x170,0x376,73" # # Security options diff --git a/trunk/arch/mips/configs/ocelot_3_defconfig b/trunk/arch/mips/configs/ocelot_3_defconfig index ec5758f22676..4d87da2b99fd 100644 --- a/trunk/arch/mips/configs/ocelot_3_defconfig +++ b/trunk/arch/mips/configs/ocelot_3_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/ocelot_c_defconfig b/trunk/arch/mips/configs/ocelot_c_defconfig index 0d33d87de1a1..a7ac2b0a8273 100644 --- a/trunk/arch/mips/configs/ocelot_c_defconfig +++ b/trunk/arch/mips/configs/ocelot_c_defconfig @@ -25,7 +25,6 @@ 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 @@ -774,7 +773,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/ocelot_defconfig b/trunk/arch/mips/configs/ocelot_defconfig index 4b999102715e..853e7bba5122 100644 --- a/trunk/arch/mips/configs/ocelot_defconfig +++ b/trunk/arch/mips/configs/ocelot_defconfig @@ -25,7 +25,6 @@ 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 @@ -723,7 +722,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/ocelot_g_defconfig b/trunk/arch/mips/configs/ocelot_g_defconfig index 827b344f6010..8524efa23a49 100644 --- a/trunk/arch/mips/configs/ocelot_g_defconfig +++ b/trunk/arch/mips/configs/ocelot_g_defconfig @@ -25,7 +25,6 @@ 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 @@ -777,7 +776,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/pb1100_defconfig b/trunk/arch/mips/configs/pb1100_defconfig index 9ed60fef69e0..1a16e92900cb 100644 --- a/trunk/arch/mips/configs/pb1100_defconfig +++ b/trunk/arch/mips/configs/pb1100_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/pb1500_defconfig b/trunk/arch/mips/configs/pb1500_defconfig index 6774254b1be6..9ea8edea6f29 100644 --- a/trunk/arch/mips/configs/pb1500_defconfig +++ b/trunk/arch/mips/configs/pb1500_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/pb1550_defconfig b/trunk/arch/mips/configs/pb1550_defconfig index 1afe5bf6e765..c4a158976f8f 100644 --- a/trunk/arch/mips/configs/pb1550_defconfig +++ b/trunk/arch/mips/configs/pb1550_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/pnx8550-jbs_defconfig b/trunk/arch/mips/configs/pnx8550-jbs_defconfig index ac616c82d348..1cbf270c301c 100644 --- a/trunk/arch/mips/configs/pnx8550-jbs_defconfig +++ b/trunk/arch/mips/configs/pnx8550-jbs_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/pnx8550-v2pci_defconfig b/trunk/arch/mips/configs/pnx8550-v2pci_defconfig index a8eb51bae3f3..bec30b15b9bd 100644 --- a/trunk/arch/mips/configs/pnx8550-v2pci_defconfig +++ b/trunk/arch/mips/configs/pnx8550-v2pci_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/qemu_defconfig b/trunk/arch/mips/configs/qemu_defconfig index 6a63a113b7ea..f5f799e93707 100644 --- a/trunk/arch/mips/configs/qemu_defconfig +++ b/trunk/arch/mips/configs/qemu_defconfig @@ -25,7 +25,6 @@ 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 @@ -687,7 +686,7 @@ CONFIG_FUSE_FS=y CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y diff --git a/trunk/arch/mips/configs/rbhma4500_defconfig b/trunk/arch/mips/configs/rbhma4500_defconfig index 6779f449bd2d..2f5650227ba3 100644 --- a/trunk/arch/mips/configs/rbhma4500_defconfig +++ b/trunk/arch/mips/configs/rbhma4500_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/rm200_defconfig b/trunk/arch/mips/configs/rm200_defconfig index b7826d3a2b77..4fee90b2b100 100644 --- a/trunk/arch/mips/configs/rm200_defconfig +++ b/trunk/arch/mips/configs/rm200_defconfig @@ -25,7 +25,6 @@ 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 @@ -1442,7 +1441,7 @@ CONFIG_NTFS_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/configs/sb1250-swarm_defconfig b/trunk/arch/mips/configs/sb1250-swarm_defconfig index 625c1c619b6b..9041f095f96f 100644 --- a/trunk/arch/mips/configs/sb1250-swarm_defconfig +++ b/trunk/arch/mips/configs/sb1250-swarm_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/sead_defconfig b/trunk/arch/mips/configs/sead_defconfig index 4401b602118f..02abb2f1bfaf 100644 --- a/trunk/arch/mips/configs/sead_defconfig +++ b/trunk/arch/mips/configs/sead_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/tb0226_defconfig b/trunk/arch/mips/configs/tb0226_defconfig index 2ba4e25e8c34..ca3d0c4ba15b 100644 --- a/trunk/arch/mips/configs/tb0226_defconfig +++ b/trunk/arch/mips/configs/tb0226_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/tb0229_defconfig b/trunk/arch/mips/configs/tb0229_defconfig index fc8a407c1add..4e2009ace278 100644 --- a/trunk/arch/mips/configs/tb0229_defconfig +++ b/trunk/arch/mips/configs/tb0229_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/tb0287_defconfig b/trunk/arch/mips/configs/tb0287_defconfig index effcb63b81a3..535a813d01a9 100644 --- a/trunk/arch/mips/configs/tb0287_defconfig +++ b/trunk/arch/mips/configs/tb0287_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/workpad_defconfig b/trunk/arch/mips/configs/workpad_defconfig index 4891d02ef8ca..3a3ef20b21cc 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-rc1 -# Thu Jul 6 10:04:21 2006 +# Linux kernel version: 2.6.18-rc2 +# Tue Jul 25 23:13:04 2006 # CONFIG_MIPS=y @@ -25,7 +25,6 @@ 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 @@ -166,6 +165,7 @@ 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 @@ -379,6 +379,7 @@ 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 @@ -855,7 +856,6 @@ 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 @@ -880,6 +880,7 @@ 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 @@ -887,7 +888,7 @@ CONFIG_MSDOS_PARTITION=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DEBUG_FS is not set CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="console=ttyVR0,19200 mem=16M" +CONFIG_CMDLINE="console=ttyVR0,19200 ide0=0x170,0x376,49 mem=16M" # # Security options diff --git a/trunk/arch/mips/configs/wrppmc_defconfig b/trunk/arch/mips/configs/wrppmc_defconfig index 3e4b16b39827..e6b1dea55842 100644 --- a/trunk/arch/mips/configs/wrppmc_defconfig +++ b/trunk/arch/mips/configs/wrppmc_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/configs/yosemite_defconfig b/trunk/arch/mips/configs/yosemite_defconfig index 3a68d8a25b66..06a072b77b1c 100644 --- a/trunk/arch/mips/configs/yosemite_defconfig +++ b/trunk/arch/mips/configs/yosemite_defconfig @@ -25,7 +25,6 @@ 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 diff --git a/trunk/arch/mips/defconfig b/trunk/arch/mips/defconfig index fff6fcc96212..cc9b24eda9e8 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 09:49:33 2006 +# Thu Jul 6 10:04:10 2006 # CONFIG_MIPS=y @@ -25,7 +25,6 @@ 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 @@ -1013,7 +1012,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_CONFIGFS_FS is not set diff --git a/trunk/arch/mips/galileo-boards/ev96100/Makefile b/trunk/arch/mips/galileo-boards/ev96100/Makefile deleted file mode 100644 index cd868ec78cbc..000000000000 --- a/trunk/arch/mips/galileo-boards/ev96100/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# -# 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 deleted file mode 100644 index a01fe9b36f2c..000000000000 --- a/trunk/arch/mips/galileo-boards/ev96100/init.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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 deleted file mode 100644 index ee5d6720f23b..000000000000 --- a/trunk/arch/mips/galileo-boards/ev96100/irq.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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 deleted file mode 100644 index 49dc6d137b9c..000000000000 --- a/trunk/arch/mips/galileo-boards/ev96100/puts.c +++ /dev/null @@ -1,138 +0,0 @@ - -/* - * 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 deleted file mode 100644 index 5ef9b7f896e6..000000000000 --- a/trunk/arch/mips/galileo-boards/ev96100/reset.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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 deleted file mode 100644 index 639ad5562c63..000000000000 --- a/trunk/arch/mips/galileo-boards/ev96100/setup.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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 deleted file mode 100644 index 8cbe8426491a..000000000000 --- a/trunk/arch/mips/galileo-boards/ev96100/time.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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 d837b26fbe51..7feca49350d1 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(regs); + do_timer(1); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif diff --git a/trunk/arch/mips/kernel/cpu-probe.c b/trunk/arch/mips/kernel/cpu-probe.c index aa2caa67299a..9fbf8430c849 100644 --- a/trunk/arch/mips/kernel/cpu-probe.c +++ b/trunk/arch/mips/kernel/cpu-probe.c @@ -38,15 +38,40 @@ static void r3081_wait(void) static void r39xx_wait(void) { - unsigned long cfg = read_c0_conf(); - write_c0_conf(cfg | TX39_CONF_HALT); + local_irq_disable(); + if (!need_resched()) + write_c0_conf(read_c0_conf() | TX39_CONF_HALT); + local_irq_enable(); } +/* + * 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\tmips3\n\t" - "wait\n\t" - ".set\tmips0"); + __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(); } /* The Au1xxx wait is available only if using 32khz counter or @@ -56,17 +81,17 @@ int allow_au1k_wait; static void au1k_wait(void) { /* using the wait instruction makes CP0 counter unusable */ - __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" + __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" : : "r" (au1k_wait)); } @@ -111,7 +136,6 @@ 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: @@ -125,6 +149,10 @@ 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/irixsig.c b/trunk/arch/mips/kernel/irixsig.c index 676e868d26fb..2132485caa74 100644 --- a/trunk/arch/mips/kernel/irixsig.c +++ b/trunk/arch/mips/kernel/irixsig.c @@ -17,6 +17,7 @@ #include #include +#include #undef DEBUG_SIG @@ -172,11 +173,12 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info, return ret; } -asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) +void do_irix_signal(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 @@ -184,19 +186,28 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) * if so. */ if (!user_mode(regs)) - return 1; + return; - if (try_to_freeze()) - goto no_signal; - - if (!oldset) + 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) - return handle_signal(signr, &info, &ka, oldset, regs); + 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; + } -no_signal: /* * Who's code doesn't conform to the restartable syscall convention * dies here!!! The li instruction, a single machine instruction, @@ -208,8 +219,22 @@ asmlinkage int do_irix_signal(sigset_t *oldset, 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 @@ -298,6 +323,9 @@ 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) { @@ -413,7 +441,7 @@ asmlinkage int irix_sigprocmask(int how, irix_sigset_t __user *new, asmlinkage int irix_sigsuspend(struct pt_regs *regs) { - sigset_t saveset, newset; + sigset_t newset; sigset_t __user *uset; uset = (sigset_t __user *) regs->regs[4]; @@ -422,18 +450,15 @@ asmlinkage int irix_sigsuspend(struct pt_regs *regs) sigdelsetmask(&newset, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); - saveset = current->blocked; + current->saved_sigmask = current->blocked; current->blocked = newset; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - regs->regs[2] = -EINTR; - while (1) { - current->state = TASK_INTERRUPTIBLE; - schedule(); - if (do_irix_signal(&saveset, regs)) - return -EINTR; - } + current->state = TASK_INTERRUPTIBLE; + schedule(); + set_thread_flag(TIF_RESTORE_SIGMASK); + return -ERESTARTNOHAND; } /* hate hate hate... */ diff --git a/trunk/arch/mips/kernel/linux32.c b/trunk/arch/mips/kernel/linux32.c index 450ac592da57..43b1162d714f 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 +#ifdef CONFIG_SYSCTL_SYSCALL asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args) { @@ -1032,7 +1032,7 @@ asmlinkage long sys32_sysctl(struct sysctl_args32 __user *args) return error; } -#endif /* CONFIG_SYSCTL */ +#endif /* CONFIG_SYSCTL_SYSCALL */ asmlinkage long sys32_newuname(struct new_utsname __user * name) { @@ -1296,9 +1296,3 @@ _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 7ab67f786bfe..2613a0dd4b82 100644 --- a/trunk/arch/mips/kernel/process.c +++ b/trunk/arch/mips/kernel/process.c @@ -273,104 +273,107 @@ long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); } -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 __init get_frame_info(struct mips_frame_info *info) +/* + * + */ +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) { - int i; - void *func = info->func; - union mips_instruction *ip = (union mips_instruction *)func; + /* 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 int 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; + 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 (info->func_size && i >= info->func_size / 4) + 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)) break; - 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->frame_size) { + if (is_sp_move_ins(ip)) + info->frame_size = - ip->i_format.simmediate; + continue; } - - 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; + if (info->pc_offset == -1 && is_ra_save_ins(ip)) { info->pc_offset = ip->i_format.simmediate / sizeof(long); + break; } } - 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; - } - - return 0; + 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; } +static struct mips_frame_info schedule_mfi __read_mostly; + static int __init frame_info_init(void) { - int i; + unsigned long size = 0; #ifdef CONFIG_KALLSYMS + unsigned long ofs; char *modname; char namebuf[KSYM_NAME_LEN + 1]; - 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]; + + kallsyms_lookup((unsigned long)schedule, &size, &ofs, &modname, namebuf); #endif - for (i = 0; i < ARRAY_SIZE(mfinfo) && mfinfo[i].func; i++) - get_frame_info(&mfinfo[i]); + 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); - mfinfo_num = i; return 0; } @@ -386,54 +389,86 @@ 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_frame || schedule_frame->pc_offset < 0) + if (schedule_mfi.pc_offset < 0) return 0; - return ((unsigned long *)t->reg29)[schedule_frame->pc_offset]; + return ((unsigned long *)t->reg29)[schedule_mfi.pc_offset]; } -/* get_wchan - a maintenance nightmare^W^Wpain in the ass ... */ -unsigned long get_wchan(struct task_struct *p) + +#ifdef CONFIG_KALLSYMS +/* used by show_backtrace() */ +unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, + unsigned long pc, unsigned long ra) { unsigned long stack_page; - unsigned long pc; -#ifdef CONFIG_KALLSYMS - unsigned long frame; -#endif + struct mips_frame_info info; + char *modname; + char namebuf[KSYM_NAME_LEN + 1]; + unsigned long size, ofs; + int leaf; - if (!p || p == current || p->state == TASK_RUNNING) + stack_page = (unsigned long)task_stack_page(task); + if (!stack_page) return 0; - stack_page = (unsigned long)task_stack_page(p); - if (!stack_page || !mfinfo_num) + if (!kallsyms_lookup(pc, &size, &ofs, &modname, namebuf)) + return 0; + /* + * Return ra if an exception occured at the first instruction + */ + if (unlikely(ofs == 0)) + return ra; + + info.func = (void *)(pc - ofs); + info.func_size = ofs; /* analyze from start to ofs */ + leaf = get_frame_info(&info); + if (leaf < 0) + return 0; + + if (*sp < stack_page || + *sp + info.frame_size > stack_page + THREAD_SIZE - 32) return 0; - pc = thread_saved_pc(p); + 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; + 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; #ifdef CONFIG_KALLSYMS - if (!in_sched_functions(pc)) - return pc; + unsigned long sp; +#endif - frame = p->thread.reg29 + schedule_frame->frame_size; - do { - int i; + if (!task || task == current || task->state == TASK_RUNNING) + goto out; + if (!task_stack_page(task)) + goto out; - if (frame < stack_page || frame > stack_page + THREAD_SIZE - 32) - return 0; + pc = thread_saved_pc(task); - for (i = mfinfo_num - 1; i >= 0; i--) { - if (pc >= (unsigned long) mfinfo[i].func) - break; - } - if (i < 0) - break; +#ifdef CONFIG_KALLSYMS + sp = task->thread.reg29 + schedule_mfi.frame_size; - pc = ((unsigned long *)frame)[mfinfo[i].pc_offset]; - if (!mfinfo[i].frame_size) - break; - frame += mfinfo[i].frame_size; - } while (in_sched_functions(pc)); + while (in_sched_functions(pc)) + pc = unwind_stack(task, &sp, pc, 0); #endif +out: return pc; } - diff --git a/trunk/arch/mips/kernel/scall32-o32.S b/trunk/arch/mips/kernel/scall32-o32.S index ba1bcd83c7d3..e71785102206 100644 --- a/trunk/arch/mips/kernel/scall32-o32.S +++ b/trunk/arch/mips/kernel/scall32-o32.S @@ -662,6 +662,8 @@ 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 939e172db953..4c22d0b4825d 100644 --- a/trunk/arch/mips/kernel/scall64-64.S +++ b/trunk/arch/mips/kernel/scall64-64.S @@ -466,3 +466,5 @@ 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 98abbc5a9f13..f25c2a2f1038 100644 --- a/trunk/arch/mips/kernel/scall64-n32.S +++ b/trunk/arch/mips/kernel/scall64-n32.S @@ -247,7 +247,7 @@ EXPORT(sysn32_call_table) PTR sys_capset PTR sys32_rt_sigpending /* 6125 */ PTR compat_sys_rt_sigtimedwait - PTR sys_rt_sigqueueinfo + PTR sys32_rt_sigqueueinfo PTR sysn32_rt_sigsuspend PTR sys32_sigaltstack PTR compat_sys_utime /* 6130 */ @@ -390,5 +390,7 @@ EXPORT(sysn32_call_table) PTR sys_splice PTR sys_sync_file_range PTR sys_tee - PTR sys_vmsplice /* 6271 */ + PTR sys_vmsplice /* 6270 */ 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 505c9ee54009..288ee4ac4dbb 100644 --- a/trunk/arch/mips/kernel/scall64-o32.S +++ b/trunk/arch/mips/kernel/scall64-o32.S @@ -498,7 +498,7 @@ sys_call_table: PTR sys_mknodat /* 4290 */ PTR sys_fchownat PTR compat_sys_futimesat - PTR compat_sys_newfstatat + PTR sys_newfstatat PTR sys_unlinkat PTR sys_renameat /* 4295 */ PTR sys_linkat @@ -514,4 +514,6 @@ 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 8c2b596a136f..fdbb508661c5 100644 --- a/trunk/arch/mips/kernel/setup.c +++ b/trunk/arch/mips/kernel/setup.c @@ -10,29 +10,15 @@ * 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 @@ -96,6 +82,12 @@ 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. @@ -143,167 +135,132 @@ static void __init print_memory_map(void) } } -static inline void parse_cmdline_early(void) +/* + * Manage initrd + */ +#ifdef CONFIG_BLK_DEV_INITRD + +static int __init rd_start_early(char *p) { - char c = ' ', *to = command_line, *from = saved_command_line; - unsigned long start_at, mem_size; - int len = 0; - int usermem = 0; + unsigned long start = memparse(p, &p); - printk("Determined physical RAM map:\n"); - print_memory_map(); +#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; - 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; +} +early_param("rd_start", rd_start_early); - if (usermem) { - printk("User-defined physical RAM map:\n"); - print_memory_map(); - } +static int __init rd_size_early(char *p) +{ + initrd_end += memparse(p, &p); + + return 0; } +early_param("rd_size", rd_size_early); -static inline int parse_rd_cmdline(unsigned long* rd_start, unsigned long* rd_end) +static unsigned long __init init_initrd(void) { + unsigned long tmp, end, size; + u32 *initrd_header; + + ROOT_DEV = Root_RAM0; + /* - * "rd_start=0xNNNNNNNN" defines the memory address of an initrd - * "rd_size=0xNN" it's size + * 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. */ - 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="); + 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]; } - 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="); + 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); -#ifdef CONFIG_64BIT - /* HACK: Guess if the sign extension was forgotten */ - if (start > 0x0000000080000000 && start < 0x00000000ffffffff) - start |= 0xffffffff00000000UL; + 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) + #endif - end = start + size; - if (start && end) { - *rd_start = start; - *rd_end = end; - return 1; - } - return 0; +/* + * 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(); } -#define MAXMEM HIGHMEM_START -#define MAXMEM_PFN PFN_DOWN(MAXMEM) +#else /* !CONFIG_SGI_IP27 */ -static inline void bootmem_init(void) +static void __init bootmem_init(void) { - unsigned long start_pfn; - unsigned long reserved_end = (unsigned long)&_end; -#ifndef CONFIG_SGI_IP27 - unsigned long first_usable_pfn; + unsigned long reserved_end; + unsigned long highest = 0; + unsigned long mapstart = -1UL; 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 */ /* - * Partially used pages are not usable - thus - * we are rounding upwards. + * 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. */ - start_pfn = PFN_UP(CPHYSADDR(reserved_end)); + reserved_end = init_initrd(); + reserved_end = PFN_UP(CPHYSADDR(max(reserved_end, (unsigned long)&_end))); -#ifndef CONFIG_SGI_IP27 - /* Find the highest page frame number we have available. */ - max_pfn = 0; - first_usable_pfn = -1UL; + /* + * Find the highest page frame number we have available. + */ for (i = 0; i < boot_mem_map.nr_map; i++) { unsigned long start, end; @@ -312,56 +269,38 @@ static inline void 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 (start >= end) + if (end > highest) + highest = end; + if (end <= reserved_end) continue; - 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; - } - } + if (start >= mapstart) + continue; + mapstart = max(reserved_end, start); } /* * Determine low and high memory ranges */ - 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"); + if (highest > PFN_DOWN(HIGHMEM_START)) { +#ifdef CONFIG_HIGHMEM + highstart_pfn = PFN_DOWN(HIGHMEM_START); + highend_pfn = highest; #endif + highest = PFN_DOWN(HIGHMEM_START); } -#ifdef CONFIG_HIGHMEM /* - * Crude, we really should make a better attempt at detecting - * highstart_pfn + * Initialize the boot-time allocator with low memory only. */ - 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); + bootmap_size = init_bootmem(mapstart, highest); /* * Register fully available low RAM pages with the bootmem allocator. */ for (i = 0; i < boot_mem_map.nr_map; i++) { - unsigned long curr_pfn, last_pfn, size; + unsigned long start, end, size; /* * Reserve usable memory. @@ -369,85 +308,50 @@ static inline void bootmem_init(void) if (boot_mem_map.map[i].type != BOOT_MEM_RAM) continue; - /* - * 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 + start = PFN_UP(boot_mem_map.map[i].addr); + end = 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; - /* - * Only register lowmem part of lowmem segment with bootmem. + * We are rounding up the start address of usable memory + * and at the end of the usable range downwards. */ - 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) + if (start >= max_low_pfn) continue; + if (start < reserved_end) + start = reserved_end; + if (end > max_low_pfn) + end = max_low_pfn; /* - * ... finally, did all the rounding and playing - * around just make the area go away? + * ... finally, is the area going away? */ - if (last_pfn <= curr_pfn) + if (end <= start) continue; + size = end - start; /* Register lowmem ranges */ - free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); - memory_present(0, curr_pfn, curr_pfn + size - 1); + free_bootmem(PFN_PHYS(start), size << PAGE_SHIFT); + memory_present(0, start, end); } - /* Reserve the bootmap memory. */ - reserve_bootmem(PFN_PHYS(first_usable_pfn), bootmap_size); -#endif /* CONFIG_SGI_IP27 */ - -#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; - } + /* + * Reserve the bootmap memory. + */ + reserve_bootmem(PFN_PHYS(mapstart), bootmap_size); - if (initrd_reserve_bootmem) - reserve_bootmem(CPHYSADDR(initrd_start), initrd_size); - } -#endif /* CONFIG_BLK_DEV_INITRD */ + /* + * Reserve initrd memory if needed. + */ + finalize_initrd(); } +#endif /* CONFIG_SGI_IP27 */ + /* * 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. @@ -465,25 +369,59 @@ static inline void bootmem_init(void) * initialization hook for anything else was introduced. */ -extern void plat_mem_setup(void); +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); 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_cmdline_early(); + parse_early_param(); + + if (usermem) { + printk("User-defined physical RAM map:\n"); + print_memory_map(); + } + bootmem_init(); sparse_init(); paging_init(); } -static inline void resource_init(void) +static void __init resource_init(void) { int i; @@ -504,10 +442,10 @@ static inline void 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 >= MAXMEM) + if (start >= HIGHMEM_START) continue; - if (end >= MAXMEM) - end = MAXMEM - 1; + if (end >= HIGHMEM_START) + end = HIGHMEM_START - 1; res = alloc_bootmem(sizeof(struct resource)); switch (boot_mem_map.map[i].type) { @@ -536,9 +474,6 @@ static inline void 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 6b4d9be31615..b9d358e05214 100644 --- a/trunk/arch/mips/kernel/signal.c +++ b/trunk/arch/mips/kernel/signal.c @@ -424,15 +424,11 @@ 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. */ @@ -446,9 +442,10 @@ 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, @@ -466,6 +463,7 @@ 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 f32a22997c3d..c86a5ddff050 100644 --- a/trunk/arch/mips/kernel/signal32.c +++ b/trunk/arch/mips/kernel/signal32.c @@ -815,9 +815,6 @@ 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 @@ -836,9 +833,10 @@ 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, @@ -856,6 +854,7 @@ 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/signal_n32.c b/trunk/arch/mips/kernel/signal_n32.c index 477c5334ec1b..50c17eaa7f25 100644 --- a/trunk/arch/mips/kernel/signal_n32.c +++ b/trunk/arch/mips/kernel/signal_n32.c @@ -42,6 +42,8 @@ #include "signal-common.h" +extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat); + /* * Including would give use the 64-bit syscall numbers ... */ @@ -81,8 +83,6 @@ struct rt_sigframe_n32 { #endif }; -extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat); - save_static_function(sysn32_rt_sigsuspend); __attribute_used__ noinline static int _sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) diff --git a/trunk/arch/mips/kernel/smp-mt.c b/trunk/arch/mips/kernel/smp-mt.c index 93429a4d3012..766253c44f3f 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(read_vpe_c0_cause() & ~(C_SW1|C_SW0)); + write_vpe_c0_cause(0); /* 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 4cc3dea36612..76cb31d57482 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/syscall.c b/trunk/arch/mips/kernel/syscall.c index 0721314db657..9951240cc3fd 100644 --- a/trunk/arch/mips/kernel/syscall.c +++ b/trunk/arch/mips/kernel/syscall.c @@ -263,7 +263,7 @@ asmlinkage int sys_olduname(struct oldold_utsname __user * name) return error; } -void sys_set_thread_area(unsigned long addr) +asmlinkage int sys_set_thread_area(unsigned long addr) { struct thread_info *ti = task_thread_info(current); @@ -271,6 +271,8 @@ void 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) diff --git a/trunk/arch/mips/kernel/time.c b/trunk/arch/mips/kernel/time.c index 170cb67f4ede..845c7e55505d 100644 --- a/trunk/arch/mips/kernel/time.c +++ b/trunk/arch/mips/kernel/time.c @@ -47,8 +47,6 @@ /* * forward reference */ -extern volatile unsigned long wall_jiffies; - DEFINE_SPINLOCK(rtc_lock); /* @@ -159,7 +157,6 @@ 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; @@ -168,8 +165,6 @@ 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. @@ -178,11 +173,7 @@ 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); @@ -217,7 +208,6 @@ 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); @@ -434,7 +424,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* * call the generic timer interrupt handling */ - do_timer(regs); + do_timer(1); /* * 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 954a198494ef..e51d8fd9a152 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -72,28 +73,68 @@ void (*board_nmi_handler_setup)(void); void (*board_ejtag_handler_setup)(void); void (*board_bind_eic_interrupt)(int irq, int regset); -/* - * 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) + +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 +static 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); + +extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, + unsigned long pc, unsigned long ra); + +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); + ra = 0; + } while (pc); + printk("\n"); +} +#else +#define show_backtrace(task, r) show_raw_backtrace((r)->regs[29]); +#endif /* * This routine abuses get_user()/put_user() to reference pointers * with at least a bit of error checking ... */ -void show_stack(struct task_struct *task, unsigned long *sp) +static void show_stacktrace(struct task_struct *task, struct pt_regs *regs) { const int field = 2 * sizeof(unsigned long); long stackdata; int i; - - if (!sp) { - if (task && task != current) - sp = (unsigned long *) task->thread.reg29; - else - sp = (unsigned long *) &sp; - } + unsigned long *sp = (unsigned long *)regs->regs[29]; printk("Stack :"); i = 0; @@ -114,32 +155,48 @@ void show_stack(struct task_struct *task, unsigned long *sp) i++; } printk("\n"); + show_backtrace(task, regs); } -void show_trace(struct task_struct *task, unsigned long *stack) +static __always_inline void prepare_frametrace(struct pt_regs *regs) { - 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"); + __asm__ __volatile__( + ".set push\n\t" + ".set noat\n\t" +#ifdef CONFIG_64BIT + "1: dla $1, 1b\n\t" + "sd $1, %0\n\t" + "sd $29, %1\n\t" + "sd $31, %2\n\t" +#else + "1: la $1, 1b\n\t" + "sw $1, %0\n\t" + "sw $29, %1\n\t" + "sw $31, %2\n\t" #endif - while (!kstack_end(stack)) { - addr = *stack++; - if (__kernel_text_address(addr)) { - printk(" [<%0*lx>] ", field, addr); - print_symbol("%s\n", addr); + ".set pop\n\t" + : "=m" (regs->cp0_epc), + "=m" (regs->regs[29]), "=m" (regs->regs[31]) + : : "memory"); +} + +void show_stack(struct task_struct *task, unsigned long *sp) +{ + 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); } } - printk("\n"); + show_stacktrace(task, ®s); } /* @@ -147,9 +204,15 @@ void show_trace(struct task_struct *task, unsigned long *stack) */ void dump_stack(void) { - unsigned long stack; + struct pt_regs regs; - show_trace(current, &stack); + /* + * Remove any garbage that may be in regs (specially func + * addresses) to avoid show_raw_backtrace() to report them + */ + memset(®s, 0, sizeof(regs)); + prepare_frametrace(®s); + show_backtrace(current, ®s); } EXPORT_SYMBOL(dump_stack); @@ -268,8 +331,7 @@ 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_stack(current, (long *) regs->regs[29]); - show_trace(current, (long *) regs->regs[29]); + show_stacktrace(current, regs); show_code((unsigned int *) regs->cp0_epc); printk("\n"); } @@ -292,6 +354,16 @@ 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 9ee0ec2cd067..51ddd2166898 100644 --- a/trunk/arch/mips/kernel/vpe.c +++ b/trunk/arch/mips/kernel/vpe.c @@ -768,10 +768,16 @@ 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 fb25e0377f11..a020a3cb4f4b 100644 --- a/trunk/arch/mips/mips-boards/atlas/atlas_int.c +++ b/trunk/arch/mips/mips-boards/atlas/atlas_int.c @@ -1,6 +1,8 @@ /* - * Carsten Langgaard, carstenl@mips.com - * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. + * Copyright (C) 1999, 2000, 2006 MIPS Technologies, Inc. + * All rights reserved. + * Authors: Carsten Langgaard + * Maciej W. Rozycki * * ######################################################################## * @@ -25,17 +27,20 @@ */ #include #include +#include #include #include #include #include -#include +#include #include +#include +#include + #include #include -#include - +#include static struct atlas_ictrl_regs *atlas_hw0_icregs; @@ -47,13 +52,13 @@ static struct atlas_ictrl_regs *atlas_hw0_icregs; void disable_atlas_irq(unsigned int irq_nr) { - atlas_hw0_icregs->intrsten = (1 << (irq_nr-ATLASINT_BASE)); + atlas_hw0_icregs->intrsten = 1 << (irq_nr - ATLAS_INT_BASE); iob(); } void enable_atlas_irq(unsigned int irq_nr) { - atlas_hw0_icregs->intseten = (1 << (irq_nr-ATLASINT_BASE)); + atlas_hw0_icregs->intseten = 1 << (irq_nr - ATLAS_INT_BASE); iob(); } @@ -107,7 +112,7 @@ static inline void atlas_hw0_irqdispatch(struct pt_regs *regs) if (unlikely(int_status == 0)) return; - irq = ATLASINT_BASE + ls1bit32(int_status); + irq = ATLAS_INT_BASE + ls1bit32(int_status); DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq); @@ -161,15 +166,14 @@ static inline unsigned int irq_ffs(unsigned int pending) } /* - * 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: + * IRQs on the Atlas board look basically like (all external interrupt + * sources are combined together on hardware interrupt 0 (MIPS IRQ 2)): * - * MIPS IRQ Source + * MIPS IRQ Source * -------- ------ - * 0 Software (ignored) - * 1 Software (ignored) - * 2 Combined hardware interrupt (hw0) + * 0 Software 0 (reschedule IPI on MT) + * 1 Software 1 (remote call IPI on MT) + * 2 Combined Atlas hardware interrupt (hw0) * 3 Hardware (ignored) * 4 Hardware (ignored) * 5 Hardware (ignored) @@ -179,7 +183,7 @@ static inline unsigned int irq_ffs(unsigned int pending) * We handle the IRQ according to _our_ priority which is: * * Highest ---- R4k Timer - * Lowest ---- Combined hardware interrupt + * Lowest ---- Software 0 * * then we just return, if multiple IRQs are pending then we will just take * another exception, big deal. @@ -193,17 +197,19 @@ 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); } -void __init arch_init_irq(void) +static inline void init_atlas_irqs (int base) { 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 @@ -211,7 +217,7 @@ void __init arch_init_irq(void) */ atlas_hw0_icregs->intrsten = 0xffffffff; - for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { + for (i = ATLAS_INT_BASE; i <= ATLAS_INT_END; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; @@ -219,3 +225,62 @@ void __init arch_init_irq(void) 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 9871a91fdb07..0c6b0ce15028 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 = ATLASINT_UART; + s.irq = ATLAS_INT_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 557bf961f36a..8d15861fce61 100644 --- a/trunk/arch/mips/mips-boards/generic/time.c +++ b/trunk/arch/mips/mips-boards/generic/time.c @@ -41,8 +41,13 @@ #include #include + +#ifdef CONFIG_MIPS_ATLAS +#include +#endif +#ifdef CONFIG_MIPS_MALTA #include -#include +#endif unsigned long cpu_khz; @@ -92,10 +97,9 @@ 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 @@ -108,29 +112,46 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * the general MIPS timer_interrupt routine. */ + int vpflags; + /* - * DVPE is necessary so long as cross-VPE interrupts - * are done via read-modify-write of Cause register. + * We could be here due to timer interrupt, + * perf counter overflow, or both. */ - int vpflags = dvpe(); - write_c0_compare (read_c0_count() - 1); - clear_c0_cause(CPUCTR_IMASKBIT); - evpe(vpflags); + if (read_c0_cause() & (1 << 26)) + perf_irq(regs); - 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) + if (read_c0_cause() & (1 << 30)) { + /* If timer interrupt, make it de-assert */ + write_c0_compare (read_c0_count() - 1); /* - * Other CPUs should do profiling and process accounting + * DVPE is necessary so long as cross-VPE interrupts + * are done via read-modify-write of Cause register. */ - local_timer_interrupt(irq, dev_id, regs); - + vpflags = dvpe(); + clear_c0_cause(CPUCTR_IMASKBIT); + evpe(vpflags); + /* + * 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(). + */ + 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; + if (cpu == 0) { /* * CPU 0 handles the global timer interrupt job and process @@ -161,9 +182,8 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) */ local_timer_interrupt(irq, dev_id, regs); } -#endif /* CONFIG_MIPS_MT_SMTC */ - out: +#endif /* CONFIG_MIPS_MT_SMTC */ return IRQ_HANDLED; } diff --git a/trunk/arch/mips/mm/c-r3k.c b/trunk/arch/mips/mm/c-r3k.c index bb041a22f20a..e1f35ef81145 100644 --- a/trunk/arch/mips/mm/c-r3k.c +++ b/trunk/arch/mips/mm/c-r3k.c @@ -335,7 +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_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 069803f58f3b..0b2da53750bd 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 inline void r4k_blast_dcache_page_setup(void) +static void __init r4k_blast_dcache_page_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); @@ -103,7 +103,7 @@ static inline void r4k_blast_dcache_page_setup(void) static void (* r4k_blast_dcache_page_indexed)(unsigned long addr); -static inline void r4k_blast_dcache_page_indexed_setup(void) +static void __init r4k_blast_dcache_page_indexed_setup(void) { unsigned long dc_lsize = cpu_dcache_line_size(); @@ -117,7 +117,7 @@ static inline void r4k_blast_dcache_page_indexed_setup(void) static void (* r4k_blast_dcache)(void); -static inline void r4k_blast_dcache_setup(void) +static void __init 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 inline void r4k_blast_icache_page_setup(void) +static void __init r4k_blast_icache_page_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); @@ -219,7 +219,7 @@ static inline void r4k_blast_icache_page_setup(void) static void (* r4k_blast_icache_page_indexed)(unsigned long addr); -static inline void r4k_blast_icache_page_indexed_setup(void) +static void __init r4k_blast_icache_page_indexed_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); @@ -243,7 +243,7 @@ static inline void r4k_blast_icache_page_indexed_setup(void) static void (* r4k_blast_icache)(void); -static inline void r4k_blast_icache_setup(void) +static void __init r4k_blast_icache_setup(void) { unsigned long ic_lsize = cpu_icache_line_size(); @@ -264,7 +264,7 @@ static inline void r4k_blast_icache_setup(void) static void (* r4k_blast_scache_page)(unsigned long addr); -static inline void r4k_blast_scache_page_setup(void) +static void __init r4k_blast_scache_page_setup(void) { unsigned long sc_lsize = cpu_scache_line_size(); @@ -282,7 +282,7 @@ static inline void r4k_blast_scache_page_setup(void) static void (* r4k_blast_scache_page_indexed)(unsigned long addr); -static inline void r4k_blast_scache_page_indexed_setup(void) +static void __init r4k_blast_scache_page_indexed_setup(void) { unsigned long sc_lsize = cpu_scache_line_size(); @@ -300,7 +300,7 @@ static inline void r4k_blast_scache_page_indexed_setup(void) static void (* r4k_blast_scache)(void); -static inline void r4k_blast_scache_setup(void) +static void __init 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) { + if (cpu_has_vtag_icache && mm == current->active_mm) { int cpu = smp_processor_id(); if (cpu_context(cpu, mm) != 0) @@ -599,7 +599,7 @@ static inline void local_r4k_flush_icache_page(void *args) * 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) { + if (cpu_has_vtag_icache && vma->vm_mm == current->active_mm) { int cpu = smp_processor_id(); if (cpu_context(cpu, vma->vm_mm) != 0) @@ -1221,7 +1221,7 @@ void au1x00_fixup_config_od(void) } } -static inline void coherency_setup(void) +static void __init coherency_setup(void) { change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); @@ -1242,7 +1242,7 @@ static inline void coherency_setup(void) clear_c0_config(CONF_CU); break; /* - * We need to catch the ealry Alchemy SOCs with + * We need to catch the early Alchemy SOCs with * the write-only co_config.od bit and set it back to one... */ case CPU_AU1000: /* rev. DA, HA, HB */ @@ -1291,7 +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_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 2d71efb82ac5..16bad7c0a63f 100644 --- a/trunk/arch/mips/mm/c-sb1.c +++ b/trunk/arch/mips/mm/c-sb1.c @@ -154,6 +154,26 @@ 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 @@ -173,8 +193,11 @@ static void local_sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long /* * Bumping the ASID is probably cheaper than the flush ... */ - if (cpu_context(cpu, vma->vm_mm) != 0) - drop_mmu_context(vma->vm_mm, cpu); + 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); } #ifdef CONFIG_SMP @@ -210,26 +233,6 @@ 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 @@ -326,9 +329,12 @@ static void local_sb1_flush_icache_page(struct vm_area_struct *vma, * 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); - } + 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(start, start + PAGE_SIZE); + } #ifdef CONFIG_SMP @@ -520,7 +526,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_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 5dfc9b1901f6..932a09d7ef84 100644 --- a/trunk/arch/mips/mm/c-tx39.c +++ b/trunk/arch/mips/mm/c-tx39.c @@ -382,7 +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_page = (void *) tx39h_flush_icache_all; flush_icache_range = (void *) tx39h_flush_icache_all; flush_cache_sigtramp = (void *) tx39h_flush_icache_all; @@ -408,7 +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_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 ddd3a2de1d73..40c8b0235183 100644 --- a/trunk/arch/mips/mm/cache.c +++ b/trunk/arch/mips/mm/cache.c @@ -25,7 +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); +void (*__flush_icache_page)(struct vm_area_struct *vma, struct page *page); /* MIPS specific cache operations */ void (*flush_cache_sigtramp)(unsigned long addr); @@ -70,6 +70,8 @@ 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; @@ -91,16 +93,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 (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); + 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)) flush_data_cache_page(addr); - } - ClearPageDcacheDirty(page); } } diff --git a/trunk/arch/mips/mm/fault.c b/trunk/arch/mips/mm/fault.c index e3a617224868..8423d8590779 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_EXEC))) + if (!(vma->vm_flags & (VM_READ | VM_WRITE | 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 (tsk->pid == 1) { + if (is_init(tsk)) { 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 2cde1b772443..2e0e21ef433e 100644 --- a/trunk/arch/mips/mm/tlb-r4k.c +++ b/trunk/arch/mips/mm/tlb-r4k.c @@ -26,11 +26,6 @@ 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 @@ -126,7 +121,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, start += (PAGE_SIZE << 1); mtc0_tlbw_hazard(); tlb_probe(); - BARRIER; + tlb_probe_hazard(); idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); @@ -168,7 +163,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) start += (PAGE_SIZE << 1); mtc0_tlbw_hazard(); tlb_probe(); - BARRIER; + tlb_probe_hazard(); idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); @@ -202,7 +197,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) write_c0_entryhi(page | newpid); mtc0_tlbw_hazard(); tlb_probe(); - BARRIER; + tlb_probe_hazard(); idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); @@ -235,7 +230,7 @@ void local_flush_tlb_one(unsigned long page) write_c0_entryhi(page); mtc0_tlbw_hazard(); tlb_probe(); - BARRIER; + tlb_probe_hazard(); idx = read_c0_index(); write_c0_entrylo0(0); write_c0_entrylo1(0); @@ -279,7 +274,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(); - BARRIER; + tlb_probe_hazard(); pudp = pud_offset(pgdp, address); pmdp = pmd_offset(pudp, address); idx = read_c0_index(); @@ -320,7 +315,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(); - BARRIER; + tlb_probe_hazard(); pmdp = pmd_offset(pgdp, address); idx = read_c0_index(); ptep = pte_offset_map(pmdp, address); @@ -351,7 +346,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); - BARRIER; + tlbw_use_hazard(); /* What is the hazard here? */ write_c0_pagemask(pagemask); write_c0_entryhi(entryhi); write_c0_entrylo0(entrylo0); @@ -361,7 +356,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, tlbw_use_hazard(); write_c0_entryhi(old_ctx); - BARRIER; + tlbw_use_hazard(); /* What is the hazard here? */ write_c0_pagemask(old_pagemask); local_flush_tlb_all(); EXIT_CRITICAL(flags); diff --git a/trunk/arch/mips/momentum/ocelot_g/gt-irq.c b/trunk/arch/mips/momentum/ocelot_g/gt-irq.c index 9fb2493fff02..6cd87cf0195a 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(regs); + do_timer(1); #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 35d5927706ea..edefa97b2330 100644 --- a/trunk/arch/mips/pci/Makefile +++ b/trunk/arch/mips/pci/Makefile @@ -11,7 +11,6 @@ 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 @@ -28,8 +27,7 @@ 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_EV96100) += fixup-ev64120.o -obj-$(CONFIG_MIPS_EV96100) += fixup-ev96100.o pci-ev96100.o +obj-$(CONFIG_MIPS_EV64120) += fixup-ev64120.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 439510af3037..c6cd6e9cdfbc 100644 --- a/trunk/arch/mips/pci/fixup-atlas.c +++ b/trunk/arch/mips/pci/fixup-atlas.c @@ -21,16 +21,16 @@ #include -#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 +#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 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 deleted file mode 100644 index e2bc977b6d58..000000000000 --- a/trunk/arch/mips/pci/fixup-ev96100.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * 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 0c0c1e6519f9..8ae46481fcb7 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, 0); + pci_cfg_vm = get_vm_area(0x2000, VM_IOREMAP); 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 deleted file mode 100644 index 9e4ea6627e21..000000000000 --- a/trunk/arch/mips/pci/ops-gt96100.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * - * 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 deleted file mode 100644 index f9457ea00def..000000000000 --- a/trunk/arch/mips/pci/pci-ev96100.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 80eb9af9ecdf..405ce0152739 100644 --- a/trunk/arch/mips/pci/pci-ip27.c +++ b/trunk/arch/mips/pci/pci-ip27.c @@ -16,8 +16,6 @@ #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-ip27/ip27-timer.c b/trunk/arch/mips/sgi-ip27/ip27-timer.c index b029ba79c27a..257ce118e380 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-timer.c +++ b/trunk/arch/mips/sgi-ip27/ip27-timer.c @@ -42,8 +42,6 @@ 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) { @@ -111,7 +109,7 @@ void ip27_rt_timer_interrupt(struct pt_regs *regs) kstat_this_cpu.irqs[irq]++; /* kstat only for bootcpu? */ if (cpu == 0) - do_timer(regs); + do_timer(1); update_process_times(user_mode(regs)); diff --git a/trunk/arch/mips/sibyte/bcm1480/irq.c b/trunk/arch/mips/sibyte/bcm1480/irq.c index ed325f0ab28a..a0222fa4416c 100644 --- a/trunk/arch/mips/sibyte/bcm1480/irq.c +++ b/trunk/arch/mips/sibyte/bcm1480/irq.c @@ -469,21 +469,6 @@ 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); @@ -536,9 +521,9 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs) if (mask_h) { if (mask_h ^ 1) - do_IRQ(63 - dclz(mask_h), regs); + do_IRQ(fls64(mask_h) - 1, regs); else - do_IRQ(127 - dclz(mask_l), regs); + do_IRQ(63 + fls64(mask_l), regs); } } } diff --git a/trunk/arch/mips/sibyte/sb1250/irq.c b/trunk/arch/mips/sibyte/sb1250/irq.c index 1de71adec6c6..a451b4c7732d 100644 --- a/trunk/arch/mips/sibyte/sb1250/irq.c +++ b/trunk/arch/mips/sibyte/sb1250/irq.c @@ -419,21 +419,6 @@ 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); @@ -490,6 +475,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(63 - dclz(mask), regs); + do_IRQ(fls64(mask) - 1, regs); } } diff --git a/trunk/arch/parisc/kernel/firmware.c b/trunk/arch/parisc/kernel/firmware.c index 4398d2a95789..c2531ae032cf 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 int flags; + unsigned long flags; switch (c) { case '\n': @@ -1088,7 +1088,8 @@ void pdc_iodc_putc(unsigned char c) */ void pdc_iodc_outc(unsigned char c) { - unsigned int n, flags; + unsigned int n; + unsigned long flags; /* fill buffer with one caracter and print it */ static int __attribute__((aligned(8))) iodc_retbuf[32]; @@ -1113,7 +1114,7 @@ void pdc_iodc_outc(unsigned char c) */ int pdc_iodc_getc(void) { - unsigned int flags; + unsigned long 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 aee311884f3f..f50b982b0834 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 (is_init(me, (void *)val)) + * if (in_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 is_init(struct module *me, void *loc) +static inline int in_init(struct module *me, void *loc) { return (loc >= me->module_init && loc <= (me->module_init + me->init_size)); } -static inline int is_core(struct module *me, void *loc) +static inline int in_core(struct module *me, void *loc) { return (loc >= me->module_core && loc <= (me->module_core + me->core_size)); } -static inline int is_local(struct module *me, void *loc) +static inline int in_local(struct module *me, void *loc) { - return is_init(me, loc) || is_core(me, loc); + return in_init(me, loc) || in_core(me, loc); } -static inline int is_local_section(struct module *me, void *loc, void *dot) +static inline int in_local_section(struct module *me, void *loc, void *dot) { - return (is_init(me, loc) && is_init(me, dot)) || - (is_core(me, loc) && is_core(me, dot)); + return (in_init(me, loc) && in_init(me, dot)) || + (in_core(me, loc) && in_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, is_init(me, loc)); + val = get_stub(me, val, addend, ELF_STUB_GOT, in_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, is_init(me, loc)); + val = get_stub(me, val, addend, ELF_STUB_GOT, in_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(!is_local_section(me, (void *)val, (void *)dot)) { + if(!in_local_section(me, (void *)val, (void *)dot)) { - if (is_local(me, (void *)val)) + if (in_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, - is_init(me, loc)); + in_init(me, loc)); else if (strncmp(strtab + sym->st_name, "$$", 2) == 0) val = get_stub(me, val, addend, ELF_STUB_MILLI, - is_init(me, loc)); + in_init(me, loc)); else val = get_stub(me, val, addend, ELF_STUB_GOT, - is_init(me, loc)); + in_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(is_local(me, (void *)(val + addend))) { + if(in_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/time.c b/trunk/arch/parisc/kernel/time.c index 5facc9bff4ef..ab641d67f551 100644 --- a/trunk/arch/parisc/kernel/time.c +++ b/trunk/arch/parisc/kernel/time.c @@ -32,9 +32,6 @@ #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; @@ -79,7 +76,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) #endif if (cpu == 0) { write_seqlock(&xtime_lock); - do_timer(regs); + do_timer(1); write_sequnlock(&xtime_lock); } } @@ -112,7 +109,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 aka wall_jiffies). The xtime_lock + * update to wall time (aka xtime). 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 de1ef2fa1a20..a0dd1b0ee483 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -731,11 +731,10 @@ config ARCH_SPARSEMEM_DEFAULT def_bool y depends on SMP && PPC_PSERIES -source "mm/Kconfig" - -config HAVE_ARCH_EARLY_PFN_TO_NID +config ARCH_POPULATES_NODE_MAP def_bool y - depends on NEED_MULTIPLE_NODES + +source "mm/Kconfig" config ARCH_MEMORY_PROBE def_bool y diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index e0df2ba1ab9f..79a17795d17b 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -67,10 +67,6 @@ 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 00d6b8addd78..962ad5ebc767 100644 --- a/trunk/arch/powerpc/kernel/setup_64.c +++ b/trunk/arch/powerpc/kernel/setup_64.c @@ -93,11 +93,6 @@ 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; diff --git a/trunk/arch/powerpc/kernel/sys_ppc32.c b/trunk/arch/powerpc/kernel/sys_ppc32.c index 2e292863e982..5e391fc25340 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 +#ifdef CONFIG_SYSCTL_SYSCALL struct __sysctl_args32 { u32 name; int nlen; diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index 7a3c3f791ade..8b278d85ca4e 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -117,8 +117,6 @@ unsigned tb_to_ns_shift; struct gettimeofday_struct do_gtod; -extern unsigned long wall_jiffies; - extern struct timezone sys_tz; static long timezone_offset; @@ -693,7 +691,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(regs); + do_timer(1); timer_recalc_offset(tb_last_jiffy); timer_check_rtc(); } @@ -816,11 +814,6 @@ 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 78a0d59903ee..e8fa50624b70 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))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) 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 (current->pid == 1) { + if (is_init(current)) { 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 eebd8b83a6b0..16fe027bbc12 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -256,20 +256,22 @@ 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 - if (base >= total_lowmem) - continue; - if (base + size > total_lowmem) - size = total_lowmem - base; + free_bootmem_with_active_regions(0, total_lowmem >> PAGE_SHIFT); +#else + free_bootmem_with_active_regions(0, max_pfn); #endif - free_bootmem(base, size); - } /* reserve the sections we're already using */ for (i = 0; i < lmb.reserved.cnt; i++) @@ -277,9 +279,8 @@ void __init do_init_bootmem(void) lmb_size_bytes(&lmb.reserved, i)); /* XXX need to clip this if using highmem? */ - for (i = 0; i < lmb.memory.cnt; i++) - memory_present(0, lmb_start_pfn(&lmb.memory, i), - lmb_end_pfn(&lmb.memory, i)); + sparse_memory_present_with_active_regions(0); + init_bootmem_done = 1; } @@ -288,10 +289,9 @@ 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,26 +307,13 @@ 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 - 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; + max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT; + max_zone_pfns[1] = top_of_ram >> PAGE_SHIFT; #else - 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); + max_zone_pfns[0] = top_of_ram >> PAGE_SHIFT; +#endif + free_area_init_nodes(max_zone_pfns); } #endif /* ! CONFIG_NEED_MULTIPLE_NODES */ diff --git a/trunk/arch/powerpc/mm/numa.c b/trunk/arch/powerpc/mm/numa.c index 6c0f1c7d83e5..43c272075e1a 100644 --- a/trunk/arch/powerpc/mm/numa.c +++ b/trunk/arch/powerpc/mm/numa.c @@ -39,96 +39,6 @@ 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; @@ -468,8 +378,8 @@ static int __init parse_numa_properties(void) continue; } - add_region(nid, start >> PAGE_SHIFT, - size >> PAGE_SHIFT); + add_active_range(nid, start >> PAGE_SHIFT, + (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT)); if (--ranges) goto new_range; @@ -482,6 +392,7 @@ 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", @@ -489,9 +400,11 @@ 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) - add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT, - lmb_size_pages(&lmb.memory, i)); + 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); + } node_set_online(0); } @@ -630,11 +543,11 @@ void __init do_init_bootmem(void) (void *)(unsigned long)boot_cpuid); for_each_online_node(nid) { - unsigned long start_pfn, end_pfn, pages_present; + unsigned long start_pfn, end_pfn; unsigned long bootmem_paddr; unsigned long bootmap_pages; - get_region(nid, &start_pfn, &end_pfn, &pages_present); + get_pfn_range_for_nid(nid, &start_pfn, &end_pfn); /* Allocate the node structure node local if possible */ NODE_DATA(nid) = careful_allocation(nid, @@ -667,19 +580,7 @@ void __init do_init_bootmem(void) init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT, start_pfn, 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); - } + free_bootmem_with_active_regions(nid, end_pfn); /* Mark reserved regions on this node */ for (i = 0; i < lmb.reserved.cnt; i++) { @@ -710,44 +611,16 @@ void __init do_init_bootmem(void) } } - /* 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); - } + sparse_memory_present_with_active_regions(nid); } } void __init paging_init(void) { - 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); - } + unsigned long max_zone_pfns[MAX_NR_ZONES] = { + lmb_end_of_DRAM() >> PAGE_SHIFT + }; + free_area_init_nodes(max_zone_pfns); } 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 7b4572805db9..3950ddccb2c8 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/inode.c @@ -82,7 +82,6 @@ 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: @@ -120,7 +119,7 @@ spufs_new_file(struct super_block *sb, struct dentry *dentry, ret = 0; inode->i_op = &spufs_file_iops; inode->i_fop = fops; - inode->u.generic_ip = SPUFS_I(inode)->i_ctx = get_spu_context(ctx); + inode->i_private = SPUFS_I(inode)->i_ctx = get_spu_context(ctx); d_add(dentry, inode); out: return ret; diff --git a/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c b/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c index d30466d74194..9d22361a26d6 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(comp); + DECLARE_COMPLETION_ONSTACK(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 6a36ea9bf673..692945c14919 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(req_complete); + DECLARE_COMPLETION_ONSTACK(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(req_complete); + DECLARE_COMPLETION_ONSTACK(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 641e6511cf06..446e17d162a5 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->u.generic_ip; + seq->private = file->f_dentry->d_inode->i_private; return rc; } diff --git a/trunk/arch/powerpc/platforms/pseries/ras.c b/trunk/arch/powerpc/platforms/pseries/ras.c index 903115d67fdc..311ed1993fc0 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 || current->pid == 1)) { + !(current->pid == 0 || is_init(current))) { /* 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 a6398fbe530d..8ed362140452 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -415,6 +415,12 @@ 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 b604926401f5..723972bb5bd9 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_IRQCONF) { + if (id == PCI_CAP_ID_HT) { id = readb(devbase + pos + 3); if (id == 0x80) break; diff --git a/trunk/arch/ppc/Kconfig b/trunk/arch/ppc/Kconfig index 8fa10cf661a8..fdd9e7b66244 100644 --- a/trunk/arch/ppc/Kconfig +++ b/trunk/arch/ppc/Kconfig @@ -953,6 +953,9 @@ 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/setup.c b/trunk/arch/ppc/kernel/setup.c index 5458ac5da7c3..75fe13815be2 100644 --- a/trunk/arch/ppc/kernel/setup.c +++ b/trunk/arch/ppc/kernel/setup.c @@ -86,10 +86,6 @@ 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 6ab8cc7226ab..187388625a76 100644 --- a/trunk/arch/ppc/kernel/time.c +++ b/trunk/arch/ppc/kernel/time.c @@ -80,8 +80,6 @@ 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; @@ -153,7 +151,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(regs); + do_timer(1); /* * update the rtc when needed, this should be performed on the @@ -173,8 +171,7 @@ 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 && - jiffies - wall_jiffies == 1) { + abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ) { if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0) last_rtc_update = xtime.tv_sec+1; else @@ -200,7 +197,7 @@ void do_gettimeofday(struct timeval *tv) { unsigned long flags; unsigned long seq; - unsigned delta, lost_ticks, usec, sec; + unsigned delta, usec, sec; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); @@ -214,10 +211,9 @@ 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, tb_ticks_per_jiffy * lost_ticks + delta); + usec += mulhwu(tb_to_us, delta); while (usec >= 1000000) { sec++; usec -= 1000000; @@ -258,7 +254,6 @@ 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 d7a433049b48..aafc8e8893d1 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 (current->pid == 1) { + if (is_init(current)) { __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 5cdfb71fcb07..465f451f3bc3 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))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) 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 (current->pid == 1) { + if (is_init(current)) { 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 523392d460fa..410200046af1 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 zones_size[MAX_NR_ZONES], i; - + unsigned long start_pfn, end_pfn; + unsigned long max_zone_pfns[MAX_NR_ZONES]; #ifdef CONFIG_HIGHMEM map_page(PKMAP_BASE, 0, 0); /* XXX gross */ pkmap_page_table = pte_offset_kernel(pmd_offset(pgd_offset_k @@ -369,19 +369,18 @@ 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. - */ - zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT; - for (i = 1; i < MAX_NR_ZONES; i++) - zones_size[i] = 0; + /* 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); #ifdef CONFIG_HIGHMEM - zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT; + 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; #endif /* CONFIG_HIGHMEM */ - - free_area_init(zones_size); + free_area_init_nodes(max_zone_pfns); } void __init mem_init(void) diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index b216ca659cdf..f900a516f099 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -51,6 +51,10 @@ 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--- @@ -149,6 +153,14 @@ 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 74ef57dcfa60..5deb9f7544a1 100644 --- a/trunk/arch/s390/Makefile +++ b/trunk/arch/s390/Makefile @@ -33,6 +33,7 @@ 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 b69ed742f981..2b1e6c9a6e0e 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 efd836c2e4a6..2b137089f625 100644 --- a/trunk/arch/s390/crypto/crypt_s390.h +++ b/trunk/arch/s390/crypto/crypt_s390.h @@ -104,63 +104,6 @@ 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 @@ -176,28 +119,24 @@ 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; - ret = 0; - __asm__ __volatile__ ( - "0: .insn rre,0xB92E0000,%1,%2 \n" /* KM opcode */ + asm volatile( + "0: .insn rre,0xb92e0000,%3,%1 \n" /* KM opcode */ "1: brc 1,0b \n" /* handle partial completion */ - __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; + " 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; } /* @@ -215,28 +154,24 @@ 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; - ret = 0; - __asm__ __volatile__ ( - "0: .insn rre,0xB92F0000,%1,%2 \n" /* KMC opcode */ + asm volatile( + "0: .insn rre,0xb92f0000,%3,%1 \n" /* KMC opcode */ "1: brc 1,0b \n" /* handle partial completion */ - __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; + " 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; } /* @@ -258,22 +193,19 @@ crypt_s390_kimd(long func, void* param, const u8* src, long src_len) register long __src_len asm("3") = src_len; int ret; - 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; + 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; } /* @@ -294,22 +226,19 @@ crypt_s390_klmd(long func, void* param, const u8* src, long src_len) register long __src_len asm("3") = src_len; int ret; - 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; + 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; } /* @@ -331,22 +260,19 @@ crypt_s390_kmac(long func, void* param, const u8* src, long src_len) register long __src_len asm("3") = src_len; int ret; - 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; + 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; } /** diff --git a/trunk/arch/s390/hypfs/hypfs_diag.c b/trunk/arch/s390/hypfs/hypfs_diag.c index 75144efbb92b..443fa377d9ff 100644 --- a/trunk/arch/s390/hypfs/hypfs_diag.c +++ b/trunk/arch/s390/hypfs/hypfs_diag.c @@ -333,22 +333,14 @@ 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" ".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"); + asm volatile( + " diag %2,%0,0x204\n" + "0:\n" + EX_TABLE(0b,0b) + : "+d" (_subcode), "+d" (_size) : "d" (addr) : "memory"); if (_subcode) return -1; - else - return _size; + return _size; } /* @@ -403,7 +395,8 @@ static void *diag204_get_buffer(enum diag204_format fmt, int *pages) *pages = 1; return diag204_alloc_rbuf(); } else {/* INFO_EXT */ - *pages = diag204(SUBC_RSI | INFO_EXT, 0, NULL); + *pages = diag204((unsigned long)SUBC_RSI | + (unsigned long)INFO_EXT, 0, NULL); if (*pages <= 0) return ERR_PTR(-ENOSYS); else @@ -490,8 +483,7 @@ static void *diag204_store(void) static void diag224(void *ptr) { - asm volatile(" diag %0,%1,0x224\n" - : :"d" (0), "d"(ptr) : "memory"); + asm volatile("diag %0,%1,0x224" : :"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 bdade5f2e325..cd702ae45d6d 100644 --- a/trunk/arch/s390/hypfs/inode.c +++ b/trunk/arch/s390/hypfs/inode.c @@ -91,7 +91,6 @@ 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) @@ -104,13 +103,13 @@ static struct inode *hypfs_make_inode(struct super_block *sb, int mode) static void hypfs_drop_inode(struct inode *inode) { - kfree(inode->u.generic_ip); + kfree(inode->i_private); generic_delete_inode(inode); } static int hypfs_open(struct inode *inode, struct file *filp) { - char *data = filp->f_dentry->d_inode->u.generic_ip; + char *data = filp->f_dentry->d_inode->i_private; struct hypfs_sb_info *fs_info; if (filp->f_mode & FMODE_WRITE) { @@ -135,12 +134,20 @@ static int hypfs_open(struct inode *inode, struct file *filp) return 0; } -static ssize_t hypfs_aio_read(struct kiocb *iocb, __user char *buf, - size_t count, loff_t offset) +static ssize_t hypfs_aio_read(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, 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); @@ -159,12 +166,13 @@ static ssize_t hypfs_aio_read(struct kiocb *iocb, __user char *buf, out: return count; } -static ssize_t hypfs_aio_write(struct kiocb *iocb, const char __user *buf, - size_t count, loff_t pos) +static ssize_t hypfs_aio_write(struct kiocb *iocb, const struct iovec *iov, + unsigned long nr_segs, loff_t offset) { 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; @@ -352,7 +360,7 @@ static struct dentry *hypfs_create_file(struct super_block *sb, parent->d_inode->i_nlink++; } else BUG(); - inode->u.generic_ip = data; + inode->i_private = 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 785c9f70ac98..c46e3d48e410 100644 --- a/trunk/arch/s390/kernel/compat_linux.c +++ b/trunk/arch/s390/kernel/compat_linux.c @@ -544,10 +544,7 @@ sys32_execve(struct pt_regs regs) current->ptrace &= ~PT_DTRACE; task_unlock(current); current->thread.fp_regs.fpc=0; - __asm__ __volatile__ - ("sr 0,0\n\t" - "sfpc 0,0\n\t" - : : :"0"); + asm volatile("sfpc %0,0" : : "d" (0)); } putname(filename); out: @@ -708,7 +705,7 @@ asmlinkage long sys32_sendfile64(int out_fd, int in_fd, return ret; } -#ifdef CONFIG_SYSCTL +#ifdef CONFIG_SYSCTL_SYSCALL 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 4d53b2739357..4aabeeaa7cf7 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 4ef44e536b2c..1eae74e72f95 100644 --- a/trunk/arch/s390/kernel/cpcmd.c +++ b/trunk/arch/s390/kernel/cpcmd.c @@ -25,11 +25,8 @@ static char cpcmd_buf[241]; */ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) { - const int mask = 0x40000000L; - unsigned long flags; - int return_code; - int return_len; - int cmdlen; + unsigned long flags, cmdlen; + int return_code, return_len; spin_lock_irqsave(&cpcmd_lock, flags); cmdlen = strlen(cmd); @@ -38,64 +35,44 @@ 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 - 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" ); + " diag %2,%0,0x8\n" + " brc 8,1f\n" + " ar %1,%4\n" #else /* CONFIG_64BIT */ - 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" ); + " sam31\n" + " diag %2,%0,0x8\n" + " sam64\n" + " brc 8,1f\n" + " agr %1,%4\n" #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 - 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" ); + " diag %1,%0,0x8\n" #else /* CONFIG_64BIT */ - 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" ); + " sam31\n" + " diag %1,%0,0x8\n" + " sam64\n" #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 7ba20922a535..43f3d0c7e132 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 = (struct debug_info*)file->f_dentry->d_inode->u.generic_ip; + debug_info = file->f_dentry->d_inode->i_private; /* 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 0c712b78a7e8..dddc3de30401 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,52 +386,51 @@ 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_sigaltstack_glue: - la %r4,SP_PTREGS(%r15) # load pt_regs as parameter - l %r1,BASED(.Lsigaltstack) - br %r1 # branch to sys_sigreturn +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 /* * Program check handler routine */ - .globl pgm_check_handler + .globl pgm_check_handler pgm_check_handler: /* * First we need to check for a special case: @@ -448,8 +447,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 @@ -461,29 +460,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 @@ -507,10 +506,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) # @@ -552,7 +551,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 @@ -569,42 +568,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 @@ -615,16 +614,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) @@ -637,36 +636,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 @@ -683,8 +682,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 @@ -696,13 +695,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 @@ -741,7 +740,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) @@ -752,14 +751,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 @@ -783,36 +782,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 @@ -834,11 +833,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: @@ -940,10 +939,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: @@ -1009,57 +1008,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 29bbfbab7332..0f758c329a5d 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,49 +326,48 @@ 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 # @@ -377,78 +376,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: @@ -465,8 +464,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 @@ -478,29 +477,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 @@ -524,9 +523,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 @@ -544,7 +543,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 @@ -568,7 +567,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 @@ -585,42 +584,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 @@ -631,7 +630,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. @@ -656,11 +655,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 @@ -668,17 +667,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 @@ -695,9 +694,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 @@ -706,14 +705,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 @@ -737,19 +736,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? @@ -764,7 +763,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 @@ -794,28 +793,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 @@ -836,9 +835,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 @@ -941,10 +940,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: @@ -1010,21 +1009,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 0f1db268a8a9..0cf59bb7a857 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 ramdisk - 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 rd + 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 1fa9fa1ca740..1b952a3664e2 100644 --- a/trunk/arch/s390/kernel/head31.S +++ b/trunk/arch/s390/kernel/head31.S @@ -254,6 +254,16 @@ 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 @@ -281,6 +291,7 @@ 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 a8bdd96494c7..b30e5897cdf7 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,6 +250,17 @@ 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 # @@ -263,45 +274,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 @@ -309,47 +320,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 access regs needed by uaccess - brasl %r14,start_kernel # go to C code + lam 0,15,.Laregs-.LPG3(%r13) # load acrs 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 6555cc48e28f..1f5e782b3d05 100644 --- a/trunk/arch/s390/kernel/ipl.c +++ b/trunk/arch/s390/kernel/ipl.c @@ -120,24 +120,15 @@ 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" - ".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" + asm volatile( + " diag %0,%2,0x308\n" + "0:\n" + EX_TABLE(0b,0b) : "+d" (_addr), "+d" (_rc) - : "d" (subcode) : "cc", "memory" ); - + : "d" (subcode) : "cc", "memory"); return _rc; } diff --git a/trunk/arch/s390/kernel/process.c b/trunk/arch/s390/kernel/process.c index d3cbfa3005ec..6603fbb41d07 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,7 +177,8 @@ 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 4562cdbce8eb..0340477f3b08 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,6 +92,3 @@ 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 95bd1e234f63..de7435054f7c 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,4 +109,3 @@ 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 2a25ec7147ff..f9899ff2e5b0 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 8cdb86e8911f..4fb443042d9c 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 8dfb690c159f..191303f6c1d8 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 e3d9325f6022..a21cfbb9d97e 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 b2e6f4c8d382..a8e6199755d4 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); /* - * Structure and data for smp_call_function(). This is designed to minimise +5B * 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,59 +418,49 @@ void smp_send_reschedule(int cpu) /* * parameter area for the set/clear control bit callbacks */ -typedef struct -{ - __u16 start_ctl; - __u16 end_ctl; +struct ec_creg_mask_parms { 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) { - ec_creg_mask_parms *pp; + struct ec_creg_mask_parms *pp = info; unsigned long cregs[16]; int 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++) + __ctl_store(cregs, 0, 15); + for (i = 0; i <= 15; i++) cregs[i] = (cregs[i] & pp->andvals[i]) | pp->orvals[i]; - __ctl_load(cregs[pp->start_ctl], pp->start_ctl, pp->end_ctl); + __ctl_load(cregs, 0, 15); } /* * Set a bit in a control register of all cpus */ -void smp_ctl_set_bit(int cr, int bit) { - ec_creg_mask_parms parms; +void smp_ctl_set_bit(int cr, int bit) +{ + struct ec_creg_mask_parms parms; - parms.start_ctl = cr; - parms.end_ctl = cr; + memset(&parms.orvals, 0, sizeof(parms.orvals)); + memset(&parms.andvals, 0xff, sizeof(parms.andvals)); parms.orvals[cr] = 1 << bit; - parms.andvals[cr] = -1L; - preempt_disable(); - smp_call_function(smp_ctl_bit_callback, &parms, 0, 1); - __ctl_set_bit(cr, bit); - preempt_enable(); + on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1); } /* * Clear a bit in a control register of all cpus */ -void smp_ctl_clear_bit(int cr, int bit) { - ec_creg_mask_parms parms; +void smp_ctl_clear_bit(int cr, int bit) +{ + struct ec_creg_mask_parms parms; - parms.start_ctl = cr; - parms.end_ctl = cr; - parms.orvals[cr] = 0; + memset(&parms.orvals, 0, sizeof(parms.orvals)); + memset(&parms.andvals, 0xff, sizeof(parms.andvals)); parms.andvals[cr] = ~(1L << bit); - preempt_disable(); - smp_call_function(smp_ctl_bit_callback, &parms, 0, 1); - __ctl_clear_bit(cr, bit); - preempt_enable(); + on_each_cpu(smp_ctl_bit_callback, &parms, 0, 1); } /* @@ -650,9 +640,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; @@ -708,7 +698,7 @@ int __cpu_disable(void) { unsigned long flags; - ec_creg_mask_parms cr_parms; + struct ec_creg_mask_parms cr_parms; int cpu = smp_processor_id(); spin_lock_irqsave(&smp_reserve_lock, flags); @@ -724,30 +714,21 @@ __cpu_disable(void) pfault_fini(); #endif - /* disable all external interrupts */ + memset(&cr_parms.orvals, 0, sizeof(cr_parms.orvals)); + memset(&cr_parms.andvals, 0xff, sizeof(cr_parms.andvals)); - cr_parms.start_ctl = 0; - cr_parms.end_ctl = 0; + /* disable all external interrupts */ 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/time.c b/trunk/arch/s390/kernel/time.c index 74e6178fbaf2..4bf66cc4a267 100644 --- a/trunk/arch/s390/kernel/time.c +++ b/trunk/arch/s390/kernel/time.c @@ -53,8 +53,6 @@ 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. */ @@ -87,9 +85,8 @@ static inline unsigned long do_gettimeoffset(void) { __u64 now; - now = (get_clock() - jiffies_timer_cc) >> 12; - /* We require the offset from the latest update of xtime */ - now -= (__u64) wall_jiffies*USECS_PER_JIFFY; + now = (get_clock() - jiffies_timer_cc) >> 12; + now -= (__u64) jiffies * USECS_PER_JIFFY; return (unsigned long) now; } @@ -166,7 +163,7 @@ EXPORT_SYMBOL(do_settimeofday); void account_ticks(struct pt_regs *regs) { __u64 tmp; - __u32 ticks, xticks; + __u32 ticks; /* Calculate how many ticks have passed. */ if (S390_lowcore.int_clock < S390_lowcore.jiffy_timer) { @@ -204,6 +201,7 @@ 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); @@ -212,13 +210,11 @@ void account_ticks(struct pt_regs *regs) xticks = 1; xtime_cc += CLK_TICKS_PER_JIFFY; } - while (xticks--) - do_timer(regs); + do_timer(xticks); } write_sequnlock(&xtime_lock); #else - for (xticks = ticks; xticks > 0; xticks--) - do_timer(regs); + do_timer(ticks); #endif #ifdef CONFIG_VIRT_CPU_ACCOUNTING @@ -351,10 +347,12 @@ void __init time_init(void) int cc; /* kick the TOD clock */ - asm volatile ("STCK 0(%1)\n\t" - "IPM %0\n\t" - "SRL %0,28" : "=r" (cc) : "a" (&init_timer_cc) - : "memory", "cc"); + asm volatile( + " stck 0(%2)\n" + " ipm %0\n" + " srl %0,28" + : "=d" (cc), "=m" (init_timer_cc) + : "a" (&init_timer_cc) : "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 c4982c963424..3eb4fab048b8 100644 --- a/trunk/arch/s390/kernel/traps.c +++ b/trunk/arch/s390/kernel/traps.c @@ -597,8 +597,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code) local_irq_enable(); if (MACHINE_HAS_IEEE) - __asm__ volatile ("stfpc %0\n\t" - : "=m" (current->thread.fp_regs.fpc)); + asm volatile("stfpc %0" : "=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 c42ffedfdb49..b0cfa6c4883d 100644 --- a/trunk/arch/s390/lib/Makefile +++ b/trunk/arch/s390/lib/Makefile @@ -5,5 +5,6 @@ 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 468f4ea33f99..027c4742a001 100644 --- a/trunk/arch/s390/lib/delay.c +++ b/trunk/arch/s390/lib/delay.c @@ -27,9 +27,7 @@ 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" - : /* no outputs */ : "r" ((loops/2) + 1)); + asm volatile("0: brct %0,0b" : : "d" ((loops/2) + 1)); } /* @@ -38,13 +36,12 @@ void __delay(unsigned long loops) */ void __udelay(unsigned long usecs) { - uint64_t start_cc, end_cc; + uint64_t start_cc; if (usecs == 0) return; - asm volatile ("STCK %0" : "=m" (start_cc)); + start_cc = get_clock(); do { cpu_relax(); - asm volatile ("STCK %0" : "=m" (end_cc)); - } while (((end_cc - start_cc)/4096) < usecs); + } while (((get_clock() - start_cc)/4096) < usecs); } diff --git a/trunk/arch/s390/lib/div64.c b/trunk/arch/s390/lib/div64.c new file mode 100644 index 000000000000..0481f3424a13 --- /dev/null +++ b/trunk/arch/s390/lib/div64.c @@ -0,0 +1,151 @@ +/* + * 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 b9b7958a226a..8d76403fcf89 100644 --- a/trunk/arch/s390/lib/spinlock.c +++ b/trunk/arch/s390/lib/spinlock.c @@ -24,57 +24,76 @@ static int __init spin_retry_setup(char *str) } __setup("spin_retry=", spin_retry_setup); -static inline void -_diag44(void) +static inline void _raw_yield(void) { -#ifdef CONFIG_64BIT if (MACHINE_HAS_DIAG44) -#endif asm volatile("diag 0,0,0x44"); } -void -_raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc) +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) { int count = spin_retry; + unsigned int cpu = ~smp_processor_id(); while (1) { if (count-- <= 0) { - _diag44(); + unsigned int owner = lp->owner_cpu; + if (owner != 0) + _raw_yield_cpu(~owner); count = spin_retry; } if (__raw_spin_is_locked(lp)) continue; - if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) + if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) { + lp->owner_pc = pc; 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) { - int count = spin_retry; + unsigned int cpu = ~smp_processor_id(); + int count; - while (count-- > 0) { + for (count = spin_retry; count > 0; count--) { if (__raw_spin_is_locked(lp)) continue; - if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0) + if (_raw_compare_and_swap(&lp->owner_cpu, 0, cpu) == 0) { + lp->owner_pc = pc; return 1; + } } return 0; } EXPORT_SYMBOL(_raw_spin_trylock_retry); -void -_raw_read_lock_wait(raw_rwlock_t *rw) +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) { unsigned int old; int count = spin_retry; while (1) { if (count-- <= 0) { - _diag44(); + _raw_yield(); count = spin_retry; } if (!__raw_read_can_lock(rw)) @@ -86,8 +105,7 @@ _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; @@ -103,14 +121,13 @@ _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) { - _diag44(); + _raw_yield(); count = spin_retry; } if (!__raw_write_can_lock(rw)) @@ -121,8 +138,7 @@ _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 86c96d6c191a..121b2935a422 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 4f\n" + " jz 7f\n" "1:"ALR" %0,%3\n" " "SLR" %1,%3\n" " "SLR" %2,%3\n" @@ -44,13 +44,23 @@ 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 5f\n" + " jnh 4f\n" "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n" " "SLR" %0,%4\n" - " j 5f\n" - "4:"SLR" %0,%0\n" - "5: \n" - EX_TABLE(0b,2b) EX_TABLE(3b,5b) + " "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) : "+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 9a4d4a29ea79..f44f0078b354 100644 --- a/trunk/arch/s390/lib/uaccess_std.c +++ b/trunk/arch/s390/lib/uaccess_std.c @@ -35,25 +35,35 @@ 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 5f\n" + " jz 8f\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 5f\n" + " j 8f\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 6f\n" + " jnh 5f\n" "4: mvcp 0(%4,%2),0(%1),%3\n" " "SLR" %0,%4\n" - " j 6f\n" - "5:"SLR" %0,%0\n" - "6: \n" - EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b) + " "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) : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) : : "cc", "memory"); return size; @@ -67,16 +77,22 @@ 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 3f\n" + " j 5f\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 3f\n" + " jnh 5f\n" "2: mvcp 0(%4,%2),0(%1),%3\n" " "SLR" %0,%4\n" - "3:\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" 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 b4957c84e4d6..6b9aec5a2c18 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,23 +2089,22 @@ 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; @@ -2120,23 +2119,22 @@ 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 ab556b600f73..5b6ca4570ea4 100644 --- a/trunk/arch/s390/math-emu/sfp-util.h +++ b/trunk/arch/s390/math-emu/sfp-util.h @@ -4,48 +4,51 @@ #include #define add_ssaaaa(sh, sl, ah, al, bh, bl) ({ \ - 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; \ + 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; \ }) #define sub_ddmmss(sh, sl, ah, al, bh, bl) ({ \ - 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; \ + 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; \ }) /* 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__ (" 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 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; \ }) #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 9b11e3e20903..226275d5c4f6 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" // switch to 31 bit - " diag %0,%1,0x64\n" - " sam64\n" // switch back to 64 bit + " sam31\n" + " diag %0,%1,0x64\n" + " sam64\n" #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 44f0cda7e72e..9c3c19fe62fc 100644 --- a/trunk/arch/s390/mm/fault.c +++ b/trunk/arch/s390/mm/fault.c @@ -353,8 +353,9 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection) */ out_of_memory: up_read(&mm->mmap_sem); - if (tsk->pid == 1) { + if (is_init(tsk)) { yield(); + down_read(&mm->mmap_sem); goto survive; } printk("VM: killing process %s\n", tsk->comm); @@ -423,20 +424,13 @@ 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" - ".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" ); + EX_TABLE(0b,1b) + : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc"); __ctl_set_bit(0, 9); return rc; } @@ -449,18 +443,11 @@ 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" - ".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" ); + EX_TABLE(0b,0b) + : : "a" (&refbk), "m" (refbk) : "cc"); } asmlinkage void diff --git a/trunk/arch/s390/mm/init.c b/trunk/arch/s390/mm/init.c index cfd9b8f7a523..127044e1707c 100644 --- a/trunk/arch/s390/mm/init.c +++ b/trunk/arch/s390/mm/init.c @@ -45,26 +45,17 @@ void diag10(unsigned long addr) { if (addr >= 0x7ff00000) return; + asm volatile( #ifdef CONFIG_64BIT - 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)); + " sam31\n" + " diag %0,%0,0x10\n" + "0: sam64\n" #else - asm volatile ( - " diag %0,%0,0x10\n" + " diag %0,%0,0x10\n" "0:\n" - ".section __ex_table,\"a\"\n" - " .align 4\n" - " .long 0b, 0b\n" - ".previous\n" - : : "a" (addr)); #endif + EX_TABLE(0b,0b) + : : "a" (addr)); } void show_mem(void) @@ -156,11 +147,10 @@ void __init paging_init(void) S390_lowcore.kernel_asce = pgdir_k; /* enable virtual mapping in kernel mode */ - __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)); + __ctl_load(pgdir_k, 1, 1); + __ctl_load(pgdir_k, 7, 7); + __ctl_load(pgdir_k, 13, 13); + __raw_local_irq_ssm(ssm_mask); local_flush_tlb(); return; @@ -241,11 +231,10 @@ void __init paging_init(void) S390_lowcore.kernel_asce = pgdir_k; /* enable virtual mapping in kernel mode */ - __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)); + __ctl_load(pgdir_k, 1, 1); + __ctl_load(pgdir_k, 7, 7); + __ctl_load(pgdir_k, 13, 13); + __raw_local_irq_ssm(ssm_mask); local_flush_tlb(); diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index 1a0db1d4c952..1cc5c9b27bfd 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -8,6 +8,7 @@ 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 @@ -51,18 +52,23 @@ 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 @@ -70,17 +76,27 @@ 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. + 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. config SH_73180_SOLUTION_ENGINE bool "SolutionEngine73180" - select CPU_SUBTYPE_SH73180 - help - Select 73180 SolutionEngine if configuring for a Hitachi SH73180(SH-Mobile 3) - evaluation board. + select SOLUTION_ENGINE + 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" @@ -89,12 +105,6 @@ 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 @@ -102,19 +112,6 @@ 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 @@ -136,25 +133,9 @@ 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 @@ -184,6 +165,13 @@ 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 @@ -222,6 +210,12 @@ 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 @@ -238,35 +232,9 @@ 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_ADX || SH_SOLUTION_ENGINE || SH_UNKNOWN || SH_CAT68701 || SH_SH03 + depends on SH_SOLUTION_ENGINE || SH_UNKNOWN || 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 @@ -294,7 +262,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. For ADX, select "Area5". + "Area6" will work for most boards. config CF_AREA6 bool "Area6" @@ -316,19 +284,6 @@ 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 @@ -339,14 +294,22 @@ 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" - depends on !CPU_SH4 - default y + default y if SH4AL_DSP || !CPU_SH4 + default n help Selecting this option will enable support for SH processors that - 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. + have DSP units (ie, SH2-DSP, SH3-DSP, and SH4AL-DSP). This option must be set in order to enable the DSP. @@ -373,6 +336,9 @@ config CPU_HAS_INTEVT config CPU_HAS_PINT_IRQ bool +config CPU_HAS_MASKREG_IRQ + bool + config CPU_HAS_INTC2_IRQ bool @@ -400,16 +366,19 @@ config SH_TMU endmenu -#source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" +source "arch/sh/boards/renesas/hs7751rvoip/Kconfig" + +source "arch/sh/boards/renesas/rts7751r2d/Kconfig" -#source "arch/sh/boards/renesas/rts7751r2d/Kconfig" +source "arch/sh/boards/renesas/r7780rp/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 + default "33333333" if CPU_SUBTYPE_SH7300 || CPU_SUBTYPE_SH7770 || \ + CPU_SUBTYPE_SH7760 + default "27000000" if CPU_SUBTYPE_SH73180 || CPU_SUBTYPE_SH7343 default "66000000" if CPU_SUBTYPE_SH4_202 help This option is used to specify the peripheral clock frequency. @@ -440,10 +409,8 @@ source "arch/sh/cchips/Kconfig" config HEARTBEAT bool "Heartbeat LED" - 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 || \ + depends on SH_MPC1211 || SH_SH03 || \ + SH_BIGSUR || SOLUTION_ENGINE || \ SH_RTS7751R2D || SH_SH4202_MICRODEV || SH_LANDISK help Use the power-on LED on your machine as a load meter. The exact @@ -459,6 +426,8 @@ config ISA_DMA_API menu "Kernel features" +source kernel/Kconfig.hz + config KEXEC bool "kexec system call (EXPERIMENTAL)" depends on EXPERIMENTAL @@ -476,10 +445,6 @@ 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--- @@ -515,6 +480,8 @@ 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 @@ -636,6 +603,16 @@ 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 8fb31ab2c02c..48479e014dac 100644 --- a/trunk/arch/sh/Kconfig.debug +++ b/trunk/arch/sh/Kconfig.debug @@ -30,8 +30,35 @@ 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. @@ -112,13 +139,4 @@ 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 e467a450662b..26d62ff51a64 100644 --- a/trunk/arch/sh/Makefile +++ b/trunk/arch/sh/Makefile @@ -18,11 +18,13 @@ 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_SH2A) := sh2a +isa-$(CONFIG_CPU_SH4AL_DSP) := sh4al isa-$(CONFIG_SH_DSP) := $(isa-y)-dsp @@ -30,9 +32,11 @@ 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),) @@ -79,24 +83,19 @@ 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 @@ -104,16 +103,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_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 +incdir-$(CONFIG_SH_HP6XX) := hp6xx ifneq ($(machdir-y),) core-y += arch/sh/boards/$(machdir-y)/ @@ -137,17 +136,14 @@ 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 +include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) \ + include/config/auto.conf FORCE @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 @@ -157,7 +153,8 @@ include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/auto.conf # 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 +include/asm-sh/.mach: $(wildcard include/config/sh/*.h) \ + include/config/auto.conf FORCE @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 \ @@ -170,7 +167,7 @@ include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/auto.conf fi @touch $@ -archprepare: maketools include/asm-sh/.cpu include/asm-sh/.mach +archprepare: include/asm-sh/.cpu include/asm-sh/.mach maketools PHONY += maketools FORCE maketools: include/linux/version.h FORCE @@ -191,4 +188,3 @@ 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 deleted file mode 100644 index 5b1c531b3991..000000000000 --- a/trunk/arch/sh/boards/adx/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# 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 deleted file mode 100644 index c6ca409dff98..000000000000 --- a/trunk/arch/sh/boards/adx/irq.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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/boards/adx/setup.c b/trunk/arch/sh/boards/adx/setup.c deleted file mode 100644 index 4938d9592343..000000000000 --- a/trunk/arch/sh/boards/adx/setup.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 ac946a2201c7..1ab04da36382 100644 --- a/trunk/arch/sh/boards/bigsur/irq.c +++ b/trunk/arch/sh/boards/bigsur/irq.c @@ -19,6 +19,7 @@ * IRQ functions for a Hitachi Big Sur Evaluation Board. * */ +#undef DEBUG #include #include @@ -41,10 +42,8 @@ #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 */ @@ -60,45 +59,39 @@ 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) { - DPRINTK("Disable L1 IRQ %d\n", irq); + pr_debug("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; } - DPRINTK("disable_bigsur_l1irq: Invalid IRQ %d\n", irq); + pr_debug("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) { - DPRINTK("Enable L1 IRQ %d\n", irq); + pr_debug("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; } - DPRINTK("enable_bigsur_l1irq: Invalid IRQ %d\n", irq); + pr_debug("enable_bigsur_l1irq: Invalid IRQ %d\n", irq); } @@ -126,51 +119,45 @@ 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) { - DPRINTK("Disable L2 IRQ %d\n", irq); + if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { + pr_debug("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; } - DPRINTK("disable_bigsur_l2irq: Invalid IRQ %d\n", irq); + pr_debug("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) { - DPRINTK("Enable L2 IRQ %d\n", irq); + if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { + pr_debug("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; } - DPRINTK("enable_bigsur_l2irq: Invalid IRQ %d\n", irq); + pr_debug("enable_bigsur_l2irq: Invalid IRQ %d\n", irq); } static void mask_and_ack_bigsur(unsigned int irq) { - DPRINTK("mask_and_ack_bigsur IRQ %d\n", irq); + pr_debug("mask_and_ack_bigsur IRQ %d\n", irq); if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) disable_bigsur_l1irq(irq); else @@ -179,7 +166,7 @@ static void mask_and_ack_bigsur(unsigned int irq) static void end_bigsur_irq(unsigned int irq) { - DPRINTK("end_bigsur_irq IRQ %d\n", irq); + pr_debug("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); @@ -193,7 +180,7 @@ static unsigned int startup_bigsur_irq(unsigned int irq) u8 mask; u32 reg; - DPRINTK("startup_bigsur_irq IRQ %d\n", irq); + pr_debug("startup_bigsur_irq IRQ %d\n", irq); if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { /* Enable the L1 IRQ */ @@ -218,7 +205,7 @@ static unsigned int startup_bigsur_irq(unsigned int irq) static void shutdown_bigsur_irq(unsigned int irq) { - DPRINTK("shutdown_bigsur_irq IRQ %d\n", irq); + pr_debug("shutdown_bigsur_irq IRQ %d\n", irq); if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) disable_bigsur_l1irq(irq); else @@ -260,7 +247,7 @@ static void make_bigsur_l1isr(unsigned int irq) { disable_bigsur_l1irq(irq); return; } - DPRINTK("make_bigsur_l1isr: bad irq, %d\n", irq); + pr_debug("make_bigsur_l1isr: bad irq, %d\n", irq); return; } @@ -277,7 +264,7 @@ static void make_bigsur_l2isr(unsigned int irq) { disable_bigsur_l2irq(irq); return; } - DPRINTK("make_bigsur_l2isr: bad irq, %d\n", irq); + pr_debug("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 dfeede9da50f..9711c20fc9e4 100644 --- a/trunk/arch/sh/boards/bigsur/setup.c +++ b/trunk/arch/sh/boards/bigsur/setup.c @@ -41,31 +41,7 @@ // Big Sur Init Routines /*===========================================================*/ -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) +static void __init bigsur_setup(char **cmdline_p) { /* Mask all 2nd level IRQ's */ outb(-1,BIGSUR_IMR0); @@ -89,7 +65,24 @@ int __init platform_setup(void) outw(1, BIGSUR_ETHR+0xe); /* set the IO port to BIGSUR_ETHER_IOPORT */ outw(BIGSUR_ETHER_IOPORT<<3, BIGSUR_ETHR+0x2); - - return 0; } +/* + * 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, + + .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 deleted file mode 100644 index 52c1de0a6dfd..000000000000 --- a/trunk/arch/sh/boards/cat68701/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# 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 deleted file mode 100644 index f9a6d185fb8b..000000000000 --- a/trunk/arch/sh/boards/cat68701/irq.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 deleted file mode 100644 index 90e5175df227..000000000000 --- a/trunk/arch/sh/boards/cat68701/setup.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 deleted file mode 100644 index 1a788a85eba3..000000000000 --- a/trunk/arch/sh/boards/cqreek/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# 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 deleted file mode 100644 index 2955adc52310..000000000000 --- a/trunk/arch/sh/boards/cqreek/irq.c +++ /dev/null @@ -1,128 +0,0 @@ -/* $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 deleted file mode 100644 index eff4ed93599f..000000000000 --- a/trunk/arch/sh/boards/cqreek/setup.c +++ /dev/null @@ -1,100 +0,0 @@ -/* $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 deleted file mode 100644 index 75999aa0a2d9..000000000000 --- a/trunk/arch/sh/boards/dmida/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# -# 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 deleted file mode 100644 index d03a25f989c2..000000000000 --- a/trunk/arch/sh/boards/dmida/mach.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 b10a6b11c034..5bf01f86c20c 100644 --- a/trunk/arch/sh/boards/dreamcast/irq.c +++ b/trunk/arch/sh/boards/dreamcast/irq.c @@ -10,7 +10,6 @@ */ #include - #include #include #include @@ -26,10 +25,10 @@ event. There are three 32-bit ESRs located at 0xa05f8900 - 0xa05f6908. Event - 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. + 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. 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 @@ -57,29 +56,23 @@ /* 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 379de1629134..b3a876a3b859 100644 --- a/trunk/arch/sh/boards/dreamcast/rtc.c +++ b/trunk/arch/sh/boards/dreamcast/rtc.c @@ -1,4 +1,5 @@ -/* arch/sh/kernel/rtc-aica.c +/* + * arch/sh/boards/dreamcast/rtc.c * * Dreamcast AICA RTC routines. * @@ -10,15 +11,12 @@ */ #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 @@ -32,7 +30,8 @@ extern int (*rtc_set_time)(const time_t); * * 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 { @@ -55,7 +54,8 @@ 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_get_time = aica_rtc_gettimeofday; - rtc_set_time = aica_rtc_settimeofday; + rtc_sh_get_time = aica_rtc_gettimeofday; + rtc_sh_set_time = aica_rtc_settimeofday; } diff --git a/trunk/arch/sh/boards/dreamcast/setup.c b/trunk/arch/sh/boards/dreamcast/setup.c index 0027b80a2343..f13017eeeb27 100644 --- a/trunk/arch/sh/boards/dreamcast/setup.c +++ b/trunk/arch/sh/boards/dreamcast/setup.c @@ -22,41 +22,21 @@ #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 *, int); +void *dreamcast_consistent_alloc(struct device *, size_t, dma_addr_t *, gfp_t); int dreamcast_consistent_free(struct device *, size_t, void *, dma_addr_t); -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) +static void __init dreamcast_setup(char **cmdline_p) { int i; @@ -78,6 +58,16 @@ int __init platform_setup(void) if (gapspci_init() < 0) printk(KERN_WARNING "GAPSPCI was not detected.\n"); #endif - - return 0; } + +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) diff --git a/trunk/arch/sh/boards/ec3104/setup.c b/trunk/arch/sh/boards/ec3104/setup.c index 4b3ef16a0e96..902bc975a13e 100644 --- a/trunk/arch/sh/boards/ec3104/setup.c +++ b/trunk/arch/sh/boards/ec3104/setup.c @@ -21,22 +21,36 @@ #include #include #include - #include #include #include #include -const char *get_system_type(void) +static void __init ec3104_setup(char **cmdline_p) { - return "EC3104"; + 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); } /* * 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, @@ -48,31 +62,4 @@ 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 deleted file mode 100644 index eb753d31812e..000000000000 --- a/trunk/arch/sh/boards/harp/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# 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 deleted file mode 100644 index 96bb41c9fc55..000000000000 --- a/trunk/arch/sh/boards/harp/irq.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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 deleted file mode 100644 index aeb7b392b190..000000000000 --- a/trunk/arch/sh/boards/harp/led.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 deleted file mode 100644 index 475311390fd6..000000000000 --- a/trunk/arch/sh/boards/harp/pcidma.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 deleted file mode 100644 index 886e450ab63e..000000000000 --- a/trunk/arch/sh/boards/harp/setup.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 927fe0aa5dfa..ff1b7f5b4e91 100644 --- a/trunk/arch/sh/boards/hp6xx/Makefile +++ b/trunk/arch/sh/boards/hp6xx/Makefile @@ -2,5 +2,6 @@ # Makefile for the HP6xx specific parts of the kernel # -obj-y := mach.o setup.o - +obj-y := setup.o +obj-$(CONFIG_PM) += pm.o pm_wakeup.o +obj-$(CONFIG_APM) += hp6xx_apm.o diff --git a/trunk/arch/sh/boards/hp6xx/hp6xx_apm.c b/trunk/arch/sh/boards/hp6xx/hp6xx_apm.c new file mode 100644 index 000000000000..ad0e712c29f6 --- /dev/null +++ b/trunk/arch/sh/boards/hp6xx/hp6xx_apm.c @@ -0,0 +1,123 @@ +/* + * 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 new file mode 100644 index 000000000000..0e501bcbd7a9 --- /dev/null +++ b/trunk/arch/sh/boards/hp6xx/pm.c @@ -0,0 +1,88 @@ +/* + * 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 new file mode 100644 index 000000000000..45e9bf0b9115 --- /dev/null +++ b/trunk/arch/sh/boards/hp6xx/pm_wakeup.S @@ -0,0 +1,58 @@ +/* + * 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 71f315663cc9..60ab17ad6054 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 -const char *get_system_type(void) -{ - return "HP6xx"; -} +#define SCPCR 0xa4000116 +#define SCPDR 0xa4000136 -int __init platform_setup(void) +static void __init hp6xx_setup(char **cmdline_p) { u8 v8; u16 v; + v = inw(HD64461_STBCR); v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST | @@ -50,5 +50,51 @@ int __init platform_setup(void) v8 &= ~DACR_DAE; ctrl_outb(v8,DACR); - return 0; + 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); } + +/* + * 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 new file mode 100644 index 000000000000..89e4beb2ad47 --- /dev/null +++ b/trunk/arch/sh/boards/landisk/Makefile @@ -0,0 +1,5 @@ +# +# 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 new file mode 100644 index 000000000000..92498b4947d5 --- /dev/null +++ b/trunk/arch/sh/boards/landisk/io.c @@ -0,0 +1,250 @@ +/* + * 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 new file mode 100644 index 000000000000..a006d6443225 --- /dev/null +++ b/trunk/arch/sh/boards/landisk/irq.c @@ -0,0 +1,99 @@ +/* + * 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 new file mode 100644 index 000000000000..e75cb578a28b --- /dev/null +++ b/trunk/arch/sh/boards/landisk/landisk_pwb.c @@ -0,0 +1,348 @@ +/* + * 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 new file mode 100644 index 000000000000..35ba726a0979 --- /dev/null +++ b/trunk/arch/sh/boards/landisk/rtc.c @@ -0,0 +1,93 @@ +/* + * 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 new file mode 100644 index 000000000000..127b9e020e00 --- /dev/null +++ b/trunk/arch/sh/boards/landisk/setup.c @@ -0,0 +1,177 @@ +/* + * 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 a76c655dceee..03b123a4bba4 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_get_time = mpc1211_rtc_gettimeofday; - rtc_set_time = mpc1211_rtc_settimeofday; + rtc_sh_get_time = mpc1211_rtc_gettimeofday; + rtc_sh_set_time = mpc1211_rtc_settimeofday; } diff --git a/trunk/arch/sh/boards/mpc1211/setup.c b/trunk/arch/sh/boards/mpc1211/setup.c index 2bfb221cc35c..8eb5d4303972 100644 --- a/trunk/arch/sh/boards/mpc1211/setup.c +++ b/trunk/arch/sh/boards/mpc1211/setup.c @@ -10,14 +10,12 @@ #include #include #include - #include #include #include #include #include - /* ALI15X3 SMBus address offsets */ #define SMBHSTSTS (0 + 0x3100) #define SMBHSTCNT (1 + 0x3100) @@ -50,11 +48,6 @@ #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, @@ -80,9 +73,6 @@ 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); @@ -90,16 +80,11 @@ 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); @@ -107,7 +92,6 @@ 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) @@ -131,10 +115,6 @@ 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 deleted file mode 100644 index 29e48971bba0..000000000000 --- a/trunk/arch/sh/boards/overdrive/galileo.c +++ /dev/null @@ -1,587 +0,0 @@ -/* - * 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 deleted file mode 100644 index 4671b6b047bb..000000000000 --- a/trunk/arch/sh/boards/overdrive/io.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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 deleted file mode 100644 index 5d730c70389e..000000000000 --- a/trunk/arch/sh/boards/overdrive/irq.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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 deleted file mode 100644 index 860d7f204a4e..000000000000 --- a/trunk/arch/sh/boards/overdrive/led.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 deleted file mode 100644 index 1c9bfeda00b7..000000000000 --- a/trunk/arch/sh/boards/overdrive/pcidma.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 deleted file mode 100644 index a3a7744c2047..000000000000 --- a/trunk/arch/sh/boards/overdrive/setup.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 7fccbf2e4a1d..14bdd531f116 100644 --- a/trunk/arch/sh/boards/renesas/edosk7705/Makefile +++ b/trunk/arch/sh/boards/renesas/edosk7705/Makefile @@ -1,10 +1,6 @@ # # 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 ba143fa4afaa..ec5be0107719 100644 --- a/trunk/arch/sh/boards/renesas/edosk7705/setup.c +++ b/trunk/arch/sh/boards/renesas/edosk7705/setup.c @@ -8,19 +8,21 @@ * Modified for edosk7705 development * board by S. Dunn, 2003. */ - #include #include -#include #include -static void init_edosk7705(void); +static void __init sh_edosk7705_init_irq(void) +{ + /* This is the Ethernet interrupt */ + make_imask_irq(0x09); +} /* * The Machine Vector */ - struct sh_machine_vector mv_edosk7705 __initmv = { + .mv_name = "EDOSK7705", .mv_nr_irqs = 80, .mv_inb = sh_edosk7705_inb, @@ -37,23 +39,6 @@ struct sh_machine_vector mv_edosk7705 __initmv = { .mv_outsl = sh_edosk7705_outsl, .mv_isa_port2addr = sh_edosk7705_isa_port2addr, - .mv_init_irq = init_edosk7705, + .mv_init_irq = sh_edosk7705_init_irq, }; 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 new file mode 100644 index 000000000000..1743be477be5 --- /dev/null +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/Kconfig @@ -0,0 +1,12 @@ +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 e8b4109ace11..e626377c55ee 100644 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/Makefile +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/Makefile @@ -1,12 +1,8 @@ # # 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 := mach.o setup.o io.o irq.o led.o +obj-y := setup.o io.o irq.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 3a1abfa2fefb..9ea1136b219b 100644 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/io.c +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/io.c @@ -10,21 +10,16 @@ * 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) @@ -33,25 +28,8 @@ extern void *area6_io16_base; /* Area 6 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 -#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); -} +#define CODEC_IOMAP(a) ((unsigned long)area6_io8_base + ((a) - CODEC_IO_BASE)) static inline unsigned long port2adr(unsigned int port) { @@ -59,9 +37,10 @@ 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(port2adr, (unsigned long)port); + maybebadio((unsigned long)port); return port; } @@ -78,25 +57,10 @@ static inline int shifted_port(unsigned long port) } #if defined(CONFIG_HS7751RVOIP_CODEC) -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))) +#define codec_port(port) \ + ((CODEC_IO_BASE <= (port)) && ((port) < (CODEC_IO_BASE + 0x20))) #else -#define CHECK_SH7751_PCIIO(port) (0) +#define codec_port(port) (0) #endif /* @@ -109,15 +73,13 @@ codec_port(unsigned long port) unsigned char hs7751rvoip_inb(unsigned long port) { if (PXSEG(port)) - return *(volatile unsigned char *)port; -#if defined(CONFIG_HS7751RVOIP_CODEC) + return ctrl_inb(port); else if (codec_port(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); + return ctrl_inb(CODEC_IOMAP(port)); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return ctrl_inb(pci_ioaddr(port)); else - return (*(volatile unsigned short *)port2adr(port) & 0xff); + return ctrl_inw(port2adr(port)) & 0xff; } unsigned char hs7751rvoip_inb_p(unsigned long port) @@ -125,38 +87,36 @@ unsigned char hs7751rvoip_inb_p(unsigned long port) unsigned char v; if (PXSEG(port)) - v = *(volatile unsigned char *)port; -#if defined(CONFIG_HS7751RVOIP_CODEC) + v = ctrl_inb(port); else if (codec_port(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); + v = ctrl_inb(CODEC_IOMAP(port)); + else if (is_pci_ioaddr(port) || shifted_port(port)) + v = ctrl_inb(pci_ioaddr(port)); else - v = (*(volatile unsigned short *)port2adr(port) & 0xff); - delay(); + v = ctrl_inw(port2adr(port)) & 0xff; + ctrl_delay(); return v; } unsigned short hs7751rvoip_inw(unsigned long port) { if (PXSEG(port)) - return *(volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - return *(volatile unsigned short *)PCI_IOMAP(port); + return ctrl_inw(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return ctrl_inw(pci_ioaddr(port)); else - maybebadio(inw, port); + maybebadio(port); return 0; } unsigned int hs7751rvoip_inl(unsigned long port) { if (PXSEG(port)) - return *(volatile unsigned long *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - return *(volatile unsigned long *)PCI_IOMAP(port); + return ctrl_inl(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return ctrl_inl(pci_ioaddr(port)); else - maybebadio(inl, port); + maybebadio(port); return 0; } @@ -164,146 +124,160 @@ void hs7751rvoip_outb(unsigned char value, unsigned long port) { if (PXSEG(port)) - *(volatile unsigned char *)port = value; -#if defined(CONFIG_HS7751RVOIP_CODEC) + ctrl_outb(value, port); else if (codec_port(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; + ctrl_outb(value, CODEC_IOMAP(port)); + else if (is_pci_ioaddr(port) || shifted_port(port)) + ctrl_outb(value, pci_ioaddr(port)); else - *(volatile unsigned short *)port2adr(port) = value; + ctrl_outb(value, port2adr(port)); } void hs7751rvoip_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) - *(volatile unsigned char *)port = value; -#if defined(CONFIG_HS7751RVOIP_CODEC) + ctrl_outb(value, port); else if (codec_port(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; + ctrl_outb(value, CODEC_IOMAP(port)); + else if (is_pci_ioaddr(port) || shifted_port(port)) + ctrl_outb(value, pci_ioaddr(port)); else - *(volatile unsigned short *)port2adr(port) = value; - delay(); + ctrl_outw(value, port2adr(port)); + + ctrl_delay(); } void hs7751rvoip_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) - *(volatile unsigned short *)port = value; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *(unsigned short *)PCI_IOMAP(port) = value; + ctrl_outw(value, port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + ctrl_outw(value, pci_ioaddr(port)); else - maybebadio(outw, port); + maybebadio(port); } void hs7751rvoip_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) - *(volatile unsigned long *)port = value; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *((unsigned long *)PCI_IOMAP(port)) = value; + ctrl_outl(value, port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + ctrl_outl(value, pci_ioaddr(port)); else - maybebadio(outl, port); + maybebadio(port); } void hs7751rvoip_insb(unsigned long port, void *addr, unsigned long count) { + u8 *buf = addr; + if (PXSEG(port)) - while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port; -#if defined(CONFIG_HS7751RVOIP_CODEC) + while (count--) + *buf++ = ctrl_inb(port); else if (codec_port(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++ = ctrl_inb(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 *) addr)++ = *bp; + while (count--) + *buf++ = *bp; } else { - volatile __u16 *p = (volatile unsigned short *)port2adr(port); + volatile u16 *p = (volatile u16 *)port2adr(port); - while (count--) *((unsigned char *) addr)++ = *p & 0xff; + while (count--) + *buf++ = *p & 0xff; } } void hs7751rvoip_insw(unsigned long port, void *addr, unsigned long count) { - volatile __u16 *p; + volatile u16 *p; + u16 *buf = addr; if (PXSEG(port)) - p = (volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - p = (volatile unsigned short *)PCI_IOMAP(port); + p = (volatile u16 *)port; + else if (is_pci_ioaddr(port) || shifted_port(port)) + p = (volatile u16 *)pci_ioaddr(port); else - p = (volatile unsigned short *)port2adr(port); - while (count--) *((__u16 *) addr)++ = *p; + p = (volatile u16 *)port2adr(port); + while (count--) + *buf++ = *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); - while (count--) *((__u32 *) addr)++ = *p; + if (is_pci_ioaddr(port) || shifted_port(port)) { + volatile u32 *p = (volatile u32 *)pci_ioaddr(port); + u32 *buf = addr; + + while (count--) + *buf++ = *p; } else - maybebadio(insl, port); + maybebadio(port); } void hs7751rvoip_outsb(unsigned long port, const void *addr, unsigned long count) { + const u8 *buf = addr; + if (PXSEG(port)) - while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++; -#if defined(CONFIG_HS7751RVOIP_CODEC) + while (count--) + ctrl_outb(*buf++, port); else if (codec_port(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--) + 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--) *bp = *((volatile unsigned char *) addr)++; + while (count--) + *bp = *buf++; } else { - volatile __u16 *p = (volatile unsigned short *)port2adr(port); + volatile u16 *p = (volatile u16 *)port2adr(port); - while (count--) *p = *((unsigned char *) addr)++; + while (count--) + *p = *buf++; } } void hs7751rvoip_outsw(unsigned long port, const void *addr, unsigned long count) { - volatile __u16 *p; + volatile u16 *p; + const u16 *buf = addr; if (PXSEG(port)) - p = (volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - p = (volatile unsigned short *)PCI_IOMAP(port); + p = (volatile u16 *)port; + else if (is_pci_ioaddr(port) || shifted_port(port)) + p = (volatile u16 *)pci_ioaddr(port); else - p = (volatile unsigned short *)port2adr(port); - while (count--) *p = *((__u16 *) addr)++; + p = (volatile u16 *)port2adr(port); + + while (count--) + *p = *buf++; } void hs7751rvoip_outsl(unsigned long port, const void *addr, unsigned long count) { - if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { - volatile __u32 *p = (__u32 *)PCI_IOMAP(port); + const u32 *buf = addr; - while (count--) *p = *((__u32 *) addr)++; + if (is_pci_ioaddr(port) || shifted_port(port)) { + volatile u32 *p = (volatile u32 *)pci_ioaddr(port); + + while (count--) + *p = *buf++; } else - maybebadio(outsl, port); + maybebadio(port); } -void *hs7751rvoip_ioremap(unsigned long offset, unsigned long size) +void __iomem *hs7751rvoip_ioport_map(unsigned long port, unsigned int size) { - if (offset >= 0xfd000000) - return (void *)offset; - else - return (void *)P2SEGADDR(offset); -} -EXPORT_SYMBOL(hs7751rvoip_ioremap); + 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); -unsigned long hs7751rvoip_isa_port2addr(unsigned long offset) -{ - return port2adr(offset); + return (void __iomem *)port2adr(port); } diff --git a/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c b/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c index 705b7ddcb0d2..c617b188258a 100644 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c @@ -35,30 +35,24 @@ 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 deleted file mode 100644 index b6608fff9f38..000000000000 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/led.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 deleted file mode 100644 index caf967f77c61..000000000000 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/mach.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 29fb5ff70fb5..0414c15c3458 100644 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/setup.c +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/setup.c @@ -1,44 +1,38 @@ /* - * linux/arch/sh/kernel/setup_hs7751rvoip.c + * Renesas Technology Sales HS7751RVoIP Support. * * 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 -#include -#include - -/* defined in mm/ioremap.c */ -extern void * p3_ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags); - -unsigned int debug_counter; - -const char *get_system_type(void) +static void __init hs7751rvoip_init_irq(void) { - return "HS7751RVoIP"; +#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 + + init_hs7751rvoip_IRQ(); } -/* - * Initialize the board - */ -void __init platform_setup(void) +static void hs7751rvoip_power_off(void) { - printk(KERN_INFO "Renesas Technology Sales HS7751RVoIP-2 support.\n"); - ctrl_outb(0xf0, PA_OUTPORTR); - debug_counter = 0; + ctrl_outw(ctrl_inw(PA_OUTPORTR) & 0xffdf, PA_OUTPORTR); } void *area5_io8_base; @@ -46,16 +40,15 @@ void *area6_io8_base; void *area5_io16_base; void *area6_io16_base; -int __init cf_init(void) +static int __init hs7751rvoip_cf_init(void) { pgprot_t prot; - unsigned long paddrbase, psize; + unsigned long paddrbase; /* 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, psize, prot.pgprot); + area5_io16_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot); if (!area5_io16_base) { printk("allocate_cf_area : can't open CF I/O window!\n"); return -ENOMEM; @@ -64,19 +57,18 @@ int __init 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, psize, prot.pgprot); + area6_io8_base = p3_ioremap(paddrbase, PAGE_SIZE, 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, psize, prot.pgprot); + area6_io16_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot); if (!area6_io16_base) { printk("allocate_cf_area : can't open CODEC I/O 16bit window!\n"); return -ENOMEM; @@ -85,4 +77,46 @@ int __init cf_init(void) return 0; } -__initcall (cf_init); +/* + * 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) diff --git a/trunk/arch/sh/boards/renesas/r7780rp/Kconfig b/trunk/arch/sh/boards/renesas/r7780rp/Kconfig new file mode 100644 index 000000000000..c26d9813d239 --- /dev/null +++ b/trunk/arch/sh/boards/renesas/r7780rp/Kconfig @@ -0,0 +1,14 @@ +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 new file mode 100644 index 000000000000..f1776d027978 --- /dev/null +++ b/trunk/arch/sh/boards/renesas/r7780rp/Makefile @@ -0,0 +1,6 @@ +# +# 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 new file mode 100644 index 000000000000..db92d6e6ae99 --- /dev/null +++ b/trunk/arch/sh/boards/renesas/r7780rp/io.c @@ -0,0 +1,301 @@ +/* + * 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 new file mode 100644 index 000000000000..61d5e5d3c294 --- /dev/null +++ b/trunk/arch/sh/boards/renesas/r7780rp/irq.c @@ -0,0 +1,117 @@ +/* + * 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 new file mode 100644 index 000000000000..9f02766b6f53 --- /dev/null +++ b/trunk/arch/sh/boards/renesas/r7780rp/led.c @@ -0,0 +1,45 @@ +/* + * 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 new file mode 100644 index 000000000000..7780d1fb13ff --- /dev/null +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/Kconfig @@ -0,0 +1,12 @@ +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 daa53334bdc3..686fc9ea5989 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/Makefile +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/Makefile @@ -1,10 +1,6 @@ # # 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 123abbbc91e0..135aa0b5e62d 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/io.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/io.c @@ -1,6 +1,4 @@ /* - * linux/arch/sh/kernel/io_rts7751r2d.c - * * Copyright (C) 2001 Ian da Silva, Jeremy Siegel * Based largely on io_se.c. * @@ -10,17 +8,13 @@ * 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. @@ -28,22 +22,6 @@ * 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) @@ -52,7 +30,7 @@ static inline unsigned long port2adr(unsigned int port) else return (PA_AREA5_IO + 0x1000 + ((port-0x1f0) << 1)); else - maybebadio(port2adr, (unsigned long)port); + maybebadio((unsigned long)port); return port; } @@ -81,17 +59,6 @@ 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))) @@ -112,8 +79,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 (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - return *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return *(volatile unsigned char *)pci_ioaddr(port); else return (*(volatile unsigned short *)port2adr(port) & 0xff); } @@ -126,11 +93,12 @@ 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 (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - v = *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + v = *(volatile unsigned char *)pci_ioaddr(port); else v = (*(volatile unsigned short *)port2adr(port) & 0xff); - delay(); + + ctrl_delay(); return v; } @@ -138,13 +106,13 @@ unsigned char rts7751r2d_inb_p(unsigned long port) unsigned short rts7751r2d_inw(unsigned long port) { if (CHECK_AX88796L_PORT(port)) - maybebadio(inw, port); + maybebadio(port); else if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - return *(volatile unsigned short *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return *(volatile unsigned short *)pci_ioaddr(port); else - maybebadio(inw, port); + maybebadio(port); return 0; } @@ -152,13 +120,13 @@ unsigned short rts7751r2d_inw(unsigned long port) unsigned int rts7751r2d_inl(unsigned long port) { if (CHECK_AX88796L_PORT(port)) - maybebadio(inl, port); + maybebadio(port); else if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - return *(volatile unsigned long *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + return *(volatile unsigned long *)pci_ioaddr(port); else - maybebadio(inl, port); + maybebadio(port); return 0; } @@ -169,8 +137,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 (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *(volatile unsigned char *)PCI_IOMAP(port) = value; + else if (is_pci_ioaddr(port) || shifted_port(port)) + *(volatile unsigned char *)pci_ioaddr(port) = value; else *(volatile unsigned short *)port2adr(port) = value; } @@ -181,143 +149,152 @@ 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 (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *(volatile unsigned char *)PCI_IOMAP(port) = value; + else if (is_pci_ioaddr(port) || shifted_port(port)) + *(volatile unsigned char *)pci_ioaddr(port) = value; else *(volatile unsigned short *)port2adr(port) = value; - delay(); + + ctrl_delay(); } void rts7751r2d_outw(unsigned short value, unsigned long port) { if (CHECK_AX88796L_PORT(port)) - maybebadio(outw, port); + maybebadio(port); else if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *(volatile unsigned short *)PCI_IOMAP(port) = value; + else if (is_pci_ioaddr(port) || shifted_port(port)) + *(volatile unsigned short *)pci_ioaddr(port) = value; else - maybebadio(outw, port); + maybebadio(port); } void rts7751r2d_outl(unsigned int value, unsigned long port) { if (CHECK_AX88796L_PORT(port)) - maybebadio(outl, port); + maybebadio(port); else if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - *(volatile unsigned long *)PCI_IOMAP(port) = value; + else if (is_pci_ioaddr(port) || shifted_port(port)) + *(volatile unsigned long *)pci_ioaddr(port) = value; else - maybebadio(outl, port); + maybebadio(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--) *s++ = *p & 0xff; + while (count--) + ctrl_outb(*p & 0xff, a++); } else if (PXSEG(port)) - 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; + 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++); } else { p = (volatile unsigned short *)port2adr(port); - while (count--) *s++ = *p & 0xff; + while (count--) + ctrl_outb(*p & 0xff, a++); } } 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 (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - p = (volatile unsigned short *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + p = (volatile unsigned short *)pci_ioaddr(port); else p = (volatile unsigned short *)port2adr(port); - while (count--) *s++ = *p; + while (count--) + ctrl_outw(*p, a++); } void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count) { if (CHECK_AX88796L_PORT(port)) - 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; + 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; + } } else - maybebadio(insl, port); + maybebadio(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 = *s++; + while (count--) + *p = ctrl_inb(a++); } else if (PXSEG(port)) - 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++; + 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++); } else { p = (volatile unsigned short *)port2adr(port); - while (count--) *p = *s++; + while (count--) + *p = ctrl_inb(a++); } } 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 (CHECK_SH7751_PCIIO(port) || shifted_port(port)) - p = (volatile unsigned short *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port) || shifted_port(port)) + p = (volatile unsigned short *)pci_ioaddr(port); else p = (volatile unsigned short *)port2adr(port); - while (count--) *p = *s++; + + while (count--) { + ctrl_outw(*p, a); + a += 2; + } } void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count) { if (CHECK_AX88796L_PORT(port)) - 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++; + 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; + } } else - maybebadio(outsl, port); -} - -void *rts7751r2d_ioremap(unsigned long offset, unsigned long size) -{ - if (offset >= 0xfd000000) - return (void *)offset; - else - return (void *)P2SEGADDR(offset); + maybebadio(port); } -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 154535440bbf..c915e7a3693a 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c @@ -41,30 +41,24 @@ 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 4d16de71fac1..e14a13d12d4a 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/led.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/led.c @@ -12,8 +12,6 @@ #include #include -extern unsigned int debug_counter; - #ifdef CONFIG_HEARTBEAT #include @@ -55,12 +53,3 @@ 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 deleted file mode 100644 index 5ed9e97ea197..000000000000 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/mach.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 2587fd1a0240..20597a6e6702 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/setup.c @@ -1,31 +1,142 @@ /* - * linux/arch/sh/kernel/setup_rts7751r2d.c - * - * Copyright (C) 2000 Kazumoto Kojima - * * Renesas Technology Sales RTS7751R2D Support. * - * Modified for RTS7751R2D by - * Atom Create Engineering Co., Ltd. 2002. + * Copyright (C) 2002 Atom Create Engineering Co., Ltd. + * 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 +#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, +}; -unsigned int debug_counter; +static int __init rts7751r2d_devices_setup(void) +{ + return platform_add_devices(rts7751r2d_devices, + ARRAY_SIZE(rts7751r2d_devices)); +} -const char *get_system_type(void) +static void rts7751r2d_power_off(void) { - return "RTS7751R2D"; + ctrl_outw(0x0001, PA_POWOFF); } /* * Initialize the board */ -void __init platform_setup(void) +static void __init rts7751r2d_setup(char **cmdline_p) { - printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n"); + device_initcall(rts7751r2d_devices_setup); + ctrl_outw(0x0000, PA_OUTPORT); - debug_counter = 0; + pm_power_off = rts7751r2d_power_off; + + voyagergx_serial_init(); + + printk(KERN_INFO "Renesas Technology Sales RTS7751R2D support.\n"); } + +/* + * 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 new file mode 100644 index 000000000000..77037567633b --- /dev/null +++ b/trunk/arch/sh/boards/renesas/sh7710voipgw/Makefile @@ -0,0 +1 @@ +obj-y := setup.o diff --git a/trunk/arch/sh/boards/renesas/sh7710voipgw/setup.c b/trunk/arch/sh/boards/renesas/sh7710voipgw/setup.c new file mode 100644 index 000000000000..e57e7afab8c6 --- /dev/null +++ b/trunk/arch/sh/boards/renesas/sh7710voipgw/setup.c @@ -0,0 +1,109 @@ +/* + * 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 cf979011aa94..cde6e5d192c4 100644 --- a/trunk/arch/sh/boards/renesas/systemh/io.c +++ b/trunk/arch/sh/boards/renesas/systemh/io.c @@ -5,66 +5,25 @@ * 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)); -#if 0 - else - return (volatile __u16 *) (PA_SUPERIO + (port << 1)); -#endif - maybebadio(name,(unsigned long)port); + maybebadio((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) @@ -76,8 +35,8 @@ unsigned char sh7751systemh_inb(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned char *)pci_ioaddr(port); else if (port <= 0x3F1) return *(volatile unsigned char *)ETHER_IOMAP(port); else @@ -90,13 +49,13 @@ unsigned char sh7751systemh_inb_p(unsigned long port) if (PXSEG(port)) v = *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port)) - v = *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + v = *(volatile unsigned char *)pci_ioaddr(port); else if (port <= 0x3F1) v = *(volatile unsigned char *)ETHER_IOMAP(port); else v = (*port2adr(port))&0xff; - delay(); + ctrl_delay(); return v; } @@ -104,14 +63,14 @@ unsigned short sh7751systemh_inw(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned short *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned short *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else if (port <= 0x3F1) return *(volatile unsigned int *)ETHER_IOMAP(port); else - maybebadio(inw, port); + maybebadio(port); return 0; } @@ -119,14 +78,14 @@ unsigned int sh7751systemh_inl(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned int *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned int *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else if (port <= 0x3F1) return *(volatile unsigned int *)ETHER_IOMAP(port); else - maybebadio(inl, port); + maybebadio(port); return 0; } @@ -135,8 +94,8 @@ void sh7751systemh_outb(unsigned char value, unsigned long port) if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned char*)pci_ioaddr(port)) = value; else if (port <= 0x3F1) *(volatile unsigned char *)ETHER_IOMAP(port) = value; else @@ -147,37 +106,37 @@ void sh7751systemh_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned char*)pci_ioaddr(port)) = value; else if (port <= 0x3F1) *(volatile unsigned char *)ETHER_IOMAP(port) = value; else *(port2adr(port)) = value; - delay(); + ctrl_delay(); } void sh7751systemh_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned short *)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned short *)pci_ioaddr(port)) = value; else if (port >= 0x2000) *port2adr(port) = value; else if (port <= 0x3F1) *(volatile unsigned short *)ETHER_IOMAP(port) = value; else - maybebadio(outw, port); + maybebadio(port); } void sh7751systemh_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned long*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned long*)pci_ioaddr(port)) = value; else - maybebadio(outl, port); + maybebadio(port); } void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count) @@ -194,7 +153,7 @@ void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count) void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count) { - maybebadio(insl, port); + maybebadio(port); } void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count) @@ -211,73 +170,5 @@ 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(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; + maybebadio(port); } diff --git a/trunk/arch/sh/boards/renesas/systemh/irq.c b/trunk/arch/sh/boards/renesas/systemh/irq.c index 8372d967f601..8d016dae2333 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,12 +57,9 @@ 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); @@ -70,23 +67,18 @@ 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 826fa3d7669c..a8467bf90c25 100644 --- a/trunk/arch/sh/boards/renesas/systemh/setup.c +++ b/trunk/arch/sh/boards/renesas/systemh/setup.c @@ -15,28 +15,21 @@ * 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 */ -void __init init_7751systemh_IRQ(void) +static void __init sh7751systemh_init_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, @@ -60,21 +53,6 @@ struct sh_machine_vector mv_7751systemh __initmv = { .mv_outsw = sh7751systemh_outsw, .mv_outsl = sh7751systemh_outsl, - .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, + .mv_init_irq = sh7751system_init_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 bea6c572ad82..a3a37c9aad2e 100644 --- a/trunk/arch/sh/boards/saturn/setup.c +++ b/trunk/arch/sh/boards/saturn/setup.c @@ -9,22 +9,17 @@ */ #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, @@ -33,11 +28,4 @@ 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 f449a94ddffd..8a03d7a52a7c 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,6 +99,7 @@ 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, @@ -110,6 +111,7 @@ static struct iop laniop = { .outb = simple_outb, .outw = simple_outw, }; +#endif /* NE2000 pc card NIC */ static struct iop neiop = { @@ -123,6 +125,7 @@ static struct iop neiop = { .outw = simple_outw, }; +#ifdef CONFIG_IDE /* CF in CF slot */ static struct iop cfiop = { .base = 0xb0600000, @@ -132,12 +135,13 @@ static struct iop cfiop = { .outb = pcc_outb, .outw = simple_outw, }; +#endif static __inline__ struct iop * port2iop(unsigned long port) { if (0) ; -#if defined(CONFIG_SMC91111) +#if defined(CONFIG_SMC91X) 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 216a78d1a108..ad1034f98a29 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 ad51f0a9c1e3..4d03bb7774be 100644 --- a/trunk/arch/sh/boards/se/7300/led.c +++ b/trunk/arch/sh/boards/se/7300/led.c @@ -12,24 +12,10 @@ */ #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); - } -} - +#include /* 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 ebcd98d4c081..6f082a722d42 100644 --- a/trunk/arch/sh/boards/se/7300/setup.c +++ b/trunk/arch/sh/boards/se/7300/setup.c @@ -9,23 +9,16 @@ #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, @@ -53,13 +46,4 @@ 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 755df5ac4a4e..72715575458b 100644 --- a/trunk/arch/sh/boards/se/73180/io.c +++ b/trunk/arch/sh/boards/se/73180/io.c @@ -99,6 +99,7 @@ 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, @@ -110,6 +111,7 @@ static struct iop laniop = { .outb = simple_outb, .outw = simple_outw, }; +#endif /* NE2000 pc card NIC */ static struct iop neiop = { @@ -123,6 +125,7 @@ static struct iop neiop = { .outw = simple_outw, }; +#ifdef CONFIG_IDE /* CF in CF slot */ static struct iop cfiop = { .base = 0xb0600000, @@ -132,12 +135,13 @@ static struct iop cfiop = { .outb = pcc_outb, .outw = simple_outw, }; +#endif static __inline__ struct iop * port2iop(unsigned long port) { if (0) ; -#if defined(CONFIG_SMC91111) +#if defined(CONFIG_SMC91X) 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 4344d0ef24aa..2c62b8ea350e 100644 --- a/trunk/arch/sh/boards/se/73180/irq.c +++ b/trunk/arch/sh/boards/se/73180/irq.c @@ -7,7 +7,6 @@ * Modified for SH-Mobile SolutionEngine 73180 Support * by YOSHII Takashi * - * */ #include @@ -16,14 +15,6 @@ #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 610439fde6ee..4b72e9a3ead9 100644 --- a/trunk/arch/sh/boards/se/73180/led.c +++ b/trunk/arch/sh/boards/se/73180/led.c @@ -14,21 +14,8 @@ #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 cdb7b5f8d942..b38ef50a160a 100644 --- a/trunk/arch/sh/boards/se/73180/setup.c +++ b/trunk/arch/sh/boards/se/73180/setup.c @@ -11,23 +11,17 @@ #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, @@ -51,17 +45,9 @@ 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 new file mode 100644 index 000000000000..4291069c0b4f --- /dev/null +++ b/trunk/arch/sh/boards/se/7343/Makefile @@ -0,0 +1,7 @@ +# +# 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 new file mode 100644 index 000000000000..646661a146ad --- /dev/null +++ b/trunk/arch/sh/boards/se/7343/io.c @@ -0,0 +1,275 @@ +/* + * 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 new file mode 100644 index 000000000000..b41e3d4ea37c --- /dev/null +++ b/trunk/arch/sh/boards/se/7343/irq.c @@ -0,0 +1,193 @@ +/* + * 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 new file mode 100644 index 000000000000..6a439cf83e46 --- /dev/null +++ b/trunk/arch/sh/boards/se/7343/led.c @@ -0,0 +1,46 @@ +/* + * 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 new file mode 100644 index 000000000000..787322291fb3 --- /dev/null +++ b/trunk/arch/sh/boards/se/7343/setup.c @@ -0,0 +1,84 @@ +#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 be89a73cc418..9a5035f80ec0 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 := 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/se/770x/io.c b/trunk/arch/sh/boards/se/770x/io.c index 9a39ee963143..9941949331ab 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.5 2004/02/22 23:08:43 kkojima Exp $ +/* $Id: io.c,v 1.7 2006/02/05 21:55:29 lethal 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,11 +20,6 @@ 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. */ @@ -52,10 +47,6 @@ 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) @@ -76,7 +67,7 @@ unsigned char se_inb_p(unsigned long port) v = (*port2adr(port) >> 8); else v = (*port2adr(port))&0xff; - delay(); + ctrl_delay(); return v; } @@ -86,13 +77,13 @@ unsigned short se_inw(unsigned long port) (sh_pcic_io_start <= port && port <= sh_pcic_io_stop)) return *port2adr(port); else - maybebadio(inw, port); + maybebadio(port); return 0; } unsigned int se_inl(unsigned long port) { - maybebadio(inl, port); + maybebadio(port); return 0; } @@ -114,7 +105,7 @@ void se_outb_p(unsigned char value, unsigned long port) *(port2adr(port)) = value << 8; else *(port2adr(port)) = value; - delay(); + ctrl_delay(); } void se_outw(unsigned short value, unsigned long port) @@ -123,12 +114,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(outw, port); + maybebadio(port); } void se_outl(unsigned int value, unsigned long port) { - maybebadio(outl, port); + maybebadio(port); } void se_insb(unsigned long port, void *addr, unsigned long count) @@ -159,7 +150,7 @@ void se_insw(unsigned long port, void *addr, unsigned long count) void se_insl(unsigned long port, void *addr, unsigned long count) { - maybebadio(insl, port); + maybebadio(port); } void se_outsb(unsigned long port, const void *addr, unsigned long count) @@ -190,37 +181,5 @@ 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(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; + maybebadio(port); } diff --git a/trunk/arch/sh/boards/se/770x/irq.c b/trunk/arch/sh/boards/se/770x/irq.c index 3e558716ce10..cff6700bbafd 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 3cddbda025fc..daf7b1ee786a 100644 --- a/trunk/arch/sh/boards/se/770x/led.c +++ b/trunk/arch/sh/boards/se/770x/led.c @@ -9,22 +9,8 @@ * 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) @@ -64,4 +50,3 @@ 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 deleted file mode 100644 index 6ec07bd3dcf1..000000000000 --- a/trunk/arch/sh/boards/se/770x/mach.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 7d1a071727cc..f3f82b7c8217 100644 --- a/trunk/arch/sh/boards/se/770x/setup.c +++ b/trunk/arch/sh/boards/se/770x/setup.c @@ -7,15 +7,17 @@ * Hitachi SolutionEngine Support. * */ - #include #include - #include #include #include -#include -#include +#include +#include +#include + +void heartbeat_se(void); +void init_se_IRQ(void); /* * Configure the Super I/O chip @@ -26,7 +28,8 @@ static void __init smsc_config(int index, int data) outb_p(data, DATA_PORT); } -static void __init init_smsc(void) +/* XXX: Another candidate for a more generic cchip machine vector */ +static void __init smsc_setup(char **cmdline_p) { outb_p(CONFIG_ENTER, CONFIG_PORT); outb_p(CONFIG_ENTER, CONFIG_PORT); @@ -69,16 +72,46 @@ static void __init init_smsc(void) outb_p(CONFIG_EXIT, CONFIG_PORT); } -const char *get_system_type(void) -{ - return "SolutionEngine"; -} - /* - * Initialize the board + * The Machine Vector */ -void __init platform_setup(void) -{ - init_smsc(); - /* XXX: RTC setting comes here */ -} +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) diff --git a/trunk/arch/sh/boards/se/7751/Makefile b/trunk/arch/sh/boards/se/7751/Makefile index ce7ca247f84d..188900c48321 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 := mach.o setup.o io.o irq.o led.o +obj-y := setup.o io.o irq.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 99041b269261..e8d846cec89d 100644 --- a/trunk/arch/sh/boards/se/7751/io.c +++ b/trunk/arch/sh/boards/se/7751/io.c @@ -1,6 +1,4 @@ -/* - * linux/arch/sh/kernel/io_7751se.c - * +/* * Copyright (C) 2001 Ian da Silva, Jeremy Siegel * Based largely on io_se.c. * @@ -10,96 +8,21 @@ * placeholder code from io_se.c left in with the * expectation of later SuperIO and PCMCIA access. */ - #include #include +#include #include -#include +#include #include -#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) +static inline volatile u16 *port2adr(unsigned int port) { if (port >= 0x2000) return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); -#if 0 - else - return (volatile __u16 *) (PA_SUPERIO + (port << 1)); -#endif - maybebadio(name,(unsigned long)port); + maybebadio((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) @@ -111,10 +34,10 @@ unsigned char sh7751se_inb(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned char *)pci_ioaddr(port); else - return (*port2adr(port))&0xff; + return (*port2adr(port)) & 0xff; } unsigned char sh7751se_inb_p(unsigned long port) @@ -123,11 +46,11 @@ unsigned char sh7751se_inb_p(unsigned long port) if (PXSEG(port)) v = *(volatile unsigned char *)port; - else if (CHECK_SH7751_PCIIO(port)) - v = *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + v = *(volatile unsigned char *)pci_ioaddr(port); else - v = (*port2adr(port))&0xff; - delay(); + v = (*port2adr(port)) & 0xff; + ctrl_delay(); return v; } @@ -135,12 +58,12 @@ unsigned short sh7751se_inw(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned short *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned short *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else - maybebadio(inw, port); + maybebadio(port); return 0; } @@ -148,12 +71,12 @@ unsigned int sh7751se_inl(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned int *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned int *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else - maybebadio(inl, port); + maybebadio(port); return 0; } @@ -162,8 +85,8 @@ void sh7751se_outb(unsigned char value, unsigned long port) if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned char*)pci_ioaddr(port)) = value; else *(port2adr(port)) = value; } @@ -172,73 +95,41 @@ void sh7751se_outb_p(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned char*)pci_ioaddr(port)) = value; else *(port2adr(port)) = value; - delay(); + ctrl_delay(); } void sh7751se_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned short *)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned short *)pci_ioaddr(port)) = value; else if (port >= 0x2000) *port2adr(port) = value; else - maybebadio(outw, port); + maybebadio(port); } void sh7751se_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned long*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned long*)pci_ioaddr(port)) = value; else - maybebadio(outl, port); + maybebadio(port); } void sh7751se_insl(unsigned long port, void *addr, unsigned long count) { - maybebadio(insl, port); + maybebadio(port); } void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count) { - 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; + maybebadio(port); } diff --git a/trunk/arch/sh/boards/se/7751/irq.c b/trunk/arch/sh/boards/se/7751/irq.c index bf6c023615df..c607b0a48479 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 a878726d3c7c..ff0355dea81b 100644 --- a/trunk/arch/sh/boards/se/7751/led.c +++ b/trunk/arch/sh/boards/se/7751/led.c @@ -8,23 +8,8 @@ * * 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) @@ -64,4 +49,3 @@ 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 deleted file mode 100644 index 62d8d3e62590..000000000000 --- a/trunk/arch/sh/boards/se/7751/mach.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 48dc5aee67d4..73e826310ba8 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,78 +11,15 @@ #include #include - -#include #include #include -#include +#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"; -} +void heartbeat_7751se(void); +void init_7751se_IRQ(void); #ifdef CONFIG_SH_KGDB +#include static int kgdb_uart_setup(void); static struct kgdb_sermap kgdb_uart_sermap = { "ttyS", 0, kgdb_uart_setup, NULL }; @@ -91,7 +28,7 @@ static struct kgdb_sermap kgdb_uart_sermap = /* * Initialize the board */ -void __init platform_setup(void) +static void __init sh7751se_setup(char **cmdline_p) { /* Call init_smsc() replacement to set up SuperIO. */ /* XXX: RTC setting comes here */ @@ -225,3 +162,37 @@ 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 d609863cfe53..0a9266bb51c5 100644 --- a/trunk/arch/sh/boards/sh03/rtc.c +++ b/trunk/arch/sh/boards/sh03/rtc.c @@ -10,9 +10,10 @@ #include #include #include -#include #include #include +#include +#include #define RTC_BASE 0xb0000000 #define RTC_SEC1 (RTC_BASE + 0) @@ -34,8 +35,6 @@ #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) @@ -128,6 +127,6 @@ int sh03_rtc_settimeofday(const time_t secs) void sh03_time_init(void) { - rtc_get_time = sh03_rtc_gettimeofday; - rtc_set_time = sh03_rtc_settimeofday; + rtc_sh_get_time = sh03_rtc_gettimeofday; + rtc_sh_set_time = sh03_rtc_settimeofday; } diff --git a/trunk/arch/sh/boards/sh03/setup.c b/trunk/arch/sh/boards/sh03/setup.c index 60290f8f289c..6c310587ddfe 100644 --- a/trunk/arch/sh/boards/sh03/setup.c +++ b/trunk/arch/sh/boards/sh03/setup.c @@ -7,22 +7,13 @@ #include #include -#include -#include #include +#include #include #include #include -#include "../../drivers/pci/pci-sh7751.h" -extern void (*board_time_init)(void); - -const char *get_system_type(void) -{ - return "Interface CTP/PCI-SH03)"; -} - -void init_sh03_IRQ(void) +static void __init init_sh03_IRQ(void) { ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR); @@ -34,38 +25,34 @@ void init_sh03_IRQ(void) extern void *cf_io_base; -unsigned long sh03_isa_port2addr(unsigned long port) +static void __iomem *sh03_ioport_map(unsigned long port, unsigned int size) { if (PXSEG(port)) - return port; + return (void __iomem *)port; /* CompactFlash (IDE) */ - if (((port >= 0x1f0) && (port <= 0x1f7)) || (port == 0x3f6)) { - return (unsigned long)cf_io_base + port; - } - return port + SH7751_PCI_IO_BASE; + if (((port >= 0x1f0) && (port <= 0x1f7)) || (port == 0x3f6)) + return (void __iomem *)((unsigned long)cf_io_base + port); + + return (void __iomem *)(port + PCI_IO_BASE); } -/* - * The Machine Vector - */ +/* 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; +} struct sh_machine_vector mv_sh03 __initmv = { + .mv_name = "Interface (CTP/PCI-SH03)", + .mv_setup = sh03_setup, .mv_nr_irqs = 48, - .mv_isa_port2addr = sh03_isa_port2addr, + .mv_ioport_map = sh03_ioport_map, .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 deleted file mode 100644 index 05d390c3599c..000000000000 --- a/trunk/arch/sh/boards/sh2000/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# 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 deleted file mode 100644 index 2fe6a11765e9..000000000000 --- a/trunk/arch/sh/boards/sh2000/setup.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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 new file mode 100644 index 000000000000..3190cc72430e --- /dev/null +++ b/trunk/arch/sh/boards/shmin/Makefile @@ -0,0 +1,5 @@ +# +# 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 new file mode 100644 index 000000000000..2f0c19706cf9 --- /dev/null +++ b/trunk/arch/sh/boards/shmin/setup.c @@ -0,0 +1,41 @@ +/* + * 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 e2eb78fc381d..0f4824264557 100644 --- a/trunk/arch/sh/boards/snapgear/io.c +++ b/trunk/arch/sh/boards/snapgear/io.c @@ -1,6 +1,4 @@ -/* - * 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. @@ -11,67 +9,22 @@ * 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) { -#if 0 - if (port >= 0x2000) - return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); -#endif - maybebadio(name,(unsigned long)port); + maybebadio((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) @@ -79,148 +32,106 @@ 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 (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned char *)pci_ioaddr(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 (CHECK_SH7751_PCIIO(port)) - v = *(volatile unsigned char *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + v = *(volatile unsigned char *)pci_ioaddr(port); else - v = (*port2adr(port))&0xff; - delay(); + v = (*port2adr(port))&0xff; + ctrl_delay(); return v; } - unsigned short snapgear_inw(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned short *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned short *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned short *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else - maybebadio(inw, port); + maybebadio(port); return 0; } - unsigned int snapgear_inl(unsigned long port) { if (PXSEG(port)) return *(volatile unsigned long *)port; - else if (CHECK_SH7751_PCIIO(port)) - return *(volatile unsigned int *)PCI_IOMAP(port); + else if (is_pci_ioaddr(port)) + return *(volatile unsigned int *)pci_ioaddr(port); else if (port >= 0x2000) return *port2adr(port); else - maybebadio(inl, port); + maybebadio(port); return 0; } - void snapgear_outb(unsigned char value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned char *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned char*)pci_ioaddr(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 (CHECK_SH7751_PCIIO(port)) - *((unsigned char*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned char*)pci_ioaddr(port)) = value; else *(port2adr(port)) = value; - delay(); + ctrl_delay(); } - void snapgear_outw(unsigned short value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned short *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned short *)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned short *)pci_ioaddr(port)) = value; else if (port >= 0x2000) *port2adr(port) = value; else - maybebadio(outw, port); + maybebadio(port); } - void snapgear_outl(unsigned int value, unsigned long port) { if (PXSEG(port)) *(volatile unsigned long *)port = value; - else if (CHECK_SH7751_PCIIO(port)) - *((unsigned long*)PCI_IOMAP(port)) = value; + else if (is_pci_ioaddr(port)) + *((unsigned long*)pci_ioaddr(port)) = value; else - maybebadio(outl, port); + maybebadio(port); } void snapgear_insl(unsigned long port, void *addr, unsigned long count) { - maybebadio(insl, port); + maybebadio(port); } void snapgear_outsl(unsigned long port, const void *addr, unsigned long count) { - 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; + maybebadio(port); } diff --git a/trunk/arch/sh/boards/snapgear/rtc.c b/trunk/arch/sh/boards/snapgear/rtc.c index b71e009da35c..1659fdd6695a 100644 --- a/trunk/arch/sh/boards/snapgear/rtc.c +++ b/trunk/arch/sh/boards/snapgear/rtc.c @@ -17,14 +17,9 @@ #include #include #include - #include -#include -#include - -/****************************************************************************/ -static int use_ds1302 = 0; +static int use_ds1302; /****************************************************************************/ /* @@ -82,10 +77,6 @@ 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)); @@ -104,10 +95,6 @@ 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)); @@ -168,11 +155,8 @@ void __init secureedge5410_rtc_init(void) } if (use_ds1302) { - 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; + rtc_sh_get_time = snapgear_rtc_gettimeofday; + rtc_sh_set_time = snapgear_rtc_settimeofday; } printk("SnapGear RTC: using %s rtc.\n", use_ds1302 ? "ds1302" : "internal"); @@ -187,10 +171,8 @@ void snapgear_rtc_gettimeofday(struct timespec *ts) { unsigned int sec, min, hr, day, mon, yr; - if (!use_ds1302) { - sh_rtc_gettimeofday(ts); + if (!use_ds1302) return; - } sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC)); min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN)); @@ -231,7 +213,7 @@ int snapgear_rtc_settimeofday(const time_t secs) unsigned long nowtime; if (!use_ds1302) - return sh_rtc_settimeofday(secs); + return 0; /* * This is called direct from the kernel timer handling code. @@ -240,10 +222,6 @@ 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); @@ -329,5 +307,3 @@ 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 f1f7c70c9402..f5e98c56b530 100644 --- a/trunk/arch/sh/boards/snapgear/setup.c +++ b/trunk/arch/sh/boards/snapgear/setup.c @@ -1,5 +1,4 @@ -/****************************************************************************/ -/* +/* * linux/arch/sh/boards/snapgear/setup.c * * Copyright (C) 2002 David McCullough @@ -12,8 +11,6 @@ * Modified for 7751 Solution Engine by * Ian da Silva and Jeremy Siegel, 2001. */ -/****************************************************************************/ - #include #include #include @@ -21,14 +18,13 @@ #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); @@ -85,101 +81,20 @@ static void __init init_snapgear_IRQ(void) make_ipr_irq(IRL3_IRQ, IRL3_IPR_ADDR, IRL3_IPR_POS, IRL3_PRIORITY); } -/****************************************************************************/ -/* - * Fast poll interrupt simulator. - */ - /* - * 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 - */ -#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) -{ - 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 + * Initialize the board */ - -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) +static void __init snapgear_setup(char **cmdline_p) { - return "SnapGear SecureEdge5410"; + board_time_init = secureedge5410_rtc_init; } /* * 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, @@ -196,20 +111,6 @@ 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 236398fbc083..8c64baa30364 100644 --- a/trunk/arch/sh/boards/superh/microdev/irq.c +++ b/trunk/arch/sh/boards/superh/microdev/irq.c @@ -11,14 +11,12 @@ #include #include - #include #include #include #define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */ - static const struct { unsigned char fpgaIrq; unsigned char mapped; @@ -93,53 +91,42 @@ 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 interrupts */ - local_irq_save(flags); - - /* disable interupts on the FPGA INTC register */ + /* 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 (irq >= NUM_EXTERNAL_IRQS) return; - if (!fpgaIrqTable[irq].mapped) return; + if (unlikely(irq >= NUM_EXTERNAL_IRQS)) + return; + if (unlikely(!fpgaIrqTable[irq].mapped)) + return; pri = 15 - irq; fpgaIrq = fpgaIrqTable[irq].fpgaIrq; priorityReg = MICRODEV_FPGA_INTPRI_REG(fpgaIrq); - /* disable interrupts */ - local_irq_save(flags); - - /* set priority for the interrupt */ + /* 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 */ @@ -158,9 +145,7 @@ 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) @@ -171,9 +156,7 @@ 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 61b402a3f5d7..031c814e6e76 100644 --- a/trunk/arch/sh/boards/superh/microdev/setup.c +++ b/trunk/arch/sh/boards/superh/microdev/setup.c @@ -10,7 +10,6 @@ * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. */ - #include #include #include @@ -21,41 +20,6 @@ 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) /****************************************************************************/ @@ -113,11 +77,6 @@ ALIAS_MV(sh4202_microdev) /* 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, @@ -291,25 +250,9 @@ static int __init microdev_devices_setup(void) return platform_add_devices(microdev_devices, ARRAY_SIZE(microdev_devices)); } -__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 - */ +/* + * Setup for the SMSC FDC37C93xAPM + */ static int __init smsc_superio_setup(void) { @@ -412,8 +355,52 @@ 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); -/* This is grotty, but, because kernel is always referenced on the link line - * before any devices, this is safe. + printk("SuperH %s board (FPGA rev: 0x%0x, CCR: 0x%0x)\n", + get_system_type(), fpgaRevision, *CacheControlRegister); +} + +/* + * The Machine Vector */ -__initcall(smsc_superio_setup); +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) diff --git a/trunk/arch/sh/boards/titan/Makefile b/trunk/arch/sh/boards/titan/Makefile new file mode 100644 index 000000000000..08d753700062 --- /dev/null +++ b/trunk/arch/sh/boards/titan/Makefile @@ -0,0 +1,5 @@ +# +# 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 new file mode 100644 index 000000000000..4730c1dd697d --- /dev/null +++ b/trunk/arch/sh/boards/titan/io.c @@ -0,0 +1,126 @@ +/* + * 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 new file mode 100644 index 000000000000..52b66d8b8d2a --- /dev/null +++ b/trunk/arch/sh/boards/titan/setup.c @@ -0,0 +1,48 @@ +/* + * 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 c5e4ed10876b..1c941370a2e3 100644 --- a/trunk/arch/sh/boards/unknown/setup.c +++ b/trunk/arch/sh/boards/unknown/setup.c @@ -14,19 +14,8 @@ */ #include #include -#include struct sh_machine_vector mv_unknown __initmv = { - .mv_nr_irqs = NR_IRQS, + .mv_name = "Unknown", }; 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 75a6876bf6c6..e5f443790079 100644 --- a/trunk/arch/sh/boot/compressed/Makefile +++ b/trunk/arch/sh/boot/compressed/Makefile @@ -18,13 +18,20 @@ 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%8x" $$[0x80000000+$(CONFIG_MEMORY_START)+$(CONFIG_BOOT_LINK_OFFSET)]) + +IMAGE_OFFSET := $(shell printf "0x%08x" $$[$(CONFIG_PAGE_OFFSET) + \ + $(CONFIG_MEMORY_START) + \ + $(CONFIG_BOOT_LINK_OFFSET)]) + +LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup -T $(obj)/../../kernel/vmlinux.lds -$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o FORCE + +$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE $(call if_changed,ld) @: diff --git a/trunk/arch/sh/cchips/Kconfig b/trunk/arch/sh/cchips/Kconfig index 155d139884c3..0582ca8346b6 100644 --- a/trunk/arch/sh/cchips/Kconfig +++ b/trunk/arch/sh/cchips/Kconfig @@ -65,6 +65,11 @@ 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 @@ -73,7 +78,6 @@ 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 ac3062671db7..7909a1b7b512 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64461/io.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64461/io.c @@ -1,11 +1,10 @@ /* - * $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) @@ -54,11 +53,6 @@ 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); @@ -67,7 +61,7 @@ unsigned char hd64461_inb(unsigned long port) unsigned char hd64461_inb_p(unsigned long port) { unsigned long v = *(volatile unsigned char*)PORT2ADDR(port); - delay(); + ctrl_delay(); return v; } @@ -89,7 +83,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; - delay(); + ctrl_delay(); } void hd64461_outw(unsigned short b, unsigned long port) @@ -144,13 +138,13 @@ void hd64461_outsl(unsigned long port, const void *buffer, unsigned long count) while(count--) *addr=*buf++; } -unsigned short hd64461_readw(unsigned long addr) +unsigned short hd64461_readw(void __iomem *addr) { - return *(volatile unsigned short*)(MEM_BASE+addr); + return ctrl_inw(MEM_BASE+(unsigned long __force)addr); } -void hd64461_writew(unsigned short b, unsigned long addr) +void hd64461_writew(unsigned short b, void __iomem *addr) { - *(volatile unsigned short*)(MEM_BASE+addr) = b; + ctrl_outw(b, MEM_BASE+(unsigned long __force)addr); } diff --git a/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c b/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c index ad126016720f..38f1e8171a3a 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c @@ -11,36 +11,28 @@ #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 d2b2851bc44b..30573d3e1966 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c @@ -25,31 +25,25 @@ 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 0dc1fb8f9687..392c8b12ce36 100644 --- a/trunk/arch/sh/cchips/voyagergx/irq.c +++ b/trunk/arch/sh/cchips/voyagergx/irq.c @@ -32,37 +32,30 @@ #include #include -#include -#include +#include static void disable_voyagergx_irq(unsigned int irq) { - unsigned long flags, val; - unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); + unsigned long 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 flags, val; - unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); + unsigned long 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); @@ -95,7 +88,8 @@ 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", @@ -103,9 +97,6 @@ static irqreturn_t voyagergx_interrupt(int irq, void *dev_id, struct pt_regs *re 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 139ca88ac9e6..66b2fedd7ad9 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 new file mode 100644 index 000000000000..6b43316d03cf --- /dev/null +++ b/trunk/arch/sh/configs/landisk_defconfig @@ -0,0 +1,1373 @@ +# +# 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 new file mode 100644 index 000000000000..d597fc571549 --- /dev/null +++ b/trunk/arch/sh/configs/r7780rp_defconfig @@ -0,0 +1,1099 @@ +# +# 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 d217e44c89a6..fe19feb95ca9 100644 --- a/trunk/arch/sh/configs/se73180_defconfig +++ b/trunk/arch/sh/configs/se73180_defconfig @@ -78,6 +78,7 @@ 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 new file mode 100644 index 000000000000..948e507b52be --- /dev/null +++ b/trunk/arch/sh/configs/se7343_defconfig @@ -0,0 +1,997 @@ +# +# 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 new file mode 100644 index 000000000000..ec9a3034daa5 --- /dev/null +++ b/trunk/arch/sh/configs/sh7710voipgw_defconfig @@ -0,0 +1,913 @@ +# +# 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/mips/configs/ev96100_defconfig b/trunk/arch/sh/configs/shmin_defconfig similarity index 50% rename from trunk/arch/mips/configs/ev96100_defconfig rename to trunk/arch/sh/configs/shmin_defconfig index 0bdc10f11610..382b3bd3963b 100644 --- a/trunk/arch/mips/configs/ev96100_defconfig +++ b/trunk/arch/sh/configs/shmin_defconfig @@ -1,159 +1,16 @@ # # Automatically generated make config: don't edit -# 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 +# Linux kernel version: 2.6.17 +# Wed Aug 2 01:45:03 2006 +# +CONFIG_SUPERH=y 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_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" +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_PTRACE=y # # Code maturity level options @@ -167,70 +24,210 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 # CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y +# CONFIG_SWAP is not set +# CONFIG_SYSVIPC is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y +# CONFIG_SYSCTL is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set -CONFIG_RELAY=y +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +# CONFIG_UID16 is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_EMBEDDED=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_KALLSYMS is not set # CONFIG_HOTPLUG is not set 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_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set +# 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 # # Loadable module support # -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 +# CONFIG_MODULES 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=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=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 is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" # -# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# 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_HW_HAS_PCI=y -# CONFIG_PCI is not set 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 + +# +# 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 +# +# CONFIG_PCI is not set # # PCCARD (PCMCIA/CardBus) support @@ -245,8 +242,13 @@ CONFIG_MMU=y # Executable file formats # CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_FLAT is not set # CONFIG_BINFMT_MISC is not set -CONFIG_TRAD_SIGNALS=y + +# +# Power management options (EXPERIMENTAL) +# +# CONFIG_PM is not set # # Networking @@ -259,16 +261,14 @@ CONFIG_NET=y # CONFIG_NETDEBUG is not set # CONFIG_PACKET is not set CONFIG_UNIX=y -CONFIG_XFRM=y -CONFIG_XFRM_USER=m -CONFIG_NET_KEY=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 is not set -CONFIG_IP_PNP_BOOTP=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 @@ -279,8 +279,6 @@ CONFIG_IP_PNP_BOOTP=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 @@ -288,7 +286,6 @@ 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 # @@ -330,13 +327,7 @@ CONFIG_NETWORK_SECMARK=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT 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 +# CONFIG_IEEE80211 is not set # # Device Drivers @@ -348,17 +339,92 @@ CONFIG_WIRELESS_EXT=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=m +# CONFIG_CONNECTOR is not set # # Memory Technology Devices (MTD) # -# CONFIG_MTD is not set +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 # # Parallel port support @@ -373,14 +439,13 @@ CONFIG_CONNECTOR=m # Block devices # # CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP 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_RAM is not set # CONFIG_BLK_DEV_INITRD is not set -CONFIG_CDROM_PKTCDVD=m -CONFIG_CDROM_PKTCDVD_BUFFERS=8 -# CONFIG_CDROM_PKTCDVD_WCACHE is not set -CONFIG_ATA_OVER_ETH=m +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set # # ATA/ATAPI/MFM/RLL support @@ -390,7 +455,7 @@ CONFIG_ATA_OVER_ETH=m # # SCSI device support # -CONFIG_RAID_ATTRS=m +# CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # @@ -423,26 +488,16 @@ CONFIG_NETDEVICES=y # # PHY device support # -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 +# CONFIG_PHYLIB is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y # CONFIG_MII is not set -CONFIG_MIPS_GT96100ETH=y -# CONFIG_DM9000 is not set +# CONFIG_STNIC is not set +# CONFIG_SMC91X is not set +CONFIG_NE2000=y # # Ethernet (1000 Mbit) @@ -485,60 +540,31 @@ CONFIG_MIPS_GT96100ETH=y # # Input device support # -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 +# CONFIG_INPUT is not set # # Hardware I/O ports # -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_LIBPS2 is not set -CONFIG_SERIO_RAW=m +# CONFIG_SERIO is not set # CONFIG_GAMEPORT is not set # # Character devices # -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_VT is not set # 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_RUNTIME_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set +# 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=y @@ -554,7 +580,6 @@ 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 @@ -611,15 +636,8 @@ 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 # @@ -672,25 +690,10 @@ CONFIG_DUMMY_CONSOLE=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=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set @@ -699,13 +702,12 @@ CONFIG_EXT2_FS=y # 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_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=m +# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -724,12 +726,12 @@ CONFIG_FUSE_FS=m # Pseudo filesystems # CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -# CONFIG_TMPFS is not set +# CONFIG_PROC_KCORE is not set +# CONFIG_SYSFS is not set +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 @@ -741,7 +743,9 @@ CONFIG_RAMFS=y # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_FS is not set +CONFIG_CRAMFS=y # CONFIG_VXFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set @@ -752,19 +756,20 @@ CONFIG_RAMFS=y # Network File Systems # CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set # CONFIG_NFS_V4 is not set # CONFIG_NFS_DIRECTIO is not set # CONFIG_NFSD is not set CONFIG_ROOT_NFS=y CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # 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 @@ -791,48 +796,22 @@ 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_DEBUG_FS is not set -CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="" +# CONFIG_UNWIND_INFO is not set +CONFIG_SH_STANDARD_BIOS=y +CONFIG_EARLY_PRINTK=y +# CONFIG_KGDB is not set # # Security options # -CONFIG_KEYS=y -CONFIG_KEYS_DEBUG_PROC_KEYS=y -# CONFIG_SECURITY is not set +# CONFIG_KEYS is not set # # Cryptographic options # -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 +# CONFIG_CRYPTO is not set # # Hardware crypto devices @@ -842,9 +821,7 @@ CONFIG_CRYPTO_CRC32C=m # Library routines # # CONFIG_CRC_CCITT is not set -CONFIG_CRC16=m -CONFIG_CRC32=m -CONFIG_LIBCRC32C=m -CONFIG_ZLIB_INFLATE=m -CONFIG_ZLIB_DEFLATE=m -CONFIG_PLIST=y +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y diff --git a/trunk/arch/sh/configs/titan_defconfig b/trunk/arch/sh/configs/titan_defconfig new file mode 100644 index 000000000000..1db2904de9e5 --- /dev/null +++ b/trunk/arch/sh/configs/titan_defconfig @@ -0,0 +1,1367 @@ +# +# 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 0f15216cd39d..defc13c37d48 100644 --- a/trunk/arch/sh/drivers/dma/Kconfig +++ b/trunk/arch/sh/drivers/dma/Kconfig @@ -11,6 +11,8 @@ 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 @@ -52,4 +54,3 @@ 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 0f866f8789f0..9cb070924180 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, 2004 Paul Mundt + * Copyright (C) 2003 - 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 @@ -13,7 +13,7 @@ #include #include #include - +#include #include #include #include @@ -47,17 +47,31 @@ 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) { - /* FIXME: Do some meaningful completion work here.. */ - return IRQ_HANDLED; -} + int i; -static struct irqaction g2_dma_irq = { - .name = "g2 DMA handler", - .handler = g2_dma_interrupt, - .flags = IRQF_DISABLED, -}; + 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; +} static int g2_enable_dma(struct dma_channel *chan) { @@ -135,8 +149,14 @@ 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 = { @@ -148,13 +168,22 @@ static struct dma_info g2_dma_info = { static int __init g2_dma_init(void) { - setup_irq(HW_EVENT_G2_DMA, &g2_dma_irq); + 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; /* Magic */ g2_dma->wait_state = 27; g2_dma->magic = 0x4659404f; - return register_dmac(&g2_dma_info); + ret = register_dmac(&g2_dma_info); + if (unlikely(ret != 0)) + free_irq(HW_EVENT_G2_DMA, 0); + + return ret; } static void __exit g2_dma_exit(void) @@ -169,4 +198,3 @@ 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 30a580aa7cbd..3b0b0f60bb3c 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 = 0; -static int count = 0; +static unsigned int xfer_complete; +static int count; static irqreturn_t pvr2_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs) { @@ -107,4 +107,3 @@ 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 e028a2d2a4ea..cbbe8bce3d67 100644 --- a/trunk/arch/sh/drivers/dma/dma-sh.c +++ b/trunk/arch/sh/drivers/dma/dma-sh.c @@ -11,14 +11,10 @@ * 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" @@ -84,18 +80,23 @@ static irqreturn_t dma_tei(int irq, void *dev_id, struct pt_regs *regs) static int sh_dmac_request_dma(struct dma_channel *chan) { - char name[32]; + if (unlikely(!chan->flags & DMA_TEI_CAPABLE)) + return 0; - snprintf(name, sizeof(name), "DMAC Transfer End (Channel %d)", + chan->name = kzalloc(32, GFP_KERNEL); + if (unlikely(chan->name == NULL)) + return -ENOMEM; + snprintf(chan->name, 32, "DMAC Transfer End (Channel %d)", chan->chan); return request_irq(get_dmte_irq(chan->chan), dma_tei, - IRQF_DISABLED, name, chan); + IRQF_DISABLED, chan->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 @@ -259,7 +260,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 (i < 0) + if (unlikely(i < 0)) return i; #endif @@ -274,7 +275,7 @@ static int __init sh_dmac_init(void) * been set. */ i = dmaor_reset(); - if (i < 0) + if (unlikely(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 365bc16a4a83..9e00cb8a39e9 100644 --- a/trunk/arch/sh/drivers/pci/Makefile +++ b/trunk/arch/sh/drivers/pci/Makefile @@ -6,7 +6,8 @@ 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 +obj-$(CONFIG_CPU_SUBTYPE_SH7751) += pci-sh7751.o ops-sh4.o +obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \ dma-dreamcast.o @@ -14,3 +15,6 @@ 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 63b1c6f4b8d2..c0af5f7ef414 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 Paul Mundt + * Copyright (C) 2002, 2003, 2006 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,36 +45,16 @@ 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); -void __init pcibios_fixup_bus(struct pci_bus *bus) +int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) { - /* - * 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. + /* + * 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? */ + 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 new file mode 100644 index 000000000000..3e321df65d22 --- /dev/null +++ b/trunk/arch/sh/drivers/pci/fixups-r7780rp.c @@ -0,0 +1,45 @@ +/* + * 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 0c590fc7a081..e72ceb560d5b 100644 --- a/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/trunk/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -10,8 +10,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ -#include "pci-sh7751.h" -#include +#include "pci-sh4.h" #define PCIMCR_MRSET_OFF 0xBFFFFFFF #define PCIMCR_RFSH_OFF 0xFFFFFFFB @@ -22,22 +21,23 @@ int pci_fixup_pcic(void) bcr1 = inl(SH7751_BCR1); bcr1 |= 0x40080000; /* Enable Bit 19 BREQEN, set PCIC to slave */ - outl(bcr1, PCI_REG(SH7751_PCIBCR1)); + pci_write_reg(bcr1, SH4_PCIBCR1); /* Enable all interrupts, so we known what to fix */ - outl(0x0000c3ff, PCI_REG(SH7751_PCIINTM)); - outl(0x0000380f, PCI_REG(SH7751_PCIAINTM)); + pci_write_reg(0x0000c3ff, SH4_PCIINTM); + pci_write_reg(0x0000380f, SH4_PCIAINTM); - outl(0xfb900047, PCI_REG(SH7751_PCICONF1)); - outl(0xab000001, PCI_REG(SH7751_PCICONF4)); + pci_write_reg(0xfb900047, SH7751_PCICONF1); + pci_write_reg(0xab000001, SH7751_PCICONF4); mcr = inl(SH7751_MCR); mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; - outl(mcr, PCI_REG(SH7751_PCIMCR)); + 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(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 57ac26c2171f..2e8a18b7ee53 100644 --- a/trunk/arch/sh/drivers/pci/fixups-sh03.c +++ b/trunk/arch/sh/drivers/pci/fixups-sh03.c @@ -3,11 +3,7 @@ #include #include -/* - * IRQ functions - */ - -int __init pcibios_map_platform_irq(u8 slot, u8 pin, struct pci_dev *dev) +int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) { int irq; @@ -17,8 +13,9 @@ int __init pcibios_map_platform_irq(u8 slot, u8 pin, struct pci_dev *dev) case 8: return 5; /* eth1 */ case 6: return 2; /* PCI bridge */ default: - printk("PCI: Bad IRQ mapping request for slot %d\n", slot); - return 2; + printk(KERN_ERR "PCI: Bad IRQ mapping request " + "for slot %d\n", slot); + return 2; } } else { switch (pin) { @@ -32,30 +29,3 @@ int __init pcibios_map_platform_irq(u8 slot, u8 pin, struct pci_dev *dev) } 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 ae82c6ca05e5..5da501bd77b5 100644 --- a/trunk/arch/sh/drivers/pci/ops-bigsur.c +++ b/trunk/arch/sh/drivers/pci/ops-bigsur.c @@ -10,15 +10,12 @@ * * PCI initialization for the Hitachi Big Sur Evaluation Board */ - #include #include #include -#include #include - #include -#include "pci-sh7751.h" +#include "pci-sh4.h" #include #define BIGSUR_PCI_IO 0x4000 @@ -41,11 +38,11 @@ static struct resource sh7751_mem_resource = { extern struct pci_ops sh7751_pci_ops; struct pci_channel board_pci_channels[] = { - { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, { 0, } }; -static struct sh7751_pci_address_map sh7751_pci_map = { +static struct sh4_pci_address_map sh7751_pci_map = { .window0 = { .base = SH7751_CS3_BASE_ADDR, .size = BIGSUR_LSR0_SIZE, @@ -58,7 +55,7 @@ static struct sh7751_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 @@ -68,15 +65,15 @@ int __init pcibios_init_platform(void) return sh7751_pcic_init(&sh7751_pci_map); } -int pcibios_map_platform_irq(u8 slot, u8 pin) +int __init pcibios_map_platform_irq(struct pci_dev *pdev, 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", @@ -84,4 +81,3 @@ int pcibios_map_platform_irq(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 new file mode 100644 index 000000000000..ada301c21fe7 --- /dev/null +++ b/trunk/arch/sh/drivers/pci/ops-landisk.c @@ -0,0 +1,68 @@ +/* + * 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 new file mode 100644 index 000000000000..554d5ed2c586 --- /dev/null +++ b/trunk/arch/sh/drivers/pci/ops-r7780rp.c @@ -0,0 +1,75 @@ +/* + * 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 83171d10141a..88f44e245424 100644 --- a/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c +++ b/trunk/arch/sh/drivers/pci/ops-rts7751r2d.c @@ -17,12 +17,11 @@ #include #include #include - -#include -#include "pci-sh7751.h" #include +#include +#include "pci-sh4.h" -int __init pcibios_map_platform_irq(u8 slot, u8 pin) +int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { switch (slot) { case 0: return IRQ_PCISLOT1; /* PCI Extend slot #1 */ @@ -52,12 +51,12 @@ static struct resource sh7751_mem_resource = { extern struct pci_ops sh7751_pci_ops; struct pci_channel board_pci_channels[] = { - { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, { NULL, NULL, NULL, 0, 0 }, }; EXPORT_SYMBOL(board_pci_channels); -static struct sh7751_pci_address_map sh7751_pci_map = { +static struct sh4_pci_address_map sh7751_pci_map = { .window0 = { .base = SH7751_CS3_BASE_ADDR, .size = 0x04000000, @@ -68,7 +67,7 @@ static struct sh7751_pci_address_map sh7751_pci_map = { .size = 0x00000000, /* Unused */ }, - .flags = SH7751_PCIC_NO_RESET, + .flags = SH4_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 new file mode 100644 index 000000000000..2d4371009a5e --- /dev/null +++ b/trunk/arch/sh/drivers/pci/ops-sh4.c @@ -0,0 +1,164 @@ +/* + * 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 3cbd14dd28fe..53dd893d4e54 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,15 +12,11 @@ * * PCI initialization for the SnapGear boards */ - #include #include #include -#include #include - -#include -#include "pci-sh7751.h" +#include "pci-sh4.h" #define SNAPGEAR_PCI_IO 0x4000 #define SNAPGEAR_PCI_MEM 0xfd000000 @@ -43,14 +39,12 @@ static struct resource sh7751_mem_resource = { .flags = IORESOURCE_MEM, }; -extern struct pci_ops sh7751_pci_ops; - struct pci_channel board_pci_channels[] = { - { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { &sh4_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, { 0, } }; -static struct sh7751_pci_address_map sh7751_pci_map = { +static struct sh4_pci_address_map sh7751_pci_map = { .window0 = { .base = SH7751_CS2_BASE_ADDR, .size = SNAPGEAR_LSR0_SIZE, @@ -61,11 +55,11 @@ static struct sh7751_pci_address_map sh7751_pci_map = { .size = SNAPGEAR_LSR1_SIZE, }, - .flags = SH7751_PCIC_NO_RESET, + .flags = SH4_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 @@ -75,7 +69,7 @@ int __init pcibios_init_platform(void) return sh7751_pcic_init(&sh7751_pci_map); } -int __init pcibios_map_platform_irq(u8 slot, u8 pin) +int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) { int irq = -1; @@ -98,4 +92,3 @@ 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 new file mode 100644 index 000000000000..c6097bcd97fd --- /dev/null +++ b/trunk/arch/sh/drivers/pci/ops-titan.c @@ -0,0 +1,83 @@ +/* + * 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 4cef4d1d8c84..ecf16344f94a 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 -#undef DEBUG -#ifdef DEBUG +#define 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,7 +116,6 @@ 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 */ @@ -125,7 +124,6 @@ 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, @@ -140,8 +138,7 @@ 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. @@ -151,7 +148,6 @@ 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) @@ -177,7 +173,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"); @@ -193,22 +189,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; } @@ -230,7 +226,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, @@ -362,7 +358,6 @@ 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 @@ -370,7 +365,6 @@ 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 @@ -396,11 +390,6 @@ 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); @@ -433,12 +422,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", @@ -490,10 +476,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 new file mode 100644 index 000000000000..5a61d6041f2c --- /dev/null +++ b/trunk/arch/sh/drivers/pci/pci-sh4.h @@ -0,0 +1,180 @@ +#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 682f3dae305d..dbe837884983 100644 --- a/trunk/arch/sh/drivers/pci/pci-sh7751.c +++ b/trunk/arch/sh/drivers/pci/pci-sh7751.c @@ -15,180 +15,14 @@ #undef DEBUG -#include -#include #include #include -#include -#include +#include #include -#include #include - -#include +#include "pci-sh4.h" +#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)); - -/* - * Direct access to PCI hardware... - */ - -#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 long flags; - u32 data; - - /* - * 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 = 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; - } - - /* - * 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 @@ -196,25 +30,29 @@ void __init pcibios_fixup_bus(struct pci_bus *b) * 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. + * space mapping) will be called via the platform defined function + * pcibios_init_platform(). */ - static int __init sh7751_pci_init(void) { + unsigned int id; int ret; pr_debug("PCI: Starting intialization.\n"); - if ((ret = pci_check_direct()) != 0) + + /* check for SH7751/SH7751R hardware */ + id = pci_read_reg(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) return ret; return pcibios_init_platform(); } - subsys_initcall(sh7751_pci_init); static int __init __area_sdram_check(unsigned int area) @@ -223,26 +61,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; } - outl(word, PCI_REG(SH7751_PCIBCR1)); + pci_write_reg(word, SH4_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; } - outl(word, PCI_REG(SH7751_PCIBCR2)); + pci_write_reg(word, SH4_PCIBCR2); return 1; } -int __init sh7751_pcic_init(struct sh7751_pci_address_map *map) +int __init sh7751_pcic_init(struct sh4_pci_address_map *map) { u32 reg; u32 word; @@ -251,39 +89,39 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map) reg = inl(SH7751_BCR1); reg |= 0x80000; outl(reg, SH7751_BCR1); - + /* Turn the clocks back on (not done in reset)*/ - outl(0, PCI_REG(SH7751_PCICLKR)); + pci_write_reg(0, SH4_PCICLKR); /* Clear Powerdown IRQ's (not done in reset) */ - word = SH7751_PCIPINT_D3 | SH7751_PCIPINT_D0; - outl(word, PCI_REG(SH7751_PCIPINT)); + word = SH4_PCIPINT_D3 | SH4_PCIPINT_D0; + pci_write_reg(word, SH4_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 & SH7751_PCIC_NO_RESET)) { + if (!(map->flags & SH4_PCIC_NO_RESET)) { /* toggle PCI reset pin */ - word = SH7751_PCICR_PREFIX | SH7751_PCICR_PRST; - outl(word,PCI_REG(SH7751_PCICR)); + 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 = SH7751_PCICR_PREFIX; - outl(word,PCI_REG(SH7751_PCICR)); + 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 */ word = SH7751_PCICONF1_WCC | SH7751_PCICONF1_PER | SH7751_PCICONF1_BUM | SH7751_PCICONF1_MES; - outl(word, PCI_REG(SH7751_PCICONF1)); + pci_write_reg(word, SH7751_PCICONF1); /* define this host as the host bridge */ - word = SH7751_PCI_HOST_BRIDGE << 24; - outl(word, PCI_REG(SH7751_PCICONF2)); + word = PCI_BASE_CLASS_BRIDGE << 24; + pci_write_reg(word, SH7751_PCICONF2); /* Set IO and Mem windows to local address * Make PCI and local address the same for easy 1 to 1 mapping @@ -291,46 +129,49 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map) * Window1 = map->window1.size @ cached area base = SDRAM */ word = map->window0.size - 1; - outl(word, PCI_REG(SH7751_PCILSR0)); + pci_write_reg(word, SH4_PCILSR0); word = map->window1.size - 1; - outl(word, PCI_REG(SH7751_PCILSR1)); + pci_write_reg(word, SH4_PCILSR1); /* Set the values on window 0 PCI config registers */ word = P2SEGADDR(map->window0.base); - outl(word, PCI_REG(SH7751_PCILAR0)); - outl(word, PCI_REG(SH7751_PCICONF5)); + pci_write_reg(word, SH4_PCILAR0); + pci_write_reg(word, SH7751_PCICONF5); /* Set the values on window 1 PCI config registers */ word = PHYSADDR(map->window1.base); - outl(word, PCI_REG(SH7751_PCILAR1)); - outl(word, PCI_REG(SH7751_PCICONF6)); + pci_write_reg(word, SH4_PCILAR1); + pci_write_reg(word, 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 & SH7751_PCIMBR_MASK; - PCIDBG(2,"PCI: Setting upper bits of Memory window to 0x%x\n", word); - outl(word , PCI_REG(SH7751_PCIMBR)); + 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); /* 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 */ - 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); + 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); - /* + /* * 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*1024), SH7751_PCI_IO_BASE+PCIBIOS_MIN_IO,0); + bigsur_port_map(PCIBIOS_MIN_IO, (64 << 10), + SH4_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 & SH7751_PCIIOBR_MASK; - PCIDBG(2,"PCI: Setting upper bits of IO window to 0x%x\n", word); - outl(word, PCI_REG(SH7751_PCIIOBR)); - + /* 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); + /* Set PCI WCRx, BCRx's, copy from BSC locations */ /* check BCR for SDRAM in specified area */ @@ -349,13 +190,13 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map) /* configure the wait control registers */ word = inl(SH7751_WCR1); - outl(word, PCI_REG(SH7751_PCIWCR1)); + pci_write_reg(word, SH4_PCIWCR1); word = inl(SH7751_WCR2); - outl(word, PCI_REG(SH7751_PCIWCR2)); + pci_write_reg(word, SH4_PCIWCR2); word = inl(SH7751_WCR3); - outl(word, PCI_REG(SH7751_PCIWCR3)); + pci_write_reg(word, SH4_PCIWCR3); word = inl(SH7751_MCR); - outl(word, PCI_REG(SH7751_PCIMCR)); + pci_write_reg(word, SH4_PCIMCR); /* NOTE: I'm ignoring the PCI error IRQs for now.. * TODO: add support for the internal error interrupts and @@ -368,49 +209,8 @@ int __init sh7751_pcic_init(struct sh7751_pci_address_map *map) /* SH7751 init done, set central function init complete */ /* use round robin mode to stop a device starving/overruning */ - word = SH7751_PCICR_PREFIX | SH7751_PCICR_CFIN | SH7751_PCICR_ARBM; - outl(word,PCI_REG(SH7751_PCICR)); + word = SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_ARBM; + pci_write_reg(word, SH4_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 1fee5cae10d1..68e3cb5e6bec 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,28 +12,6 @@ #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 @@ -128,131 +106,6 @@ #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 */ @@ -274,30 +127,9 @@ #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) -/* 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; -}; +struct sh4_pci_address_map; /* arch/sh/drivers/pci/pci-sh7751.c */ -extern int sh7751_pcic_init(struct sh7751_pci_address_map *map); +int sh7751_pcic_init(struct sh4_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 new file mode 100644 index 000000000000..bd3064a82087 --- /dev/null +++ b/trunk/arch/sh/drivers/pci/pci-sh7780.c @@ -0,0 +1,139 @@ +/* + * 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 new file mode 100644 index 000000000000..f02d2180a4bc --- /dev/null +++ b/trunk/arch/sh/drivers/pci/pci-sh7780.h @@ -0,0 +1,94 @@ +/* + * 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 7c81b8b65bb5..4ab5ea6b35fb 100644 --- a/trunk/arch/sh/drivers/pci/pci-st40.c +++ b/trunk/arch/sh/drivers/pci/pci-st40.c @@ -70,12 +70,6 @@ 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) { { @@ -422,13 +416,6 @@ 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; @@ -465,17 +452,11 @@ 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 3d546ba329cf..d439336d2e18 100644 --- a/trunk/arch/sh/drivers/pci/pci.c +++ b/trunk/arch/sh/drivers/pci/pci.c @@ -1,21 +1,45 @@ -/* arch/sh/kernel/pci.c - * $Id: pci.c,v 1.1 2003/08/24 19:15:45 lethal Exp $ +/* + * arch/sh/drivers/pci/pci.c * * 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) { @@ -26,26 +50,32 @@ 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; } - /* board-specific fixups */ - pcibios_fixup_irqs(); + pci_fixup_irqs(simple_swizzle, pcibios_map_platform_irq); 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); +} + void pcibios_update_resource(struct pci_dev *dev, struct resource *root, struct resource *res, int resource) @@ -61,13 +91,17 @@ 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); @@ -145,7 +179,8 @@ 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); } @@ -153,3 +188,39 @@ 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 f05cd96f8867..5da88a43d350 100644 --- a/trunk/arch/sh/kernel/Makefile +++ b/trunk/arch/sh/kernel/Makefile @@ -6,9 +6,10 @@ 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 + io.o io_generic.o sh_ksyms.o syscalls.o obj-y += cpu/ timers/ +obj-$(CONFIG_VSYSCALL) += vsyscall/ obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_CF_ENABLER) += cf-enabler.o @@ -18,3 +19,5 @@ 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 new file mode 100644 index 000000000000..871e7d640002 --- /dev/null +++ b/trunk/arch/sh/kernel/apm.c @@ -0,0 +1,539 @@ +/* + * 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 f1f9ab87f0b0..3e5fa1e24df0 100644 --- a/trunk/arch/sh/kernel/cf-enabler.c +++ b/trunk/arch/sh/kernel/cf-enabler.c @@ -10,7 +10,8 @@ */ #include - +#include +#include #include #include @@ -32,8 +33,6 @@ /* 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 @@ -41,9 +40,6 @@ #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; @@ -62,7 +58,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? */ @@ -87,7 +83,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 59d5b748752f..fb5dac069382 100644 --- a/trunk/arch/sh/kernel/cpu/Makefile +++ b/trunk/arch/sh/kernel/cpu/Makefile @@ -8,6 +8,5 @@ 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 97fa37f42b84..51ec64cdf348 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 Paul Mundt + * Copyright (C) 2005, 2006 Paul Mundt * * This clock framework is derived from the OMAP version by: * @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -24,7 +25,7 @@ static LIST_HEAD(clock_list); static DEFINE_SPINLOCK(clock_lock); -static DECLARE_MUTEX(clock_list_sem); +static DEFINE_MUTEX(clock_list_sem); /* * Each subtype is expected to define the init routines for these clocks, @@ -140,21 +141,21 @@ void clk_disable(struct clk *clk) int clk_register(struct clk *clk) { - down(&clock_list_sem); + mutex_lock(&clock_list_sem); list_add(&clk->node, &clock_list); kref_init(&clk->kref); - up(&clock_list_sem); + mutex_unlock(&clock_list_sem); return 0; } void clk_unregister(struct clk *clk) { - down(&clock_list_sem); + mutex_lock(&clock_list_sem); list_del(&clk->node); - up(&clock_list_sem); + mutex_unlock(&clock_list_sem); } inline unsigned long clk_get_rate(struct clk *clk) @@ -198,14 +199,14 @@ struct clk *clk_get(const char *id) { struct clk *p, *clk = ERR_PTR(-ENOENT); - down(&clock_list_sem); + mutex_lock(&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; } } - up(&clock_list_sem); + mutex_unlock(&clock_list_sem); return clk; } @@ -225,7 +226,7 @@ int __init clk_init(void) { int i, ret = 0; - BUG_ON(unlikely(!master_clk.rate)); + BUG_ON(!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 868e68b28880..bfb90eb0b7a6 100644 --- a/trunk/arch/sh/kernel/cpu/init.c +++ b/trunk/arch/sh/kernel/cpu/init.c @@ -4,6 +4,7 @@ * 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 @@ -13,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -51,7 +53,15 @@ static void __init cache_init(void) ccr = ctrl_inl(CCR); /* - * If the cache is already enabled .. flush it. + * 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 (ccr & CCR_CACHE_ENABLE) { unsigned long ways, waysize, addrstart; @@ -98,6 +108,8 @@ 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 @@ -112,6 +124,9 @@ 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); @@ -184,6 +199,10 @@ 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 e3cccea15e1d..1c034c283f59 100644 --- a/trunk/arch/sh/kernel/cpu/irq/Makefile +++ b/trunk/arch/sh/kernel/cpu/irq/Makefile @@ -3,5 +3,6 @@ # obj-y += ipr.o imask.o -obj-$(CONFIG_CPU_HAS_PINT_IRQ) += pint.o -obj-$(CONFIG_CPU_HAS_INTC2_IRQ) += intc2.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 diff --git a/trunk/arch/sh/kernel/cpu/irq/intc2.c b/trunk/arch/sh/kernel/cpu/irq/intc2.c index 30064bf6e154..e30e4b7aa70e 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}, -#ifdef CONFIG_SH_RTC - { RTC_IRQ, 4, 0, 0, INTC_RTC_MSK, TIMER_PRIORITY }, -#endif + { 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 }, { 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 0f545941fb4f..f785822cd5de 100644 --- a/trunk/arch/sh/kernel/cpu/irq/ipr.c +++ b/trunk/arch/sh/kernel/cpu/irq/ipr.c @@ -57,31 +57,27 @@ static struct hw_interrupt_type ipr_irq_type = { static void disable_ipr_irq(unsigned int irq) { - unsigned long val, flags; + unsigned long val; 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, flags; + unsigned long val; 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) @@ -89,6 +85,7 @@ 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? */ @@ -123,7 +120,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); -#if defined(CONFIG_SH_RTC) +#ifdef RTC_IRQ make_ipr_irq(RTC_IRQ, RTC_IPR_ADDR, RTC_IPR_POS, RTC_PRIORITY); #endif @@ -162,6 +159,7 @@ 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) @@ -192,6 +190,8 @@ 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/boards/adx/irq_maskreg.c b/trunk/arch/sh/kernel/cpu/irq/maskreg.c similarity index 63% rename from trunk/arch/sh/boards/adx/irq_maskreg.c rename to trunk/arch/sh/kernel/cpu/irq/maskreg.c index 4b2abe5eb165..492db31b3cab 100644 --- a/trunk/arch/sh/boards/adx/irq_maskreg.c +++ b/trunk/arch/sh/kernel/cpu/irq/maskreg.c @@ -1,30 +1,23 @@ /* - * linux/arch/sh/kernel/irq_maskreg.c + * Interrupt handling for Simple external interrupt mask register * * Copyright (C) 2001 A&D Co., Ltd. * - * 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. + * 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. */ - #include #include #include - #include #include -#include -/* 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; +/* address of external interrupt mask register */ +unsigned long irq_mask_register; /* forward declaration */ static unsigned int startup_maskreg_irq(unsigned int irq); @@ -36,7 +29,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, @@ -47,7 +40,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 */ } @@ -59,32 +52,26 @@ static void shutdown_maskreg_irq(unsigned int irq) static void disable_maskreg_irq(unsigned int irq) { - if (irq_mask_register) { - unsigned long flags; - unsigned short val, mask = 0x01 << irq; + unsigned short val, mask = 0x01 << irq; + + BUG_ON(!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); - } + /* Set "irq"th bit */ + val = ctrl_inw(irq_mask_register); + val |= mask; + ctrl_outw(val, irq_mask_register); } static void enable_maskreg_irq(unsigned int irq) { - if (irq_mask_register) { - unsigned long flags; - unsigned short val, mask = ~(0x01 << irq); + unsigned short val, mask = ~(0x01 << irq); + + BUG_ON(!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); - } + /* Clear "irq"th bit */ + val = ctrl_inw(irq_mask_register); + val &= mask; + ctrl_outw(val, irq_mask_register); } static void mask_and_ack_maskreg(unsigned int irq) @@ -101,6 +88,6 @@ static void end_maskreg_irq(unsigned int irq) void make_maskreg_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = &maskreg_irq_type; + irq_desc[irq].handler = &maskreg_irq_type; disable_maskreg_irq(irq); } diff --git a/trunk/arch/sh/kernel/cpu/irq/pint.c b/trunk/arch/sh/kernel/cpu/irq/pint.c index 80cd8108d36a..17f47b373d6e 100644 --- a/trunk/arch/sh/kernel/cpu/irq/pint.c +++ b/trunk/arch/sh/kernel/cpu/irq/pint.c @@ -48,26 +48,22 @@ static struct hw_interrupt_type pint_irq_type = { static void disable_pint_irq(unsigned int irq) { - unsigned long val, flags; + unsigned long val; - 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, flags; + unsigned long val; - 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 deleted file mode 100644 index 4304cf75cfa2..000000000000 --- a/trunk/arch/sh/kernel/cpu/rtc.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 b54dbb9a0c86..58d3815695ff 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/Makefile +++ b/trunk/arch/sh/kernel/cpu/sh3/Makefile @@ -4,10 +4,21 @@ 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 new file mode 100644 index 000000000000..0cf96f9833bc --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh3/clock-sh7706.c @@ -0,0 +1,84 @@ +/* + * 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 cc04e9e239ff..44daf44833f9 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/ex.S +++ b/trunk/arch/sh/kernel/cpu/sh3/ex.S @@ -84,8 +84,12 @@ 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_SH7300) || defined(CONFIG_CPU_SUBTYPE_SH7705) +#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) .long do_IRQ ! 32 IRQ irq0 /* 600 */ .long do_IRQ ! 33 irq1 .long do_IRQ ! 34 irq2 @@ -147,6 +151,51 @@ 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 @@ -195,4 +244,3 @@ 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 5cdc88638601..e67098836290 100644 --- a/trunk/arch/sh/kernel/cpu/sh3/probe.c +++ b/trunk/arch/sh/kernel/cpu/sh3/probe.c @@ -72,6 +72,12 @@ 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 new file mode 100644 index 000000000000..ab4d204bfba5 --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7300.c @@ -0,0 +1,43 @@ +/* + * 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 new file mode 100644 index 000000000000..a8e41c5241fa --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -0,0 +1,48 @@ +/* + * 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 new file mode 100644 index 000000000000..f933723911ca --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7708.c @@ -0,0 +1,43 @@ +/* + * 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 new file mode 100644 index 000000000000..ff43ef2a1f0c --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7709.c @@ -0,0 +1,53 @@ +/* + * 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 new file mode 100644 index 000000000000..895f99ee6a95 --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -0,0 +1,43 @@ +/* + * 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 3d5cafc71ae3..8dbf3895ece7 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/Makefile +++ b/trunk/arch/sh/kernel/cpu/sh4/Makefile @@ -7,6 +7,16 @@ 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 26a27df06505..7146893a6cca 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/ex.S +++ b/trunk/arch/sh/kernel/cpu/sh4/ex.S @@ -72,6 +72,7 @@ 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 @@ -122,6 +123,13 @@ 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 @@ -131,7 +139,8 @@ ENTRY(interrupt_table) #if defined(CONFIG_SH_FPU) .long do_fpu_state_restore ! 48 /* 800 */ .long do_fpu_state_restore ! 49 /* 820 */ -#else +#elif !defined(CONFIG_CPU_SUBTYPE_SH7343) && \ + !defined(CONFIG_CPU_SUBTYPE_SH73180) .long exception_error .long exception_error #endif @@ -224,7 +233,7 @@ ENTRY(interrupt_table) .long exception_error .long do_IRQ ! ADC adi .long do_IRQ ! CMT cmti /* FA0 */ -#elif defined(CONFIG_CPU_SUBTYPE_SH73180) +#elif defined(CONFIG_CPU_SUBTYPE_SH73180) || defined(CONFIG_CPU_SUBTYPE_SH7343) .long do_IRQ ! 50 0x840 .long do_IRQ ! 51 0x860 .long do_IRQ ! 52 0x880 @@ -379,5 +388,168 @@ 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 42427b79697b..c294de1e14a3 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, 2002, 2003, 2004 Paul Mundt + * Copyright (C) 2001 - 2006 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) & 0xffff; + pvr = (ctrl_inl(CCN_PVR) >> 8) & 0xffffff; prr = (ctrl_inl(CCN_PRR) >> 4) & 0xff; cvr = (ctrl_inl(CCN_CVR)); @@ -38,7 +38,6 @@ 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; @@ -48,13 +47,29 @@ 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; - /* Set the FPU flag, virtually all SH-4's have one */ - cpu_data->flags |= CPU_HAS_FPU; + /* + * 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; /* * Probe the underlying processor version/revision and @@ -63,56 +78,101 @@ 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_PERF_COUNTER; + cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | + CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA; break; case 0x206: cpu_data->type = CPU_SH7750S; - cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_PERF_COUNTER; + cpu_data->flags |= CPU_HAS_P2_FLUSH_BUG | CPU_HAS_FPU | + CPU_HAS_PERF_COUNTER | CPU_HAS_PTEA; 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_FPU; + 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; 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; - - /* No FPU on the SH4-500 series.. */ - cpu_data->flags &= ~CPU_HAS_FPU; + cpu_data->flags |= CPU_HAS_PTEA; 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: cpu_data->type = CPU_SH7760; break; + 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; } 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. @@ -121,18 +181,56 @@ 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 - (1 << 5)); + } + + 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); } 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 new file mode 100644 index 000000000000..6e4e96541358 --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -0,0 +1,43 @@ +/* + * 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 new file mode 100644 index 000000000000..cc9ea1e2e5df --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh73180.c @@ -0,0 +1,43 @@ +/* + * 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 new file mode 100644 index 000000000000..91d61cf91ba1 --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7343.c @@ -0,0 +1,43 @@ +/* + * 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 new file mode 100644 index 000000000000..50812d57c1c1 --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -0,0 +1,48 @@ +/* + * 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 new file mode 100644 index 000000000000..97f1c9af35d6 --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -0,0 +1,53 @@ +/* + * 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 new file mode 100644 index 000000000000..6a04cc5f5aca --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7770.c @@ -0,0 +1,53 @@ +/* + * 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 new file mode 100644 index 000000000000..72493f259edc --- /dev/null +++ b/trunk/arch/sh/kernel/cpu/sh4/setup-sh7780.c @@ -0,0 +1,79 @@ +/* + * 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 b09805f3ee23..7bcc73f9b8df 100644 --- a/trunk/arch/sh/kernel/cpu/sh4/sq.c +++ b/trunk/arch/sh/kernel/cpu/sh4/sq.c @@ -1,49 +1,52 @@ /* - * arch/sh/kernel/cpu/sq.c + * arch/sh/kernel/cpu/sh4/sq.c * * General management API for SH-4 integrated Store Queues * - * Copyright (C) 2001, 2002, 2003, 2004 Paul Mundt + * Copyright (C) 2001 - 2006 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 -static LIST_HEAD(sq_mapping_list); +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 DEFINE_SPINLOCK(sq_mapping_lock); +static kmem_cache_t *sq_cache; +static unsigned long *sq_bitmap; -/** - * 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"); -} +#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_range - Flush (prefetch) a specific SQ range @@ -56,152 +59,73 @@ inline void sq_flush(void *addr) 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) - sq_flush((void *)sq); + prefetchw((void *)sq); /* Wait for completion */ - dummy = ctrl_inl(P4SEG_STORE_QUE); - - ctrl_outl(0, P4SEG_STORE_QUE + 0); - ctrl_outl(0, P4SEG_STORE_QUE + 8); + store_queue_barrier(); } -static struct sq_mapping *__sq_alloc_mapping(unsigned long virt, unsigned long phys, unsigned long size, const char *name) +static inline void sq_mapping_list_add(struct sq_mapping *map) { - struct sq_mapping *map; - - if (virt + size > SQ_ADDRMAX) - return ERR_PTR(-ENOSPC); - - map = kmalloc(sizeof(struct sq_mapping), GFP_KERNEL); - if (!map) - return ERR_PTR(-ENOMEM); + struct sq_mapping **p, *tmp; - INIT_LIST_HEAD(&map->list); + spin_lock_irq(&sq_mapping_lock); - map->sq_addr = virt; - map->addr = phys; - map->size = size + 1; - map->name = name; + p = &sq_mapping_list; + while ((tmp = *p) != NULL) + p = &tmp->next; - list_add(&map->list, &sq_mapping_list); + map->next = tmp; + *p = map; - return map; + spin_unlock_irq(&sq_mapping_lock); } -static unsigned long __sq_get_next_addr(void) +static inline void sq_mapping_list_del(struct sq_mapping *map) { - 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; + struct sq_mapping **p, *tmp; + + spin_lock_irq(&sq_mapping_lock); + + for (p = &sq_mapping_list; (tmp = *p); p = &tmp->next) + if (tmp == map) { + *p = tmp->next; + break; } - } - return P4SEG_STORE_QUE; + spin_unlock_irq(&sq_mapping_lock); } -/** - * __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) +static int __sq_remap(struct sq_mapping *map, unsigned long flags) { - unsigned long flags, pteh, ptel; +#if defined(CONFIG_MMU) 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 ERR_PTR(-ENOMEM); + return -ENOMEM; vma->phys_addr = map->addr; if (remap_area_pages((unsigned long)vma->addr, vma->phys_addr, - map->size, pgprot_val(pgprot))) { + map->size, flags)) { vunmap(vma->addr); - return NULL; + return -EAGAIN; } -#endif /* CONFIG_MMU */ +#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 - return map; + return 0; } /** @@ -209,42 +133,65 @@ static struct sq_mapping *__sq_remap(struct sq_mapping *map) * @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 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. + * the sysfs interface. */ -struct sq_mapping *sq_remap(unsigned long phys, unsigned int size, const char *name) +unsigned long sq_remap(unsigned long phys, unsigned int size, + const char *name, unsigned long flags) { struct sq_mapping *map; - unsigned long virt, end; + unsigned long end; unsigned int psz; + int ret, page; /* Don't allow wraparound or zero size */ end = phys + size - 1; - if (!size || end < phys) - return NULL; + if (unlikely(!size || end < phys)) + return -EINVAL; /* Don't allow anyone to remap normal memory.. */ - if (phys < virt_to_phys(high_memory)) - return NULL; + if (unlikely(phys < virt_to_phys(high_memory))) + return -EINVAL; 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); - 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); + sq_mapping_list_add(map); - 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); + return map->sq_addr; - return __sq_remap(map); +out: + kmem_cache_free(sq_cache, map); + return ret; } /** @@ -255,188 +202,198 @@ struct sq_mapping *sq_remap(unsigned long phys, unsigned int size, const char *n * sq_remap(). Also frees up the pte that was previously inserted into * the kernel page table and discards the UTLB translation. */ -void sq_unmap(struct sq_mapping *map) +void sq_unmap(unsigned long vaddr) { - if (map->sq_addr > (unsigned long)high_memory) - vfree((void *)(map->sq_addr & PAGE_MASK)); + struct sq_mapping **p, *map; + struct vm_struct *vma; + int page; - list_del(&map->list); - kfree(map); -} + for (p = &sq_mapping_list; (map = *p); p = &map->next) + if (map->sq_addr == vaddr) + break; -/** - * 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; + if (unlikely(!map)) { + printk("%s: bad store queue address 0x%08lx\n", + __FUNCTION__, vaddr); + return; + } - /* Clear out both queues linearly */ - for (i = 0; i < 8; i++) { - ctrl_outl(0, addr + i + 0); - ctrl_outl(0, addr + i + 8); + page = (map->sq_addr - P4SEG_STORE_QUE) >> PAGE_SHIFT; + bitmap_release_region(sq_bitmap, page, get_order(map->size)); + +#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; } +#endif + + sq_mapping_list_del(map); - sq_flush_range(addr, len); + kmem_cache_free(sq_cache, map); } -/** - * sq_vma_unmap - Unmap a VMA range - * @area: VMA containing range. - * @addr: Start of range. - * @len: Length of range. +/* + * 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. * - * 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. + * 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. */ -static void sq_vma_unmap(struct vm_area_struct *area, - unsigned long addr, size_t len) -{ - struct list_head *pos, *tmp; +static struct kobject *sq_kobject[NR_CPUS]; - list_for_each_safe(pos, tmp, &sq_mapping_list) { - struct sq_mapping *entry; +struct sq_sysfs_attr { + struct attribute attr; + ssize_t (*show)(char *buf); + ssize_t (*store)(const char *buf, size_t count); +}; - entry = list_entry(pos, typeof(*entry), list); +#define to_sq_sysfs_attr(attr) container_of(attr, struct 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); +static ssize_t sq_sysfs_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct sq_sysfs_attr *sattr = to_sq_sysfs_attr(attr); - list_del(&entry->list); - kfree(entry); + if (likely(sattr->show)) + return sattr->show(buf); - return; - } - } + return -EIO; } -/** - * 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) +static ssize_t sq_sysfs_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t count) { - sq_flush_range(start, len); + struct sq_sysfs_attr *sattr = to_sq_sysfs_attr(attr); - return 0; + if (likely(sattr->store)) + return sattr->store(buf, count); + + return -EIO; } -static struct vm_operations_struct sq_vma_ops = { - .unmap = sq_vma_unmap, - .sync = sq_vma_sync, -}; +static ssize_t mapping_show(char *buf) +{ + struct sq_mapping **list, *entry; + char *p = buf; -/** - * 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) + 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); + + return p - buf; +} + +static ssize_t mapping_store(const char *buf, size_t count) { - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; - unsigned long size = vma->vm_end - vma->vm_start; - struct sq_mapping *map; + unsigned long base = 0, len = 0; - /* - * 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; + sscanf(buf, "%lx %lx", &base, &len); + if (!base) + return -EIO; - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + 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_flags |= VM_IO | VM_RESERVED; + return count; +} - map = __sq_alloc_mapping(vma->vm_start, offset, size, "Userspace"); +static struct sq_sysfs_attr mapping_attr = + __ATTR(mapping, 0644, mapping_show, mapping_store); - if (io_remap_pfn_range(vma, map->sq_addr, map->addr >> PAGE_SHIFT, - size, vma->vm_page_prot)) - return -EAGAIN; +static struct attribute *sq_sysfs_attrs[] = { + &mapping_attr.attr, + NULL, +}; - vma->vm_ops = &sq_vma_ops; +static struct sysfs_ops sq_sysfs_ops = { + .show = sq_sysfs_show, + .store = sq_sysfs_store, +}; - return 0; -} +static struct kobj_type ktype_percpu_entry = { + .sysfs_ops = &sq_sysfs_ops, + .default_attrs = sq_sysfs_attrs, +}; -#ifdef CONFIG_PROC_FS -static int sq_mapping_read_proc(char *buf, char **start, off_t off, - int len, int *eof, void *data) +static int __devinit sq_sysdev_add(struct sys_device *sysdev) { - struct list_head *pos; - char *p = buf; + unsigned int cpu = sysdev->id; + struct kobject *kobj; - list_for_each_prev(pos, &sq_mapping_list) { - struct sq_mapping *entry; + sq_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL); + if (unlikely(!sq_kobject[cpu])) + return -ENOMEM; - entry = list_entry(pos, typeof(*entry), list); + kobj = sq_kobject[cpu]; + kobj->parent = &sysdev->kobj; + kobject_set_name(kobj, "%s", "sq"); + kobj->ktype = &ktype_percpu_entry; - p += sprintf(p, "%08lx-%08lx [%08lx]: %s\n", entry->sq_addr, - entry->sq_addr + entry->size - 1, entry->addr, - entry->name); - } - - return p - buf; + return kobject_register(kobj); } -#endif -static struct file_operations sq_fops = { - .owner = THIS_MODULE, - .mmap = sq_mmap, -}; +static int __devexit sq_sysdev_remove(struct sys_device *sysdev) +{ + unsigned int cpu = sysdev->id; + struct kobject *kobj = sq_kobject[cpu]; -static struct miscdevice sq_dev = { - .minor = STORE_QUEUE_MINOR, - .name = "sq", - .fops = &sq_fops, + kobject_unregister(kobj); + return 0; +} + +static struct sysdev_driver sq_sysdev_driver = { + .add = sq_sysdev_add, + .remove = __devexit_p(sq_sysdev_remove), }; static int __init sq_api_init(void) { - int ret; + unsigned int nr_pages = 0x04000000 >> PAGE_SHIFT; + unsigned int size = (nr_pages + (BITS_PER_LONG - 1)) / BITS_PER_LONG; + int ret = -ENOMEM; + printk(KERN_NOTICE "sq: Registering store queue API.\n"); - create_proc_read_entry("sq_mapping", 0, 0, sq_mapping_read_proc, 0); + sq_cache = kmem_cache_create("store_queue_cache", + sizeof(struct sq_mapping), 0, 0, + NULL, NULL); + if (unlikely(!sq_cache)) + return ret; - ret = misc_register(&sq_dev); - if (ret) - remove_proc_entry("sq_mapping", NULL); + 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); return ret; } static void __exit sq_api_exit(void) { - misc_deregister(&sq_dev); - remove_proc_entry("sq_mapping", NULL); + sysdev_driver_unregister(&cpu_sysdev_class, &sq_sysdev_driver); + kfree(sq_bitmap); + kmem_cache_destroy(sq_cache); } module_init(sq_api_init); @@ -445,11 +402,7 @@ 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 1378db375e17..a00022722e9e 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 Paul Mundt + * 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 @@ -49,7 +49,7 @@ static int __init sh_console_setup(struct console *co, char *options) return 0; } -static struct console early_console = { +static struct console bios_console = { .name = "bios", .write = sh_console_write, .setup = sh_console_setup, @@ -59,34 +59,43 @@ static struct console early_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 (!(ctrl_inw(SCIF_REG + 0x10) & 0x20)) ; + while (((sci_in(&scif_port, SCFDR) & 0x1f00 >> 8) == 16)) + ; - ctrl_outb(c, SCIF_REG + 12); - ctrl_outw((ctrl_inw(SCIF_REG + 0x10) & 0x9f), SCIF_REG + 0x10); + 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); + ; if (c == '\n') scif_sercon_putc('\r'); } -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) +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) @@ -96,7 +105,7 @@ static int __init scif_sercon_setup(struct console *con, char *options) return 0; } -static struct console early_console = { +static struct console scif_console = { .name = "sercon", .write = scif_sercon_write, .setup = scif_sercon_setup, @@ -104,7 +113,7 @@ static struct console early_console = { .index = -1, }; -void scif_sercon_init(int baud) +static void scif_sercon_init(int baud) { ctrl_outw(0, SCIF_REG + 8); ctrl_outw(0, SCIF_REG); @@ -122,16 +131,61 @@ void scif_sercon_init(int baud) } #endif -void __init enable_early_printk(void) +/* + * 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) { -#ifdef CONFIG_EARLY_SCIF_CONSOLE - scif_sercon_init(115200); + 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 + } #endif - register_console(&early_console); + + if (likely(early_console)) + register_console(early_console); + + return 1; } +__setup("earlyprintk=", setup_early_printk); -void disable_early_printk(void) +void __init disable_early_printk(void) { - unregister_console(&early_console); + if (!keep_early) { + printk("disabling early console\n"); + unregister_console(early_console); + } else + printk("keeping early console\n"); } - diff --git a/trunk/arch/sh/kernel/entry.S b/trunk/arch/sh/kernel/entry.S index 7dfd2ba75f7f..fe8221855b28 100644 --- a/trunk/arch/sh/kernel/entry.S +++ b/trunk/arch/sh/kernel/entry.S @@ -18,24 +18,6 @@ #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. @@ -326,7 +308,7 @@ ENTRY(exception_error) .align 2 ret_from_exception: preempt_stop() -ret_from_irq: +ENTRY(ret_from_irq) ! mov #OFF_SR, r0 mov.l @(r0,r15), r0 ! get status register @@ -389,11 +371,12 @@ work_pending: ! r8: current_thread_info ! t: result of "tst #_TIF_NEED_RESCHED, r0" bf/s work_resched - tst #_TIF_SIGPENDING, r0 + tst #(_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK), r0 work_notifysig: bt/s restore_all mov r15, r4 - mov #0, r5 + mov r12, r5 ! set arg1(save_r0) + mov r0, r6 mov.l 2f, r1 mova restore_all, r0 jmp @r1 @@ -431,7 +414,7 @@ work_resched: .align 2 1: .long schedule -2: .long do_signal +2: .long do_notify_resume .align 2 syscall_exit_work: @@ -552,6 +535,7 @@ 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: @@ -644,7 +628,7 @@ skip_restore: ! #if defined(CONFIG_KGDB_NMI) ! Clear in_nmi - mov.l 4f, k0 + mov.l 6f, k0 mov #0, k1 mov.b k1, @k0 #endif @@ -722,7 +706,7 @@ interrupt: ! ! .align 2 -handle_exception: +ENTRY(handle_exception) ! Using k0, k1 for scratch registers (r0_bank1, r1_bank), ! save all registers onto stack. ! @@ -732,8 +716,8 @@ 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 #0x20, k1 - shll8 k1 ! k1 := 8192 (== THREAD_SIZE) + mov #(THREAD_SIZE >> 8), k1 + shll8 k1 ! k1 := THREAD_SIZE add current, k1 mov k1, r15 ! change to kernel stack ! @@ -838,300 +822,3 @@ 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 9b9e6ef626ce..f5f53d14f245 100644 --- a/trunk/arch/sh/kernel/head.S +++ b/trunk/arch/sh/kernel/head.S @@ -11,6 +11,18 @@ * 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) @@ -42,18 +54,25 @@ 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 #0x20, r1 ! - shll8 r1 ! r1 = 8192 + mov #(THREAD_SIZE >> 8), r1 + shll8 r1 ! r1 = THREAD_SIZE 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 @@ -62,6 +81,14 @@ 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 @@ -69,7 +96,7 @@ ENTRY(_stext) .balign 4 1: .long 0x400080F0 ! MD=1, RB=0, BL=0, FD=1, IMASK=0xF -2: .long stack +2: .long init_thread_union+THREAD_SIZE 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 71c9fde2fd90..501fe03e3715 100644 --- a/trunk/arch/sh/kernel/io.c +++ b/trunk/arch/sh/kernel/io.c @@ -61,6 +61,73 @@ 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 c2e07f7f3496..c7ebd6aec951 100644 --- a/trunk/arch/sh/kernel/irq.c +++ b/trunk/arch/sh/kernel/irq.c @@ -1,5 +1,4 @@ -/* $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 @@ -7,13 +6,15 @@ * * SuperH version: Copyright (C) 1999 Niibe Yutaka */ - #include #include +#include #include #include #include #include +#include +#include #include /* @@ -60,15 +61,46 @@ 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 @@ -87,7 +119,135 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, #endif irq = irq_demux(irq); - __do_IRQ(irq, ®s); + +#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); + 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 42638b92b51c..9c6315f0335d 100644 --- a/trunk/arch/sh/kernel/kgdb_stub.c +++ b/trunk/arch/sh/kernel/kgdb_stub.c @@ -101,16 +101,17 @@ #include #include +#ifdef CONFIG_SH_KGDB_CONSOLE +#include +#endif + #include #include #include #include #include #include - -#ifdef CONFIG_SH_KGDB_CONSOLE -#include -#endif +#include /* Function pointers for linkage */ kgdb_debug_hook_t *kgdb_debug_hook; @@ -240,7 +241,6 @@ 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,29 +253,6 @@ 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 6bcd8d92399f..08587cdb64d6 100644 --- a/trunk/arch/sh/kernel/machine_kexec.c +++ b/trunk/arch/sh/kernel/machine_kexec.c @@ -29,12 +29,6 @@ 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 new file mode 100644 index 000000000000..10ab62c9aede --- /dev/null +++ b/trunk/arch/sh/kernel/pm.c @@ -0,0 +1,88 @@ +/* + * 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 f2031314cb2b..0b1d5dd7a93b 100644 --- a/trunk/arch/sh/kernel/process.c +++ b/trunk/arch/sh/kernel/process.c @@ -81,16 +81,6 @@ 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)); @@ -263,6 +253,7 @@ 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; @@ -277,8 +268,10 @@ 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]; @@ -299,13 +292,15 @@ 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) { + if (cpu_data->type == CPU_SH7729 || cpu_data->type == CPU_SH7710) { ctrl_outw(BBR_INST | BBR_READ | BBR_CPU, UBC_BBRA); ctrl_outl(BRCR_PCBA | BRCR_PCTE, UBC_BRCR); } else { @@ -344,6 +339,7 @@ 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) @@ -351,19 +347,21 @@ 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) { - ubc_set_tracing(next->mm->context & MMU_CONTEXT_ASID_MASK, - next->thread.ubc_pc); + int asid = 0; +#ifdef CONFIG_MMU + asid |= next->mm->context.id & MMU_CONTEXT_ASID_MASK; +#endif + ubc_set_tracing(asid, 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 f7eebbde3291..04ca13a041c1 100644 --- a/trunk/arch/sh/kernel/ptrace.c +++ b/trunk/arch/sh/kernel/ptrace.c @@ -224,7 +224,6 @@ 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 a3c24dcbf01d..184119eeae56 100644 --- a/trunk/arch/sh/kernel/semaphore.c +++ b/trunk/arch/sh/kernel/semaphore.c @@ -14,7 +14,7 @@ #include #include -spinlock_t semaphore_wake_lock; +DEFINE_SPINLOCK(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 e75189cb1db7..5f587332234a 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -43,27 +43,14 @@ 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 @@ -90,29 +77,8 @@ static struct sh_machine_vector* __init get_mv_byname(const char* name); static char command_line[COMMAND_LINE_SIZE] = { 0, }; -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 } -}; +static struct resource code_resource = { .name = "Kernel code", }; +static struct resource data_resource = { .name = "Kernel data", }; unsigned long memory_start, memory_end; @@ -145,6 +111,24 @@ 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; @@ -237,6 +221,9 @@ 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; } @@ -245,11 +232,6 @@ 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 @@ -368,14 +350,14 @@ void __init setup_arch(char **cmdline_p) #endif /* Perform the machine specific initialisation */ - platform_setup(); + if (likely(sh_mv.mv_setup)) + sh_mv.mv_setup(cmdline_p); 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; @@ -410,25 +392,18 @@ static int __init topology_init(void) subsys_initcall(topology_init); static const char *cpu_name[] = { - [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_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_SH_NONE] = "Unknown" }; @@ -438,8 +413,10 @@ 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", NULL + "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr", + "ptea", "llsc", "l2", NULL }; static void show_cpuflags(struct seq_file *m) @@ -460,7 +437,8 @@ 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; @@ -493,7 +471,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 (test_bit(SH_CACHE_COMBINED, &(boot_cpu_data.icache.flags))) { + if (boot_cpu_data.icache.flags & SH_CACHE_COMBINED) { seq_printf(m, "unified\n"); show_cacheinfo(m, "cache", boot_cpu_data.icache); } else { @@ -502,6 +480,10 @@ 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); @@ -617,4 +599,3 @@ 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 245ed8f945e8..d3cbfa2ad4a7 100644 --- a/trunk/arch/sh/kernel/sh_ksyms.c +++ b/trunk/arch/sh/kernel/sh_ksyms.c @@ -27,21 +27,11 @@ 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 @@ -52,13 +42,8 @@ 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); @@ -94,7 +79,9 @@ 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); @@ -102,11 +89,9 @@ EXPORT_SYMBOL(flush_dcache_page); EXPORT_SYMBOL(__flush_purge_region); #endif -#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); +#if defined(CONFIG_MMU) && (defined(CONFIG_CPU_SH4) || \ + defined(CONFIG_SH7705_CACHE_32KB)) +EXPORT_SYMBOL(clear_user_page); #endif EXPORT_SYMBOL(flush_tlb_page); @@ -116,7 +101,12 @@ 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); -EXPORT_SYMBOL(consistent_sync); +#endif EXPORT_SYMBOL(clear_page); diff --git a/trunk/arch/sh/kernel/signal.c b/trunk/arch/sh/kernel/signal.c index b475c4d2405f..5213f5bc6ce0 100644 --- a/trunk/arch/sh/kernel/signal.c +++ b/trunk/arch/sh/kernel/signal.c @@ -8,7 +8,6 @@ * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima * */ - #include #include #include @@ -21,6 +20,7 @@ #include #include #include +#include #include #include @@ -29,12 +29,8 @@ #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. */ @@ -43,51 +39,17 @@ 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); - saveset = current->blocked; + current->saved_sigmask = current->blocked; siginitset(¤t->blocked, mask); 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 -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; - } + current->state = TASK_INTERRUPTIBLE; + schedule(); + set_thread_flag(TIF_RESTORE_SIGMASK); + return -ERESTARTNOHAND; } asmlinkage int @@ -348,7 +310,12 @@ get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) return (void __user *)((sp - frame_size) & -8ul); } -static void setup_frame(int sig, struct k_sigaction *ka, +/* 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, sigset_t *set, struct pt_regs *regs) { struct sigframe __user *frame; @@ -368,15 +335,18 @@ static void 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]); @@ -402,21 +372,22 @@ static void setup_frame(int sig, struct k_sigaction *ka, set_fs(USER_DS); -#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 + pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", + current->comm, current->pid, frame, regs->pc, regs->pr); flush_cache_sigtramp(regs->pr); + if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode)) flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES); - return; + + return 0; give_sigsegv: force_sigsegv(sig, current); + return -EFAULT; } -static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, +static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set, struct pt_regs *regs) { struct rt_sigframe __user *frame; @@ -452,6 +423,10 @@ static void 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]); @@ -477,28 +452,31 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, set_fs(USER_DS); -#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 + pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", + current->comm, current->pid, frame, regs->pc, regs->pr); flush_cache_sigtramp(regs->pr); + if ((-regs->pr & (L1_CACHE_BYTES-1)) < sizeof(frame->retcode)) flush_cache_sigtramp(regs->pr + L1_CACHE_BYTES); - return; + + return 0; give_sigsegv: force_sigsegv(sig, current); + return -EFAULT; } /* * OK, we're invoking a handler */ -static void +static int 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.. */ @@ -539,19 +517,23 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, /* Set up the stack frame */ if (ka->sa.sa_flags & SA_SIGINFO) - setup_rt_frame(sig, ka, info, oldset, regs); + ret = setup_rt_frame(sig, ka, info, oldset, regs); else - setup_frame(sig, ka, oldset, regs); + ret = setup_frame(sig, ka, oldset, regs); if (ka->sa.sa_flags & SA_ONESHOT) ka->sa.sa_handler = SIG_DFL; - 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); + 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; } /* @@ -563,11 +545,12 @@ 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. */ -int do_signal(struct pt_regs *regs, sigset_t *oldset) +static void do_signal(struct pt_regs *regs, unsigned int save_r0) { siginfo_t info; int signr; struct k_sigaction ka; + sigset_t *oldset; /* * We want the common case to go fast, which @@ -576,19 +559,27 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) * if so. */ if (!user_mode(regs)) - return 1; + return; if (try_to_freeze()) goto no_signal; - if (!oldset) + 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. */ - handle_signal(signr, &ka, &info, oldset, regs); - return 1; + 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); + } } no_signal: @@ -597,10 +588,27 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) /* Restart the system call - no handlers present */ if (regs->regs[0] == -ERESTARTNOHAND || regs->regs[0] == -ERESTARTSYS || - regs->regs[0] == -ERESTARTNOINTR || - regs->regs[0] == -ERESTART_RESTARTBLOCK) { + regs->regs[0] == -ERESTARTNOINTR) { + regs->regs[0] = save_r0; + regs->pc -= 2; + } else if (regs->regs[0] == -ERESTART_RESTARTBLOCK) { regs->pc -= 2; + regs->regs[3] = __NR_restart_syscall; } } - return 0; + + /* 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); } diff --git a/trunk/arch/sh/kernel/sys_sh.c b/trunk/arch/sh/kernel/sys_sh.c index 917b2f32f260..b68ff705f067 100644 --- a/trunk/arch/sh/kernel/sys_sh.c +++ b/trunk/arch/sh/kernel/sys_sh.c @@ -21,7 +21,8 @@ #include #include #include - +#include +#include #include #include @@ -44,11 +45,16 @@ asmlinkage int sys_pipe(unsigned long r4, unsigned long r5, return error; } -#if defined(HAVE_ARCH_UNMAPPED_AREA) +unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ + +EXPORT_SYMBOL(shm_align_mask); + /* - * To avoid cache alias, we map the shard page with same color. + * To avoid cache aliases, we map the shared page with same color. */ -#define COLOUR_ALIGN(addr) (((addr)+SHMLBA-1)&~(SHMLBA-1)) +#define COLOUR_ALIGN(addr, pgoff) \ + ((((addr) + shm_align_mask) & ~shm_align_mask) + \ + (((pgoff) << PAGE_SHIFT) & shm_align_mask)) unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) @@ -56,43 +62,52 @@ 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 & (SHMLBA - 1))) + if ((flags & MAP_SHARED) && (addr & shm_align_mask)) return -EINVAL; return addr; } - if (len > TASK_SIZE) + if (unlikely(len > TASK_SIZE)) return -ENOMEM; + do_colour_align = 0; + if (filp || (flags & MAP_SHARED)) + do_colour_align = 1; + if (addr) { - if (flags & MAP_PRIVATE) - addr = PAGE_ALIGN(addr); + if (do_colour_align) + addr = COLOUR_ALIGN(addr, pgoff); else - addr = COLOUR_ALIGN(addr); + addr = PAGE_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) { + + if (len > mm->cached_hole_size) { + start_addr = addr = mm->free_area_cache; + } else { mm->cached_hole_size = 0; - mm->free_area_cache = TASK_UNMAPPED_BASE; + start_addr = addr = TASK_UNMAPPED_BASE; } - if (flags & MAP_PRIVATE) - addr = PAGE_ALIGN(mm->free_area_cache); - else - addr = COLOUR_ALIGN(mm->free_area_cache); - start_addr = addr; full_search: + if (do_colour_align) + addr = COLOUR_ALIGN(addr, pgoff); + else + addr = PAGE_ALIGN(mm->free_area_cache); + for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { /* At this point: (!vma || addr < vma->vm_end). */ - if (TASK_SIZE - len < addr) { + if (unlikely(TASK_SIZE - len < addr)) { /* * Start a new search - just in case we missed * some holes. @@ -104,7 +119,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, } return -ENOMEM; } - if (!vma || addr + len <= vma->vm_start) { + if (likely(!vma || addr + len <= vma->vm_start)) { /* * Remember the place where we stopped the search: */ @@ -115,11 +130,10 @@ 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 (!(flags & MAP_PRIVATE)) - addr = COLOUR_ALIGN(addr); + if (do_colour_align) + addr = COLOUR_ALIGN(addr, pgoff); } } -#endif static inline long do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, diff --git a/trunk/arch/sh/kernel/syscalls.S b/trunk/arch/sh/kernel/syscalls.S new file mode 100644 index 000000000000..768334e95075 --- /dev/null +++ b/trunk/arch/sh/kernel/syscalls.S @@ -0,0 +1,353 @@ +/* + * 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 a1589f85499d..450c68f1df05 100644 --- a/trunk/arch/sh/kernel/time.c +++ b/trunk/arch/sh/kernel/time.c @@ -3,13 +3,12 @@ * * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka * Copyright (C) 2000 Philipp Rumpf - * Copyright (C) 2002, 2003, 2004, 2005 Paul Mundt + * Copyright (C) 2002 - 2006 Paul Mundt * Copyright (C) 2002 M. R. Brown * * Some code taken from i386 version. * Copyright (C) 1991, 1992, 1995 Linus Torvalds */ - #include #include #include @@ -19,22 +18,26 @@ #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); -/* 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 +/* 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; /* * Scheduler clock - returns current time in nanosec units. @@ -48,16 +51,10 @@ 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)); @@ -70,7 +67,6 @@ void do_gettimeofday(struct timeval *tv) tv->tv_sec = sec; tv->tv_usec = usec; } - EXPORT_SYMBOL(do_gettimeofday); int do_settimeofday(struct timespec *tv) @@ -88,8 +84,7 @@ int do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ - nsec -= 1000 * (get_timer_offset() + - (jiffies - wall_jiffies) * (1000000 / HZ)); + nsec -= 1000 * get_timer_offset(); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -103,7 +98,6 @@ int do_settimeofday(struct timespec *tv) return 0; } - EXPORT_SYMBOL(do_settimeofday); /* last time the RTC clock got updated */ @@ -115,7 +109,7 @@ static long last_rtc_update; */ void handle_timer_tick(struct pt_regs *regs) { - do_timer(regs); + do_timer(1); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -135,7 +129,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_set_time(xtime.tv_sec) == 0) + if (rtc_sh_set_time(xtime.tv_sec) == 0) last_rtc_update = xtime.tv_sec; else /* do it again in 60s */ @@ -143,8 +137,33 @@ 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) @@ -156,7 +175,6 @@ 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); @@ -168,15 +186,9 @@ void __init time_init(void) clk_init(); - 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); + rtc_sh_get_time(&xtime); + 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 d4212add53b2..205816fcf0da 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_get_time(&ts2); + rtc_sh_get_time(&ts2); do { - rtc_get_time(&ts1); + rtc_sh_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_get_time(&ts2); + rtc_sh_get_time(&ts2); } while (ts1.tv_nsec == ts2.tv_nsec && ts1.tv_sec == ts2.tv_sec); freq = 0xffffffff - ctrl_inl(TMU0_TCNT); @@ -188,6 +188,18 @@ 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; @@ -197,7 +209,7 @@ static int tmu_timer_init(void) tmu0_clk.parent = clk_get("module_clk"); /* Start TMU0 */ - ctrl_outb(0, TMU_TSTR); + tmu_timer_stop(); #if !defined(CONFIG_CPU_SUBTYPE_SH7300) && !defined(CONFIG_CPU_SUBTYPE_SH7760) ctrl_outb(TMU_TOCR_INIT, TMU_TOCR); #endif @@ -211,13 +223,15 @@ static int tmu_timer_init(void) ctrl_outl(interval, TMU0_TCOR); ctrl_outl(interval, TMU0_TCNT); - ctrl_outb(TMU_TSTR_INIT, TMU_TSTR); + tmu_timer_start(); 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 d9db1180f770..c2c597e09482 100644 --- a/trunk/arch/sh/kernel/traps.c +++ b/trunk/arch/sh/kernel/traps.c @@ -36,40 +36,15 @@ #ifdef CONFIG_SH_KGDB #include -#define CHK_REMOTE_DEBUG(regs) \ -{ \ - if ((kgdb_debug_hook != (kgdb_debug_hook_t *) NULL) && (!user_mode(regs))) \ - { \ - (*kgdb_debug_hook)(regs); \ - } \ +#define CHK_REMOTE_DEBUG(regs) \ +{ \ + if (kgdb_debug_hook && !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 @@ -86,7 +61,7 @@ asmlinkage void do_##name(unsigned long r4, unsigned long r5, \ #define VMALLOC_OFFSET (8*1024*1024) #define MODULE_RANGE (8*1024*1024) -spinlock_t die_lock; +DEFINE_SPINLOCK(die_lock); void die(const char * str, struct pt_regs * regs, long err) { @@ -575,8 +550,117 @@ int is_dsp_inst(struct pt_regs *regs) #define is_dsp_inst(regs) (0) #endif /* CONFIG_SH_DSP */ -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) +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); +} asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7, @@ -634,14 +718,16 @@ void __init trap_init(void) exception_handling_table[TRAP_ILLEGAL_SLOT_INST] = (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; - } +#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; #endif /* Setup VBR for boot cpu */ @@ -655,20 +741,12 @@ void show_stack(struct task_struct *tsk, unsigned long *sp) unsigned long module_end = VMALLOC_END; int i = 1; - if (tsk && !sp) { + if (!tsk) + tsk = current; + if (tsk == current) + sp = (unsigned long *)current_stack_pointer; + else 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 95fdd9135fcf..5eb930918186 100644 --- a/trunk/arch/sh/kernel/vmlinux.lds.S +++ b/trunk/arch/sh/kernel/vmlinux.lds.S @@ -2,6 +2,7 @@ * ld script to make SuperH Linux kernel * Written by Niibe Yutaka */ +#include #include #ifdef CONFIG_CPU_LITTLE_ENDIAN @@ -13,7 +14,7 @@ OUTPUT_ARCH(sh) ENTRY(_start) SECTIONS { - . = 0x80000000 + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET; + . = CONFIG_PAGE_OFFSET + CONFIG_MEMORY_START + CONFIG_ZERO_PAGE_OFFSET; _text = .; /* Text and read-only data */ text = .; /* Text and read-only data */ .empty_zero_page : { @@ -40,16 +41,16 @@ SECTIONS *(.data) /* Align the initial ramdisk image (INITRD) on page boundaries. */ - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __rd_start = .; *(.initrd) - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __rd_end = .; CONSTRUCTORS } - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); .data.page_aligned : { *(.data.idt) } . = ALIGN(32); @@ -60,12 +61,10 @@ SECTIONS _edata = .; /* End of data section */ - . = ALIGN(8192); /* init_task */ + . = ALIGN(THREAD_SIZE); /* init_task */ .data.init_task : { *(.data.init_task) } - /* stack */ - .stack : { stack = .; _stack = .; } - . = ALIGN(4096); /* Init code and data */ + . = ALIGN(PAGE_SIZE); /* Init code and data */ __init_begin = .; _sinittext = .; .init.text : { *(.init.text) } @@ -96,7 +95,7 @@ SECTIONS __machvec_start = .; .init.machvec : { *(.init.machvec) } __machvec_end = .; - . = ALIGN(4096); + . = ALIGN(PAGE_SIZE); __init_end = .; . = ALIGN(4); diff --git a/trunk/arch/sh/kernel/vsyscall/Makefile b/trunk/arch/sh/kernel/vsyscall/Makefile new file mode 100644 index 000000000000..4bbce1cfa359 --- /dev/null +++ b/trunk/arch/sh/kernel/vsyscall/Makefile @@ -0,0 +1,36 @@ +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 new file mode 100644 index 000000000000..d4b5be4f3d5f --- /dev/null +++ b/trunk/arch/sh/kernel/vsyscall/vsyscall-note.S @@ -0,0 +1,25 @@ +/* + * 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 new file mode 100644 index 000000000000..555a64f124ca --- /dev/null +++ b/trunk/arch/sh/kernel/vsyscall/vsyscall-sigreturn.S @@ -0,0 +1,39 @@ +#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 new file mode 100644 index 000000000000..c2ac7f0282b3 --- /dev/null +++ b/trunk/arch/sh/kernel/vsyscall/vsyscall-syscall.S @@ -0,0 +1,10 @@ +#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 new file mode 100644 index 000000000000..3b6eb34c43fa --- /dev/null +++ b/trunk/arch/sh/kernel/vsyscall/vsyscall-trapa.S @@ -0,0 +1,42 @@ + .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 new file mode 100644 index 000000000000..075d6cc1a2d7 --- /dev/null +++ b/trunk/arch/sh/kernel/vsyscall/vsyscall.c @@ -0,0 +1,150 @@ +/* + * 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 new file mode 100644 index 000000000000..b13c3d439fee --- /dev/null +++ b/trunk/arch/sh/kernel/vsyscall/vsyscall.lds.S @@ -0,0 +1,74 @@ +/* + * 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 7c50dfe68c07..cbdd0d40e545 100644 --- a/trunk/arch/sh/lib/checksum.S +++ b/trunk/arch/sh/lib/checksum.S @@ -202,8 +202,9 @@ 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 - add #2,r6 ! r6 was < 2. Deal with it. + mov r6,r2 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 db6b736537ad..560bc17eebdd 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.w @(0x02,r5), r12 ! 18 LS (latency=2) - xtrct r10, r9 ! 48 EX + mov.l @(0x00,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 95670090680e..af91fe2b72a6 100644 --- a/trunk/arch/sh/lib/memset.S +++ b/trunk/arch/sh/lib/memset.S @@ -29,6 +29,7 @@ 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 new file mode 100644 index 000000000000..638b342c781a --- /dev/null +++ b/trunk/arch/sh/math-emu/Makefile @@ -0,0 +1 @@ +obj-y := math.o diff --git a/trunk/arch/sh/math-emu/math.c b/trunk/arch/sh/math-emu/math.c new file mode 100644 index 000000000000..26b6046814fd --- /dev/null +++ b/trunk/arch/sh/math-emu/math.c @@ -0,0 +1,624 @@ +/* + * 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 new file mode 100644 index 000000000000..8ae1bd310ad0 --- /dev/null +++ b/trunk/arch/sh/math-emu/sfp-util.h @@ -0,0 +1,72 @@ +/* + * 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 fb586b1cf8bb..9dd606464d23 100644 --- a/trunk/arch/sh/mm/Kconfig +++ b/trunk/arch/sh/mm/Kconfig @@ -20,7 +20,10 @@ config CPU_SH4 config CPU_SH4A bool select CPU_SH4 - select CPU_HAS_INTC2_IRQ + +config CPU_SH4AL_DSP + bool + select CPU_SH4A config CPU_SUBTYPE_ST40 bool @@ -48,6 +51,12 @@ 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 @@ -69,6 +78,12 @@ 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 @@ -133,10 +148,6 @@ 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 @@ -144,6 +155,17 @@ 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 @@ -161,15 +183,59 @@ 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 + depends on CPU_SH4A && MMU 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 9489a1424644..3ffd7f68c0a2 100644 --- a/trunk/arch/sh/mm/Makefile +++ b/trunk/arch/sh/mm/Makefile @@ -6,20 +6,26 @@ 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 pg-sh4.o +obj-$(CONFIG_CPU_SH4) += cache-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 +mmu-$(CONFIG_MMU) := fault.o clear_page.o copy_page.o tlb-flush.o \ + ioremap.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 ioremap.o +obj-$(CONFIG_CPU_SH3) += tlb-sh3.o +obj-$(CONFIG_CPU_SH4) += tlb-sh4.o pg-sh4.o obj-$(CONFIG_SH7705_CACHE_32KB) += pg-sh7705.o endif -obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o +obj-$(CONFIG_SH7705_CACHE_32KB) += cache-sh7705.o +obj-$(CONFIG_32BIT) += pmb.o diff --git a/trunk/arch/sh/mm/cache-debugfs.c b/trunk/arch/sh/mm/cache-debugfs.c new file mode 100644 index 000000000000..a22d914e4d15 --- /dev/null +++ b/trunk/arch/sh/mm/cache-debugfs.c @@ -0,0 +1,147 @@ +/* + * 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 524cea5b47f9..e48cc22724d9 100644 --- a/trunk/arch/sh/mm/cache-sh4.c +++ b/trunk/arch/sh/mm/cache-sh4.c @@ -2,49 +2,120 @@ * arch/sh/mm/cache-sh4.c * * Copyright (C) 1999, 2000, 2002 Niibe Yutaka - * Copyright (C) 2001, 2002, 2003, 2004 Paul Mundt + * Copyright (C) 2001 - 2006 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 -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); +/* + * 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"); +} /* * SH-4 has virtually indexed and physically tagged cache. */ -struct semaphore p3map_sem[4]; +/* 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]; void __init p3_cache_init(void) { - if (remap_area_pages(P3SEG, 0, PAGE_SIZE*4, _PAGE_CACHABLE)) + 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)) panic("%s failed.", __FUNCTION__); - sema_init (&p3map_sem[0], 1); - sema_init (&p3map_sem[1], 1); - sema_init (&p3map_sem[2], 1); - sema_init (&p3map_sem[3], 1); + for (i = 0; i < cpu_data->dcache.n_aliases; i++) + sema_init(&p3map_sem[i], 1); } /* @@ -89,7 +160,6 @@ void __flush_purge_region(void *start, int size) } } - /* * No write back please */ @@ -108,40 +178,6 @@ 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. * @@ -153,14 +189,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); @@ -172,30 +208,33 @@ 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; - extern void __flush_cache_4096(unsigned long addr, unsigned long phys, unsigned long exec_offset); + unsigned long flags, exec_offset = 0; /* - * SH7751, SH7751R, and ST40 have no restriction to handle cache. - * (While SH7750 must do that at P2 area.) + * 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. */ - 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); - } + 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); } /* @@ -206,15 +245,19 @@ 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 */ - 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); + n = cpu_data->dcache.n_aliases; + for (i = 0; i < n; i++, addr += PAGE_SIZE) + flush_cache_4096(addr, phys); } + + wmb(); } +/* TODO: Selective icache invalidation through IC address array.. */ static inline void flush_icache_all(void) { unsigned long flags, ccr; @@ -227,34 +270,142 @@ 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) { - if (cpu_data->dcache.ways == 1) - __flush_dcache_all(); - else - __flush_dcache_all_ex(); + flush_dcache_all(); 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) { - /* 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 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. */ - flush_cache_all(); + 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. + */ + 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(); } /* @@ -263,27 +414,40 @@ 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) & CACHE_ALIAS) { + if ((address^phys) & alias_mask) { /* Loop 4K of the D-cache */ flush_cache_4096( - CACHE_OC_ADDRESS_ARRAY | (address & CACHE_ALIAS), + CACHE_OC_ADDRESS_ARRAY | (address & alias_mask), phys); /* Loop another 4K of the D-cache */ flush_cache_4096( - CACHE_OC_ADDRESS_ARRAY | (phys & CACHE_ALIAS), + CACHE_OC_ADDRESS_ARRAY | (phys & alias_mask), phys); } - if (vma->vm_flags & VM_EXEC) - /* Loop 4K (half) of the I-cache */ + 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. + */ flush_cache_4096( - CACHE_IC_ADDRESS_ARRAY | (address & 0x1000), + CACHE_IC_ADDRESS_ARRAY | (address & alias_mask), phys); + } } /* @@ -298,52 +462,31 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long address, unsigne void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { - 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; - - dir = pgd_offset(vma->vm_mm, p); - pmd = pmd_offset(dir, p); + /* + * 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; - 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) + /* + * 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. + */ flush_icache_all(); + } } /* @@ -357,5 +500,273 @@ 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 bf94eedb0a8e..045abdf078f5 100644 --- a/trunk/arch/sh/mm/cache-sh7705.c +++ b/trunk/arch/sh/mm/cache-sh7705.c @@ -9,7 +9,6 @@ * for more details. * */ - #include #include #include @@ -25,14 +24,10 @@ #include #include -/* 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)) - +/* + * The 32KB cache on the SH7705 suffers from the same synonym problem + * as SH4 CPUs + */ static inline void cache_wback_all(void) { unsigned long ways, waysize, addrstart; @@ -73,7 +68,6 @@ 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 */ @@ -128,7 +122,6 @@ 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) @@ -186,7 +179,8 @@ 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); } @@ -203,4 +197,3 @@ 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 08acead7b2a1..7b96425ae270 100644 --- a/trunk/arch/sh/mm/clear_page.S +++ b/trunk/arch/sh/mm/clear_page.S @@ -193,102 +193,5 @@ ENTRY(__clear_user_page) nop .L4096: .word 4096 -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 ee73e30263af..c81e6b67ad30 100644 --- a/trunk/arch/sh/mm/consistent.c +++ b/trunk/arch/sh/mm/consistent.c @@ -9,6 +9,8 @@ */ #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 775f86cd3fe8..68663b8f99ae 100644 --- a/trunk/arch/sh/mm/fault.c +++ b/trunk/arch/sh/mm/fault.c @@ -1,33 +1,22 @@ -/* $Id: fault.c,v 1.14 2004/01/13 05:52:11 kkojima Exp $ +/* + * Page fault handler for SH with an MMU. * - * 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); @@ -80,7 +69,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))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) goto bad_area; } @@ -160,7 +149,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, */ out_of_memory: up_read(&mm->mmap_sem); - if (current->pid == 1) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; @@ -187,18 +176,30 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, goto no_context; } +#ifdef CONFIG_SH_STORE_QUEUES /* - * Called with interrupt disabled. + * 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. */ -asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess, - unsigned long address) +#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) { - unsigned long addrmax = P4SEG; pgd_t *pgd; + pud_t *pud; pmd_t *pmd; pte_t *pte; pte_t entry; - struct mm_struct *mm; + struct mm_struct *mm = current->mm; spinlock_t *ptl; int ret = 1; @@ -207,31 +208,37 @@ asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess, kgdb_bus_err_hook(); #endif -#ifdef CONFIG_SH_STORE_QUEUES - addrmax = P4SEG_STORE_QUE + 0x04000000; -#endif - - if (address >= P3SEG && address < addrmax) { + /* + * 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) { pgd = pgd_offset_k(address); mm = NULL; - } else if (address >= TASK_SIZE) - return 1; - else if (!(mm = current->mm)) - return 1; - else + } else { + if (unlikely(address >= TASK_SIZE || !mm)) + return 1; + pgd = pgd_offset(mm, address); + } - pmd = pmd_offset(pgd, address); + pud = pud_offset(pgd, address); + if (pud_none_or_clear_bad(pud)) + return 1; + pmd = pmd_offset(pud, 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 (pte_none(entry) || pte_not_present(entry) - || (writeaccess && !pte_write(entry))) + if (unlikely(pte_none(entry) || pte_not_present(entry))) + goto unlock; + if (unlikely(writeaccess && !pte_write(entry))) goto unlock; if (writeaccess) @@ -243,13 +250,7 @@ asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess, * ITLB is not affected by "ldtlb" instruction. * So, we need to flush the entry by ourselves. */ - - { - unsigned long flags; - local_irq_save(flags); - __flush_tlb_page(get_asid(), address&PAGE_MASK); - local_irq_restore(flags); - } + __flush_tlb_page(get_asid(), address & PAGE_MASK); #endif set_pte(pte, entry); @@ -260,121 +261,3 @@ asmlinkage int __do_page_fault(struct pt_regs *regs, unsigned long writeaccess, 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 2a85bc15a412..329059d6b54a 100644 --- a/trunk/arch/sh/mm/hugetlbpage.c +++ b/trunk/arch/sh/mm/hugetlbpage.c @@ -26,61 +26,41 @@ 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) { - pmd = pmd_alloc(mm, pgd, addr); - if (pmd) - pte = pte_alloc_map(mm, pmd, addr); + pud = pud_alloc(mm, pgd, addr); + if (pud) { + pmd = pmd_alloc(mm, pud, 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) { - 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; + pud = pud_offset(pgd, addr); + if (pud) { + pmd = pmd_offset(pud, addr); + if (pmd) + pte = pte_offset_map(pmd, addr); + } } -} - -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; + return pte; } struct page *follow_huge_addr(struct mm_struct *mm, diff --git a/trunk/arch/sh/mm/init.c b/trunk/arch/sh/mm/init.c index 8ea27ca4b700..7154d1ce9785 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,6 +80,7 @@ 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; @@ -89,7 +90,17 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) return; } - pmd = pmd_offset(pgd, addr); + 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); if (pmd_none(*pmd)) { pte = (pte_t *)get_zeroed_page(GFP_ATOMIC); set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER)); @@ -212,6 +223,8 @@ 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]; @@ -237,8 +250,13 @@ 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)); @@ -254,7 +272,12 @@ void __init mem_init(void) datasize = (unsigned long) &_edata - (unsigned long) &_etext; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; - printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n", + 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", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), max_mapnr << (PAGE_SHIFT-10), codesize >> 10, @@ -263,6 +286,9 @@ 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 96fa4a999e2a..a9fe80cfc233 100644 --- a/trunk/arch/sh/mm/ioremap.c +++ b/trunk/arch/sh/mm/ioremap.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -134,6 +135,20 @@ 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.. */ @@ -192,7 +207,7 @@ void __iounmap(void __iomem *addr) unsigned long vaddr = (unsigned long __force)addr; struct vm_struct *p; - if (PXSEG(vaddr) < P3SEG) + if (PXSEG(vaddr) < P3SEG || is_pci_memaddr(vaddr)) return; #ifdef CONFIG_32BIT diff --git a/trunk/arch/sh/mm/pg-nommu.c b/trunk/arch/sh/mm/pg-nommu.c index 8f9165a4e333..d15221beaa16 100644 --- a/trunk/arch/sh/mm/pg-nommu.c +++ b/trunk/arch/sh/mm/pg-nommu.c @@ -14,23 +14,24 @@ #include #include -static void copy_page_nommu(void *to, void *from) +void copy_page_nommu(void *to, void *from) { memcpy(to, from, PAGE_SIZE); } -static void clear_page_nommu(void *to) +void clear_page_nommu(void *to) { memset(to, 0, PAGE_SIZE); } -static int __init pg_nommu_init(void) +__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n) { - copy_page = copy_page_nommu; - clear_page = clear_page_nommu; - + memcpy(to, from, n); return 0; } -subsys_initcall(pg_nommu_init); - +__kernel_size_t __clear_user(void *to, __kernel_size_t n) +{ + memset(to, 0, n); + return 0; +} diff --git a/trunk/arch/sh/mm/pg-sh4.c b/trunk/arch/sh/mm/pg-sh4.c index c776b60fc250..07371ed7a313 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 Paul Mundt + * Copyright (C) 2002 - 2005 Paul Mundt * * Released under the terms of the GNU GPL v2.0. */ @@ -23,6 +23,8 @@ extern struct semaphore p3map_sem[]; +#define CACHE_ALIAS (cpu_data->dcache.alias_mask) + /* * clear_user_page * @to: P1 address @@ -35,14 +37,15 @@ 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 *dir = pgd_offset_k(p3_addr); - pmd_t *pmd = pmd_offset(dir, p3_addr); + pgd_t *pgd = pgd_offset_k(p3_addr); + pud_t *pud = pud_offset(pgd, p3_addr); + pmd_t *pmd = pmd_offset(pud, p3_addr); pte_t *pte = pte_offset_kernel(pmd, p3_addr); pte_t entry; unsigned long flags; @@ -67,21 +70,22 @@ 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 *dir = pgd_offset_k(p3_addr); - pmd_t *pmd = pmd_offset(dir, p3_addr); + pgd_t *pgd = pgd_offset_k(p3_addr); + pud_t *pud = pud_offset(pgd, p3_addr); + pmd_t *pmd = pmd_offset(pud, 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 new file mode 100644 index 000000000000..92e745341e4d --- /dev/null +++ b/trunk/arch/sh/mm/pmb.c @@ -0,0 +1,400 @@ +/* + * 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 new file mode 100644 index 000000000000..73ec7f6084fa --- /dev/null +++ b/trunk/arch/sh/mm/tlb-flush.c @@ -0,0 +1,134 @@ +/* + * 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 115b1b6be40b..812b2d567de2 100644 --- a/trunk/arch/sh/mm/tlb-sh4.c +++ b/trunk/arch/sh/mm/tlb-sh4.c @@ -36,7 +36,6 @@ 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) @@ -59,10 +58,11 @@ void update_mmu_cache(struct vm_area_struct * vma, ctrl_outl(vpn, MMU_PTEH); pteval = pte_val(pte); + /* Set PTEA register */ - /* TODO: make this look less hacky */ - ptea = ((pteval >> 28) & 0xe) | (pteval & 0x1); - ctrl_outl(ptea, MMU_PTEA); + if (cpu_data->flags & CPU_HAS_PTEA) + /* TODO: make this look less hacky */ + ctrl_outl(((pteval >> 28) & 0xe) | (pteval & 0x1), 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 686738d4aa3c..1f25d9bb7538 100644 --- a/trunk/arch/sh/oprofile/Makefile +++ b/trunk/arch/sh/oprofile/Makefile @@ -7,7 +7,11 @@ 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 182fe9092577..ac57638977ee 100644 --- a/trunk/arch/sh/tools/mach-types +++ b/trunk/arch/sh/tools/mach-types @@ -8,16 +8,15 @@ 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 @@ -25,4 +24,9 @@ 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/time.c b/trunk/arch/sh64/kernel/time.c index b8162e59030e..9c4a38a8698c 100644 --- a/trunk/arch/sh64/kernel/time.c +++ b/trunk/arch/sh64/kernel/time.c @@ -107,8 +107,6 @@ #define TICK_SIZE (tick_nsec / 1000) -extern unsigned long wall_jiffies; - static unsigned long tmu_base, rtc_base; unsigned long cprc_base; @@ -194,13 +192,6 @@ 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)); @@ -229,8 +220,7 @@ int do_settimeofday(struct timespec *tv) * wall time. Discover what correction gettimeofday() would have * made, and then undo it! */ - nsec -= 1000 * (usecs_since_tick() + - (jiffies - wall_jiffies) * (1000000 / HZ)); + nsec -= 1000 * usecs_since_tick(); wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -298,7 +288,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(regs); + do_timer(1); #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 f08d0eaf6497..8e2f6c28b739 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 (tsk->pid == 1) { + if (is_init(tsk)) { 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 (current->pid == 1) { + if (is_init(current)) { panic("INIT out of memory\n"); yield(); goto survive; } printk("fault:Out of memory\n"); up_read(&mm->mmap_sem); - if (current->pid == 1) { + if (is_init(current)) { 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 bfd31aac2df3..edb6cc665f56 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(regs); + do_timer(1); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -765,8 +765,6 @@ 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; @@ -775,26 +773,17 @@ 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)); @@ -819,8 +808,7 @@ 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() + - (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ)); + tv->tv_nsec -= 1000 * do_gettimeoffset(); while (tv->tv_nsec < 0) { tv->tv_nsec += NSEC_PER_SEC; tv->tv_sec--; diff --git a/trunk/arch/sparc/kernel/time.c b/trunk/arch/sparc/kernel/time.c index 845081b01267..e10dc831944d 100644 --- a/trunk/arch/sparc/kernel/time.c +++ b/trunk/arch/sparc/kernel/time.c @@ -43,8 +43,6 @@ #include #include -extern unsigned long wall_jiffies; - DEFINE_SPINLOCK(rtc_lock); enum sparc_clock_type sp_clock_typ; DEFINE_SPINLOCK(mostek_lock); @@ -128,7 +126,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs * regs) #endif clear_clock_irq(); - do_timer(regs); + do_timer(1); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -449,7 +447,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, wall_jiffies, et al.) + * now (both members of xtime, et al.) */ void do_gettimeofday(struct timeval *tv) { @@ -459,26 +457,17 @@ 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)); @@ -521,8 +510,7 @@ 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() + - (jiffies - wall_jiffies) * (USEC_PER_SEC / HZ)); + nsec -= 1000 * do_gettimeoffset(); 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 577505b692ae..ef095b6c43b1 100644 --- a/trunk/arch/sparc/lib/copy_user.S +++ b/trunk/arch/sparc/lib/copy_user.S @@ -14,6 +14,7 @@ #include #include #include +#include /* Work around cpp -rob */ #define ALLOC #alloc @@ -366,6 +367,9 @@ 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/defconfig b/trunk/arch/sparc64/defconfig index 51cf6027b701..0fbdaa5daa8c 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 -# Sat Sep 23 18:32:19 2006 +# Tue Sep 26 23:09:35 2006 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -141,6 +141,7 @@ 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 @@ -194,21 +195,9 @@ 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=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_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y CONFIG_IPV6_ROUTER_PREF=y @@ -247,6 +236,7 @@ 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) @@ -401,6 +391,7 @@ CONFIG_IDEDMA_AUTO=y # CONFIG_RAID_ATTRS=m CONFIG_SCSI=y +CONFIG_SCSI_NETLINK=y CONFIG_SCSI_PROC_FS=y # @@ -422,12 +413,13 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set # -# SCSI Transport Attributes +# SCSI Transports # 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 @@ -440,16 +432,18 @@ 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 @@ -461,6 +455,11 @@ 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) # @@ -575,6 +574,7 @@ 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,6 +1006,7 @@ 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 @@ -1353,6 +1354,7 @@ 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/sys_sparc32.c b/trunk/arch/sparc64/kernel/sys_sparc32.c index c88ae23ce812..69444f266e2d 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 +#ifndef CONFIG_SYSCTL_SYSCALL return -ENOSYS; #else struct __sysctl_args32 tmp; diff --git a/trunk/arch/sparc64/kernel/time.c b/trunk/arch/sparc64/kernel/time.c index b0b4feeec098..00f6fc4aaaff 100644 --- a/trunk/arch/sparc64/kernel/time.c +++ b/trunk/arch/sparc64/kernel/time.c @@ -53,8 +53,6 @@ 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; @@ -465,7 +463,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(regs); + do_timer(1); /* Guarantee that the following sequences execute * uninterrupted. @@ -496,7 +494,7 @@ void timer_tick_interrupt(struct pt_regs *regs) { write_seqlock(&xtime_lock); - do_timer(regs); + do_timer(1); timer_check_rtc(); diff --git a/trunk/arch/sparc64/mm/init.c b/trunk/arch/sparc64/mm/init.c index dcba4e6ab570..09cb7fccc03a 100644 --- a/trunk/arch/sparc64/mm/init.c +++ b/trunk/arch/sparc64/mm/init.c @@ -920,8 +920,7 @@ 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; - if (ramdisk_image >= (unsigned long)_end - 2 * PAGE_SIZE) - ramdisk_image -= KERNBASE; + 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 642541769a17..9c581328e76a 100644 --- a/trunk/arch/sparc64/solaris/misc.c +++ b/trunk/arch/sparc64/solaris/misc.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -422,7 +423,9 @@ 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 9558a7cf34d5..11154b6773ec 100644 --- a/trunk/arch/um/Makefile-x86_64 +++ b/trunk/arch/um/Makefile-x86_64 @@ -4,10 +4,13 @@ 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)__ -fno-builtin -m64 -USER_CFLAGS += -fno-builtin -m64 +CFLAGS += -U__$(SUBARCH)__ $(_extra_flags_) +USER_CFLAGS += $(_extra_flags_) + 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 e82764f75e7f..3576b3cc505e 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 struct chan_ops not_configged_ops = { +static const 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, - struct chan_opts *opts) + const 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; - struct chan_ops *ops; + const struct chan_ops *ops; }; -static struct chan_type chan_table[] = { +static const struct chan_type chan_table[] = { { "fd", &fd_ops }, #ifdef CONFIG_NULL_CHAN @@ -534,10 +534,10 @@ static struct chan_type chan_table[] = { }; static struct chan *parse_chan(struct line *line, char *str, int device, - struct chan_opts *opts) + const struct chan_opts *opts) { - struct chan_type *entry; - struct chan_ops *ops; + const struct chan_type *entry; + const 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, - struct chan_opts *opts) + const 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 7326c42f7ef9..3bc3cf6b94aa 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 struct net_user_info daemon_user_info; +extern const 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 53d09ed78b42..824386974f88 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 struct net_kern_info daemon_kern_info = { +static const 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 c944265955e2..77954ea77043 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); } -struct net_user_info daemon_user_info = { +const 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 c41f75e4acb5..108b7dafbd0e 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, struct chan_opts *opts) +static void *fd_init(char *str, int device, const struct chan_opts *opts) { struct fd_chan *data; char *end; @@ -77,7 +77,7 @@ static void fd_close(int fd, void *d) } } -struct chan_ops fd_ops = { +const 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 37232f908cd7..d247ef45c374 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 struct file_operations hostaudio_fops = { +static const struct file_operations hostaudio_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = hostaudio_read, @@ -292,7 +292,7 @@ static struct file_operations hostaudio_fops = { .release = hostaudio_release, }; -static struct file_operations hostmixer_fops = { +static const 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 ebebaabb78ad..563ce7690a1e 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 struct { +static const 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) { - struct line_driver *driver = line->driver; + const 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, - struct chan_opts *opts) + const struct chan_opts *opts) { struct line *line; char *new; diff --git a/trunk/arch/um/drivers/mcast.h b/trunk/arch/um/drivers/mcast.h index a2c6db243458..bc56af9d3e53 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 struct net_user_info mcast_user_info; +extern const 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 3a7af18cf944..c090fbd464e7 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 struct net_kern_info mcast_kern_info = { +static const 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 afe85bfa66e0..4d2bd39a85bc 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); } -struct net_user_info mcast_user_info = { +const 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 79610b5ce67e..773a134e7fdb 100644 --- a/trunk/arch/um/drivers/mconsole_kern.c +++ b/trunk/arch/um/drivers/mconsole_kern.c @@ -598,6 +598,11 @@ 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]; @@ -622,10 +627,10 @@ static void console_write(struct console *console, const char *string, return; list_for_each(ele, &clients){ - struct mconsole_entry *entry; + struct mconsole_output *entry; - entry = list_entry(ele, struct mconsole_entry, list); - mconsole_reply_len(&entry->request, console_buf, + entry = list_entry(ele, struct mconsole_output, list); + mconsole_reply_len(entry->req, console_buf, console_index, 0, 1); } @@ -649,10 +654,10 @@ late_initcall(mc_add_console); static void with_console(struct mc_request *req, void (*proc)(void *), void *arg) { - struct mconsole_entry entry; + struct mconsole_output entry; unsigned long flags; - entry.request = *req; + entry.req = 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 5b2f5fe9e426..17068eb746c0 100644 --- a/trunk/arch/um/drivers/mconsole_user.c +++ b/trunk/arch/um/drivers/mconsole_user.c @@ -131,6 +131,10 @@ 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 022f67bb6873..9a3b5daf6250 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 struct file_operations mmapper_fops = { +static const struct file_operations mmapper_fops = { .owner = THIS_MODULE, .read = mmapper_read, .write = mmapper_write, @@ -95,7 +95,7 @@ static struct file_operations mmapper_fops = { .release = mmapper_release, }; -static struct miscdevice mmapper_dev = { +static const 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 4a7966b21931..300a54a6523e 100644 --- a/trunk/arch/um/drivers/net_kern.c +++ b/trunk/arch/um/drivers/net_kern.c @@ -114,18 +114,11 @@ 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; @@ -149,8 +142,6 @@ 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); @@ -160,7 +151,6 @@ 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; } @@ -169,15 +159,12 @@ 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); @@ -246,9 +233,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(&lp->lock); + spin_lock_irq(&lp->lock); set_ether_mac(dev, hwaddr->sa_data); - spin_unlock(&lp->lock); + spin_unlock_irq(&lp->lock); return(0); } @@ -258,7 +245,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(&lp->lock); + spin_lock_irq(&lp->lock); new_mtu = (*lp->set_mtu)(new_mtu, &lp->user); if(new_mtu < 0){ @@ -269,7 +256,7 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu) dev->mtu = new_mtu; out: - spin_unlock(&lp->lock); + spin_unlock_irq(&lp->lock); return err; } @@ -295,6 +282,37 @@ 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); @@ -330,15 +348,13 @@ static int eth_configure(int n, void *init, char *mac, list_add(&device->list, &devices); spin_unlock(&devices_lock); - if (setup_etheraddr(mac, device->mac)) - device->have_mac = 1; + setup_etheraddr(mac, device->mac); printk(KERN_INFO "Netdevice %d ", n); - 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("(%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) { @@ -404,7 +420,6 @@ 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, @@ -419,14 +434,12 @@ 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; - if (lp->have_mac) - memcpy(lp->mac, device->mac, sizeof(lp->mac)); + memcpy(lp->mac, device->mac, sizeof(lp->mac)); if (transport->user->init) (*transport->user->init)(&lp->user, dev); - if (device->have_mac) - set_ether_mac(dev, device->mac); + set_ether_mac(dev, device->mac); return 0; } @@ -569,12 +582,13 @@ 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); @@ -582,7 +596,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); @@ -754,47 +768,6 @@ 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)){ @@ -832,7 +805,7 @@ int dev_netmask(void *d, void *m) struct net_device *dev = d; struct in_device *ip = dev->ip_ptr; struct in_ifaddr *in; - __u32 *mask_out = m; + __be32 *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 107c5e43fa00..f3a3f8a29c7a 100644 --- a/trunk/arch/um/drivers/net_user.c +++ b/trunk/arch/um/drivers/net_user.c @@ -12,6 +12,7 @@ #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 14cc5f78398a..9016c68beee8 100644 --- a/trunk/arch/um/drivers/null.c +++ b/trunk/arch/um/drivers/null.c @@ -8,9 +8,10 @@ #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, struct chan_opts *opts) +static void *null_init(char *str, int device, const struct chan_opts *opts) { return(&null_chan); } @@ -31,7 +32,7 @@ static void null_free(void *data) { } -struct chan_ops null_ops = { +const 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 4c767c7adb96..6e1ef8558283 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 struct net_kern_info pcap_kern_info = { +static const 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 edfcb29273e1..2ef641ded960 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); } -struct net_user_info pcap_user_info = { +const 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 c43e8bb32502..f2e8fc42ecc2 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, struct chan_opts *opts) +static void *port_init(char *str, int device, const 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); } -struct chan_ops port_ops = { +const 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 1c555c38de4d..abec620e8380 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, struct chan_opts *opts) +static void *pty_chan_init(char *str, int device, const 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); } -struct chan_ops pty_ops = { +const struct chan_ops pty_ops = { .type = "pty", .init = pty_chan_init, .open = pty_open, @@ -131,7 +131,7 @@ struct chan_ops pty_ops = { .winch = 0, }; -struct chan_ops pts_ops = { +const 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 ba471f5864a6..73b2bdd6d2d3 100644 --- a/trunk/arch/um/drivers/random.c +++ b/trunk/arch/um/drivers/random.c @@ -20,6 +20,10 @@ #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) @@ -68,7 +72,7 @@ static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size, return ret; } -static struct file_operations rng_chrdev_ops = { +static const 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 bb0dab41c2e4..c64f8c61d274 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 struct net_user_info slip_user_info; +extern const 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 163ee0d5f75e..ccea2d7885e5 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)); } -struct net_kern_info slip_kern_info = { +const 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 89fbec185cc1..8460285c69a5 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); } -struct net_user_info slip_user_info = { +const 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 6cf88ab580c9..89ccf83b7577 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 struct net_user_info slirp_user_info; +extern const 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 95e50c943e14..ae322e1c8a87 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)); } -struct net_kern_info slirp_kern_info = { +const 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 33c5f6e625e8..ce5e85d1de3d 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); } -struct net_user_info slirp_user_info = { +const 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 6dafd6fbfdae..6f13e7c71a82 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 int ssl_version = 1; +static const 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 struct tty_operations ssl_ops = { +static const 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 6d2cf32a9e8f..911539293871 100644 --- a/trunk/arch/um/drivers/stderr_console.c +++ b/trunk/arch/um/drivers/stderr_console.c @@ -9,6 +9,8 @@ /* * 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 856f568c2687..e4bfcfe8550b 100644 --- a/trunk/arch/um/drivers/stdio_console.c +++ b/trunk/arch/um/drivers/stdio_console.c @@ -108,9 +108,10 @@ 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 struct tty_operations console_ops = { +static const 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 9f70edf5d8ef..11de3ac1eb5c 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, struct chan_opts *opts) +static void *tty_chan_init(char *str, int device, const 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; } -struct chan_ops tty_ops = { +const 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 34085315aa57..fda4a3940698 100644 --- a/trunk/arch/um/drivers/ubd_kern.c +++ b/trunk/arch/um/drivers/ubd_kern.c @@ -668,18 +668,15 @@ 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_close; + goto out; dev->size = ROUND_BLOCK(dev->size); err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]); if(err) - goto out_close; + goto out; if(fake_major != MAJOR_NR) ubd_new_disk(fake_major, dev->size, n, @@ -691,8 +688,6 @@ static int ubd_add(int n) make_ide_entries(ubd_gendisk[n]->disk_name); err = 0; -out_close: - ubd_close(dev); out: return err; } @@ -986,8 +981,6 @@ 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 aaa636661043..386f8b952982 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, struct chan_opts *opts) +void *xterm_init(char *str, int device, const struct chan_opts *opts) { struct xterm_chan *data; @@ -194,7 +194,7 @@ static void xterm_free(void *d) free(d); } -struct chan_ops xterm_ops = { +const 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 1bb5e9d94270..572d286ed2c6 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; - struct chan_ops *ops; + const 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, - struct chan_opts *opts); + const 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, - struct chan_opts *opts); + const 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 659bb3cac32f..a795547a1dbd 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, struct chan_opts *); + void *(*init)(char *, int, const 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 struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops, - xterm_ops; +extern const 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 89e1dc835a5b..59cfa9e0cad0 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 struct kern_handlers handlinfo_kern; +extern const 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 27bf2f6fbc05..642c9a0320f9 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; - struct line_driver *driver; + const struct line_driver *driver; int have_irq; }; @@ -99,7 +99,7 @@ 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, struct chan_opts *opts); + char *str, const 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 f7de6df60dd7..280459fb0b26 100644 --- a/trunk/arch/um/include/net_kern.h +++ b/trunk/arch/um/include/net_kern.h @@ -18,7 +18,6 @@ struct uml_net { struct platform_device pdev; int index; unsigned char mac[ETH_ALEN]; - int have_mac; }; struct uml_net_private { @@ -29,7 +28,6 @@ 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 *); @@ -54,15 +52,14 @@ struct transport { struct list_head list; char *name; int (*setup)(char *, char **, void *); - struct net_user_info *user; - struct net_kern_info *kern; + const struct net_user_info *user; + const 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); @@ -70,14 +67,3 @@ 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 47ef7cb49a8e..19f207cd70fe 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,9 +25,8 @@ struct net_user_info { }; extern void ether_user_init(void *data, void *dev); -extern void dev_ip_addr(void *d, unsigned char *bin_buf); -extern void iter_addresses(void *d, void (*cb)(unsigned char *, - unsigned char *, void *), +extern void iter_addresses(void *d, void (*cb)(unsigned char *, + unsigned char *, void *), void *arg); extern void *get_output_buffer(int *len_out); @@ -52,14 +51,3 @@ 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 24fb6d8680e1..120ca21a513a 100644 --- a/trunk/arch/um/include/os.h +++ b/trunk/arch/um/include/os.h @@ -14,6 +14,7 @@ #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 @@ -198,7 +199,9 @@ 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); @@ -216,7 +219,6 @@ 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); @@ -307,12 +309,9 @@ 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, 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 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 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 853b26f148c5..e88926b16072 100644 --- a/trunk/arch/um/include/skas/skas.h +++ b/trunk/arch/um/include/skas/skas.h @@ -14,8 +14,7 @@ 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_proc(void *stack, void (*handler)(int sig)); -extern void new_thread_handler(int sig); +extern void new_thread_handler(void); 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 ea1ba3d42aee..11bafab669e9 100644 --- a/trunk/arch/um/include/sysdep-i386/archsetjmp.h +++ b/trunk/arch/um/include/sysdep-i386/archsetjmp.h @@ -16,4 +16,7 @@ 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 454fc60aff6d..9a5e1a6ec800 100644 --- a/trunk/arch/um/include/sysdep-x86_64/archsetjmp.h +++ b/trunk/arch/um/include/sysdep-x86_64/archsetjmp.h @@ -18,4 +18,7 @@ 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 8d353f0feec1..617bb9efc934 100644 --- a/trunk/arch/um/include/sysdep-x86_64/ptrace.h +++ b/trunk/arch/um/include/sysdep-x86_64/ptrace.h @@ -50,6 +50,21 @@ #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]) @@ -89,9 +104,12 @@ union uml_pt_regs { #endif #ifdef UML_CONFIG_MODE_SKAS struct skas_regs { - /* XXX */ - unsigned long regs[27]; - unsigned long fp[65]; + /* 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]; struct faultinfo faultinfo; long syscall; int is_user; @@ -120,11 +138,16 @@ 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)) @@ -183,6 +206,13 @@ 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); \ @@ -214,6 +244,13 @@ 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 a160d9fcc596..8aee45b07434 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 a2d93065b2d0..6fa63a2a89e3 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_kern.o ptrace.o reboot.o resource.o sigio.o \ + physmem.o process.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 d21ebad666b4..8b7f2cdedf94 100644 --- a/trunk/arch/um/kernel/exitcode.c +++ b/trunk/arch/um/kernel/exitcode.c @@ -16,9 +16,13 @@ int uml_exitcode = 0; static int read_proc_exitcode(char *page, char **start, off_t off, int count, int *eof, void *data) { - int len; + int len, val; - len = sprintf(page, "%d\n", uml_exitcode); + /* 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 -= 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 2c86e7fdb014..13aa115cd1b4 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 *); +extern void __bb_init_func(void *) __attribute__((weak)); EXPORT_SYMBOL(__bb_init_func); /* This is defined (and referred to in profiling stub code) only by some GCC @@ -21,14 +21,3 @@ 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 c97045d6d89f..f030e44262ba 100644 --- a/trunk/arch/um/kernel/ksyms.c +++ b/trunk/arch/um/kernel/ksyms.c @@ -21,7 +21,6 @@ #include "mem_user.h" #include "os.h" -EXPORT_SYMBOL(stop); EXPORT_SYMBOL(uml_physmem); EXPORT_SYMBOL(set_signals); EXPORT_SYMBOL(get_signals); @@ -41,12 +40,14 @@ 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 93121c6d26e5..c95855ba6ab5 100644 --- a/trunk/arch/um/kernel/mem.c +++ b/trunk/arch/um/kernel/mem.c @@ -226,7 +226,8 @@ void paging_init(void) for(i = 0; i < ARRAY_SIZE(zones_size); i++) zones_size[i] = 0; - zones_size[ZONE_DMA] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT); + zones_size[ZONE_NORMAL] = (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_kern.c b/trunk/arch/um/kernel/process.c similarity index 96% rename from trunk/arch/um/kernel/process_kern.c rename to trunk/arch/um/kernel/process.c index 537895d68ad1..fe6c64abda5b 100644 --- a/trunk/arch/um/kernel/process_kern.c +++ b/trunk/arch/um/kernel/process.c @@ -1,10 +1,9 @@ -/* +/* * 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" @@ -113,11 +112,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 ; @@ -128,7 +127,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); } @@ -142,19 +141,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; @@ -183,11 +182,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 *)); @@ -211,7 +210,7 @@ void default_idle(void) */ if(need_resched()) schedule(); - + idle_sleep(10); } } @@ -226,7 +225,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; @@ -235,7 +234,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)) @@ -246,7 +245,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); @@ -271,7 +270,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 ea3a8e409a6e..3e3fa7e7e3cf 100644 --- a/trunk/arch/um/kernel/skas/Makefile +++ b/trunk/arch/um/kernel/skas/Makefile @@ -3,8 +3,7 @@ # Licensed under the GPL # -obj-y := clone.o exec_kern.o mem.o mmu.o process_kern.o \ - syscall.o tlb.o uaccess.o +obj-y := clone.o exec.o mem.o mmu.o process.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 new file mode 100644 index 000000000000..54b795951372 --- /dev/null +++ b/trunk/arch/um/kernel/skas/exec.c @@ -0,0 +1,30 @@ +/* + * 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 deleted file mode 100644 index 77ed7bbab219..000000000000 --- a/trunk/arch/um/kernel/skas/exec_kern.c +++ /dev/null @@ -1,41 +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; -} - -/* - * 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 79c22707a637..4cd2ff546ef6 100644 --- a/trunk/arch/um/kernel/skas/mmu.c +++ b/trunk/arch/um/kernel/skas/mmu.c @@ -61,8 +61,10 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, #endif *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); - *pte = pte_mkexec(*pte); - *pte = pte_wrprotect(*pte); + /* 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); return(0); out_pmd: diff --git a/trunk/arch/um/kernel/skas/process_kern.c b/trunk/arch/um/kernel/skas/process.c similarity index 85% rename from trunk/arch/um/kernel/skas/process_kern.c rename to trunk/arch/um/kernel/skas/process.c index 55caeec8b257..ae4fa71d3b8b 100644 --- a/trunk/arch/um/kernel/skas/process_kern.c +++ b/trunk/arch/um/kernel/skas/process.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); -void new_thread_handler(int sig) +/* This is called magically, by its address being stuffed in a jmp_buf + * and being longjmp-d to. + */ +void new_thread_handler(void) { 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,22 +70,13 @@ void new_thread_handler(int sig) 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) { } -void fork_handler(int sig) +/* Called magically, see new_thread_handler above */ +void fork_handler(void) { - 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"); @@ -109,7 +100,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)(int); + void (*handler)(void); if(current->thread.forking){ memcpy(&p->thread.regs.regs.skas, ®s->regs.skas, @@ -123,12 +114,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, - &p->thread.mode.skas.fork_buf, handler); + handler); return(0); } @@ -164,7 +155,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); @@ -182,8 +173,7 @@ 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.fork_buf)); + &init_task.thread.mode.skas.switch_buf)); } int external_pid_skas(struct task_struct *task) diff --git a/trunk/arch/um/kernel/time.c b/trunk/arch/um/kernel/time.c index 2454bbd9555d..a92965f8f9cd 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(regs); + do_timer(1); - nsecs = get_time() + local_offset; + nsecs = get_time(); 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 e5eeaf2b6af1..c7b195c7e51f 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 (current->pid == 1) { + if (is_init(current)) { up_read(&mm->mmap_sem); yield(); down_read(&mm->mmap_sem); @@ -140,14 +140,6 @@ 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 @@ -253,6 +245,15 @@ 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 7896cf98232d..55005710dcbb 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) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { .start = c_start, .next = c_next, .stop = c_stop, diff --git a/trunk/arch/um/os-Linux/Makefile b/trunk/arch/um/os-Linux/Makefile index f4bfc4c7ccac..b4183929b32c 100644 --- a/trunk/arch/um/os-Linux/Makefile +++ b/trunk/arch/um/os-Linux/Makefile @@ -4,15 +4,19 @@ # 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 tt.o tty.o uaccess.o umid.o tls.o \ + signal.o start_up.o time.o trap.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 tt.o tty.o tls.o \ + process.o sigio.o signal.o start_up.o time.o trap.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 b84f6c4740f7..57ecdaf2f67e 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 struct net_user_info ethertap_user_info; +extern const 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 768606bec233..16385e2ada85 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)); } -struct net_kern_info ethertap_kern_info = { +const 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 8f49507e64ef..f559bdf746e6 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); } -struct net_user_info ethertap_user_info = { +const 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 25d4a2868814..d3e8d3af6245 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 struct net_user_info tuntap_user_info; +extern const 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 190009a6f89c..0edbac63c527 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)); } -struct net_kern_info tuntap_kern_info = { +const 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 87c3aa0252db..e846b23f7558 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); } -struct net_user_info tuntap_user_info = { +const 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 b170b4704dc4..4203681e508d 100644 --- a/trunk/arch/um/os-Linux/mem.c +++ b/trunk/arch/um/os-Linux/mem.c @@ -132,6 +132,9 @@ static void which_tmpdir(void) else if(found < 0) printf("read returned errno %d\n", -found); +out: + close(fd); + return; found: @@ -141,11 +144,12 @@ static void which_tmpdir(void) if(strncmp(buf, "tmpfs", strlen("tmpfs"))){ printf("not tmpfs\n"); - return; + goto out; } printf("OK\n"); default_tmpdir = "/dev/shm"; + goto out; } /* diff --git a/trunk/arch/um/os-Linux/skas/process.c b/trunk/arch/um/os-Linux/skas/process.c index 42e3d1ed802c..cb9ab54146cc 100644 --- a/trunk/arch/um/os-Linux/skas/process.c +++ b/trunk/arch/um/os-Linux/skas/process.c @@ -444,56 +444,22 @@ void map_stub_pages(int fd, unsigned long code, } } -void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, - void (*handler)(int)) +void new_thread(void *stack, jmp_buf *buf, void (*handler)(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); + (*buf)[0].JB_IP = (unsigned long) handler; + (*buf)[0].JB_SP = (unsigned long) stack + + (PAGE_SIZE << UML_CONFIG_KERNEL_STACK_ORDER) - sizeof(void *); } #define INIT_JMP_NEW_THREAD 0 -#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); -} +#define INIT_JMP_CALLBACK 1 +#define INIT_JMP_HALT 2 +#define INIT_JMP_REBOOT 3 -void switch_threads(void *me, void *next) +void switch_threads(jmp_buf *me, jmp_buf *you) { - 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); + if(UML_SETJMP(me) == 0) + UML_LONGJMP(you, 1); } static jmp_buf initial_jmpbuf; @@ -503,23 +469,21 @@ static void (*cb_proc)(void *arg); static void *cb_arg; static jmp_buf *cb_back; -int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) +int start_idle_thread(void *stack, jmp_buf *switch_buf) { - 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: - new_thread_proc((void *) stack, new_thread_handler); - break; - case INIT_JMP_REMOVE_SIGSTACK: - remove_sigstack(); + (*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 *); break; case INIT_JMP_CALLBACK: (*cb_proc)(cb_arg); @@ -534,7 +498,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) 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/v850/kernel/memcons.c b/trunk/arch/v850/kernel/memcons.c index 491614c435cd..815f8a43926f 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) { - int flags; + unsigned long flags; char *point; spin_lock_irqsave (memcons_lock, flags); diff --git a/trunk/arch/v850/kernel/rte_cb_leds.c b/trunk/arch/v850/kernel/rte_cb_leds.c index f654088b2760..996bd4f33ecb 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) { \ - int _flags; \ + unsigned long _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 f36b778f1432..35213fa9f7d8 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; - int flags; + unsigned long 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; - int flags; + unsigned long 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) { - int flags; + unsigned long 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) { - int flags; + unsigned long 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) { - int flags; + unsigned long 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) { - int flags; + unsigned long flags; free_mb_sram (mapping->mb_sram_addr, mapping->size); diff --git a/trunk/arch/v850/kernel/time.c b/trunk/arch/v850/kernel/time.c index a0b46695f186..f4d1a4d3cdc2 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 (regs); + do_timer (1); #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 efe249e7d6b3..b87a19f0d584 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -85,6 +85,9 @@ config ARCH_MAY_HAVE_PC_FDC bool default y +config ARCH_POPULATES_NODE_MAP + def_bool y + config DMI bool default y @@ -168,6 +171,7 @@ 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 @@ -183,6 +187,11 @@ 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 @@ -358,6 +367,10 @@ 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 diff --git a/trunk/arch/x86_64/defconfig b/trunk/arch/x86_64/defconfig index 647610ecb580..4844b543bed0 100644 --- a/trunk/arch/x86_64/defconfig +++ b/trunk/arch/x86_64/defconfig @@ -1,11 +1,12 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-git5 -# Tue Sep 26 09:30:47 2006 +# Linux kernel version: 2.6.18-git7 +# Wed Sep 27 21:53:10 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 @@ -179,6 +180,7 @@ 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 @@ -251,6 +253,7 @@ 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 # @@ -1458,6 +1461,7 @@ 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 diff --git a/trunk/arch/x86_64/ia32/sys_ia32.c b/trunk/arch/x86_64/ia32/sys_ia32.c index b0e82c7947dc..f280d3665f4b 100644 --- a/trunk/arch/x86_64/ia32/sys_ia32.c +++ b/trunk/arch/x86_64/ia32/sys_ia32.c @@ -648,7 +648,7 @@ sys32_pause(void) } -#ifdef CONFIG_SYSCTL +#ifdef CONFIG_SYSCTL_SYSCALL struct sysctl_ia32 { unsigned int name; int nlen; diff --git a/trunk/arch/x86_64/kernel/e820.c b/trunk/arch/x86_64/kernel/e820.c index c0af3828df45..b3f0908668ec 100644 --- a/trunk/arch/x86_64/kernel/e820.c +++ b/trunk/arch/x86_64/kernel/e820.c @@ -162,59 +162,14 @@ 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) @@ -224,43 +179,10 @@ 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. */ @@ -342,6 +264,49 @@ 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. */ diff --git a/trunk/arch/x86_64/kernel/mpparse.c b/trunk/arch/x86_64/kernel/mpparse.c index 20e88f4b564b..b8d53dfa9931 100644 --- a/trunk/arch/x86_64/kernel/mpparse.c +++ b/trunk/arch/x86_64/kernel/mpparse.c @@ -152,6 +152,21 @@ static void __init MP_bus_info (struct mpc_config_bus *m) } } +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)) @@ -159,16 +174,10 @@ static void __init MP_ioapic_info (struct mpc_config_ioapic *m) printk("I/O APIC #%d at 0x%X.\n", m->mpc_apicid, 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"); + + if (bad_ioapic(m->mpc_apicaddr)) return; - } + mp_ioapics[nr_ioapics] = *m; nr_ioapics++; } @@ -647,16 +656,8 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base) { int idx = 0; - 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"); + if (bad_ioapic(address)) return; - } idx = nr_ioapics++; diff --git a/trunk/arch/x86_64/kernel/nmi.c b/trunk/arch/x86_64/kernel/nmi.c index 4d6fb047952e..7af9cb3e2d99 100644 --- a/trunk/arch/x86_64/kernel/nmi.c +++ b/trunk/arch/x86_64/kernel/nmi.c @@ -28,6 +28,10 @@ #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 diff --git a/trunk/arch/x86_64/kernel/pci-dma.c b/trunk/arch/x86_64/kernel/pci-dma.c index 4dcb671bd19f..f8d857453f8a 100644 --- a/trunk/arch/x86_64/kernel/pci-dma.c +++ b/trunk/arch/x86_64/kernel/pci-dma.c @@ -170,8 +170,20 @@ 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); @@ -231,57 +243,64 @@ 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; + 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; + 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; #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 0; } early_param("iommu", iommu_setup); diff --git a/trunk/arch/x86_64/kernel/pci-swiotlb.c b/trunk/arch/x86_64/kernel/pci-swiotlb.c index 6a55f87ba97f..697f0aa794b9 100644 --- a/trunk/arch/x86_64/kernel/pci-swiotlb.c +++ b/trunk/arch/x86_64/kernel/pci-swiotlb.c @@ -3,7 +3,8 @@ #include #include #include -#include +#include + #include #include #include diff --git a/trunk/arch/x86_64/kernel/setup.c b/trunk/arch/x86_64/kernel/setup.c index f98e48cae6da..fc944b5e8f4a 100644 --- a/trunk/arch/x86_64/kernel/setup.c +++ b/trunk/arch/x86_64/kernel/setup.c @@ -123,9 +123,6 @@ 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 = { @@ -172,9 +169,6 @@ 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, @@ -245,7 +239,8 @@ static void __init probe_roms(void) } /* check for adapter roms on 2k boundaries */ - for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) { + for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; + start += 2048) { rom = isa_bus_to_virt(start); if (!romsignature(rom)) continue; @@ -292,7 +287,8 @@ 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_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT); + e820_register_active_regions(0, start_pfn, end_pfn); + free_bootmem_with_active_regions(0, end_pfn); reserve_bootmem(bootmap, bootmap_size); } #endif @@ -384,6 +380,7 @@ void __init setup_arch(char **cmdline_p) finish_e820_parsing(); + e820_register_active_regions(0, 0, -1UL); /* * partially used pages are not usable - thus * we are rounding upwards: @@ -414,6 +411,9 @@ void __init setup_arch(char **cmdline_p) 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. @@ -532,7 +532,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 < STANDARD_IO_RESOURCES; i++) + for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) request_resource(&ioport_resource, &standard_io_resources[i]); } diff --git a/trunk/arch/x86_64/kernel/time.c b/trunk/arch/x86_64/kernel/time.c index 1c255ee76e7c..557e92af7bea 100644 --- a/trunk/arch/x86_64/kernel/time.c +++ b/trunk/arch/x86_64/kernel/time.c @@ -77,7 +77,6 @@ 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; @@ -119,7 +118,7 @@ unsigned int (*do_gettimeoffset)(void) = do_gettimeoffset_tsc; void do_gettimeofday(struct timeval *tv) { - unsigned long seq, t; + unsigned long seq; unsigned int sec, usec; do { @@ -136,10 +135,7 @@ 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 */ - - t = (jiffies - wall_jiffies) * USEC_PER_TICK + - do_gettimeoffset(); - usec += t; + usec += do_gettimeoffset(); } while (read_seqretry(&xtime_lock, seq)); @@ -165,8 +161,7 @@ int do_settimeofday(struct timespec *tv) write_seqlock_irq(&xtime_lock); - nsec -= do_gettimeoffset() * NSEC_PER_USEC + - (jiffies - wall_jiffies) * NSEC_PER_TICK; + nsec -= do_gettimeoffset() * NSEC_PER_USEC; wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); @@ -415,16 +410,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); - jiffies += lost; - } + else + lost = 0; /* * Do the timer stuff. */ - do_timer(regs); + do_timer(lost + 1); #ifndef CONFIG_SMP update_process_times(user_mode(regs)); #endif @@ -1071,7 +1066,6 @@ 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/vmlinux.lds.S b/trunk/arch/x86_64/kernel/vmlinux.lds.S index d0564f1bcb0b..b9df2ab6529f 100644 --- a/trunk/arch/x86_64/kernel/vmlinux.lds.S +++ b/trunk/arch/x86_64/kernel/vmlinux.lds.S @@ -67,13 +67,6 @@ SECTIONS _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) { @@ -108,9 +101,6 @@ SECTIONS .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); @@ -229,6 +219,13 @@ 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/vsyscall.c b/trunk/arch/x86_64/kernel/vsyscall.c index ac48c3857ddb..a98b460af6a1 100644 --- a/trunk/arch/x86_64/kernel/vsyscall.c +++ b/trunk/arch/x86_64/kernel/vsyscall.c @@ -66,8 +66,7 @@ static __always_inline void do_vgettimeofday(struct timeval * tv) sequence = read_seqbegin(&__xtime_lock); sec = __xtime.tv_sec; - usec = (__xtime.tv_nsec / 1000) + - (__jiffies - __wall_jiffies) * (1000000 / HZ); + usec = __xtime.tv_nsec / 1000; if (__vxtime.mode != VXTIME_HPET) { t = get_cycles_sync(); @@ -155,8 +154,8 @@ vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) 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->t0 == (j = __jiffies)) { - p = tcache->t1; + 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); @@ -165,8 +164,8 @@ vgetcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); } if (tcache) { - tcache->t0 = j; - tcache->t1 = p; + tcache->blob[0] = j; + tcache->blob[1] = p; } if (cpu) *cpu = p & 0xfff; diff --git a/trunk/arch/x86_64/mm/fault.c b/trunk/arch/x86_64/mm/fault.c index 1a17b0733ab5..3751b4788e28 100644 --- a/trunk/arch/x86_64/mm/fault.c +++ b/trunk/arch/x86_64/mm/fault.c @@ -244,7 +244,7 @@ static int is_errata93(struct pt_regs *regs, unsigned long address) int unhandled_signal(struct task_struct *tsk, int sig) { - if (tsk->pid == 1) + if (is_init(tsk)) return 1; if (tsk->ptrace & PT_PTRACED) return 0; @@ -464,7 +464,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))) + if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) goto bad_area; } @@ -580,7 +580,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, */ out_of_memory: up_read(&mm->mmap_sem); - if (current->pid == 1) { + if (is_init(current)) { yield(); goto again; } diff --git a/trunk/arch/x86_64/mm/init.c b/trunk/arch/x86_64/mm/init.c index 1e4669fa5734..19c72520a868 100644 --- a/trunk/arch/x86_64/mm/init.c +++ b/trunk/arch/x86_64/mm/init.c @@ -403,69 +403,15 @@ 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 zones[MAX_NR_ZONES], holes[MAX_NR_ZONES]; - + unsigned long max_zone_pfns[MAX_NR_ZONES] = {MAX_DMA_PFN, + MAX_DMA32_PFN, + end_pfn}; memory_present(0, 0, end_pfn); sparse_init(); - size_zones(zones, holes, 0, end_pfn); - free_area_init_node(0, NODE_DATA(0), zones, - __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes); + free_area_init_nodes(max_zone_pfns); } #endif @@ -516,19 +462,6 @@ 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. @@ -541,12 +474,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__); @@ -560,7 +493,24 @@ int remove_memory(u64 start, u64 size) } EXPORT_SYMBOL_GPL(remove_memory); -#else /* CONFIG_MEMORY_HOTPLUG */ +#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 /* * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, * just online the pages. @@ -586,7 +536,7 @@ int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) } return err; } -#endif /* CONFIG_MEMORY_HOTPLUG */ +#endif static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, kcore_vsyscall; @@ -608,7 +558,8 @@ void __init mem_init(void) #else totalram_pages = free_all_bootmem(); #endif - reservedpages = end_pfn - totalram_pages - e820_hole_size(0, end_pfn); + reservedpages = end_pfn - totalram_pages - + absent_pages_in_range(0, end_pfn); after_bootmem = 1; @@ -708,8 +659,10 @@ 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 45d7d823c3b8..c6e5e8d401a4 100644 --- a/trunk/arch/x86_64/mm/ioremap.c +++ b/trunk/arch/x86_64/mm/ioremap.c @@ -12,117 +12,16 @@ #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. @@ -165,6 +64,7 @@ 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; @@ -194,6 +94,8 @@ 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 */ @@ -209,7 +111,8 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l return NULL; area->phys_addr = phys_addr; addr = area->addr; - if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) { + if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size, + phys_addr, pgprot)) { 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 5cf594f9230d..b5b8dba28b4e 100644 --- a/trunk/arch/x86_64/mm/k8topology.c +++ b/trunk/arch/x86_64/mm/k8topology.c @@ -149,6 +149,9 @@ 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 322bf45fc36a..829a008bd39b 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); - e820_bootmem_free(NODE_DATA(nodeid), start, end); + free_bootmem_with_active_regions(nodeid, 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); setup_node_bootmem(i, nodes[i].start, nodes[i].end); + } numa_init_array(); return 0; } @@ -299,6 +296,7 @@ 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); } @@ -340,12 +338,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) diff --git a/trunk/arch/x86_64/mm/srat.c b/trunk/arch/x86_64/mm/srat.c index ca10701e7a90..3cc0544e25f5 100644 --- a/trunk/arch/x86_64/mm/srat.c +++ b/trunk/arch/x86_64/mm/srat.c @@ -23,22 +23,13 @@ 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] __initdata; +static struct bootnode nodes_add[MAX_NUMNODES]; 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. */ @@ -93,6 +84,7 @@ 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) @@ -159,7 +151,7 @@ acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) pxm, pa->apic_id, node); } -#ifdef RESERVE_HOTADD +#ifdef CONFIG_MEMORY_HOTPLUG_RESERVE /* * Protect against too large hotadd areas that would fill up memory. */ @@ -175,7 +167,7 @@ static int hotadd_enough_memory(struct bootnode *nd) if (mem < 0) return 0; - allowed = (end_pfn - e820_hole_size(0, end_pfn)) * PAGE_SIZE; + allowed = (end_pfn - absent_pages_in_range(0, end_pfn)) * PAGE_SIZE; allowed = (allowed / 100) * hotadd_percent; if (allocated + mem > allowed) { unsigned long range; @@ -202,15 +194,37 @@ 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 /* - * It is fine to add this area to the nodes data it will be used later + * Update nodes_add and decide if to include add are in the zone. + * Both SPARSE and RESERVE need nodes_add infomation. * 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 changed = 0; + int ret = 0, changed = 0; struct bootnode *nd = &nodes_add[node]; /* I had some trouble with strange memory hotadd regions breaking @@ -225,8 +239,10 @@ 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 (e820_hole_size(s_pfn, e_pfn) != e_pfn - s_pfn) { - printk(KERN_ERR "SRAT: Hotplug area has existing memory\n"); + 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); return -1; } @@ -237,7 +253,6 @@ 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; @@ -255,14 +270,12 @@ static int reserve_hotadd(int node, unsigned long start, unsigned long end) printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n"); } - if ((nd->end >> PAGE_SHIFT) > end_pfn) - end_pfn = nd->end >> PAGE_SHIFT; + ret = update_end_of_memory(nd->end); if (changed) printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n", nd->start, nd->end); - return 0; + return ret; } -#endif /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ void __init @@ -281,7 +294,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) } if (ma->flags.enabled == 0) return; - if (ma->flags.hot_pluggable && hotadd_percent == 0) + if (ma->flags.hot_pluggable && !save_add_info()) return; start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); @@ -319,16 +332,18 @@ 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); -#ifdef RESERVE_HOTADD - if (ma->flags.hot_pluggable && reserve_hotadd(node, start, end) < 0) { + 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). @@ -343,13 +358,12 @@ 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 -= e820_hole_size(s, e); - pxmram -= nodes_add[i].end - nodes_add[i].start; + pxmram -= absent_pages_in_range(s, e); if ((long)pxmram < 0) pxmram = 0; } - e820ram = end_pfn - e820_hole_size(0, end_pfn); + e820ram = end_pfn - absent_pages_in_range(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 @@ -452,3 +466,16 @@ 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/xtensa/kernel/time.c b/trunk/arch/xtensa/kernel/time.c index 412ab32de391..37347e369987 100644 --- a/trunk/arch/xtensa/kernel/time.c +++ b/trunk/arch/xtensa/kernel/time.c @@ -26,8 +26,6 @@ #include -extern volatile unsigned long wall_jiffies; - DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -110,7 +108,6 @@ 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); @@ -129,7 +126,7 @@ EXPORT_SYMBOL(do_settimeofday); void do_gettimeofday(struct timeval *tv) { unsigned long flags; - unsigned long sec, usec, delta, lost, seq; + unsigned long sec, usec, delta, seq; do { seq = read_seqbegin_irqsave(&xtime_lock, flags); @@ -137,12 +134,9 @@ 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 += lost * (1000000UL/HZ) + (delta * CCOUNT_NSEC) / NSEC_PER_USEC; + usec += (delta * CCOUNT_NSEC) / NSEC_PER_USEC; for (; usec >= 1000000; sec++, usec -= 1000000) ; @@ -175,12 +169,11 @@ irqreturn_t timer_interrupt (int irq, void *dev_id, struct pt_regs *regs) last_ccount_stamp = next; next += CCOUNT_PER_JIFFY; - do_timer (regs); /* Linux handler in kernel/timer.c */ + do_timer (1); /* 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 && - jiffies - wall_jiffies == 1) { + abs((xtime.tv_nsec/1000)-(1000000-1000000/HZ))<5000000/HZ) { 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 a945a33e85a1..dd0dbec2e57e 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 (current->pid == 1) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/xtensa/platform-iss/network.c b/trunk/arch/xtensa/platform-iss/network.c index d96164e602fe..15d64414bd60 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; - u32 addr; + __be32 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 b6f5f0a79655..83766a6bdee2 100644 --- a/trunk/block/Kconfig +++ b/trunk/block/Kconfig @@ -1,6 +1,24 @@ # # 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 @@ -33,4 +51,6 @@ config LSF If unsure, say Y. +endif + source block/Kconfig.iosched diff --git a/trunk/block/Kconfig.iosched b/trunk/block/Kconfig.iosched index 48d090e266fc..903f0d3b6852 100644 --- a/trunk/block/Kconfig.iosched +++ b/trunk/block/Kconfig.iosched @@ -1,3 +1,4 @@ +if BLOCK menu "IO Schedulers" @@ -67,3 +68,5 @@ config DEFAULT_IOSCHED default "noop" if DEFAULT_NOOP endmenu + +endif diff --git a/trunk/block/Makefile b/trunk/block/Makefile index c05de0e0037f..4b84d0d5947b 100644 --- a/trunk/block/Makefile +++ b/trunk/block/Makefile @@ -2,7 +2,7 @@ # Makefile for the kernel block layer # -obj-y := elevator.o ll_rw_blk.o ioctl.o genhd.o scsi_ioctl.o +obj-$(CONFIG_BLOCK) := 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 5da56d48fbd3..50b95e4c1425 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,7 +14,6 @@ #include #include #include -#include #include #include @@ -93,9 +92,8 @@ struct as_data { struct rb_root sort_list[2]; struct list_head fifo_list[2]; - struct as_rq *next_arq[2]; /* next in sort order */ + struct request *next_rq[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 */ @@ -115,7 +113,6 @@ 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 */ @@ -133,8 +130,6 @@ struct as_data { unsigned long antic_expire; }; -#define list_entry_fifo(ptr) list_entry((ptr), struct as_rq, fifo) - /* * per-request data. */ @@ -150,40 +145,14 @@ enum arq_state { AS_RQ_POSTSCHED, /* when they shouldn't be */ }; -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; +#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) - 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 DEFINE_PER_CPU(unsigned long, ioc_count); static struct completion *ioc_gone; -static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq); +static void as_move_to_dispatch(struct as_data *ad, struct request *rq); static void as_antic_stop(struct as_data *ad); /* @@ -194,7 +163,8 @@ static void as_antic_stop(struct as_data *ad); static void free_as_io_context(struct as_io_context *aic) { kfree(aic); - if (atomic_dec_and_test(&ioc_count) && ioc_gone) + elv_ioc_count_dec(ioc_count); + if (ioc_gone && !elv_ioc_count_read(ioc_count)) complete(ioc_gone); } @@ -230,7 +200,7 @@ static struct as_io_context *alloc_as_io_context(void) ret->seek_total = 0; ret->seek_samples = 0; ret->seek_mean = 0; - atomic_inc(&ioc_count); + elv_ioc_count_inc(ioc_count); } return ret; @@ -240,9 +210,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(void) +static struct io_context *as_get_io_context(int node) { - struct io_context *ioc = get_io_context(GFP_ATOMIC); + struct io_context *ioc = get_io_context(GFP_ATOMIC, node); if (ioc && !ioc->aic) { ioc->aic = alloc_as_io_context(); if (!ioc->aic) { @@ -253,194 +223,43 @@ static struct io_context *as_get_io_context(void) return ioc; } -static void as_put_io_context(struct as_rq *arq) +static void as_put_io_context(struct request *rq) { struct as_io_context *aic; - if (unlikely(!arq->io_context)) + if (unlikely(!RQ_IOC(rq))) return; - aic = arq->io_context->aic; + aic = RQ_IOC(rq)->aic; - if (arq->is_sync == REQ_SYNC && aic) { + if (rq_is_sync(rq) && aic) { spin_lock(&aic->lock); set_bit(AS_TASK_IORUNNING, &aic->state); aic->last_end_request = jiffies; spin_unlock(&aic->lock); } - 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; + put_io_context(RQ_IOC(rq)); } /* * rb tree support functions */ -#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; -} +#define RQ_RB_ROOT(ad, rq) (&(ad)->sort_list[rq_is_sync((rq))]) -static void as_add_arq_rb(struct as_data *ad, struct as_rq *arq) +static void as_add_rq_rb(struct as_data *ad, struct request *rq) { - struct as_rq *alias; + struct request *alias; - while ((unlikely(alias = __as_add_arq_rb(ad, arq)))) { + while ((unlikely(alias = elv_rb_add(RQ_RB_ROOT(ad, rq), rq)))) { as_move_to_dispatch(ad, alias); as_antic_stop(ad); } } -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) +static inline void as_del_rq_rb(struct as_data *ad, struct request *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; + elv_rb_del(RQ_RB_ROOT(ad, rq), rq); } /* @@ -458,26 +277,26 @@ as_find_arq_rb(struct as_data *ad, sector_t sector, int data_dir) * 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 as_rq * -as_choose_req(struct as_data *ad, struct as_rq *arq1, struct as_rq *arq2) +static struct request * +as_choose_req(struct as_data *ad, struct request *rq1, struct request *rq2) { 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 (arq1 == NULL || arq1 == arq2) - return arq2; - if (arq2 == NULL) - return arq1; + if (rq1 == NULL || rq1 == rq2) + return rq2; + if (rq2 == NULL) + return rq1; - data_dir = arq1->is_sync; + data_dir = rq_is_sync(rq1); last = ad->last_sector[data_dir]; - s1 = arq1->request->sector; - s2 = arq2->request->sector; + s1 = rq1->sector; + s2 = rq2->sector; - BUG_ON(data_dir != arq2->is_sync); + BUG_ON(data_dir != rq_is_sync(rq2)); /* * Strict one way elevator _except_ in the case where we allow @@ -504,61 +323,58 @@ as_choose_req(struct as_data *ad, struct as_rq *arq1, struct as_rq *arq2) /* Found required data */ if (!r1_wrap && r2_wrap) - return arq1; + return rq1; else if (!r2_wrap && r1_wrap) - return arq2; + return rq2; else if (r1_wrap && r2_wrap) { /* both behind the head */ if (s1 <= s2) - return arq1; + return rq1; else - return arq2; + return rq2; } /* Both requests in front of the head */ if (d1 < d2) - return arq1; + return rq1; else if (d2 < d1) - return arq2; + return rq2; else { if (s1 >= s2) - return arq1; + return rq1; else - return arq2; + return rq2; } } /* - * as_find_next_arq finds the next request after @prev in elevator order. + * as_find_next_rq 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 as_rq *as_find_next_arq(struct as_data *ad, struct as_rq *last) +static struct request * +as_find_next_rq(struct as_data *ad, struct request *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 as_rq *arq_next, *arq_prev; + struct request *next = NULL, *prev = NULL; - BUG_ON(!RB_EMPTY_NODE(&last->rb_node)); + BUG_ON(RB_EMPTY_NODE(&last->rb_node)); if (rbprev) - arq_prev = rb_entry_arq(rbprev); - else - arq_prev = NULL; + prev = rb_entry_rq(rbprev); if (rbnext) - arq_next = rb_entry_arq(rbnext); + next = rb_entry_rq(rbnext); else { - arq_next = as_find_first_arq(ad, data_dir); - if (arq_next == last) - arq_next = NULL; - } + const int data_dir = rq_is_sync(last); - ret = as_choose_req(ad, arq_next, arq_prev); + rbnext = rb_first(&ad->sort_list[data_dir]); + if (rbnext && rbnext != &last->rb_node) + next = rb_entry_rq(rbnext); + } - return ret; + return as_choose_req(ad, next, prev); } /* @@ -712,8 +528,7 @@ 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) { - struct as_rq *arq = RQ_DATA(rq); - int data_dir = arq->is_sync; + int data_dir = rq_is_sync(rq); unsigned long thinktime = 0; sector_t seek_dist; @@ -752,11 +567,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 as_rq *arq) + struct request *rq) { unsigned long delay; /* milliseconds */ sector_t last = ad->last_sector[ad->batch_data_dir]; - sector_t next = arq->request->sector; + sector_t next = rq->sector; sector_t delta; /* acceptable close offset (in sectors) */ sector_t s; @@ -813,7 +628,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 as_rq *arq) +static int as_can_break_anticipation(struct as_data *ad, struct request *rq) { struct io_context *ioc; struct as_io_context *aic; @@ -821,7 +636,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq) ioc = ad->io_context; BUG_ON(!ioc); - if (arq && ioc == arq->io_context) { + if (rq && ioc == RQ_IOC(rq)) { /* request from same process */ return 1; } @@ -848,7 +663,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq) return 1; } - if (arq && arq->is_sync == REQ_SYNC && as_close_req(ad, aic, arq)) { + if (rq && rq_is_sync(rq) && as_close_req(ad, aic, rq)) { /* * Found a close request that is not one of ours. * @@ -864,7 +679,7 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq) ad->exit_no_coop = (7*ad->exit_no_coop)/8; } - as_update_iohist(ad, aic, arq->request); + as_update_iohist(ad, aic, rq); return 1; } @@ -891,10 +706,10 @@ static int as_can_break_anticipation(struct as_data *ad, struct as_rq *arq) } /* - * as_can_anticipate indicates whether we should either run arq + * as_can_anticipate indicates whether we should either run rq * or keep anticipating a better request. */ -static int as_can_anticipate(struct as_data *ad, struct as_rq *arq) +static int as_can_anticipate(struct as_data *ad, struct request *rq) { if (!ad->io_context) /* @@ -908,7 +723,7 @@ static int as_can_anticipate(struct as_data *ad, struct as_rq *arq) */ return 0; - if (as_can_break_anticipation(ad, arq)) + if (as_can_break_anticipation(ad, rq)) /* * This request is a good candidate. Don't keep anticipating, * run it. @@ -926,16 +741,16 @@ static int as_can_anticipate(struct as_data *ad, struct as_rq *arq) } /* - * as_update_arq must be called whenever a request (arq) is added to + * as_update_rq must be called whenever a request (rq) 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_arq(struct as_data *ad, struct as_rq *arq) +static void as_update_rq(struct as_data *ad, struct request *rq) { - const int data_dir = arq->is_sync; + const int data_dir = rq_is_sync(rq); - /* keep the next_arq cache up to date */ - ad->next_arq[data_dir] = as_choose_req(ad, arq, ad->next_arq[data_dir]); + /* keep the next_rq cache up to date */ + ad->next_rq[data_dir] = as_choose_req(ad, rq, ad->next_rq[data_dir]); /* * have we been anticipating this request? @@ -944,7 +759,7 @@ static void as_update_arq(struct as_data *ad, struct as_rq *arq) */ if (ad->antic_status == ANTIC_WAIT_REQ || ad->antic_status == ANTIC_WAIT_NEXT) { - if (as_can_break_anticipation(ad, arq)) + if (as_can_break_anticipation(ad, rq)) as_antic_stop(ad); } } @@ -984,12 +799,11 @@ 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 (arq->state != AS_RQ_REMOVED) { - printk("arq->state %d\n", arq->state); + if (RQ_STATE(rq) != AS_RQ_REMOVED) { + printk("rq->state %d\n", RQ_STATE(rq)); WARN_ON(1); goto out; } @@ -1009,14 +823,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 == arq->is_sync) { + if (ad->new_batch && ad->batch_data_dir == rq_is_sync(rq)) { update_write_batch(ad); ad->current_batch_expires = jiffies + ad->batch_expire[REQ_SYNC]; ad->new_batch = 0; } - if (ad->io_context == arq->io_context && ad->io_context) { + if (ad->io_context == RQ_IOC(rq) && ad->io_context) { ad->antic_start = jiffies; ad->ioc_finished = 1; if (ad->antic_status == ANTIC_WAIT_REQ) { @@ -1028,9 +842,9 @@ static void as_completed_request(request_queue_t *q, struct request *rq) } } - as_put_io_context(arq); + as_put_io_context(rq); out: - arq->state = AS_RQ_POSTSCHED; + RQ_SET_STATE(rq, AS_RQ_POSTSCHED); } /* @@ -1041,27 +855,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) { - struct as_rq *arq = RQ_DATA(rq); - const int data_dir = arq->is_sync; + const int data_dir = rq_is_sync(rq); struct as_data *ad = q->elevator->elevator_data; + struct io_context *ioc; - WARN_ON(arq->state != AS_RQ_QUEUED); + WARN_ON(RQ_STATE(rq) != AS_RQ_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); + ioc = RQ_IOC(rq); + if (ioc && ioc->aic) { + BUG_ON(!atomic_read(&ioc->aic->nr_queued)); + atomic_dec(&ioc->aic->nr_queued); } /* - * Update the "next_arq" cache if we are about to remove its + * Update the "next_rq" cache if we are about to remove its * entry */ - if (ad->next_arq[data_dir] == arq) - ad->next_arq[data_dir] = as_find_next_arq(ad, arq); + if (ad->next_rq[data_dir] == rq) + ad->next_rq[data_dir] = as_find_next_rq(ad, rq); - list_del_init(&arq->fifo); - as_del_arq_hash(arq); - as_del_arq_rb(ad, arq); + rq_fifo_clear(rq); + as_del_rq_rb(ad, rq); } /* @@ -1074,7 +888,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 as_rq *arq; + struct request *rq; long delta_jif; delta_jif = jiffies - ad->last_check_fifo[adir]; @@ -1088,9 +902,9 @@ static int as_fifo_expired(struct as_data *ad, int adir) if (list_empty(&ad->fifo_list[adir])) return 0; - arq = list_entry_fifo(ad->fifo_list[adir].next); + rq = rq_entry_fifo(ad->fifo_list[adir].next); - return time_after(jiffies, arq->expires); + return time_after(jiffies, rq_fifo_time(rq)); } /* @@ -1113,25 +927,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 as_rq *arq) +static void as_move_to_dispatch(struct as_data *ad, struct request *rq) { - struct request *rq = arq->request; - const int data_dir = arq->is_sync; + const int data_dir = rq_is_sync(rq); - BUG_ON(!RB_EMPTY_NODE(&arq->rb_node)); + BUG_ON(RB_EMPTY_NODE(&rq->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_arq + * as_find_next_rq */ 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, &arq->io_context); + copy_io_context(&ad->io_context, &ioc); } else { if (ad->io_context) { put_io_context(ad->io_context); @@ -1143,19 +957,19 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq) } ad->ioc_finished = 0; - ad->next_arq[data_dir] = as_find_next_arq(ad, arq); + ad->next_rq[data_dir] = as_find_next_rq(ad, rq); /* * take it off the sort and fifo list, add to dispatch queue */ as_remove_queued_request(ad->q, rq); - WARN_ON(arq->state != AS_RQ_QUEUED); + WARN_ON(RQ_STATE(rq) != AS_RQ_QUEUED); elv_dispatch_sort(ad->q, rq); - arq->state = AS_RQ_DISPATCHED; - if (arq->io_context && arq->io_context->aic) - atomic_inc(&arq->io_context->aic->nr_dispatched); + RQ_SET_STATE(rq, AS_RQ_DISPATCHED); + if (RQ_IOC(rq) && RQ_IOC(rq)->aic) + atomic_inc(&RQ_IOC(rq)->aic->nr_dispatched); ad->nr_dispatched++; } @@ -1167,9 +981,9 @@ static void as_move_to_dispatch(struct as_data *ad, struct as_rq *arq) 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)) { /* @@ -1185,14 +999,14 @@ static int as_dispatch_request(request_queue_t *q, int force) ad->changed_batch = 0; ad->new_batch = 0; - while (ad->next_arq[REQ_SYNC]) { - as_move_to_dispatch(ad, ad->next_arq[REQ_SYNC]); + while (ad->next_rq[REQ_SYNC]) { + as_move_to_dispatch(ad, ad->next_rq[REQ_SYNC]); dispatched++; } ad->last_check_fifo[REQ_SYNC] = jiffies; - while (ad->next_arq[REQ_ASYNC]) { - as_move_to_dispatch(ad, ad->next_arq[REQ_ASYNC]); + while (ad->next_rq[REQ_ASYNC]) { + as_move_to_dispatch(ad, ad->next_rq[REQ_ASYNC]); dispatched++; } ad->last_check_fifo[REQ_ASYNC] = jiffies; @@ -1216,19 +1030,19 @@ static int as_dispatch_request(request_queue_t *q, int force) /* * batch is still running or no reads or no writes */ - arq = ad->next_arq[ad->batch_data_dir]; + rq = ad->next_rq[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, arq)) { + if (as_can_anticipate(ad, rq)) { as_antic_waitreq(ad); return 0; } } - if (arq) { + if (rq) { /* we have a "next request" */ if (reads && !writes) ad->current_batch_expires = @@ -1256,7 +1070,7 @@ static int as_dispatch_request(request_queue_t *q, int force) ad->changed_batch = 1; } ad->batch_data_dir = REQ_SYNC; - arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next); + rq = rq_entry_fifo(ad->fifo_list[REQ_SYNC].next); ad->last_check_fifo[ad->batch_data_dir] = jiffies; goto dispatch_request; } @@ -1282,7 +1096,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; - arq = ad->next_arq[ad->batch_data_dir]; + rq = ad->next_rq[ad->batch_data_dir]; goto dispatch_request; } @@ -1296,8 +1110,7 @@ static int as_dispatch_request(request_queue_t *q, int force) if (as_fifo_expired(ad, ad->batch_data_dir)) { fifo_expired: - arq = list_entry_fifo(ad->fifo_list[ad->batch_data_dir].next); - BUG_ON(arq == NULL); + rq = rq_entry_fifo(ad->fifo_list[ad->batch_data_dir].next); } if (ad->changed_batch) { @@ -1316,70 +1129,58 @@ static int as_dispatch_request(request_queue_t *q, int force) } /* - * arq is the selected appropriate request. + * rq is the selected appropriate request. */ - as_move_to_dispatch(ad, arq); + as_move_to_dispatch(ad, rq); return 1; } /* - * add arq to rbtree and fifo + * add rq 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; - arq->state = AS_RQ_NEW; + RQ_SET_STATE(rq, AS_RQ_NEW); - 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; + data_dir = rq_is_sync(rq); - arq->io_context = as_get_io_context(); + rq->elevator_private = as_get_io_context(q->node); - if (arq->io_context) { - as_update_iohist(ad, arq->io_context->aic, arq->request); - atomic_inc(&arq->io_context->aic->nr_queued); + if (RQ_IOC(rq)) { + as_update_iohist(ad, RQ_IOC(rq)->aic, rq); + atomic_inc(&RQ_IOC(rq)->aic->nr_queued); } - as_add_arq_rb(ad, arq); - if (rq_mergeable(arq->request)) - as_add_arq_hash(ad, arq); + as_add_rq_rb(ad, rq); /* * set expire time (only used for reads) and add to fifo list */ - arq->expires = jiffies + ad->fifo_expire[data_dir]; - list_add_tail(&arq->fifo, &ad->fifo_list[data_dir]); + rq_set_fifo_time(rq, jiffies + ad->fifo_expire[data_dir]); + list_add_tail(&rq->queuelist, &ad->fifo_list[data_dir]); - as_update_arq(ad, arq); /* keep state machine up to date */ - arq->state = AS_RQ_QUEUED; + as_update_rq(ad, rq); /* keep state machine up to date */ + RQ_SET_STATE(rq, AS_RQ_QUEUED); } static void as_activate_request(request_queue_t *q, struct request *rq) { - 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); + 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); } static void as_deactivate_request(request_queue_t *q, struct request *rq) { - 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); + 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); } /* @@ -1396,93 +1197,35 @@ 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 = 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; - } + __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; } 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) +static void as_merged_request(request_queue_t *q, struct request *req, int type) { 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 (rq_rb_key(req) != arq->rb_key) { - as_del_arq_rb(ad, arq); - as_add_arq_rb(ad, arq); + if (type == ELEVATOR_FRONT_MERGE) { + as_del_rq_rb(ad, req); + as_add_rq_rb(ad, req); /* * Note! At this stage of this and the next function, our next * request may not be optimal - eg the request may have "grown" @@ -1494,38 +1237,22 @@ static void as_merged_request(request_queue_t *q, struct request *req) 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); - /* - * reposition arq (this is the merged request) in hash, and in rbtree - * in case of a front merge + * if next expires before rq, assign its expire time to arq + * and move into next position (next will be deleted) in fifo */ - 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); - } + 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); - /* - * 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; + list_move(&req->queuelist, &next->queuelist); + rq_set_fifo_time(req, rq_fifo_time(next)); /* * Don't copy here but swap, because when anext is * removed below, it must contain the unused context */ - swap_io_context(&arq->io_context, &anext->io_context); + swap_io_context(&rioc, &nioc); } } @@ -1533,9 +1260,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(anext); + as_put_io_context(next); - anext->state = AS_RQ_MERGED; + RQ_SET_STATE(next, AS_RQ_MERGED); } /* @@ -1553,61 +1280,18 @@ static void as_work_handler(void *data) unsigned long flags; spin_lock_irqsave(q->queue_lock, flags); - if (!as_queue_empty(q)) - q->request_fn(q); + blk_start_queueing(q); spin_unlock_irqrestore(q->queue_lock, flags); } -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) +static int as_may_queue(request_queue_t *q, int rw) { 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(); + ioc = as_get_io_context(q->node); if (ad->io_context == ioc) ret = ELV_MQUEUE_MUST; put_io_context(ioc); @@ -1626,23 +1310,16 @@ 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), and alloc a arq for - * each request on the free lists + * initialize elevator private data (as_data). */ 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) @@ -1651,30 +1328,12 @@ 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; @@ -1787,10 +1446,8 @@ 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 = 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_former_req_fn = elv_rb_former_request, + .elevator_latter_req_fn = elv_rb_latter_request, .elevator_may_queue_fn = as_may_queue, .elevator_init_fn = as_init_queue, .elevator_exit_fn = as_exit_queue, @@ -1806,11 +1463,6 @@ 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) { /* @@ -1822,21 +1474,19 @@ static int __init as_init(void) return 0; } - kmem_cache_destroy(arq_pool); return ret; } static void __exit as_exit(void) { - DECLARE_COMPLETION(all_gone); + DECLARE_COMPLETION_ONSTACK(all_gone); elv_unregister(&iosched_as); ioc_gone = &all_gone; /* ioc_gone's update must be visible before reading ioc_count */ smp_wmb(); - if (atomic_read(&ioc_count)) + if (elv_ioc_count_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 265f7a830619..135593c8e45b 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[5] __read_mostly = { 0, BLK_TC_ACT(BLK_TC_BARRIER), BLK_TC_ACT(BLK_TC_SYNC), 0, BLK_TC_ACT(BLK_TC_AHEAD) }; +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) }; /* * More could be added as needed, taking care to increment the decrementer @@ -81,6 +81,8 @@ static u32 bio_act[5] __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 @@ -103,6 +105,7 @@ 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))) @@ -217,7 +220,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->u.generic_ip; + filp->private_data = inode->i_private; return 0; } @@ -450,8 +453,10 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) **/ void blk_trace_shutdown(request_queue_t *q) { - blk_trace_startstop(q, 0); - blk_trace_remove(q); + if (q->blk_trace) { + blk_trace_startstop(q, 0); + blk_trace_remove(q); + } } /* @@ -471,6 +476,9 @@ 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; @@ -488,20 +496,6 @@ 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) @@ -530,7 +524,7 @@ static void blk_trace_set_ht_offsets(void) static __init int blk_trace_init(void) { mutex_init(&blk_tree_mutex); - blk_trace_calibrate_offsets(); + on_each_cpu(blk_trace_check_cpu_time, NULL, 1, 1); blk_trace_set_ht_offsets(); return 0; diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index 3a3aee08ec5f..d3d76136f53a 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,7 +17,6 @@ * 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 */ @@ -32,8 +31,6 @@ 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 */ @@ -41,37 +38,19 @@ static DEFINE_SPINLOCK(cfq_exit_lock); #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_DATA(rq) (rq)->elevator_private +#define RQ_CIC(rq) ((struct cfq_io_context*)(rq)->elevator_private) +#define RQ_CFQQ(rq) ((rq)->elevator_private2) -/* - * 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 atomic_t ioc_count = ATOMIC_INIT(0); +static DEFINE_PER_CPU(unsigned long, ioc_count); 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) @@ -102,29 +81,14 @@ 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 */ @@ -141,13 +105,10 @@ 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; @@ -170,23 +131,24 @@ struct cfq_queue { struct hlist_node cfq_hash; /* hash key */ unsigned int key; - /* on either rr or empty list of cfqd */ + /* member of the rr/busy/cur/idle cfqd list */ 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 cfq_rq *next_crq; + struct request *next_rq; /* 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]; @@ -199,18 +161,6 @@ 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, @@ -220,6 +170,7 @@ 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) \ @@ -244,69 +195,13 @@ 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 cfq_rq *); +static void cfq_dispatch_insert(request_queue_t *, struct request *); 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 @@ -333,12 +228,12 @@ static inline pid_t cfq_queue_pid(struct task_struct *task, int rw) } /* - * Lifted from AS - choose which of crq1 and crq2 that is best served now. + * Lifted from AS - choose which of rq1 and rq2 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 cfq_rq * -cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2) +static struct request * +cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2) { sector_t last, s1, s2, d1 = 0, d2 = 0; unsigned long back_max; @@ -346,18 +241,22 @@ cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2) #define CFQ_RQ2_WRAP 0x02 /* request 2 wraps */ unsigned wrap = 0; /* bit mask: requests behind the disk head? */ - if (crq1 == NULL || crq1 == crq2) - return crq2; - if (crq2 == NULL) - return crq1; + if (rq1 == NULL || rq1 == rq2) + return rq2; + if (rq2 == NULL) + return rq1; - 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; + 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; - s1 = crq1->request->sector; - s2 = crq2->request->sector; + s1 = rq1->sector; + s2 = rq2->sector; last = cfqd->last_sector; @@ -392,23 +291,23 @@ cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2) * check two variables for all permutations: --> faster! */ switch (wrap) { - case 0: /* common case for CFQ: crq1 and crq2 not wrapped */ + case 0: /* common case for CFQ: rq1 and rq2 not wrapped */ if (d1 < d2) - return crq1; + return rq1; else if (d2 < d1) - return crq2; + return rq2; else { if (s1 >= s2) - return crq1; + return rq1; else - return crq2; + return rq2; } case CFQ_RQ2_WRAP: - return crq1; + return rq1; case CFQ_RQ1_WRAP: - return crq2; - case (CFQ_RQ1_WRAP|CFQ_RQ2_WRAP): /* both crqs wrapped */ + return rq2; + case (CFQ_RQ1_WRAP|CFQ_RQ2_WRAP): /* both rqs wrapped */ default: /* * Since both rqs are wrapped, @@ -417,50 +316,43 @@ cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2) * since back seek takes more time than forward. */ if (s1 <= s2) - return crq1; + return rq1; else - return crq2; + return rq2; } } /* * would be nice to take fifo expire time into account as well */ -static struct cfq_rq * -cfq_find_next_crq(struct cfq_data *cfqd, struct cfq_queue *cfqq, - struct cfq_rq *last) +static struct request * +cfq_find_next_rq(struct cfq_data *cfqd, struct cfq_queue *cfqq, + struct request *last) { - struct cfq_rq *crq_next = NULL, *crq_prev = NULL; - struct rb_node *rbnext, *rbprev; - - if (!(rbnext = rb_next(&last->rb_node))) { - rbnext = rb_first(&cfqq->sort_list); - if (rbnext == &last->rb_node) - rbnext = NULL; - } + struct rb_node *rbnext = rb_next(&last->rb_node); + struct rb_node *rbprev = rb_prev(&last->rb_node); + struct request *next = NULL, *prev = NULL; - rbprev = rb_prev(&last->rb_node); + BUG_ON(RB_EMPTY_NODE(&last->rb_node)); if (rbprev) - crq_prev = rb_entry_crq(rbprev); - if (rbnext) - crq_next = rb_entry_crq(rbnext); - - return cfq_choose_req(cfqd, crq_next, crq_prev); -} + prev = rb_entry_rq(rbprev); -static void cfq_update_next_crq(struct cfq_rq *crq) -{ - struct cfq_queue *cfqq = crq->cfq_queue; + 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); + } - if (cfqq->next_crq == crq) - cfqq->next_crq = cfq_find_next_crq(cfqq->cfqd, cfqq, crq); + return cfq_choose_req(cfqd, next, prev); } static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted) { struct cfq_data *cfqd = cfqq->cfqd; - struct list_head *list, *entry; + struct list_head *list; BUG_ON(!cfq_cfqq_on_rr(cfqq)); @@ -485,31 +377,26 @@ static void cfq_resort_rr_list(struct cfq_queue *cfqq, int preempted) } /* - * if queue was preempted, just add to front to be fair. busy_rr - * isn't sorted, but insert at the back for fairness. + * 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 (preempted || list == &cfqd->busy_rr) { - if (preempted) - list = list->prev; + if (preempted || cfq_cfqq_queue_new(cfqq)) { + struct list_head *n = list; + struct cfq_queue *__cfqq; - list_add_tail(&cfqq->cfq_list, list); - return; - } + while (n->next != list) { + __cfqq = list_entry_cfqq(n->next); + if (!cfq_cfqq_queue_new(__cfqq)) + break; - /* - * sort by when queue was last serviced - */ - entry = list; - while ((entry = entry->prev) != list) { - struct cfq_queue *__cfqq = list_entry_cfqq(entry); + n = n->next; + } - if (!__cfqq->service_last) - break; - if (time_before(__cfqq->service_last, cfqq->service_last)) - break; + list = n; } - list_add(&cfqq->cfq_list, entry); + list_add_tail(&cfqq->cfq_list, list); } /* @@ -531,7 +418,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_move(&cfqq->cfq_list, &cfqd->empty_list); + list_del_init(&cfqq->cfq_list); BUG_ON(!cfqd->busy_queues); cfqd->busy_queues--; @@ -540,81 +427,43 @@ cfq_del_cfqq_rr(struct cfq_data *cfqd, struct cfq_queue *cfqq) /* * rb tree support functions */ -static inline void cfq_del_crq_rb(struct cfq_rq *crq) +static inline void cfq_del_rq_rb(struct request *rq) { - struct cfq_queue *cfqq = crq->cfq_queue; + struct cfq_queue *cfqq = RQ_CFQQ(rq); struct cfq_data *cfqd = cfqq->cfqd; - const int sync = cfq_crq_is_sync(crq); + const int sync = rq_is_sync(rq); BUG_ON(!cfqq->queued[sync]); cfqq->queued[sync]--; - cfq_update_next_crq(crq); - - rb_erase(&crq->rb_node, &cfqq->sort_list); + elv_rb_del(&cfqq->sort_list, rq); if (cfq_cfqq_on_rr(cfqq) && RB_EMPTY_ROOT(&cfqq->sort_list)) cfq_del_cfqq_rr(cfqd, cfqq); } -static struct cfq_rq * -__cfq_add_crq_rb(struct cfq_rq *crq) +static void cfq_add_rq_rb(struct request *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_queue *cfqq = RQ_CFQQ(rq); struct cfq_data *cfqd = cfqq->cfqd; - struct request *rq = crq->request; - struct cfq_rq *__alias; + struct request *__alias; - crq->rb_key = rq_rb_key(rq); - cfqq->queued[cfq_crq_is_sync(crq)]++; + cfqq->queued[rq_is_sync(rq)]++; /* * looks a little odd, but the first insert might return an alias. * if that happens, put the alias on the dispatch list */ - while ((__alias = __cfq_add_crq_rb(crq)) != NULL) + while ((__alias = elv_rb_add(&cfqq->sort_list, rq)) != 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_crq_rb(struct cfq_queue *cfqq, struct cfq_rq *crq) +cfq_reposition_rq_rb(struct cfq_queue *cfqq, struct request *rq) { - rb_erase(&crq->rb_node, &cfqq->sort_list); - cfqq->queued[cfq_crq_is_sync(crq)]--; - - cfq_add_crq_rb(crq); + elv_rb_del(&cfqq->sort_list, rq); + cfqq->queued[rq_is_sync(rq)]--; + cfq_add_rq_rb(rq); } static struct request * @@ -623,27 +472,14 @@ 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) - 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); + if (cfqq) { + sector_t sector = bio->bi_sector + bio_sectors(bio); - if (sector < crq->rb_key) - n = n->rb_left; - else if (sector > crq->rb_key) - n = n->rb_right; - else - return crq->request; + return elv_rb_find(&cfqq->sort_list, sector); } -out: return NULL; } @@ -673,11 +509,18 @@ static void cfq_deactivate_request(request_queue_t *q, struct request *rq) static void cfq_remove_request(struct request *rq) { - struct cfq_rq *crq = RQ_DATA(rq); + struct cfq_queue *cfqq = RQ_CFQQ(rq); + + if (cfqq->next_rq == rq) + cfqq->next_rq = cfq_find_next_rq(cfqq->cfqd, cfqq, rq); list_del_init(&rq->queuelist); - cfq_del_crq_rb(crq); - cfq_del_crq_hash(crq); + cfq_del_rq_rb(rq); + + if (rq_is_meta(rq)) { + WARN_ON(!cfqq->meta_pending); + cfqq->meta_pending--; + } } static int @@ -685,39 +528,23 @@ 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)) { - ret = ELEVATOR_FRONT_MERGE; - goto out; + *req = __rq; + return ELEVATOR_FRONT_MERGE; } return ELEVATOR_NO_MERGE; -out: - *req = __rq; - return ret; } -static void cfq_merged_request(request_queue_t *q, struct request *req) +static void cfq_merged_request(request_queue_t *q, struct request *req, + int type) { - 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; + if (type == ELEVATOR_FRONT_MERGE) { + struct cfq_queue *cfqq = RQ_CFQQ(req); - cfq_update_next_crq(crq); - cfq_reposition_crq_rb(cfqq, crq); + cfq_reposition_rq_rb(cfqq, req); } } @@ -725,8 +552,6 @@ 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 */ @@ -768,13 +593,12 @@ __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)) { - cfqq->service_last = now; + if (!preempted && !cfq_cfqq_dispatched(cfqq)) 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 @@ -868,26 +692,25 @@ static struct cfq_queue *cfq_set_active_queue(struct cfq_data *cfqd) { struct cfq_queue *cfqq = NULL; - /* - * 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) + 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 + */ cfqq = list_entry_cfqq(cfqd->cur_rr.next); - - /* - * 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)) + } 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. + */ cfqq = list_entry_cfqq(cfqd->busy_rr.next); - - /* - * 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)) { + } 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 + */ unsigned long end = cfqd->last_end_request + CFQ_IDLE_GRACE; if (time_after_eq(jiffies, end)) @@ -942,16 +765,14 @@ 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 cfq_rq *crq) +static void cfq_dispatch_insert(request_queue_t *q, struct request *rq) { struct cfq_data *cfqd = q->elevator->elevator_data; - struct cfq_queue *cfqq = crq->cfq_queue; - struct request *rq; + struct cfq_queue *cfqq = RQ_CFQQ(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); + cfq_remove_request(rq); + cfqq->on_dispatch[rq_is_sync(rq)]++; + elv_dispatch_sort(q, rq); rq = list_entry(q->queue_head.prev, struct request, queuelist); cfqd->last_sector = rq->sector + rq->nr_sectors; @@ -960,24 +781,23 @@ static void cfq_dispatch_insert(request_queue_t *q, struct cfq_rq *crq) /* * return expired entry, or NULL to just start from scratch in rbtree */ -static inline struct cfq_rq *cfq_check_fifo(struct cfq_queue *cfqq) +static inline struct request *cfq_check_fifo(struct cfq_queue *cfqq) { struct cfq_data *cfqd = cfqq->cfqd; struct request *rq; - struct cfq_rq *crq; + int fifo; if (cfq_cfqq_fifo_expire(cfqq)) return NULL; + if (list_empty(&cfqq->fifo)) + return NULL; - if (!list_empty(&cfqq->fifo)) { - int fifo = cfq_cfqq_class_sync(cfqq); + fifo = cfq_cfqq_class_sync(cfqq); + rq = rq_entry_fifo(cfqq->fifo.next); - 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; - } + if (time_after(jiffies, rq->start_time + cfqd->cfq_fifo_expire[fifo])) { + cfq_mark_cfqq_fifo_expire(cfqq); + return rq; } return NULL; @@ -1063,25 +883,25 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq, BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list)); do { - struct cfq_rq *crq; + struct request *rq; /* * follow expired path, else get first next available */ - if ((crq = cfq_check_fifo(cfqq)) == NULL) - crq = cfqq->next_crq; + if ((rq = cfq_check_fifo(cfqq)) == NULL) + rq = cfqq->next_rq; /* * finally, insert request into driver dispatch list */ - cfq_dispatch_insert(cfqd->queue, crq); + cfq_dispatch_insert(cfqd->queue, rq); cfqd->dispatch_slice++; dispatched++; if (!cfqd->active_cic) { - atomic_inc(&crq->io_context->ioc->refcount); - cfqd->active_cic = crq->io_context; + atomic_inc(&RQ_CIC(rq)->ioc->refcount); + cfqd->active_cic = RQ_CIC(rq); } if (RB_EMPTY_ROOT(&cfqq->sort_list)) @@ -1112,13 +932,12 @@ 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 ((crq = cfqq->next_crq)) { - cfq_dispatch_insert(cfqq->cfqd->queue, crq); + while (cfqq->next_rq) { + cfq_dispatch_insert(cfqq->cfqd->queue, cfqq->next_rq); dispatched++; } BUG_ON(!list_empty(&cfqq->fifo)); @@ -1194,8 +1013,8 @@ cfq_dispatch_requests(request_queue_t *q, int force) } /* - * 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. + * 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. * * queue lock must be held here. */ @@ -1223,7 +1042,7 @@ static void cfq_put_queue(struct cfq_queue *cfqq) kmem_cache_free(cfq_pool, cfqq); } -static inline struct cfq_queue * +static struct cfq_queue * __cfq_find_cfq_hash(struct cfq_data *cfqd, unsigned int key, unsigned int prio, const int hashval) { @@ -1260,62 +1079,63 @@ static void cfq_free_io_context(struct io_context *ioc) freed++; } - if (atomic_sub_and_test(freed, &ioc_count) && ioc_gone) + elv_ioc_count_mod(ioc_count, -freed); + + if (ioc_gone && !elv_ioc_count_read(ioc_count)) complete(ioc_gone); } -static void cfq_trim(struct io_context *ioc) +static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) { - ioc->set_ioprio = NULL; - cfq_free_io_context(ioc); + if (unlikely(cfqq == cfqd->active_queue)) + __cfq_slice_expired(cfqd, cfqq, 0); + + cfq_put_queue(cfqq); } -/* - * Called with interrupts disabled - */ -static void cfq_exit_single_io_context(struct cfq_io_context *cic) +static void __cfq_exit_single_io_context(struct cfq_data *cfqd, + struct cfq_io_context *cic) { - 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); + list_del_init(&cic->queue_list); + smp_wmb(); + cic->key = NULL; if (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]); + cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]); cic->cfqq[ASYNC] = NULL; } if (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]); + cfq_exit_cfqq(cfqd, cic->cfqq[SYNC]); cic->cfqq[SYNC] = NULL; } +} - cic->key = NULL; - list_del_init(&cic->queue_list); - spin_unlock(q->queue_lock); + +/* + * 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); + } } 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) { @@ -1324,22 +1144,21 @@ 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 = kmem_cache_alloc(cfq_ioc_pool, gfp_mask); + struct cfq_io_context *cic; + 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; - atomic_inc(&ioc_count); + elv_ioc_count_inc(ioc_count); } return cic; @@ -1420,15 +1239,12 @@ static inline void changed_ioprio(struct cfq_io_context *cic) spin_unlock(cfqd->queue->queue_lock); } -/* - * callback from sys_ioprio_set, irqs are disabled - */ -static int cfq_ioc_set_ioprio(struct io_context *ioc, unsigned int ioprio) +static void cfq_ioc_set_ioprio(struct io_context *ioc) { struct cfq_io_context *cic; struct rb_node *n; - spin_lock(&cfq_exit_lock); + ioc->ioprio_changed = 0; n = rb_first(&ioc->cic_root); while (n != NULL) { @@ -1437,10 +1253,6 @@ static int cfq_ioc_set_ioprio(struct io_context *ioc, unsigned int ioprio) changed_ioprio(cic); n = rb_next(n); } - - spin_unlock(&cfq_exit_lock); - - return 0; } static struct cfq_queue * @@ -1460,12 +1272,18 @@ 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(cfq_pool, gfp_mask); + new_cfqq = kmem_cache_alloc_node(cfq_pool, gfp_mask|__GFP_NOFAIL, cfqd->queue->node); spin_lock_irq(cfqd->queue->queue_lock); goto retry; } else { - cfqq = kmem_cache_alloc(cfq_pool, gfp_mask); + cfqq = kmem_cache_alloc_node(cfq_pool, gfp_mask, cfqd->queue->node); if (!cfqq) goto out; } @@ -1480,13 +1298,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); } @@ -1502,12 +1320,10 @@ 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) { - spin_lock(&cfq_exit_lock); + WARN_ON(!list_empty(&cic->queue_list)); 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); - atomic_dec(&ioc_count); + elv_ioc_count_dec(ioc_count); } static struct cfq_io_context * @@ -1551,7 +1367,6 @@ 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; @@ -1573,11 +1388,12 @@ 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(&cfq_exit_lock); + spin_unlock_irq(cfqd->queue->queue_lock); } /* @@ -1593,7 +1409,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); + ioc = get_io_context(gfp_mask, cfqd->queue->node); if (!ioc) return NULL; @@ -1607,6 +1423,10 @@ 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); @@ -1640,15 +1460,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 cfq_rq *crq) + struct request *rq) { sector_t sdist; u64 total; - if (cic->last_request_pos < crq->request->sector) - sdist = crq->request->sector - cic->last_request_pos; + if (cic->last_request_pos < rq->sector) + sdist = rq->sector - cic->last_request_pos; else - sdist = cic->last_request_pos - crq->request->sector; + sdist = cic->last_request_pos - rq->sector; /* * Don't allow the seek distance to get too large from the @@ -1699,7 +1519,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 cfq_rq *crq) + struct request *rq) { struct cfq_queue *cfqq = cfqd->active_queue; @@ -1718,7 +1538,17 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, */ if (new_cfqq->slice_left < cfqd->cfq_slice_idle) return 0; - if (cfq_crq_is_sync(crq) && !cfq_cfqq_sync(cfqq)) + /* + * 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) return 1; return 0; @@ -1730,47 +1560,45 @@ 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) { - struct cfq_queue *__cfqq, *next; - - list_for_each_entry_safe(__cfqq, next, &cfqd->cur_rr, cfq_list) - cfq_resort_rr_list(__cfqq, 1); + cfq_slice_expired(cfqd, 1); if (!cfqq->slice_left) cfqq->slice_left = cfq_prio_to_slice(cfqd, cfqq) / 2; - cfqq->slice_end = cfqq->slice_left + jiffies; - cfq_slice_expired(cfqd, 1); - __cfq_set_active_queue(cfqd, cfqq); -} - -/* - * should really be a ll_rw_blk.c helper - */ -static void cfq_start_queueing(struct cfq_data *cfqd, struct cfq_queue *cfqq) -{ - request_queue_t *q = cfqd->queue; + /* + * 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); - if (!blk_queue_plugged(q)) - q->request_fn(q); - else - __generic_unplug_device(q); + cfqq->slice_end = cfqq->slice_left + jiffies; } /* - * Called when a new fs request (crq) is added (to cfqq). Check if there's + * Called when a new fs request (rq) 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) +cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, + struct request *rq) { - struct cfq_io_context *cic = crq->io_context; + struct cfq_io_context *cic = RQ_CIC(rq); + + if (rq_is_meta(rq)) + cfqq->meta_pending++; + + /* + * 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); /* * we never wait for an async request and we don't allow preemption * of an async request. so just return early */ - if (!cfq_crq_is_sync(crq)) { + if (!rq_is_sync(rq)) { /* * sync process issued an async request, if it's waiting * then expire it and kick rq handling. @@ -1778,17 +1606,17 @@ cfq_crq_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); - cfq_start_queueing(cfqd, cfqq); + blk_start_queueing(cfqd->queue); } return; } cfq_update_io_thinktime(cfqd, cic); - cfq_update_io_seektime(cfqd, cic, crq); + cfq_update_io_seektime(cfqd, cic, rq); cfq_update_idle_window(cfqd, cfqq, cic); cic->last_queue = jiffies; - cic->last_request_pos = crq->request->sector + crq->request->nr_sectors; + cic->last_request_pos = rq->sector + rq->nr_sectors; if (cfqq == cfqd->active_queue) { /* @@ -1799,9 +1627,9 @@ cfq_crq_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); - cfq_start_queueing(cfqd, cfqq); + blk_start_queueing(cfqd->queue); } - } else if (cfq_should_preempt(cfqd, cfqq, crq)) { + } else if (cfq_should_preempt(cfqd, cfqq, rq)) { /* * not the active queue - expire current slice if it is * idle and has expired it's mean thinktime or this new queue @@ -1809,34 +1637,32 @@ cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, */ cfq_preempt_queue(cfqd, cfqq); cfq_mark_cfqq_must_dispatch(cfqq); - cfq_start_queueing(cfqd, cfqq); + blk_start_queueing(cfqd->queue); } } static void cfq_insert_request(request_queue_t *q, struct request *rq) { struct cfq_data *cfqd = q->elevator->elevator_data; - struct cfq_rq *crq = RQ_DATA(rq); - struct cfq_queue *cfqq = crq->cfq_queue; + struct cfq_queue *cfqq = RQ_CFQQ(rq); cfq_init_prio_data(cfqq); - cfq_add_crq_rb(crq); + cfq_add_rq_rb(rq); - list_add_tail(&rq->queuelist, &cfqq->fifo); + if (!cfq_cfqq_on_rr(cfqq)) + cfq_add_cfqq_rr(cfqd, cfqq); - if (rq_mergeable(rq)) - cfq_add_crq_hash(cfqd, crq); + list_add_tail(&rq->queuelist, &cfqq->fifo); - cfq_crq_enqueued(cfqd, cfqq, crq); + cfq_rq_enqueued(cfqd, cfqq, rq); } static void cfq_completed_request(request_queue_t *q, struct request *rq) { - struct cfq_rq *crq = RQ_DATA(rq); - struct cfq_queue *cfqq = crq->cfq_queue; + struct cfq_queue *cfqq = RQ_CFQQ(rq); struct cfq_data *cfqd = cfqq->cfqd; - const int sync = cfq_crq_is_sync(crq); + const int sync = rq_is_sync(rq); unsigned long now; now = jiffies; @@ -1849,15 +1675,11 @@ 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)) { - if (cfq_cfqq_on_rr(cfqq)) { - cfqq->service_last = now; - cfq_resort_rr_list(cfqq, 0); - } - } + if (!cfq_cfqq_dispatched(cfqq) && cfq_cfqq_on_rr(cfqq)) + cfq_resort_rr_list(cfqq, 0); if (sync) - crq->io_context->last_end_request = now; + RQ_CIC(rq)->last_end_request = now; /* * If this is the active queue, check if it needs to be expired, @@ -1873,30 +1695,6 @@ 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) @@ -1933,9 +1731,7 @@ static void cfq_prio_boost(struct cfq_queue *cfqq) cfq_resort_rr_list(cfqq, 0); } -static inline int -__cfq_may_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq, - struct task_struct *task, int rw) +static inline int __cfq_may_queue(struct cfq_queue *cfqq) { if ((cfq_cfqq_wait_request(cfqq) || cfq_cfqq_must_alloc(cfqq)) && !cfq_cfqq_must_alloc_slice(cfqq)) { @@ -1946,7 +1742,7 @@ __cfq_may_queue(struct cfq_data *cfqd, struct cfq_queue *cfqq, return ELV_MQUEUE_MAY; } -static int cfq_may_queue(request_queue_t *q, int rw, struct bio *bio) +static int cfq_may_queue(request_queue_t *q, int rw) { struct cfq_data *cfqd = q->elevator->elevator_data; struct task_struct *tsk = current; @@ -1963,48 +1759,30 @@ static int cfq_may_queue(request_queue_t *q, int rw, struct bio *bio) cfq_init_prio_data(cfqq); cfq_prio_boost(cfqq); - return __cfq_may_queue(cfqd, cfqq, tsk, rw); + return __cfq_may_queue(cfqq); } 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_data *cfqd = q->elevator->elevator_data; - struct cfq_rq *crq = RQ_DATA(rq); + struct cfq_queue *cfqq = RQ_CFQQ(rq); - if (crq) { - struct cfq_queue *cfqq = crq->cfq_queue; + if (cfqq) { const int rw = rq_data_dir(rq); BUG_ON(!cfqq->allocated[rw]); cfqq->allocated[rw]--; - put_io_context(crq->io_context->ioc); + put_io_context(RQ_CIC(rq)->ioc); - mempool_free(crq, cfqd->crq_pool); rq->elevator_private = NULL; + rq->elevator_private2 = NULL; - cfq_check_waiters(q, cfqq); cfq_put_queue(cfqq); } } @@ -2013,8 +1791,7 @@ 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, struct bio *bio, - gfp_t gfp_mask) +cfq_set_request(request_queue_t *q, struct request *rq, gfp_t gfp_mask) { struct cfq_data *cfqd = q->elevator->elevator_data; struct task_struct *tsk = current; @@ -2022,7 +1799,6 @@ cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio, 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; @@ -2046,42 +1822,18 @@ cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio, cfqq->allocated[rw]++; cfq_clear_cfqq_must_alloc(cfqq); - cfqd->rq_starved = 0; atomic_inc(&cfqq->ref); - spin_unlock_irqrestore(q->queue_lock, flags); - 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); + spin_unlock_irqrestore(q->queue_lock, flags); - rq->elevator_private = crq; - return 0; - } + rq->elevator_private = cic; + rq->elevator_private2 = cfqq; + 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; @@ -2090,27 +1842,10 @@ cfq_set_request(request_queue_t *q, struct request *rq, struct bio *bio, 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); - - 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); + blk_start_queueing(q); spin_unlock_irqrestore(q->queue_lock, flags); } @@ -2193,7 +1928,6 @@ 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) @@ -2203,25 +1937,14 @@ 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); - 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); + + __cfq_exit_single_io_context(cfqd, cic); } 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); } @@ -2231,7 +1954,7 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e) struct cfq_data *cfqd; int i; - cfqd = kmalloc(sizeof(*cfqd), GFP_KERNEL); + cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL, q->node); if (!cfqd) return NULL; @@ -2243,23 +1966,12 @@ 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->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); + cfqd->cfq_hash = kmalloc_node(sizeof(struct hlist_head) * CFQ_QHASH_ENTRIES, GFP_KERNEL, q->node); if (!cfqd->cfq_hash) - goto out_cfqhash; - - cfqd->crq_pool = mempool_create_slab_pool(BLKDEV_MIN_RQ, crq_pool); - if (!cfqd->crq_pool) - goto out_crqpool; + goto out_free; - 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]); @@ -2275,7 +1987,6 @@ 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]; @@ -2287,19 +1998,13 @@ static void *cfq_init_queue(request_queue_t *q, elevator_t *e) cfqd->cfq_slice_idle = cfq_slice_idle; return cfqd; -out_crqpool: - kfree(cfqd->cfq_hash); -out_cfqhash: - kfree(cfqd->crq_hash); -out_crqhash: +out_free: 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) @@ -2308,11 +2013,6 @@ 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) @@ -2358,7 +2058,6 @@ 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); @@ -2386,7 +2085,6 @@ 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); @@ -2402,7 +2100,6 @@ 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), @@ -2425,14 +2122,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 = cfq_former_request, - .elevator_latter_req_fn = cfq_latter_request, + .elevator_former_req_fn = elv_rb_former_request, + .elevator_latter_req_fn = elv_rb_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_trim, + .trim = cfq_free_io_context, }, .elevator_attrs = cfq_attrs, .elevator_name = "cfq", @@ -2463,12 +2160,12 @@ static int __init cfq_init(void) static void __exit cfq_exit(void) { - DECLARE_COMPLETION(all_gone); + DECLARE_COMPLETION_ONSTACK(all_gone); elv_unregister(&iosched_cfq); ioc_gone = &all_gone; /* ioc_gone's update must be visible before reading ioc_count */ smp_wmb(); - if (atomic_read(&ioc_count)) + if (elv_ioc_count_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 c7ca9f0b6498..b7c5b34cb7b4 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,7 +12,6 @@ #include #include #include -#include #include /* @@ -24,13 +23,6 @@ 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 @@ -45,8 +37,7 @@ struct deadline_data { /* * next in sort order. read, write or both are NULL */ - struct deadline_rq *next_drq[2]; - struct hlist_head *hash; /* request hash */ + struct request *next_rq[2]; unsigned int batching; /* number of sequential requests made */ sector_t last_sector; /* head position */ unsigned int starved; /* times reads have starved writes */ @@ -58,240 +49,69 @@ struct deadline_data { int fifo_batch; int writes_starved; int front_merges; - - mempool_t *drq_pool; }; -/* - * 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) +static void deadline_move_request(struct deadline_data *, struct request *); -/* - * 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; -} +#define RQ_RB_ROOT(dd, rq) (&(dd)->sort_list[rq_data_dir((rq))]) static void -deadline_add_drq_rb(struct deadline_data *dd, struct deadline_rq *drq) +deadline_add_rq_rb(struct deadline_data *dd, struct request *rq) { - struct deadline_rq *__alias; - - drq->rb_key = rq_rb_key(drq->request); + struct rb_root *root = RQ_RB_ROOT(dd, rq); + struct request *__alias; retry: - __alias = __deadline_add_drq_rb(dd, drq); - if (!__alias) { - rb_insert_color(&drq->rb_node, DRQ_RB_ROOT(dd, drq)); - return; + __alias = elv_rb_add(root, rq); + if (unlikely(__alias)) { + deadline_move_request(dd, __alias); + goto retry; } - - deadline_move_request(dd, __alias); - goto retry; } static inline void -deadline_del_drq_rb(struct deadline_data *dd, struct deadline_rq *drq) +deadline_del_rq_rb(struct deadline_data *dd, struct request *rq) { - const int data_dir = rq_data_dir(drq->request); + const int data_dir = rq_data_dir(rq); - if (dd->next_drq[data_dir] == drq) { - struct rb_node *rbnext = rb_next(&drq->rb_node); + if (dd->next_rq[data_dir] == rq) { + struct rb_node *rbnext = rb_next(&rq->rb_node); - dd->next_drq[data_dir] = NULL; + dd->next_rq[data_dir] = NULL; if (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; + dd->next_rq[data_dir] = rb_entry_rq(rbnext); } - return NULL; + elv_rb_del(RQ_RB_ROOT(dd, rq), rq); } /* - * 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 + * add rq to rbtree and fifo */ static void deadline_add_request(struct request_queue *q, struct request *rq) { struct deadline_data *dd = q->elevator->elevator_data; - struct deadline_rq *drq = RQ_DATA(rq); + const int data_dir = rq_data_dir(rq); - const int data_dir = rq_data_dir(drq->request); + deadline_add_rq_rb(dd, rq); - deadline_add_drq_rb(dd, drq); /* * set expire time (only used for reads) and add to fifo list */ - 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); + rq_set_fifo_time(rq, jiffies + dd->fifo_expire[data_dir]); + list_add_tail(&rq->queuelist, &dd->fifo_list[data_dir]); } /* - * remove rq from rbtree, fifo, and hash + * remove rq from rbtree and fifo. */ 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; - list_del_init(&drq->fifo); - deadline_del_drq_rb(dd, drq); - deadline_del_drq_hash(drq); + rq_fifo_clear(rq); + deadline_del_rq_rb(dd, rq); } static int @@ -301,28 +121,15 @@ 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 rb_key = bio->bi_sector + bio_sectors(bio); + sector_t sector = bio->bi_sector + bio_sectors(bio); - __rq = deadline_find_drq_rb(dd, rb_key, bio_data_dir(bio)); + __rq = elv_rb_find(&dd->sort_list[bio_data_dir(bio)], sector); if (__rq) { - BUG_ON(rb_key != rq_rb_key(__rq)); + BUG_ON(sector != __rq->sector); if (elv_rq_merge_ok(__rq, bio)) { ret = ELEVATOR_FRONT_MERGE; @@ -333,29 +140,21 @@ 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) +static void deadline_merged_request(request_queue_t *q, struct request *req, + int type) { 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 (rq_rb_key(req) != drq->rb_key) { - deadline_del_drq_rb(dd, drq); - deadline_add_drq_rb(dd, drq); + if (type == ELEVATOR_FRONT_MERGE) { + elv_rb_del(RQ_RB_ROOT(dd, req), req); + deadline_add_rq_rb(dd, req); } } @@ -363,33 +162,14 @@ 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); - /* - * reposition drq (this is the merged request) in hash, and in rbtree - * in case of a front merge + * if next expires before rq, assign its expire time to rq + * and move into next position (next will be deleted) in fifo */ - 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; + 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)); } } @@ -403,52 +183,50 @@ 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 deadline_rq *drq) +deadline_move_to_dispatch(struct deadline_data *dd, struct request *rq) { - request_queue_t *q = drq->request->q; + request_queue_t *q = rq->q; - deadline_remove_request(q, drq->request); - elv_dispatch_add_tail(q, drq->request); + deadline_remove_request(q, rq); + elv_dispatch_add_tail(q, rq); } /* * move an entry to dispatch queue */ static void -deadline_move_request(struct deadline_data *dd, struct deadline_rq *drq) +deadline_move_request(struct deadline_data *dd, struct request *rq) { - const int data_dir = rq_data_dir(drq->request); - struct rb_node *rbnext = rb_next(&drq->rb_node); + const int data_dir = rq_data_dir(rq); + struct rb_node *rbnext = rb_next(&rq->rb_node); - dd->next_drq[READ] = NULL; - dd->next_drq[WRITE] = NULL; + dd->next_rq[READ] = NULL; + dd->next_rq[WRITE] = NULL; if (rbnext) - dd->next_drq[data_dir] = rb_entry_drq(rbnext); + dd->next_rq[data_dir] = rb_entry_rq(rbnext); - dd->last_sector = drq->request->sector + drq->request->nr_sectors; + dd->last_sector = rq->sector + rq->nr_sectors; /* * take it off the sort and fifo list, move * to dispatch queue */ - deadline_move_to_dispatch(dd, drq); + deadline_move_to_dispatch(dd, rq); } -#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 deadline_rq *drq = list_entry_fifo(dd->fifo_list[ddir].next); + struct request *rq = rq_entry_fifo(dd->fifo_list[ddir].next); /* - * drq is expired! + * rq is expired! */ - if (time_after(jiffies, drq->expires)) + if (time_after(jiffies, rq_fifo_time(rq))) return 1; return 0; @@ -463,21 +241,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 deadline_rq *drq; + struct request *rq; int data_dir; /* * batches are currently reads XOR writes */ - if (dd->next_drq[WRITE]) - drq = dd->next_drq[WRITE]; + if (dd->next_rq[WRITE]) + rq = dd->next_rq[WRITE]; else - drq = dd->next_drq[READ]; + rq = dd->next_rq[READ]; - if (drq) { + if (rq) { /* we have a "next request" */ - if (dd->last_sector != drq->request->sector) + if (dd->last_sector != rq->sector) /* end the batch on a non sequential request */ dd->batching += dd->fifo_batch; @@ -526,30 +304,33 @@ 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; - drq = list_entry_fifo(dd->fifo_list[data_dir].next); + rq = rq_entry_fifo(dd->fifo_list[data_dir].next); - } else if (dd->next_drq[data_dir]) { + } else if (dd->next_rq[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. */ - drq = dd->next_drq[data_dir]; + rq = dd->next_rq[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; - drq = deadline_find_first_drq(dd, data_dir); + node = rb_first(&dd->sort_list[data_dir]); + if (node) + rq = rb_entry_rq(node); } dispatch_request: /* - * drq is the selected appropriate request. + * rq is the selected appropriate request. */ dd->batching++; - deadline_move_request(dd, drq); + deadline_move_request(dd, rq); return 1; } @@ -562,30 +343,6 @@ 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; @@ -593,46 +350,21 @@ 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), and alloc a drq for - * each request on the free lists + * initialize elevator private data (deadline_data). */ 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; @@ -645,39 +377,6 @@ 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 */ @@ -757,10 +456,8 @@ 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 = 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_former_req_fn = elv_rb_former_request, + .elevator_latter_req_fn = elv_rb_latter_request, .elevator_init_fn = deadline_init_queue, .elevator_exit_fn = deadline_exit_queue, }, @@ -772,24 +469,11 @@ static struct elevator_type iosched_deadline = { static int __init deadline_init(void) { - 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; + return elv_register(&iosched_deadline); } 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 9b72dc7c8a5c..487dd3da8853 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,12 +33,23 @@ #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? */ @@ -56,8 +67,7 @@ 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->waiting && !rq->special) + if (rq->rq_disk == bio->bi_bdev->bd_disk && !rq->special) return 1; return 0; @@ -151,27 +161,44 @@ __setup("elevator=", elevator_setup); static struct kobj_type elv_ktype; -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); - } +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]); + 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); } @@ -198,7 +225,7 @@ int elevator_init(request_queue_t *q, char *name) e = elevator_get("noop"); } - eq = elevator_alloc(e); + eq = elevator_alloc(q, e); if (!eq) return -ENOMEM; @@ -212,6 +239,8 @@ 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); @@ -223,10 +252,118 @@ 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. If sort != 0, rq is sort-inserted; otherwise, rq will be - * appended to the dispatch queue. To be used by specific elevators. + * entry. rq is sort insted into the dispatch queue. To be used by + * specific elevators. */ void elv_dispatch_sort(request_queue_t *q, struct request *rq) { @@ -235,6 +372,9 @@ 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; @@ -242,7 +382,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->flags & (REQ_SOFTBARRIER|REQ_HARDBARRIER|REQ_STARTED)) + if (pos->cmd_flags & (REQ_SOFTBARRIER|REQ_HARDBARRIER|REQ_STARTED)) break; if (rq->sector >= boundary) { if (pos->sector < boundary) @@ -258,11 +398,38 @@ 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) { @@ -271,18 +438,30 @@ 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) +void elv_merged_request(request_queue_t *q, struct request *rq, int type) { elevator_t *e = q->elevator; if (e->ops->elevator_merged_fn) - e->ops->elevator_merged_fn(q, rq); + e->ops->elevator_merged_fn(q, rq, type); + + if (type == ELEVATOR_BACK_MERGE) + elv_rqhash_reposition(q, rq); q->last_merge = rq; } @@ -294,8 +473,11 @@ 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); - q->nr_sorted--; + elv_rqhash_reposition(q, rq); + elv_rqhash_del(q, next); + + q->nr_sorted--; q->last_merge = rq; } @@ -313,7 +495,7 @@ void elv_requeue_request(request_queue_t *q, struct request *rq) e->ops->elevator_deactivate_req_fn(q, rq); } - rq->flags &= ~REQ_STARTED; + rq->cmd_flags &= ~REQ_STARTED; elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE); } @@ -344,13 +526,13 @@ void elv_insert(request_queue_t *q, struct request *rq, int where) switch (where) { case ELEVATOR_INSERT_FRONT: - rq->flags |= REQ_SOFTBARRIER; + rq->cmd_flags |= REQ_SOFTBARRIER; list_add(&rq->queuelist, &q->queue_head); break; case ELEVATOR_INSERT_BACK: - rq->flags |= REQ_SOFTBARRIER; + rq->cmd_flags |= REQ_SOFTBARRIER; elv_drain_elevator(q); list_add_tail(&rq->queuelist, &q->queue_head); /* @@ -369,10 +551,14 @@ void elv_insert(request_queue_t *q, struct request *rq, int where) case ELEVATOR_INSERT_SORT: BUG_ON(!blk_fs_request(rq)); - rq->flags |= REQ_SORTED; + rq->cmd_flags |= REQ_SORTED; q->nr_sorted++; - if (q->last_merge == NULL && rq_mergeable(rq)) - q->last_merge = rq; + if (rq_mergeable(rq)) { + elv_rqhash_add(q, rq); + if (!q->last_merge) + q->last_merge = rq; + } + /* * Some ioscheds (cfq) run q->request_fn directly, so * rq cannot be accessed after calling @@ -387,7 +573,7 @@ void elv_insert(request_queue_t *q, struct request *rq, int where) * insertion; otherwise, requests should be requeued * in ordseq order. */ - rq->flags |= REQ_SOFTBARRIER; + rq->cmd_flags |= REQ_SOFTBARRIER; if (q->ordseq == 0) { list_add(&rq->queuelist, &q->queue_head); @@ -429,9 +615,9 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where, int plug) { if (q->ordcolor) - rq->flags |= REQ_ORDERED_COLOR; + rq->cmd_flags |= REQ_ORDERED_COLOR; - if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { + if (rq->cmd_flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { /* * toggle ordered color */ @@ -452,7 +638,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->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT) + } else if (!(rq->cmd_flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT) where = ELEVATOR_INSERT_BACK; if (plug) @@ -461,6 +647,8 @@ 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) { @@ -471,6 +659,8 @@ 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; @@ -493,7 +683,7 @@ struct request *elv_next_request(request_queue_t *q) int ret; while ((rq = __elv_next_request(q)) != NULL) { - if (!(rq->flags & REQ_STARTED)) { + if (!(rq->cmd_flags & REQ_STARTED)) { elevator_t *e = q->elevator; /* @@ -510,7 +700,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->flags |= REQ_STARTED; + rq->cmd_flags |= REQ_STARTED; blk_add_trace_rq(q, rq, BLK_TA_ISSUE); } @@ -519,7 +709,7 @@ struct request *elv_next_request(request_queue_t *q) q->boundary_rq = NULL; } - if ((rq->flags & REQ_DONTPREP) || !q->prep_rq_fn) + if ((rq->cmd_flags & REQ_DONTPREP) || !q->prep_rq_fn) break; ret = q->prep_rq_fn(q, rq); @@ -541,7 +731,7 @@ struct request *elv_next_request(request_queue_t *q) nr_bytes = rq->data_len; blkdev_dequeue_request(rq); - rq->flags |= REQ_QUIET; + rq->cmd_flags |= REQ_QUIET; end_that_request_chunk(rq, 0, nr_bytes); end_that_request_last(rq, 0); } else { @@ -554,9 +744,12 @@ 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); @@ -569,6 +762,8 @@ 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; @@ -582,6 +777,8 @@ 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; @@ -600,13 +797,12 @@ 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, struct bio *bio, - gfp_t gfp_mask) +int elv_set_request(request_queue_t *q, struct request *rq, 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, bio, gfp_mask); + return e->ops->elevator_set_req_fn(q, rq, gfp_mask); rq->elevator_private = NULL; return 0; @@ -620,12 +816,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, struct bio *bio) +int elv_may_queue(request_queue_t *q, int rw) { elevator_t *e = q->elevator; if (e->ops->elevator_may_queue_fn) - return e->ops->elevator_may_queue_fn(q, rw, bio); + return e->ops->elevator_may_queue_fn(q, rw); return ELV_MQUEUE_MAY; } @@ -792,7 +988,7 @@ static int elevator_switch(request_queue_t *q, struct elevator_type *new_e) /* * Allocate new elevator */ - e = elevator_alloc(new_e); + e = elevator_alloc(q, new_e); if (!e) return 0; @@ -908,11 +1104,26 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name) return len; } -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); +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); diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index 25d1f42568cc..653919d50cd4 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -295,10 +295,15 @@ 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(); - subsystem_register(&block_subsys); - return 0; + err = subsystem_register(&block_subsys); + if (err < 0) + printk(KERN_WARNING "%s: subsystem_register error: %d\n", + __FUNCTION__, err); + return err; } subsys_initcall(genhd_device_init); diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 9c3a06bcb7ba..83425fb3c8db 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -39,6 +39,7 @@ 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 @@ -277,19 +278,19 @@ void blk_queue_make_request(request_queue_t * q, make_request_fn * mfn) EXPORT_SYMBOL(blk_queue_make_request); -static inline void rq_init(request_queue_t *q, struct request *rq) +static 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; @@ -382,8 +383,8 @@ unsigned blk_ordered_req_seq(struct request *rq) if (rq == &q->post_flush_rq) return QUEUE_ORDSEQ_POSTFLUSH; - if ((rq->flags & REQ_ORDERED_COLOR) == - (q->orig_bar_rq->flags & REQ_ORDERED_COLOR)) + if ((rq->cmd_flags & REQ_ORDERED_COLOR) == + (q->orig_bar_rq->cmd_flags & REQ_ORDERED_COLOR)) return QUEUE_ORDSEQ_DRAIN; else return QUEUE_ORDSEQ_DONE; @@ -446,11 +447,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); @@ -471,11 +472,13 @@ 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); - rq->flags = bio_data_dir(q->orig_bar_rq->bio); - rq->flags |= q->ordered & QUEUE_ORDERED_FUA ? REQ_FUA : 0; + 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->elevator_private = NULL; - rq->rl = NULL; + rq->elevator_private2 = NULL; init_request_from_bio(rq, q->orig_bar_rq->bio); rq->end_io = bar_end_io; @@ -587,8 +590,8 @@ static int flush_dry_bio_endio(struct bio *bio, unsigned int bytes, int error) return 0; } -static inline int ordered_bio_endio(struct request *rq, struct bio *bio, - unsigned int nbytes, int error) +static 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; @@ -1124,7 +1127,7 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq) } list_del_init(&rq->queuelist); - rq->flags &= ~REQ_QUEUED; + rq->cmd_flags &= ~REQ_QUEUED; rq->tag = -1; if (unlikely(bqt->tag_index[tag] == NULL)) @@ -1160,7 +1163,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->flags & REQ_QUEUED))) { + if (unlikely((rq->cmd_flags & REQ_QUEUED))) { printk(KERN_ERR "%s: request %p for device [%s] already tagged %d", __FUNCTION__, rq, @@ -1168,13 +1171,18 @@ int blk_queue_start_tag(request_queue_t *q, struct request *rq) BUG(); } - tag = find_first_zero_bit(bqt->tag_map, bqt->max_depth); - if (tag >= bqt->max_depth) - return 1; + /* + * 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; - __set_bit(tag, bqt->tag_map); + } while (test_and_set_bit(tag, bqt->tag_map)); - rq->flags |= REQ_QUEUED; + rq->cmd_flags |= REQ_QUEUED; rq->tag = tag; bqt->tag_index[tag] = rq; blkdev_dequeue_request(rq); @@ -1210,65 +1218,31 @@ 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->flags &= ~REQ_QUEUED; + rq->cmd_flags &= ~REQ_QUEUED; } else blk_queue_end_tag(q, rq); - rq->flags &= ~REQ_STARTED; + rq->cmd_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: 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("%s: dev %s: type=%x, flags=%x\n", msg, + rq->rq_disk ? rq->rq_disk->disk_name : "?", rq->cmd_type, + rq->cmd_flags); 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 (rq->flags & (REQ_BLOCK_PC | REQ_PC)) { + if (blk_pc_request(rq)) { printk("cdb: "); for (bit = 0; bit < sizeof(rq->cmd); bit++) printk("%02x ", rq->cmd[bit]); @@ -1441,7 +1415,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->flags |= REQ_NOMERGE; + req->cmd_flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; return 0; @@ -1464,7 +1438,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->flags |= REQ_NOMERGE; + req->cmd_flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; return 0; @@ -1491,7 +1465,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->flags |= REQ_NOMERGE; + req->cmd_flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; return 0; @@ -1530,7 +1504,7 @@ static int ll_front_merge_fn(request_queue_t *q, struct request *req, if (req->nr_sectors + bio_sectors(bio) > max_sectors) { - req->flags |= REQ_NOMERGE; + req->cmd_flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; return 0; @@ -1847,8 +1821,7 @@ static void blk_release_queue(struct kobject *kobj) if (q->queue_tags) __blk_queue_free_tags(q); - if (q->blk_trace) - blk_trace_shutdown(q); + blk_trace_shutdown(q); kmem_cache_free(requestq_cachep, q); } @@ -2030,14 +2003,13 @@ EXPORT_SYMBOL(blk_get_queue); static inline void blk_free_request(request_queue_t *q, struct request *rq) { - if (rq->flags & REQ_ELVPRIV) + if (rq->cmd_flags & REQ_ELVPRIV) elv_put_request(q, rq); mempool_free(rq, q->rq.rq_pool); } -static inline struct request * -blk_alloc_request(request_queue_t *q, int rw, struct bio *bio, - int priv, gfp_t gfp_mask) +static struct request * +blk_alloc_request(request_queue_t *q, int rw, int priv, gfp_t gfp_mask) { struct request *rq = mempool_alloc(q->rq.rq_pool, gfp_mask); @@ -2045,17 +2017,17 @@ blk_alloc_request(request_queue_t *q, int rw, struct bio *bio, return NULL; /* - * first three bits are identical in rq->flags and bio->bi_rw, + * first three bits are identical in rq->cmd_flags and bio->bi_rw, * see bio.h and blkdev.h */ - rq->flags = rw; + rq->cmd_flags = rw | REQ_ALLOCED; if (priv) { - if (unlikely(elv_set_request(q, rq, bio, gfp_mask))) { + if (unlikely(elv_set_request(q, rq, gfp_mask))) { mempool_free(rq, q->rq.rq_pool); return NULL; } - rq->flags |= REQ_ELVPRIV; + rq->cmd_flags |= REQ_ELVPRIV; } return rq; @@ -2142,13 +2114,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, bio); + may_queue = elv_may_queue(q, rw); 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); + ioc = current_io_context(GFP_ATOMIC, q->node); /* * The queue will fill after this allocation, so set * it as full, and mark this process as "batching". @@ -2190,7 +2162,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, bio, priv, gfp_mask); + rq = blk_alloc_request(q, rw, priv, gfp_mask); if (unlikely(!rq)) { /* * Allocation failed presumably due to memory. Undo anything @@ -2226,7 +2198,6 @@ 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: @@ -2269,7 +2240,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); + ioc = current_io_context(GFP_NOIO, q->node); ioc_set_batching(q, ioc); spin_lock_irq(q->queue_lock); @@ -2300,6 +2271,25 @@ 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 @@ -2352,7 +2342,8 @@ 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->flags |= REQ_SPECIAL | REQ_SOFTBARRIER; + rq->cmd_type = REQ_TYPE_SPECIAL; + rq->cmd_flags |= REQ_SOFTBARRIER; rq->special = data; @@ -2366,11 +2357,7 @@ 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); - - if (blk_queue_plugged(q)) - __generic_unplug_device(q); - else - q->request_fn(q); + blk_start_queueing(q); spin_unlock_irqrestore(q->queue_lock, flags); } @@ -2559,7 +2546,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->flags |= REQ_NOMERGE; + rq->cmd_flags |= REQ_NOMERGE; rq->end_io = done; WARN_ON(irqs_disabled()); spin_lock_irq(q->queue_lock); @@ -2599,10 +2586,9 @@ int blk_execute_rq(request_queue_t *q, struct gendisk *bd_disk, rq->sense_len = 0; } - rq->waiting = &wait; + rq->end_io_data = &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; @@ -2711,8 +2697,6 @@ 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)) @@ -2720,18 +2704,16 @@ 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 (rl) { + if (req->cmd_flags & REQ_ALLOCED) { int rw = rq_data_dir(req); - int priv = req->flags & REQ_ELVPRIV; + int priv = req->cmd_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); @@ -2765,9 +2747,9 @@ EXPORT_SYMBOL(blk_put_request); */ void blk_end_sync_rq(struct request *rq, int error) { - struct completion *waiting = rq->waiting; + struct completion *waiting = rq->end_io_data; - rq->waiting = NULL; + rq->end_io_data = NULL; __blk_put_request(rq->q, rq); /* @@ -2830,7 +2812,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->waiting || next->special) + || next->special) return 0; /* @@ -2891,22 +2873,24 @@ 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->flags |= REQ_CMD; + req->cmd_type = REQ_TYPE_FS; /* * inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST) */ if (bio_rw_ahead(bio) || bio_failfast(bio)) - req->flags |= REQ_FAILFAST; + req->cmd_flags |= REQ_FAILFAST; /* * REQ_BARRIER implies no merging, but lets make it explicit */ if (unlikely(bio_barrier(bio))) - req->flags |= (REQ_HARDBARRIER | REQ_NOMERGE); + req->cmd_flags |= (REQ_HARDBARRIER | REQ_NOMERGE); if (bio_sync(bio)) - req->flags |= REQ_RW_SYNC; + req->cmd_flags |= REQ_RW_SYNC; + if (bio_rw_meta(bio)) + req->cmd_flags |= REQ_RW_META; req->errors = 0; req->hard_sector = req->sector = bio->bi_sector; @@ -2915,7 +2899,6 @@ 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; @@ -2925,17 +2908,11 @@ 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, rw, nr_sectors, cur_nr_sectors, barrier, err, sync; - unsigned short prio; - sector_t sector; + int el_ret, nr_sectors, barrier, err; + const unsigned short prio = bio_prio(bio); + const int sync = bio_sync(bio); - 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 @@ -2944,8 +2921,6 @@ 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; @@ -2973,7 +2948,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); + elv_merged_request(q, req, el_ret); goto out; case ELEVATOR_FRONT_MERGE: @@ -2993,14 +2968,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 = cur_nr_sectors; - req->hard_cur_sectors = cur_nr_sectors; - req->sector = req->hard_sector = sector; + 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->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); + elv_merged_request(q, req, el_ret); goto out; /* ELV_NO_MERGE: elevator says don't/can't merge. */ @@ -3013,7 +2988,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, rw, bio); + req = get_request_wait(q, bio_data_dir(bio), bio); /* * After dropping the lock and possibly sleeping here, our request @@ -3307,7 +3282,7 @@ static int __end_that_request_first(struct request *req, int uptodate, req->errors = 0; if (!uptodate) { - if (blk_fs_request(req) && !(req->flags & REQ_QUIET)) + if (blk_fs_request(req) && !(req->cmd_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); @@ -3570,8 +3545,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->flags and bio->bi_rw */ - rq->flags |= (bio->bi_rw & 3); + /* first two bits are identical in rq->cmd_flags and bio->bi_rw */ + rq->cmd_flags |= (bio->bi_rw & 3); rq->nr_phys_segments = bio_phys_segments(q, bio); rq->nr_hw_segments = bio_hw_segments(q, bio); @@ -3659,25 +3634,22 @@ 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); } @@ -3689,7 +3661,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. */ -struct io_context *current_io_context(gfp_t gfp_flags) +static struct io_context *current_io_context(gfp_t gfp_flags, int node) { struct task_struct *tsk = current; struct io_context *ret; @@ -3698,11 +3670,11 @@ struct io_context *current_io_context(gfp_t gfp_flags) if (likely(ret)) return ret; - ret = kmem_cache_alloc(iocontext_cachep, gfp_flags); + ret = kmem_cache_alloc_node(iocontext_cachep, gfp_flags, node); if (ret) { atomic_set(&ret->refcount, 1); ret->task = current; - ret->set_ioprio = NULL; + ret->ioprio_changed = 0; ret->last_waited = jiffies; /* doesn't matter... */ ret->nr_batch_requests = 0; /* because this is 0 */ ret->aic = NULL; @@ -3722,10 +3694,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) +struct io_context *get_io_context(gfp_t gfp_flags, int node) { struct io_context *ret; - ret = current_io_context(gfp_flags); + ret = current_io_context(gfp_flags, node); if (likely(ret)) atomic_inc(&ret->refcount); return ret; @@ -3838,9 +3810,6 @@ 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 56a7c620574f..79af43179421 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(sizeof(*nd), GFP_KERNEL); + nd = kmalloc_node(sizeof(*nd), GFP_KERNEL, q->node); if (!nd) return NULL; INIT_LIST_HEAD(&nd->queue); diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index b33eda26e205..2dc326421a24 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->flags |= REQ_BLOCK_PC; + rq->cmd_type = REQ_TYPE_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->flags |= REQ_BLOCK_PC; + rq->cmd_type = REQ_TYPE_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->flags |= REQ_BLOCK_PC; + rq->cmd_type = REQ_TYPE_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 c26c08b36829..bdb9c8b78ed8 100644 --- a/trunk/drivers/acorn/char/i2c.c +++ b/trunk/drivers/acorn/char/i2c.c @@ -308,7 +308,6 @@ 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 1dda370f402b..98099de59b45 100644 --- a/trunk/drivers/acpi/acpi_memhotplug.c +++ b/trunk/drivers/acpi/acpi_memhotplug.c @@ -238,6 +238,10 @@ 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 6809c283ec58..6342e612c203 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 struct i2c_algorithm acpi_ec_smbus_algorithm = { +static const 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 507f051d1cef..20beea778ea2 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) { - (void)kmem_cache_destroy(cache); + kmem_cache_destroy(cache); return (AE_OK); } diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 71066066d626..0a395fca843b 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -38,6 +38,7 @@ #include #include #include /* need_resched() */ +#include #include #include @@ -453,7 +454,8 @@ 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) { + if (sleep_ticks > cx->promotion.threshold.ticks && + cx->promotion.state->latency <= system_latency_constraint()) { cx->promotion.count++; cx->demotion.count = 0; if (cx->promotion.count >= @@ -494,8 +496,10 @@ 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) { + if ((pr->power.state - pr->power.states) > max_cstate || + pr->power.state->latency > system_latency_constraint()) { if (cx->demotion.state) next_state = cx->demotion.state; } @@ -1009,9 +1013,11 @@ 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", + "bus master activity: %08x\n" + "maximum allowed latency: %d usec\n", pr->power.state ? pr->power.state - pr->power.states : 0, - max_cstate, (unsigned)pr->power.bm_activity); + max_cstate, (unsigned)pr->power.bm_activity, + system_latency_constraint()); seq_puts(seq, "states:\n"); @@ -1077,6 +1083,28 @@ 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) { @@ -1093,6 +1121,7 @@ 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) @@ -1164,6 +1193,7 @@ 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 99837d932f36..3f4aa0c99ee4 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 PCI && EXPERIMENTAL + depends on ISA && 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,6 +400,7 @@ 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 1d1c30a2fcd0..377425e71391 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 ffa111eea9da..5719704eb0ee 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -643,11 +643,9 @@ 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])) { - ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n"); - ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; - return 0; - } + if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) + return -ENOENT; + 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 753b0152afd1..b4abd6850367 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -5453,6 +5453,11 @@ 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 3fa80f09f2ae..02b2b2787d9b 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -1515,7 +1515,11 @@ static int ata_eh_reset(struct ata_port *ap, int classify, if (prereset) { rc = prereset(ap); if (rc) { - ata_port_printk(ap, KERN_ERR, + 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, "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 688bb55e197a..08b3a407473e 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 = 14; + probe_ent->irq = ATA_PRIMARY_IRQ; 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 = 15; + probe_ent->irq2 = ATA_SECONDARY_IRQ; else - probe_ent->irq = 15; + probe_ent->irq = ATA_SECONDARY_IRQ; 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 8448ee6e0eed..87af3b5861ab 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 3293cf9a7eb5..599ee266722c 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.3" +#define DRV_VERSION "0.2.4" /** * timing_setup - shared timing computation and load @@ -137,11 +137,8 @@ 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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no])) + return -ENOENT; pci_read_config_byte(pdev, 0x42, &ata66); if (ata66 & bitmask[ap->port_no]) @@ -167,11 +164,9 @@ 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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no])) + return -ENOENT; + /* No host side cable detection */ ap->cbl = ATA_CBL_PATA80; return ata_std_prereset(ap); @@ -262,12 +257,8 @@ 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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } - + if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no])) + return -ENOENT; pci_read_config_byte(pdev, 0x52, &ata66); if (ata66 & bitmask[ap->port_no]) @@ -368,7 +359,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, @@ -402,7 +393,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, @@ -436,7 +427,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, @@ -470,7 +461,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, @@ -504,7 +495,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, @@ -538,7 +529,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 d6ef3bf1bac7..c4ccb75a4f1d 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.1" +#define DRV_VERSION "0.4.2" /* * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we @@ -47,11 +47,9 @@ 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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no])) + return -ENOENT; + ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -90,11 +88,9 @@ 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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no])) + return -ENOENT; + pci_read_config_byte(pdev, 0x49, &tmp); if (tmp & (1 >> ap->port_no)) ap->cbl = ATA_CBL_PATA40; @@ -344,7 +340,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, @@ -379,8 +375,6 @@ 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 3f78a1e54a75..6c2269b6bd3c 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.2" +#define DRV_VERSION "0.4.3" enum { ATIIXP_IDE_PIO_TIMING = 0x40, @@ -41,11 +41,9 @@ 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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no])) + return -ENOENT; + ap->cbl = ATA_CBL_PATA80; return ata_std_prereset(ap); } @@ -244,7 +242,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 abf1bb7bd322..e92b0ef43ec5 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 792ce4828510..a6c6cebd0dae 100644 --- a/trunk/drivers/ata/pata_cs5520.c +++ b/trunk/drivers/ata/pata_cs5520.c @@ -193,8 +193,6 @@ 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 f3d8a3bc1e78..7bba4d954e9c 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 69d6b4258724..d64fcdceaf01 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 fd55474e0d15..dfa5ac539048 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 c30bc181304f..95cd1ca181f5 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.1" +#define DRV_VERSION "0.4.2" /** * efar_pre_reset - check for 40/80 pin @@ -42,11 +42,9 @@ 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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->port_no])) + return -ENOENT; + pci_read_config_byte(pdev, 0x47, &tmp); if (tmp & (2 >> ap->port_no)) ap->cbl = ATA_CBL_PATA40; @@ -263,8 +261,6 @@ 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 94bb1dfc3f19..cf656ecbe507 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 532a7928f803..10318c0012ef 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 06c8db079b91..5c5d4f6ab901 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 152770133ab1..1f084ab1ccc6 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 73948c8b7270..640b8b0954f5 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 af39097d8081..82a46ff40000 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 6832a643a9eb..be3a866b111f 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 0; + return -ENOENT; /* 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,8 +164,7 @@ static const struct ata_port_operations jmicron_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, - /* Timeout handling. Special recovery hooks here */ - .eng_timeout = ata_eng_timeout, + /* IRQ-related hooks */ .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 ad37c220bb2c..10231ef731d1 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 1958c4ed09a8..3c65393c1f01 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 thinkpad with a PCMCIA + * Thinkpad specific note: If you boot an MPIIX using a 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.1" +#define DRV_VERSION "0.7.2" enum { IDETIM = 0x6C, /* IDE control register */ @@ -54,11 +54,8 @@ 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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (!pci_test_config_bits(pdev, &mpiix_enable_bits[ap->port_no])) + return -ENOENT; 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 16cb254cb973..76eb9c90bee1 100644 --- a/trunk/drivers/ata/pata_netcell.c +++ b/trunk/drivers/ata/pata_netcell.c @@ -90,8 +90,7 @@ static const struct ata_port_operations netcell_ops = { .qc_issue = ata_qc_issue_prot, .data_xfer = ata_pio_data_xfer, - /* Timeout handling. Special recovery hooks here */ - .eng_timeout = ata_eng_timeout, + /* IRQ-related hooks */ .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 93d6646d2954..2005a95f48f6 100644 --- a/trunk/drivers/ata/pata_ns87410.c +++ b/trunk/drivers/ata/pata_ns87410.c @@ -45,11 +45,8 @@ 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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->port_no])) + return -ENOENT; ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -179,7 +176,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 04c618a2664b..31a285ca88dc 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.1" +#define DRV_VERSION "0.5.2" /** * oldpiix_pre_reset - probe begin @@ -42,11 +42,8 @@ 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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->port_no])) + return -ENOENT; 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 c3d01325e0e2..57fe21f3a975 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.4" +#define DRV_VERSION "0.2.5" enum { READ_REG = 0, /* index of Read cycle timing register */ @@ -59,11 +59,9 @@ 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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->port_no])) + return -ENOENT; + ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -229,7 +227,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 177a455f4251..7296a20cd107 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.1" +#define DRV_VERSION "0.2.2" enum { READ_REG = 0, /* index of Read cycle timing register */ @@ -59,11 +59,9 @@ 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)) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (ap->port_no && !pci_test_config_bits(pdev, &optidma_enable_bits)) + return -ENOENT; + ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -388,7 +386,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, @@ -423,7 +421,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 62b25cda409b..cb501e145a42 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 31ab9c886209..bd4ed6734edc 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-ac3" +#define DRV_VERSION "0.74-ac5" #undef PDC_DEBUG #ifdef PDC_DEBUG @@ -311,10 +311,8 @@ 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)) { - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (!pdc2027x_port_enabled(ap)) + return -ENOENT; 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 35cfdf0ac3f0..7977f471d5e9 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 277f8411b521..c20bcf43ed6d 100644 --- a/trunk/drivers/ata/pata_radisys.c +++ b/trunk/drivers/ata/pata_radisys.c @@ -255,8 +255,6 @@ 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 3c6d84fd4312..eccc6fd45032 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 4166c1a8a9e8..107e6cd3dc0d 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 af456113c55d..a5c8d7e121d1 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.6" +#define DRV_VERSION "0.3.7" #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_OSB4, PCI_ANY_ID, osb4_cable }, + { PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, 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,10 +352,12 @@ 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 @@ -385,10 +387,12 @@ 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 8f7db9638d0a..c8b2e26db70d 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 2e555168b431..17791e2785f9 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.3" +#define DRV_VERSION "0.4.4" struct sis_chipset { u16 device; /* PCI host ID */ @@ -74,11 +74,9 @@ 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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (!pci_test_config_bits(pdev, &sis_enable_bits[ap->port_no])) + return -ENOENT; + /* 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) @@ -575,8 +573,6 @@ 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, @@ -610,8 +606,6 @@ 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, @@ -646,8 +640,6 @@ 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, @@ -681,8 +673,6 @@ 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, @@ -716,8 +706,6 @@ 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 f8499786917a..5b762acc5687 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.2" +#define DRV_VERSION "0.2.3" enum { /* @@ -49,11 +49,8 @@ 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])) { - ata_port_disable(ap); - dev_printk(KERN_INFO, &pdev->dev, "port disabled. ignoring.\n"); - return 0; - } + if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no])) + return -ENOENT; ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -264,7 +261,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 36f788728f3f..a954ed93a40c 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_probe_init - probe begin + * triflex_prereset - probe begin * @ap: ATA port * * Set up cable type and use generic probe init */ -static int triflex_probe_init(struct ata_port *ap) +static int triflex_prereset(struct ata_port *ap) { static const struct pci_bits triflex_enable_bits[] = { { 0x80, 1, 0x01, 0x01 }, @@ -61,11 +61,8 @@ static int triflex_probe_init(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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no])) + return -ENOENT; ap->cbl = ATA_CBL_PATA40; return ata_std_prereset(ap); } @@ -74,7 +71,7 @@ static int triflex_probe_init(struct ata_port *ap) static void triflex_error_handler(struct ata_port *ap) { - ata_bmdma_drive_eh(ap, triflex_probe_init, ata_std_softreset, NULL, ata_std_postreset); + ata_bmdma_drive_eh(ap, triflex_prereset, ata_std_softreset, NULL, ata_std_postreset); } /** @@ -221,7 +218,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 1b2ff133b163..7b5dd2343b9a 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.13" +#define DRV_VERSION "0.1.14" /* * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx @@ -155,11 +155,8 @@ 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])) { - ata_port_disable(ap); - printk(KERN_INFO "ata%u: port disabled. ignoring.\n", ap->id); - return 0; - } + if (!pci_test_config_bits(pdev, &via_enable_bits[ap->port_no])) + return -ENOENT; } if ((config->flags & VIA_UDMA) >= VIA_UDMA_66) @@ -325,7 +322,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, @@ -360,7 +357,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 fdce6e07ecd2..c01496df4a99 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -463,6 +463,7 @@ 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 b539e5e75b56..7bbb9eeda235 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) += memory.o +obj-$(CONFIG_MEMORY_HOTPLUG_SPARSE) += memory.o obj-$(CONFIG_SMP) += topology.o obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o diff --git a/trunk/drivers/base/class.c b/trunk/drivers/base/class.c index b06b0e2b9c62..b32b77ff2dcd 100644 --- a/trunk/drivers/base/class.c +++ b/trunk/drivers/base/class.c @@ -228,7 +228,7 @@ struct class *class_create(struct module *owner, const char *name) /** * class_destroy - destroys a struct class structure - * @cs: pointer to the struct class that is to be destroyed + * @cls: 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(). @@ -658,9 +658,9 @@ int class_device_register(struct class_device *class_dev) /** * class_device_create - creates a class device and registers it with sysfs - * @cs: pointer to the struct class that this device should be registered to. + * @cls: 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. - * @dev: the dev_t for the char device to be added. + * @devt: 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 * @@ -766,7 +766,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. - * @dev: the dev_t of the device that was previously registered. + * @devt: 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() diff --git a/trunk/drivers/base/firmware_class.c b/trunk/drivers/base/firmware_class.c index 5d6c011183f5..14615694ae9a 100644 --- a/trunk/drivers/base/firmware_class.c +++ b/trunk/drivers/base/firmware_class.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "base.h" @@ -511,7 +512,6 @@ 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, }; - ret = kernel_thread(request_firmware_work_func, fw_work, - CLONE_FS | CLONE_FILES); + task = kthread_run(request_firmware_work_func, fw_work, + "firmware/%s", name); - if (ret < 0) { + if (IS_ERR(task)) { fw_work->cont(NULL, fw_work->context); module_put(fw_work->module); kfree(fw_work); - return ret; + return PTR_ERR(task); } return 0; } @@ -602,7 +602,7 @@ firmware_class_exit(void) class_unregister(&firmware_class); } -module_init(firmware_class_init); +fs_initcall(firmware_class_init); module_exit(firmware_class_exit); EXPORT_SYMBOL(release_firmware); diff --git a/trunk/drivers/block/DAC960.c b/trunk/drivers/block/DAC960.c index a360215dbce7..b3f639fbf220 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(Completion); + DECLARE_COMPLETION_ONSTACK(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->waiting; + Command->Completion = Request->end_io_data; 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 a82f37f749a5..f9217c34bc2b 100644 --- a/trunk/drivers/block/DAC960.h +++ b/trunk/drivers/block/DAC960.h @@ -71,7 +71,7 @@ Define a Boolean data type. */ -typedef enum { false, true } __attribute__ ((packed)) boolean; +typedef bool boolean; /* diff --git a/trunk/drivers/block/Kconfig b/trunk/drivers/block/Kconfig index b5382cedf0c0..422e31d5f8e5 100644 --- a/trunk/drivers/block/Kconfig +++ b/trunk/drivers/block/Kconfig @@ -2,6 +2,8 @@ # Block device driver configuration # +if BLOCK + menu "Block devices" config BLK_DEV_FD @@ -468,3 +470,5 @@ 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 2cd3391ff878..99f87efe0f58 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, 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, +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, 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(wait); + DECLARE_COMPLETION_ONSTACK(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(wait); + DECLARE_COMPLETION_ONSTACK(wait); __u32 left; __u32 sz; BYTE __user *data_ptr; @@ -1229,7 +1229,6 @@ 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; } @@ -1326,10 +1325,9 @@ 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; - unsigned int total_size; + sector_t total_size; unsigned long flags = 0; int ret = 0; @@ -1348,15 +1346,25 @@ 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, size_buff, 1, + cciss_read_capacity(ctlr, drv_index, 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]); @@ -1392,7 +1400,6 @@ static void cciss_update_drive_info(int ctlr, int drv_index) } freeret: - kfree(size_buff); kfree(inq_buff); return; mem_msg: @@ -1717,6 +1724,22 @@ 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; @@ -1750,6 +1773,7 @@ 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; @@ -1792,7 +1816,7 @@ static int sendcmd_withirq(__u8 cmd, u64bit buff_dma_handle; unsigned long flags; int return_status; - DECLARE_COMPLETION(wait); + DECLARE_COMPLETION_ONSTACK(wait); if ((c = cmd_alloc(h, 0)) == NULL) return -ENOMEM; @@ -1893,12 +1917,15 @@ static int sendcmd_withirq(__u8 cmd, } static void cciss_geometry_inquiry(int ctlr, int logvol, - int withirq, unsigned int total_size, + int withirq, sector_t 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, @@ -1917,10 +1944,10 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, drv->nr_blocks = total_size; drv->heads = 255; drv->sectors = 32; // Sectors per track - drv->cylinders = total_size / 255 / 32; + t = drv->heads * drv->sectors; + drv->cylinders = total_size; + rem = do_div(drv->cylinders, t); } else { - unsigned int t; - drv->block_size = block_size; drv->nr_blocks = total_size; drv->heads = inq_buff->data_byte[6]; @@ -1930,42 +1957,84 @@ 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 / t; + drv->cylinders = total_size; + rem = do_div(drv->cylinders, 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, ReadCapdata_struct *buf, - int withirq, unsigned int *total_size, +cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, unsigned int *block_size) { + ReadCapdata_struct *buf; int return_code; - memset(buf, 0, sizeof(*buf)); + 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)); if (withirq) return_code = sendcmd_withirq(CCISS_READ_CAPACITY, - ctlr, buf, sizeof(*buf), 1, - logvol, 0, TYPE_CMD); + ctlr, buf, sizeof(ReadCapdata_struct), + 1, logvol, 0, TYPE_CMD); else return_code = sendcmd(CCISS_READ_CAPACITY, - ctlr, buf, sizeof(*buf), 1, logvol, 0, - NULL, TYPE_CMD); + ctlr, buf, sizeof(ReadCapdata_struct), + 1, logvol, 0, NULL, TYPE_CMD); if (return_code == IO_OK) { - *total_size = - be32_to_cpu(*((__be32 *) & buf->total_size[0])) + 1; - *block_size = be32_to_cpu(*((__be32 *) & buf->block_size[0])); + *total_size = be32_to_cpu(*(__u32 *) 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= %u block_size= %d\n", + 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", *total_size, *block_size); + kfree(buf); return; } @@ -1976,8 +2045,7 @@ static int cciss_revalidate(struct gendisk *disk) int logvol; int FOUND = 0; unsigned int block_size; - unsigned int total_size; - ReadCapdata_struct *size_buff = NULL; + sector_t total_size; InquiryData_struct *inq_buff = NULL; for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { @@ -1990,27 +2058,24 @@ 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; } - - cciss_read_capacity(h->ctlr, logvol, size_buff, 1, &total_size, - &block_size); + 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_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; } @@ -2419,7 +2484,8 @@ static void do_cciss_request(request_queue_t *q) { ctlr_info_t *h = q->queuedata; CommandList_struct *c; - int start_blk, seg; + sector_t start_blk; + int seg; struct request *creq; u64bit temp64; struct scatterlist tmp_sg[MAXSGENTRIES]; @@ -2463,10 +2529,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) ? XFER_READ : XFER_WRITE; + (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; c->Request.Timeout = 0; // Don't time out c->Request.CDB[0] = - (rq_data_dir(creq) == READ) ? CCISS_READ : CCISS_WRITE; + (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; start_blk = creq->sector; #ifdef CCISS_DEBUG printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n", (int)creq->sector, @@ -2500,15 +2566,33 @@ static void do_cciss_request(request_queue_t *q) #endif /* CCISS_DEBUG */ c->Header.SGList = c->Header.SGTotal = seg; - 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; + 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; + } spin_lock_irq(q->queue_lock); @@ -2518,9 +2602,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. */ @@ -2948,31 +3032,23 @@ 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; - int total_size; + sector_t 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 */ @@ -3027,7 +3103,6 @@ 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])) @@ -3046,8 +3121,26 @@ 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 */ - cciss_read_capacity(cntl_num, i, size_buff, 0, + + /* 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, &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]); @@ -3057,7 +3150,6 @@ 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 868e0d862b0d..562235c1445a 100644 --- a/trunk/drivers/block/cciss.h +++ b/trunk/drivers/block/cciss.h @@ -76,6 +76,9 @@ 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 53fea549ba8b..4af7c4c0c7af 100644 --- a/trunk/drivers/block/cciss_cmd.h +++ b/trunk/drivers/block/cciss_cmd.h @@ -118,11 +118,34 @@ typedef struct _ReadCapdata_struct BYTE block_size[4]; // Size of blocks in bytes } ReadCapdata_struct; -// 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) +#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 // BMIC commands #define BMIC_READ 0x26 diff --git a/trunk/drivers/block/cciss_scsi.c b/trunk/drivers/block/cciss_scsi.c index 05f79d7393f7..bb15051ffbe0 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(wait); + DECLARE_COMPLETION_ONSTACK(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 78082edc14b4..4abc193314ee 100644 --- a/trunk/drivers/block/cpqarray.c +++ b/trunk/drivers/block/cpqarray.c @@ -989,7 +989,6 @@ 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 ad1d7065a1b2..629c5769d994 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 flags=%lx\n", (long)current_req->sector, - current_req->flags); + printk("sect=%ld type=%x flags=%x\n", (long)current_req->sector, + current_req->cmd_type, current_req->cmd_flags); return; } if (test_bit(0, &fdc_busy)) { diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index 7b3b94ddddcc..d6bb8da955a2 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -66,12 +66,14 @@ #include #include #include +#include #include #include #include /* for invalidate_bdev() */ #include #include #include +#include #include @@ -522,15 +524,12 @@ 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; @@ -570,14 +569,18 @@ 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 @@ -587,47 +590,21 @@ static int loop_thread(void *data) set_user_nice(current, -20); - lo->lo_state = Lo_bound; - lo->lo_pending = 1; + while (!kthread_should_stop() || lo->lo_bio) { - /* - * complete it, we are running - */ - complete(&lo->lo_done); - - for (;;) { - int pending; + wait_event_interruptible(lo->lo_event, + lo->lo_bio || kthread_should_stop()); - if (wait_for_completion_interruptible(&lo->lo_bh_done)) + if (!lo->lo_bio) 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; } @@ -662,7 +639,8 @@ 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 = mapping->host->i_blksize; + lo->lo_blocksize = S_ISBLK(mapping->host->i_mode) ? + mapping->host->i_bdev->bd_block_size : PAGE_SIZE; lo->old_gfp_mask = mapping_gfp_mask(mapping); mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); complete(&p->wait); @@ -794,7 +772,9 @@ 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 = inode->i_blksize; + lo_blocksize = S_ISBLK(inode->i_mode) ? + inode->i_bdev->bd_block_size : PAGE_SIZE; + error = 0; } else { goto out_putf; @@ -837,12 +817,26 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, set_blocksize(bdev, lo_blocksize); - error = kernel_thread(loop_thread, lo, CLONE_KERNEL); - if (error < 0) - goto out_putf; - wait_for_completion(&lo->lo_done); + 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); 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: @@ -904,12 +898,9 @@ 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); - wait_for_completion(&lo->lo_done); + kthread_stop(lo->lo_thread); lo->lo_backing_file = NULL; @@ -922,6 +913,7 @@ 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); @@ -1174,6 +1166,162 @@ 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; @@ -1201,6 +1349,9 @@ 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 }; /* @@ -1284,9 +1435,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 bdbade9a5cf5..9d1035e8d9d8 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=%lx)\n", - req->rq_disk->disk_name, req, req->flags); + dprintk(DBG_BLKDEV, "%s: request %p: dequeued (flags=%x)\n", + req->rq_disk->disk_name, req, req->cmd_type); - if (!(req->flags & REQ_CMD)) + if (!blk_fs_request(req)) 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.flags = REQ_SPECIAL; + sreq.cmd_type = REQ_TYPE_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 2403721f9db1..40a11e567970 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 (pd_req->flags & REQ_SPECIAL) { + if (blk_special_request(pd_req)) { phase = pd_special; return pd_special(); } @@ -713,20 +713,18 @@ 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(wait); + DECLARE_COMPLETION_ONSTACK(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.waiting = &wait; + rq.end_io_data = &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 451b996bba91..a6b2aa67c9b2 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(wait); + DECLARE_COMPLETION_ONSTACK(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->flags |= REQ_BLOCK_PC | REQ_HARDBARRIER; + rq->cmd_type = REQ_TYPE_BLOCK_PC; + rq->cmd_flags |= REQ_HARDBARRIER; if (cgc->quiet) - rq->flags |= REQ_QUIET; + rq->cmd_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->flags |= REQ_NOMERGE; - rq->waiting = &wait; + rq->end_io_data = &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 cc42e762396f..f2305ee792a1 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(" rq_status=%d errors=%d current_nr_sectors=%ld\n", - req->rq_status, req->errors, req->current_nr_sectors); + printk(" errors=%d current_nr_sectors=%ld\n", + 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 89e3c2f8b776..dfda796eba56 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(" rq_status=%d errors=%d current_nr_sectors=%ld\n", - CURRENT->rq_status, CURRENT->errors, CURRENT->current_nr_sectors); + printk(" errors=%d current_nr_sectors=%ld\n", + 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 d62b49fbf10c..45a8f402b07b 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, int uptodate); +static void ub_end_rq(struct request *rq, unsigned int status); 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,9 +639,15 @@ 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) || lun->changed) { + 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)) { blkdev_dequeue_request(rq); - ub_end_rq(rq, 0); + ub_end_rq(rq, SAM_STAT_CHECK_CONDITION); return 0; } @@ -693,7 +699,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) drop: ub_put_cmd(lun, cmd); - ub_end_rq(rq, 0); + ub_end_rq(rq, DID_ERROR << 16); return 0; } @@ -761,47 +767,53 @@ 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; - int uptodate; + unsigned int scsi_status; 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) - rq->errors = SAM_STAT_CHECK_CONDITION; + scsi_status = SAM_STAT_CHECK_CONDITION; else - rq->errors = DID_ERROR << 16; + scsi_status = 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, uptodate); + ub_end_rq(rq, scsi_status); blk_start_queue(lun->disk->queue); } -static void ub_end_rq(struct request *rq, int uptodate) +static void ub_end_rq(struct request *rq, unsigned int scsi_status) { + 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 e828e4cbd3e1..ebf3025721d1 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 (!(req->flags & REQ_CMD)) { + if (!blk_fs_request(req)) { end_request(req, 0); continue; } diff --git a/trunk/drivers/bluetooth/bfusb.c b/trunk/drivers/bluetooth/bfusb.c index 23f96213f4ac..efcc28ec9d9a 100644 --- a/trunk/drivers/bluetooth/bfusb.c +++ b/trunk/drivers/bluetooth/bfusb.c @@ -2,7 +2,7 @@ * * AVM BlueFRITZ! USB driver * - * Copyright (C) 2003 Marcel Holtmann + * Copyright (C) 2003-2006 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify @@ -59,7 +59,6 @@ static struct usb_device_id bfusb_table[] = { MODULE_DEVICE_TABLE(usb, bfusb_table); - #define BFUSB_MAX_BLOCK_SIZE 256 #define BFUSB_BLOCK_TIMEOUT 3000 @@ -70,7 +69,7 @@ MODULE_DEVICE_TABLE(usb, bfusb_table); #define BFUSB_MAX_BULK_TX 2 #define BFUSB_MAX_BULK_RX 2 -struct bfusb { +struct bfusb_data { struct hci_dev *hdev; unsigned long state; @@ -92,137 +91,136 @@ struct bfusb { struct sk_buff_head completed_q; }; -struct bfusb_scb { +struct bfusb_data_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 *bfusb) +static struct urb *bfusb_get_completed(struct bfusb_data *data) { struct sk_buff *skb; struct urb *urb = NULL; - BT_DBG("bfusb %p", bfusb); + BT_DBG("bfusb %p", data); - skb = skb_dequeue(&bfusb->completed_q); + skb = skb_dequeue(&data->completed_q); if (skb) { - urb = ((struct bfusb_scb *) skb->cb)->urb; + urb = ((struct bfusb_data_scb *) skb->cb)->urb; kfree_skb(skb); } return urb; } -static void bfusb_unlink_urbs(struct bfusb *bfusb) +static void bfusb_unlink_urbs(struct bfusb_data *data) { struct sk_buff *skb; struct urb *urb; - BT_DBG("bfusb %p", bfusb); + BT_DBG("bfusb %p", data); - while ((skb = skb_dequeue(&bfusb->pending_q))) { - urb = ((struct bfusb_scb *) skb->cb)->urb; + while ((skb = skb_dequeue(&data->pending_q))) { + urb = ((struct bfusb_data_scb *) skb->cb)->urb; usb_kill_urb(urb); - skb_queue_tail(&bfusb->completed_q, skb); + skb_queue_tail(&data->completed_q, skb); } - while ((urb = bfusb_get_completed(bfusb))) + while ((urb = bfusb_get_completed(data))) usb_free_urb(urb); } - -static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb) +static int bfusb_send_bulk(struct bfusb_data *data, struct sk_buff *skb) { - struct bfusb_scb *scb = (void *) skb->cb; - struct urb *urb = bfusb_get_completed(bfusb); + struct bfusb_data_scb *scb = (void *) skb->cb; + struct urb *urb = bfusb_get_completed(data); int err, pipe; - BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len); + BT_DBG("bfusb %p skb %p len %d", data, skb, skb->len); if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC))) return -ENOMEM; - pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep); + pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep); - usb_fill_bulk_urb(urb, bfusb->udev, pipe, skb->data, skb->len, + usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len, bfusb_tx_complete, skb); scb->urb = urb; - skb_queue_tail(&bfusb->pending_q, skb); + skb_queue_tail(&data->pending_q, skb); err = usb_submit_urb(urb, GFP_ATOMIC); if (err) { BT_ERR("%s bulk tx submit failed urb %p err %d", - bfusb->hdev->name, urb, err); - skb_unlink(skb, &bfusb->pending_q); + data->hdev->name, urb, err); + skb_unlink(skb, &data->pending_q); usb_free_urb(urb); } else - atomic_inc(&bfusb->pending_tx); + atomic_inc(&data->pending_tx); return err; } -static void bfusb_tx_wakeup(struct bfusb *bfusb) +static void bfusb_tx_wakeup(struct bfusb_data *data) { struct sk_buff *skb; - BT_DBG("bfusb %p", bfusb); + BT_DBG("bfusb %p", data); - if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) { - set_bit(BFUSB_TX_WAKEUP, &bfusb->state); + if (test_and_set_bit(BFUSB_TX_PROCESS, &data->state)) { + set_bit(BFUSB_TX_WAKEUP, &data->state); return; } do { - clear_bit(BFUSB_TX_WAKEUP, &bfusb->state); + clear_bit(BFUSB_TX_WAKEUP, &data->state); - 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); + 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); break; } } - } while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state)); + } while (test_bit(BFUSB_TX_WAKEUP, &data->state)); - clear_bit(BFUSB_TX_PROCESS, &bfusb->state); + clear_bit(BFUSB_TX_PROCESS, &data->state); } static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs) { struct sk_buff *skb = (struct sk_buff *) urb->context; - struct bfusb *bfusb = (struct bfusb *) skb->dev; + struct bfusb_data *data = (struct bfusb_data *) skb->dev; - BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len); + BT_DBG("bfusb %p urb %p skb %p len %d", data, urb, skb, skb->len); - atomic_dec(&bfusb->pending_tx); + atomic_dec(&data->pending_tx); - if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags)) + if (!test_bit(HCI_RUNNING, &data->hdev->flags)) return; if (!urb->status) - bfusb->hdev->stat.byte_tx += skb->len; + data->hdev->stat.byte_tx += skb->len; else - bfusb->hdev->stat.err_tx++; + data->hdev->stat.err_tx++; - read_lock(&bfusb->lock); + read_lock(&data->lock); - skb_unlink(skb, &bfusb->pending_q); - skb_queue_tail(&bfusb->completed_q, skb); + skb_unlink(skb, &data->pending_q); + skb_queue_tail(&data->completed_q, skb); - bfusb_tx_wakeup(bfusb); + bfusb_tx_wakeup(data); - read_unlock(&bfusb->lock); + read_unlock(&data->lock); } -static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb) +static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb) { - struct bfusb_scb *scb; + struct bfusb_data_scb *scb; struct sk_buff *skb; int err, pipe, size = HCI_MAX_FRAME_SIZE + 32; @@ -231,28 +229,29 @@ static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb) if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC))) return -ENOMEM; - if (!(skb = bt_skb_alloc(size, GFP_ATOMIC))) { + skb = bt_skb_alloc(size, GFP_ATOMIC); + if (!skb) { usb_free_urb(urb); return -ENOMEM; } - skb->dev = (void *) bfusb; + skb->dev = (void *) data; - scb = (struct bfusb_scb *) skb->cb; + scb = (struct bfusb_data_scb *) skb->cb; scb->urb = urb; - pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep); + pipe = usb_rcvbulkpipe(data->udev, data->bulk_in_ep); - usb_fill_bulk_urb(urb, bfusb->udev, pipe, skb->data, size, + usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, size, bfusb_rx_complete, skb); - skb_queue_tail(&bfusb->pending_q, skb); + skb_queue_tail(&data->pending_q, skb); err = usb_submit_urb(urb, GFP_ATOMIC); if (err) { BT_ERR("%s bulk rx submit failed urb %p err %d", - bfusb->hdev->name, urb, err); - skb_unlink(skb, &bfusb->pending_q); + data->hdev->name, urb, err); + skb_unlink(skb, &data->pending_q); kfree_skb(skb); usb_free_urb(urb); } @@ -260,15 +259,15 @@ static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb) return err; } -static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len) +static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned char *buf, int len) { - BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len); + BT_DBG("bfusb %p hdr 0x%02x data %p len %d", data, hdr, buf, len); if (hdr & 0x10) { - BT_ERR("%s error in block", bfusb->hdev->name); - if (bfusb->reassembly) - kfree_skb(bfusb->reassembly); - bfusb->reassembly = NULL; + BT_ERR("%s error in block", data->hdev->name); + if (data->reassembly) + kfree_skb(data->reassembly); + data->reassembly = NULL; return -EIO; } @@ -277,46 +276,46 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char * unsigned char pkt_type; int pkt_len = 0; - if (bfusb->reassembly) { - BT_ERR("%s unexpected start block", bfusb->hdev->name); - kfree_skb(bfusb->reassembly); - bfusb->reassembly = NULL; + if (data->reassembly) { + BT_ERR("%s unexpected start block", data->hdev->name); + kfree_skb(data->reassembly); + data->reassembly = NULL; } if (len < 1) { - BT_ERR("%s no packet type found", bfusb->hdev->name); + BT_ERR("%s no packet type found", data->hdev->name); return -EPROTO; } - pkt_type = *data++; len--; + pkt_type = *buf++; len--; switch (pkt_type) { case HCI_EVENT_PKT: if (len >= HCI_EVENT_HDR_SIZE) { - struct hci_event_hdr *hdr = (struct hci_event_hdr *) data; + struct hci_event_hdr *hdr = (struct hci_event_hdr *) buf; pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen; } else { - BT_ERR("%s event block is too short", bfusb->hdev->name); + BT_ERR("%s event block is too short", data->hdev->name); return -EILSEQ; } break; case HCI_ACLDATA_PKT: if (len >= HCI_ACL_HDR_SIZE) { - struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) data; + struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) buf; pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen); } else { - BT_ERR("%s data block is too short", bfusb->hdev->name); + BT_ERR("%s data block is too short", data->hdev->name); return -EILSEQ; } break; case HCI_SCODATA_PKT: if (len >= HCI_SCO_HDR_SIZE) { - struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) data; + struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) buf; pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen; } else { - BT_ERR("%s audio block is too short", bfusb->hdev->name); + BT_ERR("%s audio block is too short", data->hdev->name); return -EILSEQ; } break; @@ -324,27 +323,27 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char * skb = bt_skb_alloc(pkt_len, GFP_ATOMIC); if (!skb) { - BT_ERR("%s no memory for the packet", bfusb->hdev->name); + BT_ERR("%s no memory for the packet", data->hdev->name); return -ENOMEM; } - skb->dev = (void *) bfusb->hdev; + skb->dev = (void *) data->hdev; bt_cb(skb)->pkt_type = pkt_type; - bfusb->reassembly = skb; + data->reassembly = skb; } else { - if (!bfusb->reassembly) { - BT_ERR("%s unexpected continuation block", bfusb->hdev->name); + if (!data->reassembly) { + BT_ERR("%s unexpected continuation block", data->hdev->name); return -EIO; } } if (len > 0) - memcpy(skb_put(bfusb->reassembly, len), data, len); + memcpy(skb_put(data->reassembly, len), buf, len); if (hdr & 0x08) { - hci_recv_frame(bfusb->reassembly); - bfusb->reassembly = NULL; + hci_recv_frame(data->reassembly); + data->reassembly = NULL; } return 0; @@ -353,22 +352,22 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char * static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs) { struct sk_buff *skb = (struct sk_buff *) urb->context; - struct bfusb *bfusb = (struct bfusb *) skb->dev; + struct bfusb_data *data = (struct bfusb_data *) 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(&bfusb->lock); + read_lock(&data->lock); - if (!test_bit(HCI_RUNNING, &bfusb->hdev->flags)) + if (!test_bit(HCI_RUNNING, &data->hdev->flags)) goto unlock; if (urb->status || !count) goto resubmit; - bfusb->hdev->stat.byte_rx += count; + data->hdev->stat.byte_rx += count; skb_put(skb, count); @@ -387,90 +386,89 @@ static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs) if (count < len) { BT_ERR("%s block extends over URB buffer ranges", - bfusb->hdev->name); + data->hdev->name); } if ((hdr & 0xe1) == 0xc1) - bfusb_recv_block(bfusb, hdr, buf, len); + bfusb_recv_block(data, hdr, buf, len); count -= len; buf += len; } - skb_unlink(skb, &bfusb->pending_q); + skb_unlink(skb, &data->pending_q); kfree_skb(skb); - bfusb_rx_submit(bfusb, urb); + bfusb_rx_submit(data, urb); - read_unlock(&bfusb->lock); + read_unlock(&data->lock); return; resubmit: - urb->dev = bfusb->udev; + urb->dev = data->udev; err = usb_submit_urb(urb, GFP_ATOMIC); if (err) { BT_ERR("%s bulk resubmit failed urb %p err %d", - bfusb->hdev->name, urb, err); + data->hdev->name, urb, err); } unlock: - read_unlock(&bfusb->lock); + read_unlock(&data->lock); } - static int bfusb_open(struct hci_dev *hdev) { - struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; + struct bfusb_data *data = hdev->driver_data; unsigned long flags; int i, err; - BT_DBG("hdev %p bfusb %p", hdev, bfusb); + BT_DBG("hdev %p bfusb %p", hdev, data); if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) return 0; - write_lock_irqsave(&bfusb->lock, flags); + write_lock_irqsave(&data->lock, flags); - err = bfusb_rx_submit(bfusb, NULL); + err = bfusb_rx_submit(data, NULL); if (!err) { for (i = 1; i < BFUSB_MAX_BULK_RX; i++) - bfusb_rx_submit(bfusb, NULL); + bfusb_rx_submit(data, NULL); } else { clear_bit(HCI_RUNNING, &hdev->flags); } - write_unlock_irqrestore(&bfusb->lock, flags); + write_unlock_irqrestore(&data->lock, flags); return err; } static int bfusb_flush(struct hci_dev *hdev) { - struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; + struct bfusb_data *data = hdev->driver_data; - BT_DBG("hdev %p bfusb %p", hdev, bfusb); + BT_DBG("hdev %p bfusb %p", hdev, data); - skb_queue_purge(&bfusb->transmit_q); + skb_queue_purge(&data->transmit_q); return 0; } static int bfusb_close(struct hci_dev *hdev) { - struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; + struct bfusb_data *data = hdev->driver_data; unsigned long flags; - BT_DBG("hdev %p bfusb %p", hdev, bfusb); + BT_DBG("hdev %p bfusb %p", hdev, data); if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; - write_lock_irqsave(&bfusb->lock, flags); - write_unlock_irqrestore(&bfusb->lock, flags); + write_lock_irqsave(&data->lock, flags); + write_unlock_irqrestore(&data->lock, flags); - bfusb_unlink_urbs(bfusb); + bfusb_unlink_urbs(data); bfusb_flush(hdev); return 0; @@ -479,7 +477,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 *bfusb; + struct bfusb_data *data; struct sk_buff *nskb; unsigned char buf[3]; int sent = 0, size, count; @@ -494,7 +492,7 @@ static int bfusb_send_frame(struct sk_buff *skb) if (!test_bit(HCI_RUNNING, &hdev->flags)) return -EBUSY; - bfusb = (struct bfusb *) hdev->driver_data; + data = hdev->driver_data; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: @@ -514,12 +512,13 @@ static int bfusb_send_frame(struct sk_buff *skb) count = skb->len; /* Max HCI frame size seems to be 1511 + 1 */ - if (!(nskb = bt_skb_alloc(count + 32, GFP_ATOMIC))) { + nskb = bt_skb_alloc(count + 32, GFP_ATOMIC); + if (!nskb) { BT_ERR("Can't allocate memory for new packet"); return -ENOMEM; } - nskb->dev = (void *) bfusb; + nskb->dev = (void *) data; while (count) { size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE); @@ -536,18 +535,18 @@ static int bfusb_send_frame(struct sk_buff *skb) } /* Don't send frame with multiple size of bulk max packet */ - if ((nskb->len % bfusb->bulk_pkt_size) == 0) { + if ((nskb->len % data->bulk_pkt_size) == 0) { buf[0] = 0xdd; buf[1] = 0x00; memcpy(skb_put(nskb, 2), buf, 2); } - read_lock(&bfusb->lock); + read_lock(&data->lock); - skb_queue_tail(&bfusb->transmit_q, nskb); - bfusb_tx_wakeup(bfusb); + skb_queue_tail(&data->transmit_q, nskb); + bfusb_tx_wakeup(data); - read_unlock(&bfusb->lock); + read_unlock(&data->lock); kfree_skb(skb); @@ -556,11 +555,11 @@ static int bfusb_send_frame(struct sk_buff *skb) static void bfusb_destruct(struct hci_dev *hdev) { - struct bfusb *bfusb = (struct bfusb *) hdev->driver_data; + struct bfusb_data *data = hdev->driver_data; - BT_DBG("hdev %p bfusb %p", hdev, bfusb); + BT_DBG("hdev %p bfusb %p", hdev, data); - kfree(bfusb); + kfree(data); } static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg) @@ -568,25 +567,24 @@ static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg return -ENOIOCTLCMD; } - -static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count) +static int bfusb_load_firmware(struct bfusb_data *data, unsigned char *firmware, int count) { unsigned char *buf; int err, pipe, len, size, sent = 0; - BT_DBG("bfusb %p udev %p", bfusb, bfusb->udev); + BT_DBG("bfusb %p udev %p", data, data->udev); BT_INFO("BlueFRITZ! USB loading firmware"); - pipe = usb_sndctrlpipe(bfusb->udev, 0); + pipe = usb_sndctrlpipe(data->udev, 0); - if (usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION, + if (usb_control_msg(data->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; } - bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0; + data->udev->toggle[0] = data->udev->toggle[1] = 0; buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC); if (!buf) { @@ -594,14 +592,14 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int return -ENOMEM; } - pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep); + pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep); while (count) { size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3); memcpy(buf, firmware + sent, size); - err = usb_bulk_msg(bfusb->udev, pipe, buf, size, + err = usb_bulk_msg(data->udev, pipe, buf, size, &len, BFUSB_BLOCK_TIMEOUT); if (err || (len != size)) { @@ -613,21 +611,23 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count -= size; } - if ((err = usb_bulk_msg(bfusb->udev, pipe, NULL, 0, - &len, BFUSB_BLOCK_TIMEOUT)) < 0) { + err = usb_bulk_msg(data->udev, pipe, NULL, 0, + &len, BFUSB_BLOCK_TIMEOUT); + if (err < 0) { BT_ERR("Error in null packet request"); goto error; } - pipe = usb_sndctrlpipe(bfusb->udev, 0); + pipe = usb_sndctrlpipe(data->udev, 0); - if ((err = usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION, - 0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT)) < 0) { + err = usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION, + 0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT); + if (err < 0) { BT_ERR("Can't change to running configuration"); goto error; } - bfusb->udev->toggle[0] = bfusb->udev->toggle[1] = 0; + data->udev->toggle[0] = data->udev->toggle[1] = 0; BT_INFO("BlueFRITZ! USB device ready"); @@ -637,9 +637,9 @@ static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int error: kfree(buf); - pipe = usb_sndctrlpipe(bfusb->udev, 0); + pipe = usb_sndctrlpipe(data->udev, 0); - usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION, + usb_control_msg(data->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 *bfusb; + struct bfusb_data *data; BT_DBG("intf %p id %p", intf, id); @@ -672,23 +672,24 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i } /* Initialize control structure and load firmware */ - if (!(bfusb = kzalloc(sizeof(struct bfusb), GFP_KERNEL))) { + data = kzalloc(sizeof(struct bfusb_data), GFP_KERNEL); + if (!data) { BT_ERR("Can't allocate memory for control structure"); goto done; } - 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); + 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); - rwlock_init(&bfusb->lock); + rwlock_init(&data->lock); - bfusb->reassembly = NULL; + data->reassembly = NULL; - skb_queue_head_init(&bfusb->transmit_q); - skb_queue_head_init(&bfusb->pending_q); - skb_queue_head_init(&bfusb->completed_q); + skb_queue_head_init(&data->transmit_q); + skb_queue_head_init(&data->pending_q); + skb_queue_head_init(&data->completed_q); if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) { BT_ERR("Firmware request failed"); @@ -697,7 +698,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(bfusb, firmware->data, firmware->size) < 0) { + if (bfusb_load_firmware(data, firmware->data, firmware->size) < 0) { BT_ERR("Firmware loading failed"); goto release; } @@ -711,10 +712,10 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i goto error; } - bfusb->hdev = hdev; + data->hdev = hdev; hdev->type = HCI_USB; - hdev->driver_data = bfusb; + hdev->driver_data = data; SET_HCIDEV_DEV(hdev, &intf->dev); hdev->open = bfusb_open; @@ -732,7 +733,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i goto error; } - usb_set_intfdata(intf, bfusb); + usb_set_intfdata(intf, data); return 0; @@ -740,7 +741,7 @@ static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *i release_firmware(firmware); error: - kfree(bfusb); + kfree(data); done: return -EIO; @@ -748,8 +749,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 *bfusb = usb_get_intfdata(intf); - struct hci_dev *hdev = bfusb->hdev; + struct bfusb_data *data = usb_get_intfdata(intf); + struct hci_dev *hdev = data->hdev; BT_DBG("intf %p", intf); @@ -779,7 +780,8 @@ static int __init bfusb_init(void) BT_INFO("BlueFRITZ! USB driver ver %s", VERSION); - if ((err = usb_register(&bfusb_driver)) < 0) + err = usb_register(&bfusb_driver); + if (err < 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 93ba25b7ea32..420b645c4c9f 100644 --- a/trunk/drivers/bluetooth/hci_ldisc.c +++ b/trunk/drivers/bluetooth/hci_ldisc.c @@ -241,15 +241,11 @@ 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); - - hu = (struct hci_uart *) hdev->driver_data; - kfree(hu); + kfree(hdev->driver_data); } /* ------ LDISC part ------ */ @@ -272,7 +268,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 controll structure"); + BT_ERR("Can't allocate control structure"); return -ENFILE; } @@ -360,7 +356,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; @@ -375,7 +371,8 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char 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 e2d4beac7420..0801af4ad2b9 100644 --- a/trunk/drivers/bluetooth/hci_usb.c +++ b/trunk/drivers/bluetooth/hci_usb.c @@ -96,6 +96,9 @@ 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 aac67a3a6019..a278d98a9151 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-2005 Marcel Holtmann + * Copyright (C) 2000-2001 Qualcomm Incorporated + * Copyright (C) 2002-2003 Maxim Krasnyansky + * Copyright (C) 2004-2006 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 *vhci = hdev->driver_data; + struct vhci_data *data = hdev->driver_data; if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; - skb_queue_purge(&vhci->readq); + skb_queue_purge(&data->readq); return 0; } static int vhci_flush(struct hci_dev *hdev) { - struct vhci_data *vhci = hdev->driver_data; + struct vhci_data *data = hdev->driver_data; - skb_queue_purge(&vhci->readq); + skb_queue_purge(&data->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 *vhci; + struct vhci_data *data; 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; - vhci = hdev->driver_data; + data = hdev->driver_data; memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1); - skb_queue_tail(&vhci->readq, skb); + skb_queue_tail(&data->readq, skb); - if (vhci->flags & VHCI_FASYNC) - kill_fasync(&vhci->fasync, SIGIO, POLL_IN); + if (data->flags & VHCI_FASYNC) + kill_fasync(&data->fasync, SIGIO, POLL_IN); - wake_up_interruptible(&vhci->read_wait); + wake_up_interruptible(&data->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 *vhci, +static inline ssize_t vhci_get_user(struct vhci_data *data, 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 *vhci, return -EFAULT; } - skb->dev = (void *) vhci->hdev; + skb->dev = (void *) data->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 *vhci, return count; } -static inline ssize_t vhci_put_user(struct vhci_data *vhci, +static inline ssize_t vhci_put_user(struct vhci_data *data, struct sk_buff *skb, char __user *buf, int count) { char __user *ptr = buf; @@ -161,42 +161,43 @@ static inline ssize_t vhci_put_user(struct vhci_data *vhci, total += len; - vhci->hdev->stat.byte_tx += len; + data->hdev->stat.byte_tx += len; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: - vhci->hdev->stat.cmd_tx++; + data->hdev->stat.cmd_tx++; break; case HCI_ACLDATA_PKT: - vhci->hdev->stat.acl_tx++; + data->hdev->stat.acl_tx++; break; case HCI_SCODATA_PKT: - vhci->hdev->stat.cmd_tx++; + data->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 *vhci = file->private_data; + struct vhci_data *data = file->private_data; struct sk_buff *skb; ssize_t ret = 0; - add_wait_queue(&vhci->read_wait, &wait); + add_wait_queue(&data->read_wait, &wait); while (count) { set_current_state(TASK_INTERRUPTIBLE); - skb = skb_dequeue(&vhci->readq); + skb = skb_dequeue(&data->readq); if (!skb) { if (file->f_flags & O_NONBLOCK) { ret = -EAGAIN; @@ -213,7 +214,7 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo } if (access_ok(VERIFY_WRITE, buf, count)) - ret = vhci_put_user(vhci, skb, buf, count); + ret = vhci_put_user(data, skb, buf, count); else ret = -EFAULT; @@ -221,7 +222,7 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo break; } set_current_state(TASK_RUNNING); - remove_wait_queue(&vhci->read_wait, &wait); + remove_wait_queue(&data->read_wait, &wait); return ret; } @@ -229,21 +230,21 @@ static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, lo static ssize_t vhci_write(struct file *file, const char __user *buf, size_t count, loff_t *pos) { - struct vhci_data *vhci = file->private_data; + struct vhci_data *data = file->private_data; if (!access_ok(VERIFY_READ, buf, count)) return -EFAULT; - return vhci_get_user(vhci, buf, count); + return vhci_get_user(data, buf, count); } static unsigned int vhci_poll(struct file *file, poll_table *wait) { - struct vhci_data *vhci = file->private_data; + struct vhci_data *data = file->private_data; - poll_wait(file, &vhci->read_wait, wait); + poll_wait(file, &data->read_wait, wait); - if (!skb_queue_empty(&vhci->readq)) + if (!skb_queue_empty(&data->readq)) return POLLIN | POLLRDNORM; return POLLOUT | POLLWRNORM; @@ -257,26 +258,26 @@ static int vhci_ioctl(struct inode *inode, struct file *file, static int vhci_open(struct inode *inode, struct file *file) { - struct vhci_data *vhci; + struct vhci_data *data; struct hci_dev *hdev; - vhci = kzalloc(sizeof(struct vhci_data), GFP_KERNEL); - if (!vhci) + data = kzalloc(sizeof(struct vhci_data), GFP_KERNEL); + if (!data) return -ENOMEM; - skb_queue_head_init(&vhci->readq); - init_waitqueue_head(&vhci->read_wait); + skb_queue_head_init(&data->readq); + init_waitqueue_head(&data->read_wait); hdev = hci_alloc_dev(); if (!hdev) { - kfree(vhci); + kfree(data); return -ENOMEM; } - vhci->hdev = hdev; + data->hdev = hdev; - hdev->type = HCI_VHCI; - hdev->driver_data = vhci; + hdev->type = HCI_VIRTUAL; + hdev->driver_data = data; hdev->open = vhci_open_dev; hdev->close = vhci_close_dev; @@ -288,20 +289,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(vhci); + kfree(data); hci_free_dev(hdev); return -EBUSY; } - file->private_data = vhci; + file->private_data = data; return nonseekable_open(inode, file); } static int vhci_release(struct inode *inode, struct file *file) { - struct vhci_data *vhci = file->private_data; - struct hci_dev *hdev = vhci->hdev; + struct vhci_data *data = file->private_data; + struct hci_dev *hdev = data->hdev; if (hci_unregister_dev(hdev) < 0) { BT_ERR("Can't unregister HCI device %s", hdev->name); @@ -316,17 +317,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 *vhci = file->private_data; + struct vhci_data *data = file->private_data; int err; - err = fasync_helper(fd, file, on, &vhci->fasync); + err = fasync_helper(fd, file, on, &data->fasync); if (err < 0) return err; if (on) - vhci->flags |= VHCI_FASYNC; + data->flags |= VHCI_FASYNC; else - vhci->flags &= ~VHCI_FASYNC; + data->flags &= ~VHCI_FASYNC; return 0; } diff --git a/trunk/drivers/cdrom/Kconfig b/trunk/drivers/cdrom/Kconfig index ff5652d40619..4b12e9031fb3 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 + depends on ISA && BLOCK 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 d239cf8b20bd..b38c84a7a8e3 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->flags |= REQ_BLOCK_PC; + rq->cmd_type = REQ_TYPE_BLOCK_PC; rq->timeout = 60 * HZ; bio = rq->bio; diff --git a/trunk/drivers/cdrom/cdu31a.c b/trunk/drivers/cdrom/cdu31a.c index 37bdb0163f0d..ccd91c1a84bd 100644 --- a/trunk/drivers/cdrom/cdu31a.c +++ b/trunk/drivers/cdrom/cdu31a.c @@ -1338,8 +1338,10 @@ static void do_cdu31a_request(request_queue_t * q) } /* WTF??? */ - if (!(req->flags & REQ_CMD)) + if (!blk_fs_request(req)) { + end_request(req, 0); 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 52ea94b891f5..bde1c665d9f4 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -439,6 +439,14 @@ 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 @@ -739,7 +747,7 @@ config NVRAM config RTC tristate "Enhanced Real Time Clock Support" - depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM + depends on !PPC && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV && !ARM && !SUPERH ---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 @@ -823,14 +831,6 @@ 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,6 +1006,7 @@ 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 8c6dfc621520..19114df59bbd 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -47,6 +47,7 @@ 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 @@ -68,7 +69,6 @@ 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/drm/Kconfig b/trunk/drivers/char/drm/Kconfig index 5278c388d3e7..ef833a1c27eb 100644 --- a/trunk/drivers/char/drm/Kconfig +++ b/trunk/drivers/char/drm/Kconfig @@ -60,7 +60,9 @@ 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 will eventually be replaced by the i915 one. + 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. config DRM_I915 tristate "i915 driver" @@ -68,8 +70,9 @@ 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 will eventually replace the I830 driver, when - later release of X start to use the new DDX and DRI. + 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. endchoice diff --git a/trunk/drivers/char/drm/Makefile b/trunk/drivers/char/drm/Makefile index 9d180c42816c..3ad0f648c6b2 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_sysfs.o drm_hashtab.o drm_sman.o drm_mm.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_ds.o sis_mm.o +sis-objs := sis_drv.o sis_mm.o savage-objs := savage_drv.o savage_bci.o savage_state.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 +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 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 d2a56182bc35..7690a59ace04 100644 --- a/trunk/drivers/char/drm/drmP.h +++ b/trunk/drivers/char/drm/drmP.h @@ -79,6 +79,7 @@ #define __OS_HAS_MTRR (defined(CONFIG_MTRR)) #include "drm_os_linux.h" +#include "drm_hashtab.h" /***********************************************************************/ /** \name DRM template customization defaults */ @@ -104,7 +105,7 @@ #define DRM_DEBUG_CODE 2 /**< Include debugging code if > 1, then also include looping detection. */ -#define DRM_HASH_SIZE 16 /**< Size of key hash table. Must be power of 2. */ +#define DRM_MAGIC_HASH_ORDER 4 /**< 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 @@ -134,19 +135,12 @@ #define DRM_MEM_CTXBITMAP 18 #define DRM_MEM_STUB 19 #define DRM_MEM_SGLISTS 20 -#define DRM_MEM_CTXLIST 21 +#define DRM_MEM_CTXLIST 21 +#define DRM_MEM_MM 22 +#define DRM_MEM_HASHTAB 23 #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) - -/*@}*/ - -/***********************************************************************/ -/** \name Backward compatibility section */ -/*@{*/ - -#define DRM_RPR_ARG(vma) vma, - -#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT) +#define DRM_MAP_HASH_OFFSET 0x10000000 /*@}*/ @@ -211,8 +205,6 @@ /*@{*/ #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)) @@ -286,7 +278,8 @@ typedef struct drm_devstate { } drm_devstate_t; typedef struct drm_magic_entry { - drm_magic_t magic; + drm_hash_item_t hash_item; + struct list_head head; struct drm_file *priv; struct drm_magic_entry *next; } drm_magic_entry_t; @@ -493,6 +486,7 @@ 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; @@ -527,6 +521,22 @@ 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 @@ -646,13 +656,15 @@ typedef struct drm_device { /*@{ */ drm_file_t *file_first; /**< file list head */ drm_file_t *file_last; /**< file list tail */ - drm_magic_head_t magiclist[DRM_HASH_SIZE]; /**< magic hash table */ + drm_open_hash_t magiclist; /**< magic hash table */ + struct list_head magicfree; /*@} */ /** \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 */ /*@{ */ @@ -711,10 +723,8 @@ typedef struct drm_device { drm_agp_head_t *agp; /**< AGP data */ struct pci_dev *pdev; /**< PCI device structure */ - 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 */ + int pci_vendor; /**< PCI vendor id */ + int pci_device; /**< PCI device id */ #ifdef __alpha__ struct pci_controller *hose; #endif @@ -736,6 +746,12 @@ 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) { @@ -1011,6 +1027,18 @@ 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 2a37586a7ee8..c7b19d35bcd6 100644 --- a/trunk/drivers/char/drm/drm_auth.c +++ b/trunk/drivers/char/drm/drm_auth.c @@ -35,20 +35,6 @@ #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. * @@ -63,14 +49,12 @@ 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; - int hash = drm_hash_magic(magic); + drm_hash_item_t *hash; mutex_lock(&dev->struct_mutex); - for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { - if (pt->magic == magic) { - retval = pt->priv; - break; - } + 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; } mutex_unlock(&dev->struct_mutex); return retval; @@ -90,28 +74,20 @@ 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); - 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; - } + drm_ht_insert_item(&dev->magiclist, &entry->hash_item); + list_add_tail(&entry->head, &dev->magicfree); mutex_unlock(&dev->struct_mutex); return 0; @@ -128,34 +104,24 @@ 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; - int hash; + drm_hash_item_t *hash; DRM_DEBUG("%d\n", magic); - hash = drm_hash_magic(magic); mutex_lock(&dev->struct_mutex); - 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; - } + if (drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) { + mutex_unlock(&dev->struct_mutex); + return -EINVAL; } + 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 -EINVAL; + return 0; } /** diff --git a/trunk/drivers/char/drm/drm_bufs.c b/trunk/drivers/char/drm/drm_bufs.c index 006b06d29727..029baea33b62 100644 --- a/trunk/drivers/char/drm/drm_bufs.c +++ b/trunk/drivers/char/drm/drm_bufs.c @@ -65,43 +65,29 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, return NULL; } -/* - * 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) +static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash, + unsigned long user_token, int hashed_handle) { - 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; + 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 - hash += PAGE_SIZE; - map32_handle += PAGE_SIZE; + if (!use_hashed_handle) { + int ret; + hash->key = user_token; + ret = drm_ht_insert_item(&dev->map_hash, hash); + if (ret != -EINVAL) + return ret; } + 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. @@ -123,6 +109,8 @@ 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) @@ -257,11 +245,20 @@ 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 */ - list->user_token = HandleID(map->type == _DRM_SHM - ? (unsigned long)map->handle - : map->offset, dev); + 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; mutex_unlock(&dev->struct_mutex); *maplist = list; @@ -346,6 +343,7 @@ 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; } @@ -441,8 +439,10 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, return -EINVAL; } - if (!map) + if (!map) { + mutex_unlock(&dev->struct_mutex); 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 3c0b882a8e72..b366c5b1bd16 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 DRM_ARRAY_SIZE( drm_ioctls ) +#define DRIVER_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) /** * Take down the DRM device. @@ -155,12 +155,13 @@ int drm_lastclose(drm_device_t * dev) del_timer(&dev->timer); /* Clear pid list */ - for (i = 0; i < DRM_HASH_SIZE; i++) { - for (pt = dev->magiclist[i].head; pt; pt = next) { - next = pt->next; + 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); drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); } - dev->magiclist[i].head = dev->magiclist[i].tail = NULL; + drm_ht_remove(&dev->magiclist); } /* Clear AGP information */ @@ -299,6 +300,7 @@ 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 b7f7951c4587..898f47dafec0 100644 --- a/trunk/drivers/char/drm/drm_fops.c +++ b/trunk/drivers/char/drm/drm_fops.c @@ -53,6 +53,8 @@ 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) @@ -69,13 +71,11 @@ static int drm_setup(drm_device_t * dev) return i; } - for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++) + for (i = 0; i < ARRAY_SIZE(dev->counts); i++) atomic_set(&dev->counts[i], 0); - for (i = 0; i < DRM_HASH_SIZE; i++) { - dev->magiclist[i].head = NULL; - dev->magiclist[i].tail = NULL; - } + drm_ht_create(&dev->magiclist, DRM_MAGIC_HASH_ORDER); + INIT_LIST_HEAD(&dev->magicfree); 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 new file mode 100644 index 000000000000..a0b2d6802ae4 --- /dev/null +++ b/trunk/drivers/char/drm/drm_hashtab.c @@ -0,0 +1,190 @@ +/************************************************************************** + * + * 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 new file mode 100644 index 000000000000..40afec05bff8 --- /dev/null +++ b/trunk/drivers/char/drm/drm_hashtab.h @@ -0,0 +1,67 @@ +/************************************************************************** + * + * 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 e9e2db18952d..d4f874520082 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 >= DRM_ARRAY_SIZE(drm_compat_ioctls)) + if (nr >= 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 555f323b8a32..565895547d75 100644 --- a/trunk/drivers/char/drm/drm_ioctl.c +++ b/trunk/drivers/char/drm/drm_ioctl.c @@ -127,9 +127,10 @@ int drm_setunique(struct inode *inode, struct file *filp, domain = bus >> 8; bus &= 0xff; - if ((domain != dev->pci_domain) || - (bus != dev->pci_bus) || - (slot != dev->pci_slot) || (func != dev->pci_func)) + if ((domain != drm_get_pci_domain(dev)) || + (bus != dev->pdev->bus->number) || + (slot != PCI_SLOT(dev->pdev->devfn)) || + (func != PCI_FUNC(dev->pdev->devfn))) return -EINVAL; return 0; @@ -140,15 +141,17 @@ static int drm_set_busid(drm_device_t * dev) int len; if (dev->unique != NULL) - return EBUSY; + return 0; 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", - dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func); + drm_get_pci_domain(dev), dev->pdev->bus->number, + PCI_SLOT(dev->pdev->devfn), + PCI_FUNC(dev->pdev->devfn)); if (len > dev->unique_len) DRM_ERROR("Unique buffer overflowed\n"); @@ -157,7 +160,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); @@ -330,27 +333,32 @@ 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; - DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv)); + if (copy_from_user(&sv, argp, sizeof(sv))) + return -EFAULT; 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; - DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv)); + if (copy_to_user(argp, &retv, sizeof(retv))) + return -EFAULT; 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 = DRM_MAX(if_version, dev->if_version); + dev->if_version = max(if_version, dev->if_version); if (sv.drm_di_minor >= 1) { /* * Version 1.1 includes tying of DRM to specific device */ - drm_set_busid(dev); + ret = drm_set_busid(dev); + if (ret) + return ret; } } @@ -358,7 +366,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 ebdb7182c4fd..4553a3a1e496 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) != dev->pci_domain || - (p.busnum & 0xff) != dev->pci_bus || - p.devnum != dev->pci_slot || p.funcnum != dev->pci_func) + 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)) return -EINVAL; p.irq = dev->irq; @@ -255,7 +255,8 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) if (!dev->irq) return -EINVAL; - DRM_COPY_FROM_USER_IOCTL(vblwait, argp, sizeof(vblwait)); + if (copy_from_user(&vblwait, argp, sizeof(vblwait))) + return -EFAULT; switch (vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK) { case _DRM_VBLANK_RELATIVE: @@ -329,7 +330,8 @@ int drm_wait_vblank(DRM_IOCTL_ARGS) } done: - DRM_COPY_TO_USER_IOCTL(argp, vblwait, sizeof(vblwait)); + if (copy_to_user(argp, &vblwait, sizeof(vblwait))) + return -EFAULT; return ret; } diff --git a/trunk/drivers/char/drm/drm_mm.c b/trunk/drivers/char/drm/drm_mm.c new file mode 100644 index 000000000000..617526bd5b0c --- /dev/null +++ b/trunk/drivers/char/drm/drm_mm.c @@ -0,0 +1,201 @@ +/************************************************************************** + * + * 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 b1bb3c7b568d..09398d5fbd3f 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|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, 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, 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|CHIP_IS_IGP}, \ + {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_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|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, 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, 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|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, 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, 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|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, 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, 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|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, 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, 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|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}, \ + {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}, \ {0, 0, 0} #define r128_PCI_IDS \ @@ -209,6 +209,7 @@ {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} @@ -227,6 +228,10 @@ {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 \ @@ -285,5 +290,9 @@ {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 362a270af0f1..62d5fe15f046 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' : '-', - VM_OFFSET(vma)); + vma->vm_pgoff << PAGE_SHIFT); #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 new file mode 100644 index 000000000000..425c82336ee0 --- /dev/null +++ b/trunk/drivers/char/drm/drm_sman.c @@ -0,0 +1,352 @@ +/************************************************************************** + * + * 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 new file mode 100644 index 000000000000..ddc732a1bf27 --- /dev/null +++ b/trunk/drivers/char/drm/drm_sman.h @@ -0,0 +1,176 @@ +/************************************************************************** + * + * 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 9a842a36bb27..7b1d4e8659ba 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 ffd0800ed601..b40ae438f531 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; - struct list_head *list; + drm_hash_item_t *hash; /* * Find the right map @@ -70,14 +70,11 @@ 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; - 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 (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; if (map && map->type == _DRM_AGP) { unsigned long offset = address - vma->vm_start; @@ -467,7 +464,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, VM_OFFSET(vma)); + vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT); /* Length must match exact page count */ if (!dma || (length >> PAGE_SHIFT) != dma->page_count) { @@ -521,12 +518,11 @@ 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; - struct list_head *list; + drm_hash_item_t *hash; DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n", - vma->vm_start, vma->vm_end, VM_OFFSET(vma)); + vma->vm_start, vma->vm_end, vma->vm_pgoff << PAGE_SHIFT); if (!priv->authenticated) return -EACCES; @@ -535,7 +531,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) * the AGP mapped at physical address 0 * --BenH. */ - if (!VM_OFFSET(vma) + if (!(vma->vm_pgoff << PAGE_SHIFT) #if __OS_HAS_AGP && (!dev->agp || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE) @@ -543,23 +539,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma) ) return drm_mmap_dma(filp, vma); - /* 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; + if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff << PAGE_SHIFT, &hash)) { + DRM_ERROR("Could not find map\n"); + return -EINVAL; } + map = drm_hash_entry(hash, drm_map_list_t, hash)->map; if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) return -EPERM; @@ -620,7 +605,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(DRM_RPR_ARG(vma) vma->vm_start, + if (io_remap_pfn_range(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 c658dde3633b..fa2de70f7401 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, - VM_OFFSET(vma) >> PAGE_SHIFT, + vma->vm_pgoff, 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 ((unsigned long)buf_priv->virtual > -1024UL) { + if (IS_ERR(buf_priv->virtual)) { /* Real error */ DRM_ERROR("mmap error\n"); - retcode = (signed int)buf_priv->virtual; + retcode = PTR_ERR(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 *) ((u32) buf_priv->kernel_virtual + used) = 0; + *(u32 *) ((char *) 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 *) ((u32) buf_priv->virtual + used) = 0; + *(u32 *) ((char *) 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 b0f815d8cea8..4f0e5746ab33 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, - VM_OFFSET(vma) >> PAGE_SHIFT, + vma->vm_pgoff, 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 = virtual; + retcode = PTR_ERR((void *)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 a94233bdbc0e..fb7913ff5286 100644 --- a/trunk/drivers/char/drm/i915_dma.c +++ b/trunk/drivers/char/drm/i915_dma.c @@ -31,6 +31,11 @@ #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 @@ -255,7 +260,7 @@ static int i915_dma_init(DRM_IOCTL_ARGS) retcode = i915_dma_resume(dev); break; default: - retcode = -EINVAL; + retcode = DRM_ERR(EINVAL); break; } @@ -347,7 +352,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; @@ -386,7 +391,7 @@ static int i915_emit_box(drm_device_t * dev, RING_LOCALS; if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) { - return EFAULT; + return DRM_ERR(EFAULT); } if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { @@ -395,24 +400,40 @@ static int i915_emit_box(drm_device_t * dev, return DRM_ERR(EINVAL); } - 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(); + 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(); + } 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++; + dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; + + if (dev_priv->counter > 0x7FFFFFFFUL) + dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1; 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 5aa3e0e3bb45..6af83e613f27 100644 --- a/trunk/drivers/char/drm/i915_drm.h +++ b/trunk/drivers/char/drm/i915_drm.h @@ -98,6 +98,12 @@ 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 2d565031c002..fdc2bf192714 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,6 +254,8 @@ 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 cd96cfa430db..0d4a162aa385 100644 --- a/trunk/drivers/char/drm/i915_irq.c +++ b/trunk/drivers/char/drm/i915_irq.c @@ -71,21 +71,27 @@ 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__); - ret = dev_priv->counter; + dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter; - BEGIN_LP_RING(2); + 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); OUT_RING(0); OUT_RING(GFX_OP_USER_INTERRUPT); ADVANCE_LP_RING(); - - return ret; + + return dev_priv->counter; } 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 5ad43ba7b5aa..5ed965688293 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_RB2D_DSTCACHE_CTLSTAT); - tmp |= RADEON_RB2D_DC_FLUSH_ALL; - RADEON_WRITE(RADEON_RB2D_DSTCACHE_CTLSTAT, tmp); + tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT); + tmp |= RADEON_RB3D_DC_FLUSH_ALL; + RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp); for (i = 0; i < dev_priv->usec_timeout; i++) { - if (!(RADEON_READ(RADEON_RB2D_DSTCACHE_CTLSTAT) - & RADEON_RB2D_DC_BUSY)) { + if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT) + & RADEON_RB3D_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 & CHIP_IS_AGP) { + if (dev_priv->flags & RADEON_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 & CHIP_IS_AGP) { + if (dev_priv->flags & RADEON_IS_AGP) { RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, dev_priv->ring_rptr->offset - dev->agp->base + dev_priv->gart_vm_start); @@ -1258,6 +1258,13 @@ 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 */ @@ -1295,7 +1302,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) { u32 tmp; - if (dev_priv->flags & CHIP_IS_PCIE) { + if (dev_priv->flags & RADEON_IS_PCIE) { radeon_set_pciegart(dev_priv, on); return; } @@ -1333,20 +1340,22 @@ 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 & CHIP_NEW_MEMMAP) && !dev_priv->new_memmap) - { - DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX\n"); + 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"); radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); } - if (init->is_pci && (dev_priv->flags & CHIP_IS_AGP)) - { + if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) { DRM_DEBUG("Forcing AGP card to PCI mode\n"); - dev_priv->flags &= ~CHIP_IS_AGP; + 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; } - if ((!(dev_priv->flags & CHIP_IS_AGP)) && !dev->sg) { + if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) { DRM_ERROR("PCI GART memory not allocated!\n"); radeon_do_cleanup_cp(dev); return DRM_ERR(EINVAL); @@ -1489,7 +1498,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 & CHIP_IS_AGP) { + if (dev_priv->flags & RADEON_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); @@ -1548,7 +1557,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 & CHIP_IS_AGP) { + if (dev_priv->flags & RADEON_IS_AGP) { base = dev->agp->base; /* Check if valid */ if ((base + dev_priv->gart_size) > dev_priv->fb_location && @@ -1578,7 +1587,7 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init) } #if __OS_HAS_AGP - if (dev_priv->flags & CHIP_IS_AGP) + if (dev_priv->flags & RADEON_IS_AGP) dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset - dev->agp->base + dev_priv->gart_vm_start); @@ -1604,7 +1613,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 & CHIP_IS_AGP) { + if (dev_priv->flags & RADEON_IS_AGP) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); } else @@ -1624,7 +1633,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 & CHIP_IS_PCIE); + !!(dev_priv->flags & RADEON_IS_PCIE); dev_priv->gart_info.gart_table_location = DRM_ATI_GART_FB; @@ -1636,7 +1645,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 & CHIP_IS_PCIE) { + if (dev_priv->flags & RADEON_IS_PCIE) { DRM_ERROR ("Cannot use PCI Express without GART in FB memory\n"); radeon_do_cleanup_cp(dev); @@ -1678,7 +1687,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev) drm_irq_uninstall(dev); #if __OS_HAS_AGP - if (dev_priv->flags & CHIP_IS_AGP) { + if (dev_priv->flags & RADEON_IS_AGP) { if (dev_priv->cp_ring != NULL) { drm_core_ioremapfree(dev_priv->cp_ring, dev); dev_priv->cp_ring = NULL; @@ -1733,7 +1742,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 & CHIP_IS_AGP) { + if (dev_priv->flags & RADEON_IS_AGP) { /* Turn off PCI GART */ radeon_set_pcigart(dev_priv, 0); } else @@ -2177,13 +2186,15 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) dev->dev_private = (void *)dev_priv; dev_priv->flags = flags; - switch (flags & CHIP_FAMILY_MASK) { + switch (flags & RADEON_FAMILY_MASK) { case CHIP_R100: case CHIP_RV200: case CHIP_R200: case CHIP_R300: + case CHIP_R350: case CHIP_R420: - dev_priv->flags |= CHIP_HAS_HIERZ; + case CHIP_RV410: + dev_priv->flags |= RADEON_HAS_HIERZ; break; default: /* all other chips have no hierarchical z buffer */ @@ -2191,13 +2202,14 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) } if (drm_device_is_agp(dev)) - dev_priv->flags |= CHIP_IS_AGP; - - if (drm_device_is_pcie(dev)) - dev_priv->flags |= CHIP_IS_PCIE; + 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; DRM_DEBUG("%s card detected\n", - ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : (((dev_priv->flags & CHIP_IS_PCIE) ? "PCIE" : "PCI")))); + ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_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 eb985c2a31e9..2eb652ec6745 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 & CHIP_FAMILY_MASK; + int family = dev_priv->flags & RADEON_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 e5a256f5429c..f45cd7f147a5 100644 --- a/trunk/drivers/char/drm/radeon_drv.h +++ b/trunk/drivers/char/drm/radeon_drv.h @@ -133,15 +133,16 @@ enum radeon_cp_microcode_version { * Chip flags */ enum radeon_chip_flags { - 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, + 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, }; #define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \ @@ -424,6 +425,8 @@ 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) @@ -441,6 +444,7 @@ 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) @@ -545,6 +549,11 @@ 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) @@ -681,6 +690,7 @@ 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 @@ -986,13 +996,13 @@ do { \ } while (0) #define RADEON_FLUSH_CACHE() do { \ - OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB2D_DC_FLUSH ); \ + OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB3D_DC_FLUSH ); \ } while (0) #define RADEON_PURGE_CACHE() do { \ - OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ - OUT_RING( RADEON_RB2D_DC_FLUSH_ALL ); \ + OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB3D_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 39a7f685e3fd..feac5f005d47 100644 --- a/trunk/drivers/char/drm/radeon_state.c +++ b/trunk/drivers/char/drm/radeon_state.c @@ -42,7 +42,11 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t * drm_file_t * filp_priv, u32 *offset) { - u32 off = *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; struct drm_radeon_driver_file_fields *radeon_priv; /* Hrm ... the story of the offset ... So this function converts @@ -62,10 +66,8 @@ 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 >= 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))) + if ((off >= fb_start && off <= fb_end) || + (off >= gart_start && off <= gart_end)) return 0; /* Ok, that didn't happen... now check if we have a zero based @@ -78,16 +80,13 @@ 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 > (dev_priv->fb_location + dev_priv->fb_size)) - off = off - (dev_priv->fb_location + dev_priv->fb_size) + - dev_priv->gart_vm_start; + if (off > fb_end) + off = off - fb_end - 1 + gart_start; /* Now recheck and fail if out of bounds */ - 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); + 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); *offset = off; return 0; } @@ -869,7 +868,7 @@ static void radeon_cp_dispatch_clear(drm_device_t * dev, */ dev_priv->sarea_priv->ctx_owner = 0; - if ((dev_priv->flags & CHIP_HAS_HIERZ) + if ((dev_priv->flags & RADEON_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 @@ -914,7 +913,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 & CHIP_HAS_HIERZ) + if ((dev_priv->flags & RADEON_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 @@ -998,7 +997,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 & CHIP_HAS_HIERZ) + if ((dev_priv->flags & RADEON_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 */ @@ -1270,9 +1269,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(7); + BEGIN_RING(9); - OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5)); + OUT_RING(CP_PACKET0(RADEON_DP_GUI_MASTER_CNTL, 0)); OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_NONE | @@ -1284,6 +1283,7 @@ 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,6 +1292,7 @@ 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); @@ -2987,16 +2988,21 @@ 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 & CHIP_IS_PCIE) + if (dev_priv->flags & RADEON_IS_PCIE) value = RADEON_CARD_PCIE; - else if (dev_priv->flags & CHIP_IS_AGP) + else if (dev_priv->flags & RADEON_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 5e9dc86f2956..3d5b3218b6ff 100644 --- a/trunk/drivers/char/drm/sis_drv.c +++ b/trunk/drivers/char/drm/sis_drv.c @@ -35,11 +35,44 @@ 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, - .context_ctor = sis_init_context, - .context_dtor = sis_final_context, - .reclaim_buffers = drm_core_reclaim_buffers, + .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, .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 e218e5269503..2b8d6f6ed7c0 100644 --- a/trunk/drivers/char/drm/sis_drv.h +++ b/trunk/drivers/char/drm/sis_drv.h @@ -31,23 +31,39 @@ /* General customization: */ -#define DRIVER_AUTHOR "SIS" +#define DRIVER_AUTHOR "SIS, Tungsten Graphics" #define DRIVER_NAME "sis" #define DRIVER_DESC "SIS 300/630/540" -#define DRIVER_DATE "20030826" +#define DRIVER_DATE "20060704" #define DRIVER_MAJOR 1 -#define DRIVER_MINOR 1 -#define DRIVER_PATCHLEVEL 0 +#define DRIVER_MINOR 2 +#define DRIVER_PATCHLEVEL 1 -#include "sis_ds.h" +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); typedef struct drm_sis_private { - memHeap_t *AGPHeap; - memHeap_t *FBHeap; + 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; } drm_sis_private_t; -extern int sis_init_context(drm_device_t * dev, int context); -extern int sis_final_context(drm_device_t * dev, int context); +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 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 deleted file mode 100644 index 2e485d482943..000000000000 --- a/trunk/drivers/char/drm/sis_ds.c +++ /dev/null @@ -1,299 +0,0 @@ -/* 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 deleted file mode 100644 index 94f2b4728b63..000000000000 --- a/trunk/drivers/char/drm/sis_ds.h +++ /dev/null @@ -1,146 +0,0 @@ -/* 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 5e9936bc307f..d26f5dbb7853 100644 --- a/trunk/drivers/char/drm/sis_mm.c +++ b/trunk/drivers/char/drm/sis_mm.c @@ -1,414 +1,348 @@ -/* 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 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. - * All rights reserved. + * 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, 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: + * 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 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. + * 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. * - * Authors: - * Sung-Ching Lin * + **************************************************************************/ + +/* + * Authors: + * Thomas Hellström */ #include "drmP.h" #include "sis_drm.h" #include "sis_drv.h" -#include "sis_ds.h" -#if defined(__linux__) && defined(CONFIG_FB_SIS) + #include