diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index 6de71308a9060..5b5aba404aacb 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX @@ -89,8 +89,6 @@ cciss.txt - info, major/minor #'s for Compaq's SMART Array Controllers. cdrom/ - directory with information on the CD-ROM drivers that Linux has. -cli-sti-removal.txt - - cli()/sti() removal guide. computone.txt - info on Computone Intelliport II/Plus Multiport Serial Driver. connector/ diff --git a/Documentation/ABI/testing/sysfs-class-regulator b/Documentation/ABI/testing/sysfs-class-regulator new file mode 100644 index 0000000000000..79a4a75b2d2ce --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-regulator @@ -0,0 +1,315 @@ +What: /sys/class/regulator/.../state +Date: April 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + state. This holds the regulator output state. + + This will be one of the following strings: + + 'enabled' + 'disabled' + 'unknown' + + 'enabled' means the regulator output is ON and is supplying + power to the system. + + 'disabled' means the regulator output is OFF and is not + supplying power to the system.. + + 'unknown' means software cannot determine the state. + + NOTE: this field can be used in conjunction with microvolts + and microamps to determine regulator output levels. + + +What: /sys/class/regulator/.../type +Date: April 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + type. This holds the regulator type. + + This will be one of the following strings: + + 'voltage' + 'current' + 'unknown' + + 'voltage' means the regulator output voltage can be controlled + by software. + + 'current' means the regulator output current limit can be + controlled by software. + + 'unknown' means software cannot control either voltage or + current limit. + + +What: /sys/class/regulator/.../microvolts +Date: April 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + microvolts. This holds the regulator output voltage setting + measured in microvolts (i.e. E-6 Volts). + + NOTE: This value should not be used to determine the regulator + output voltage level as this value is the same regardless of + whether the regulator is enabled or disabled. + + +What: /sys/class/regulator/.../microamps +Date: April 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + microamps. This holds the regulator output current limit + setting measured in microamps (i.e. E-6 Amps). + + NOTE: This value should not be used to determine the regulator + output current level as this value is the same regardless of + whether the regulator is enabled or disabled. + + +What: /sys/class/regulator/.../opmode +Date: April 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + opmode. This holds the regulator operating mode setting. + + The opmode value can be one of the following strings: + + 'fast' + 'normal' + 'idle' + 'standby' + 'unknown' + + The modes are described in include/linux/regulator/regulator.h + + NOTE: This value should not be used to determine the regulator + output operating mode as this value is the same regardless of + whether the regulator is enabled or disabled. + + +What: /sys/class/regulator/.../min_microvolts +Date: April 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + min_microvolts. This holds the minimum safe working regulator + output voltage setting for this domain measured in microvolts. + + NOTE: this will return the string 'constraint not defined' if + the power domain has no min microvolts constraint defined by + platform code. + + +What: /sys/class/regulator/.../max_microvolts +Date: April 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + max_microvolts. This holds the maximum safe working regulator + output voltage setting for this domain measured in microvolts. + + NOTE: this will return the string 'constraint not defined' if + the power domain has no max microvolts constraint defined by + platform code. + + +What: /sys/class/regulator/.../min_microamps +Date: April 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + min_microamps. This holds the minimum safe working regulator + output current limit setting for this domain measured in + microamps. + + NOTE: this will return the string 'constraint not defined' if + the power domain has no min microamps constraint defined by + platform code. + + +What: /sys/class/regulator/.../max_microamps +Date: April 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + max_microamps. This holds the maximum safe working regulator + output current limit setting for this domain measured in + microamps. + + NOTE: this will return the string 'constraint not defined' if + the power domain has no max microamps constraint defined by + platform code. + + +What: /sys/class/regulator/.../num_users +Date: April 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + num_users. This holds the number of consumer devices that + have called regulator_enable() on this regulator. + + +What: /sys/class/regulator/.../requested_microamps +Date: April 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + requested_microamps. This holds the total requested load + current in microamps for this regulator from all its consumer + devices. + + +What: /sys/class/regulator/.../parent +Date: April 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Some regulator directories will contain a link called parent. + This points to the parent or supply regulator if one exists. + +What: /sys/class/regulator/.../suspend_mem_microvolts +Date: May 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + suspend_mem_microvolts. This holds the regulator output + voltage setting for this domain measured in microvolts when + the system is suspended to memory. + + NOTE: this will return the string 'not defined' if + the power domain has no suspend to memory voltage defined by + platform code. + +What: /sys/class/regulator/.../suspend_disk_microvolts +Date: May 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + suspend_disk_microvolts. This holds the regulator output + voltage setting for this domain measured in microvolts when + the system is suspended to disk. + + NOTE: this will return the string 'not defined' if + the power domain has no suspend to disk voltage defined by + platform code. + +What: /sys/class/regulator/.../suspend_standby_microvolts +Date: May 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + suspend_standby_microvolts. This holds the regulator output + voltage setting for this domain measured in microvolts when + the system is suspended to standby. + + NOTE: this will return the string 'not defined' if + the power domain has no suspend to standby voltage defined by + platform code. + +What: /sys/class/regulator/.../suspend_mem_mode +Date: May 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + suspend_mem_mode. This holds the regulator operating mode + setting for this domain when the system is suspended to + memory. + + NOTE: this will return the string 'not defined' if + the power domain has no suspend to memory mode defined by + platform code. + +What: /sys/class/regulator/.../suspend_disk_mode +Date: May 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + suspend_disk_mode. This holds the regulator operating mode + setting for this domain when the system is suspended to disk. + + NOTE: this will return the string 'not defined' if + the power domain has no suspend to disk mode defined by + platform code. + +What: /sys/class/regulator/.../suspend_standby_mode +Date: May 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + suspend_standby_mode. This holds the regulator operating mode + setting for this domain when the system is suspended to + standby. + + NOTE: this will return the string 'not defined' if + the power domain has no suspend to standby mode defined by + platform code. + +What: /sys/class/regulator/.../suspend_mem_state +Date: May 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + suspend_mem_state. This holds the regulator operating state + when suspended to memory. + + This will be one of the following strings: + + 'enabled' + 'disabled' + 'not defined' + +What: /sys/class/regulator/.../suspend_disk_state +Date: May 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + suspend_disk_state. This holds the regulator operating state + when suspended to disk. + + This will be one of the following strings: + + 'enabled' + 'disabled' + 'not defined' + +What: /sys/class/regulator/.../suspend_standby_state +Date: May 2008 +KernelVersion: 2.6.26 +Contact: Liam Girdwood +Description: + Each regulator directory will contain a field called + suspend_standby_state. This holds the regulator operating + state when suspended to standby. + + This will be one of the following strings: + + 'enabled' + 'disabled' + 'not defined' diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index 0eb0d027eb32e..1615350b7b53b 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -12,7 +12,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \ - mac80211.xml debugobjects.xml + mac80211.xml debugobjects.xml sh.xml ### # The build process is as follows (targets): @@ -102,6 +102,13 @@ C-procfs-example = procfs_example.xml C-procfs-example2 = $(addprefix $(obj)/,$(C-procfs-example)) $(obj)/procfs-guide.xml: $(C-procfs-example2) +# List of programs to build +##oops, this is a kernel module::hostprogs-y := procfs_example +obj-m += procfs_example.o + +# Tell kbuild to always build the programs +always := $(hostprogs-y) + notfoundtemplate = echo "*** You have to install docbook-utils or xmlto ***"; \ exit 1 db2xtemplate = db2TYPE -o $(dir $@) $< diff --git a/Documentation/DocBook/kgdb.tmpl b/Documentation/DocBook/kgdb.tmpl index e8acd1f034567..372dec20c8dab 100644 --- a/Documentation/DocBook/kgdb.tmpl +++ b/Documentation/DocBook/kgdb.tmpl @@ -98,6 +98,24 @@ "Kernel debugging" select "KGDB: kernel debugging with remote gdb". + It is advised, but not required that you turn on the + CONFIG_FRAME_POINTER kernel option. This option inserts code to + into the compiled executable which saves the frame information in + registers or on the stack at different points which will allow a + debugger such as gdb to more accurately construct stack back traces + while debugging the kernel. + + + If the architecture that you are using supports the kernel option + CONFIG_DEBUG_RODATA, you should consider turning it off. This + option will prevent the use of software breakpoints because it + marks certain regions of the kernel's memory space as read-only. + If kgdb supports it for the architecture you are using, you can + use hardware breakpoints if you desire to run with the + CONFIG_DEBUG_RODATA option turned on, else you need to turn off + this option. + + Next you should choose one of more I/O drivers to interconnect debugging host and debugged target. Early boot debugging requires a KGDB I/O driver that supports early debugging and the driver must be diff --git a/Documentation/DocBook/procfs_example.c b/Documentation/DocBook/procfs_example.c index 7064084c1c5e4..2f3de0fb83651 100644 --- a/Documentation/DocBook/procfs_example.c +++ b/Documentation/DocBook/procfs_example.c @@ -189,8 +189,6 @@ static int __init init_procfs_example(void) return 0; no_symlink: - remove_proc_entry("tty", example_dir); -no_tty: remove_proc_entry("bar", example_dir); no_bar: remove_proc_entry("foo", example_dir); @@ -206,7 +204,6 @@ static int __init init_procfs_example(void) static void __exit cleanup_procfs_example(void) { remove_proc_entry("jiffies_too", example_dir); - remove_proc_entry("tty", example_dir); remove_proc_entry("bar", example_dir); remove_proc_entry("foo", example_dir); remove_proc_entry("jiffies", example_dir); @@ -222,3 +219,4 @@ module_exit(cleanup_procfs_example); MODULE_AUTHOR("Erik Mouw"); MODULE_DESCRIPTION("procfs examples"); +MODULE_LICENSE("GPL"); diff --git a/Documentation/DocBook/s390-drivers.tmpl b/Documentation/DocBook/s390-drivers.tmpl index 4acc73240a6d5..95bfc12e5439d 100644 --- a/Documentation/DocBook/s390-drivers.tmpl +++ b/Documentation/DocBook/s390-drivers.tmpl @@ -100,7 +100,7 @@ the hardware structures represented here, please consult the Principles of Operation. -!Iinclude/asm-s390/cio.h +!Iarch/s390/include/asm/cio.h ccw devices @@ -114,7 +114,7 @@ ccw device structure. Device drivers must not bypass those functions or strange side effects may happen. -!Iinclude/asm-s390/ccwdev.h +!Iarch/s390/include/asm/ccwdev.h !Edrivers/s390/cio/device.c !Edrivers/s390/cio/device_ops.c @@ -125,7 +125,7 @@ measurement data which is made available by the channel subsystem for each channel attached device. -!Iinclude/asm-s390/cmb.h +!Iarch/s390/include/asm/cmb.h !Edrivers/s390/cio/cmf.c @@ -142,7 +142,7 @@ ccw group devices -!Iinclude/asm-s390/ccwgroup.h +!Iarch/s390/include/asm/ccwgroup.h !Edrivers/s390/cio/ccwgroup.c diff --git a/Documentation/DocBook/sh.tmpl b/Documentation/DocBook/sh.tmpl new file mode 100644 index 0000000000000..0c3dc4c69dd11 --- /dev/null +++ b/Documentation/DocBook/sh.tmpl @@ -0,0 +1,105 @@ + + + + + + SuperH Interfaces Guide + + + + Paul + Mundt + +
+ lethal@linux-sh.org +
+
+
+
+ + + 2008 + Paul Mundt + + + 2008 + Renesas Technology Corp. + + + + + This documentation is free software; you can redistribute + it and/or modify it under the terms of the GNU General Public + License version 2 as published by the Free Software Foundation. + + + + This program is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + MA 02111-1307 USA + + + + For more details see the file COPYING in the source + distribution of Linux. + + +
+ + + + + Memory Management + + SH-4 + + Store Queue API +!Earch/sh/kernel/cpu/sh4/sq.c + + + + SH-5 + + TLB Interfaces +!Iarch/sh/mm/tlb-sh5.c +!Iarch/sh/include/asm/tlb_64.h + + + + + Clock Framework Extensions +!Iarch/sh/include/asm/clock.h + + + Machine Specific Interfaces + + mach-dreamcast +!Iarch/sh/boards/mach-dreamcast/rtc.c + + + mach-x3proto +!Earch/sh/boards/mach-x3proto/ilsel.c + + + + Busses + + SuperHyway +!Edrivers/sh/superhyway/superhyway.c + + + + Maple +!Edrivers/sh/maple/maple.c + + +
diff --git a/Documentation/DocBook/videobook.tmpl b/Documentation/DocBook/videobook.tmpl index 89817795e668d..0bc25949b6683 100644 --- a/Documentation/DocBook/videobook.tmpl +++ b/Documentation/DocBook/videobook.tmpl @@ -1648,7 +1648,7 @@ static struct video_buffer capture_fb; Public Functions Provided -!Edrivers/media/video/videodev.c +!Edrivers/media/video/v4l2-dev.c diff --git a/Documentation/DocBook/z8530book.tmpl b/Documentation/DocBook/z8530book.tmpl index 42c75ba71ba22..a42a8a4c76890 100644 --- a/Documentation/DocBook/z8530book.tmpl +++ b/Documentation/DocBook/z8530book.tmpl @@ -69,12 +69,6 @@ device to be used as both a tty interface and as a synchronous controller is a project for Linux post the 2.4 release - - The support code handles most common card configurations and - supports running both Cisco HDLC and Synchronous PPP. With extra - glue the frame relay and X.25 protocols can also be used with this - driver. - @@ -179,35 +173,27 @@ If you wish to use the network interface facilities of the driver, then you need to attach a network device to each channel that is - present and in use. In addition to use the SyncPPP and Cisco HDLC + present and in use. In addition to use the generic HDLC you need to follow some additional plumbing rules. They may seem complex but a look at the example hostess_sv11 driver should reassure you. The network device used for each channel should be pointed to by - the netdevice field of each channel. The dev-> priv field of the + the netdevice field of each channel. The hdlc-> priv field of the network device points to your private data - you will need to be - able to find your ppp device from this. In addition to use the - sync ppp layer the private data must start with a void * pointer - to the syncppp structures. + able to find your private data from this. The way most drivers approach this particular problem is to create a structure holding the Z8530 device definition and - put that and the syncppp pointer into the private field of - the network device. The network device fields of the channels - then point back to the network devices. The ppp_device can also - be put in the private structure conveniently. + put that into the private field of the network device. The + network device fields of the channels then point back to the + network devices. - If you wish to use the synchronous ppp then you need to attach - the syncppp layer to the network device. You should do this before - you register the network device. The - sppp_attach requires that the first void * - pointer in your private data is pointing to an empty struct - ppp_device. The function fills in the initial data for the - ppp/hdlc layer. + If you wish to use the generic HDLC then you need to register + the HDLC device. Before you register your network device you will also need to @@ -314,10 +300,10 @@ buffer in sk_buff format and queues it for transmission. The caller must provide the entire packet with the exception of the bitstuffing and CRC. This is normally done by the caller via - the syncppp interface layer. It returns 0 if the buffer has been - queued and non zero values for queue full. If the function accepts - the buffer it becomes property of the Z8530 layer and the caller - should not free it. + the generic HDLC interface layer. It returns 0 if the buffer has been + queued and non zero values for queue full. If the function accepts + the buffer it becomes property of the Z8530 layer and the caller + should not free it. The function z8530_get_stats returns a pointer diff --git a/Documentation/Makefile b/Documentation/Makefile new file mode 100644 index 0000000000000..94b9457335344 --- /dev/null +++ b/Documentation/Makefile @@ -0,0 +1,3 @@ +obj-m := DocBook/ accounting/ auxdisplay/ connector/ \ + filesystems/configfs/ ia64/ networking/ \ + pcmcia/ spi/ video4linux/ vm/ watchdog/src/ diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 118ca6e9404f4..f79ad9ff6031a 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -528,7 +528,33 @@ See more details on the proper patch format in the following references. +16) Sending "git pull" requests (from Linus emails) +Please write the git repo address and branch name alone on the same line +so that I can't even by mistake pull from the wrong branch, and so +that a triple-click just selects the whole thing. + +So the proper format is something along the lines of: + + "Please pull from + + git://jdelvare.pck.nerim.net/jdelvare-2.6 i2c-for-linus + + to get these changes:" + +so that I don't have to hunt-and-peck for the address and inevitably +get it wrong (actually, I've only gotten it wrong a few times, and +checking against the diffstat tells me when I get it wrong, but I'm +just a lot more comfortable when I don't have to "look for" the right +thing to pull, and double-check that I have the right branch-name). + + +Please use "git diff -M --stat --summary" to generate the diffstat: +the -M enables rename detection, and the summary enables a summary of +new/deleted or renamed files. + +With rename detection, the statistics are rather different [...] +because git will notice that a fair number of the changes are renames. ----------------------------------- SECTION 2 - HINTS, TIPS, AND TRICKS diff --git a/Documentation/accounting/Makefile b/Documentation/accounting/Makefile new file mode 100644 index 0000000000000..31929eb875b19 --- /dev/null +++ b/Documentation/accounting/Makefile @@ -0,0 +1,10 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := getdelays + +# Tell kbuild to always build the programs +always := $(hostprogs-y) + +HOSTCFLAGS_getdelays.o += -I$(objtree)/usr/include diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c index 3f7755f3963f1..cc49400b4af89 100644 --- a/Documentation/accounting/getdelays.c +++ b/Documentation/accounting/getdelays.c @@ -201,13 +201,19 @@ void print_delayacct(struct taskstats *t) "RECLAIM %12s%15s\n" " %15llu%15llu\n", "count", "real total", "virtual total", "delay total", - t->cpu_count, t->cpu_run_real_total, t->cpu_run_virtual_total, - t->cpu_delay_total, + (unsigned long long)t->cpu_count, + (unsigned long long)t->cpu_run_real_total, + (unsigned long long)t->cpu_run_virtual_total, + (unsigned long long)t->cpu_delay_total, "count", "delay total", - t->blkio_count, t->blkio_delay_total, - "count", "delay total", t->swapin_count, t->swapin_delay_total, + (unsigned long long)t->blkio_count, + (unsigned long long)t->blkio_delay_total, "count", "delay total", - t->freepages_count, t->freepages_delay_total); + (unsigned long long)t->swapin_count, + (unsigned long long)t->swapin_delay_total, + "count", "delay total", + (unsigned long long)t->freepages_count, + (unsigned long long)t->freepages_delay_total); } void task_context_switch_counts(struct taskstats *t) @@ -215,14 +221,17 @@ void task_context_switch_counts(struct taskstats *t) printf("\n\nTask %15s%15s\n" " %15llu%15llu\n", "voluntary", "nonvoluntary", - t->nvcsw, t->nivcsw); + (unsigned long long)t->nvcsw, (unsigned long long)t->nivcsw); } void print_cgroupstats(struct cgroupstats *c) { printf("sleeping %llu, blocked %llu, running %llu, stopped %llu, " - "uninterruptible %llu\n", c->nr_sleeping, c->nr_io_wait, - c->nr_running, c->nr_stopped, c->nr_uninterruptible); + "uninterruptible %llu\n", (unsigned long long)c->nr_sleeping, + (unsigned long long)c->nr_io_wait, + (unsigned long long)c->nr_running, + (unsigned long long)c->nr_stopped, + (unsigned long long)c->nr_uninterruptible); } diff --git a/Documentation/arm/IXP4xx b/Documentation/arm/IXP4xx index 43edb4ecf27db..72fbcc4fcab09 100644 --- a/Documentation/arm/IXP4xx +++ b/Documentation/arm/IXP4xx @@ -32,7 +32,7 @@ Linux currently supports the following features on the IXP4xx chips: - Flash access (MTD/JFFS) - I2C through GPIO on IXP42x - GPIO for input/output/interrupts - See include/asm-arm/arch-ixp4xx/platform.h for access functions. + See arch/arm/mach-ixp4xx/include/mach/platform.h for access functions. - Timers (watchdog, OS) The following components of the chips are not supported by Linux and diff --git a/Documentation/arm/Interrupts b/Documentation/arm/Interrupts index c202ed35d7d61..f09ab1b90ef1b 100644 --- a/Documentation/arm/Interrupts +++ b/Documentation/arm/Interrupts @@ -158,7 +158,7 @@ So, what's changed? be re-checked for pending events. (see the Neponset IRQ handler for details). -7. fixup_irq() is gone, as is include/asm-arm/arch-*/irq.h +7. fixup_irq() is gone, as is arch/arm/mach-*/include/mach/irq.h Please note that this will not solve all problems - some of them are hardware based. Mixing level-based and edge-based IRQs on the same diff --git a/Documentation/arm/README b/Documentation/arm/README index 9b9c8226fdc42..d98783fbe0c7c 100644 --- a/Documentation/arm/README +++ b/Documentation/arm/README @@ -79,7 +79,7 @@ Machine/Platform support To this end, we now have arch/arm/mach-$(MACHINE) directories which are designed to house the non-driver files for a particular machine (eg, PCI, memory management, architecture definitions etc). For all future - machines, there should be a corresponding include/asm-arm/arch-$(MACHINE) + machines, there should be a corresponding arch/arm/mach-$(MACHINE)/include/mach directory. @@ -176,7 +176,7 @@ Kernel entry (head.S) class typically based around one or more system on a chip devices, and acts as a natural container around the actual implementations. These classes are given directories - arch/arm/mach- and - include/asm-arm/arch- - which contain the source files to + arch/arm/mach- - which contain the source files to/include/mach support the machine class. This directories also contain any machine specific supporting code. diff --git a/Documentation/arm/Samsung-S3C24XX/GPIO.txt b/Documentation/arm/Samsung-S3C24XX/GPIO.txt index 8caea8c237eec..b5d20c0b2ab46 100644 --- a/Documentation/arm/Samsung-S3C24XX/GPIO.txt +++ b/Documentation/arm/Samsung-S3C24XX/GPIO.txt @@ -16,13 +16,13 @@ Introduction Headers ------- - See include/asm-arm/arch-s3c2410/regs-gpio.h for the list + See arch/arm/mach-s3c2410/include/mach/regs-gpio.h for the list of GPIO pins, and the configuration values for them. This - is included by using #include + is included by using #include The GPIO management functions are defined in the hardware - header include/asm-arm/arch-s3c2410/hardware.h which can be - included by #include + header arch/arm/mach-s3c2410/include/mach/hardware.h which can be + included by #include A useful amount of documentation can be found in the hardware header on how the GPIO functions (and others) work. diff --git a/Documentation/arm/Samsung-S3C24XX/Overview.txt b/Documentation/arm/Samsung-S3C24XX/Overview.txt index d04e1e30c47f8..014a8ec4877d2 100644 --- a/Documentation/arm/Samsung-S3C24XX/Overview.txt +++ b/Documentation/arm/Samsung-S3C24XX/Overview.txt @@ -36,7 +36,7 @@ Layout in arch/arm/mach-s3c2410 and S3C2440 in arch/arm/mach-s3c2440 Register, kernel and platform data definitions are held in the - include/asm-arm/arch-s3c2410 directory. + arch/arm/mach-s3c2410 directory./include/mach Machines diff --git a/Documentation/arm/Samsung-S3C24XX/USB-Host.txt b/Documentation/arm/Samsung-S3C24XX/USB-Host.txt index b93b68e2b143e..67671eba42312 100644 --- a/Documentation/arm/Samsung-S3C24XX/USB-Host.txt +++ b/Documentation/arm/Samsung-S3C24XX/USB-Host.txt @@ -49,7 +49,7 @@ Board Support Platform Data ------------- - See linux/include/asm-arm/arch-s3c2410/usb-control.h for the + See arch/arm/mach-s3c2410/include/mach/usb-control.h for the descriptions of the platform device data. An implementation can be found in linux/arch/arm/mach-s3c2410/usb-simtec.c . diff --git a/Documentation/auxdisplay/Makefile b/Documentation/auxdisplay/Makefile new file mode 100644 index 0000000000000..51fe23332c81f --- /dev/null +++ b/Documentation/auxdisplay/Makefile @@ -0,0 +1,10 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := cfag12864b-example + +# Tell kbuild to always build the programs +always := $(hostprogs-y) + +HOSTCFLAGS_cfag12864b-example.o += -I$(objtree)/usr/include diff --git a/Documentation/cciss.txt b/Documentation/cciss.txt index 63e59b8847c54..8244c6442faa4 100644 --- a/Documentation/cciss.txt +++ b/Documentation/cciss.txt @@ -112,27 +112,18 @@ Hot plug support for SCSI tape drives Hot plugging of SCSI tape drives is supported, with some caveats. The cciss driver must be informed that changes to the SCSI bus -have been made, in addition to and prior to informing the SCSI -mid layer. This may be done via the /proc filesystem. For example: +have been made. This may be done via the /proc filesystem. +For example: echo "rescan" > /proc/scsi/cciss0/1 -This causes the adapter to query the adapter about changes to the -physical SCSI buses and/or fibre channel arbitrated loop and the +This causes the driver to query the adapter about changes to the +physical SCSI buses and/or fibre channel arbitrated loop and the driver to make note of any new or removed sequential access devices or medium changers. The driver will output messages indicating what devices have been added or removed and the controller, bus, target and -lun used to address the device. Once this is done, the SCSI mid layer -can be informed of changes to the virtual SCSI bus which the driver -presents to it in the usual way. For example: - - echo scsi add-single-device 3 2 1 0 > /proc/scsi/scsi - -to add a device on controller 3, bus 2, target 1, lun 0. Note that -the driver makes an effort to preserve the devices positions -in the virtual SCSI bus, so if you are only moving tape drives -around on the same adapter and not adding or removing tape drives -from the adapter, informing the SCSI mid layer may not be necessary. +lun used to address the device. It then notifies the SCSI mid layer +of these changes. Note that the naming convention of the /proc filesystem entries contains a number in addition to the driver name. (E.g. "cciss0" diff --git a/Documentation/cli-sti-removal.txt b/Documentation/cli-sti-removal.txt deleted file mode 100644 index 60932b02fcb33..0000000000000 --- a/Documentation/cli-sti-removal.txt +++ /dev/null @@ -1,133 +0,0 @@ - -#### cli()/sti() removal guide, started by Ingo Molnar - - -as of 2.5.28, five popular macros have been removed on SMP, and -are being phased out on UP: - - cli(), sti(), save_flags(flags), save_flags_cli(flags), restore_flags(flags) - -until now it was possible to protect driver code against interrupt -handlers via a cli(), but from now on other, more lightweight methods -have to be used for synchronization, such as spinlocks or semaphores. - -for example, driver code that used to do something like: - - struct driver_data; - - irq_handler (...) - { - .... - driver_data.finish = 1; - driver_data.new_work = 0; - .... - } - - ... - - ioctl_func (...) - { - ... - cli(); - ... - driver_data.finish = 0; - driver_data.new_work = 2; - ... - sti(); - ... - } - -was SMP-correct because the cli() function ensured that no -interrupt handler (amongst them the above irq_handler()) function -would execute while the cli()-ed section is executing. - -but from now on a more direct method of locking has to be used: - - DEFINE_SPINLOCK(driver_lock); - struct driver_data; - - irq_handler (...) - { - unsigned long flags; - .... - spin_lock_irqsave(&driver_lock, flags); - .... - driver_data.finish = 1; - driver_data.new_work = 0; - .... - spin_unlock_irqrestore(&driver_lock, flags); - .... - } - - ... - - ioctl_func (...) - { - ... - spin_lock_irq(&driver_lock); - ... - driver_data.finish = 0; - driver_data.new_work = 2; - ... - spin_unlock_irq(&driver_lock); - ... - } - -the above code has a number of advantages: - -- the locking relation is easier to understand - actual lock usage - pinpoints the critical sections. cli() usage is too opaque. - Easier to understand means it's easier to debug. - -- it's faster, because spinlocks are faster to acquire than the - potentially heavily-used IRQ lock. Furthermore, your driver does - not have to wait eg. for a big heavy SCSI interrupt to finish, - because the driver_lock spinlock is only used by your driver. - cli() on the other hand was used by many drivers, and extended - the critical section to the whole IRQ handler function - creating - serious lock contention. - - -to make the transition easier, we've still kept the cli(), sti(), -save_flags(), save_flags_cli() and restore_flags() macros defined -on UP systems - but their usage will be phased out until 2.6 is -released. - -drivers that want to disable local interrupts (interrupts on the -current CPU), can use the following five macros: - - local_irq_disable(), local_irq_enable(), local_save_flags(flags), - local_irq_save(flags), local_irq_restore(flags) - -but beware, their meaning and semantics are much simpler, far from -that of the old cli(), sti(), save_flags(flags) and restore_flags(flags) -SMP meaning: - - local_irq_disable() => turn local IRQs off - - local_irq_enable() => turn local IRQs on - - local_save_flags(flags) => save the current IRQ state into flags. The - state can be on or off. (on some - architectures there's even more bits in it.) - - local_irq_save(flags) => save the current IRQ state into flags and - disable interrupts. - - local_irq_restore(flags) => restore the IRQ state from flags. - -(local_irq_save can save both irqs on and irqs off state, and -local_irq_restore can restore into both irqs on and irqs off state.) - -another related change is that synchronize_irq() now takes a parameter: -synchronize_irq(irq). This change too has the purpose of making SMP -synchronization more lightweight - this way you can wait for your own -interrupt handler to finish, no need to wait for other IRQ sources. - - -why were these changes done? The main reason was the architectural burden -of maintaining the cli()/sti() interface - it became a real problem. The -new interrupt system is much more streamlined, easier to understand, debug, -and it's also a bit faster - the same happened to it that will happen to -cli()/sti() using drivers once they convert to spinlocks :-) - diff --git a/Documentation/connector/Makefile b/Documentation/connector/Makefile new file mode 100644 index 0000000000000..8df1a7285a06b --- /dev/null +++ b/Documentation/connector/Makefile @@ -0,0 +1,11 @@ +ifneq ($(CONFIG_CONNECTOR),) +obj-m += cn_test.o +endif + +# List of programs to build +hostprogs-y := ucon + +# Tell kbuild to always build the programs +always := $(hostprogs-y) + +HOSTCFLAGS_ucon.o += -I$(objtree)/usr/include diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index ba0aacde94fba..94bbc27ddd4fb 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt @@ -59,15 +59,10 @@ apicid values in those tables for disabled apics. In the event BIOS doesn't mark such hot-pluggable cpus as disabled entries, one could use this parameter "additional_cpus=x" to represent those cpus in the cpu_possible_map. -s390 uses the number of cpus it detects at IPL time to also the number of bits -in cpu_possible_map. If it is desired to add additional cpus at a later time -the number should be specified using this option or the possible_cpus option. - possible_cpus=n [s390 only] use this to set hotpluggable cpus. This option sets possible_cpus bits in cpu_possible_map. Thus keeping the numbers of bits set constant even if the machine gets rebooted. - This option overrides additional_cpus. CPU maps and such ----------------- diff --git a/Documentation/devices.txt b/Documentation/devices.txt index e6244cde26e94..05c80645e4ee1 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt @@ -2560,9 +2560,6 @@ Your cooperation is appreciated. 96 = /dev/usb/hiddev0 1st USB HID device ... 111 = /dev/usb/hiddev15 16th USB HID device - 112 = /dev/usb/auer0 1st auerswald ISDN device - ... - 127 = /dev/usb/auer15 16th auerswald ISDN device 128 = /dev/usb/brlvgr0 First Braille Voyager device ... 131 = /dev/usb/brlvgr3 Fourth Braille Voyager device diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 721c71b86e068..eb1a47b974278 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -19,15 +19,6 @@ Who: Pavel Machek --------------------------- -What: old NCR53C9x driver -When: October 2007 -Why: Replaced by the much better esp_scsi driver. Actual low-level - driver can be ported over almost trivially. -Who: David Miller - Christoph Hellwig - ---------------------------- - What: Video4Linux API 1 ioctls and video_decoder.h from Video devices. When: December 2008 Files: include/linux/video_decoder.h include/linux/videodev.h @@ -47,6 +38,30 @@ Who: Mauro Carvalho Chehab --------------------------- +What: old tuner-3036 i2c driver +When: 2.6.28 +Why: This driver is for VERY old i2c-over-parallel port teletext receiver + boxes. Rather then spending effort on converting this driver to V4L2, + and since it is extremely unlikely that anyone still uses one of these + devices, it was decided to drop it. +Who: Hans Verkuil + Mauro Carvalho Chehab + + --------------------------- + +What: V4L2 dpc7146 driver +When: 2.6.28 +Why: Old driver for the dpc7146 demonstration board that is no longer + relevant. The last time this was tested on actual hardware was + probably around 2002. Since this is a driver for a demonstration + board the decision was made to remove it rather than spending a + lot of effort continually updating this driver to stay in sync + with the latest internal V4L2 or I2C API. +Who: Hans Verkuil + Mauro Carvalho Chehab + +--------------------------- + What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl]) When: November 2005 Files: drivers/pcmcia/: pcmcia_ioctl.c @@ -181,19 +196,6 @@ Who: Tejun Heo --------------------------- -What: The arch/ppc and include/asm-ppc directories -When: Jun 2008 -Why: The arch/powerpc tree is the merged architecture for ppc32 and ppc64 - platforms. Currently there are efforts underway to port the remaining - arch/ppc platforms to the merged tree. New submissions to the arch/ppc - tree have been frozen with the 2.6.22 kernel release and that tree will - remain in bug-fix only mode until its scheduled removal. Platforms - that are not ported by June 2008 will be removed due to the lack of an - interested maintainer. -Who: linuxppc-dev@ozlabs.org - ---------------------------- - What: i386/x86_64 bzImage symlinks When: April 2010 diff --git a/Documentation/filesystems/configfs/Makefile b/Documentation/filesystems/configfs/Makefile new file mode 100644 index 0000000000000..be7ec5e67dbcb --- /dev/null +++ b/Documentation/filesystems/configfs/Makefile @@ -0,0 +1,3 @@ +ifneq ($(CONFIG_CONFIGFS_FS),) +obj-m += configfs_example_explicit.o configfs_example_macros.o +endif diff --git a/Documentation/filesystems/configfs/configfs.txt b/Documentation/filesystems/configfs/configfs.txt index 44c97e6accb26..fabcb0e00f25d 100644 --- a/Documentation/filesystems/configfs/configfs.txt +++ b/Documentation/filesystems/configfs/configfs.txt @@ -311,9 +311,20 @@ the subsystem must be ready for it. [An Example] The best example of these basic concepts is the simple_children -subsystem/group and the simple_child item in configfs_example.c It -shows a trivial object displaying and storing an attribute, and a simple -group creating and destroying these children. +subsystem/group and the simple_child item in configfs_example_explicit.c +and configfs_example_macros.c. It shows a trivial object displaying and +storing an attribute, and a simple group creating and destroying these +children. + +The only difference between configfs_example_explicit.c and +configfs_example_macros.c is how the attributes of the childless item +are defined. The childless item has extended attributes, each with +their own show()/store() operation. This follows a convention commonly +used in sysfs. configfs_example_explicit.c creates these attributes +by explicitly defining the structures involved. Conversely +configfs_example_macros.c uses some convenience macros from configfs.h +to define the attributes. These macros are similar to their sysfs +counterparts. [Hierarchy Navigation and the Subsystem Mutex] diff --git a/Documentation/filesystems/configfs/configfs_example.c b/Documentation/filesystems/configfs/configfs_example.c deleted file mode 100644 index 039648791701f..0000000000000 --- a/Documentation/filesystems/configfs/configfs_example.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - * vim: noexpandtab ts=8 sts=0 sw=8: - * - * configfs_example.c - This file is a demonstration module containing - * a number of configfs subsystems. - * - * 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 021110-1307, USA. - * - * Based on sysfs: - * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel - * - * configfs Copyright (C) 2005 Oracle. All rights reserved. - */ - -#include -#include -#include - -#include - - - -/* - * 01-childless - * - * This first example is a childless subsystem. It cannot create - * any config_items. It just has attributes. - * - * Note that we are enclosing the configfs_subsystem inside a container. - * This is not necessary if a subsystem has no attributes directly - * on the subsystem. See the next example, 02-simple-children, for - * such a subsystem. - */ - -struct childless { - struct configfs_subsystem subsys; - int showme; - int storeme; -}; - -struct childless_attribute { - struct configfs_attribute attr; - ssize_t (*show)(struct childless *, char *); - ssize_t (*store)(struct childless *, const char *, size_t); -}; - -static inline struct childless *to_childless(struct config_item *item) -{ - return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL; -} - -static ssize_t childless_showme_read(struct childless *childless, - char *page) -{ - ssize_t pos; - - pos = sprintf(page, "%d\n", childless->showme); - childless->showme++; - - return pos; -} - -static ssize_t childless_storeme_read(struct childless *childless, - char *page) -{ - return sprintf(page, "%d\n", childless->storeme); -} - -static ssize_t childless_storeme_write(struct childless *childless, - const char *page, - size_t count) -{ - unsigned long tmp; - char *p = (char *) page; - - tmp = simple_strtoul(p, &p, 10); - if (!p || (*p && (*p != '\n'))) - return -EINVAL; - - if (tmp > INT_MAX) - return -ERANGE; - - childless->storeme = tmp; - - return count; -} - -static ssize_t childless_description_read(struct childless *childless, - char *page) -{ - return sprintf(page, -"[01-childless]\n" -"\n" -"The childless subsystem is the simplest possible subsystem in\n" -"configfs. It does not support the creation of child config_items.\n" -"It only has a few attributes. In fact, it isn't much different\n" -"than a directory in /proc.\n"); -} - -static struct childless_attribute childless_attr_showme = { - .attr = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO }, - .show = childless_showme_read, -}; -static struct childless_attribute childless_attr_storeme = { - .attr = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR }, - .show = childless_storeme_read, - .store = childless_storeme_write, -}; -static struct childless_attribute childless_attr_description = { - .attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO }, - .show = childless_description_read, -}; - -static struct configfs_attribute *childless_attrs[] = { - &childless_attr_showme.attr, - &childless_attr_storeme.attr, - &childless_attr_description.attr, - NULL, -}; - -static ssize_t childless_attr_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - struct childless *childless = to_childless(item); - struct childless_attribute *childless_attr = - container_of(attr, struct childless_attribute, attr); - ssize_t ret = 0; - - if (childless_attr->show) - ret = childless_attr->show(childless, page); - return ret; -} - -static ssize_t childless_attr_store(struct config_item *item, - struct configfs_attribute *attr, - const char *page, size_t count) -{ - struct childless *childless = to_childless(item); - struct childless_attribute *childless_attr = - container_of(attr, struct childless_attribute, attr); - ssize_t ret = -EINVAL; - - if (childless_attr->store) - ret = childless_attr->store(childless, page, count); - return ret; -} - -static struct configfs_item_operations childless_item_ops = { - .show_attribute = childless_attr_show, - .store_attribute = childless_attr_store, -}; - -static struct config_item_type childless_type = { - .ct_item_ops = &childless_item_ops, - .ct_attrs = childless_attrs, - .ct_owner = THIS_MODULE, -}; - -static struct childless childless_subsys = { - .subsys = { - .su_group = { - .cg_item = { - .ci_namebuf = "01-childless", - .ci_type = &childless_type, - }, - }, - }, -}; - - -/* ----------------------------------------------------------------- */ - -/* - * 02-simple-children - * - * This example merely has a simple one-attribute child. Note that - * there is no extra attribute structure, as the child's attribute is - * known from the get-go. Also, there is no container for the - * subsystem, as it has no attributes of its own. - */ - -struct simple_child { - struct config_item item; - int storeme; -}; - -static inline struct simple_child *to_simple_child(struct config_item *item) -{ - return item ? container_of(item, struct simple_child, item) : NULL; -} - -static struct configfs_attribute simple_child_attr_storeme = { - .ca_owner = THIS_MODULE, - .ca_name = "storeme", - .ca_mode = S_IRUGO | S_IWUSR, -}; - -static struct configfs_attribute *simple_child_attrs[] = { - &simple_child_attr_storeme, - NULL, -}; - -static ssize_t simple_child_attr_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - ssize_t count; - struct simple_child *simple_child = to_simple_child(item); - - count = sprintf(page, "%d\n", simple_child->storeme); - - return count; -} - -static ssize_t simple_child_attr_store(struct config_item *item, - struct configfs_attribute *attr, - const char *page, size_t count) -{ - struct simple_child *simple_child = to_simple_child(item); - unsigned long tmp; - char *p = (char *) page; - - tmp = simple_strtoul(p, &p, 10); - if (!p || (*p && (*p != '\n'))) - return -EINVAL; - - if (tmp > INT_MAX) - return -ERANGE; - - simple_child->storeme = tmp; - - return count; -} - -static void simple_child_release(struct config_item *item) -{ - kfree(to_simple_child(item)); -} - -static struct configfs_item_operations simple_child_item_ops = { - .release = simple_child_release, - .show_attribute = simple_child_attr_show, - .store_attribute = simple_child_attr_store, -}; - -static struct config_item_type simple_child_type = { - .ct_item_ops = &simple_child_item_ops, - .ct_attrs = simple_child_attrs, - .ct_owner = THIS_MODULE, -}; - - -struct simple_children { - struct config_group group; -}; - -static inline struct simple_children *to_simple_children(struct config_item *item) -{ - return item ? container_of(to_config_group(item), struct simple_children, group) : NULL; -} - -static struct config_item *simple_children_make_item(struct config_group *group, const char *name) -{ - struct simple_child *simple_child; - - simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL); - if (!simple_child) - return ERR_PTR(-ENOMEM); - - - config_item_init_type_name(&simple_child->item, name, - &simple_child_type); - - simple_child->storeme = 0; - - return &simple_child->item; -} - -static struct configfs_attribute simple_children_attr_description = { - .ca_owner = THIS_MODULE, - .ca_name = "description", - .ca_mode = S_IRUGO, -}; - -static struct configfs_attribute *simple_children_attrs[] = { - &simple_children_attr_description, - NULL, -}; - -static ssize_t simple_children_attr_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - return sprintf(page, -"[02-simple-children]\n" -"\n" -"This subsystem allows the creation of child config_items. These\n" -"items have only one attribute that is readable and writeable.\n"); -} - -static void simple_children_release(struct config_item *item) -{ - kfree(to_simple_children(item)); -} - -static struct configfs_item_operations simple_children_item_ops = { - .release = simple_children_release, - .show_attribute = simple_children_attr_show, -}; - -/* - * Note that, since no extra work is required on ->drop_item(), - * no ->drop_item() is provided. - */ -static struct configfs_group_operations simple_children_group_ops = { - .make_item = simple_children_make_item, -}; - -static struct config_item_type simple_children_type = { - .ct_item_ops = &simple_children_item_ops, - .ct_group_ops = &simple_children_group_ops, - .ct_attrs = simple_children_attrs, - .ct_owner = THIS_MODULE, -}; - -static struct configfs_subsystem simple_children_subsys = { - .su_group = { - .cg_item = { - .ci_namebuf = "02-simple-children", - .ci_type = &simple_children_type, - }, - }, -}; - - -/* ----------------------------------------------------------------- */ - -/* - * 03-group-children - * - * This example reuses the simple_children group from above. However, - * the simple_children group is not the subsystem itself, it is a - * child of the subsystem. Creation of a group in the subsystem creates - * a new simple_children group. That group can then have simple_child - * children of its own. - */ - -static struct config_group *group_children_make_group(struct config_group *group, const char *name) -{ - struct simple_children *simple_children; - - simple_children = kzalloc(sizeof(struct simple_children), - GFP_KERNEL); - if (!simple_children) - return ERR_PTR(-ENOMEM); - - - config_group_init_type_name(&simple_children->group, name, - &simple_children_type); - - return &simple_children->group; -} - -static struct configfs_attribute group_children_attr_description = { - .ca_owner = THIS_MODULE, - .ca_name = "description", - .ca_mode = S_IRUGO, -}; - -static struct configfs_attribute *group_children_attrs[] = { - &group_children_attr_description, - NULL, -}; - -static ssize_t group_children_attr_show(struct config_item *item, - struct configfs_attribute *attr, - char *page) -{ - return sprintf(page, -"[03-group-children]\n" -"\n" -"This subsystem allows the creation of child config_groups. These\n" -"groups are like the subsystem simple-children.\n"); -} - -static struct configfs_item_operations group_children_item_ops = { - .show_attribute = group_children_attr_show, -}; - -/* - * Note that, since no extra work is required on ->drop_item(), - * no ->drop_item() is provided. - */ -static struct configfs_group_operations group_children_group_ops = { - .make_group = group_children_make_group, -}; - -static struct config_item_type group_children_type = { - .ct_item_ops = &group_children_item_ops, - .ct_group_ops = &group_children_group_ops, - .ct_attrs = group_children_attrs, - .ct_owner = THIS_MODULE, -}; - -static struct configfs_subsystem group_children_subsys = { - .su_group = { - .cg_item = { - .ci_namebuf = "03-group-children", - .ci_type = &group_children_type, - }, - }, -}; - -/* ----------------------------------------------------------------- */ - -/* - * We're now done with our subsystem definitions. - * For convenience in this module, here's a list of them all. It - * allows the init function to easily register them. Most modules - * will only have one subsystem, and will only call register_subsystem - * on it directly. - */ -static struct configfs_subsystem *example_subsys[] = { - &childless_subsys.subsys, - &simple_children_subsys, - &group_children_subsys, - NULL, -}; - -static int __init configfs_example_init(void) -{ - int ret; - int i; - struct configfs_subsystem *subsys; - - for (i = 0; example_subsys[i]; i++) { - subsys = example_subsys[i]; - - config_group_init(&subsys->su_group); - mutex_init(&subsys->su_mutex); - ret = configfs_register_subsystem(subsys); - if (ret) { - printk(KERN_ERR "Error %d while registering subsystem %s\n", - ret, - subsys->su_group.cg_item.ci_namebuf); - goto out_unregister; - } - } - - return 0; - -out_unregister: - for (; i >= 0; i--) { - configfs_unregister_subsystem(example_subsys[i]); - } - - return ret; -} - -static void __exit configfs_example_exit(void) -{ - int i; - - for (i = 0; example_subsys[i]; i++) { - configfs_unregister_subsystem(example_subsys[i]); - } -} - -module_init(configfs_example_init); -module_exit(configfs_example_exit); -MODULE_LICENSE("GPL"); diff --git a/Documentation/filesystems/configfs/configfs_example_explicit.c b/Documentation/filesystems/configfs/configfs_example_explicit.c new file mode 100644 index 0000000000000..d428cc9f07f39 --- /dev/null +++ b/Documentation/filesystems/configfs/configfs_example_explicit.c @@ -0,0 +1,485 @@ +/* + * vim: noexpandtab ts=8 sts=0 sw=8: + * + * configfs_example_explicit.c - This file is a demonstration module + * containing a number of configfs subsystems. It explicitly defines + * each structure without using the helper macros defined in + * configfs.h. + * + * 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 021110-1307, USA. + * + * Based on sysfs: + * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel + * + * configfs Copyright (C) 2005 Oracle. All rights reserved. + */ + +#include +#include +#include + +#include + + + +/* + * 01-childless + * + * This first example is a childless subsystem. It cannot create + * any config_items. It just has attributes. + * + * Note that we are enclosing the configfs_subsystem inside a container. + * This is not necessary if a subsystem has no attributes directly + * on the subsystem. See the next example, 02-simple-children, for + * such a subsystem. + */ + +struct childless { + struct configfs_subsystem subsys; + int showme; + int storeme; +}; + +struct childless_attribute { + struct configfs_attribute attr; + ssize_t (*show)(struct childless *, char *); + ssize_t (*store)(struct childless *, const char *, size_t); +}; + +static inline struct childless *to_childless(struct config_item *item) +{ + return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL; +} + +static ssize_t childless_showme_read(struct childless *childless, + char *page) +{ + ssize_t pos; + + pos = sprintf(page, "%d\n", childless->showme); + childless->showme++; + + return pos; +} + +static ssize_t childless_storeme_read(struct childless *childless, + char *page) +{ + return sprintf(page, "%d\n", childless->storeme); +} + +static ssize_t childless_storeme_write(struct childless *childless, + const char *page, + size_t count) +{ + unsigned long tmp; + char *p = (char *) page; + + tmp = simple_strtoul(p, &p, 10); + if (!p || (*p && (*p != '\n'))) + return -EINVAL; + + if (tmp > INT_MAX) + return -ERANGE; + + childless->storeme = tmp; + + return count; +} + +static ssize_t childless_description_read(struct childless *childless, + char *page) +{ + return sprintf(page, +"[01-childless]\n" +"\n" +"The childless subsystem is the simplest possible subsystem in\n" +"configfs. It does not support the creation of child config_items.\n" +"It only has a few attributes. In fact, it isn't much different\n" +"than a directory in /proc.\n"); +} + +static struct childless_attribute childless_attr_showme = { + .attr = { .ca_owner = THIS_MODULE, .ca_name = "showme", .ca_mode = S_IRUGO }, + .show = childless_showme_read, +}; +static struct childless_attribute childless_attr_storeme = { + .attr = { .ca_owner = THIS_MODULE, .ca_name = "storeme", .ca_mode = S_IRUGO | S_IWUSR }, + .show = childless_storeme_read, + .store = childless_storeme_write, +}; +static struct childless_attribute childless_attr_description = { + .attr = { .ca_owner = THIS_MODULE, .ca_name = "description", .ca_mode = S_IRUGO }, + .show = childless_description_read, +}; + +static struct configfs_attribute *childless_attrs[] = { + &childless_attr_showme.attr, + &childless_attr_storeme.attr, + &childless_attr_description.attr, + NULL, +}; + +static ssize_t childless_attr_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + struct childless *childless = to_childless(item); + struct childless_attribute *childless_attr = + container_of(attr, struct childless_attribute, attr); + ssize_t ret = 0; + + if (childless_attr->show) + ret = childless_attr->show(childless, page); + return ret; +} + +static ssize_t childless_attr_store(struct config_item *item, + struct configfs_attribute *attr, + const char *page, size_t count) +{ + struct childless *childless = to_childless(item); + struct childless_attribute *childless_attr = + container_of(attr, struct childless_attribute, attr); + ssize_t ret = -EINVAL; + + if (childless_attr->store) + ret = childless_attr->store(childless, page, count); + return ret; +} + +static struct configfs_item_operations childless_item_ops = { + .show_attribute = childless_attr_show, + .store_attribute = childless_attr_store, +}; + +static struct config_item_type childless_type = { + .ct_item_ops = &childless_item_ops, + .ct_attrs = childless_attrs, + .ct_owner = THIS_MODULE, +}; + +static struct childless childless_subsys = { + .subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "01-childless", + .ci_type = &childless_type, + }, + }, + }, +}; + + +/* ----------------------------------------------------------------- */ + +/* + * 02-simple-children + * + * This example merely has a simple one-attribute child. Note that + * there is no extra attribute structure, as the child's attribute is + * known from the get-go. Also, there is no container for the + * subsystem, as it has no attributes of its own. + */ + +struct simple_child { + struct config_item item; + int storeme; +}; + +static inline struct simple_child *to_simple_child(struct config_item *item) +{ + return item ? container_of(item, struct simple_child, item) : NULL; +} + +static struct configfs_attribute simple_child_attr_storeme = { + .ca_owner = THIS_MODULE, + .ca_name = "storeme", + .ca_mode = S_IRUGO | S_IWUSR, +}; + +static struct configfs_attribute *simple_child_attrs[] = { + &simple_child_attr_storeme, + NULL, +}; + +static ssize_t simple_child_attr_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + ssize_t count; + struct simple_child *simple_child = to_simple_child(item); + + count = sprintf(page, "%d\n", simple_child->storeme); + + return count; +} + +static ssize_t simple_child_attr_store(struct config_item *item, + struct configfs_attribute *attr, + const char *page, size_t count) +{ + struct simple_child *simple_child = to_simple_child(item); + unsigned long tmp; + char *p = (char *) page; + + tmp = simple_strtoul(p, &p, 10); + if (!p || (*p && (*p != '\n'))) + return -EINVAL; + + if (tmp > INT_MAX) + return -ERANGE; + + simple_child->storeme = tmp; + + return count; +} + +static void simple_child_release(struct config_item *item) +{ + kfree(to_simple_child(item)); +} + +static struct configfs_item_operations simple_child_item_ops = { + .release = simple_child_release, + .show_attribute = simple_child_attr_show, + .store_attribute = simple_child_attr_store, +}; + +static struct config_item_type simple_child_type = { + .ct_item_ops = &simple_child_item_ops, + .ct_attrs = simple_child_attrs, + .ct_owner = THIS_MODULE, +}; + + +struct simple_children { + struct config_group group; +}; + +static inline struct simple_children *to_simple_children(struct config_item *item) +{ + return item ? container_of(to_config_group(item), struct simple_children, group) : NULL; +} + +static struct config_item *simple_children_make_item(struct config_group *group, const char *name) +{ + struct simple_child *simple_child; + + simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL); + if (!simple_child) + return ERR_PTR(-ENOMEM); + + config_item_init_type_name(&simple_child->item, name, + &simple_child_type); + + simple_child->storeme = 0; + + return &simple_child->item; +} + +static struct configfs_attribute simple_children_attr_description = { + .ca_owner = THIS_MODULE, + .ca_name = "description", + .ca_mode = S_IRUGO, +}; + +static struct configfs_attribute *simple_children_attrs[] = { + &simple_children_attr_description, + NULL, +}; + +static ssize_t simple_children_attr_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + return sprintf(page, +"[02-simple-children]\n" +"\n" +"This subsystem allows the creation of child config_items. These\n" +"items have only one attribute that is readable and writeable.\n"); +} + +static void simple_children_release(struct config_item *item) +{ + kfree(to_simple_children(item)); +} + +static struct configfs_item_operations simple_children_item_ops = { + .release = simple_children_release, + .show_attribute = simple_children_attr_show, +}; + +/* + * Note that, since no extra work is required on ->drop_item(), + * no ->drop_item() is provided. + */ +static struct configfs_group_operations simple_children_group_ops = { + .make_item = simple_children_make_item, +}; + +static struct config_item_type simple_children_type = { + .ct_item_ops = &simple_children_item_ops, + .ct_group_ops = &simple_children_group_ops, + .ct_attrs = simple_children_attrs, + .ct_owner = THIS_MODULE, +}; + +static struct configfs_subsystem simple_children_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "02-simple-children", + .ci_type = &simple_children_type, + }, + }, +}; + + +/* ----------------------------------------------------------------- */ + +/* + * 03-group-children + * + * This example reuses the simple_children group from above. However, + * the simple_children group is not the subsystem itself, it is a + * child of the subsystem. Creation of a group in the subsystem creates + * a new simple_children group. That group can then have simple_child + * children of its own. + */ + +static struct config_group *group_children_make_group(struct config_group *group, const char *name) +{ + struct simple_children *simple_children; + + simple_children = kzalloc(sizeof(struct simple_children), + GFP_KERNEL); + if (!simple_children) + return ERR_PTR(-ENOMEM); + + config_group_init_type_name(&simple_children->group, name, + &simple_children_type); + + return &simple_children->group; +} + +static struct configfs_attribute group_children_attr_description = { + .ca_owner = THIS_MODULE, + .ca_name = "description", + .ca_mode = S_IRUGO, +}; + +static struct configfs_attribute *group_children_attrs[] = { + &group_children_attr_description, + NULL, +}; + +static ssize_t group_children_attr_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + return sprintf(page, +"[03-group-children]\n" +"\n" +"This subsystem allows the creation of child config_groups. These\n" +"groups are like the subsystem simple-children.\n"); +} + +static struct configfs_item_operations group_children_item_ops = { + .show_attribute = group_children_attr_show, +}; + +/* + * Note that, since no extra work is required on ->drop_item(), + * no ->drop_item() is provided. + */ +static struct configfs_group_operations group_children_group_ops = { + .make_group = group_children_make_group, +}; + +static struct config_item_type group_children_type = { + .ct_item_ops = &group_children_item_ops, + .ct_group_ops = &group_children_group_ops, + .ct_attrs = group_children_attrs, + .ct_owner = THIS_MODULE, +}; + +static struct configfs_subsystem group_children_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "03-group-children", + .ci_type = &group_children_type, + }, + }, +}; + +/* ----------------------------------------------------------------- */ + +/* + * We're now done with our subsystem definitions. + * For convenience in this module, here's a list of them all. It + * allows the init function to easily register them. Most modules + * will only have one subsystem, and will only call register_subsystem + * on it directly. + */ +static struct configfs_subsystem *example_subsys[] = { + &childless_subsys.subsys, + &simple_children_subsys, + &group_children_subsys, + NULL, +}; + +static int __init configfs_example_init(void) +{ + int ret; + int i; + struct configfs_subsystem *subsys; + + for (i = 0; example_subsys[i]; i++) { + subsys = example_subsys[i]; + + config_group_init(&subsys->su_group); + mutex_init(&subsys->su_mutex); + ret = configfs_register_subsystem(subsys); + if (ret) { + printk(KERN_ERR "Error %d while registering subsystem %s\n", + ret, + subsys->su_group.cg_item.ci_namebuf); + goto out_unregister; + } + } + + return 0; + +out_unregister: + for (; i >= 0; i--) { + configfs_unregister_subsystem(example_subsys[i]); + } + + return ret; +} + +static void __exit configfs_example_exit(void) +{ + int i; + + for (i = 0; example_subsys[i]; i++) { + configfs_unregister_subsystem(example_subsys[i]); + } +} + +module_init(configfs_example_init); +module_exit(configfs_example_exit); +MODULE_LICENSE("GPL"); diff --git a/Documentation/filesystems/configfs/configfs_example_macros.c b/Documentation/filesystems/configfs/configfs_example_macros.c new file mode 100644 index 0000000000000..d8e30a0378aa2 --- /dev/null +++ b/Documentation/filesystems/configfs/configfs_example_macros.c @@ -0,0 +1,448 @@ +/* + * vim: noexpandtab ts=8 sts=0 sw=8: + * + * configfs_example_macros.c - This file is a demonstration module + * containing a number of configfs subsystems. It uses the helper + * macros defined by configfs.h + * + * 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 021110-1307, USA. + * + * Based on sysfs: + * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel + * + * configfs Copyright (C) 2005 Oracle. All rights reserved. + */ + +#include +#include +#include + +#include + + + +/* + * 01-childless + * + * This first example is a childless subsystem. It cannot create + * any config_items. It just has attributes. + * + * Note that we are enclosing the configfs_subsystem inside a container. + * This is not necessary if a subsystem has no attributes directly + * on the subsystem. See the next example, 02-simple-children, for + * such a subsystem. + */ + +struct childless { + struct configfs_subsystem subsys; + int showme; + int storeme; +}; + +static inline struct childless *to_childless(struct config_item *item) +{ + return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct childless, subsys) : NULL; +} + +CONFIGFS_ATTR_STRUCT(childless); +#define CHILDLESS_ATTR(_name, _mode, _show, _store) \ +struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR(_name, _mode, _show, _store) +#define CHILDLESS_ATTR_RO(_name, _show) \ +struct childless_attribute childless_attr_##_name = __CONFIGFS_ATTR_RO(_name, _show); + +static ssize_t childless_showme_read(struct childless *childless, + char *page) +{ + ssize_t pos; + + pos = sprintf(page, "%d\n", childless->showme); + childless->showme++; + + return pos; +} + +static ssize_t childless_storeme_read(struct childless *childless, + char *page) +{ + return sprintf(page, "%d\n", childless->storeme); +} + +static ssize_t childless_storeme_write(struct childless *childless, + const char *page, + size_t count) +{ + unsigned long tmp; + char *p = (char *) page; + + tmp = simple_strtoul(p, &p, 10); + if (!p || (*p && (*p != '\n'))) + return -EINVAL; + + if (tmp > INT_MAX) + return -ERANGE; + + childless->storeme = tmp; + + return count; +} + +static ssize_t childless_description_read(struct childless *childless, + char *page) +{ + return sprintf(page, +"[01-childless]\n" +"\n" +"The childless subsystem is the simplest possible subsystem in\n" +"configfs. It does not support the creation of child config_items.\n" +"It only has a few attributes. In fact, it isn't much different\n" +"than a directory in /proc.\n"); +} + +CHILDLESS_ATTR_RO(showme, childless_showme_read); +CHILDLESS_ATTR(storeme, S_IRUGO | S_IWUSR, childless_storeme_read, + childless_storeme_write); +CHILDLESS_ATTR_RO(description, childless_description_read); + +static struct configfs_attribute *childless_attrs[] = { + &childless_attr_showme.attr, + &childless_attr_storeme.attr, + &childless_attr_description.attr, + NULL, +}; + +CONFIGFS_ATTR_OPS(childless); +static struct configfs_item_operations childless_item_ops = { + .show_attribute = childless_attr_show, + .store_attribute = childless_attr_store, +}; + +static struct config_item_type childless_type = { + .ct_item_ops = &childless_item_ops, + .ct_attrs = childless_attrs, + .ct_owner = THIS_MODULE, +}; + +static struct childless childless_subsys = { + .subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "01-childless", + .ci_type = &childless_type, + }, + }, + }, +}; + + +/* ----------------------------------------------------------------- */ + +/* + * 02-simple-children + * + * This example merely has a simple one-attribute child. Note that + * there is no extra attribute structure, as the child's attribute is + * known from the get-go. Also, there is no container for the + * subsystem, as it has no attributes of its own. + */ + +struct simple_child { + struct config_item item; + int storeme; +}; + +static inline struct simple_child *to_simple_child(struct config_item *item) +{ + return item ? container_of(item, struct simple_child, item) : NULL; +} + +static struct configfs_attribute simple_child_attr_storeme = { + .ca_owner = THIS_MODULE, + .ca_name = "storeme", + .ca_mode = S_IRUGO | S_IWUSR, +}; + +static struct configfs_attribute *simple_child_attrs[] = { + &simple_child_attr_storeme, + NULL, +}; + +static ssize_t simple_child_attr_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + ssize_t count; + struct simple_child *simple_child = to_simple_child(item); + + count = sprintf(page, "%d\n", simple_child->storeme); + + return count; +} + +static ssize_t simple_child_attr_store(struct config_item *item, + struct configfs_attribute *attr, + const char *page, size_t count) +{ + struct simple_child *simple_child = to_simple_child(item); + unsigned long tmp; + char *p = (char *) page; + + tmp = simple_strtoul(p, &p, 10); + if (!p || (*p && (*p != '\n'))) + return -EINVAL; + + if (tmp > INT_MAX) + return -ERANGE; + + simple_child->storeme = tmp; + + return count; +} + +static void simple_child_release(struct config_item *item) +{ + kfree(to_simple_child(item)); +} + +static struct configfs_item_operations simple_child_item_ops = { + .release = simple_child_release, + .show_attribute = simple_child_attr_show, + .store_attribute = simple_child_attr_store, +}; + +static struct config_item_type simple_child_type = { + .ct_item_ops = &simple_child_item_ops, + .ct_attrs = simple_child_attrs, + .ct_owner = THIS_MODULE, +}; + + +struct simple_children { + struct config_group group; +}; + +static inline struct simple_children *to_simple_children(struct config_item *item) +{ + return item ? container_of(to_config_group(item), struct simple_children, group) : NULL; +} + +static struct config_item *simple_children_make_item(struct config_group *group, const char *name) +{ + struct simple_child *simple_child; + + simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL); + if (!simple_child) + return ERR_PTR(-ENOMEM); + + config_item_init_type_name(&simple_child->item, name, + &simple_child_type); + + simple_child->storeme = 0; + + return &simple_child->item; +} + +static struct configfs_attribute simple_children_attr_description = { + .ca_owner = THIS_MODULE, + .ca_name = "description", + .ca_mode = S_IRUGO, +}; + +static struct configfs_attribute *simple_children_attrs[] = { + &simple_children_attr_description, + NULL, +}; + +static ssize_t simple_children_attr_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + return sprintf(page, +"[02-simple-children]\n" +"\n" +"This subsystem allows the creation of child config_items. These\n" +"items have only one attribute that is readable and writeable.\n"); +} + +static void simple_children_release(struct config_item *item) +{ + kfree(to_simple_children(item)); +} + +static struct configfs_item_operations simple_children_item_ops = { + .release = simple_children_release, + .show_attribute = simple_children_attr_show, +}; + +/* + * Note that, since no extra work is required on ->drop_item(), + * no ->drop_item() is provided. + */ +static struct configfs_group_operations simple_children_group_ops = { + .make_item = simple_children_make_item, +}; + +static struct config_item_type simple_children_type = { + .ct_item_ops = &simple_children_item_ops, + .ct_group_ops = &simple_children_group_ops, + .ct_attrs = simple_children_attrs, + .ct_owner = THIS_MODULE, +}; + +static struct configfs_subsystem simple_children_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "02-simple-children", + .ci_type = &simple_children_type, + }, + }, +}; + + +/* ----------------------------------------------------------------- */ + +/* + * 03-group-children + * + * This example reuses the simple_children group from above. However, + * the simple_children group is not the subsystem itself, it is a + * child of the subsystem. Creation of a group in the subsystem creates + * a new simple_children group. That group can then have simple_child + * children of its own. + */ + +static struct config_group *group_children_make_group(struct config_group *group, const char *name) +{ + struct simple_children *simple_children; + + simple_children = kzalloc(sizeof(struct simple_children), + GFP_KERNEL); + if (!simple_children) + return ERR_PTR(-ENOMEM); + + config_group_init_type_name(&simple_children->group, name, + &simple_children_type); + + return &simple_children->group; +} + +static struct configfs_attribute group_children_attr_description = { + .ca_owner = THIS_MODULE, + .ca_name = "description", + .ca_mode = S_IRUGO, +}; + +static struct configfs_attribute *group_children_attrs[] = { + &group_children_attr_description, + NULL, +}; + +static ssize_t group_children_attr_show(struct config_item *item, + struct configfs_attribute *attr, + char *page) +{ + return sprintf(page, +"[03-group-children]\n" +"\n" +"This subsystem allows the creation of child config_groups. These\n" +"groups are like the subsystem simple-children.\n"); +} + +static struct configfs_item_operations group_children_item_ops = { + .show_attribute = group_children_attr_show, +}; + +/* + * Note that, since no extra work is required on ->drop_item(), + * no ->drop_item() is provided. + */ +static struct configfs_group_operations group_children_group_ops = { + .make_group = group_children_make_group, +}; + +static struct config_item_type group_children_type = { + .ct_item_ops = &group_children_item_ops, + .ct_group_ops = &group_children_group_ops, + .ct_attrs = group_children_attrs, + .ct_owner = THIS_MODULE, +}; + +static struct configfs_subsystem group_children_subsys = { + .su_group = { + .cg_item = { + .ci_namebuf = "03-group-children", + .ci_type = &group_children_type, + }, + }, +}; + +/* ----------------------------------------------------------------- */ + +/* + * We're now done with our subsystem definitions. + * For convenience in this module, here's a list of them all. It + * allows the init function to easily register them. Most modules + * will only have one subsystem, and will only call register_subsystem + * on it directly. + */ +static struct configfs_subsystem *example_subsys[] = { + &childless_subsys.subsys, + &simple_children_subsys, + &group_children_subsys, + NULL, +}; + +static int __init configfs_example_init(void) +{ + int ret; + int i; + struct configfs_subsystem *subsys; + + for (i = 0; example_subsys[i]; i++) { + subsys = example_subsys[i]; + + config_group_init(&subsys->su_group); + mutex_init(&subsys->su_mutex); + ret = configfs_register_subsystem(subsys); + if (ret) { + printk(KERN_ERR "Error %d while registering subsystem %s\n", + ret, + subsys->su_group.cg_item.ci_namebuf); + goto out_unregister; + } + } + + return 0; + +out_unregister: + for (; i >= 0; i--) { + configfs_unregister_subsystem(example_subsys[i]); + } + + return ret; +} + +static void __exit configfs_example_exit(void) +{ + int i; + + for (i = 0; example_subsys[i]; i++) { + configfs_unregister_subsystem(example_subsys[i]); + } +} + +module_init(configfs_example_init); +module_exit(configfs_example_exit); +MODULE_LICENSE("GPL"); diff --git a/Documentation/filesystems/quota.txt b/Documentation/filesystems/quota.txt index a590c4093eff8..5e8de25bf0f1e 100644 --- a/Documentation/filesystems/quota.txt +++ b/Documentation/filesystems/quota.txt @@ -3,14 +3,14 @@ Quota subsystem =============== Quota subsystem allows system administrator to set limits on used space and -number of used inodes (inode is a filesystem structure which is associated -with each file or directory) for users and/or groups. For both used space and -number of used inodes there are actually two limits. The first one is called -softlimit and the second one hardlimit. An user can never exceed a hardlimit -for any resource. User is allowed to exceed softlimit but only for limited -period of time. This period is called "grace period" or "grace time". When -grace time is over, user is not able to allocate more space/inodes until he -frees enough of them to get below softlimit. +number of used inodes (inode is a filesystem structure which is associated with +each file or directory) for users and/or groups. For both used space and number +of used inodes there are actually two limits. The first one is called softlimit +and the second one hardlimit. An user can never exceed a hardlimit for any +resource (unless he has CAP_SYS_RESOURCE capability). User is allowed to exceed +softlimit but only for limited period of time. This period is called "grace +period" or "grace time". When grace time is over, user is not able to allocate +more space/inodes until he frees enough of them to get below softlimit. Quota limits (and amount of grace time) are set independently for each filesystem. @@ -53,6 +53,12 @@ in parentheses): QUOTA_NL_BSOFTLONGWARN - space (block) softlimit is exceeded longer than given grace period. QUOTA_NL_BSOFTWARN - space (block) softlimit + - four warnings are also defined for the event when user stops + exceeding some limit: + QUOTA_NL_IHARDBELOW - inode hardlimit + QUOTA_NL_ISOFTBELOW - inode softlimit + QUOTA_NL_BHARDBELOW - space (block) hardlimit + QUOTA_NL_BSOFTBELOW - space (block) softlimit QUOTA_NL_A_DEV_MAJOR (u32) - major number of a device with the affected filesystem QUOTA_NL_A_DEV_MINOR (u32) diff --git a/Documentation/ftrace.txt b/Documentation/ftrace.txt index f218f616ff6bb..d330fe3103da9 100644 --- a/Documentation/ftrace.txt +++ b/Documentation/ftrace.txt @@ -4,6 +4,7 @@ Copyright 2008 Red Hat Inc. Author: Steven Rostedt License: The GNU Free Documentation License, Version 1.2 + (dual licensed under the GPL v2) Reviewers: Elias Oltmanns, Randy Dunlap, Andrew Morton, John Kacur, and David Teigland. diff --git a/Documentation/hwmon/dme1737 b/Documentation/hwmon/dme1737 index 8f446070e64a5..001d2e70bc112 100644 --- a/Documentation/hwmon/dme1737 +++ b/Documentation/hwmon/dme1737 @@ -10,6 +10,10 @@ Supported chips: Prefix: 'sch311x' Addresses scanned: none, address read from Super-I/O config space Datasheet: http://www.nuhorizons.com/FeaturedProducts/Volume1/SMSC/311x.pdf + * SMSC SCH5027 + Prefix: 'sch5027' + Addresses scanned: I2C 0x2c, 0x2d, 0x2e + Datasheet: Provided by SMSC upon request and under NDA Authors: Juerg Haefliger @@ -22,34 +26,36 @@ Module Parameters and PWM output control functions. Using this parameter shouldn't be required since the BIOS usually takes care of this. - -Note that there is no need to use this parameter if the driver loads without -complaining. The driver will say so if it is necessary. +* probe_all_addr: bool Include non-standard LPC addresses 0x162e and 0x164e + when probing for ISA devices. This is required for the + following boards: + - VIA EPIA SN18000 Description ----------- This driver implements support for the hardware monitoring capabilities of the -SMSC DME1737 and Asus A8000 (which are the same) and SMSC SCH311x Super-I/O -chips. These chips feature monitoring of 3 temp sensors temp[1-3] (2 remote -diodes and 1 internal), 7 voltages in[0-6] (6 external and 1 internal) and up -to 6 fan speeds fan[1-6]. Additionally, the chips implement up to 5 PWM -outputs pwm[1-3,5-6] for controlling fan speeds both manually and +SMSC DME1737 and Asus A8000 (which are the same), SMSC SCH5027, and SMSC +SCH311x Super-I/O chips. These chips feature monitoring of 3 temp sensors +temp[1-3] (2 remote diodes and 1 internal), 7 voltages in[0-6] (6 external and +1 internal) and up to 6 fan speeds fan[1-6]. Additionally, the chips implement +up to 5 PWM outputs pwm[1-3,5-6] for controlling fan speeds both manually and automatically. -For the DME1737 and A8000, fan[1-2] and pwm[1-2] are always present. Fan[3-6] -and pwm[3,5-6] are optional features and their availability depends on the -configuration of the chip. The driver will detect which features are present -during initialization and create the sysfs attributes accordingly. +For the DME1737, A8000 and SCH5027, fan[1-2] and pwm[1-2] are always present. +Fan[3-6] and pwm[3,5-6] are optional features and their availability depends on +the configuration of the chip. The driver will detect which features are +present during initialization and create the sysfs attributes accordingly. For the SCH311x, fan[1-3] and pwm[1-3] are always present and fan[4-6] and pwm[5-6] don't exist. -The hardware monitoring features of the DME1737 and A8000 are only accessible -via SMBus, while the SCH311x only provides access via the ISA bus. The driver -will therefore register itself as an I2C client driver if it detects a DME1737 -or A8000 and as a platform driver if it detects a SCH311x chip. +The hardware monitoring features of the DME1737, A8000, and SCH5027 are only +accessible via SMBus, while the SCH311x only provides access via the ISA bus. +The driver will therefore register itself as an I2C client driver if it detects +a DME1737, A8000, or SCH5027 and as a platform driver if it detects a SCH311x +chip. Voltage Monitoring @@ -60,6 +66,7 @@ scaling resistors. The values returned by the driver therefore reflect true millivolts and don't need scaling. The voltage inputs are mapped as follows (the last column indicates the input ranges): +DME1737, A8000: in0: +5VTR (+5V standby) 0V - 6.64V in1: Vccp (processor core) 0V - 3V in2: VCC (internal +3.3V) 0V - 4.38V @@ -68,6 +75,24 @@ millivolts and don't need scaling. The voltage inputs are mapped as follows in5: VTR (+3.3V standby) 0V - 4.38V in6: Vbat (+3.0V) 0V - 4.38V +SCH311x: + in0: +2.5V 0V - 6.64V + in1: Vccp (processor core) 0V - 2V + in2: VCC (internal +3.3V) 0V - 4.38V + in3: +5V 0V - 6.64V + in4: +12V 0V - 16V + in5: VTR (+3.3V standby) 0V - 4.38V + in6: Vbat (+3.0V) 0V - 4.38V + +SCH5027: + in0: +5VTR (+5V standby) 0V - 6.64V + in1: Vccp (processor core) 0V - 3V + in2: VCC (internal +3.3V) 0V - 4.38V + in3: V2_IN 0V - 1.5V + in4: V1_IN 0V - 1.5V + in5: VTR (+3.3V standby) 0V - 4.38V + in6: Vbat (+3.0V) 0V - 4.38V + Each voltage input has associated min and max limits which trigger an alarm when crossed. diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index f4ce1fdbeff66..3496b7020e7c7 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 @@ -6,12 +6,14 @@ Supported chips: Prefix: 'it87' Addresses scanned: from Super I/O config space (8 I/O ports) Datasheet: Publicly available at the ITE website - http://www.ite.com.tw/ + http://www.ite.com.tw/product_info/file/pc/IT8705F_V.0.4.1.pdf * IT8712F Prefix: 'it8712' Addresses scanned: from Super I/O config space (8 I/O ports) Datasheet: Publicly available at the ITE website - http://www.ite.com.tw/ + http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.1.pdf + http://www.ite.com.tw/product_info/file/pc/Errata%20V0.1%20for%20IT8712F%20V0.9.1.pdf + http://www.ite.com.tw/product_info/file/pc/IT8712F_V0.9.3.pdf * IT8716F/IT8726F Prefix: 'it8716' Addresses scanned: from Super I/O config space (8 I/O ports) @@ -90,14 +92,13 @@ 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 supported by the driver for the IT8716F and -IT8718F but not for the IT8712F +2 additional fans. The additional fans are 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. +revisions. The 16-bit tachometer mode is enabled by the driver when one +of the above chips is detected. The IT8726F is just bit enhanced IT8716F with additional hardware for AMD power sequencing. Therefore the chip will appear as IT8716F diff --git a/Documentation/hwmon/lm85 b/Documentation/hwmon/lm85 index 9549237530cf8..6d41db7f17f8b 100644 --- a/Documentation/hwmon/lm85 +++ b/Documentation/hwmon/lm85 @@ -96,11 +96,6 @@ initial testing of the ADM1027 it was 1.00 degC steps. Analog Devices has confirmed this "bug". The ADT7463 is reported to work as described in the documentation. The current lm85 driver does not show the offset register. -The ADT7463 has a THERM asserted counter. This counter has a 22.76ms -resolution and a range of 5.8 seconds. The driver implements a 32-bit -accumulator of the counter value to extend the range to over a year. The -counter will stay at it's max value until read. - See the vendor datasheets for more information. There is application note from National (AN-1260) with some additional information about the LM85. The Analog Devices datasheet is very detailed and describes a procedure for @@ -206,13 +201,15 @@ Configuration choices: The National LM85's have two vendor specific configuration features. Tach. mode and Spinup Control. For more details on these, -see the LM85 datasheet or Application Note AN-1260. +see the LM85 datasheet or Application Note AN-1260. These features +are not currently supported by the lm85 driver. The Analog Devices ADM1027 has several vendor specific enhancements. The number of pulses-per-rev of the fans can be set, Tach monitoring can be optimized for PWM operation, and an offset can be applied to the temperatures to compensate for systemic errors in the -measurements. +measurements. These features are not currently supported by the lm85 +driver. In addition to the ADM1027 features, the ADT7463 also has Tmin control and THERM asserted counts. Automatic Tmin control acts to adjust the diff --git a/Documentation/hwmon/w83627hf b/Documentation/hwmon/w83627hf index 880a59f53da91..6ee36dbafd64a 100644 --- a/Documentation/hwmon/w83627hf +++ b/Documentation/hwmon/w83627hf @@ -40,10 +40,6 @@ Module Parameters (default is 1) Use 'init=0' to bypass initializing the chip. Try this if your computer crashes when you load the module. -* reset: int - (default is 0) - The driver used to reset the chip on load, but does no more. Use - 'reset=1' to restore the old behavior. Report if you need to do this. Description ----------- diff --git a/Documentation/hwmon/w83791d b/Documentation/hwmon/w83791d index f153b2f6d62ca..a67d3b7a70983 100644 --- a/Documentation/hwmon/w83791d +++ b/Documentation/hwmon/w83791d @@ -22,6 +22,7 @@ Credits: Additional contributors: Sven Anders + Marc Hulsman Module Parameters ----------------- @@ -67,9 +68,8 @@ 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 for fan 1/2/3 -and 1, 2, 4, 8, 16, 32, 64 or 128 for fan 4/5) to give the readings more -range or accuracy. +readings can be divided by a programmable divider (1, 2, 4, 8, 16, +32, 64 or 128 for all fans) to give the readings more range or accuracy. Voltage sensors (also known as IN sensors) report their values in millivolts. An alarm is triggered if the voltage has crossed a programmable minimum diff --git a/Documentation/i2c/upgrading-clients b/Documentation/i2c/upgrading-clients new file mode 100644 index 0000000000000..9a45f9bb6a255 --- /dev/null +++ b/Documentation/i2c/upgrading-clients @@ -0,0 +1,281 @@ +Upgrading I2C Drivers to the new 2.6 Driver Model +================================================= + +Ben Dooks + +Introduction +------------ + +This guide outlines how to alter existing Linux 2.6 client drivers from +the old to the new new binding methods. + + +Example old-style driver +------------------------ + + +struct example_state { + struct i2c_client client; + .... +}; + +static struct i2c_driver example_driver; + +static unsigned short ignore[] = { I2C_CLIENT_END }; +static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END }; + +I2C_CLIENT_INSMOD; + +static int example_attach(struct i2c_adapter *adap, int addr, int kind) +{ + struct example_state *state; + struct device *dev = &adap->dev; /* to use for dev_ reports */ + int ret; + + state = kzalloc(sizeof(struct example_state), GFP_KERNEL); + if (state == NULL) { + dev_err(dev, "failed to create our state\n"); + return -ENOMEM; + } + + example->client.addr = addr; + example->client.flags = 0; + example->client.adapter = adap; + + i2c_set_clientdata(&state->i2c_client, state); + strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE); + + ret = i2c_attach_client(&state->i2c_client); + if (ret < 0) { + dev_err(dev, "failed to attach client\n"); + kfree(state); + return ret; + } + + dev = &state->i2c_client.dev; + + /* rest of the initialisation goes here. */ + + dev_info(dev, "example client created\n"); + + return 0; +} + +static int __devexit example_detach(struct i2c_client *client) +{ + struct example_state *state = i2c_get_clientdata(client); + + i2c_detach_client(client); + kfree(state); + return 0; +} + +static int example_attach_adapter(struct i2c_adapter *adap) +{ + return i2c_probe(adap, &addr_data, example_attach); +} + +static struct i2c_driver example_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "example", + }, + .attach_adapter = example_attach_adapter, + .detach_client = __devexit_p(example_detach), + .suspend = example_suspend, + .resume = example_resume, +}; + + +Updating the client +------------------- + +The new style binding model will check against a list of supported +devices and their associated address supplied by the code registering +the busses. This means that the driver .attach_adapter and +.detach_adapter methods can be removed, along with the addr_data, +as follows: + +- static struct i2c_driver example_driver; + +- static unsigned short ignore[] = { I2C_CLIENT_END }; +- static unsigned short normal_addr[] = { OUR_ADDR, I2C_CLIENT_END }; + +- I2C_CLIENT_INSMOD; + +- static int example_attach_adapter(struct i2c_adapter *adap) +- { +- return i2c_probe(adap, &addr_data, example_attach); +- } + + static struct i2c_driver example_driver = { +- .attach_adapter = example_attach_adapter, +- .detach_client = __devexit_p(example_detach), + } + +Add the probe and remove methods to the i2c_driver, as so: + + static struct i2c_driver example_driver = { ++ .probe = example_probe, ++ .remove = __devexit_p(example_remove), + } + +Change the example_attach method to accept the new parameters +which include the i2c_client that it will be working with: + +- static int example_attach(struct i2c_adapter *adap, int addr, int kind) ++ static int example_probe(struct i2c_client *client, ++ const struct i2c_device_id *id) + +Change the name of example_attach to example_probe to align it with the +i2c_driver entry names. The rest of the probe routine will now need to be +changed as the i2c_client has already been setup for use. + +The necessary client fields have already been setup before +the probe function is called, so the following client setup +can be removed: + +- example->client.addr = addr; +- example->client.flags = 0; +- example->client.adapter = adap; +- +- strlcpy(client->i2c_client.name, "example", I2C_NAME_SIZE); + +The i2c_set_clientdata is now: + +- i2c_set_clientdata(&state->client, state); ++ i2c_set_clientdata(client, state); + +The call to i2c_attach_client is no longer needed, if the probe +routine exits successfully, then the driver will be automatically +attached by the core. Change the probe routine as so: + +- ret = i2c_attach_client(&state->i2c_client); +- if (ret < 0) { +- dev_err(dev, "failed to attach client\n"); +- kfree(state); +- return ret; +- } + + +Remove the storage of 'struct i2c_client' from the 'struct example_state' +as we are provided with the i2c_client in our example_probe. Instead we +store a pointer to it for when it is needed. + +struct example_state { +- struct i2c_client client; ++ struct i2c_client *client; + +the new i2c client as so: + +- struct device *dev = &adap->dev; /* to use for dev_ reports */ ++ struct device *dev = &i2c_client->dev; /* to use for dev_ reports */ + +And remove the change after our client is attached, as the driver no +longer needs to register a new client structure with the core: + +- dev = &state->i2c_client.dev; + +In the probe routine, ensure that the new state has the client stored +in it: + +static int example_probe(struct i2c_client *i2c_client, + const struct i2c_device_id *id) +{ + struct example_state *state; + struct device *dev = &i2c_client->dev; + int ret; + + state = kzalloc(sizeof(struct example_state), GFP_KERNEL); + if (state == NULL) { + dev_err(dev, "failed to create our state\n"); + return -ENOMEM; + } + ++ state->client = i2c_client; + +Update the detach method, by changing the name to _remove and +to delete the i2c_detach_client call. It is possible that you +can also remove the ret variable as it is not not needed for +any of the core functions. + +- static int __devexit example_detach(struct i2c_client *client) ++ static int __devexit example_remove(struct i2c_client *client) +{ + struct example_state *state = i2c_get_clientdata(client); + +- i2c_detach_client(client); + +And finally ensure that we have the correct ID table for the i2c-core +and other utilities: + ++ struct i2c_device_id example_idtable[] = { ++ { "example", 0 }, ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(i2c, example_idtable); + +static struct i2c_driver example_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "example", + }, ++ .id_table = example_ids, + + +Our driver should now look like this: + +struct example_state { + struct i2c_client *client; + .... +}; + +static int example_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct example_state *state; + struct device *dev = &client->dev; + + state = kzalloc(sizeof(struct example_state), GFP_KERNEL); + if (state == NULL) { + dev_err(dev, "failed to create our state\n"); + return -ENOMEM; + } + + state->client = client; + i2c_set_clientdata(client, state); + + /* rest of the initialisation goes here. */ + + dev_info(dev, "example client created\n"); + + return 0; +} + +static int __devexit example_remove(struct i2c_client *client) +{ + struct example_state *state = i2c_get_clientdata(client); + + kfree(state); + return 0; +} + +static struct i2c_device_id example_idtable[] = { + { "example", 0 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, example_idtable); + +static struct i2c_driver example_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "example", + }, + .id_table = example_idtable, + .probe = example_probe, + .remove = __devexit_p(example_remove), + .suspend = example_suspend, + .resume = example_resume, +}; diff --git a/Documentation/ia64/Makefile b/Documentation/ia64/Makefile new file mode 100644 index 0000000000000..b75db69ec483a --- /dev/null +++ b/Documentation/ia64/Makefile @@ -0,0 +1,8 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := aliasing-test + +# Tell kbuild to always build the programs +always := $(hostprogs-y) diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt index 3bb5f466a90db..1c6b545635a27 100644 --- a/Documentation/ioctl-number.txt +++ b/Documentation/ioctl-number.txt @@ -105,7 +105,6 @@ Code Seq# Include File Comments 'T' all linux/soundcard.h conflict! 'T' all asm-i386/ioctls.h conflict! 'U' 00-EF linux/drivers/usb/usb.h -'U' F0-FF drivers/usb/auerswald.c 'V' all linux/vt.h 'W' 00-1F linux/watchdog.h conflict! 'W' 00-1F linux/wanrouter.h conflict! diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt index 9691c7f5166c1..0705040531a53 100644 --- a/Documentation/kdump/kdump.txt +++ b/Documentation/kdump/kdump.txt @@ -65,26 +65,26 @@ Install kexec-tools 2) Download the kexec-tools user-space package from the following URL: -http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/kexec-tools-testing.tar.gz +http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/kexec-tools.tar.gz -This is a symlink to the latest version, which at the time of writing is -20061214, the only release of kexec-tools-testing so far. As other versions -are released, the older ones will remain available at -http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/ +This is a symlink to the latest version. -Note: Latest kexec-tools-testing git tree is available at +The latest kexec-tools git tree is available at: -git://git.kernel.org/pub/scm/linux/kernel/git/horms/kexec-tools-testing.git +git://git.kernel.org/pub/scm/linux/kernel/git/horms/kexec-tools.git or -http://www.kernel.org/git/?p=linux/kernel/git/horms/kexec-tools-testing.git;a=summary +http://www.kernel.org/git/?p=linux/kernel/git/horms/kexec-tools.git + +More information about kexec-tools can be found at +http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/README.html 3) Unpack the tarball with the tar command, as follows: - tar xvpzf kexec-tools-testing.tar.gz + tar xvpzf kexec-tools.tar.gz 4) Change to the kexec-tools directory, as follows: - cd kexec-tools-testing-VERSION + cd kexec-tools-VERSION 5) Configure the package, as follows: diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index 82fafe0429fed..655414821edc3 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c @@ -36,11 +36,13 @@ #include #include #include +#include #include "linux/lguest_launcher.h" #include "linux/virtio_config.h" #include "linux/virtio_net.h" #include "linux/virtio_blk.h" #include "linux/virtio_console.h" +#include "linux/virtio_rng.h" #include "linux/virtio_ring.h" #include "asm-x86/bootparam.h" /*L:110 We can ignore the 39 include files we need for this program, but I do @@ -64,8 +66,8 @@ typedef uint8_t u8; #endif /* We can have up to 256 pages for devices. */ #define DEVICE_PAGES 256 -/* This will occupy 2 pages: it must be a power of 2. */ -#define VIRTQUEUE_NUM 128 +/* This will occupy 3 pages: it must be a power of 2. */ +#define VIRTQUEUE_NUM 256 /*L:120 verbose is both a global flag and a macro. The C preprocessor allows * this, and although I wouldn't recommend it, it works quite nicely here. */ @@ -74,12 +76,19 @@ static bool verbose; do { if (verbose) printf(args); } while(0) /*:*/ -/* The pipe to send commands to the waker process */ -static int waker_fd; +/* File descriptors for the Waker. */ +struct { + int pipe[2]; + int lguest_fd; +} waker_fds; + /* The pointer to the start of guest memory. */ static void *guest_base; /* The maximum guest physical address allowed, and maximum possible. */ static unsigned long guest_limit, guest_max; +/* The pipe for signal hander to write to. */ +static int timeoutpipe[2]; +static unsigned int timeout_usec = 500; /* a per-cpu variable indicating whose vcpu is currently running */ static unsigned int __thread cpu_id; @@ -155,11 +164,14 @@ struct virtqueue /* Last available index we saw. */ u16 last_avail_idx; - /* The routine to call when the Guest pings us. */ - void (*handle_output)(int fd, struct virtqueue *me); + /* The routine to call when the Guest pings us, or timeout. */ + void (*handle_output)(int fd, struct virtqueue *me, bool timeout); /* Outstanding buffers */ unsigned int inflight; + + /* Is this blocked awaiting a timer? */ + bool blocked; }; /* Remember the arguments to the program so we can "reboot" */ @@ -190,6 +202,9 @@ static void *_convert(struct iovec *iov, size_t size, size_t align, return iov->iov_base; } +/* Wrapper for the last available index. Makes it easier to change. */ +#define lg_last_avail(vq) ((vq)->last_avail_idx) + /* The virtio configuration space is defined to be little-endian. x86 is * little-endian too, but it's nice to be explicit so we have these helpers. */ #define cpu_to_le16(v16) (v16) @@ -199,6 +214,33 @@ static void *_convert(struct iovec *iov, size_t size, size_t align, #define le32_to_cpu(v32) (v32) #define le64_to_cpu(v64) (v64) +/* Is this iovec empty? */ +static bool iov_empty(const struct iovec iov[], unsigned int num_iov) +{ + unsigned int i; + + for (i = 0; i < num_iov; i++) + if (iov[i].iov_len) + return false; + return true; +} + +/* Take len bytes from the front of this iovec. */ +static void iov_consume(struct iovec iov[], unsigned num_iov, unsigned len) +{ + unsigned int i; + + for (i = 0; i < num_iov; i++) { + unsigned int used; + + used = iov[i].iov_len < len ? iov[i].iov_len : len; + iov[i].iov_base += used; + iov[i].iov_len -= used; + len -= used; + } + assert(len == 0); +} + /* The device virtqueue descriptors are followed by feature bitmasks. */ static u8 *get_feature_bits(struct device *dev) { @@ -254,6 +296,7 @@ static void *map_zeroed_pages(unsigned int num) PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) err(1, "Mmaping %u pages of /dev/zero", num); + close(fd); return addr; } @@ -540,69 +583,64 @@ static void add_device_fd(int fd) * watch, but handing a file descriptor mask through to the kernel is fairly * icky. * - * Instead, we fork off a process which watches the file descriptors and writes + * Instead, we clone off a thread which watches the file descriptors and writes * the LHREQ_BREAK command to the /dev/lguest file descriptor to tell the Host * stop running the Guest. This causes the Launcher to return from the * /dev/lguest read with -EAGAIN, where it will write to /dev/lguest to reset * the LHREQ_BREAK and wake us up again. * * This, of course, is merely a different *kind* of icky. + * + * Given my well-known antipathy to threads, I'd prefer to use processes. But + * it's easier to share Guest memory with threads, and trivial to share the + * devices.infds as the Launcher changes it. */ -static void wake_parent(int pipefd, int lguest_fd) +static int waker(void *unused) { - /* Add the pipe from the Launcher to the fdset in the device_list, so - * we watch it, too. */ - add_device_fd(pipefd); + /* Close the write end of the pipe: only the Launcher has it open. */ + close(waker_fds.pipe[1]); for (;;) { fd_set rfds = devices.infds; unsigned long args[] = { LHREQ_BREAK, 1 }; + unsigned int maxfd = devices.max_infd; + + /* We also listen to the pipe from the Launcher. */ + FD_SET(waker_fds.pipe[0], &rfds); + if (waker_fds.pipe[0] > maxfd) + maxfd = waker_fds.pipe[0]; /* Wait until input is ready from one of the devices. */ - select(devices.max_infd+1, &rfds, NULL, NULL, NULL); - /* Is it a message from the Launcher? */ - if (FD_ISSET(pipefd, &rfds)) { - int fd; - /* If read() returns 0, it means the Launcher has - * exited. We silently follow. */ - if (read(pipefd, &fd, sizeof(fd)) == 0) - exit(0); - /* Otherwise it's telling us to change what file - * descriptors we're to listen to. Positive means - * listen to a new one, negative means stop - * listening. */ - if (fd >= 0) - FD_SET(fd, &devices.infds); - else - FD_CLR(-fd - 1, &devices.infds); - } else /* Send LHREQ_BREAK command. */ - pwrite(lguest_fd, args, sizeof(args), cpu_id); + select(maxfd+1, &rfds, NULL, NULL, NULL); + + /* Message from Launcher? */ + if (FD_ISSET(waker_fds.pipe[0], &rfds)) { + char c; + /* If this fails, then assume Launcher has exited. + * Don't do anything on exit: we're just a thread! */ + if (read(waker_fds.pipe[0], &c, 1) != 1) + _exit(0); + continue; + } + + /* Send LHREQ_BREAK command to snap the Launcher out of it. */ + pwrite(waker_fds.lguest_fd, args, sizeof(args), cpu_id); } + return 0; } /* This routine just sets up a pipe to the Waker process. */ -static int setup_waker(int lguest_fd) -{ - int pipefd[2], child; - - /* We create a pipe to talk to the Waker, and also so it knows when the - * Launcher dies (and closes pipe). */ - pipe(pipefd); - child = fork(); - if (child == -1) - err(1, "forking"); - - if (child == 0) { - /* We are the Waker: close the "writing" end of our copy of the - * pipe and start waiting for input. */ - close(pipefd[1]); - wake_parent(pipefd[0], lguest_fd); - } - /* Close the reading end of our copy of the pipe. */ - close(pipefd[0]); +static void setup_waker(int lguest_fd) +{ + /* This pipe is closed when Launcher dies, telling Waker. */ + if (pipe(waker_fds.pipe) != 0) + err(1, "Creating pipe for Waker"); + + /* Waker also needs to know the lguest fd */ + waker_fds.lguest_fd = lguest_fd; - /* Here is the fd used to talk to the waker. */ - return pipefd[1]; + if (clone(waker, malloc(4096) + 4096, CLONE_VM | SIGCHLD, NULL) == -1) + err(1, "Creating Waker"); } /* @@ -661,19 +699,22 @@ static unsigned get_vq_desc(struct virtqueue *vq, unsigned int *out_num, unsigned int *in_num) { unsigned int i, head; + u16 last_avail; /* Check it isn't doing very strange things with descriptor numbers. */ - if ((u16)(vq->vring.avail->idx - vq->last_avail_idx) > vq->vring.num) + last_avail = lg_last_avail(vq); + if ((u16)(vq->vring.avail->idx - last_avail) > vq->vring.num) errx(1, "Guest moved used index from %u to %u", - vq->last_avail_idx, vq->vring.avail->idx); + last_avail, vq->vring.avail->idx); /* If there's nothing new since last we looked, return invalid. */ - if (vq->vring.avail->idx == vq->last_avail_idx) + if (vq->vring.avail->idx == last_avail) return vq->vring.num; /* Grab the next descriptor number they're advertising, and increment * the index we've seen. */ - head = vq->vring.avail->ring[vq->last_avail_idx++ % vq->vring.num]; + head = vq->vring.avail->ring[last_avail % vq->vring.num]; + lg_last_avail(vq)++; /* If their number is silly, that's a fatal mistake. */ if (head >= vq->vring.num) @@ -821,8 +862,8 @@ static bool handle_console_input(int fd, struct device *dev) unsigned long args[] = { LHREQ_BREAK, 0 }; /* Close the fd so Waker will know it has to * exit. */ - close(waker_fd); - /* Just in case waker is blocked in BREAK, send + close(waker_fds.pipe[1]); + /* Just in case Waker is blocked in BREAK, send * unbreak now. */ write(fd, args, sizeof(args)); exit(2); @@ -839,7 +880,7 @@ static bool handle_console_input(int fd, struct device *dev) /* Handling output for console is simple: we just get all the output buffers * and write them to stdout. */ -static void handle_console_output(int fd, struct virtqueue *vq) +static void handle_console_output(int fd, struct virtqueue *vq, bool timeout) { unsigned int head, out, in; int len; @@ -854,6 +895,21 @@ static void handle_console_output(int fd, struct virtqueue *vq) } } +static void block_vq(struct virtqueue *vq) +{ + struct itimerval itm; + + vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY; + vq->blocked = true; + + itm.it_interval.tv_sec = 0; + itm.it_interval.tv_usec = 0; + itm.it_value.tv_sec = 0; + itm.it_value.tv_usec = timeout_usec; + + setitimer(ITIMER_REAL, &itm, NULL); +} + /* * The Network * @@ -861,22 +917,34 @@ static void handle_console_output(int fd, struct virtqueue *vq) * and write them (ignoring the first element) to this device's file descriptor * (/dev/net/tun). */ -static void handle_net_output(int fd, struct virtqueue *vq) +static void handle_net_output(int fd, struct virtqueue *vq, bool timeout) { - unsigned int head, out, in; + unsigned int head, out, in, num = 0; int len; struct iovec iov[vq->vring.num]; + static int last_timeout_num; /* Keep getting output buffers from the Guest until we run out. */ while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) { if (in) errx(1, "Input buffers in output queue?"); - /* Check header, but otherwise ignore it (we told the Guest we - * supported no features, so it shouldn't have anything - * interesting). */ - (void)convert(&iov[0], struct virtio_net_hdr); - len = writev(vq->dev->fd, iov+1, out-1); + len = writev(vq->dev->fd, iov, out); + if (len < 0) + err(1, "Writing network packet to tun"); add_used_and_trigger(fd, vq, head, len); + num++; + } + + /* Block further kicks and set up a timer if we saw anything. */ + if (!timeout && num) + block_vq(vq); + + if (timeout) { + if (num < last_timeout_num) + timeout_usec += 10; + else if (timeout_usec > 1) + timeout_usec--; + last_timeout_num = num; } } @@ -887,7 +955,6 @@ static bool handle_tun_input(int fd, struct device *dev) unsigned int head, in_num, out_num; int len; struct iovec iov[dev->vq->vring.num]; - struct virtio_net_hdr *hdr; /* First we need a network buffer from the Guests's recv virtqueue. */ head = get_vq_desc(dev->vq, iov, &out_num, &in_num); @@ -896,25 +963,23 @@ static bool handle_tun_input(int fd, struct device *dev) * early, the Guest won't be ready yet. Wait until the device * status says it's ready. */ /* FIXME: Actually want DRIVER_ACTIVE here. */ - if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK) - warn("network: no dma buffer!"); + + /* Now tell it we want to know if new things appear. */ + dev->vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY; + wmb(); + /* We'll turn this back on if input buffers are registered. */ return false; } else if (out_num) errx(1, "Output buffers in network recv queue?"); - /* First element is the header: we set it to 0 (no features). */ - hdr = convert(&iov[0], struct virtio_net_hdr); - hdr->flags = 0; - hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE; - /* Read the packet from the device directly into the Guest's buffer. */ - len = readv(dev->fd, iov+1, in_num-1); + len = readv(dev->fd, iov, in_num); if (len <= 0) err(1, "reading network"); /* Tell the Guest about the new packet. */ - add_used_and_trigger(fd, dev->vq, head, sizeof(*hdr) + len); + add_used_and_trigger(fd, dev->vq, head, len); verbose("tun input packet len %i [%02x %02x] (%s)\n", len, ((u8 *)iov[1].iov_base)[0], ((u8 *)iov[1].iov_base)[1], @@ -927,11 +992,18 @@ static bool handle_tun_input(int fd, struct device *dev) /*L:215 This is the callback attached to the network and console input * virtqueues: it ensures we try again, in case we stopped console or net * delivery because Guest didn't have any buffers. */ -static void enable_fd(int fd, struct virtqueue *vq) +static void enable_fd(int fd, struct virtqueue *vq, bool timeout) { add_device_fd(vq->dev->fd); - /* Tell waker to listen to it again */ - write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd)); + /* Snap the Waker out of its select loop. */ + write(waker_fds.pipe[1], "", 1); +} + +static void net_enable_fd(int fd, struct virtqueue *vq, bool timeout) +{ + /* We don't need to know again when Guest refills receive buffer. */ + vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY; + enable_fd(fd, vq, timeout); } /* When the Guest tells us they updated the status field, we handle it. */ @@ -951,7 +1023,7 @@ static void update_device_status(struct device *dev) for (vq = dev->vq; vq; vq = vq->next) { memset(vq->vring.desc, 0, vring_size(vq->config.num, getpagesize())); - vq->last_avail_idx = 0; + lg_last_avail(vq) = 0; } } else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) { warnx("Device %s configuration FAILED", dev->name); @@ -960,10 +1032,10 @@ static void update_device_status(struct device *dev) verbose("Device %s OK: offered", dev->name); for (i = 0; i < dev->desc->feature_len; i++) - verbose(" %08x", get_feature_bits(dev)[i]); + verbose(" %02x", get_feature_bits(dev)[i]); verbose(", accepted"); for (i = 0; i < dev->desc->feature_len; i++) - verbose(" %08x", get_feature_bits(dev) + verbose(" %02x", get_feature_bits(dev) [dev->desc->feature_len+i]); if (dev->ready) @@ -1000,7 +1072,7 @@ static void handle_output(int fd, unsigned long addr) if (strcmp(vq->dev->name, "console") != 0) verbose("Output to %s\n", vq->dev->name); if (vq->handle_output) - vq->handle_output(fd, vq); + vq->handle_output(fd, vq, false); return; } } @@ -1014,6 +1086,29 @@ static void handle_output(int fd, unsigned long addr) strnlen(from_guest_phys(addr), guest_limit - addr)); } +static void handle_timeout(int fd) +{ + char buf[32]; + struct device *i; + struct virtqueue *vq; + + /* Clear the pipe */ + read(timeoutpipe[0], buf, sizeof(buf)); + + /* Check each device and virtqueue: flush blocked ones. */ + for (i = devices.dev; i; i = i->next) { + for (vq = i->vq; vq; vq = vq->next) { + if (!vq->blocked) + continue; + + vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY; + vq->blocked = false; + if (vq->handle_output) + vq->handle_output(fd, vq, true); + } + } +} + /* This is called when the Waker wakes us up: check for incoming file * descriptors. */ static void handle_input(int fd) @@ -1024,16 +1119,20 @@ static void handle_input(int fd) for (;;) { struct device *i; fd_set fds = devices.infds; + int num; + num = select(devices.max_infd+1, &fds, NULL, NULL, &poll); + /* Could get interrupted */ + if (num < 0) + continue; /* If nothing is ready, we're done. */ - if (select(devices.max_infd+1, &fds, NULL, NULL, &poll) == 0) + if (num == 0) break; /* Otherwise, call the device(s) which have readable file * descriptors and a method of handling them. */ for (i = devices.dev; i; i = i->next) { if (i->handle_input && FD_ISSET(i->fd, &fds)) { - int dev_fd; if (i->handle_input(fd, i)) continue; @@ -1043,13 +1142,12 @@ static void handle_input(int fd) * buffers to deliver into. Console also uses * it when it discovers that stdin is closed. */ FD_CLR(i->fd, &devices.infds); - /* Tell waker to ignore it too, by sending a - * negative fd number (-1, since 0 is a valid - * FD number). */ - dev_fd = -i->fd - 1; - write(waker_fd, &dev_fd, sizeof(dev_fd)); } } + + /* Is this the timeout fd? */ + if (FD_ISSET(timeoutpipe[0], &fds)) + handle_timeout(fd); } } @@ -1098,7 +1196,7 @@ static struct lguest_device_desc *new_dev_desc(u16 type) /* Each device descriptor is followed by the description of its virtqueues. We * specify how many descriptors the virtqueue is to have. */ static void add_virtqueue(struct device *dev, unsigned int num_descs, - void (*handle_output)(int fd, struct virtqueue *me)) + void (*handle_output)(int, struct virtqueue *, bool)) { unsigned int pages; struct virtqueue **i, *vq = malloc(sizeof(*vq)); @@ -1114,6 +1212,7 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs, vq->last_avail_idx = 0; vq->dev = dev; vq->inflight = 0; + vq->blocked = false; /* Initialize the configuration. */ vq->config.num = num_descs; @@ -1246,6 +1345,24 @@ static void setup_console(void) } /*:*/ +static void timeout_alarm(int sig) +{ + write(timeoutpipe[1], "", 1); +} + +static void setup_timeout(void) +{ + if (pipe(timeoutpipe) != 0) + err(1, "Creating timeout pipe"); + + if (fcntl(timeoutpipe[1], F_SETFL, + fcntl(timeoutpipe[1], F_GETFL) | O_NONBLOCK) != 0) + err(1, "Making timeout pipe nonblocking"); + + add_device_fd(timeoutpipe[0]); + signal(SIGALRM, timeout_alarm); +} + /*M:010 Inter-guest networking is an interesting area. Simplest is to have a * --sharenet= option which opens or creates a named pipe. This can be * used to send packets to another guest in a 1:1 manner. @@ -1264,10 +1381,25 @@ static void setup_console(void) static u32 str2ip(const char *ipaddr) { - unsigned int byte[4]; + unsigned int b[4]; - sscanf(ipaddr, "%u.%u.%u.%u", &byte[0], &byte[1], &byte[2], &byte[3]); - return (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | byte[3]; + if (sscanf(ipaddr, "%u.%u.%u.%u", &b[0], &b[1], &b[2], &b[3]) != 4) + errx(1, "Failed to parse IP address '%s'", ipaddr); + return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; +} + +static void str2mac(const char *macaddr, unsigned char mac[6]) +{ + unsigned int m[6]; + if (sscanf(macaddr, "%02x:%02x:%02x:%02x:%02x:%02x", + &m[0], &m[1], &m[2], &m[3], &m[4], &m[5]) != 6) + errx(1, "Failed to parse mac address '%s'", macaddr); + mac[0] = m[0]; + mac[1] = m[1]; + mac[2] = m[2]; + mac[3] = m[3]; + mac[4] = m[4]; + mac[5] = m[5]; } /* This code is "adapted" from libbridge: it attaches the Host end of the @@ -1288,6 +1420,7 @@ static void add_to_bridge(int fd, const char *if_name, const char *br_name) errx(1, "interface %s does not exist!", if_name); strncpy(ifr.ifr_name, br_name, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ-1] = '\0'; ifr.ifr_ifindex = ifidx; if (ioctl(fd, SIOCBRADDIF, &ifr) < 0) err(1, "can't add %s to bridge %s", if_name, br_name); @@ -1296,64 +1429,75 @@ static void add_to_bridge(int fd, const char *if_name, const char *br_name) /* This sets up the Host end of the network device with an IP address, brings * it up so packets will flow, the copies the MAC address into the hwaddr * pointer. */ -static void configure_device(int fd, const char *devname, u32 ipaddr, - unsigned char hwaddr[6]) +static void configure_device(int fd, const char *tapif, u32 ipaddr) { struct ifreq ifr; struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr; - /* Don't read these incantations. Just cut & paste them like I did! */ memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, devname); + strcpy(ifr.ifr_name, tapif); + + /* Don't read these incantations. Just cut & paste them like I did! */ sin->sin_family = AF_INET; sin->sin_addr.s_addr = htonl(ipaddr); if (ioctl(fd, SIOCSIFADDR, &ifr) != 0) - err(1, "Setting %s interface address", devname); + err(1, "Setting %s interface address", tapif); ifr.ifr_flags = IFF_UP; if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0) - err(1, "Bringing interface %s up", devname); - - /* SIOC stands for Socket I/O Control. G means Get (vs S for Set - * above). IF means Interface, and HWADDR is hardware address. - * Simple! */ - if (ioctl(fd, SIOCGIFHWADDR, &ifr) != 0) - err(1, "getting hw address for %s", devname); - memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, 6); + err(1, "Bringing interface %s up", tapif); } -/*L:195 Our network is a Host<->Guest network. This can either use bridging or - * routing, but the principle is the same: it uses the "tun" device to inject - * packets into the Host as if they came in from a normal network card. We - * just shunt packets between the Guest and the tun device. */ -static void setup_tun_net(const char *arg) +static int get_tun_device(char tapif[IFNAMSIZ]) { - struct device *dev; struct ifreq ifr; - int netfd, ipfd; - u32 ip; - const char *br_name = NULL; - struct virtio_net_config conf; + int netfd; + + /* Start with this zeroed. Messy but sure. */ + memset(&ifr, 0, sizeof(ifr)); /* We open the /dev/net/tun device and tell it we want a tap device. A * tap device is like a tun device, only somehow different. To tell * the truth, I completely blundered my way through this code, but it * works now! */ netfd = open_or_die("/dev/net/tun", O_RDWR); - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR; strcpy(ifr.ifr_name, "tap%d"); if (ioctl(netfd, TUNSETIFF, &ifr) != 0) err(1, "configuring /dev/net/tun"); + + if (ioctl(netfd, TUNSETOFFLOAD, + TUN_F_CSUM|TUN_F_TSO4|TUN_F_TSO6|TUN_F_TSO_ECN) != 0) + err(1, "Could not set features for tun device"); + /* We don't need checksums calculated for packets coming in this * device: trust us! */ ioctl(netfd, TUNSETNOCSUM, 1); + memcpy(tapif, ifr.ifr_name, IFNAMSIZ); + return netfd; +} + +/*L:195 Our network is a Host<->Guest network. This can either use bridging or + * routing, but the principle is the same: it uses the "tun" device to inject + * packets into the Host as if they came in from a normal network card. We + * just shunt packets between the Guest and the tun device. */ +static void setup_tun_net(char *arg) +{ + struct device *dev; + int netfd, ipfd; + u32 ip = INADDR_ANY; + bool bridging = false; + char tapif[IFNAMSIZ], *p; + struct virtio_net_config conf; + + netfd = get_tun_device(tapif); + /* First we create a new network device. */ dev = new_device("net", VIRTIO_ID_NET, netfd, handle_tun_input); /* Network devices need a receive and a send queue, just like * console. */ - add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd); + add_virtqueue(dev, VIRTQUEUE_NUM, net_enable_fd); add_virtqueue(dev, VIRTQUEUE_NUM, handle_net_output); /* We need a socket to perform the magic network ioctls to bring up the @@ -1364,28 +1508,50 @@ static void setup_tun_net(const char *arg) /* If the command line was --tunnet=bridge: do bridging. */ if (!strncmp(BRIDGE_PFX, arg, strlen(BRIDGE_PFX))) { - ip = INADDR_ANY; - br_name = arg + strlen(BRIDGE_PFX); - add_to_bridge(ipfd, ifr.ifr_name, br_name); - } else /* It is an IP address to set up the device with */ + arg += strlen(BRIDGE_PFX); + bridging = true; + } + + /* A mac address may follow the bridge name or IP address */ + p = strchr(arg, ':'); + if (p) { + str2mac(p+1, conf.mac); + add_feature(dev, VIRTIO_NET_F_MAC); + *p = '\0'; + } + + /* arg is now either an IP address or a bridge name */ + if (bridging) + add_to_bridge(ipfd, tapif, arg); + else ip = str2ip(arg); - /* Set up the tun device, and get the mac address for the interface. */ - configure_device(ipfd, ifr.ifr_name, ip, conf.mac); + /* Set up the tun device. */ + configure_device(ipfd, tapif, ip); - /* Tell Guest what MAC address to use. */ - add_feature(dev, VIRTIO_NET_F_MAC); add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY); + /* Expect Guest to handle everything except UFO */ + add_feature(dev, VIRTIO_NET_F_CSUM); + add_feature(dev, VIRTIO_NET_F_GUEST_CSUM); + add_feature(dev, VIRTIO_NET_F_GUEST_TSO4); + add_feature(dev, VIRTIO_NET_F_GUEST_TSO6); + add_feature(dev, VIRTIO_NET_F_GUEST_ECN); + add_feature(dev, VIRTIO_NET_F_HOST_TSO4); + add_feature(dev, VIRTIO_NET_F_HOST_TSO6); + add_feature(dev, VIRTIO_NET_F_HOST_ECN); set_config(dev, sizeof(conf), &conf); /* We don't need the socket any more; setup is done. */ close(ipfd); - verbose("device %u: tun net %u.%u.%u.%u\n", - devices.device_num++, - (u8)(ip>>24),(u8)(ip>>16),(u8)(ip>>8),(u8)ip); - if (br_name) - verbose("attached to bridge: %s\n", br_name); + devices.device_num++; + + if (bridging) + verbose("device %u: tun %s attached to bridge: %s\n", + devices.device_num, tapif, arg); + else + verbose("device %u: tun %s: %s\n", + devices.device_num, tapif, arg); } /* Our block (disk) device should be really simple: the Guest asks for a block @@ -1550,7 +1716,7 @@ static bool handle_io_finish(int fd, struct device *dev) } /* When the Guest submits some I/O, we just need to wake the I/O thread. */ -static void handle_virtblk_output(int fd, struct virtqueue *vq) +static void handle_virtblk_output(int fd, struct virtqueue *vq, bool timeout) { struct vblk_info *vblk = vq->dev->priv; char c = 0; @@ -1621,6 +1787,64 @@ static void setup_block_file(const char *filename) verbose("device %u: virtblock %llu sectors\n", devices.device_num, le64_to_cpu(conf.capacity)); } + +/* Our random number generator device reads from /dev/random into the Guest's + * input buffers. The usual case is that the Guest doesn't want random numbers + * and so has no buffers although /dev/random is still readable, whereas + * console is the reverse. + * + * The same logic applies, however. */ +static bool handle_rng_input(int fd, struct device *dev) +{ + int len; + unsigned int head, in_num, out_num, totlen = 0; + struct iovec iov[dev->vq->vring.num]; + + /* First we need a buffer from the Guests's virtqueue. */ + head = get_vq_desc(dev->vq, iov, &out_num, &in_num); + + /* If they're not ready for input, stop listening to this file + * descriptor. We'll start again once they add an input buffer. */ + if (head == dev->vq->vring.num) + return false; + + if (out_num) + errx(1, "Output buffers in rng?"); + + /* This is why we convert to iovecs: the readv() call uses them, and so + * it reads straight into the Guest's buffer. We loop to make sure we + * fill it. */ + while (!iov_empty(iov, in_num)) { + len = readv(dev->fd, iov, in_num); + if (len <= 0) + err(1, "Read from /dev/random gave %i", len); + iov_consume(iov, in_num, len); + totlen += len; + } + + /* Tell the Guest about the new input. */ + add_used_and_trigger(fd, dev->vq, head, totlen); + + /* Everything went OK! */ + return true; +} + +/* And this creates a "hardware" random number device for the Guest. */ +static void setup_rng(void) +{ + struct device *dev; + int fd; + + fd = open_or_die("/dev/random", O_RDONLY); + + /* The device responds to return from I/O thread. */ + dev = new_device("rng", VIRTIO_ID_RNG, fd, handle_rng_input); + + /* The device has one virtqueue, where the Guest places inbufs. */ + add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd); + + verbose("device %u: rng\n", devices.device_num++); +} /* That's the end of device setup. */ /*L:230 Reboot is pretty easy: clean up and exec() the Launcher afresh. */ @@ -1628,11 +1852,12 @@ static void __attribute__((noreturn)) restart_guest(void) { unsigned int i; - /* Closing pipes causes the Waker thread and io_threads to die, and - * closing /dev/lguest cleans up the Guest. Since we don't track all - * open fds, we simply close everything beyond stderr. */ + /* Since we don't track all open fds, we simply close everything beyond + * stderr. */ for (i = 3; i < FD_SETSIZE; i++) close(i); + + /* The exec automatically gets rid of the I/O and Waker threads. */ execv(main_args[0], main_args); err(1, "Could not exec %s", main_args[0]); } @@ -1663,7 +1888,7 @@ static void __attribute__((noreturn)) run_guest(int lguest_fd) /* ERESTART means that we need to reboot the guest */ } else if (errno == ERESTART) { restart_guest(); - /* EAGAIN means the Waker wanted us to look at some input. + /* EAGAIN means a signal (timeout). * Anything else means a bug or incompatible change. */ } else if (errno != EAGAIN) err(1, "Running guest failed"); @@ -1691,13 +1916,14 @@ static struct option opts[] = { { "verbose", 0, NULL, 'v' }, { "tunnet", 1, NULL, 't' }, { "block", 1, NULL, 'b' }, + { "rng", 0, NULL, 'r' }, { "initrd", 1, NULL, 'i' }, { NULL }, }; static void usage(void) { errx(1, "Usage: lguest [--verbose] " - "[--tunnet=(|bridge:)\n" + "[--tunnet=(:|bridge::)\n" "|--block=|--initrd=]...\n" " vmlinux [args...]"); } @@ -1765,6 +1991,9 @@ int main(int argc, char *argv[]) case 'b': setup_block_file(optarg); break; + case 'r': + setup_rng(); + break; case 'i': initrd_name = optarg; break; @@ -1783,6 +2012,9 @@ int main(int argc, char *argv[]) /* We always have a console device */ setup_console(); + /* We can timeout waiting for Guest network transmit. */ + setup_timeout(); + /* Now we load the kernel */ start = load_kernel(open_or_die(argv[optind+1], O_RDONLY)); @@ -1826,10 +2058,10 @@ int main(int argc, char *argv[]) * /dev/lguest file descriptor. */ lguest_fd = tell_kernel(pgdir, start); - /* We fork off a child process, which wakes the Launcher whenever one - * of the input file descriptors needs attention. We call this the - * Waker, and we'll cover it in a moment. */ - waker_fd = setup_waker(lguest_fd); + /* We clone off a thread, which wakes the Launcher whenever one of the + * input file descriptors needs attention. We call this the Waker, and + * we'll cover it in a moment. */ + setup_waker(lguest_fd); /* Finally, run the Guest. This doesn't return. */ run_guest(lguest_fd); diff --git a/Documentation/networking/Makefile b/Documentation/networking/Makefile new file mode 100644 index 0000000000000..6d8af1ac56c41 --- /dev/null +++ b/Documentation/networking/Makefile @@ -0,0 +1,8 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := ifenslave + +# Tell kbuild to always build the programs +always := $(hostprogs-y) diff --git a/Documentation/networking/ifenslave.c b/Documentation/networking/ifenslave.c index a12059886755c..1b96ccda38365 100644 --- a/Documentation/networking/ifenslave.c +++ b/Documentation/networking/ifenslave.c @@ -1081,7 +1081,7 @@ static int set_if_addr(char *master_ifname, char *slave_ifname) } - ipaddr = ifr.ifr_addr.sa_data; + ipaddr = (unsigned char *)ifr.ifr_addr.sa_data; v_print("Interface '%s': set IP %s to %d.%d.%d.%d\n", slave_ifname, ifra[i].desc, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]); diff --git a/Documentation/pcmcia/Makefile b/Documentation/pcmcia/Makefile new file mode 100644 index 0000000000000..accde871ae777 --- /dev/null +++ b/Documentation/pcmcia/Makefile @@ -0,0 +1,10 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := crc32hash + +# Tell kbuild to always build the programs +always := $(hostprogs-y) + +HOSTCFLAGS_crc32hash.o += -I$(objtree)/usr/include diff --git a/Documentation/pcmcia/crc32hash.c b/Documentation/pcmcia/crc32hash.c index cbc36d299af80..4210e5abab8a8 100644 --- a/Documentation/pcmcia/crc32hash.c +++ b/Documentation/pcmcia/crc32hash.c @@ -26,7 +26,7 @@ int main(int argc, char **argv) { printf("no string passed as argument\n"); return -1; } - result = crc32(argv[1], strlen(argv[1])); + result = crc32((unsigned char const *)argv[1], strlen(argv[1])); printf("0x%x\n", result); return 0; } diff --git a/Documentation/power/pm_qos_interface.txt b/Documentation/power/pm_qos_interface.txt index 49adb1a335148..c40866e8b9576 100644 --- a/Documentation/power/pm_qos_interface.txt +++ b/Documentation/power/pm_qos_interface.txt @@ -1,4 +1,4 @@ -PM quality of Service interface. +PM Quality Of Service Interface. This interface provides a kernel and user mode interface for registering performance expectations by drivers, subsystems and user space applications on @@ -7,6 +7,11 @@ one of the parameters. Currently we have {cpu_dma_latency, network_latency, network_throughput} as the initial set of pm_qos parameters. +Each parameters have defined units: + * latency: usec + * timeout: usec + * throughput: kbs (kilo bit / sec) + The infrastructure exposes multiple misc device nodes one per implemented parameter. The set of parameters implement is defined by pm_qos_power_init() and pm_qos_params.h. This is done because having the available parameters diff --git a/Documentation/power/power_supply_class.txt b/Documentation/power/power_supply_class.txt index a8686e5a68579..c6cd4956047c2 100644 --- a/Documentation/power/power_supply_class.txt +++ b/Documentation/power/power_supply_class.txt @@ -101,6 +101,10 @@ of charge when battery became full/empty". It also could mean "value of charge when battery considered full/empty at given conditions (temperature, age)". I.e. these attributes represents real thresholds, not design values. +CHARGE_COUNTER - the current charge counter (in µAh). This could easily +be negative; there is no empty or full value. It is only useful for +relative, time-based measurements. + ENERGY_FULL, ENERGY_EMPTY - same as above but for energy. CAPACITY - capacity in percents. diff --git a/Documentation/power/regulator/consumer.txt b/Documentation/power/regulator/consumer.txt new file mode 100644 index 0000000000000..82b7a43aadba7 --- /dev/null +++ b/Documentation/power/regulator/consumer.txt @@ -0,0 +1,182 @@ +Regulator Consumer Driver Interface +=================================== + +This text describes the regulator interface for consumer device drivers. +Please see overview.txt for a description of the terms used in this text. + + +1. Consumer Regulator Access (static & dynamic drivers) +======================================================= + +A consumer driver can get access to it's supply regulator by calling :- + +regulator = regulator_get(dev, "Vcc"); + +The consumer passes in it's struct device pointer and power supply ID. The core +then finds the correct regulator by consulting a machine specific lookup table. +If the lookup is successful then this call will return a pointer to the struct +regulator that supplies this consumer. + +To release the regulator the consumer driver should call :- + +regulator_put(regulator); + +Consumers can be supplied by more than one regulator e.g. codec consumer with +analog and digital supplies :- + +digital = regulator_get(dev, "Vcc"); /* digital core */ +analog = regulator_get(dev, "Avdd"); /* analog */ + +The regulator access functions regulator_get() and regulator_put() will +usually be called in your device drivers probe() and remove() respectively. + + +2. Regulator Output Enable & Disable (static & dynamic drivers) +==================================================================== + +A consumer can enable it's power supply by calling:- + +int regulator_enable(regulator); + +NOTE: The supply may already be enabled before regulator_enabled() is called. +This may happen if the consumer shares the regulator or the regulator has been +previously enabled by bootloader or kernel board initialization code. + +A consumer can determine if a regulator is enabled by calling :- + +int regulator_is_enabled(regulator); + +This will return > zero when the regulator is enabled. + + +A consumer can disable it's supply when no longer needed by calling :- + +int regulator_disable(regulator); + +NOTE: This may not disable the supply if it's shared with other consumers. The +regulator will only be disabled when the enabled reference count is zero. + +Finally, a regulator can be forcefully disabled in the case of an emergency :- + +int regulator_force_disable(regulator); + +NOTE: this will immediately and forcefully shutdown the regulator output. All +consumers will be powered off. + + +3. Regulator Voltage Control & Status (dynamic drivers) +====================================================== + +Some consumer drivers need to be able to dynamically change their supply +voltage to match system operating points. e.g. CPUfreq drivers can scale +voltage along with frequency to save power, SD drivers may need to select the +correct card voltage, etc. + +Consumers can control their supply voltage by calling :- + +int regulator_set_voltage(regulator, min_uV, max_uV); + +Where min_uV and max_uV are the minimum and maximum acceptable voltages in +microvolts. + +NOTE: this can be called when the regulator is enabled or disabled. If called +when enabled, then the voltage changes instantly, otherwise the voltage +configuration changes and the voltage is physically set when the regulator is +next enabled. + +The regulators configured voltage output can be found by calling :- + +int regulator_get_voltage(regulator); + +NOTE: get_voltage() will return the configured output voltage whether the +regulator is enabled or disabled and should NOT be used to determine regulator +output state. However this can be used in conjunction with is_enabled() to +determine the regulator physical output voltage. + + +4. Regulator Current Limit Control & Status (dynamic drivers) +=========================================================== + +Some consumer drivers need to be able to dynamically change their supply +current limit to match system operating points. e.g. LCD backlight driver can +change the current limit to vary the backlight brightness, USB drivers may want +to set the limit to 500mA when supplying power. + +Consumers can control their supply current limit by calling :- + +int regulator_set_current_limit(regulator, min_uV, max_uV); + +Where min_uA and max_uA are the minimum and maximum acceptable current limit in +microamps. + +NOTE: this can be called when the regulator is enabled or disabled. If called +when enabled, then the current limit changes instantly, otherwise the current +limit configuration changes and the current limit is physically set when the +regulator is next enabled. + +A regulators current limit can be found by calling :- + +int regulator_get_current_limit(regulator); + +NOTE: get_current_limit() will return the current limit whether the regulator +is enabled or disabled and should not be used to determine regulator current +load. + + +5. Regulator Operating Mode Control & Status (dynamic drivers) +============================================================= + +Some consumers can further save system power by changing the operating mode of +their supply regulator to be more efficient when the consumers operating state +changes. e.g. consumer driver is idle and subsequently draws less current + +Regulator operating mode can be changed indirectly or directly. + +Indirect operating mode control. +-------------------------------- +Consumer drivers can request a change in their supply regulator operating mode +by calling :- + +int regulator_set_optimum_mode(struct regulator *regulator, int load_uA); + +This will cause the core to recalculate the total load on the regulator (based +on all it's consumers) and change operating mode (if necessary and permitted) +to best match the current operating load. + +The load_uA value can be determined from the consumers datasheet. e.g.most +datasheets have tables showing the max current consumed in certain situations. + +Most consumers will use indirect operating mode control since they have no +knowledge of the regulator or whether the regulator is shared with other +consumers. + +Direct operating mode control. +------------------------------ +Bespoke or tightly coupled drivers may want to directly control regulator +operating mode depending on their operating point. This can be achieved by +calling :- + +int regulator_set_mode(struct regulator *regulator, unsigned int mode); +unsigned int regulator_get_mode(struct regulator *regulator); + +Direct mode will only be used by consumers that *know* about the regulator and +are not sharing the regulator with other consumers. + + +6. Regulator Events +=================== +Regulators can notify consumers of external events. Events could be received by +consumers under regulator stress or failure conditions. + +Consumers can register interest in regulator events by calling :- + +int regulator_register_notifier(struct regulator *regulator, + struct notifier_block *nb); + +Consumers can uregister interest by calling :- + +int regulator_unregister_notifier(struct regulator *regulator, + struct notifier_block *nb); + +Regulators use the kernel notifier framework to send event to thier interested +consumers. diff --git a/Documentation/power/regulator/machine.txt b/Documentation/power/regulator/machine.txt new file mode 100644 index 0000000000000..c9a35665cf707 --- /dev/null +++ b/Documentation/power/regulator/machine.txt @@ -0,0 +1,101 @@ +Regulator Machine Driver Interface +=================================== + +The regulator machine driver interface is intended for board/machine specific +initialisation code to configure the regulator subsystem. Typical things that +machine drivers would do are :- + + 1. Regulator -> Device mapping. + 2. Regulator supply configuration. + 3. Power Domain constraint setting. + + + +1. Regulator -> device mapping +============================== +Consider the following machine :- + + Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V] + | + +-> [Consumer B @ 3.3V] + +The drivers for consumers A & B must be mapped to the correct regulator in +order to control their power supply. This mapping can be achieved in machine +initialisation code by calling :- + +int regulator_set_device_supply(const char *regulator, struct device *dev, + const char *supply); + +and is shown with the following code :- + +regulator_set_device_supply("Regulator-1", devB, "Vcc"); +regulator_set_device_supply("Regulator-2", devA, "Vcc"); + +This maps Regulator-1 to the 'Vcc' supply for Consumer B and maps Regulator-2 +to the 'Vcc' supply for Consumer A. + + +2. Regulator supply configuration. +================================== +Consider the following machine (again) :- + + Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V] + | + +-> [Consumer B @ 3.3V] + +Regulator-1 supplies power to Regulator-2. This relationship must be registered +with the core so that Regulator-1 is also enabled when Consumer A enables it's +supply (Regulator-2). + +This relationship can be register with the core via :- + +int regulator_set_supply(const char *regulator, const char *regulator_supply); + +In this example we would use the following code :- + +regulator_set_supply("Regulator-2", "Regulator-1"); + +Relationships can be queried by calling :- + +const char *regulator_get_supply(const char *regulator); + + +3. Power Domain constraint setting. +=================================== +Each power domain within a system has physical constraints on voltage and +current. This must be defined in software so that the power domain is always +operated within specifications. + +Consider the following machine (again) :- + + Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V] + | + +-> [Consumer B @ 3.3V] + +This gives us two regulators and two power domains: + + Domain 1: Regulator-2, Consumer B. + Domain 2: Consumer A. + +Constraints can be registered by calling :- + +int regulator_set_platform_constraints(const char *regulator, + struct regulation_constraints *constraints); + +The example is defined as follows :- + +struct regulation_constraints domain_1 = { + .min_uV = 3300000, + .max_uV = 3300000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, +}; + +struct regulation_constraints domain_2 = { + .min_uV = 1800000, + .max_uV = 2000000, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + .valid_modes_mask = REGULATOR_MODE_NORMAL, +}; + +regulator_set_platform_constraints("Regulator-1", &domain_1); +regulator_set_platform_constraints("Regulator-2", &domain_2); diff --git a/Documentation/power/regulator/overview.txt b/Documentation/power/regulator/overview.txt new file mode 100644 index 0000000000000..bdcb332bd7fbe --- /dev/null +++ b/Documentation/power/regulator/overview.txt @@ -0,0 +1,171 @@ +Linux voltage and current regulator framework +============================================= + +About +===== + +This framework is designed to provide a standard kernel interface to control +voltage and current regulators. + +The intention is to allow systems to dynamically control regulator power output +in order to save power and prolong battery life. This applies to both voltage +regulators (where voltage output is controllable) and current sinks (where +current limit is controllable). + +(C) 2008 Wolfson Microelectronics PLC. +Author: Liam Girdwood + + +Nomenclature +============ + +Some terms used in this document:- + + o Regulator - Electronic device that supplies power to other devices. + Most regulators can enable and disable their output whilst + some can control their output voltage and or current. + + Input Voltage -> Regulator -> Output Voltage + + + o PMIC - Power Management IC. An IC that contains numerous regulators + and often contains other susbsystems. + + + o Consumer - Electronic device that is supplied power by a regulator. + Consumers can be classified into two types:- + + Static: consumer does not change it's supply voltage or + current limit. It only needs to enable or disable it's + power supply. It's supply voltage is set by the hardware, + bootloader, firmware or kernel board initialisation code. + + Dynamic: consumer needs to change it's supply voltage or + current limit to meet operation demands. + + + o Power Domain - Electronic circuit that is supplied it's input power by the + output power of a regulator, switch or by another power + domain. + + The supply regulator may be behind a switch(s). i.e. + + Regulator -+-> Switch-1 -+-> Switch-2 --> [Consumer A] + | | + | +-> [Consumer B], [Consumer C] + | + +-> [Consumer D], [Consumer E] + + That is one regulator and three power domains: + + Domain 1: Switch-1, Consumers D & E. + Domain 2: Switch-2, Consumers B & C. + Domain 3: Consumer A. + + and this represents a "supplies" relationship: + + Domain-1 --> Domain-2 --> Domain-3. + + A power domain may have regulators that are supplied power + by other regulators. i.e. + + Regulator-1 -+-> Regulator-2 -+-> [Consumer A] + | + +-> [Consumer B] + + This gives us two regulators and two power domains: + + Domain 1: Regulator-2, Consumer B. + Domain 2: Consumer A. + + and a "supplies" relationship: + + Domain-1 --> Domain-2 + + + o Constraints - Constraints are used to define power levels for performance + and hardware protection. Constraints exist at three levels: + + Regulator Level: This is defined by the regulator hardware + operating parameters and is specified in the regulator + datasheet. i.e. + + - voltage output is in the range 800mV -> 3500mV. + - regulator current output limit is 20mA @ 5V but is + 10mA @ 10V. + + Power Domain Level: This is defined in software by kernel + level board initialisation code. It is used to constrain a + power domain to a particular power range. i.e. + + - Domain-1 voltage is 3300mV + - Domain-2 voltage is 1400mV -> 1600mV + - Domain-3 current limit is 0mA -> 20mA. + + Consumer Level: This is defined by consumer drivers + dynamically setting voltage or current limit levels. + + e.g. a consumer backlight driver asks for a current increase + from 5mA to 10mA to increase LCD illumination. This passes + to through the levels as follows :- + + Consumer: need to increase LCD brightness. Lookup and + request next current mA value in brightness table (the + consumer driver could be used on several different + personalities based upon the same reference device). + + Power Domain: is the new current limit within the domain + operating limits for this domain and system state (e.g. + battery power, USB power) + + Regulator Domains: is the new current limit within the + regulator operating parameters for input/ouput voltage. + + If the regulator request passes all the constraint tests + then the new regulator value is applied. + + +Design +====== + +The framework is designed and targeted at SoC based devices but may also be +relevant to non SoC devices and is split into the following four interfaces:- + + + 1. Consumer driver interface. + + This uses a similar API to the kernel clock interface in that consumer + drivers can get and put a regulator (like they can with clocks atm) and + get/set voltage, current limit, mode, enable and disable. This should + allow consumers complete control over their supply voltage and current + limit. This also compiles out if not in use so drivers can be reused in + systems with no regulator based power control. + + See Documentation/power/regulator/consumer.txt + + 2. Regulator driver interface. + + This allows regulator drivers to register their regulators and provide + operations to the core. It also has a notifier call chain for propagating + regulator events to clients. + + See Documentation/power/regulator/regulator.txt + + 3. Machine interface. + + This interface is for machine specific code and allows the creation of + voltage/current domains (with constraints) for each regulator. It can + provide regulator constraints that will prevent device damage through + overvoltage or over current caused by buggy client drivers. It also + allows the creation of a regulator tree whereby some regulators are + supplied by others (similar to a clock tree). + + See Documentation/power/regulator/machine.txt + + 4. Userspace ABI. + + The framework also exports a lot of useful voltage/current/opmode data to + userspace via sysfs. This could be used to help monitor device power + consumption and status. + + See Documentation/ABI/testing/regulator-sysfs.txt diff --git a/Documentation/power/regulator/regulator.txt b/Documentation/power/regulator/regulator.txt new file mode 100644 index 0000000000000..a690501435922 --- /dev/null +++ b/Documentation/power/regulator/regulator.txt @@ -0,0 +1,30 @@ +Regulator Driver Interface +========================== + +The regulator driver interface is relatively simple and designed to allow +regulator drivers to register their services with the core framework. + + +Registration +============ + +Drivers can register a regulator by calling :- + +struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, + void *reg_data); + +This will register the regulators capabilities and operations the regulator +core. The core does not touch reg_data (private to regulator driver). + +Regulators can be unregistered by calling :- + +void regulator_unregister(struct regulator_dev *rdev); + + +Regulator Events +================ +Regulators can send events (e.g. over temp, under voltage, etc) to consumer +drivers by calling :- + +int regulator_notifier_call_chain(struct regulator_dev *rdev, + unsigned long event, void *data); diff --git a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX index 3be84aa38dfe1..29d839ce7327a 100644 --- a/Documentation/powerpc/00-INDEX +++ b/Documentation/powerpc/00-INDEX @@ -20,8 +20,6 @@ mpc52xx-device-tree-bindings.txt - MPC5200 Device Tree Bindings ppc_htab.txt - info about the Linux/PPC /proc/ppc_htab entry -SBC8260_memory_mapping.txt - - EST SBC8260 board info smp.txt - use and state info about Linux/PPC on MP machines sound.txt diff --git a/Documentation/powerpc/SBC8260_memory_mapping.txt b/Documentation/powerpc/SBC8260_memory_mapping.txt deleted file mode 100644 index e6e9ee0506c3e..0000000000000 --- a/Documentation/powerpc/SBC8260_memory_mapping.txt +++ /dev/null @@ -1,197 +0,0 @@ -Please mail me (Jon Diekema, diekema_jon@si.com or diekema@cideas.com) -if you have questions, comments or corrections. - - * EST SBC8260 Linux memory mapping rules - - http://www.estc.com/ - http://www.estc.com/products/boards/SBC8260-8240_ds.html - - Initial conditions: - ------------------- - - Tasks that need to be perform by the boot ROM before control is - transferred to zImage (compressed Linux kernel): - - - Define the IMMR to 0xf0000000 - - - Initialize the memory controller so that RAM is available at - physical address 0x00000000. On the SBC8260 is this 16M (64M) - SDRAM. - - - The boot ROM should only clear the RAM that it is using. - - The reason for doing this is to enhances the chances of a - successful post mortem on a Linux panic. One of the first - items to examine is the 16k (LOG_BUF_LEN) circular console - buffer called log_buf which is defined in kernel/printk.c. - - - To enhance boot ROM performance, the I-cache can be enabled. - - Date: Mon, 22 May 2000 14:21:10 -0700 - From: Neil Russell - - LiMon (LInux MONitor) runs with and starts Linux with MMU - off, I-cache enabled, D-cache disabled. The I-cache doesn't - need hints from the MMU to work correctly as the D-cache - does. No D-cache means no special code to handle devices in - the presence of cache (no snooping, etc). The use of the - I-cache means that the monitor can run acceptably fast - directly from ROM, rather than having to copy it to RAM. - - - Build the board information structure (see - include/asm-ppc/est8260.h for its definition) - - - The compressed Linux kernel (zImage) contains a bootstrap loader - that is position independent; you can load it into any RAM, - ROM or FLASH memory address >= 0x00500000 (above 5 MB), or - at its link address of 0x00400000 (4 MB). - - Note: If zImage is loaded at its link address of 0x00400000 (4 MB), - then zImage will skip the step of moving itself to - its link address. - - - Load R3 with the address of the board information structure - - - Transfer control to zImage - - - The Linux console port is SMC1, and the baud rate is controlled - from the bi_baudrate field of the board information structure. - On thing to keep in mind when picking the baud rate, is that - there is no flow control on the SMC ports. I would stick - with something safe and standard like 19200. - - On the EST SBC8260, the SMC1 port is on the COM1 connector of - the board. - - - EST SBC8260 defaults: - --------------------- - - Chip - Memory Sel Bus Use - --------------------- --- --- ---------------------------------- - 0x00000000-0x03FFFFFF CS2 60x (16M or 64M)/64M SDRAM - 0x04000000-0x04FFFFFF CS4 local 4M/16M SDRAM (soldered to the board) - 0x21000000-0x21000000 CS7 60x 1B/64K Flash present detect (from the flash SIMM) - 0x21000001-0x21000001 CS7 60x 1B/64K Switches (read) and LEDs (write) - 0x22000000-0x2200FFFF CS5 60x 8K/64K EEPROM - 0xFC000000-0xFCFFFFFF CS6 60x 2M/16M flash (8 bits wide, soldered to the board) - 0xFE000000-0xFFFFFFFF CS0 60x 4M/16M flash (SIMM) - - Notes: - ------ - - - The chip selects can map 32K blocks and up (powers of 2) - - - The SDRAM machine can handled up to 128Mbytes per chip select - - - Linux uses the 60x bus memory (the SDRAM DIMM) for the - communications buffers. - - - BATs can map 128K-256Mbytes each. There are four data BATs and - four instruction BATs. Generally the data and instruction BATs - are mapped the same. - - - The IMMR must be set above the kernel virtual memory addresses, - which start at 0xC0000000. Otherwise, the kernel may crash as - soon as you start any threads or processes due to VM collisions - in the kernel or user process space. - - - Details from Dan Malek on 10/29/1999: - - The user application virtual space consumes the first 2 Gbytes - (0x00000000 to 0x7FFFFFFF). The kernel virtual text starts at - 0xC0000000, with data following. There is a "protection hole" - between the end of kernel data and the start of the kernel - dynamically allocated space, but this space is still within - 0xCxxxxxxx. - - Obviously the kernel can't map any physical addresses 1:1 in - these ranges. - - - Details from Dan Malek on 5/19/2000: - - During the early kernel initialization, the kernel virtual - memory allocator is not operational. Prior to this KVM - initialization, we choose to map virtual to physical addresses - 1:1. That is, the kernel virtual address exactly matches the - physical address on the bus. These mappings are typically done - in arch/ppc/kernel/head.S, or arch/ppc/mm/init.c. Only - absolutely necessary mappings should be done at this time, for - example board control registers or a serial uart. Normal device - driver initialization should map resources later when necessary. - - Although platform dependent, and certainly the case for embedded - 8xx, traditionally memory is mapped at physical address zero, - and I/O devices above physical address 0x80000000. The lowest - and highest (above 0xf0000000) I/O addresses are traditionally - used for devices or registers we need to map during kernel - initialization and prior to KVM operation. For this reason, - and since it followed prior PowerPC platform examples, I chose - to map the embedded 8xx kernel to the 0xc0000000 virtual address. - This way, we can enable the MMU to map the kernel for proper - operation, and still map a few windows before the KVM is operational. - - On some systems, you could possibly run the kernel at the - 0x80000000 or any other virtual address. It just depends upon - mapping that must be done prior to KVM operational. You can never - map devices or kernel spaces that overlap with the user virtual - space. This is why default IMMR mapping used by most BDM tools - won't work. They put the IMMR at something like 0x10000000 or - 0x02000000 for example. You simply can't map these addresses early - in the kernel, and continue proper system operation. - - The embedded 8xx/82xx kernel is mature enough that all you should - need to do is map the IMMR someplace at or above 0xf0000000 and it - should boot far enough to get serial console messages and KGDB - connected on any platform. There are lots of other subtle memory - management design features that you simply don't need to worry - about. If you are changing functions related to MMU initialization, - you are likely breaking things that are known to work and are - heading down a path of disaster and frustration. Your changes - should be to make the flexibility of the processor fit Linux, - not force arbitrary and non-workable memory mappings into Linux. - - - You don't want to change KERNELLOAD or KERNELBASE, otherwise the - virtual memory and MMU code will get confused. - - arch/ppc/Makefile:KERNELLOAD = 0xc0000000 - - include/asm-ppc/page.h:#define PAGE_OFFSET 0xc0000000 - include/asm-ppc/page.h:#define KERNELBASE PAGE_OFFSET - - - RAM is at physical address 0x00000000, and gets mapped to - virtual address 0xC0000000 for the kernel. - - - Physical addresses used by the Linux kernel: - -------------------------------------------- - - 0x00000000-0x3FFFFFFF 1GB reserved for RAM - 0xF0000000-0xF001FFFF 128K IMMR 64K used for dual port memory, - 64K for 8260 registers - - - Logical addresses used by the Linux kernel: - ------------------------------------------- - - 0xF0000000-0xFFFFFFFF 256M BAT0 (IMMR: dual port RAM, registers) - 0xE0000000-0xEFFFFFFF 256M BAT1 (I/O space for custom boards) - 0xC0000000-0xCFFFFFFF 256M BAT2 (RAM) - 0xD0000000-0xDFFFFFFF 256M BAT3 (if RAM > 256MByte) - - - EST SBC8260 Linux mapping: - -------------------------- - - DBAT0, IBAT0, cache inhibited: - - Chip - Memory Sel Use - --------------------- --- --------------------------------- - 0xF0000000-0xF001FFFF n/a IMMR: dual port RAM, registers - - DBAT1, IBAT1, cache inhibited: - diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index 928a79ceb7aae..de4063cb4fdc0 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt @@ -278,7 +278,7 @@ it with special cases. a 64-bit platform. d) request and get assigned a platform number (see PLATFORM_* - constants in include/asm-powerpc/processor.h + constants in arch/powerpc/include/asm/processor.h 32-bit embedded kernels: @@ -340,7 +340,7 @@ the block to RAM before passing it to the kernel. --------- The kernel is entered with r3 pointing to an area of memory that is - roughly described in include/asm-powerpc/prom.h by the structure + roughly described in arch/powerpc/include/asm/prom.h by the structure boot_param_header: struct boot_param_header { diff --git a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt index b35f3482e3e4d..2ea76d9d137c5 100644 --- a/Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt +++ b/Documentation/powerpc/dts-bindings/fsl/cpm_qe/serial.txt @@ -7,6 +7,15 @@ Currently defined compatibles: - fsl,cpm2-scc-uart - fsl,qe-uart +Modem control lines connected to GPIO controllers are listed in the gpios +property as described in booting-without-of.txt, section IX.1 in the following +order: + +CTS, RTS, DCD, DSR, DTR, and RI. + +The gpios property is optional and can be left out when control lines are +not used. + Example: serial@11a00 { @@ -18,4 +27,6 @@ Example: interrupt-parent = <&PIC>; fsl,cpm-brg = <1>; fsl,cpm-command = <00800000>; + gpios = <&gpio_c 15 0 + &gpio_d 29 0>; }; diff --git a/Documentation/powerpc/eeh-pci-error-recovery.txt b/Documentation/powerpc/eeh-pci-error-recovery.txt index df7afe43d4628..9d4e33df624c2 100644 --- a/Documentation/powerpc/eeh-pci-error-recovery.txt +++ b/Documentation/powerpc/eeh-pci-error-recovery.txt @@ -133,7 +133,7 @@ error. Given an arbitrary address, the routine pci_get_device_by_addr() will find the pci device associated with that address (if any). -The default include/asm-powerpc/io.h macros readb(), inb(), insb(), +The default arch/powerpc/include/asm/io.h macros readb(), inb(), insb(), etc. include a check to see if the i/o read returned all-0xff's. If so, these make a call to eeh_dn_check_failure(), which in turn asks the firmware if the all-ff's value is the sign of a true EEH diff --git a/Documentation/rfkill.txt b/Documentation/rfkill.txt index 0843ed0163a58..28b6ec87c6420 100644 --- a/Documentation/rfkill.txt +++ b/Documentation/rfkill.txt @@ -390,9 +390,10 @@ rfkill lines are inactive, it must return RFKILL_STATE_SOFT_BLOCKED if its soft rfkill input line is active. Only if none of the rfkill input lines are active, will it return RFKILL_STATE_UNBLOCKED. -If it doesn't implement the get_state() hook, it must make sure that its calls -to rfkill_force_state() are enough to keep the status always up-to-date, and it -must do a rfkill_force_state() on resume from sleep. +Since the device has a hardware rfkill line, it IS subject to state changes +external to rfkill. Therefore, the driver must make sure that it calls +rfkill_force_state() to keep the status always up-to-date, and it must do a +rfkill_force_state() on resume from sleep. Every time the driver gets a notification from the card that one of its rfkill lines changed state (polling might be needed on badly designed cards that don't @@ -422,13 +423,24 @@ of the hardware is unknown), or read-write (where the hardware can be queried about its current state). The rfkill class will call the get_state hook of a device every time it needs -to know the *real* current state of the hardware. This can happen often. +to know the *real* current state of the hardware. This can happen often, but +it does not do any polling, so it is not enough on hardware that is subject +to state changes outside of the rfkill subsystem. + +Therefore, calling rfkill_force_state() when a state change happens is +mandatory when the device has a hardware rfkill line, or when something else +like the firmware could cause its state to be changed without going through the +rfkill class. Some hardware provides events when its status changes. In these cases, it is best for the driver to not provide a get_state hook, and instead register the rfkill class *already* with the correct status, and keep it updated using rfkill_force_state() when it gets an event from the hardware. +rfkill_force_state() must be used on the device resume handlers to update the +rfkill status, should there be any chance of the device status changing during +the sleep. + There is no provision for a statically-allocated rfkill struct. You must use rfkill_allocate() to allocate one. diff --git a/Documentation/spi/Makefile b/Documentation/spi/Makefile new file mode 100644 index 0000000000000..a5b03c88beae2 --- /dev/null +++ b/Documentation/spi/Makefile @@ -0,0 +1,11 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := spidev_test spidev_fdx + +# Tell kbuild to always build the programs +always := $(hostprogs-y) + +HOSTCFLAGS_spidev_test.o += -I$(objtree)/usr/include +HOSTCFLAGS_spidev_fdx.o += -I$(objtree)/usr/include diff --git a/Documentation/spi/pxa2xx b/Documentation/spi/pxa2xx index f3853cc37bde3..bbe8dee681a5d 100644 --- a/Documentation/spi/pxa2xx +++ b/Documentation/spi/pxa2xx @@ -19,7 +19,7 @@ Declaring PXA2xx Master Controllers ----------------------------------- Typically a SPI master is defined in the arch/.../mach-*/board-*.c as a "platform device". The master configuration is passed to the driver via a table -found in include/asm-arm/arch-pxa/pxa2xx_spi.h: +found in arch/arm/mach-pxa/include/mach/pxa2xx_spi.h: struct pxa2xx_spi_master { enum pxa_ssp_type ssp_type; @@ -94,7 +94,7 @@ using the "spi_board_info" structure found in "linux/spi/spi.h". See Each slave device attached to the PXA must provide slave specific configuration information via the structure "pxa2xx_spi_chip" found in -"include/asm-arm/arch-pxa/pxa2xx_spi.h". The pxa2xx_spi master controller driver +"arch/arm/mach-pxa/include/mach/pxa2xx_spi.h". The pxa2xx_spi master controller driver will uses the configuration whenever the driver communicates with the slave device. diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary index 6d5f18143c503..8bae2f018d342 100644 --- a/Documentation/spi/spi-summary +++ b/Documentation/spi/spi-summary @@ -210,7 +210,7 @@ board should normally be set up and registered. So for example arch/.../mach-*/board-*.c files might have code like: - #include /* for mysoc_spi_data */ + #include /* for mysoc_spi_data */ /* if your mach-* infrastructure doesn't support kernels that can * run on multiple boards, pdata wouldn't benefit from "__init". @@ -227,7 +227,7 @@ So for example arch/.../mach-*/board-*.c files might have code like: And SOC-specific utility code might look something like: - #include + #include static struct platform_device spi2 = { ... }; diff --git a/Documentation/usb/auerswald.txt b/Documentation/usb/auerswald.txt deleted file mode 100644 index 7ee4d8f69116f..0000000000000 --- a/Documentation/usb/auerswald.txt +++ /dev/null @@ -1,30 +0,0 @@ - Auerswald USB kernel driver - =========================== - -What is it? What can I do with it? -================================== -The auerswald USB kernel driver connects your linux 2.4.x -system to the auerswald usb-enabled devices. - -There are two types of auerswald usb devices: -a) small PBX systems (ISDN) -b) COMfort system telephones (ISDN) - -The driver installation creates the devices -/dev/usb/auer0..15. These devices carry a vendor- -specific protocol. You may run all auerswald java -software on it. The java software needs a native -library "libAuerUsbJNINative.so" installed on -your system. This library is available from -auerswald and shipped as part of the java software. - -You may create the devices with: - mknod -m 666 /dev/usb/auer0 c 180 112 - ... - mknod -m 666 /dev/usb/auer15 c 180 127 - -Future plans -============ -- Connection to ISDN4LINUX (the hisax interface) - -The maintainer of this driver is wolfgang@iksw-muees.de diff --git a/Documentation/usb/power-management.txt b/Documentation/usb/power-management.txt index b2fc4d4a99177..9d31140e3f5bc 100644 --- a/Documentation/usb/power-management.txt +++ b/Documentation/usb/power-management.txt @@ -436,7 +436,12 @@ post_reset; the USB core guarantees that this is true of internal suspend/resume events as well. If a driver wants to block all suspend/resume calls during some -critical section, it can simply acquire udev->pm_mutex. +critical section, it can simply acquire udev->pm_mutex. Note that +calls to resume may be triggered indirectly. Block IO due to memory +allocations can make the vm subsystem resume a device. Thus while +holding this lock you must not allocate memory with GFP_KERNEL or +GFP_NOFS. + Alternatively, if the critical section might call some of the usb_autopm_* routines, the driver can avoid deadlock by doing: diff --git a/Documentation/video4linux/CARDLIST.au0828 b/Documentation/video4linux/CARDLIST.au0828 index 86d1c8e7b18f3..eedc399e8debd 100644 --- a/Documentation/video4linux/CARDLIST.au0828 +++ b/Documentation/video4linux/CARDLIST.au0828 @@ -2,3 +2,4 @@ 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008] 2 -> Hauppauge HVR850 (au0828) [2040:7240] 3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620] + 4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281] diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 10591467ef166..89c7f32abf9f2 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -1,11 +1,11 @@ 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800] - 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2750,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883] + 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883] 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036] 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208] 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201] 5 -> MSI VOX USB 2.0 (em2820/em2840) 6 -> Terratec Cinergy 200 USB (em2800) - 7 -> Leadtek Winfast USB II (em2800) + 7 -> Leadtek Winfast USB II (em2800) [0413:6023] 8 -> Kworld USB2800 (em2800) 9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a] 10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500] @@ -14,7 +14,46 @@ 13 -> Terratec Prodigy XS (em2880) [0ccd:0047] 14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840) 15 -> V-Gear PocketTV (em2800) - 16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f] + 16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b,2040:651f] 17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227] 18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502] 19 -> PointNix Intra-Oral Camera (em2860) + 20 -> AMD ATI TV Wonder HD 600 (em2880) [0438:b002] + 21 -> eMPIA Technology, Inc. GrabBeeX+ Video Encoder (em2800) [eb1a:2801] + 22 -> Unknown EM2750/EM2751 webcam grabber (em2750) [eb1a:2750,eb1a:2751] + 23 -> Huaqi DLCW-130 (em2750) + 24 -> D-Link DUB-T210 TV Tuner (em2820/em2840) [2001:f112] + 25 -> Gadmei UTV310 (em2820/em2840) + 26 -> Hercules Smart TV USB 2.0 (em2820/em2840) + 27 -> Pinnacle PCTV USB 2 (Philips FM1216ME) (em2820/em2840) + 28 -> Leadtek Winfast USB II Deluxe (em2820/em2840) + 29 -> Pinnacle Dazzle DVC 100 (em2820/em2840) + 30 -> Videology 20K14XUSB USB2.0 (em2820/em2840) + 31 -> Usbgear VD204v9 (em2821) + 32 -> Supercomp USB 2.0 TV (em2821) + 33 -> SIIG AVTuner-PVR/Prolink PlayTV USB 2.0 (em2821) + 34 -> Terratec Cinergy A Hybrid XS (em2860) [0ccd:004f] + 35 -> Typhoon DVD Maker (em2860) + 36 -> NetGMBH Cam (em2860) + 37 -> Gadmei UTV330 (em2860) + 38 -> Yakumo MovieMixer (em2861) + 39 -> KWorld PVRTV 300U (em2861) [eb1a:e300] + 40 -> Plextor ConvertX PX-TV100U (em2861) [093b:a005] + 41 -> Kworld 350 U DVB-T (em2870) [eb1a:e350] + 42 -> Kworld 355 U DVB-T (em2870) [eb1a:e355,eb1a:e357] + 43 -> Terratec Cinergy T XS (em2870) [0ccd:0043] + 44 -> Terratec Cinergy T XS (MT2060) (em2870) + 45 -> Pinnacle PCTV DVB-T (em2870) + 46 -> Compro, VideoMate U3 (em2870) [185b:2870] + 47 -> KWorld DVB-T 305U (em2880) [eb1a:e305] + 48 -> KWorld DVB-T 310U (em2880) + 49 -> MSI DigiVox A/D (em2880) [eb1a:e310] + 50 -> MSI DigiVox A/D II (em2880) [eb1a:e320] + 51 -> Terratec Hybrid XS Secam (em2880) [0ccd:004c] + 52 -> DNT DA2 Hybrid (em2881) + 53 -> Pinnacle Hybrid Pro (em2881) + 54 -> Kworld VS-DVB-T 323UR (em2882) [eb1a:e323] + 55 -> Terratec Hybrid XS (em2882) (em2882) [0ccd:005e] + 56 -> Pinnacle Hybrid Pro (2) (em2882) [2304:0226] + 57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316] + 58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041] diff --git a/Documentation/video4linux/Makefile b/Documentation/video4linux/Makefile new file mode 100644 index 0000000000000..1ed0e98d057d0 --- /dev/null +++ b/Documentation/video4linux/Makefile @@ -0,0 +1,8 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := v4lgrab + +# Tell kbuild to always build the programs +always := $(hostprogs-y) diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index 0c4880af57a33..78a863ab8a5ac 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt @@ -1,4 +1,4 @@ -List of the webcams know by gspca. +List of the webcams known by gspca. The modules are: gspca_main main driver @@ -226,6 +226,7 @@ sonixj 0c45:6130 Sonix Pccam sonixj 0c45:6138 Sn9c120 Mo4000 sonixj 0c45:613b Surfer SN-206 sonixj 0c45:613c Sonix Pccam168 +sonixj 0c45:6143 Sonix Pccam168 sunplus 0d64:0303 Sunplus FashionCam DXG etoms 102c:6151 Qcam Sangha CIF etoms 102c:6251 Qcam xxxxxx VGA diff --git a/Documentation/vm/Makefile b/Documentation/vm/Makefile new file mode 100644 index 0000000000000..6f562f778b289 --- /dev/null +++ b/Documentation/vm/Makefile @@ -0,0 +1,8 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := slabinfo + +# Tell kbuild to always build the programs +always := $(hostprogs-y) diff --git a/Documentation/watchdog/src/Makefile b/Documentation/watchdog/src/Makefile new file mode 100644 index 0000000000000..40e5f46e4740a --- /dev/null +++ b/Documentation/watchdog/src/Makefile @@ -0,0 +1,8 @@ +# kbuild trick to avoid linker error. Can be omitted if a module is built. +obj- := dummy.o + +# List of programs to build +hostprogs-y := watchdog-simple watchdog-test + +# Tell kbuild to always build the programs +always := $(hostprogs-y) diff --git a/MAINTAINERS b/MAINTAINERS index 03c5d6ccb9f88..4c5e9fe0f7db5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -502,6 +502,12 @@ L: openezx-devel@lists.openezx.org (subscribers-only) W: http://www.openezx.org/ S: Maintained +ARM/FREESCALE IMX / MXC ARM ARCHITECTURE +P: Sascha Hauer +M: kernel@pengutronix.de +L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) +S: Maintained + ARM/GLOMATION GESBC9312SX MACHINE SUPPORT P: Lennert Buytenhek M: kernel@wantstofly.org @@ -588,6 +594,11 @@ M: kernel@wantstofly.org L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) S: Maintained +ARM/MAGICIAN MACHINE SUPPORT +P: Philipp Zabel +M: philipp.zabel@gmail.com +S: Maintained + ARM/TOSA MACHINE SUPPORT P: Dmitry Baryshkov M: dbaryshkov@gmail.com @@ -714,6 +725,15 @@ L: linux-wireless@vger.kernel.org L: ath5k-devel@lists.ath5k.org S: Maintained +ATHEROS ATH9K WIRELESS DRIVER +P: Luis R. Rodriguez +M: lrodriguez@atheros.com +P: Jouni Malinen +M: jmalinen@atheros.com +L: linux-wireless@vger.kernel.org +L: ath9k-devel@lists.ath9k.org +S: Supported + ATI_REMOTE2 DRIVER P: Ville Syrjala M: syrjala@sci.fi @@ -1229,7 +1249,7 @@ S: Maintained CPU FREQUENCY DRIVERS P: Dave Jones M: davej@codemonkey.org.uk -L: cpufreq@lists.linux.org.uk +L: cpufreq@vger.kernel.org W: http://www.codemonkey.org.uk/projects/cpufreq/ T: git kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git S: Maintained @@ -1878,13 +1898,9 @@ W: http://gigaset307x.sourceforge.net/ S: Maintained HARDWARE MONITORING -P: Mark M. Hoffman -M: mhoffman@lightlink.com L: lm-sensors@lm-sensors.org W: http://www.lm-sensors.org/ -T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git testing -T: git lm-sensors.org:/kernel/mhoffman/hwmon-2.6.git release -S: Maintained +S: Orphaned HARDWARE RANDOM NUMBER GENERATOR CORE S: Orphaned @@ -2446,7 +2462,7 @@ L: kernel-janitors@vger.kernel.org W: http://www.kerneljanitors.org/ S: Maintained -KERNEL NFSD +KERNEL NFSD, SUNRPC, AND LOCKD SERVERS P: J. Bruce Fields M: bfields@fieldses.org P: Neil Brown @@ -2912,6 +2928,12 @@ M: jirislaby@gmail.com L: linux-kernel@vger.kernel.org S: Maintained +MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER +P: Felipe Balbi +M: felipe.balbi@nokia.com +L: linux-usb@vger.kernel.org +S: Maintained + MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE) P: Andrew Gallatin M: gallatin@myri.com @@ -3060,9 +3082,10 @@ M: horms@verge.net.au P: Julian Anastasov M: ja@ssi.bg L: netdev@vger.kernel.org +L: lvs-devel@vger.kernel.org S: Maintained -NFS CLIENT +NFS, SUNRPC, AND LOCKD CLIENTS P: Trond Myklebust M: Trond.Myklebust@netapp.com L: linux-nfs@vger.kernel.org @@ -3796,6 +3819,12 @@ P: Ben Nizette M: bn@niasdigital.com S: Maintained +SOC-CAMERA V4L2 SUBSYSTEM +P: Guennadi Liakhovetski +M: g.liakhovetski@gmx.de +L: video4linux-list@redhat.com +S: Maintained + SOFTWARE RAID (Multiple Disks) SUPPORT P: Ingo Molnar M: mingo@redhat.com @@ -3962,7 +3991,7 @@ M: lethal@linux-sh.org L: linux-sh@vger.kernel.org W: http://www.linux-sh.org T: git kernel.org:/pub/scm/linux/kernel/git/lethal/sh-2.6.git -S: Maintained +S: Supported SUN3/3X P: Sam Creasey @@ -4173,12 +4202,6 @@ M: oliver@neukum.name L: linux-usb@vger.kernel.org S: Maintained -USB AUERSWALD DRIVER -P: Wolfgang Muees -M: wolfgang@iksw-muees.de -L: linux-usb@vger.kernel.org -S: Maintained - USB BLOCK DRIVER (UB ub) P: Pete Zaitcev M: zaitcev@redhat.com @@ -4498,6 +4521,15 @@ M: kaber@trash.net L: netdev@vger.kernel.org S: Maintained +VOLTAGE AND CURRENT REGULATOR FRAMEWORK +P: Liam Girdwood +M: lg@opensource.wolfsonmicro.com +P: Mark Brown +M: broonie@opensource.wolfsonmicro.com +W: http://opensource.wolfsonmicro.com/node/15 +T: git kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git +S: Supported + VT1211 HARDWARE MONITOR DRIVER P: Juerg Haefliger M: juergh@gmail.com @@ -4652,12 +4684,6 @@ L: linux-wireless@vger.kernel.org L: zd1211-devs@lists.sourceforge.net (subscribers-only) S: Maintained -ZF MACHZ WATCHDOG -P: Fernando Fuganti -M: fuganti@netbank.com.br -W: http://cvs.conectiva.com.br/drivers/ZFL-watchdog/ -S: Maintained - ZR36067 VIDEO FOR LINUX DRIVER P: Ronald Bultje M: rbultje@ronald.bitfreak.net diff --git a/Makefile b/Makefile index 40f24810116cc..53bf6ec1af9d2 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 -SUBLEVEL = 26 -EXTRAVERSION = +SUBLEVEL = 27 +EXTRAVERSION = -rc3 NAME = Rotary Wombat # *DOCUMENTATION* @@ -206,7 +206,11 @@ ifeq ($(ARCH),x86_64) endif # Where to locate arch specific headers -hdr-arch := $(SRCARCH) +ifeq ($(ARCH),sparc64) + hdr-arch := sparc +else + hdr-arch := $(SRCARCH) +endif KCONFIG_CONFIG ?= .config @@ -817,6 +821,9 @@ ifdef CONFIG_HEADERS_CHECK endif ifdef CONFIG_SAMPLES $(Q)$(MAKE) $(build)=samples +endif +ifdef CONFIG_BUILD_DOCSRC + $(Q)$(MAKE) $(build)=Documentation endif $(call vmlinux-modpost) $(call if_changed_rule,vmlinux__) @@ -925,10 +932,10 @@ ifneq ($(KBUILD_SRC),) echo " in the '$(srctree)' directory.";\ /bin/false; \ fi; - $(Q)if [ ! -d include2 ]; then mkdir -p include2; fi; - $(Q)if [ -e $(srctree)/include/asm-$(SRCARCH)/system.h ]; then \ + $(Q)if [ ! -d include2 ]; then \ + mkdir -p include2; \ ln -fsn $(srctree)/include/asm-$(SRCARCH) include2/asm; \ - fi + fi endif # prepare2 creates a makefile if using a separate output directory @@ -1162,7 +1169,7 @@ MRPROPER_FILES += .config .config.old include/asm .version .old_version \ # clean: rm-dirs := $(CLEAN_DIRS) clean: rm-files := $(CLEAN_FILES) -clean-dirs := $(addprefix _clean_,$(srctree) $(vmlinux-alldirs)) +clean-dirs := $(addprefix _clean_,$(srctree) $(vmlinux-alldirs) Documentation) PHONY += $(clean-dirs) clean archclean $(clean-dirs): @@ -1488,7 +1495,7 @@ quiet_cmd_cscope-file = FILELST cscope.files cmd_cscope-file = (echo \-k; echo \-q; $(all-sources)) > cscope.files quiet_cmd_cscope = MAKE cscope.out - cmd_cscope = cscope -b + cmd_cscope = cscope -b -f cscope.out cscope: FORCE $(call cmd,cscope-file) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c8f528284a94e..4b8acd2851f48 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -17,6 +17,7 @@ config ARM select HAVE_KRETPROBES if (HAVE_KPROBES) select HAVE_FTRACE if (!XIP_KERNEL) select HAVE_DYNAMIC_FTRACE if (HAVE_FTRACE) + select HAVE_GENERIC_DMA_COHERENT help The ARM series is a line of low-power-consumption RISC chip designs licensed by ARM Ltd and targeted at embedded applications and @@ -234,6 +235,7 @@ config ARCH_VERSATILE config ARCH_AT91 bool "Atmel AT91" select GENERIC_GPIO + select HAVE_CLK help This enables support for systems based on the Atmel AT91RM9200, AT91SAM9 and AT91CAP9 processors. @@ -267,7 +269,6 @@ config ARCH_EP93XX select ARM_VIC select GENERIC_GPIO select HAVE_CLK - select HAVE_CLK select ARCH_REQUIRE_GPIOLIB help This enables support for the Cirrus EP93xx series of CPUs. @@ -1224,6 +1225,8 @@ source "drivers/dma/Kconfig" source "drivers/dca/Kconfig" +source "drivers/regulator/Kconfig" + source "drivers/uio/Kconfig" endmenu diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 2f07477442369..703a44fa0f9b7 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -97,9 +97,7 @@ textofs-y := 0x00008000 machine-$(CONFIG_ARCH_RPC) := rpc machine-$(CONFIG_ARCH_EBSA110) := ebsa110 machine-$(CONFIG_ARCH_CLPS7500) := clps7500 - incdir-$(CONFIG_ARCH_CLPS7500) := cl7500 machine-$(CONFIG_FOOTBRIDGE) := footbridge - incdir-$(CONFIG_FOOTBRIDGE) := ebsa285 machine-$(CONFIG_ARCH_SHARK) := shark machine-$(CONFIG_ARCH_SA1100) := sa1100 ifeq ($(CONFIG_ARCH_SA1100),y) @@ -114,13 +112,15 @@ endif machine-$(CONFIG_ARCH_IOP32X) := iop32x machine-$(CONFIG_ARCH_IOP33X) := iop33x machine-$(CONFIG_ARCH_IOP13XX) := iop13xx + plat-$(CONFIG_PLAT_IOP) := iop machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_IXP2000) := ixp2000 machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx machine-$(CONFIG_ARCH_OMAP1) := omap1 machine-$(CONFIG_ARCH_OMAP2) := omap2 - incdir-$(CONFIG_ARCH_OMAP) := omap - machine-$(CONFIG_ARCH_S3C2410) := s3c2410 + plat-$(CONFIG_ARCH_OMAP) := omap + machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443 + plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x machine-$(CONFIG_ARCH_VERSATILE) := versatile machine-$(CONFIG_ARCH_IMX) := imx @@ -135,10 +135,11 @@ endif machine-$(CONFIG_ARCH_DAVINCI) := davinci machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood machine-$(CONFIG_ARCH_KS8695) := ks8695 - incdir-$(CONFIG_ARCH_MXC) := mxc + plat-$(CONFIG_ARCH_MXC) := mxc machine-$(CONFIG_ARCH_MX2) := mx2 machine-$(CONFIG_ARCH_MX3) := mx3 machine-$(CONFIG_ARCH_ORION5X) := orion5x + plat-$(CONFIG_PLAT_ORION) := orion machine-$(CONFIG_ARCH_MSM7X00A) := msm machine-$(CONFIG_ARCH_LOKI) := loki machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0 @@ -153,17 +154,22 @@ endif # The byte offset of the kernel image in RAM from the start of RAM. TEXT_OFFSET := $(textofs-y) -ifeq ($(incdir-y),) -incdir-y := $(machine-y) -endif -INCDIR := arch-$(incdir-y) - +# The first directory contains additional information for the boot setup code ifneq ($(machine-y),) -MACHINE := arch/arm/mach-$(machine-y)/ +MACHINE := arch/arm/mach-$(word 1,$(machine-y))/ else MACHINE := endif +machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) +platdirs := $(patsubst %,arch/arm/plat-%/,$(plat-y)) + +ifeq ($(KBUILD_SRC),) +KBUILD_CPPFLAGS += $(patsubst %,-I%include,$(machdirs) $(platdirs)) +else +KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs) $(platdirs)) +endif + export TEXT_OFFSET GZFLAGS MMUEXT # Do we have FASTFPE? @@ -174,23 +180,11 @@ endif # If we have a machine-specific directory, then include it in the build. core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ -core-y += $(MACHINE) -core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2400/ -core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2412/ -core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2440/ -core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2442/ -core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2443/ +core-y += $(machdirs) $(platdirs) core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/ 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_PLAT_ORION) += arch/arm/plat-orion/ -core-$(CONFIG_ARCH_OMAP) += arch/arm/plat-omap/ -core-$(CONFIG_PLAT_S3C24XX) += arch/arm/plat-s3c24xx/ -core-$(CONFIG_ARCH_MXC) += arch/arm/plat-mxc/ - drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ libs-y := arch/arm/lib/ $(libs-y) @@ -210,20 +204,10 @@ boot := arch/arm/boot # them changed. We use .arch to indicate when they were updated # last, otherwise make uses the target directory mtime. -include/asm-arm/.arch: $(wildcard include/config/arch/*.h) include/config/auto.conf - @echo ' SYMLINK include/asm-arm/arch -> include/asm-arm/$(INCDIR)' -ifneq ($(KBUILD_SRC),) - $(Q)mkdir -p include/asm-arm - $(Q)ln -fsn $(srctree)/include/asm-arm/$(INCDIR) include/asm-arm/arch -else - $(Q)ln -fsn $(INCDIR) include/asm-arm/arch -endif - @touch $@ - archprepare: maketools PHONY += maketools FORCE -maketools: include/linux/version.h include/asm-arm/.arch FORCE +maketools: include/linux/version.h FORCE $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h # Convert bzImage to zImage diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 95baac4939e09..94462a097f866 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile @@ -112,6 +112,3 @@ $(obj)/font.c: $(FONTC) $(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config @sed "$(SEDFLAGS)" < $< > $@ - -$(obj)/misc.o: $(obj)/misc.c include/asm/arch/uncompress.h lib/inflate.c - diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S index dd3fbd6766e14..aa5ee49c5c5ae 100644 --- a/arch/arm/boot/compressed/head-xscale.S +++ b/arch/arm/boot/compressed/head-xscale.S @@ -6,7 +6,6 @@ */ #include -#include .section ".start", "ax" diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index de41daeab5e98..d42f89b7760bf 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -37,7 +37,7 @@ #else -#include +#include .macro writeb, ch, rb senduart \ch, \rb diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c index 7145cc7c04f0b..65ce8fff29db1 100644 --- a/arch/arm/boot/compressed/misc.c +++ b/arch/arm/boot/compressed/misc.c @@ -27,7 +27,7 @@ unsigned int __machine_arch_type; static void putstr(const char *ptr); #include -#include +#include #ifdef CONFIG_DEBUG_ICEDCC diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 85579654d3b77..283051eaf931c 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index f6d3fdda7067c..ec8a5471bf06d 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c index 8822b684d474a..db83091614082 100644 --- a/arch/arm/common/sharpsl_pm.c +++ b/arch/arm/common/sharpsl_pm.c @@ -26,13 +26,12 @@ #include #include -#include -#include +#include #include -#include -#include -#include -#include +#include +#include +#include +#include #include /* diff --git a/arch/arm/common/time-acorn.c b/arch/arm/common/time-acorn.c index d544da4147310..df0983aafe694 100644 --- a/arch/arm/common/time-acorn.c +++ b/arch/arm/common/time-acorn.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/common/uengine.c b/arch/arm/common/uengine.c index 117cab30bd36c..7ecd3c0ab011a 100644 --- a/arch/arm/common/uengine.c +++ b/arch/arm/common/uengine.c @@ -16,8 +16,7 @@ #include #include #include -#include -#include +#include #include #include diff --git a/arch/arm/configs/at91cap9adk_defconfig b/arch/arm/configs/at91cap9adk_defconfig index be2b2f38fd949..bf97801a10682 100644 --- a/arch/arm/configs/at91cap9adk_defconfig +++ b/arch/arm/configs/at91cap9adk_defconfig @@ -170,7 +170,7 @@ CONFIG_MACH_AT91CAP9ADK=y # AT91 Board Options # CONFIG_MTD_AT91_DATAFLASH_CARD=y -# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set +# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set # # AT91 Feature Selections @@ -442,7 +442,7 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_MUSEUM_IDS is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set -CONFIG_MTD_NAND_AT91=y +CONFIG_MTD_NAND_ATMEL=y # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_ALAUDA is not set diff --git a/arch/arm/configs/at91sam9260ek_defconfig b/arch/arm/configs/at91sam9260ek_defconfig index 2011adfa67589..38e6a0abeb4ea 100644 --- a/arch/arm/configs/at91sam9260ek_defconfig +++ b/arch/arm/configs/at91sam9260ek_defconfig @@ -176,7 +176,7 @@ CONFIG_MACH_AT91SAM9260EK=y # AT91 Board Options # # CONFIG_MTD_AT91_DATAFLASH_CARD is not set -# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set +# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set # # AT91 Feature Selections diff --git a/arch/arm/configs/at91sam9261ek_defconfig b/arch/arm/configs/at91sam9261ek_defconfig index 4049768962d2d..93b779f94b41e 100644 --- a/arch/arm/configs/at91sam9261ek_defconfig +++ b/arch/arm/configs/at91sam9261ek_defconfig @@ -169,7 +169,7 @@ CONFIG_MACH_AT91SAM9261EK=y # AT91 Board Options # # CONFIG_MTD_AT91_DATAFLASH_CARD is not set -# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set +# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set # # AT91 Feature Selections @@ -433,7 +433,7 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_MUSEUM_IDS is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set -CONFIG_MTD_NAND_AT91=y +CONFIG_MTD_NAND_ATMEL=y # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_ALAUDA is not set diff --git a/arch/arm/configs/at91sam9263ek_defconfig b/arch/arm/configs/at91sam9263ek_defconfig index fa1c5aecb5a8d..a7ddd94363cac 100644 --- a/arch/arm/configs/at91sam9263ek_defconfig +++ b/arch/arm/configs/at91sam9263ek_defconfig @@ -169,7 +169,7 @@ CONFIG_MACH_AT91SAM9263EK=y # AT91 Board Options # CONFIG_MTD_AT91_DATAFLASH_CARD=y -# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set +# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set # # AT91 Feature Selections @@ -428,7 +428,7 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_MUSEUM_IDS is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set -CONFIG_MTD_NAND_AT91=y +CONFIG_MTD_NAND_ATMEL=y # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_ALAUDA is not set diff --git a/arch/arm/configs/at91sam9g20ek_defconfig b/arch/arm/configs/at91sam9g20ek_defconfig index c06863847364d..df0d6ee672b38 100644 --- a/arch/arm/configs/at91sam9g20ek_defconfig +++ b/arch/arm/configs/at91sam9g20ek_defconfig @@ -168,7 +168,7 @@ CONFIG_MACH_AT91SAM9G20EK=y # AT91 Board Options # # CONFIG_MTD_AT91_DATAFLASH_CARD is not set -# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set +# CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16 is not set # # AT91 Feature Selections @@ -442,10 +442,10 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_MUSEUM_IDS is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set -CONFIG_MTD_NAND_AT91=y -CONFIG_MTD_NAND_AT91_ECC_SOFT=y -# CONFIG_MTD_NAND_AT91_ECC_HW is not set -# CONFIG_MTD_NAND_AT91_ECC_NONE is not set +CONFIG_MTD_NAND_ATMEL=y +CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y +# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_ALAUDA is not set diff --git a/arch/arm/configs/at91sam9rlek_defconfig b/arch/arm/configs/at91sam9rlek_defconfig index d8ec5f9ca6ec4..1c76642272a1b 100644 --- a/arch/arm/configs/at91sam9rlek_defconfig +++ b/arch/arm/configs/at91sam9rlek_defconfig @@ -392,7 +392,7 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_MUSEUM_IDS is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set -CONFIG_MTD_NAND_AT91=y +CONFIG_MTD_NAND_ATMEL=y # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_ONENAND is not set diff --git a/arch/arm/configs/cam60_defconfig b/arch/arm/configs/cam60_defconfig index f3cd4a95373ab..f945105d6cd60 100644 --- a/arch/arm/configs/cam60_defconfig +++ b/arch/arm/configs/cam60_defconfig @@ -466,10 +466,10 @@ CONFIG_MTD_NAND_VERIFY_WRITE=y # CONFIG_MTD_NAND_MUSEUM_IDS is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set -CONFIG_MTD_NAND_AT91=y -# CONFIG_MTD_NAND_AT91_ECC_SOFT is not set -CONFIG_MTD_NAND_AT91_ECC_HW=y -# CONFIG_MTD_NAND_AT91_ECC_NONE is not set +CONFIG_MTD_NAND_ATMEL=y +# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set +CONFIG_MTD_NAND_ATMEL_ECC_HW=y +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_ALAUDA is not set diff --git a/arch/arm/configs/qil-a9260_defconfig b/arch/arm/configs/qil-a9260_defconfig index ef903bed061e6..5cbd815896474 100644 --- a/arch/arm/configs/qil-a9260_defconfig +++ b/arch/arm/configs/qil-a9260_defconfig @@ -458,10 +458,10 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_MUSEUM_IDS is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set -CONFIG_MTD_NAND_AT91=y -CONFIG_MTD_NAND_AT91_ECC_SOFT=y -# CONFIG_MTD_NAND_AT91_ECC_HW is not set -# CONFIG_MTD_NAND_AT91_ECC_NONE is not set +CONFIG_MTD_NAND_ATMEL=y +CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y +# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_ALAUDA is not set diff --git a/arch/arm/configs/sam9_l9260_defconfig b/arch/arm/configs/sam9_l9260_defconfig index 8688362bcf7b1..1174e27648757 100644 --- a/arch/arm/configs/sam9_l9260_defconfig +++ b/arch/arm/configs/sam9_l9260_defconfig @@ -429,7 +429,7 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_MUSEUM_IDS is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set -CONFIG_MTD_NAND_AT91=y +CONFIG_MTD_NAND_ATMEL=y # CONFIG_MTD_NAND_NANDSIM is not set CONFIG_MTD_NAND_PLATFORM=y # CONFIG_MTD_ONENAND is not set diff --git a/arch/arm/configs/usb-a9260_defconfig b/arch/arm/configs/usb-a9260_defconfig index 3680bd2df26d8..fcb4aaabd439d 100644 --- a/arch/arm/configs/usb-a9260_defconfig +++ b/arch/arm/configs/usb-a9260_defconfig @@ -458,10 +458,10 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_MUSEUM_IDS is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set -CONFIG_MTD_NAND_AT91=y -CONFIG_MTD_NAND_AT91_ECC_SOFT=y -# CONFIG_MTD_NAND_AT91_ECC_HW is not set -# CONFIG_MTD_NAND_AT91_ECC_NONE is not set +CONFIG_MTD_NAND_ATMEL=y +CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y +# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_ALAUDA is not set diff --git a/arch/arm/configs/usb-a9263_defconfig b/arch/arm/configs/usb-a9263_defconfig index 48d455bc73631..b786e0407e8e0 100644 --- a/arch/arm/configs/usb-a9263_defconfig +++ b/arch/arm/configs/usb-a9263_defconfig @@ -450,10 +450,10 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_MUSEUM_IDS is not set CONFIG_MTD_NAND_IDS=y # CONFIG_MTD_NAND_DISKONCHIP is not set -CONFIG_MTD_NAND_AT91=y -CONFIG_MTD_NAND_AT91_ECC_SOFT=y -# CONFIG_MTD_NAND_AT91_ECC_HW is not set -# CONFIG_MTD_NAND_AT91_ECC_NONE is not set +CONFIG_MTD_NAND_ATMEL=y +CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y +# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set +# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set # CONFIG_MTD_NAND_NANDSIM is not set # CONFIG_MTD_NAND_PLATFORM is not set # CONFIG_MTD_ALAUDA is not set diff --git a/arch/arm/configs/yl9200_defconfig b/arch/arm/configs/yl9200_defconfig index 26de37f74686d..a9f41c24c9dc2 100644 --- a/arch/arm/configs/yl9200_defconfig +++ b/arch/arm/configs/yl9200_defconfig @@ -421,7 +421,7 @@ CONFIG_MTD_NAND=y # CONFIG_MTD_NAND_ECC_SMC is not set # CONFIG_MTD_NAND_MUSEUM_IDS is not set CONFIG_MTD_NAND_IDS=y -CONFIG_MTD_NAND_AT91=y +CONFIG_MTD_NAND_ATMEL=y # CONFIG_MTD_NAND_NANDSIM is not set CONFIG_MTD_NAND_PLATFORM=y # CONFIG_MTD_ALAUDA is not set diff --git a/include/asm-arm/Kbuild b/arch/arm/include/asm/Kbuild similarity index 100% rename from include/asm-arm/Kbuild rename to arch/arm/include/asm/Kbuild diff --git a/include/asm-arm/a.out-core.h b/arch/arm/include/asm/a.out-core.h similarity index 100% rename from include/asm-arm/a.out-core.h rename to arch/arm/include/asm/a.out-core.h diff --git a/include/asm-arm/a.out.h b/arch/arm/include/asm/a.out.h similarity index 100% rename from include/asm-arm/a.out.h rename to arch/arm/include/asm/a.out.h diff --git a/include/asm-arm/assembler.h b/arch/arm/include/asm/assembler.h similarity index 98% rename from include/asm-arm/assembler.h rename to arch/arm/include/asm/assembler.h index 911393b2c6f00..6116e4893c0ad 100644 --- a/include/asm-arm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/assembler.h + * arch/arm/include/asm/assembler.h * * Copyright (C) 1996-2000 Russell King * diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h new file mode 100644 index 0000000000000..325f881ccb502 --- /dev/null +++ b/arch/arm/include/asm/atomic.h @@ -0,0 +1,212 @@ +/* + * arch/arm/include/asm/atomic.h + * + * Copyright (C) 1996 Russell King. + * Copyright (C) 2002 Deep Blue Solutions Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_ATOMIC_H +#define __ASM_ARM_ATOMIC_H + +#include +#include + +typedef struct { volatile int counter; } atomic_t; + +#define ATOMIC_INIT(i) { (i) } + +#ifdef __KERNEL__ + +#define atomic_read(v) ((v)->counter) + +#if __LINUX_ARM_ARCH__ >= 6 + +/* + * ARMv6 UP and SMP safe atomic ops. We use load exclusive and + * store exclusive to ensure that these are atomic. We may loop + * to ensure that the update happens. Writing to 'v->counter' + * without using the following operations WILL break the atomic + * nature of these ops. + */ +static inline void atomic_set(atomic_t *v, int i) +{ + unsigned long tmp; + + __asm__ __volatile__("@ atomic_set\n" +"1: ldrex %0, [%1]\n" +" strex %0, %2, [%1]\n" +" teq %0, #0\n" +" bne 1b" + : "=&r" (tmp) + : "r" (&v->counter), "r" (i) + : "cc"); +} + +static inline int atomic_add_return(int i, atomic_t *v) +{ + unsigned long tmp; + int result; + + __asm__ __volatile__("@ atomic_add_return\n" +"1: ldrex %0, [%2]\n" +" add %0, %0, %3\n" +" strex %1, %0, [%2]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp) + : "r" (&v->counter), "Ir" (i) + : "cc"); + + return result; +} + +static inline int atomic_sub_return(int i, atomic_t *v) +{ + unsigned long tmp; + int result; + + __asm__ __volatile__("@ atomic_sub_return\n" +"1: ldrex %0, [%2]\n" +" sub %0, %0, %3\n" +" strex %1, %0, [%2]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (result), "=&r" (tmp) + : "r" (&v->counter), "Ir" (i) + : "cc"); + + return result; +} + +static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new) +{ + unsigned long oldval, res; + + do { + __asm__ __volatile__("@ atomic_cmpxchg\n" + "ldrex %1, [%2]\n" + "mov %0, #0\n" + "teq %1, %3\n" + "strexeq %0, %4, [%2]\n" + : "=&r" (res), "=&r" (oldval) + : "r" (&ptr->counter), "Ir" (old), "r" (new) + : "cc"); + } while (res); + + return oldval; +} + +static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) +{ + unsigned long tmp, tmp2; + + __asm__ __volatile__("@ atomic_clear_mask\n" +"1: ldrex %0, [%2]\n" +" bic %0, %0, %3\n" +" strex %1, %0, [%2]\n" +" teq %1, #0\n" +" bne 1b" + : "=&r" (tmp), "=&r" (tmp2) + : "r" (addr), "Ir" (mask) + : "cc"); +} + +#else /* ARM_ARCH_6 */ + +#include + +#ifdef CONFIG_SMP +#error SMP not supported on pre-ARMv6 CPUs +#endif + +#define atomic_set(v,i) (((v)->counter) = (i)) + +static inline int atomic_add_return(int i, atomic_t *v) +{ + unsigned long flags; + int val; + + raw_local_irq_save(flags); + val = v->counter; + v->counter = val += i; + raw_local_irq_restore(flags); + + return val; +} + +static inline int atomic_sub_return(int i, atomic_t *v) +{ + unsigned long flags; + int val; + + raw_local_irq_save(flags); + val = v->counter; + v->counter = val -= i; + raw_local_irq_restore(flags); + + return val; +} + +static inline int atomic_cmpxchg(atomic_t *v, int old, int new) +{ + int ret; + unsigned long flags; + + raw_local_irq_save(flags); + ret = v->counter; + if (likely(ret == old)) + v->counter = new; + raw_local_irq_restore(flags); + + return ret; +} + +static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) +{ + unsigned long flags; + + raw_local_irq_save(flags); + *addr &= ~mask; + raw_local_irq_restore(flags); +} + +#endif /* __LINUX_ARM_ARCH__ */ + +#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) + +static inline int atomic_add_unless(atomic_t *v, int a, int u) +{ + int c, old; + + c = atomic_read(v); + while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c) + c = old; + return c != u; +} +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) + +#define atomic_add(i, v) (void) atomic_add_return(i, v) +#define atomic_inc(v) (void) atomic_add_return(1, v) +#define atomic_sub(i, v) (void) atomic_sub_return(i, v) +#define atomic_dec(v) (void) atomic_sub_return(1, v) + +#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0) +#define atomic_inc_return(v) (atomic_add_return(1, v)) +#define atomic_dec_return(v) (atomic_sub_return(1, v)) +#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0) + +#define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0) + +/* Atomic operations are already serializing on ARM */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + +#include +#endif +#endif diff --git a/include/asm-arm/auxvec.h b/arch/arm/include/asm/auxvec.h similarity index 100% rename from include/asm-arm/auxvec.h rename to arch/arm/include/asm/auxvec.h diff --git a/include/asm-arm/bitops.h b/arch/arm/include/asm/bitops.h similarity index 100% rename from include/asm-arm/bitops.h rename to arch/arm/include/asm/bitops.h diff --git a/include/asm-arm/bug.h b/arch/arm/include/asm/bug.h similarity index 100% rename from include/asm-arm/bug.h rename to arch/arm/include/asm/bug.h diff --git a/arch/arm/include/asm/bugs.h b/arch/arm/include/asm/bugs.h new file mode 100644 index 0000000000000..a97f1ea708d19 --- /dev/null +++ b/arch/arm/include/asm/bugs.h @@ -0,0 +1,21 @@ +/* + * arch/arm/include/asm/bugs.h + * + * Copyright (C) 1995-2003 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. + */ +#ifndef __ASM_BUGS_H +#define __ASM_BUGS_H + +#ifdef CONFIG_MMU +extern void check_writebuffer_bugs(void); + +#define check_bugs() check_writebuffer_bugs() +#else +#define check_bugs() do { } while (0) +#endif + +#endif diff --git a/arch/arm/include/asm/byteorder.h b/arch/arm/include/asm/byteorder.h new file mode 100644 index 0000000000000..4fbfb22f65a0f --- /dev/null +++ b/arch/arm/include/asm/byteorder.h @@ -0,0 +1,58 @@ +/* + * arch/arm/include/asm/byteorder.h + * + * ARM Endian-ness. In little endian mode, the data bus is connected such + * that byte accesses appear as: + * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31 + * and word accesses (data or instruction) appear as: + * d0...d31 + * + * When in big endian mode, byte accesses appear as: + * 0 = d24...d31, 1 = d16...d23, 2 = d8...d15, 3 = d0...d7 + * and word accesses (data or instruction) appear as: + * d0...d31 + */ +#ifndef __ASM_ARM_BYTEORDER_H +#define __ASM_ARM_BYTEORDER_H + +#include +#include + +static inline __attribute_const__ __u32 ___arch__swab32(__u32 x) +{ + __u32 t; + +#ifndef __thumb__ + if (!__builtin_constant_p(x)) { + /* + * The compiler needs a bit of a hint here to always do the + * right thing and not screw it up to different degrees + * depending on the gcc version. + */ + asm ("eor\t%0, %1, %1, ror #16" : "=r" (t) : "r" (x)); + } else +#endif + t = x ^ ((x << 16) | (x >> 16)); /* eor r1,r0,r0,ror #16 */ + + x = (x << 24) | (x >> 8); /* mov r0,r0,ror #8 */ + t &= ~0x00FF0000; /* bic r1,r1,#0x00FF0000 */ + x ^= (t >> 8); /* eor r0,r0,r1,lsr #8 */ + + return x; +} + +#define __arch__swab32(x) ___arch__swab32(x) + +#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __BYTEORDER_HAS_U64__ +# define __SWAB_64_THRU_32__ +#endif + +#ifdef __ARMEB__ +#include +#else +#include +#endif + +#endif + diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h new file mode 100644 index 0000000000000..cb7a9e97fd7ef --- /dev/null +++ b/arch/arm/include/asm/cache.h @@ -0,0 +1,10 @@ +/* + * arch/arm/include/asm/cache.h + */ +#ifndef __ASMARM_CACHE_H +#define __ASMARM_CACHE_H + +#define L1_CACHE_SHIFT 5 +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) + +#endif diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h new file mode 100644 index 0000000000000..9073d9c6567e7 --- /dev/null +++ b/arch/arm/include/asm/cacheflush.h @@ -0,0 +1,537 @@ +/* + * arch/arm/include/asm/cacheflush.h + * + * Copyright (C) 1999-2002 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. + */ +#ifndef _ASMARM_CACHEFLUSH_H +#define _ASMARM_CACHEFLUSH_H + +#include +#include + +#include +#include + +#define CACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) + +/* + * Cache Model + * =========== + */ +#undef _CACHE +#undef MULTI_CACHE + +#if defined(CONFIG_CPU_CACHE_V3) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE v3 +# endif +#endif + +#if defined(CONFIG_CPU_CACHE_V4) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE v4 +# endif +#endif + +#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \ + defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) +# define MULTI_CACHE 1 +#endif + +#if defined(CONFIG_CPU_ARM926T) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE arm926 +# endif +#endif + +#if defined(CONFIG_CPU_ARM940T) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE arm940 +# endif +#endif + +#if defined(CONFIG_CPU_ARM946E) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE arm946 +# endif +#endif + +#if defined(CONFIG_CPU_CACHE_V4WB) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE v4wb +# endif +#endif + +#if defined(CONFIG_CPU_XSCALE) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE xscale +# endif +#endif + +#if defined(CONFIG_CPU_XSC3) +# ifdef _CACHE +# define MULTI_CACHE 1 +# else +# define _CACHE xsc3 +# endif +#endif + +#if defined(CONFIG_CPU_FEROCEON) +# define MULTI_CACHE 1 +#endif + +#if defined(CONFIG_CPU_V6) +//# ifdef _CACHE +# define MULTI_CACHE 1 +//# else +//# define _CACHE v6 +//# endif +#endif + +#if defined(CONFIG_CPU_V7) +//# ifdef _CACHE +# define MULTI_CACHE 1 +//# else +//# define _CACHE v7 +//# endif +#endif + +#if !defined(_CACHE) && !defined(MULTI_CACHE) +#error Unknown cache maintainence model +#endif + +/* + * This flag is used to indicate that the page pointed to by a pte + * is dirty and requires cleaning before returning it to the user. + */ +#define PG_dcache_dirty PG_arch_1 + +/* + * MM Cache Management + * =================== + * + * The arch/arm/mm/cache-*.S and arch/arm/mm/proc-*.S files + * implement these methods. + * + * Start addresses are inclusive and end addresses are exclusive; + * start addresses should be rounded down, end addresses up. + * + * See Documentation/cachetlb.txt for more information. + * Please note that the implementation of these, and the required + * effects are cache-type (VIVT/VIPT/PIPT) specific. + * + * flush_cache_kern_all() + * + * Unconditionally clean and invalidate the entire cache. + * + * flush_cache_user_mm(mm) + * + * Clean and invalidate all user space cache entries + * before a change of page tables. + * + * flush_cache_user_range(start, end, flags) + * + * Clean and invalidate a range of cache entries in the + * specified address space before a change of page tables. + * - start - user start address (inclusive, page aligned) + * - end - user end address (exclusive, page aligned) + * - flags - vma->vm_flags field + * + * 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 + * + * DMA Cache Coherency + * =================== + * + * 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 + * + * dma_clean_range(start, end) + * + * Clean (write back) the specified virtual address range. + * - start - virtual start address + * - end - virtual end address + * + * dma_flush_range(start, end) + * + * Clean and invalidate the specified virtual address range. + * - start - virtual start address + * - end - virtual end address + */ + +struct cpu_cache_fns { + void (*flush_kern_all)(void); + void (*flush_user_all)(void); + void (*flush_user_range)(unsigned long, unsigned long, unsigned int); + + void (*coherent_kern_range)(unsigned long, unsigned long); + void (*coherent_user_range)(unsigned long, unsigned long); + void (*flush_kern_dcache_page)(void *); + + void (*dma_inv_range)(const void *, const void *); + void (*dma_clean_range)(const void *, const void *); + void (*dma_flush_range)(const void *, const void *); +}; + +struct outer_cache_fns { + void (*inv_range)(unsigned long, unsigned long); + void (*clean_range)(unsigned long, unsigned long); + void (*flush_range)(unsigned long, unsigned long); +}; + +/* + * Select the calling method + */ +#ifdef MULTI_CACHE + +extern struct cpu_cache_fns cpu_cache; + +#define __cpuc_flush_kern_all cpu_cache.flush_kern_all +#define __cpuc_flush_user_all cpu_cache.flush_user_all +#define __cpuc_flush_user_range cpu_cache.flush_user_range +#define __cpuc_coherent_kern_range cpu_cache.coherent_kern_range +#define __cpuc_coherent_user_range cpu_cache.coherent_user_range +#define __cpuc_flush_dcache_page cpu_cache.flush_kern_dcache_page + +/* + * These are private to the dma-mapping API. Do not use directly. + * Their sole purpose is to ensure that data held in the cache + * is visible to DMA, or data written by DMA to system memory is + * visible to the CPU. + */ +#define dmac_inv_range cpu_cache.dma_inv_range +#define dmac_clean_range cpu_cache.dma_clean_range +#define dmac_flush_range cpu_cache.dma_flush_range + +#else + +#define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all) +#define __cpuc_flush_user_all __glue(_CACHE,_flush_user_cache_all) +#define __cpuc_flush_user_range __glue(_CACHE,_flush_user_cache_range) +#define __cpuc_coherent_kern_range __glue(_CACHE,_coherent_kern_range) +#define __cpuc_coherent_user_range __glue(_CACHE,_coherent_user_range) +#define __cpuc_flush_dcache_page __glue(_CACHE,_flush_kern_dcache_page) + +extern void __cpuc_flush_kern_all(void); +extern void __cpuc_flush_user_all(void); +extern void __cpuc_flush_user_range(unsigned long, unsigned long, unsigned int); +extern void __cpuc_coherent_kern_range(unsigned long, unsigned long); +extern void __cpuc_coherent_user_range(unsigned long, unsigned long); +extern void __cpuc_flush_dcache_page(void *); + +/* + * These are private to the dma-mapping API. Do not use directly. + * Their sole purpose is to ensure that data held in the cache + * is visible to DMA, or data written by DMA to system memory is + * visible to the CPU. + */ +#define dmac_inv_range __glue(_CACHE,_dma_inv_range) +#define dmac_clean_range __glue(_CACHE,_dma_clean_range) +#define dmac_flush_range __glue(_CACHE,_dma_flush_range) + +extern void dmac_inv_range(const void *, const void *); +extern void dmac_clean_range(const void *, const void *); +extern void dmac_flush_range(const void *, const void *); + +#endif + +#ifdef CONFIG_OUTER_CACHE + +extern struct outer_cache_fns outer_cache; + +static inline void outer_inv_range(unsigned long start, unsigned long end) +{ + if (outer_cache.inv_range) + outer_cache.inv_range(start, end); +} +static inline void outer_clean_range(unsigned long start, unsigned long end) +{ + if (outer_cache.clean_range) + outer_cache.clean_range(start, end); +} +static inline void outer_flush_range(unsigned long start, unsigned long end) +{ + if (outer_cache.flush_range) + outer_cache.flush_range(start, end); +} + +#else + +static inline void outer_inv_range(unsigned long start, unsigned long end) +{ } +static inline void outer_clean_range(unsigned long start, unsigned long end) +{ } +static inline void outer_flush_range(unsigned long start, unsigned long end) +{ } + +#endif + +/* + * flush_cache_vmap() is used when creating mappings (eg, via vmap, + * vmalloc, ioremap etc) in kernel space for pages. Since the + * direct-mappings of these pages may contain cached data, we need + * to do a full cache flush to ensure that writebacks don't corrupt + * data placed into these pages via the new mappings. + */ +#define flush_cache_vmap(start, end) flush_cache_all() +#define flush_cache_vunmap(start, end) flush_cache_all() + +/* + * Copy user data from/to a page which is mapped into a different + * processes address space. Really, we want to allow our "user + * space" model to handle this. + */ +#define copy_to_user_page(vma, page, vaddr, dst, src, len) \ + do { \ + memcpy(dst, src, len); \ + flush_ptrace_access(vma, page, vaddr, dst, len, 1);\ + } while (0) + +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + do { \ + memcpy(dst, src, len); \ + } while (0) + +/* + * Convert calls to our calling convention. + */ +#define flush_cache_all() __cpuc_flush_kern_all() +#ifndef CONFIG_CPU_CACHE_VIPT +static inline void flush_cache_mm(struct mm_struct *mm) +{ + if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) + __cpuc_flush_user_all(); +} + +static inline void +flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) +{ + if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) + __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end), + vma->vm_flags); +} + +static inline void +flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn) +{ + if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) { + unsigned long addr = user_addr & PAGE_MASK; + __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags); + } +} + +static inline void +flush_ptrace_access(struct vm_area_struct *vma, struct page *page, + unsigned long uaddr, void *kaddr, + unsigned long len, int write) +{ + if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) { + unsigned long addr = (unsigned long)kaddr; + __cpuc_coherent_kern_range(addr, addr + len); + } +} +#else +extern void flush_cache_mm(struct mm_struct *mm); +extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); +extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn); +extern void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, + unsigned long uaddr, void *kaddr, + unsigned long len, int write); +#endif + +#define flush_cache_dup_mm(mm) flush_cache_mm(mm) + +/* + * flush_cache_user_range is used when we want to ensure that the + * Harvard caches are synchronised for the user space address range. + * This is used for the ARM private sys_cacheflush system call. + */ +#define flush_cache_user_range(vma,start,end) \ + __cpuc_coherent_user_range((start) & PAGE_MASK, PAGE_ALIGN(end)) + +/* + * Perform necessary cache operations to ensure that data previously + * stored within this range of addresses can be executed by the CPU. + */ +#define flush_icache_range(s,e) __cpuc_coherent_kern_range(s,e) + +/* + * Perform necessary cache operations to ensure that the TLB will + * see data written in the specified area. + */ +#define clean_dcache_area(start,size) cpu_dcache_clean_area(start, size) + +/* + * flush_dcache_page is used when the kernel has written to the page + * cache page at virtual address page->virtual. + * + * If this page isn't mapped (ie, page_mapping == NULL), or it might + * have userspace mappings, then we _must_ always clean + invalidate + * the dcache entries associated with the kernel mapping. + * + * Otherwise we can defer the operation, and clean the cache when we are + * about to change to user space. This is the same method as used on SPARC64. + * See update_mmu_cache for the user space part. + */ +extern void flush_dcache_page(struct page *); + +extern void __flush_dcache_page(struct address_space *mapping, struct page *page); + +static inline void __flush_icache_all(void) +{ + asm("mcr p15, 0, %0, c7, c5, 0 @ invalidate I-cache\n" + : + : "r" (0)); +} + +#define ARCH_HAS_FLUSH_ANON_PAGE +static inline void flush_anon_page(struct vm_area_struct *vma, + struct page *page, unsigned long vmaddr) +{ + extern void __flush_anon_page(struct vm_area_struct *vma, + struct page *, unsigned long); + if (PageAnon(page)) + __flush_anon_page(vma, page, vmaddr); +} + +#define flush_dcache_mmap_lock(mapping) \ + spin_lock_irq(&(mapping)->tree_lock) +#define flush_dcache_mmap_unlock(mapping) \ + spin_unlock_irq(&(mapping)->tree_lock) + +#define flush_icache_user_range(vma,page,addr,len) \ + flush_dcache_page(page) + +/* + * We don't appear to need to do anything here. In fact, if we did, we'd + * duplicate cache flushing elsewhere performed by flush_dcache_page(). + */ +#define flush_icache_page(vma,page) do { } while (0) + +static inline void flush_ioremap_region(unsigned long phys, void __iomem *virt, + unsigned offset, size_t size) +{ + const void *start = (void __force *)virt + offset; + dmac_inv_range(start, start + size); +} + +#define __cacheid_present(val) (val != read_cpuid(CPUID_ID)) +#define __cacheid_type_v7(val) ((val & (7 << 29)) == (4 << 29)) + +#define __cacheid_vivt_prev7(val) ((val & (15 << 25)) != (14 << 25)) +#define __cacheid_vipt_prev7(val) ((val & (15 << 25)) == (14 << 25)) +#define __cacheid_vipt_nonaliasing_prev7(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25)) +#define __cacheid_vipt_aliasing_prev7(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25 | 1 << 23)) + +#define __cacheid_vivt(val) (__cacheid_type_v7(val) ? 0 : __cacheid_vivt_prev7(val)) +#define __cacheid_vipt(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_prev7(val)) +#define __cacheid_vipt_nonaliasing(val) (__cacheid_type_v7(val) ? 1 : __cacheid_vipt_nonaliasing_prev7(val)) +#define __cacheid_vipt_aliasing(val) (__cacheid_type_v7(val) ? 0 : __cacheid_vipt_aliasing_prev7(val)) +#define __cacheid_vivt_asid_tagged_instr(val) (__cacheid_type_v7(val) ? ((val & (3 << 14)) == (1 << 14)) : 0) + +#if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT) +/* + * VIVT caches only + */ +#define cache_is_vivt() 1 +#define cache_is_vipt() 0 +#define cache_is_vipt_nonaliasing() 0 +#define cache_is_vipt_aliasing() 0 +#define icache_is_vivt_asid_tagged() 0 + +#elif !defined(CONFIG_CPU_CACHE_VIVT) && defined(CONFIG_CPU_CACHE_VIPT) +/* + * VIPT caches only + */ +#define cache_is_vivt() 0 +#define cache_is_vipt() 1 +#define cache_is_vipt_nonaliasing() \ + ({ \ + unsigned int __val = read_cpuid(CPUID_CACHETYPE); \ + __cacheid_vipt_nonaliasing(__val); \ + }) + +#define cache_is_vipt_aliasing() \ + ({ \ + unsigned int __val = read_cpuid(CPUID_CACHETYPE); \ + __cacheid_vipt_aliasing(__val); \ + }) + +#define icache_is_vivt_asid_tagged() \ + ({ \ + unsigned int __val = read_cpuid(CPUID_CACHETYPE); \ + __cacheid_vivt_asid_tagged_instr(__val); \ + }) + +#else +/* + * VIVT or VIPT caches. Note that this is unreliable since ARM926 + * and V6 CPUs satisfy the "(val & (15 << 25)) == (14 << 25)" test. + * There's no way to tell from the CacheType register what type (!) + * the cache is. + */ +#define cache_is_vivt() \ + ({ \ + unsigned int __val = read_cpuid(CPUID_CACHETYPE); \ + (!__cacheid_present(__val)) || __cacheid_vivt(__val); \ + }) + +#define cache_is_vipt() \ + ({ \ + unsigned int __val = read_cpuid(CPUID_CACHETYPE); \ + __cacheid_present(__val) && __cacheid_vipt(__val); \ + }) + +#define cache_is_vipt_nonaliasing() \ + ({ \ + unsigned int __val = read_cpuid(CPUID_CACHETYPE); \ + __cacheid_present(__val) && \ + __cacheid_vipt_nonaliasing(__val); \ + }) + +#define cache_is_vipt_aliasing() \ + ({ \ + unsigned int __val = read_cpuid(CPUID_CACHETYPE); \ + __cacheid_present(__val) && \ + __cacheid_vipt_aliasing(__val); \ + }) + +#define icache_is_vivt_asid_tagged() \ + ({ \ + unsigned int __val = read_cpuid(CPUID_CACHETYPE); \ + __cacheid_present(__val) && \ + __cacheid_vivt_asid_tagged_instr(__val); \ + }) + +#endif + +#endif diff --git a/arch/arm/include/asm/checksum.h b/arch/arm/include/asm/checksum.h new file mode 100644 index 0000000000000..6dcc164308688 --- /dev/null +++ b/arch/arm/include/asm/checksum.h @@ -0,0 +1,139 @@ +/* + * arch/arm/include/asm/checksum.h + * + * IP checksum routines + * + * Copyright (C) Original authors of ../asm-i386/checksum.h + * Copyright (C) 1996-1999 Russell King + */ +#ifndef __ASM_ARM_CHECKSUM_H +#define __ASM_ARM_CHECKSUM_H + +#include + +/* + * computes the checksum of a memory block at buff, length len, + * and adds in "sum" (32-bit) + * + * returns a 32-bit number suitable for feeding into itself + * or csum_tcpudp_magic + * + * this function must be called with even lengths, except + * for the last fragment, which may be odd + * + * it's best to have buff aligned on a 32-bit boundary + */ +__wsum csum_partial(const void *buff, int len, __wsum sum); + +/* + * the same as csum_partial, but copies from src while it + * checksums, and handles user-space pointer exceptions correctly, when needed. + * + * here even more important to align src and dst on a 32-bit (or even + * better 64-bit) boundary + */ + +__wsum +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum); + +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr); + +/* + * Fold a partial checksum without adding pseudo headers + */ +static inline __sum16 csum_fold(__wsum sum) +{ + __asm__( + "add %0, %1, %1, ror #16 @ csum_fold" + : "=r" (sum) + : "r" (sum) + : "cc"); + return (__force __sum16)(~(__force u32)sum >> 16); +} + +/* + * This is a version of ip_compute_csum() optimized for IP headers, + * which always checksum on 4 octet boundaries. + */ +static inline __sum16 +ip_fast_csum(const void *iph, unsigned int ihl) +{ + unsigned int tmp1; + __wsum sum; + + __asm__ __volatile__( + "ldr %0, [%1], #4 @ ip_fast_csum \n\ + ldr %3, [%1], #4 \n\ + sub %2, %2, #5 \n\ + adds %0, %0, %3 \n\ + ldr %3, [%1], #4 \n\ + adcs %0, %0, %3 \n\ + ldr %3, [%1], #4 \n\ +1: adcs %0, %0, %3 \n\ + ldr %3, [%1], #4 \n\ + tst %2, #15 @ do this carefully \n\ + subne %2, %2, #1 @ without destroying \n\ + bne 1b @ the carry flag \n\ + adcs %0, %0, %3 \n\ + adc %0, %0, #0" + : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1) + : "1" (iph), "2" (ihl) + : "cc", "memory"); + return csum_fold(sum); +} + +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + __asm__( + "adds %0, %1, %2 @ csum_tcpudp_nofold \n\ + adcs %0, %0, %3 \n" +#ifdef __ARMEB__ + "adcs %0, %0, %4 \n" +#else + "adcs %0, %0, %4, lsl #8 \n" +#endif + "adcs %0, %0, %5 \n\ + adc %0, %0, #0" + : "=&r"(sum) + : "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto)) + : "cc"); + return sum; +} +/* + * computes the checksum of the TCP/UDP pseudo-header + * returns a 16-bit checksum, already complemented + */ +static inline __sum16 +csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) +{ + return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); +} + + +/* + * this routine is used for miscellaneous IP-like checksums, mainly + * in icmp.c + */ +static inline __sum16 +ip_compute_csum(const void *buff, int len) +{ + return csum_fold(csum_partial(buff, len, 0)); +} + +#define _HAVE_ARCH_IPV6_CSUM +extern __wsum +__csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __be32 len, + __be32 proto, __wsum sum); + +static inline __sum16 +csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, __u32 len, + unsigned short proto, __wsum sum) +{ + return csum_fold(__csum_ipv6_magic(saddr, daddr, htonl(len), + htonl(proto), sum)); +} +#endif diff --git a/include/asm-arm/cnt32_to_63.h b/arch/arm/include/asm/cnt32_to_63.h similarity index 100% rename from include/asm-arm/cnt32_to_63.h rename to arch/arm/include/asm/cnt32_to_63.h diff --git a/include/asm-arm/cpu-multi32.h b/arch/arm/include/asm/cpu-multi32.h similarity index 97% rename from include/asm-arm/cpu-multi32.h rename to arch/arm/include/asm/cpu-multi32.h index 3479de9266e55..e2b5b0b2116a7 100644 --- a/include/asm-arm/cpu-multi32.h +++ b/arch/arm/include/asm/cpu-multi32.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/cpu-multi32.h + * arch/arm/include/asm/cpu-multi32.h * * Copyright (C) 2000 Russell King * diff --git a/include/asm-arm/cpu-single.h b/arch/arm/include/asm/cpu-single.h similarity index 97% rename from include/asm-arm/cpu-single.h rename to arch/arm/include/asm/cpu-single.h index 0b120ee36091c..f073a6d2a406b 100644 --- a/include/asm-arm/cpu-single.h +++ b/arch/arm/include/asm/cpu-single.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/cpu-single.h + * arch/arm/include/asm/cpu-single.h * * Copyright (C) 2000 Russell King * diff --git a/arch/arm/include/asm/cpu.h b/arch/arm/include/asm/cpu.h new file mode 100644 index 0000000000000..634b2d7c612a7 --- /dev/null +++ b/arch/arm/include/asm/cpu.h @@ -0,0 +1,25 @@ +/* + * arch/arm/include/asm/cpu.h + * + * Copyright (C) 2004-2005 ARM Ltd. + * + * 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. + */ +#ifndef __ASM_ARM_CPU_H +#define __ASM_ARM_CPU_H + +#include + +struct cpuinfo_arm { + struct cpu cpu; +#ifdef CONFIG_SMP + struct task_struct *idle; + unsigned int loops_per_jiffy; +#endif +}; + +DECLARE_PER_CPU(struct cpuinfo_arm, cpu_data); + +#endif diff --git a/include/asm-arm/cputime.h b/arch/arm/include/asm/cputime.h similarity index 100% rename from include/asm-arm/cputime.h rename to arch/arm/include/asm/cputime.h diff --git a/include/asm-arm/current.h b/arch/arm/include/asm/current.h similarity index 100% rename from include/asm-arm/current.h rename to arch/arm/include/asm/current.h diff --git a/include/asm-arm/delay.h b/arch/arm/include/asm/delay.h similarity index 100% rename from include/asm-arm/delay.h rename to arch/arm/include/asm/delay.h diff --git a/include/asm-arm/device.h b/arch/arm/include/asm/device.h similarity index 100% rename from include/asm-arm/device.h rename to arch/arm/include/asm/device.h diff --git a/include/asm-arm/div64.h b/arch/arm/include/asm/div64.h similarity index 100% rename from include/asm-arm/div64.h rename to arch/arm/include/asm/div64.h diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h new file mode 100644 index 0000000000000..45329fca1b64e --- /dev/null +++ b/arch/arm/include/asm/dma-mapping.h @@ -0,0 +1,458 @@ +#ifndef ASMARM_DMA_MAPPING_H +#define ASMARM_DMA_MAPPING_H + +#ifdef __KERNEL__ + +#include /* need struct page */ + +#include + +#include + +/* + * DMA-consistent mapping functions. These allocate/free a region of + * uncached, unwrite-buffered mapped memory space for use with DMA + * devices. This is the "generic" version. The PCI specific version + * is in pci.h + * + * Note: Drivers should NOT use this function directly, as it will break + * platforms with CONFIG_DMABOUNCE. + * Use the driver DMA support - see dma-mapping.h (dma_sync_*) + */ +extern void dma_cache_maint(const void *kaddr, size_t size, int rw); + +/* + * Return whether the given device DMA address mask can be supported + * properly. For example, if your device can only drive the low 24-bits + * during bus mastering, then you would pass 0x00ffffff as the mask + * to this function. + * + * FIXME: This should really be a platform specific issue - we should + * return false if GFP_DMA allocations may not satisfy the supplied 'mask'. + */ +static inline int dma_supported(struct device *dev, u64 mask) +{ + return dev->dma_mask && *dev->dma_mask != 0; +} + +static inline int dma_set_mask(struct device *dev, u64 dma_mask) +{ + if (!dev->dma_mask || !dma_supported(dev, dma_mask)) + return -EIO; + + *dev->dma_mask = dma_mask; + + return 0; +} + +static inline int dma_get_cache_alignment(void) +{ + return 32; +} + +static inline int dma_is_consistent(struct device *dev, dma_addr_t handle) +{ + return !!arch_is_coherent(); +} + +/* + * DMA errors are defined by all-bits-set in the DMA address. + */ +static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) +{ + return dma_addr == ~0; +} + +/* + * Dummy noncoherent implementation. We don't provide a dma_cache_sync + * function so drivers using this API are highlighted with build warnings. + */ +static inline void * +dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) +{ + return NULL; +} + +static inline void +dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr, + dma_addr_t handle) +{ +} + +/** + * dma_alloc_coherent - allocate consistent memory for DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @size: required memory size + * @handle: bus-specific DMA address + * + * Allocate some uncached, unbuffered memory for a device for + * performing DMA. This function allocates pages, and will + * return the CPU-viewed address, and sets @handle to be the + * device-viewed address. + */ +extern void * +dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp); + +/** + * dma_free_coherent - free memory allocated by dma_alloc_coherent + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @size: size of memory originally requested in dma_alloc_coherent + * @cpu_addr: CPU-view address returned from dma_alloc_coherent + * @handle: device-view address returned from dma_alloc_coherent + * + * Free (and unmap) a DMA buffer previously allocated by + * dma_alloc_coherent(). + * + * References to memory and mappings associated with cpu_addr/handle + * during and after this call executing are illegal. + */ +extern void +dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, + dma_addr_t handle); + +/** + * dma_mmap_coherent - map a coherent DMA allocation into user space + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @vma: vm_area_struct describing requested user mapping + * @cpu_addr: kernel CPU-view address returned from dma_alloc_coherent + * @handle: device-view address returned from dma_alloc_coherent + * @size: size of memory originally requested in dma_alloc_coherent + * + * Map a coherent DMA buffer previously allocated by dma_alloc_coherent + * into user space. The coherent DMA buffer must not be freed by the + * driver until the user space mapping has been released. + */ +int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t handle, size_t size); + + +/** + * dma_alloc_writecombine - allocate writecombining memory for DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @size: required memory size + * @handle: bus-specific DMA address + * + * Allocate some uncached, buffered memory for a device for + * performing DMA. This function allocates pages, and will + * return the CPU-viewed address, and sets @handle to be the + * device-viewed address. + */ +extern void * +dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp); + +#define dma_free_writecombine(dev,size,cpu_addr,handle) \ + dma_free_coherent(dev,size,cpu_addr,handle) + +int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t handle, size_t size); + + +/** + * dma_map_single - map a single buffer for streaming DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @cpu_addr: CPU direct mapped address of buffer + * @size: size of buffer to map + * @dir: DMA transfer direction + * + * Ensure that any data held in the cache is appropriately discarded + * or written back. + * + * The device owns this memory once this call has completed. The CPU + * can regain ownership by calling dma_unmap_single() or + * dma_sync_single_for_cpu(). + */ +#ifndef CONFIG_DMABOUNCE +static inline dma_addr_t +dma_map_single(struct device *dev, void *cpu_addr, size_t size, + enum dma_data_direction dir) +{ + if (!arch_is_coherent()) + dma_cache_maint(cpu_addr, size, dir); + + return virt_to_dma(dev, (unsigned long)cpu_addr); +} +#else +extern dma_addr_t dma_map_single(struct device *,void *, size_t, enum dma_data_direction); +#endif + +/** + * dma_map_page - map a portion of a page for streaming DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @page: page that buffer resides in + * @offset: offset into page for start of buffer + * @size: size of buffer to map + * @dir: DMA transfer direction + * + * Ensure that any data held in the cache is appropriately discarded + * or written back. + * + * The device owns this memory once this call has completed. The CPU + * can regain ownership by calling dma_unmap_page() or + * dma_sync_single_for_cpu(). + */ +static inline dma_addr_t +dma_map_page(struct device *dev, struct page *page, + unsigned long offset, size_t size, + enum dma_data_direction dir) +{ + return dma_map_single(dev, page_address(page) + offset, size, (int)dir); +} + +/** + * dma_unmap_single - unmap a single buffer previously mapped + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @handle: DMA address of buffer + * @size: size of buffer to map + * @dir: DMA transfer direction + * + * Unmap a single streaming mode DMA translation. The handle and size + * must match what was provided in the previous dma_map_single() call. + * All other usages are undefined. + * + * After this call, reads by the CPU to the buffer are guaranteed to see + * whatever the device wrote there. + */ +#ifndef CONFIG_DMABOUNCE +static inline void +dma_unmap_single(struct device *dev, dma_addr_t handle, size_t size, + enum dma_data_direction dir) +{ + /* nothing to do */ +} +#else +extern void dma_unmap_single(struct device *, dma_addr_t, size_t, enum dma_data_direction); +#endif + +/** + * dma_unmap_page - unmap a buffer previously mapped through dma_map_page() + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @handle: DMA address of buffer + * @size: size of buffer to map + * @dir: DMA transfer direction + * + * Unmap a single streaming mode DMA translation. The handle and size + * must match what was provided in the previous dma_map_single() call. + * All other usages are undefined. + * + * After this call, reads by the CPU to the buffer are guaranteed to see + * whatever the device wrote there. + */ +static inline void +dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size, + enum dma_data_direction dir) +{ + dma_unmap_single(dev, handle, size, (int)dir); +} + +/** + * dma_map_sg - map a set of SG buffers for streaming mode DMA + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @sg: list of buffers + * @nents: number of buffers to map + * @dir: DMA transfer direction + * + * Map a set of buffers described by scatterlist in streaming + * mode for DMA. This is the scatter-gather version of the + * above dma_map_single interface. Here the scatter gather list + * elements are each tagged with the appropriate dma address + * and length. They are obtained via sg_dma_{address,length}(SG). + * + * NOTE: An implementation may be able to use a smaller number of + * DMA address/length pairs than there are SG table elements. + * (for example via virtual mapping capabilities) + * The routine returns the number of addr/length pairs actually + * used, at most nents. + * + * Device ownership issues as mentioned above for dma_map_single are + * the same here. + */ +#ifndef CONFIG_DMABOUNCE +static inline int +dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) +{ + int i; + + for (i = 0; i < nents; i++, sg++) { + char *virt; + + sg->dma_address = page_to_dma(dev, sg_page(sg)) + sg->offset; + virt = sg_virt(sg); + + if (!arch_is_coherent()) + dma_cache_maint(virt, sg->length, dir); + } + + return nents; +} +#else +extern int dma_map_sg(struct device *, struct scatterlist *, int, enum dma_data_direction); +#endif + +/** + * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @sg: list of buffers + * @nents: number of buffers to map + * @dir: DMA transfer direction + * + * Unmap a set of streaming mode DMA translations. + * Again, CPU read rules concerning calls here are the same as for + * dma_unmap_single() above. + */ +#ifndef CONFIG_DMABOUNCE +static inline void +dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) +{ + + /* nothing to do */ +} +#else +extern void dma_unmap_sg(struct device *, struct scatterlist *, int, enum dma_data_direction); +#endif + + +/** + * dma_sync_single_for_cpu + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @handle: DMA address of buffer + * @size: size of buffer to map + * @dir: DMA transfer direction + * + * Make physical memory consistent for a single streaming mode DMA + * translation after a transfer. + * + * If you perform a dma_map_single() but wish to interrogate the + * buffer using the cpu, yet do not wish to teardown the PCI dma + * mapping, you must call this function before doing so. At the + * next point you give the PCI dma address back to the card, you + * must first the perform a dma_sync_for_device, and then the + * device again owns the buffer. + */ +#ifndef CONFIG_DMABOUNCE +static inline void +dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size, + enum dma_data_direction dir) +{ + if (!arch_is_coherent()) + dma_cache_maint((void *)dma_to_virt(dev, handle), size, dir); +} + +static inline void +dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size, + enum dma_data_direction dir) +{ + if (!arch_is_coherent()) + dma_cache_maint((void *)dma_to_virt(dev, handle), size, dir); +} +#else +extern void dma_sync_single_for_cpu(struct device*, dma_addr_t, size_t, enum dma_data_direction); +extern void dma_sync_single_for_device(struct device*, dma_addr_t, size_t, enum dma_data_direction); +#endif + + +/** + * dma_sync_sg_for_cpu + * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices + * @sg: list of buffers + * @nents: number of buffers to map + * @dir: DMA transfer direction + * + * Make physical memory consistent for a set of streaming + * mode DMA translations after a transfer. + * + * The same as dma_sync_single_for_* but for a scatter-gather list, + * same rules and usage. + */ +#ifndef CONFIG_DMABOUNCE +static inline void +dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) +{ + int i; + + for (i = 0; i < nents; i++, sg++) { + char *virt = sg_virt(sg); + if (!arch_is_coherent()) + dma_cache_maint(virt, sg->length, dir); + } +} + +static inline void +dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction dir) +{ + int i; + + for (i = 0; i < nents; i++, sg++) { + char *virt = sg_virt(sg); + if (!arch_is_coherent()) + dma_cache_maint(virt, sg->length, dir); + } +} +#else +extern void dma_sync_sg_for_cpu(struct device*, struct scatterlist*, int, enum dma_data_direction); +extern void dma_sync_sg_for_device(struct device*, struct scatterlist*, int, enum dma_data_direction); +#endif + +#ifdef CONFIG_DMABOUNCE +/* + * For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic" + * and utilize bounce buffers as needed to work around limited DMA windows. + * + * On the SA-1111, a bug limits DMA to only certain regions of RAM. + * On the IXP425, the PCI inbound window is 64MB (256MB total RAM) + * On some ADI engineering systems, PCI inbound window is 32MB (12MB total RAM) + * + * The following are helper functions used by the dmabounce subystem + * + */ + +/** + * dmabounce_register_dev + * + * @dev: valid struct device pointer + * @small_buf_size: size of buffers to use with small buffer pool + * @large_buf_size: size of buffers to use with large buffer pool (can be 0) + * + * This function should be called by low-level platform code to register + * a device as requireing DMA buffer bouncing. The function will allocate + * appropriate DMA pools for the device. + * + */ +extern int dmabounce_register_dev(struct device *, unsigned long, unsigned long); + +/** + * dmabounce_unregister_dev + * + * @dev: valid struct device pointer + * + * This function should be called by low-level platform code when device + * that was previously registered with dmabounce_register_dev is removed + * from the system. + * + */ +extern void dmabounce_unregister_dev(struct device *); + +/** + * dma_needs_bounce + * + * @dev: valid struct device pointer + * @dma_handle: dma_handle of unbounced buffer + * @size: size of region being mapped + * + * Platforms that utilize the dmabounce mechanism must implement + * this function. + * + * The dmabounce routines call this function whenever a dma-mapping + * is requested to determine whether a given buffer needs to be bounced + * or not. The function must return 0 if the buffer is OK for + * DMA access and 1 if the buffer needs to be bounced. + * + */ +extern int dma_needs_bounce(struct device*, dma_addr_t, size_t); +#endif /* CONFIG_DMABOUNCE */ + +#endif /* __KERNEL__ */ +#endif diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h new file mode 100644 index 0000000000000..75154b1931173 --- /dev/null +++ b/arch/arm/include/asm/dma.h @@ -0,0 +1,143 @@ +#ifndef __ASM_ARM_DMA_H +#define __ASM_ARM_DMA_H + +typedef unsigned int dmach_t; + +#include +#include +#include +#include + +/* + * This is the maximum virtual address which can be DMA'd from. + */ +#ifndef MAX_DMA_ADDRESS +#define MAX_DMA_ADDRESS 0xffffffff +#endif + +/* + * DMA modes + */ +typedef unsigned int dmamode_t; + +#define DMA_MODE_MASK 3 + +#define DMA_MODE_READ 0 +#define DMA_MODE_WRITE 1 +#define DMA_MODE_CASCADE 2 +#define DMA_AUTOINIT 4 + +extern spinlock_t dma_spin_lock; + +static inline unsigned long claim_dma_lock(void) +{ + unsigned long flags; + spin_lock_irqsave(&dma_spin_lock, flags); + return flags; +} + +static inline void release_dma_lock(unsigned long flags) +{ + spin_unlock_irqrestore(&dma_spin_lock, flags); +} + +/* Clear the 'DMA Pointer Flip Flop'. + * Write 0 for LSB/MSB, 1 for MSB/LSB access. + */ +#define clear_dma_ff(channel) + +/* Set only the page register bits of the transfer address. + * + * NOTE: This is an architecture specific function, and should + * be hidden from the drivers + */ +extern void set_dma_page(dmach_t channel, char pagenr); + +/* Request a DMA channel + * + * Some architectures may need to do allocate an interrupt + */ +extern int request_dma(dmach_t channel, const char * device_id); + +/* Free a DMA channel + * + * Some architectures may need to do free an interrupt + */ +extern void free_dma(dmach_t channel); + +/* Enable DMA for this channel + * + * On some architectures, this may have other side effects like + * enabling an interrupt and setting the DMA registers. + */ +extern void enable_dma(dmach_t channel); + +/* Disable DMA for this channel + * + * On some architectures, this may have other side effects like + * disabling an interrupt or whatever. + */ +extern void disable_dma(dmach_t channel); + +/* Test whether the specified channel has an active DMA transfer + */ +extern int dma_channel_active(dmach_t channel); + +/* Set the DMA scatter gather list for this channel + * + * This should not be called if a DMA channel is enabled, + * especially since some DMA architectures don't update the + * DMA address immediately, but defer it to the enable_dma(). + */ +extern void set_dma_sg(dmach_t channel, struct scatterlist *sg, int nr_sg); + +/* Set the DMA address for this channel + * + * This should not be called if a DMA channel is enabled, + * especially since some DMA architectures don't update the + * DMA address immediately, but defer it to the enable_dma(). + */ +extern void __set_dma_addr(dmach_t channel, void *addr); +#define set_dma_addr(channel, addr) \ + __set_dma_addr(channel, bus_to_virt(addr)) + +/* Set the DMA byte count for this channel + * + * This should not be called if a DMA channel is enabled, + * especially since some DMA architectures don't update the + * DMA count immediately, but defer it to the enable_dma(). + */ +extern void set_dma_count(dmach_t channel, unsigned long count); + +/* Set the transfer direction for this channel + * + * This should not be called if a DMA channel is enabled, + * especially since some DMA architectures don't update the + * DMA transfer direction immediately, but defer it to the + * enable_dma(). + */ +extern void set_dma_mode(dmach_t channel, dmamode_t mode); + +/* Set the transfer speed for this channel + */ +extern void set_dma_speed(dmach_t channel, int cycle_ns); + +/* Get DMA residue count. After a DMA transfer, this + * should return zero. Reading this while a DMA transfer is + * still in progress will return unpredictable results. + * If called before the channel has been used, it may return 1. + * Otherwise, it returns the number of _bytes_ left to transfer. + */ +extern int get_dma_residue(dmach_t channel); + +#ifndef NO_DMA +#define NO_DMA 255 +#endif + +#ifdef CONFIG_PCI +extern int isa_dma_bridge_buggy; +#else +#define isa_dma_bridge_buggy (0) +#endif + +#endif /* _ARM_DMA_H */ diff --git a/include/asm-arm/domain.h b/arch/arm/include/asm/domain.h similarity index 98% rename from include/asm-arm/domain.h rename to arch/arm/include/asm/domain.h index 3c12a7625304d..cc7ef4080711f 100644 --- a/include/asm-arm/domain.h +++ b/arch/arm/include/asm/domain.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/domain.h + * arch/arm/include/asm/domain.h * * Copyright (C) 1999 Russell King. * diff --git a/include/asm-arm/ecard.h b/arch/arm/include/asm/ecard.h similarity index 99% rename from include/asm-arm/ecard.h rename to arch/arm/include/asm/ecard.h index 5e22881a630da..29f2610efc707 100644 --- a/include/asm-arm/ecard.h +++ b/arch/arm/include/asm/ecard.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/ecard.h + * arch/arm/include/asm/ecard.h * * definitions for expansion cards * diff --git a/include/asm-arm/elf.h b/arch/arm/include/asm/elf.h similarity index 100% rename from include/asm-arm/elf.h rename to arch/arm/include/asm/elf.h diff --git a/include/asm-arm/emergency-restart.h b/arch/arm/include/asm/emergency-restart.h similarity index 100% rename from include/asm-arm/emergency-restart.h rename to arch/arm/include/asm/emergency-restart.h diff --git a/include/asm-arm/errno.h b/arch/arm/include/asm/errno.h similarity index 100% rename from include/asm-arm/errno.h rename to arch/arm/include/asm/errno.h diff --git a/include/asm-arm/fb.h b/arch/arm/include/asm/fb.h similarity index 100% rename from include/asm-arm/fb.h rename to arch/arm/include/asm/fb.h diff --git a/include/asm-arm/fcntl.h b/arch/arm/include/asm/fcntl.h similarity index 100% rename from include/asm-arm/fcntl.h rename to arch/arm/include/asm/fcntl.h diff --git a/include/asm-arm/fiq.h b/arch/arm/include/asm/fiq.h similarity index 96% rename from include/asm-arm/fiq.h rename to arch/arm/include/asm/fiq.h index a3bad09e825ca..2242ce22ec6c8 100644 --- a/include/asm-arm/fiq.h +++ b/arch/arm/include/asm/fiq.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/fiq.h + * arch/arm/include/asm/fiq.h * * Support for FIQ on ARM architectures. * Written by Philip Blundell , 1998 diff --git a/include/asm-arm/flat.h b/arch/arm/include/asm/flat.h similarity index 90% rename from include/asm-arm/flat.h rename to arch/arm/include/asm/flat.h index 9918aa46d9e53..1d77e51907f6d 100644 --- a/include/asm-arm/flat.h +++ b/arch/arm/include/asm/flat.h @@ -1,5 +1,5 @@ /* - * include/asm-arm/flat.h -- uClinux flat-format executables + * arch/arm/include/asm/flat.h -- uClinux flat-format executables */ #ifndef __ARM_FLAT_H__ diff --git a/arch/arm/include/asm/floppy.h b/arch/arm/include/asm/floppy.h new file mode 100644 index 0000000000000..c9f03eccc9d86 --- /dev/null +++ b/arch/arm/include/asm/floppy.h @@ -0,0 +1,148 @@ +/* + * arch/arm/include/asm/floppy.h + * + * Copyright (C) 1996-2000 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. + * + * Note that we don't touch FLOPPY_DMA nor FLOPPY_IRQ here + */ +#ifndef __ASM_ARM_FLOPPY_H +#define __ASM_ARM_FLOPPY_H +#if 0 +#include +#endif + +#define fd_outb(val,port) \ + do { \ + if ((port) == FD_DOR) \ + fd_setdor((val)); \ + else \ + outb((val),(port)); \ + } while(0) + +#define fd_inb(port) inb((port)) +#define fd_request_irq() request_irq(IRQ_FLOPPYDISK,floppy_interrupt,\ + IRQF_DISABLED,"floppy",NULL) +#define fd_free_irq() free_irq(IRQ_FLOPPYDISK,NULL) +#define fd_disable_irq() disable_irq(IRQ_FLOPPYDISK) +#define fd_enable_irq() enable_irq(IRQ_FLOPPYDISK) + +static inline int fd_dma_setup(void *data, unsigned int length, + unsigned int mode, unsigned long addr) +{ + set_dma_mode(DMA_FLOPPY, mode); + __set_dma_addr(DMA_FLOPPY, data); + set_dma_count(DMA_FLOPPY, length); + virtual_dma_port = addr; + enable_dma(DMA_FLOPPY); + return 0; +} +#define fd_dma_setup fd_dma_setup + +#define fd_request_dma() request_dma(DMA_FLOPPY,"floppy") +#define fd_free_dma() free_dma(DMA_FLOPPY) +#define fd_disable_dma() disable_dma(DMA_FLOPPY) + +/* need to clean up dma.h */ +#define DMA_FLOPPYDISK DMA_FLOPPY + +/* Floppy_selects is the list of DOR's to select drive fd + * + * On initialisation, the floppy list is scanned, and the drives allocated + * in the order that they are found. This is done by seeking the drive + * to a non-zero track, and then restoring it to track 0. If an error occurs, + * then there is no floppy drive present. [to be put back in again] + */ +static unsigned char floppy_selects[2][4] = +{ + { 0x10, 0x21, 0x23, 0x33 }, + { 0x10, 0x21, 0x23, 0x33 } +}; + +#define fd_setdor(dor) \ +do { \ + int new_dor = (dor); \ + if (new_dor & 0xf0) \ + new_dor = (new_dor & 0x0c) | floppy_selects[fdc][new_dor & 3]; \ + else \ + new_dor &= 0x0c; \ + outb(new_dor, FD_DOR); \ +} while (0) + +/* + * Someday, we'll automatically detect which drives are present... + */ +static inline void fd_scandrives (void) +{ +#if 0 + int floppy, drive_count; + + fd_disable_irq(); + raw_cmd = &default_raw_cmd; + raw_cmd->flags = FD_RAW_SPIN | FD_RAW_NEED_SEEK; + raw_cmd->track = 0; + raw_cmd->rate = ?; + drive_count = 0; + for (floppy = 0; floppy < 4; floppy ++) { + current_drive = drive_count; + /* + * Turn on floppy motor + */ + if (start_motor(redo_fd_request)) + continue; + /* + * Set up FDC + */ + fdc_specify(); + /* + * Tell FDC to recalibrate + */ + output_byte(FD_RECALIBRATE); + LAST_OUT(UNIT(floppy)); + /* wait for command to complete */ + if (!successful) { + int i; + for (i = drive_count; i < 3; i--) + floppy_selects[fdc][i] = floppy_selects[fdc][i + 1]; + floppy_selects[fdc][3] = 0; + floppy -= 1; + } else + drive_count++; + } +#else + floppy_selects[0][0] = 0x10; + floppy_selects[0][1] = 0x21; + floppy_selects[0][2] = 0x23; + floppy_selects[0][3] = 0x33; +#endif +} + +#define FDC1 (0x3f0) + +#define FLOPPY0_TYPE 4 +#define FLOPPY1_TYPE 4 + +#define N_FDC 1 +#define N_DRIVE 4 + +#define CROSS_64KB(a,s) (0) + +/* + * This allows people to reverse the order of + * fd0 and fd1, in case their hardware is + * strangely connected (as some RiscPCs + * and A5000s seem to be). + */ +static void driveswap(int *ints, int dummy, int dummy2) +{ + floppy_selects[0][0] ^= floppy_selects[0][1]; + floppy_selects[0][1] ^= floppy_selects[0][0]; + floppy_selects[0][0] ^= floppy_selects[0][1]; +} + +#define EXTRA_FLOPPY_PARAMS ,{ "driveswap", &driveswap, NULL, 0, 0 } + +#endif diff --git a/include/asm-arm/fpstate.h b/arch/arm/include/asm/fpstate.h similarity index 97% rename from include/asm-arm/fpstate.h rename to arch/arm/include/asm/fpstate.h index 392eb53323238..ee5e03efc1bbe 100644 --- a/include/asm-arm/fpstate.h +++ b/arch/arm/include/asm/fpstate.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/fpstate.h + * arch/arm/include/asm/fpstate.h * * Copyright (C) 1995 Russell King * diff --git a/include/asm-arm/ftrace.h b/arch/arm/include/asm/ftrace.h similarity index 100% rename from include/asm-arm/ftrace.h rename to arch/arm/include/asm/ftrace.h diff --git a/include/asm-arm/futex.h b/arch/arm/include/asm/futex.h similarity index 100% rename from include/asm-arm/futex.h rename to arch/arm/include/asm/futex.h diff --git a/include/asm-arm/glue.h b/arch/arm/include/asm/glue.h similarity index 99% rename from include/asm-arm/glue.h rename to arch/arm/include/asm/glue.h index a97a182ba2873..a0e39d5d00c93 100644 --- a/include/asm-arm/glue.h +++ b/arch/arm/include/asm/glue.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/glue.h + * arch/arm/include/asm/glue.h * * Copyright (C) 1997-1999 Russell King * Copyright (C) 2000-2002 Deep Blue Solutions Ltd. diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h new file mode 100644 index 0000000000000..166a7a3e28400 --- /dev/null +++ b/arch/arm/include/asm/gpio.h @@ -0,0 +1,7 @@ +#ifndef _ARCH_ARM_GPIO_H +#define _ARCH_ARM_GPIO_H + +/* not all ARM platforms necessarily support this API ... */ +#include + +#endif /* _ARCH_ARM_GPIO_H */ diff --git a/include/asm-arm/hardirq.h b/arch/arm/include/asm/hardirq.h similarity index 100% rename from include/asm-arm/hardirq.h rename to arch/arm/include/asm/hardirq.h diff --git a/include/asm-arm/hardware/arm_timer.h b/arch/arm/include/asm/hardware/arm_timer.h similarity index 100% rename from include/asm-arm/hardware/arm_timer.h rename to arch/arm/include/asm/hardware/arm_timer.h diff --git a/include/asm-arm/hardware/arm_twd.h b/arch/arm/include/asm/hardware/arm_twd.h similarity index 100% rename from include/asm-arm/hardware/arm_twd.h rename to arch/arm/include/asm/hardware/arm_twd.h diff --git a/include/asm-arm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h similarity index 97% rename from include/asm-arm/hardware/cache-l2x0.h rename to arch/arm/include/asm/hardware/cache-l2x0.h index 54029a740396d..64f2252a25cdc 100644 --- a/include/asm-arm/hardware/cache-l2x0.h +++ b/arch/arm/include/asm/hardware/cache-l2x0.h @@ -1,5 +1,5 @@ /* - * include/asm-arm/hardware/cache-l2x0.h + * arch/arm/include/asm/hardware/cache-l2x0.h * * Copyright (C) 2007 ARM Limited * diff --git a/include/asm-arm/hardware/clps7111.h b/arch/arm/include/asm/hardware/clps7111.h similarity index 99% rename from include/asm-arm/hardware/clps7111.h rename to arch/arm/include/asm/hardware/clps7111.h index 8d3228dc17784..44477225aed60 100644 --- a/include/asm-arm/hardware/clps7111.h +++ b/arch/arm/include/asm/hardware/clps7111.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/clps7111.h + * arch/arm/include/asm/hardware/clps7111.h * * This file contains the hardware definitions of the CLPS7111 internal * registers. diff --git a/include/asm-arm/hardware/cs89712.h b/arch/arm/include/asm/hardware/cs89712.h similarity index 97% rename from include/asm-arm/hardware/cs89712.h rename to arch/arm/include/asm/hardware/cs89712.h index ad99a3e1b8029..f75626933e94d 100644 --- a/include/asm-arm/hardware/cs89712.h +++ b/arch/arm/include/asm/hardware/cs89712.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/cs89712.h + * arch/arm/include/asm/hardware/cs89712.h * * This file contains the hardware definitions of the CS89712 * additional internal registers. diff --git a/include/asm-arm/hardware/debug-8250.S b/arch/arm/include/asm/hardware/debug-8250.S similarity index 93% rename from include/asm-arm/hardware/debug-8250.S rename to arch/arm/include/asm/hardware/debug-8250.S index 07c97fb233fcd..22c689255e6e8 100644 --- a/include/asm-arm/hardware/debug-8250.S +++ b/arch/arm/include/asm/hardware/debug-8250.S @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/debug-8250.S + * arch/arm/include/asm/hardware/debug-8250.S * * Copyright (C) 1994-1999 Russell King * diff --git a/include/asm-arm/hardware/debug-pl01x.S b/arch/arm/include/asm/hardware/debug-pl01x.S similarity index 93% rename from include/asm-arm/hardware/debug-pl01x.S rename to arch/arm/include/asm/hardware/debug-pl01x.S index 23c541a9e89ab..f9fd083eff630 100644 --- a/include/asm-arm/hardware/debug-pl01x.S +++ b/arch/arm/include/asm/hardware/debug-pl01x.S @@ -1,4 +1,4 @@ -/* linux/include/asm-arm/hardware/debug-pl01x.S +/* arch/arm/include/asm/hardware/debug-pl01x.S * * Debugging macro include header * diff --git a/include/asm-arm/hardware/dec21285.h b/arch/arm/include/asm/hardware/dec21285.h similarity index 98% rename from include/asm-arm/hardware/dec21285.h rename to arch/arm/include/asm/hardware/dec21285.h index 546f7077be9c4..0d7552751aafc 100644 --- a/include/asm-arm/hardware/dec21285.h +++ b/arch/arm/include/asm/hardware/dec21285.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/dec21285.h + * arch/arm/include/asm/hardware/dec21285.h * * Copyright (C) 1998 Russell King * @@ -19,7 +19,7 @@ #define DC21285_PCI_MEM 0x80000000 #ifndef __ASSEMBLY__ -#include +#include #define DC21285_IO(x) ((volatile unsigned long *)(ARMCSR_BASE+(x))) #else #define DC21285_IO(x) (x) diff --git a/include/asm-arm/hardware/entry-macro-iomd.S b/arch/arm/include/asm/hardware/entry-macro-iomd.S similarity index 99% rename from include/asm-arm/hardware/entry-macro-iomd.S rename to arch/arm/include/asm/hardware/entry-macro-iomd.S index 9bb580a5b15ed..e0af4983723fb 100644 --- a/include/asm-arm/hardware/entry-macro-iomd.S +++ b/arch/arm/include/asm/hardware/entry-macro-iomd.S @@ -1,5 +1,5 @@ /* - * include/asm-arm/hardware/entry-macro-iomd.S + * arch/arm/include/asm/hardware/entry-macro-iomd.S * * Low-level IRQ helper macros for IOC/IOMD based platforms * diff --git a/include/asm-arm/hardware/ep7211.h b/arch/arm/include/asm/hardware/ep7211.h similarity index 96% rename from include/asm-arm/hardware/ep7211.h rename to arch/arm/include/asm/hardware/ep7211.h index 017aa68f612db..654d5f625c49c 100644 --- a/include/asm-arm/hardware/ep7211.h +++ b/arch/arm/include/asm/hardware/ep7211.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/ep7211.h + * arch/arm/include/asm/hardware/ep7211.h * * This file contains the hardware definitions of the EP7211 internal * registers. diff --git a/include/asm-arm/hardware/ep7212.h b/arch/arm/include/asm/hardware/ep7212.h similarity index 98% rename from include/asm-arm/hardware/ep7212.h rename to arch/arm/include/asm/hardware/ep7212.h index 0e952e7470730..3b43bbeaf1db4 100644 --- a/include/asm-arm/hardware/ep7212.h +++ b/arch/arm/include/asm/hardware/ep7212.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/ep7212.h + * arch/arm/include/asm/hardware/ep7212.h * * This file contains the hardware definitions of the EP7212 internal * registers. diff --git a/include/asm-arm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h similarity index 96% rename from include/asm-arm/hardware/gic.h rename to arch/arm/include/asm/hardware/gic.h index 966e428ad32c8..4924914af1882 100644 --- a/include/asm-arm/hardware/gic.h +++ b/arch/arm/include/asm/hardware/gic.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/gic.h + * arch/arm/include/asm/hardware/gic.h * * Copyright (C) 2002 ARM Limited, All Rights Reserved. * diff --git a/include/asm-arm/hardware/icst307.h b/arch/arm/include/asm/hardware/icst307.h similarity index 96% rename from include/asm-arm/hardware/icst307.h rename to arch/arm/include/asm/hardware/icst307.h index ff8618a441c0c..554f128a10464 100644 --- a/include/asm-arm/hardware/icst307.h +++ b/arch/arm/include/asm/hardware/icst307.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/icst307.h + * arch/arm/include/asm/hardware/icst307.h * * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. * diff --git a/include/asm-arm/hardware/icst525.h b/arch/arm/include/asm/hardware/icst525.h similarity index 96% rename from include/asm-arm/hardware/icst525.h rename to arch/arm/include/asm/hardware/icst525.h index edd5a5704406c..58f0dc43e2edb 100644 --- a/include/asm-arm/hardware/icst525.h +++ b/arch/arm/include/asm/hardware/icst525.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/icst525.h + * arch/arm/include/asm/hardware/icst525.h * * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. * diff --git a/include/asm-arm/hardware/ioc.h b/arch/arm/include/asm/hardware/ioc.h similarity index 97% rename from include/asm-arm/hardware/ioc.h rename to arch/arm/include/asm/hardware/ioc.h index b3b46ef659432..1f6b8013becb4 100644 --- a/include/asm-arm/hardware/ioc.h +++ b/arch/arm/include/asm/hardware/ioc.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/ioc.h + * arch/arm/include/asm/hardware/ioc.h * * Copyright (C) Russell King * diff --git a/include/asm-arm/hardware/iomd.h b/arch/arm/include/asm/hardware/iomd.h similarity index 99% rename from include/asm-arm/hardware/iomd.h rename to arch/arm/include/asm/hardware/iomd.h index 396e55ad06c6a..9c5afbd71a69a 100644 --- a/include/asm-arm/hardware/iomd.h +++ b/arch/arm/include/asm/hardware/iomd.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/iomd.h + * arch/arm/include/asm/hardware/iomd.h * * Copyright (C) 1999 Russell King * diff --git a/include/asm-arm/hardware/iop3xx-adma.h b/arch/arm/include/asm/hardware/iop3xx-adma.h similarity index 99% rename from include/asm-arm/hardware/iop3xx-adma.h rename to arch/arm/include/asm/hardware/iop3xx-adma.h index af64676650a22..87bff09633aac 100644 --- a/include/asm-arm/hardware/iop3xx-adma.h +++ b/arch/arm/include/asm/hardware/iop3xx-adma.h @@ -19,7 +19,7 @@ #define _ADMA_H #include #include -#include +#include #include /* Memory copy units */ diff --git a/include/asm-arm/hardware/iop3xx-gpio.h b/arch/arm/include/asm/hardware/iop3xx-gpio.h similarity index 95% rename from include/asm-arm/hardware/iop3xx-gpio.h rename to arch/arm/include/asm/hardware/iop3xx-gpio.h index 0c9331f9ac246..b69d972b1f7d2 100644 --- a/include/asm-arm/hardware/iop3xx-gpio.h +++ b/arch/arm/include/asm/hardware/iop3xx-gpio.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/iop3xx-gpio.h + * arch/arm/include/asm/hardware/iop3xx-gpio.h * * IOP3xx GPIO wrappers * @@ -25,7 +25,7 @@ #ifndef __ASM_ARM_HARDWARE_IOP3XX_GPIO_H #define __ASM_ARM_HARDWARE_IOP3XX_GPIO_H -#include +#include #include #define IOP3XX_N_GPIOS 8 diff --git a/include/asm-arm/hardware/iop3xx.h b/arch/arm/include/asm/hardware/iop3xx.h similarity index 99% rename from include/asm-arm/hardware/iop3xx.h rename to arch/arm/include/asm/hardware/iop3xx.h index 18f6937f50103..4b8e7f5599299 100644 --- a/include/asm-arm/hardware/iop3xx.h +++ b/arch/arm/include/asm/hardware/iop3xx.h @@ -1,5 +1,5 @@ /* - * include/asm-arm/hardware/iop3xx.h + * arch/arm/include/asm/hardware/iop3xx.h * * Intel IOP32X and IOP33X register definitions * diff --git a/include/asm-arm/hardware/iop_adma.h b/arch/arm/include/asm/hardware/iop_adma.h similarity index 100% rename from include/asm-arm/hardware/iop_adma.h rename to arch/arm/include/asm/hardware/iop_adma.h diff --git a/include/asm-arm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h similarity index 100% rename from include/asm-arm/hardware/it8152.h rename to arch/arm/include/asm/hardware/it8152.h diff --git a/include/asm-arm/hardware/linkup-l1110.h b/arch/arm/include/asm/hardware/linkup-l1110.h similarity index 100% rename from include/asm-arm/hardware/linkup-l1110.h rename to arch/arm/include/asm/hardware/linkup-l1110.h diff --git a/include/asm-arm/hardware/locomo.h b/arch/arm/include/asm/hardware/locomo.h similarity index 99% rename from include/asm-arm/hardware/locomo.h rename to arch/arm/include/asm/hardware/locomo.h index fb0645de6f315..954b1be991b4a 100644 --- a/include/asm-arm/hardware/locomo.h +++ b/arch/arm/include/asm/hardware/locomo.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/locomo.h + * arch/arm/include/asm/hardware/locomo.h * * This file contains the definitions for the LoCoMo G/A Chip * diff --git a/include/asm-arm/hardware/memc.h b/arch/arm/include/asm/hardware/memc.h similarity index 93% rename from include/asm-arm/hardware/memc.h rename to arch/arm/include/asm/hardware/memc.h index 8aef5aa0e01bd..42ba7c167d1fb 100644 --- a/include/asm-arm/hardware/memc.h +++ b/arch/arm/include/asm/hardware/memc.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/memc.h + * arch/arm/include/asm/hardware/memc.h * * Copyright (C) Russell King. * diff --git a/include/asm-arm/hardware/pci_v3.h b/arch/arm/include/asm/hardware/pci_v3.h similarity index 99% rename from include/asm-arm/hardware/pci_v3.h rename to arch/arm/include/asm/hardware/pci_v3.h index 4d497bdb9a979..2811c7e2cfdf1 100644 --- a/include/asm-arm/hardware/pci_v3.h +++ b/arch/arm/include/asm/hardware/pci_v3.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/pci_v3.h + * arch/arm/include/asm/hardware/pci_v3.h * * Internal header file PCI V3 chip * diff --git a/include/asm-arm/hardware/sa1111.h b/arch/arm/include/asm/hardware/sa1111.h similarity index 99% rename from include/asm-arm/hardware/sa1111.h rename to arch/arm/include/asm/hardware/sa1111.h index 61b1d05c7df74..5da2595759e52 100644 --- a/include/asm-arm/hardware/sa1111.h +++ b/arch/arm/include/asm/hardware/sa1111.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/sa1111.h + * arch/arm/include/asm/hardware/sa1111.h * * Copyright (C) 2000 John G Dorsey * @@ -12,7 +12,7 @@ #ifndef _ASM_ARCH_SA1111 #define _ASM_ARCH_SA1111 -#include +#include /* * The SA1111 is always located at virtual 0xf4000000, and is always diff --git a/include/asm-arm/hardware/scoop.h b/arch/arm/include/asm/hardware/scoop.h similarity index 100% rename from include/asm-arm/hardware/scoop.h rename to arch/arm/include/asm/hardware/scoop.h diff --git a/include/asm-arm/hardware/sharpsl_pm.h b/arch/arm/include/asm/hardware/sharpsl_pm.h similarity index 100% rename from include/asm-arm/hardware/sharpsl_pm.h rename to arch/arm/include/asm/hardware/sharpsl_pm.h diff --git a/include/asm-arm/hardware/ssp.h b/arch/arm/include/asm/hardware/ssp.h similarity index 100% rename from include/asm-arm/hardware/ssp.h rename to arch/arm/include/asm/hardware/ssp.h diff --git a/include/asm-arm/hardware/uengine.h b/arch/arm/include/asm/hardware/uengine.h similarity index 100% rename from include/asm-arm/hardware/uengine.h rename to arch/arm/include/asm/hardware/uengine.h diff --git a/include/asm-arm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h similarity index 97% rename from include/asm-arm/hardware/vic.h rename to arch/arm/include/asm/hardware/vic.h index ed9ca3736a0be..263f2c362a306 100644 --- a/include/asm-arm/hardware/vic.h +++ b/arch/arm/include/asm/hardware/vic.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/hardware/vic.h + * arch/arm/include/asm/hardware/vic.h * * Copyright (c) ARM Limited 2003. All rights reserved. * diff --git a/arch/arm/include/asm/hw_irq.h b/arch/arm/include/asm/hw_irq.h new file mode 100644 index 0000000000000..90831f6f5f5cb --- /dev/null +++ b/arch/arm/include/asm/hw_irq.h @@ -0,0 +1,27 @@ +/* + * Nothing to see here yet + */ +#ifndef _ARCH_ARM_HW_IRQ_H +#define _ARCH_ARM_HW_IRQ_H + +static inline void ack_bad_irq(int irq) +{ + extern unsigned long irq_err_count; + irq_err_count++; +} + +/* + * Obsolete inline function for calling irq descriptor handlers. + */ +static inline void desc_handle_irq(unsigned int irq, struct irq_desc *desc) +{ + desc->handle_irq(irq, desc); +} + +void set_irq_flags(unsigned int irq, unsigned int flags); + +#define IRQF_VALID (1 << 0) +#define IRQF_PROBE (1 << 1) +#define IRQF_NOAUTOEN (1 << 2) + +#endif diff --git a/include/asm-arm/hwcap.h b/arch/arm/include/asm/hwcap.h similarity index 100% rename from include/asm-arm/hwcap.h rename to arch/arm/include/asm/hwcap.h diff --git a/arch/arm/include/asm/ide.h b/arch/arm/include/asm/ide.h new file mode 100644 index 0000000000000..b507ce8e5019a --- /dev/null +++ b/arch/arm/include/asm/ide.h @@ -0,0 +1,23 @@ +/* + * arch/arm/include/asm/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + */ + +/* + * This file contains the ARM architecture specific IDE code. + */ + +#ifndef __ASMARM_IDE_H +#define __ASMARM_IDE_H + +#ifdef __KERNEL__ + +#define __ide_mm_insw(port,addr,len) readsw(port,addr,len) +#define __ide_mm_insl(port,addr,len) readsl(port,addr,len) +#define __ide_mm_outsw(port,addr,len) writesw(port,addr,len) +#define __ide_mm_outsl(port,addr,len) writesl(port,addr,len) + +#endif /* __KERNEL__ */ + +#endif /* __ASMARM_IDE_H */ diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h new file mode 100644 index 0000000000000..94a95d7fafd6c --- /dev/null +++ b/arch/arm/include/asm/io.h @@ -0,0 +1,287 @@ +/* + * arch/arm/include/asm/io.h + * + * Copyright (C) 1996-2000 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. + * + * Modifications: + * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both + * constant addresses and variable addresses. + * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture + * specific IO header files. + * 27-Mar-1999 PJB Second parameter of memcpy_toio is const.. + * 04-Apr-1999 PJB Added check_signature. + * 12-Dec-1999 RMK More cleanups + * 18-Jun-2000 RMK Removed virt_to_* and friends definitions + * 05-Oct-2004 BJD Moved memory string functions to use void __iomem + */ +#ifndef __ASM_ARM_IO_H +#define __ASM_ARM_IO_H + +#ifdef __KERNEL__ + +#include +#include +#include + +/* + * ISA I/O bus memory addresses are 1:1 with the physical address. + */ +#define isa_virt_to_bus virt_to_phys +#define isa_page_to_bus page_to_phys +#define isa_bus_to_virt phys_to_virt + +/* + * Generic IO read/write. These perform native-endian accesses. Note + * that some architectures will want to re-define __raw_{read,write}w. + */ +extern void __raw_writesb(void __iomem *addr, const void *data, int bytelen); +extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen); +extern void __raw_writesl(void __iomem *addr, const void *data, int longlen); + +extern void __raw_readsb(const void __iomem *addr, void *data, int bytelen); +extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen); +extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); + +#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v)) +#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)) +#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v)) + +#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a)) +#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a)) +#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a)) + +/* + * Architecture ioremap implementation. + */ +#define MT_DEVICE 0 +#define MT_DEVICE_NONSHARED 1 +#define MT_DEVICE_CACHED 2 +#define MT_DEVICE_IXP2000 3 +/* + * types 4 onwards can be found in asm/mach/map.h and are undefined + * for ioremap + */ + +/* + * __arm_ioremap takes CPU physical address. + * __arm_ioremap_pfn takes a Page Frame Number and an offset into that page + */ +extern void __iomem * __arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int); +extern void __iomem * __arm_ioremap(unsigned long, size_t, unsigned int); +extern void __iounmap(volatile void __iomem *addr); + +/* + * Bad read/write accesses... + */ +extern void __readwrite_bug(const char *fn); + +/* + * Now, pick up the machine-defined IO definitions + */ +#include + +/* + * IO port access primitives + * ------------------------- + * + * The ARM doesn't have special IO access instructions; all IO is memory + * mapped. Note that these are defined to perform little endian accesses + * only. Their primary purpose is to access PCI and ISA peripherals. + * + * Note that for a big endian machine, this implies that the following + * big endian mode connectivity is in place, as described by numerous + * ARM documents: + * + * PCI: D0-D7 D8-D15 D16-D23 D24-D31 + * ARM: D24-D31 D16-D23 D8-D15 D0-D7 + * + * The machine specific io.h include defines __io to translate an "IO" + * address to a memory address. + * + * Note that we prevent GCC re-ordering or caching values in expressions + * by introducing sequence points into the in*() definitions. Note that + * __raw_* do not guarantee this behaviour. + * + * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space. + */ +#ifdef __io +#define outb(v,p) __raw_writeb(v,__io(p)) +#define outw(v,p) __raw_writew((__force __u16) \ + cpu_to_le16(v),__io(p)) +#define outl(v,p) __raw_writel((__force __u32) \ + cpu_to_le32(v),__io(p)) + +#define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __v; }) +#define inw(p) ({ __u16 __v = le16_to_cpu((__force __le16) \ + __raw_readw(__io(p))); __v; }) +#define inl(p) ({ __u32 __v = le32_to_cpu((__force __le32) \ + __raw_readl(__io(p))); __v; }) + +#define outsb(p,d,l) __raw_writesb(__io(p),d,l) +#define outsw(p,d,l) __raw_writesw(__io(p),d,l) +#define outsl(p,d,l) __raw_writesl(__io(p),d,l) + +#define insb(p,d,l) __raw_readsb(__io(p),d,l) +#define insw(p,d,l) __raw_readsw(__io(p),d,l) +#define insl(p,d,l) __raw_readsl(__io(p),d,l) +#endif + +#define outb_p(val,port) outb((val),(port)) +#define outw_p(val,port) outw((val),(port)) +#define outl_p(val,port) outl((val),(port)) +#define inb_p(port) inb((port)) +#define inw_p(port) inw((port)) +#define inl_p(port) inl((port)) + +#define outsb_p(port,from,len) outsb(port,from,len) +#define outsw_p(port,from,len) outsw(port,from,len) +#define outsl_p(port,from,len) outsl(port,from,len) +#define insb_p(port,to,len) insb(port,to,len) +#define insw_p(port,to,len) insw(port,to,len) +#define insl_p(port,to,len) insl(port,to,len) + +/* + * String version of IO memory access ops: + */ +extern void _memcpy_fromio(void *, const volatile void __iomem *, size_t); +extern void _memcpy_toio(volatile void __iomem *, const void *, size_t); +extern void _memset_io(volatile void __iomem *, int, size_t); + +#define mmiowb() + +/* + * Memory access primitives + * ------------------------ + * + * These perform PCI memory accesses via an ioremap region. They don't + * take an address as such, but a cookie. + * + * Again, this are defined to perform little endian accesses. See the + * IO port primitives for more information. + */ +#ifdef __mem_pci +#define readb(c) ({ __u8 __v = __raw_readb(__mem_pci(c)); __v; }) +#define readw(c) ({ __u16 __v = le16_to_cpu((__force __le16) \ + __raw_readw(__mem_pci(c))); __v; }) +#define readl(c) ({ __u32 __v = le32_to_cpu((__force __le32) \ + __raw_readl(__mem_pci(c))); __v; }) +#define readb_relaxed(addr) readb(addr) +#define readw_relaxed(addr) readw(addr) +#define readl_relaxed(addr) readl(addr) + +#define readsb(p,d,l) __raw_readsb(__mem_pci(p),d,l) +#define readsw(p,d,l) __raw_readsw(__mem_pci(p),d,l) +#define readsl(p,d,l) __raw_readsl(__mem_pci(p),d,l) + +#define writeb(v,c) __raw_writeb(v,__mem_pci(c)) +#define writew(v,c) __raw_writew((__force __u16) \ + cpu_to_le16(v),__mem_pci(c)) +#define writel(v,c) __raw_writel((__force __u32) \ + cpu_to_le32(v),__mem_pci(c)) + +#define writesb(p,d,l) __raw_writesb(__mem_pci(p),d,l) +#define writesw(p,d,l) __raw_writesw(__mem_pci(p),d,l) +#define writesl(p,d,l) __raw_writesl(__mem_pci(p),d,l) + +#define memset_io(c,v,l) _memset_io(__mem_pci(c),(v),(l)) +#define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l)) +#define memcpy_toio(c,a,l) _memcpy_toio(__mem_pci(c),(a),(l)) + +#elif !defined(readb) + +#define readb(c) (__readwrite_bug("readb"),0) +#define readw(c) (__readwrite_bug("readw"),0) +#define readl(c) (__readwrite_bug("readl"),0) +#define writeb(v,c) __readwrite_bug("writeb") +#define writew(v,c) __readwrite_bug("writew") +#define writel(v,c) __readwrite_bug("writel") + +#define check_signature(io,sig,len) (0) + +#endif /* __mem_pci */ + +/* + * ioremap and friends. + * + * ioremap takes a PCI memory address, as specified in + * Documentation/IO-mapping.txt. + * + */ +#ifndef __arch_ioremap +#define ioremap(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE) +#define ioremap_nocache(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE) +#define ioremap_cached(cookie,size) __arm_ioremap(cookie, size, MT_DEVICE_CACHED) +#define iounmap(cookie) __iounmap(cookie) +#else +#define ioremap(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE) +#define ioremap_nocache(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE) +#define ioremap_cached(cookie,size) __arch_ioremap((cookie), (size), MT_DEVICE_CACHED) +#define iounmap(cookie) __arch_iounmap(cookie) +#endif + +/* + * io{read,write}{8,16,32} macros + */ +#ifndef ioread8 +#define ioread8(p) ({ unsigned int __v = __raw_readb(p); __v; }) +#define ioread16(p) ({ unsigned int __v = le16_to_cpu((__force __le16)__raw_readw(p)); __v; }) +#define ioread32(p) ({ unsigned int __v = le32_to_cpu((__force __le32)__raw_readl(p)); __v; }) + +#define iowrite8(v,p) __raw_writeb(v, p) +#define iowrite16(v,p) __raw_writew((__force __u16)cpu_to_le16(v), p) +#define iowrite32(v,p) __raw_writel((__force __u32)cpu_to_le32(v), p) + +#define ioread8_rep(p,d,c) __raw_readsb(p,d,c) +#define ioread16_rep(p,d,c) __raw_readsw(p,d,c) +#define ioread32_rep(p,d,c) __raw_readsl(p,d,c) + +#define iowrite8_rep(p,s,c) __raw_writesb(p,s,c) +#define iowrite16_rep(p,s,c) __raw_writesw(p,s,c) +#define iowrite32_rep(p,s,c) __raw_writesl(p,s,c) + +extern void __iomem *ioport_map(unsigned long port, unsigned int nr); +extern void ioport_unmap(void __iomem *addr); +#endif + +struct pci_dev; + +extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen); +extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr); + +/* + * can the hardware map this into one segment or not, given no other + * constraints. + */ +#define BIOVEC_MERGEABLE(vec1, vec2) \ + ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) + +#ifdef CONFIG_MMU +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE +extern int valid_phys_addr_range(unsigned long addr, size_t size); +extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size); +#endif + +/* + * Convert a physical pointer to a virtual kernel pointer for /dev/mem + * access + */ +#define xlate_dev_mem_ptr(p) __va(p) + +/* + * Convert a virtual cached pointer to an uncached pointer + */ +#define xlate_dev_kmem_ptr(p) p + +/* + * Register ISA memory and port locations for glibc iopl/inb/outb + * emulation. + */ +extern void register_isa_ports(unsigned int mmio, unsigned int io, + unsigned int io_shift); + +#endif /* __KERNEL__ */ +#endif /* __ASM_ARM_IO_H */ diff --git a/include/asm-arm/ioctl.h b/arch/arm/include/asm/ioctl.h similarity index 100% rename from include/asm-arm/ioctl.h rename to arch/arm/include/asm/ioctl.h diff --git a/include/asm-arm/ioctls.h b/arch/arm/include/asm/ioctls.h similarity index 100% rename from include/asm-arm/ioctls.h rename to arch/arm/include/asm/ioctls.h diff --git a/include/asm-arm/ipcbuf.h b/arch/arm/include/asm/ipcbuf.h similarity index 100% rename from include/asm-arm/ipcbuf.h rename to arch/arm/include/asm/ipcbuf.h diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h new file mode 100644 index 0000000000000..d6786090d02ca --- /dev/null +++ b/arch/arm/include/asm/irq.h @@ -0,0 +1,28 @@ +#ifndef __ASM_ARM_IRQ_H +#define __ASM_ARM_IRQ_H + +#include + +#ifndef irq_canonicalize +#define irq_canonicalize(i) (i) +#endif + +#ifndef NR_IRQS +#define NR_IRQS 128 +#endif + +/* + * Use this value to indicate lack of interrupt + * capability + */ +#ifndef NO_IRQ +#define NO_IRQ ((unsigned int)(-1)) +#endif + +#ifndef __ASSEMBLY__ +struct irqaction; +extern void migrate_irqs(void); +#endif + +#endif + diff --git a/include/asm-arm/irq_regs.h b/arch/arm/include/asm/irq_regs.h similarity index 100% rename from include/asm-arm/irq_regs.h rename to arch/arm/include/asm/irq_regs.h diff --git a/include/asm-arm/irqflags.h b/arch/arm/include/asm/irqflags.h similarity index 100% rename from include/asm-arm/irqflags.h rename to arch/arm/include/asm/irqflags.h diff --git a/include/asm-arm/kdebug.h b/arch/arm/include/asm/kdebug.h similarity index 100% rename from include/asm-arm/kdebug.h rename to arch/arm/include/asm/kdebug.h diff --git a/include/asm-arm/kexec.h b/arch/arm/include/asm/kexec.h similarity index 100% rename from include/asm-arm/kexec.h rename to arch/arm/include/asm/kexec.h diff --git a/include/asm-arm/kgdb.h b/arch/arm/include/asm/kgdb.h similarity index 100% rename from include/asm-arm/kgdb.h rename to arch/arm/include/asm/kgdb.h diff --git a/include/asm-arm/kmap_types.h b/arch/arm/include/asm/kmap_types.h similarity index 100% rename from include/asm-arm/kmap_types.h rename to arch/arm/include/asm/kmap_types.h diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h new file mode 100644 index 0000000000000..a5d0d99ad3870 --- /dev/null +++ b/arch/arm/include/asm/kprobes.h @@ -0,0 +1,79 @@ +/* + * arch/arm/include/asm/kprobes.h + * + * Copyright (C) 2006, 2007 Motorola Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ + +#ifndef _ARM_KPROBES_H +#define _ARM_KPROBES_H + +#include +#include +#include + +#define __ARCH_WANT_KPROBES_INSN_SLOT +#define MAX_INSN_SIZE 2 +#define MAX_STACK_SIZE 64 /* 32 would probably be OK */ + +/* + * This undefined instruction must be unique and + * reserved solely for kprobes' use. + */ +#define KPROBE_BREAKPOINT_INSTRUCTION 0xe7f001f8 + +#define regs_return_value(regs) ((regs)->ARM_r0) +#define flush_insn_slot(p) do { } while (0) +#define kretprobe_blacklist_size 0 + +typedef u32 kprobe_opcode_t; + +struct kprobe; +typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *); + +/* Architecture specific copy of original instruction. */ +struct arch_specific_insn { + kprobe_opcode_t *insn; + kprobe_insn_handler_t *insn_handler; +}; + +struct prev_kprobe { + struct kprobe *kp; + unsigned int status; +}; + +/* per-cpu kprobe control block */ +struct kprobe_ctlblk { + unsigned int kprobe_status; + struct prev_kprobe prev_kprobe; + struct pt_regs jprobe_saved_regs; + char jprobes_stack[MAX_STACK_SIZE]; +}; + +void arch_remove_kprobe(struct kprobe *); +void kretprobe_trampoline(void); + +int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr); +int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr); +int kprobe_exceptions_notify(struct notifier_block *self, + unsigned long val, void *data); + +enum kprobe_insn { + INSN_REJECTED, + INSN_GOOD, + INSN_GOOD_NO_SLOT +}; + +enum kprobe_insn arm_kprobe_decode_insn(kprobe_opcode_t, + struct arch_specific_insn *); +void __init arm_kprobe_decode_init(void); + +#endif /* _ARM_KPROBES_H */ diff --git a/include/asm-arm/leds.h b/arch/arm/include/asm/leds.h similarity index 96% rename from include/asm-arm/leds.h rename to arch/arm/include/asm/leds.h index 12290ea55801c..c545739f39b7e 100644 --- a/include/asm-arm/leds.h +++ b/arch/arm/include/asm/leds.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/leds.h + * arch/arm/include/asm/leds.h * * Copyright (C) 1998 Russell King * diff --git a/include/asm-arm/limits.h b/arch/arm/include/asm/limits.h similarity index 100% rename from include/asm-arm/limits.h rename to arch/arm/include/asm/limits.h diff --git a/include/asm-arm/linkage.h b/arch/arm/include/asm/linkage.h similarity index 100% rename from include/asm-arm/linkage.h rename to arch/arm/include/asm/linkage.h diff --git a/include/asm-arm/local.h b/arch/arm/include/asm/local.h similarity index 100% rename from include/asm-arm/local.h rename to arch/arm/include/asm/local.h diff --git a/include/asm-arm/locks.h b/arch/arm/include/asm/locks.h similarity index 99% rename from include/asm-arm/locks.h rename to arch/arm/include/asm/locks.h index 852220eecdbc5..ef4c897772d14 100644 --- a/include/asm-arm/locks.h +++ b/arch/arm/include/asm/locks.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/locks.h + * arch/arm/include/asm/locks.h * * Copyright (C) 2000 Russell King * diff --git a/include/asm-arm/mach/arch.h b/arch/arm/include/asm/mach/arch.h similarity index 97% rename from include/asm-arm/mach/arch.h rename to arch/arm/include/asm/mach/arch.h index bcc8aed7c9a9a..c59842dc7cb8d 100644 --- a/include/asm-arm/mach/arch.h +++ b/arch/arm/include/asm/mach/arch.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/mach/arch.h + * arch/arm/include/asm/mach/arch.h * * Copyright (C) 2000 Russell King * diff --git a/arch/arm/include/asm/mach/dma.h b/arch/arm/include/asm/mach/dma.h new file mode 100644 index 0000000000000..fc7278ea71467 --- /dev/null +++ b/arch/arm/include/asm/mach/dma.h @@ -0,0 +1,57 @@ +/* + * arch/arm/include/asm/mach/dma.h + * + * Copyright (C) 1998-2000 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. + * + * This header file describes the interface between the generic DMA handler + * (dma.c) and the architecture-specific DMA backends (dma-*.c) + */ + +struct dma_struct; +typedef struct dma_struct dma_t; + +struct dma_ops { + int (*request)(dmach_t, dma_t *); /* optional */ + void (*free)(dmach_t, dma_t *); /* optional */ + void (*enable)(dmach_t, dma_t *); /* mandatory */ + void (*disable)(dmach_t, dma_t *); /* mandatory */ + int (*residue)(dmach_t, dma_t *); /* optional */ + int (*setspeed)(dmach_t, dma_t *, int); /* optional */ + char *type; +}; + +struct dma_struct { + void *addr; /* single DMA address */ + unsigned long count; /* single DMA size */ + struct scatterlist buf; /* single DMA */ + int sgcount; /* number of DMA SG */ + struct scatterlist *sg; /* DMA Scatter-Gather List */ + + unsigned int active:1; /* Transfer active */ + unsigned int invalid:1; /* Address/Count changed */ + + dmamode_t dma_mode; /* DMA mode */ + int speed; /* DMA speed */ + + unsigned int lock; /* Device is allocated */ + const char *device_id; /* Device name */ + + unsigned int dma_base; /* Controller base address */ + int dma_irq; /* Controller IRQ */ + struct scatterlist cur_sg; /* Current controller buffer */ + unsigned int state; + + struct dma_ops *d_ops; +}; + +/* Prototype: void arch_dma_init(dma) + * Purpose : Initialise architecture specific DMA + * Params : dma - pointer to array of DMA structures + */ +extern void arch_dma_init(dma_t *dma); + +extern void isa_init_dma(dma_t *dma); diff --git a/include/asm-arm/mach/flash.h b/arch/arm/include/asm/mach/flash.h similarity index 96% rename from include/asm-arm/mach/flash.h rename to arch/arm/include/asm/mach/flash.h index 05b029ef6371c..4ca69fe2c850c 100644 --- a/include/asm-arm/mach/flash.h +++ b/arch/arm/include/asm/mach/flash.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/mach/flash.h + * arch/arm/include/asm/mach/flash.h * * Copyright (C) 2003 Russell King, All Rights Reserved. * diff --git a/arch/arm/include/asm/mach/irda.h b/arch/arm/include/asm/mach/irda.h new file mode 100644 index 0000000000000..38f77b5e56cfc --- /dev/null +++ b/arch/arm/include/asm/mach/irda.h @@ -0,0 +1,20 @@ +/* + * arch/arm/include/asm/mach/irda.h + * + * Copyright (C) 2004 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. + */ +#ifndef __ASM_ARM_MACH_IRDA_H +#define __ASM_ARM_MACH_IRDA_H + +struct irda_platform_data { + int (*startup)(struct device *); + void (*shutdown)(struct device *); + int (*set_power)(struct device *, unsigned int state); + void (*set_speed)(struct device *, unsigned int speed); +}; + +#endif diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h new file mode 100644 index 0000000000000..acac5302e4eaf --- /dev/null +++ b/arch/arm/include/asm/mach/irq.h @@ -0,0 +1,34 @@ +/* + * arch/arm/include/asm/mach/irq.h + * + * Copyright (C) 1995-2000 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. + */ +#ifndef __ASM_ARM_MACH_IRQ_H +#define __ASM_ARM_MACH_IRQ_H + +#include + +struct seq_file; + +/* + * This is internal. Do not use it. + */ +extern void (*init_arch_irq)(void); +extern void init_FIQ(void); +extern int show_fiq_list(struct seq_file *, void *); + +/* + * This is for easy migration, but should be changed in the source + */ +#define do_bad_IRQ(irq,desc) \ +do { \ + spin_lock(&desc->lock); \ + handle_bad_irq(irq, desc); \ + spin_unlock(&desc->lock); \ +} while(0) + +#endif diff --git a/arch/arm/include/asm/mach/map.h b/arch/arm/include/asm/mach/map.h new file mode 100644 index 0000000000000..06f583b13999c --- /dev/null +++ b/arch/arm/include/asm/mach/map.h @@ -0,0 +1,36 @@ +/* + * arch/arm/include/asm/map.h + * + * Copyright (C) 1999-2000 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 mapping constructs and function prototypes + */ +#include + +struct map_desc { + unsigned long virtual; + unsigned long pfn; + unsigned long length; + unsigned int type; +}; + +/* types 0-3 are defined in asm/io.h */ +#define MT_CACHECLEAN 4 +#define MT_MINICLEAN 5 +#define MT_LOW_VECTORS 6 +#define MT_HIGH_VECTORS 7 +#define MT_MEMORY 8 +#define MT_ROM 9 + +#define MT_NONSHARED_DEVICE MT_DEVICE_NONSHARED +#define MT_IXP2000_DEVICE MT_DEVICE_IXP2000 + +#ifdef CONFIG_MMU +extern void iotable_init(struct map_desc *, int); +#else +#define iotable_init(map,num) do { } while (0) +#endif diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h new file mode 100644 index 0000000000000..4da332b03144c --- /dev/null +++ b/arch/arm/include/asm/mach/mmc.h @@ -0,0 +1,15 @@ +/* + * arch/arm/include/asm/mach/mmc.h + */ +#ifndef ASMARM_MACH_MMC_H +#define ASMARM_MACH_MMC_H + +#include + +struct mmc_platform_data { + unsigned int ocr_mask; /* available voltages */ + u32 (*translate_vdd)(struct device *, unsigned int); + unsigned int (*status)(struct device *); +}; + +#endif diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h new file mode 100644 index 0000000000000..32da1ae17e066 --- /dev/null +++ b/arch/arm/include/asm/mach/pci.h @@ -0,0 +1,72 @@ +/* + * arch/arm/include/asm/mach/pci.h + * + * Copyright (C) 2000 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. + */ + +struct pci_sys_data; +struct pci_bus; + +struct hw_pci { + struct list_head buses; + int nr_controllers; + int (*setup)(int nr, struct pci_sys_data *); + struct pci_bus *(*scan)(int nr, struct pci_sys_data *); + void (*preinit)(void); + void (*postinit)(void); + u8 (*swizzle)(struct pci_dev *dev, u8 *pin); + int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin); +}; + +/* + * Per-controller structure + */ +struct pci_sys_data { + struct list_head node; + int busnr; /* primary bus number */ + u64 mem_offset; /* bus->cpu memory mapping offset */ + unsigned long io_offset; /* bus->cpu IO mapping offset */ + struct pci_bus *bus; /* PCI bus */ + struct resource *resource[3]; /* Primary PCI bus resources */ + /* Bridge swizzling */ + u8 (*swizzle)(struct pci_dev *, u8 *); + /* IRQ mapping */ + int (*map_irq)(struct pci_dev *, u8, u8); + struct hw_pci *hw; +}; + +/* + * This is the standard PCI-PCI bridge swizzling algorithm. + */ +u8 pci_std_swizzle(struct pci_dev *dev, u8 *pinp); + +/* + * Call this with your hw_pci struct to initialise the PCI system. + */ +void pci_common_init(struct hw_pci *); + +/* + * PCI controllers + */ +extern int iop3xx_pci_setup(int nr, struct pci_sys_data *); +extern struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *); +extern void iop3xx_pci_preinit(void); +extern void iop3xx_pci_preinit_cond(void); + +extern int dc21285_setup(int nr, struct pci_sys_data *); +extern struct pci_bus *dc21285_scan_bus(int nr, struct pci_sys_data *); +extern void dc21285_preinit(void); +extern void dc21285_postinit(void); + +extern int via82c505_setup(int nr, struct pci_sys_data *); +extern struct pci_bus *via82c505_scan_bus(int nr, struct pci_sys_data *); +extern void via82c505_init(void *sysdata); + +extern int pci_v3_setup(int nr, struct pci_sys_data *); +extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *); +extern void pci_v3_preinit(void); +extern void pci_v3_postinit(void); diff --git a/include/asm-avr32/mach/serial_at91.h b/arch/arm/include/asm/mach/serial_at91.h similarity index 94% rename from include/asm-avr32/mach/serial_at91.h rename to arch/arm/include/asm/mach/serial_at91.h index 55b317a89061b..ea6d063923b8f 100644 --- a/include/asm-avr32/mach/serial_at91.h +++ b/arch/arm/include/asm/mach/serial_at91.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/mach/serial_at91.h + * arch/arm/include/asm/mach/serial_at91.h * * Based on serial_sa1100.h by Nicolas Pitre * diff --git a/include/asm-arm/mach/serial_sa1100.h b/arch/arm/include/asm/mach/serial_sa1100.h similarity index 86% rename from include/asm-arm/mach/serial_sa1100.h rename to arch/arm/include/asm/mach/serial_sa1100.h index 20c22bb218d92..d09064bf95a0d 100644 --- a/include/asm-arm/mach/serial_sa1100.h +++ b/arch/arm/include/asm/mach/serial_sa1100.h @@ -1,9 +1,9 @@ /* - * linux/include/asm-arm/mach/serial_sa1100.h + * arch/arm/include/asm/mach/serial_sa1100.h * * Author: Nicolas Pitre * - * Moved to include/asm-arm/mach and changed lots, Russell King + * Moved and changed lots, Russell King * * Low level machine dependent UART functions. */ diff --git a/include/asm-arm/mach/sharpsl_param.h b/arch/arm/include/asm/mach/sharpsl_param.h similarity index 100% rename from include/asm-arm/mach/sharpsl_param.h rename to arch/arm/include/asm/mach/sharpsl_param.h diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h new file mode 100644 index 0000000000000..b2cc1fcd04005 --- /dev/null +++ b/arch/arm/include/asm/mach/time.h @@ -0,0 +1,57 @@ +/* + * arch/arm/include/asm/mach/time.h + * + * Copyright (C) 2004 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_ARM_MACH_TIME_H +#define __ASM_ARM_MACH_TIME_H + +#include + +/* + * This is our kernel timer structure. + * + * - init + * Initialise the kernels jiffy timer source, claim interrupt + * using setup_irq. This is called early on during initialisation + * while interrupts are still disabled on the local CPU. + * - suspend + * Suspend the kernel jiffy timer source, if necessary. This + * is called with interrupts disabled, after all normal devices + * have been suspended. If no action is required, set this to + * NULL. + * - resume + * Resume the kernel jiffy timer source, if necessary. This + * is called with interrupts disabled before any normal devices + * are resumed. If no action is required, set this to NULL. + * - offset + * Return the timer offset in microseconds since the last timer + * interrupt. Note: this must take account of any unprocessed + * timer interrupt which may be pending. + */ +struct sys_timer { + struct sys_device dev; + void (*init)(void); + void (*suspend)(void); + void (*resume)(void); +#ifndef CONFIG_GENERIC_TIME + unsigned long (*offset)(void); +#endif +}; + +extern struct sys_timer *system_timer; +extern void timer_tick(void); + +/* + * Kernel time keeping support. + */ +struct timespec; +extern int (*set_rtc)(void); +extern void save_time_delta(struct timespec *delta, struct timespec *rtc); +extern void restore_time_delta(struct timespec *delta, struct timespec *rtc); + +#endif diff --git a/include/asm-arm/mach/udc_pxa2xx.h b/arch/arm/include/asm/mach/udc_pxa2xx.h similarity index 95% rename from include/asm-arm/mach/udc_pxa2xx.h rename to arch/arm/include/asm/mach/udc_pxa2xx.h index 9e5ed7c0f27fb..270902c353fde 100644 --- a/include/asm-arm/mach/udc_pxa2xx.h +++ b/arch/arm/include/asm/mach/udc_pxa2xx.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/mach/udc_pxa2xx.h + * arch/arm/include/asm/mach/udc_pxa2xx.h * * This supports machine-specific differences in how the PXA2xx * USB Device Controller (UDC) is wired. diff --git a/arch/arm/include/asm/mc146818rtc.h b/arch/arm/include/asm/mc146818rtc.h new file mode 100644 index 0000000000000..e1ca48a9e9734 --- /dev/null +++ b/arch/arm/include/asm/mc146818rtc.h @@ -0,0 +1,28 @@ +/* + * Machine dependent access functions for RTC registers. + */ +#ifndef _ASM_MC146818RTC_H +#define _ASM_MC146818RTC_H + +#include +#include + +#ifndef RTC_PORT +#define RTC_PORT(x) (0x70 + (x)) +#define RTC_ALWAYS_BCD 1 /* RTC operates in binary mode */ +#endif + +/* + * The yet supported machines all access the RTC index register via + * an ISA port access but the way to access the date register differs ... + */ +#define CMOS_READ(addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +inb_p(RTC_PORT(1)); \ +}) +#define CMOS_WRITE(val, addr) ({ \ +outb_p((addr),RTC_PORT(0)); \ +outb_p((val),RTC_PORT(1)); \ +}) + +#endif /* _ASM_MC146818RTC_H */ diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h new file mode 100644 index 0000000000000..1e070a2b561aa --- /dev/null +++ b/arch/arm/include/asm/memory.h @@ -0,0 +1,334 @@ +/* + * arch/arm/include/asm/memory.h + * + * Copyright (C) 2000-2002 Russell King + * modification for nommu, Hyok S. Choi, 2004 + * + * 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. + * + * Note: this file should not be included by non-asm/.h files + */ +#ifndef __ASM_ARM_MEMORY_H +#define __ASM_ARM_MEMORY_H + +/* + * Allow for constants defined here to be used from assembly code + * by prepending the UL suffix only with actual C code compilation. + */ +#ifndef __ASSEMBLY__ +#define UL(x) (x##UL) +#else +#define UL(x) (x) +#endif + +#include +#include +#include + +#ifdef CONFIG_MMU + +#ifndef TASK_SIZE +/* + * TASK_SIZE - the maximum size of a user space task. + * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area + */ +#define TASK_SIZE UL(0xbf000000) +#define TASK_UNMAPPED_BASE UL(0x40000000) +#endif + +/* + * The maximum size of a 26-bit user space task. + */ +#define TASK_SIZE_26 UL(0x04000000) + +/* + * Page offset: 3GB + */ +#ifndef PAGE_OFFSET +#define PAGE_OFFSET UL(0xc0000000) +#endif + +/* + * The module space lives between the addresses given by TASK_SIZE + * and PAGE_OFFSET - it must be within 32MB of the kernel text. + */ +#define MODULE_END (PAGE_OFFSET) +#define MODULE_START (MODULE_END - 16*1048576) + +#if TASK_SIZE > MODULE_START +#error Top of user space clashes with start of module space +#endif + +/* + * The XIP kernel gets mapped at the bottom of the module vm area. + * Since we use sections to map it, this macro replaces the physical address + * with its virtual address while keeping offset from the base section. + */ +#define XIP_VIRT_ADDR(physaddr) (MODULE_START + ((physaddr) & 0x000fffff)) + +/* + * Allow 16MB-aligned ioremap pages + */ +#define IOREMAP_MAX_ORDER 24 + +#else /* CONFIG_MMU */ + +/* + * The limitation of user task size can grow up to the end of free ram region. + * It is difficult to define and perhaps will never meet the original meaning + * of this define that was meant to. + * Fortunately, there is no reference for this in noMMU mode, for now. + */ +#ifndef TASK_SIZE +#define TASK_SIZE (CONFIG_DRAM_SIZE) +#endif + +#ifndef TASK_UNMAPPED_BASE +#define TASK_UNMAPPED_BASE UL(0x00000000) +#endif + +#ifndef PHYS_OFFSET +#define PHYS_OFFSET (CONFIG_DRAM_BASE) +#endif + +#ifndef END_MEM +#define END_MEM (CONFIG_DRAM_BASE + CONFIG_DRAM_SIZE) +#endif + +#ifndef PAGE_OFFSET +#define PAGE_OFFSET (PHYS_OFFSET) +#endif + +/* + * The module can be at any place in ram in nommu mode. + */ +#define MODULE_END (END_MEM) +#define MODULE_START (PHYS_OFFSET) + +#endif /* !CONFIG_MMU */ + +/* + * Size of DMA-consistent memory region. Must be multiple of 2M, + * between 2MB and 14MB inclusive. + */ +#ifndef CONSISTENT_DMA_SIZE +#define CONSISTENT_DMA_SIZE SZ_2M +#endif + +/* + * Physical vs virtual RAM address space conversion. These are + * private definitions which should NOT be used outside memory.h + * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. + */ +#ifndef __virt_to_phys +#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET) +#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) +#endif + +/* + * Convert a physical address to a Page Frame Number and back + */ +#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT) +#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT) + +#ifndef __ASSEMBLY__ + +/* + * The DMA mask corresponding to the maximum bus address allocatable + * using GFP_DMA. The default here places no restriction on DMA + * allocations. This must be the smallest DMA mask in the system, + * so a successful GFP_DMA allocation will always satisfy this. + */ +#ifndef ISA_DMA_THRESHOLD +#define ISA_DMA_THRESHOLD (0xffffffffULL) +#endif + +#ifndef arch_adjust_zones +#define arch_adjust_zones(node,size,holes) do { } while (0) +#endif + +/* + * PFNs are used to describe any physical page; this means + * PFN 0 == physical address 0. + * + * This is the PFN of the first RAM page in the kernel + * direct-mapped view. We assume this is the first page + * of RAM in the mem_map as well. + */ +#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) + +/* + * These are *only* valid on the kernel direct mapped RAM memory. + * Note: Drivers should NOT use these. They are the wrong + * translation for translating DMA addresses. Use the driver + * DMA support - see dma-mapping.h. + */ +static inline unsigned long virt_to_phys(void *x) +{ + return __virt_to_phys((unsigned long)(x)); +} + +static inline void *phys_to_virt(unsigned long x) +{ + return (void *)(__phys_to_virt((unsigned long)(x))); +} + +/* + * Drivers should NOT use these either. + */ +#define __pa(x) __virt_to_phys((unsigned long)(x)) +#define __va(x) ((void *)__phys_to_virt((unsigned long)(x))) +#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) + +/* + * Virtual <-> DMA view memory address translations + * Again, these are *only* valid on the kernel direct mapped RAM + * memory. Use of these is *deprecated* (and that doesn't mean + * use the __ prefixed forms instead.) See dma-mapping.h. + */ +static inline __deprecated unsigned long virt_to_bus(void *x) +{ + return __virt_to_bus((unsigned long)x); +} + +static inline __deprecated void *bus_to_virt(unsigned long x) +{ + return (void *)__bus_to_virt(x); +} + +/* + * Conversion between a struct page and a physical address. + * + * Note: when converting an unknown physical address to a + * struct page, the resulting pointer must be validated + * using VALID_PAGE(). It must return an invalid struct page + * for any physical address not corresponding to a system + * RAM address. + * + * page_to_pfn(page) convert a struct page * to a PFN number + * pfn_to_page(pfn) convert a _valid_ PFN number to struct page * + * pfn_valid(pfn) indicates whether a PFN number is valid + * + * virt_to_page(k) convert a _valid_ virtual address to struct page * + * virt_addr_valid(k) indicates whether a virtual address is valid + */ +#ifndef CONFIG_DISCONTIGMEM + +#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET + +#ifndef CONFIG_SPARSEMEM +#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr)) +#endif + +#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) +#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) + +#define PHYS_TO_NID(addr) (0) + +#else /* CONFIG_DISCONTIGMEM */ + +/* + * This is more complex. We have a set of mem_map arrays spread + * around in memory. + */ +#include + +#define arch_pfn_to_nid(pfn) PFN_TO_NID(pfn) +#define arch_local_page_offset(pfn, nid) LOCAL_MAP_NR((pfn) << PAGE_SHIFT) + +#define pfn_valid(pfn) \ + ({ \ + unsigned int nid = PFN_TO_NID(pfn); \ + int valid = nid < MAX_NUMNODES; \ + if (valid) { \ + pg_data_t *node = NODE_DATA(nid); \ + valid = (pfn - node->node_start_pfn) < \ + node->node_spanned_pages; \ + } \ + valid; \ + }) + +#define virt_to_page(kaddr) \ + (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)) + +#define virt_addr_valid(kaddr) (KVADDR_TO_NID(kaddr) < MAX_NUMNODES) + +/* + * Common discontigmem stuff. + * PHYS_TO_NID is used by the ARM kernel/setup.c + */ +#define PHYS_TO_NID(addr) PFN_TO_NID((addr) >> PAGE_SHIFT) + +/* + * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory + * and returns the mem_map of that node. + */ +#define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID(kaddr)) + +/* + * Given a page frame number, find the owning node of the memory + * and returns the mem_map of that node. + */ +#define PFN_TO_MAPBASE(pfn) NODE_MEM_MAP(PFN_TO_NID(pfn)) + +#ifdef NODE_MEM_SIZE_BITS +#define NODE_MEM_SIZE_MASK ((1 << NODE_MEM_SIZE_BITS) - 1) + +/* + * Given a kernel address, find the home node of the underlying memory. + */ +#define KVADDR_TO_NID(addr) \ + (((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MEM_SIZE_BITS) + +/* + * Given a page frame number, convert it to a node id. + */ +#define PFN_TO_NID(pfn) \ + (((pfn) - PHYS_PFN_OFFSET) >> (NODE_MEM_SIZE_BITS - PAGE_SHIFT)) + +/* + * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory + * and returns the index corresponding to the appropriate page in the + * node's mem_map. + */ +#define LOCAL_MAP_NR(addr) \ + (((unsigned long)(addr) & NODE_MEM_SIZE_MASK) >> PAGE_SHIFT) + +#endif /* NODE_MEM_SIZE_BITS */ + +#endif /* !CONFIG_DISCONTIGMEM */ + +/* + * For BIO. "will die". Kill me when bio_to_phys() and bvec_to_phys() die. + */ +#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) + +/* + * Optional device DMA address remapping. Do _not_ use directly! + * We should really eliminate virt_to_bus() here - it's deprecated. + */ +#ifndef __arch_page_to_dma +#define page_to_dma(dev, page) ((dma_addr_t)__virt_to_bus((unsigned long)page_address(page))) +#define dma_to_virt(dev, addr) ((void *)__bus_to_virt(addr)) +#define virt_to_dma(dev, addr) ((dma_addr_t)__virt_to_bus((unsigned long)(addr))) +#else +#define page_to_dma(dev, page) (__arch_page_to_dma(dev, page)) +#define dma_to_virt(dev, addr) (__arch_dma_to_virt(dev, addr)) +#define virt_to_dma(dev, addr) (__arch_virt_to_dma(dev, addr)) +#endif + +/* + * Optional coherency support. Currently used only by selected + * Intel XSC3-based systems. + */ +#ifndef arch_is_coherent +#define arch_is_coherent() 0 +#endif + +#endif + +#include + +#endif diff --git a/include/asm-arm/mman.h b/arch/arm/include/asm/mman.h similarity index 100% rename from include/asm-arm/mman.h rename to arch/arm/include/asm/mman.h diff --git a/include/asm-arm/mmu.h b/arch/arm/include/asm/mmu.h similarity index 100% rename from include/asm-arm/mmu.h rename to arch/arm/include/asm/mmu.h diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h new file mode 100644 index 0000000000000..a301e446007f5 --- /dev/null +++ b/arch/arm/include/asm/mmu_context.h @@ -0,0 +1,117 @@ +/* + * arch/arm/include/asm/mmu_context.h + * + * Copyright (C) 1996 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. + * + * Changelog: + * 27-06-1996 RMK Created + */ +#ifndef __ASM_ARM_MMU_CONTEXT_H +#define __ASM_ARM_MMU_CONTEXT_H + +#include +#include +#include +#include + +void __check_kvm_seq(struct mm_struct *mm); + +#ifdef CONFIG_CPU_HAS_ASID + +/* + * On ARMv6, we have the following structure in the Context ID: + * + * 31 7 0 + * +-------------------------+-----------+ + * | process ID | ASID | + * +-------------------------+-----------+ + * | context ID | + * +-------------------------------------+ + * + * The ASID is used to tag entries in the CPU caches and TLBs. + * The context ID is used by debuggers and trace logic, and + * should be unique within all running processes. + */ +#define ASID_BITS 8 +#define ASID_MASK ((~0) << ASID_BITS) +#define ASID_FIRST_VERSION (1 << ASID_BITS) + +extern unsigned int cpu_last_asid; + +void __init_new_context(struct task_struct *tsk, struct mm_struct *mm); +void __new_context(struct mm_struct *mm); + +static inline void check_context(struct mm_struct *mm) +{ + if (unlikely((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) + __new_context(mm); + + if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq)) + __check_kvm_seq(mm); +} + +#define init_new_context(tsk,mm) (__init_new_context(tsk,mm),0) + +#else + +static inline void check_context(struct mm_struct *mm) +{ + if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq)) + __check_kvm_seq(mm); +} + +#define init_new_context(tsk,mm) 0 + +#endif + +#define destroy_context(mm) do { } while(0) + +/* + * This is called when "tsk" is about to enter lazy TLB mode. + * + * mm: describes the currently active mm context + * tsk: task which is entering lazy tlb + * cpu: cpu number which is entering lazy tlb + * + * tsk->mm will be NULL + */ +static inline void +enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) +{ +} + +/* + * This is the actual mm switch as far as the scheduler + * is concerned. No registers are touched. We avoid + * calling the CPU specific function when the mm hasn't + * actually changed. + */ +static inline void +switch_mm(struct mm_struct *prev, struct mm_struct *next, + struct task_struct *tsk) +{ +#ifdef CONFIG_MMU + unsigned int cpu = smp_processor_id(); + +#ifdef CONFIG_SMP + /* check for possible thread migration */ + if (!cpus_empty(next->cpu_vm_mask) && !cpu_isset(cpu, next->cpu_vm_mask)) + __flush_icache_all(); +#endif + if (!cpu_test_and_set(cpu, next->cpu_vm_mask) || prev != next) { + check_context(next); + cpu_switch_mm(next->pgd, next); + if (cache_is_vivt()) + cpu_clear(cpu, prev->cpu_vm_mask); + } +#endif +} + +#define deactivate_mm(tsk,mm) do { } while (0) +#define activate_mm(prev,next) switch_mm(prev, next, NULL) + +#endif diff --git a/arch/arm/include/asm/mmzone.h b/arch/arm/include/asm/mmzone.h new file mode 100644 index 0000000000000..ae63a4fd28c83 --- /dev/null +++ b/arch/arm/include/asm/mmzone.h @@ -0,0 +1,30 @@ +/* + * arch/arm/include/asm/mmzone.h + * + * 1999-12-29 Nicolas Pitre Created + * + * 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. + */ +#ifndef __ASM_MMZONE_H +#define __ASM_MMZONE_H + +/* + * Currently defined in arch/arm/mm/discontig.c + */ +extern pg_data_t discontig_node_data[]; + +/* + * Return a pointer to the node data for node n. + */ +#define NODE_DATA(nid) (&discontig_node_data[nid]) + +/* + * NODE_MEM_MAP gives the kaddr for the mem_map of the node. + */ +#define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map) + +#include + +#endif diff --git a/include/asm-arm/module.h b/arch/arm/include/asm/module.h similarity index 100% rename from include/asm-arm/module.h rename to arch/arm/include/asm/module.h diff --git a/include/asm-arm/msgbuf.h b/arch/arm/include/asm/msgbuf.h similarity index 100% rename from include/asm-arm/msgbuf.h rename to arch/arm/include/asm/msgbuf.h diff --git a/arch/arm/include/asm/mtd-xip.h b/arch/arm/include/asm/mtd-xip.h new file mode 100644 index 0000000000000..4225372a26f30 --- /dev/null +++ b/arch/arm/include/asm/mtd-xip.h @@ -0,0 +1,26 @@ +/* + * MTD primitives for XIP support. Architecture specific functions + * + * Do not include this file directly. It's included from linux/mtd/xip.h + * + * Author: Nicolas Pitre + * Created: Nov 2, 2004 + * Copyright: (C) 2004 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * $Id: xip.h,v 1.2 2004/12/01 15:49:10 nico Exp $ + */ + +#ifndef __ARM_MTD_XIP_H__ +#define __ARM_MTD_XIP_H__ + +#include +#include + +/* fill instruction prefetch */ +#define xip_iprefetch() do { asm volatile (".rep 8; nop; .endr"); } while (0) + +#endif /* __ARM_MTD_XIP_H__ */ diff --git a/arch/arm/include/asm/mutex.h b/arch/arm/include/asm/mutex.h new file mode 100644 index 0000000000000..93226cf23ae0a --- /dev/null +++ b/arch/arm/include/asm/mutex.h @@ -0,0 +1,127 @@ +/* + * arch/arm/include/asm/mutex.h + * + * ARM optimized mutex locking primitives + * + * Please look into asm-generic/mutex-xchg.h for a formal definition. + */ +#ifndef _ASM_MUTEX_H +#define _ASM_MUTEX_H + +#if __LINUX_ARM_ARCH__ < 6 +/* On pre-ARMv6 hardware the swp based implementation is the most efficient. */ +# include +#else + +/* + * Attempting to lock a mutex on ARMv6+ can be done with a bastardized + * atomic decrement (it is not a reliable atomic decrement but it satisfies + * the defined semantics for our purpose, while being smaller and faster + * than a real atomic decrement or atomic swap. The idea is to attempt + * decrementing the lock value only once. If once decremented it isn't zero, + * or if its store-back fails due to a dispute on the exclusive store, we + * simply bail out immediately through the slow path where the lock will be + * reattempted until it succeeds. + */ +static inline void +__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res; + + __asm__ ( + + "ldrex %0, [%2] \n\t" + "sub %0, %0, #1 \n\t" + "strex %1, %0, [%2] " + + : "=&r" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "cc","memory" ); + + __res |= __ex_flag; + if (unlikely(__res != 0)) + fail_fn(count); +} + +static inline int +__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res; + + __asm__ ( + + "ldrex %0, [%2] \n\t" + "sub %0, %0, #1 \n\t" + "strex %1, %0, [%2] " + + : "=&r" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "cc","memory" ); + + __res |= __ex_flag; + if (unlikely(__res != 0)) + __res = fail_fn(count); + return __res; +} + +/* + * Same trick is used for the unlock fast path. However the original value, + * rather than the result, is used to test for success in order to have + * better generated assembly. + */ +static inline void +__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res, __orig; + + __asm__ ( + + "ldrex %0, [%3] \n\t" + "add %1, %0, #1 \n\t" + "strex %2, %1, [%3] " + + : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) + : "r" (&(count)->counter) + : "cc","memory" ); + + __orig |= __ex_flag; + if (unlikely(__orig != 0)) + fail_fn(count); +} + +/* + * If the unlock was done on a contended lock, or if the unlock simply fails + * then the mutex remains locked. + */ +#define __mutex_slowpath_needs_to_unlock() 1 + +/* + * For __mutex_fastpath_trylock we use another construct which could be + * described as a "single value cmpxchg". + * + * This provides the needed trylock semantics like cmpxchg would, but it is + * lighter and less generic than a true cmpxchg implementation. + */ +static inline int +__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) +{ + int __ex_flag, __res, __orig; + + __asm__ ( + + "1: ldrex %0, [%3] \n\t" + "subs %1, %0, #1 \n\t" + "strexeq %2, %1, [%3] \n\t" + "movlt %0, #0 \n\t" + "cmpeq %2, #0 \n\t" + "bgt 1b " + + : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) + : "r" (&count->counter) + : "cc", "memory" ); + + return __orig; +} + +#endif +#endif diff --git a/include/asm-arm/nwflash.h b/arch/arm/include/asm/nwflash.h similarity index 100% rename from include/asm-arm/nwflash.h rename to arch/arm/include/asm/nwflash.h diff --git a/include/asm-arm/page-nommu.h b/arch/arm/include/asm/page-nommu.h similarity index 96% rename from include/asm-arm/page-nommu.h rename to arch/arm/include/asm/page-nommu.h index ea1cde84f500d..3574c0deb37fc 100644 --- a/include/asm-arm/page-nommu.h +++ b/arch/arm/include/asm/page-nommu.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/page-nommu.h + * arch/arm/include/asm/page-nommu.h * * Copyright (C) 2004 Hyok S. Choi * diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h new file mode 100644 index 0000000000000..cf2e2680daaa1 --- /dev/null +++ b/arch/arm/include/asm/page.h @@ -0,0 +1,199 @@ +/* + * arch/arm/include/asm/page.h + * + * Copyright (C) 1995-2003 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. + */ +#ifndef _ASMARM_PAGE_H +#define _ASMARM_PAGE_H + +/* PAGE_SHIFT determines the page size */ +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +#ifndef __ASSEMBLY__ + +#ifndef CONFIG_MMU + +#include "page-nommu.h" + +#else + +#include + +/* + * User Space Model + * ================ + * + * This section selects the correct set of functions for dealing with + * page-based copying and clearing for user space for the particular + * processor(s) we're building for. + * + * We have the following to choose from: + * v3 - ARMv3 + * v4wt - ARMv4 with writethrough cache, without minicache + * v4wb - ARMv4 with writeback cache, without minicache + * v4_mc - ARMv4 with minicache + * xscale - Xscale + * xsc3 - XScalev3 + */ +#undef _USER +#undef MULTI_USER + +#ifdef CONFIG_CPU_COPY_V3 +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER v3 +# endif +#endif + +#ifdef CONFIG_CPU_COPY_V4WT +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER v4wt +# endif +#endif + +#ifdef CONFIG_CPU_COPY_V4WB +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER v4wb +# endif +#endif + +#ifdef CONFIG_CPU_COPY_FEROCEON +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER feroceon +# endif +#endif + +#ifdef CONFIG_CPU_SA1100 +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER v4_mc +# endif +#endif + +#ifdef CONFIG_CPU_XSCALE +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER xscale_mc +# endif +#endif + +#ifdef CONFIG_CPU_XSC3 +# ifdef _USER +# define MULTI_USER 1 +# else +# define _USER xsc3_mc +# endif +#endif + +#ifdef CONFIG_CPU_COPY_V6 +# define MULTI_USER 1 +#endif + +#if !defined(_USER) && !defined(MULTI_USER) +#error Unknown user operations model +#endif + +struct cpu_user_fns { + void (*cpu_clear_user_page)(void *p, unsigned long user); + void (*cpu_copy_user_page)(void *to, const void *from, + unsigned long user); +}; + +#ifdef MULTI_USER +extern struct cpu_user_fns cpu_user; + +#define __cpu_clear_user_page cpu_user.cpu_clear_user_page +#define __cpu_copy_user_page cpu_user.cpu_copy_user_page + +#else + +#define __cpu_clear_user_page __glue(_USER,_clear_user_page) +#define __cpu_copy_user_page __glue(_USER,_copy_user_page) + +extern void __cpu_clear_user_page(void *p, unsigned long user); +extern void __cpu_copy_user_page(void *to, const void *from, + unsigned long user); +#endif + +#define clear_user_page(addr,vaddr,pg) __cpu_clear_user_page(addr, vaddr) +#define copy_user_page(to,from,vaddr,pg) __cpu_copy_user_page(to, from, vaddr) + +#define clear_page(page) memzero((void *)(page), PAGE_SIZE) +extern void copy_page(void *to, const void *from); + +#undef STRICT_MM_TYPECHECKS + +#ifdef STRICT_MM_TYPECHECKS +/* + * These are used to make use of C type-checking.. + */ +typedef struct { unsigned long pte; } pte_t; +typedef struct { unsigned long pmd; } pmd_t; +typedef struct { unsigned long pgd[2]; } pgd_t; +typedef struct { unsigned long pgprot; } pgprot_t; + +#define pte_val(x) ((x).pte) +#define pmd_val(x) ((x).pmd) +#define pgd_val(x) ((x).pgd[0]) +#define pgprot_val(x) ((x).pgprot) + +#define __pte(x) ((pte_t) { (x) } ) +#define __pmd(x) ((pmd_t) { (x) } ) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +#else +/* + * .. while these make it easier on the compiler + */ +typedef unsigned long pte_t; +typedef unsigned long pmd_t; +typedef unsigned long pgd_t[2]; +typedef unsigned long pgprot_t; + +#define pte_val(x) (x) +#define pmd_val(x) (x) +#define pgd_val(x) ((x)[0]) +#define pgprot_val(x) (x) + +#define __pte(x) (x) +#define __pmd(x) (x) +#define __pgprot(x) (x) + +#endif /* STRICT_MM_TYPECHECKS */ + +#endif /* CONFIG_MMU */ + +typedef struct page *pgtable_t; + +#include + +#endif /* !__ASSEMBLY__ */ + +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +/* + * With EABI on ARMv5 and above we must have 64-bit aligned slab pointers. + */ +#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) +#define ARCH_SLAB_MINALIGN 8 +#endif + +#include + +#endif diff --git a/arch/arm/include/asm/param.h b/arch/arm/include/asm/param.h new file mode 100644 index 0000000000000..8b24bf94c06ba --- /dev/null +++ b/arch/arm/include/asm/param.h @@ -0,0 +1,31 @@ +/* + * arch/arm/include/asm/param.h + * + * Copyright (C) 1995-1999 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. + */ +#ifndef __ASM_PARAM_H +#define __ASM_PARAM_H + +#ifdef __KERNEL__ +# define HZ CONFIG_HZ /* Internal kernel timer frequency */ +# define USER_HZ 100 /* User interfaces are in "ticks" */ +# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ +#else +# define HZ 100 +#endif + +#define EXEC_PAGESIZE 4096 + +#ifndef NOGROUP +#define NOGROUP (-1) +#endif + +/* max length of hostname */ +#define MAXHOSTNAMELEN 64 + +#endif + diff --git a/arch/arm/include/asm/parport.h b/arch/arm/include/asm/parport.h new file mode 100644 index 0000000000000..26e94b09035a7 --- /dev/null +++ b/arch/arm/include/asm/parport.h @@ -0,0 +1,18 @@ +/* + * arch/arm/include/asm/parport.h: ARM-specific parport initialisation + * + * Copyright (C) 1999, 2000 Tim Waugh + * + * This file should only be included by drivers/parport/parport_pc.c. + */ + +#ifndef __ASMARM_PARPORT_H +#define __ASMARM_PARPORT_H + +static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); +static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) +{ + return parport_pc_find_isa_ports (autoirq, autodma); +} + +#endif /* !(_ASMARM_PARPORT_H) */ diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h new file mode 100644 index 0000000000000..721c03d53f4b3 --- /dev/null +++ b/arch/arm/include/asm/pci.h @@ -0,0 +1,91 @@ +#ifndef ASMARM_PCI_H +#define ASMARM_PCI_H + +#ifdef __KERNEL__ +#include + +#include /* for PCIBIOS_MIN_* */ + +#define pcibios_scan_all_fns(a, b) 0 + +#ifdef CONFIG_PCI_HOST_ITE8152 +/* ITE bridge requires setting latency timer to avoid early bus access + termination by PIC bus mater devices +*/ +extern void pcibios_set_master(struct pci_dev *dev); +#else +static inline void pcibios_set_master(struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} +#endif + +static inline void pcibios_penalize_isa_irq(int irq, int active) +{ + /* We don't do dynamic PCI IRQ allocation */ +} + +/* + * The PCI address space does equal the physical memory address space. + * The networking and block device layers use this boolean for bounce + * buffer decisions. + */ +#define PCI_DMA_BUS_IS_PHYS (0) + +/* + * Whether pci_unmap_{single,page} is a nop depends upon the + * configuration. + */ +#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME; +#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME; +#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME) +#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL)) +#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) +#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) + +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} +#endif + +#define HAVE_PCI_MMAP +extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine); + +extern void +pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, + struct resource *res); + +extern void +pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, + struct pci_bus_region *region); + +static inline struct resource * +pcibios_select_root(struct pci_dev *pdev, struct resource *res) +{ + struct resource *root = NULL; + + if (res->flags & IORESOURCE_IO) + root = &ioport_resource; + if (res->flags & IORESOURCE_MEM) + root = &iomem_resource; + + return root; +} + +/* + * Dummy implementation; always return 0. + */ +static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) +{ + return 0; +} + +#endif /* __KERNEL__ */ + +#endif diff --git a/include/asm-arm/percpu.h b/arch/arm/include/asm/percpu.h similarity index 100% rename from include/asm-arm/percpu.h rename to arch/arm/include/asm/percpu.h diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h new file mode 100644 index 0000000000000..3dcd64bf18241 --- /dev/null +++ b/arch/arm/include/asm/pgalloc.h @@ -0,0 +1,136 @@ +/* + * arch/arm/include/asm/pgalloc.h + * + * Copyright (C) 2000-2001 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. + */ +#ifndef _ASMARM_PGALLOC_H +#define _ASMARM_PGALLOC_H + +#include +#include +#include +#include +#include + +#define check_pgt_cache() do { } while (0) + +#ifdef CONFIG_MMU + +#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER)) +#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL)) + +/* + * Since we have only two-level page tables, these are trivial + */ +#define pmd_alloc_one(mm,addr) ({ BUG(); ((pmd_t *)2); }) +#define pmd_free(mm, pmd) do { } while (0) +#define pgd_populate(mm,pmd,pte) BUG() + +extern pgd_t *get_pgd_slow(struct mm_struct *mm); +extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd); + +#define pgd_alloc(mm) get_pgd_slow(mm) +#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd) + +/* + * Allocate one PTE table. + * + * This actually allocates two hardware PTE tables, but we wrap this up + * into one table thus: + * + * +------------+ + * | h/w pt 0 | + * +------------+ + * | h/w pt 1 | + * +------------+ + * | Linux pt 0 | + * +------------+ + * | Linux pt 1 | + * +------------+ + */ +static inline pte_t * +pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) +{ + pte_t *pte; + + pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); + if (pte) { + clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE); + pte += PTRS_PER_PTE; + } + + return pte; +} + +static inline pgtable_t +pte_alloc_one(struct mm_struct *mm, unsigned long addr) +{ + struct page *pte; + + pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); + if (pte) { + void *page = page_address(pte); + clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE); + pgtable_page_ctor(pte); + } + + return pte; +} + +/* + * Free one PTE table. + */ +static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) +{ + if (pte) { + pte -= PTRS_PER_PTE; + free_page((unsigned long)pte); + } +} + +static inline void pte_free(struct mm_struct *mm, pgtable_t pte) +{ + pgtable_page_dtor(pte); + __free_page(pte); +} + +static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval) +{ + pmdp[0] = __pmd(pmdval); + pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t)); + flush_pmd_entry(pmdp); +} + +/* + * Populate the pmdp entry with a pointer to the pte. This pmd is part + * of the mm address space. + * + * Ensure that we always set both PMD entries. + */ +static inline void +pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) +{ + unsigned long pte_ptr = (unsigned long)ptep; + + /* + * The pmd must be loaded with the physical + * address of the PTE table + */ + pte_ptr -= PTRS_PER_PTE * sizeof(void *); + __pmd_populate(pmdp, __pa(pte_ptr) | _PAGE_KERNEL_TABLE); +} + +static inline void +pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep) +{ + __pmd_populate(pmdp, page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE); +} +#define pmd_pgtable(pmd) pmd_page(pmd) + +#endif /* CONFIG_MMU */ + +#endif diff --git a/include/asm-arm/pgtable-hwdef.h b/arch/arm/include/asm/pgtable-hwdef.h similarity index 98% rename from include/asm-arm/pgtable-hwdef.h rename to arch/arm/include/asm/pgtable-hwdef.h index f3b5120c99fef..fd1521d5cb9dd 100644 --- a/include/asm-arm/pgtable-hwdef.h +++ b/arch/arm/include/asm/pgtable-hwdef.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/pgtable-hwdef.h + * arch/arm/include/asm/pgtable-hwdef.h * * Copyright (C) 1995-2002 Russell King * diff --git a/include/asm-arm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h similarity index 98% rename from include/asm-arm/pgtable-nommu.h rename to arch/arm/include/asm/pgtable-nommu.h index 386fcc10a9730..b011f2e939aa7 100644 --- a/include/asm-arm/pgtable-nommu.h +++ b/arch/arm/include/asm/pgtable-nommu.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/pgtable-nommu.h + * arch/arm/include/asm/pgtable-nommu.h * * Copyright (C) 1995-2002 Russell King * Copyright (C) 2004 Hyok S. Choi diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h new file mode 100644 index 0000000000000..8e21ef15bd743 --- /dev/null +++ b/arch/arm/include/asm/pgtable.h @@ -0,0 +1,401 @@ +/* + * arch/arm/include/asm/pgtable.h + * + * Copyright (C) 1995-2002 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. + */ +#ifndef _ASMARM_PGTABLE_H +#define _ASMARM_PGTABLE_H + +#include +#include + +#ifndef CONFIG_MMU + +#include "pgtable-nommu.h" + +#else + +#include +#include +#include + +/* + * Just any arbitrary offset to the start of the vmalloc VM area: the + * current 8MB value just means that there will be a 8MB "hole" after the + * physical memory until the kernel virtual memory starts. That means that + * any out-of-bounds memory accesses will hopefully be caught. + * The vmalloc() routines leaves a hole of 4kB between each vmalloced + * area for the same reason. ;) + * + * Note that platforms may override VMALLOC_START, but they must provide + * VMALLOC_END. VMALLOC_END defines the (exclusive) limit of this space, + * which may not overlap IO space. + */ +#ifndef VMALLOC_START +#define VMALLOC_OFFSET (8*1024*1024) +#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) +#endif + +/* + * Hardware-wise, we have a two level page table structure, where the first + * level has 4096 entries, and the second level has 256 entries. Each entry + * is one 32-bit word. Most of the bits in the second level entry are used + * by hardware, and there aren't any "accessed" and "dirty" bits. + * + * Linux on the other hand has a three level page table structure, which can + * be wrapped to fit a two level page table structure easily - using the PGD + * and PTE only. However, Linux also expects one "PTE" table per page, and + * at least a "dirty" bit. + * + * Therefore, we tweak the implementation slightly - we tell Linux that we + * have 2048 entries in the first level, each of which is 8 bytes (iow, two + * hardware pointers to the second level.) The second level contains two + * hardware PTE tables arranged contiguously, followed by Linux versions + * which contain the state information Linux needs. We, therefore, end up + * with 512 entries in the "PTE" level. + * + * This leads to the page tables having the following layout: + * + * pgd pte + * | | + * +--------+ +0 + * | |-----> +------------+ +0 + * +- - - - + +4 | h/w pt 0 | + * | |-----> +------------+ +1024 + * +--------+ +8 | h/w pt 1 | + * | | +------------+ +2048 + * +- - - - + | Linux pt 0 | + * | | +------------+ +3072 + * +--------+ | Linux pt 1 | + * | | +------------+ +4096 + * + * See L_PTE_xxx below for definitions of bits in the "Linux pt", and + * PTE_xxx for definitions of bits appearing in the "h/w pt". + * + * PMD_xxx definitions refer to bits in the first level page table. + * + * The "dirty" bit is emulated by only granting hardware write permission + * iff the page is marked "writable" and "dirty" in the Linux PTE. This + * means that a write to a clean page will cause a permission fault, and + * the Linux MM layer will mark the page dirty via handle_pte_fault(). + * For the hardware to notice the permission change, the TLB entry must + * be flushed, and ptep_set_access_flags() does that for us. + * + * The "accessed" or "young" bit is emulated by a similar method; we only + * allow accesses to the page if the "young" bit is set. Accesses to the + * page will cause a fault, and handle_pte_fault() will set the young bit + * for us as long as the page is marked present in the corresponding Linux + * PTE entry. Again, ptep_set_access_flags() will ensure that the TLB is + * up to date. + * + * However, when the "young" bit is cleared, we deny access to the page + * by clearing the hardware PTE. Currently Linux does not flush the TLB + * for us in this case, which means the TLB will retain the transation + * until either the TLB entry is evicted under pressure, or a context + * switch which changes the user space mapping occurs. + */ +#define PTRS_PER_PTE 512 +#define PTRS_PER_PMD 1 +#define PTRS_PER_PGD 2048 + +/* + * PMD_SHIFT determines the size of the area a second-level page table can map + * PGDIR_SHIFT determines what a third-level page table entry can map + */ +#define PMD_SHIFT 21 +#define PGDIR_SHIFT 21 + +#define LIBRARY_TEXT_START 0x0c000000 + +#ifndef __ASSEMBLY__ +extern void __pte_error(const char *file, int line, unsigned long val); +extern void __pmd_error(const char *file, int line, unsigned long val); +extern void __pgd_error(const char *file, int line, unsigned long val); + +#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte)) +#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd)) +#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd)) +#endif /* !__ASSEMBLY__ */ + +#define PMD_SIZE (1UL << PMD_SHIFT) +#define PMD_MASK (~(PMD_SIZE-1)) +#define PGDIR_SIZE (1UL << PGDIR_SHIFT) +#define PGDIR_MASK (~(PGDIR_SIZE-1)) + +/* + * This is the lowest virtual address we can permit any user space + * mapping to be mapped at. This is particularly important for + * non-high vector CPUs. + */ +#define FIRST_USER_ADDRESS PAGE_SIZE + +#define FIRST_USER_PGD_NR 1 +#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) - FIRST_USER_PGD_NR) + +/* + * section address mask and size definitions. + */ +#define SECTION_SHIFT 20 +#define SECTION_SIZE (1UL << SECTION_SHIFT) +#define SECTION_MASK (~(SECTION_SIZE-1)) + +/* + * ARMv6 supersection address mask and size definitions. + */ +#define SUPERSECTION_SHIFT 24 +#define SUPERSECTION_SIZE (1UL << SUPERSECTION_SHIFT) +#define SUPERSECTION_MASK (~(SUPERSECTION_SIZE-1)) + +/* + * "Linux" PTE definitions. + * + * We keep two sets of PTEs - the hardware and the linux version. + * This allows greater flexibility in the way we map the Linux bits + * onto the hardware tables, and allows us to have YOUNG and DIRTY + * bits. + * + * The PTE table pointer refers to the hardware entries; the "Linux" + * entries are stored 1024 bytes below. + */ +#define L_PTE_PRESENT (1 << 0) +#define L_PTE_FILE (1 << 1) /* only when !PRESENT */ +#define L_PTE_YOUNG (1 << 1) +#define L_PTE_BUFFERABLE (1 << 2) /* matches PTE */ +#define L_PTE_CACHEABLE (1 << 3) /* matches PTE */ +#define L_PTE_USER (1 << 4) +#define L_PTE_WRITE (1 << 5) +#define L_PTE_EXEC (1 << 6) +#define L_PTE_DIRTY (1 << 7) +#define L_PTE_SHARED (1 << 10) /* shared(v6), coherent(xsc3) */ + +#ifndef __ASSEMBLY__ + +/* + * The pgprot_* and protection_map entries will be fixed up in runtime + * to include the cachable and bufferable bits based on memory policy, + * as well as any architecture dependent bits like global/ASID and SMP + * shared mapping bits. + */ +#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_CACHEABLE | L_PTE_BUFFERABLE +#define _L_PTE_READ L_PTE_USER | L_PTE_EXEC + +extern pgprot_t pgprot_user; +extern pgprot_t pgprot_kernel; + +#define PAGE_NONE pgprot_user +#define PAGE_COPY __pgprot(pgprot_val(pgprot_user) | _L_PTE_READ) +#define PAGE_SHARED __pgprot(pgprot_val(pgprot_user) | _L_PTE_READ | \ + L_PTE_WRITE) +#define PAGE_READONLY __pgprot(pgprot_val(pgprot_user) | _L_PTE_READ) +#define PAGE_KERNEL pgprot_kernel + +#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT) +#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ) +#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE) +#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ) + +#endif /* __ASSEMBLY__ */ + +/* + * The table below defines the page protection levels that we insert into our + * Linux page table version. These get translated into the best that the + * architecture can perform. Note that on most ARM hardware: + * 1) We cannot do execute protection + * 2) If we could do execute protection, then read is implied + * 3) write implies read permissions + */ +#define __P000 __PAGE_NONE +#define __P001 __PAGE_READONLY +#define __P010 __PAGE_COPY +#define __P011 __PAGE_COPY +#define __P100 __PAGE_READONLY +#define __P101 __PAGE_READONLY +#define __P110 __PAGE_COPY +#define __P111 __PAGE_COPY + +#define __S000 __PAGE_NONE +#define __S001 __PAGE_READONLY +#define __S010 __PAGE_SHARED +#define __S011 __PAGE_SHARED +#define __S100 __PAGE_READONLY +#define __S101 __PAGE_READONLY +#define __S110 __PAGE_SHARED +#define __S111 __PAGE_SHARED + +#ifndef __ASSEMBLY__ +/* + * ZERO_PAGE is a global shared page that is always zero: used + * for zero-mapped memory areas etc.. + */ +extern struct page *empty_zero_page; +#define ZERO_PAGE(vaddr) (empty_zero_page) + +#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) +#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))) + +#define pte_none(pte) (!pte_val(pte)) +#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) +#define pte_page(pte) (pfn_to_page(pte_pfn(pte))) +#define pte_offset_kernel(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) +#define pte_offset_map(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) +#define pte_offset_map_nested(dir,addr) (pmd_page_vaddr(*(dir)) + __pte_index(addr)) +#define pte_unmap(pte) do { } while (0) +#define pte_unmap_nested(pte) do { } while (0) + +#define set_pte_ext(ptep,pte,ext) cpu_set_pte_ext(ptep,pte,ext) + +#define set_pte_at(mm,addr,ptep,pteval) do { \ + set_pte_ext(ptep, pteval, (addr) >= TASK_SIZE ? 0 : PTE_EXT_NG); \ + } while (0) + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) +#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE) +#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) +#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) +#define pte_special(pte) (0) + +/* + * The following only works if pte_present() is not true. + */ +#define pte_file(pte) (pte_val(pte) & L_PTE_FILE) +#define pte_to_pgoff(x) (pte_val(x) >> 2) +#define pgoff_to_pte(x) __pte(((x) << 2) | L_PTE_FILE) + +#define PTE_FILE_MAX_BITS 30 + +#define PTE_BIT_FUNC(fn,op) \ +static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } + +PTE_BIT_FUNC(wrprotect, &= ~L_PTE_WRITE); +PTE_BIT_FUNC(mkwrite, |= L_PTE_WRITE); +PTE_BIT_FUNC(mkclean, &= ~L_PTE_DIRTY); +PTE_BIT_FUNC(mkdirty, |= L_PTE_DIRTY); +PTE_BIT_FUNC(mkold, &= ~L_PTE_YOUNG); +PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); + +static inline pte_t pte_mkspecial(pte_t pte) { return pte; } + +/* + * Mark the prot value as uncacheable and unbufferable. + */ +#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE)) +#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~L_PTE_CACHEABLE) + +#define pmd_none(pmd) (!pmd_val(pmd)) +#define pmd_present(pmd) (pmd_val(pmd)) +#define pmd_bad(pmd) (pmd_val(pmd) & 2) + +#define copy_pmd(pmdpd,pmdps) \ + do { \ + pmdpd[0] = pmdps[0]; \ + pmdpd[1] = pmdps[1]; \ + flush_pmd_entry(pmdpd); \ + } while (0) + +#define pmd_clear(pmdp) \ + do { \ + pmdp[0] = __pmd(0); \ + pmdp[1] = __pmd(0); \ + clean_pmd_entry(pmdp); \ + } while (0) + +static inline pte_t *pmd_page_vaddr(pmd_t pmd) +{ + unsigned long ptr; + + ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1); + ptr += PTRS_PER_PTE * sizeof(void *); + + return __va(ptr); +} + +#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd))) + +/* + * Permanent address of a page. We never have highmem, so this is trivial. + */ +#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT)) + +/* + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. + */ +#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot) + +/* + * The "pgd_xxx()" functions here are trivial for a folded two-level + * setup: the pgd is never bad, and a pmd always exists (as it's folded + * into the pgd entry) + */ +#define pgd_none(pgd) (0) +#define pgd_bad(pgd) (0) +#define pgd_present(pgd) (1) +#define pgd_clear(pgdp) do { } while (0) +#define set_pgd(pgd,pgdp) do { } while (0) + +/* to find an entry in a page-table-directory */ +#define pgd_index(addr) ((addr) >> PGDIR_SHIFT) + +#define pgd_offset(mm, addr) ((mm)->pgd+pgd_index(addr)) + +/* to find an entry in a kernel page-table-directory */ +#define pgd_offset_k(addr) pgd_offset(&init_mm, addr) + +/* Find an entry in the second-level page table.. */ +#define pmd_offset(dir, addr) ((pmd_t *)(dir)) + +/* Find an entry in the third-level page table.. */ +#define __pte_index(addr) (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) + +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +{ + const unsigned long mask = L_PTE_EXEC | L_PTE_WRITE | L_PTE_USER; + pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); + return pte; +} + +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; + +/* Encode and decode a swap entry. + * + * We support up to 32GB of swap on 4k machines + */ +#define __swp_type(x) (((x).val >> 2) & 0x7f) +#define __swp_offset(x) ((x).val >> 9) +#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) }) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) +#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val }) + +/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ +/* FIXME: this is not correct */ +#define kern_addr_valid(addr) (1) + +#include + +/* + * We provide our own arch_get_unmapped_area to cope with VIPT caches. + */ +#define HAVE_ARCH_UNMAPPED_AREA + +/* + * remap a physical page `pfn' of size `size' with page protection `prot' + * into virtual address `from' + */ +#define io_remap_pfn_range(vma,from,pfn,size,prot) \ + remap_pfn_range(vma, from, pfn, size, prot) + +#define pgtable_cache_init() do { } while (0) + +#endif /* !__ASSEMBLY__ */ + +#endif /* CONFIG_MMU */ + +#endif /* _ASMARM_PGTABLE_H */ diff --git a/include/asm-arm/poll.h b/arch/arm/include/asm/poll.h similarity index 100% rename from include/asm-arm/poll.h rename to arch/arm/include/asm/poll.h diff --git a/arch/arm/include/asm/posix_types.h b/arch/arm/include/asm/posix_types.h new file mode 100644 index 0000000000000..2446d23bfdbff --- /dev/null +++ b/arch/arm/include/asm/posix_types.h @@ -0,0 +1,77 @@ +/* + * arch/arm/include/asm/posix_types.h + * + * Copyright (C) 1996-1998 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. + * + * Changelog: + * 27-06-1996 RMK Created + */ +#ifndef __ARCH_ARM_POSIX_TYPES_H +#define __ARCH_ARM_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_timer_t; +typedef int __kernel_clockid_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef unsigned short __kernel_old_dev_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { + int val[2]; +} __kernel_fsid_t; + +#if defined(__KERNEL__) + +#undef __FD_SET +#define __FD_SET(fd, fdsetp) \ + (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] |= (1<<((fd) & 31))) + +#undef __FD_CLR +#define __FD_CLR(fd, fdsetp) \ + (((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] &= ~(1<<((fd) & 31))) + +#undef __FD_ISSET +#define __FD_ISSET(fd, fdsetp) \ + ((((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] & (1<<((fd) & 31))) != 0) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \ + (memset (fdsetp, 0, sizeof (*(fd_set *)(fdsetp)))) + +#endif + +#endif diff --git a/include/asm-arm/proc-fns.h b/arch/arm/include/asm/proc-fns.h similarity index 99% rename from include/asm-arm/proc-fns.h rename to arch/arm/include/asm/proc-fns.h index 75ec760f4c748..db80203b68e0a 100644 --- a/include/asm-arm/proc-fns.h +++ b/arch/arm/include/asm/proc-fns.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/proc-fns.h + * arch/arm/include/asm/proc-fns.h * * Copyright (C) 1997-1999 Russell King * Copyright (C) 2000 Deep Blue Solutions Ltd diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h new file mode 100644 index 0000000000000..b01d5e7e3d5ab --- /dev/null +++ b/arch/arm/include/asm/processor.h @@ -0,0 +1,131 @@ +/* + * arch/arm/include/asm/processor.h + * + * Copyright (C) 1995-1999 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. + */ + +#ifndef __ASM_ARM_PROCESSOR_H +#define __ASM_ARM_PROCESSOR_H + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ __label__ _l; _l: &&_l;}) + +#ifdef __KERNEL__ + +#include +#include + +#ifdef __KERNEL__ +#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \ + TASK_SIZE : TASK_SIZE_26) +#define STACK_TOP_MAX TASK_SIZE +#endif + +union debug_insn { + u32 arm; + u16 thumb; +}; + +struct debug_entry { + u32 address; + union debug_insn insn; +}; + +struct debug_info { + int nsaved; + struct debug_entry bp[2]; +}; + +struct thread_struct { + /* fault info */ + unsigned long address; + unsigned long trap_no; + unsigned long error_code; + /* debugging */ + struct debug_info debug; +}; + +#define INIT_THREAD { } + +#ifdef CONFIG_MMU +#define nommu_start_thread(regs) do { } while (0) +#else +#define nommu_start_thread(regs) regs->ARM_r10 = current->mm->start_data +#endif + +#define start_thread(regs,pc,sp) \ +({ \ + unsigned long *stack = (unsigned long *)sp; \ + set_fs(USER_DS); \ + memzero(regs->uregs, sizeof(regs->uregs)); \ + if (current->personality & ADDR_LIMIT_32BIT) \ + regs->ARM_cpsr = USR_MODE; \ + else \ + regs->ARM_cpsr = USR26_MODE; \ + if (elf_hwcap & HWCAP_THUMB && pc & 1) \ + regs->ARM_cpsr |= PSR_T_BIT; \ + regs->ARM_pc = pc & ~1; /* pc */ \ + regs->ARM_sp = sp; /* sp */ \ + regs->ARM_r2 = stack[2]; /* r2 (envp) */ \ + regs->ARM_r1 = stack[1]; /* r1 (argv) */ \ + regs->ARM_r0 = stack[0]; /* r0 (argc) */ \ + nommu_start_thread(regs); \ +}) + +/* Forward declaration, a strange C thing */ +struct task_struct; + +/* Free all resources held by a thread. */ +extern void release_thread(struct task_struct *); + +/* Prepare to copy thread state - unlazy all lazy status */ +#define prepare_to_copy(tsk) do { } while (0) + +unsigned long get_wchan(struct task_struct *p); + +#define cpu_relax() barrier() + +/* + * Create a new kernel thread + */ +extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); + +#define task_pt_regs(p) \ + ((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1) + +#define KSTK_EIP(tsk) task_pt_regs(tsk)->ARM_pc +#define KSTK_ESP(tsk) task_pt_regs(tsk)->ARM_sp + +/* + * Prefetching support - only ARMv5. + */ +#if __LINUX_ARM_ARCH__ >= 5 + +#define ARCH_HAS_PREFETCH +static inline void prefetch(const void *ptr) +{ + __asm__ __volatile__( + "pld\t%0" + : + : "o" (*(char *)ptr) + : "cc"); +} + +#define ARCH_HAS_PREFETCHW +#define prefetchw(ptr) prefetch(ptr) + +#define ARCH_HAS_SPINLOCK_PREFETCH +#define spin_lock_prefetch(x) do { } while (0) + +#endif + +#endif + +#endif /* __ASM_ARM_PROCESSOR_H */ diff --git a/include/asm-arm/procinfo.h b/arch/arm/include/asm/procinfo.h similarity index 97% rename from include/asm-arm/procinfo.h rename to arch/arm/include/asm/procinfo.h index 4d3c685075e08..ca52e584ef74f 100644 --- a/include/asm-arm/procinfo.h +++ b/arch/arm/include/asm/procinfo.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/procinfo.h + * arch/arm/include/asm/procinfo.h * * Copyright (C) 1996-1999 Russell King * diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h new file mode 100644 index 0000000000000..b415c0e854589 --- /dev/null +++ b/arch/arm/include/asm/ptrace.h @@ -0,0 +1,162 @@ +/* + * arch/arm/include/asm/ptrace.h + * + * Copyright (C) 1996-2003 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. + */ +#ifndef __ASM_ARM_PTRACE_H +#define __ASM_ARM_PTRACE_H + +#include + +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 +/* PTRACE_ATTACH is 16 */ +/* PTRACE_DETACH is 17 */ +#define PTRACE_GETWMMXREGS 18 +#define PTRACE_SETWMMXREGS 19 +/* 20 is unused */ +#define PTRACE_OLDSETOPTIONS 21 +#define PTRACE_GET_THREAD_AREA 22 +#define PTRACE_SET_SYSCALL 23 +/* PTRACE_SYSCALL is 24 */ +#define PTRACE_GETCRUNCHREGS 25 +#define PTRACE_SETCRUNCHREGS 26 + +/* + * PSR bits + */ +#define USR26_MODE 0x00000000 +#define FIQ26_MODE 0x00000001 +#define IRQ26_MODE 0x00000002 +#define SVC26_MODE 0x00000003 +#define USR_MODE 0x00000010 +#define FIQ_MODE 0x00000011 +#define IRQ_MODE 0x00000012 +#define SVC_MODE 0x00000013 +#define ABT_MODE 0x00000017 +#define UND_MODE 0x0000001b +#define SYSTEM_MODE 0x0000001f +#define MODE32_BIT 0x00000010 +#define MODE_MASK 0x0000001f +#define PSR_T_BIT 0x00000020 +#define PSR_F_BIT 0x00000040 +#define PSR_I_BIT 0x00000080 +#define PSR_A_BIT 0x00000100 +#define PSR_J_BIT 0x01000000 +#define PSR_Q_BIT 0x08000000 +#define PSR_V_BIT 0x10000000 +#define PSR_C_BIT 0x20000000 +#define PSR_Z_BIT 0x40000000 +#define PSR_N_BIT 0x80000000 +#define PCMASK 0 + +/* + * Groups of PSR bits + */ +#define PSR_f 0xff000000 /* Flags */ +#define PSR_s 0x00ff0000 /* Status */ +#define PSR_x 0x0000ff00 /* Extension */ +#define PSR_c 0x000000ff /* Control */ + +#ifndef __ASSEMBLY__ + +/* + * This struct defines the way the registers are stored on the + * stack during a system call. Note that sizeof(struct pt_regs) + * has to be a multiple of 8. + */ +struct pt_regs { + long uregs[18]; +}; + +#define ARM_cpsr uregs[16] +#define ARM_pc uregs[15] +#define ARM_lr uregs[14] +#define ARM_sp uregs[13] +#define ARM_ip uregs[12] +#define ARM_fp uregs[11] +#define ARM_r10 uregs[10] +#define ARM_r9 uregs[9] +#define ARM_r8 uregs[8] +#define ARM_r7 uregs[7] +#define ARM_r6 uregs[6] +#define ARM_r5 uregs[5] +#define ARM_r4 uregs[4] +#define ARM_r3 uregs[3] +#define ARM_r2 uregs[2] +#define ARM_r1 uregs[1] +#define ARM_r0 uregs[0] +#define ARM_ORIG_r0 uregs[17] + +#ifdef __KERNEL__ + +#define user_mode(regs) \ + (((regs)->ARM_cpsr & 0xf) == 0) + +#ifdef CONFIG_ARM_THUMB +#define thumb_mode(regs) \ + (((regs)->ARM_cpsr & PSR_T_BIT)) +#else +#define thumb_mode(regs) (0) +#endif + +#define isa_mode(regs) \ + ((((regs)->ARM_cpsr & PSR_J_BIT) >> 23) | \ + (((regs)->ARM_cpsr & PSR_T_BIT) >> 5)) + +#define processor_mode(regs) \ + ((regs)->ARM_cpsr & MODE_MASK) + +#define interrupts_enabled(regs) \ + (!((regs)->ARM_cpsr & PSR_I_BIT)) + +#define fast_interrupts_enabled(regs) \ + (!((regs)->ARM_cpsr & PSR_F_BIT)) + +/* Are the current registers suitable for user mode? + * (used to maintain security in signal handlers) + */ +static inline int valid_user_regs(struct pt_regs *regs) +{ + if (user_mode(regs) && (regs->ARM_cpsr & PSR_I_BIT) == 0) { + regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT); + return 1; + } + + /* + * Force CPSR to something logical... + */ + regs->ARM_cpsr &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | PSR_T_BIT | MODE32_BIT; + if (!(elf_hwcap & HWCAP_26BIT)) + regs->ARM_cpsr |= USR_MODE; + + return 0; +} + +#define pc_pointer(v) \ + ((v) & ~PCMASK) + +#define instruction_pointer(regs) \ + (pc_pointer((regs)->ARM_pc)) + +#ifdef CONFIG_SMP +extern unsigned long profile_pc(struct pt_regs *regs); +#else +#define profile_pc(regs) instruction_pointer(regs) +#endif + +#define predicate(x) ((x) & 0xf0000000) +#define PREDICATE_ALWAYS 0xe0000000 + +#endif /* __KERNEL__ */ + +#endif /* __ASSEMBLY__ */ + +#endif + diff --git a/include/asm-arm/resource.h b/arch/arm/include/asm/resource.h similarity index 100% rename from include/asm-arm/resource.h rename to arch/arm/include/asm/resource.h diff --git a/include/asm-arm/scatterlist.h b/arch/arm/include/asm/scatterlist.h similarity index 100% rename from include/asm-arm/scatterlist.h rename to arch/arm/include/asm/scatterlist.h diff --git a/include/asm-arm/sections.h b/arch/arm/include/asm/sections.h similarity index 100% rename from include/asm-arm/sections.h rename to arch/arm/include/asm/sections.h diff --git a/include/asm-arm/segment.h b/arch/arm/include/asm/segment.h similarity index 100% rename from include/asm-arm/segment.h rename to arch/arm/include/asm/segment.h diff --git a/include/asm-arm/sembuf.h b/arch/arm/include/asm/sembuf.h similarity index 100% rename from include/asm-arm/sembuf.h rename to arch/arm/include/asm/sembuf.h diff --git a/arch/arm/include/asm/serial.h b/arch/arm/include/asm/serial.h new file mode 100644 index 0000000000000..ebb049091e260 --- /dev/null +++ b/arch/arm/include/asm/serial.h @@ -0,0 +1,19 @@ +/* + * arch/arm/include/asm/serial.h + * + * Copyright (C) 1996 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. + * + * Changelog: + * 15-10-1996 RMK Created + */ + +#ifndef __ASM_SERIAL_H +#define __ASM_SERIAL_H + +#define BASE_BAUD (1843200 / 16) + +#endif diff --git a/include/asm-arm/setup.h b/arch/arm/include/asm/setup.h similarity index 100% rename from include/asm-arm/setup.h rename to arch/arm/include/asm/setup.h diff --git a/include/asm-arm/shmbuf.h b/arch/arm/include/asm/shmbuf.h similarity index 100% rename from include/asm-arm/shmbuf.h rename to arch/arm/include/asm/shmbuf.h diff --git a/include/asm-arm/shmparam.h b/arch/arm/include/asm/shmparam.h similarity index 100% rename from include/asm-arm/shmparam.h rename to arch/arm/include/asm/shmparam.h diff --git a/include/asm-arm/sigcontext.h b/arch/arm/include/asm/sigcontext.h similarity index 100% rename from include/asm-arm/sigcontext.h rename to arch/arm/include/asm/sigcontext.h diff --git a/include/asm-arm/siginfo.h b/arch/arm/include/asm/siginfo.h similarity index 100% rename from include/asm-arm/siginfo.h rename to arch/arm/include/asm/siginfo.h diff --git a/include/asm-arm/signal.h b/arch/arm/include/asm/signal.h similarity index 100% rename from include/asm-arm/signal.h rename to arch/arm/include/asm/signal.h diff --git a/include/asm-arm/sizes.h b/arch/arm/include/asm/sizes.h similarity index 100% rename from include/asm-arm/sizes.h rename to arch/arm/include/asm/sizes.h diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h new file mode 100644 index 0000000000000..727b5c042e522 --- /dev/null +++ b/arch/arm/include/asm/smp.h @@ -0,0 +1,147 @@ +/* + * arch/arm/include/asm/smp.h + * + * Copyright (C) 2004-2005 ARM Ltd. + * + * 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. + */ +#ifndef __ASM_ARM_SMP_H +#define __ASM_ARM_SMP_H + +#include +#include +#include + +#include + +#ifndef CONFIG_SMP +# error " included in non-SMP build" +#endif + +#define raw_smp_processor_id() (current_thread_info()->cpu) + +/* + * at the moment, there's not a big penalty for changing CPUs + * (the >big< penalty is running SMP in the first place) + */ +#define PROC_CHANGE_PENALTY 15 + +struct seq_file; + +/* + * generate IPI list text + */ +extern void show_ipi_list(struct seq_file *p); + +/* + * Called from assembly code, this handles an IPI. + */ +asmlinkage void do_IPI(struct pt_regs *regs); + +/* + * Setup the SMP cpu_possible_map + */ +extern void smp_init_cpus(void); + +/* + * Move global data into per-processor storage. + */ +extern void smp_store_cpu_info(unsigned int cpuid); + +/* + * Raise an IPI cross call on CPUs in callmap. + */ +extern void smp_cross_call(cpumask_t callmap); + +/* + * Broadcast a timer interrupt to the other CPUs. + */ +extern void smp_send_timer(void); + +/* + * Broadcast a clock event to other CPUs. + */ +extern void smp_timer_broadcast(cpumask_t mask); + +/* + * Boot a secondary CPU, and assign it the specified idle task. + * This also gives us the initial stack to use for this CPU. + */ +extern int boot_secondary(unsigned int cpu, struct task_struct *); + +/* + * Called from platform specific assembly code, this is the + * secondary CPU entry point. + */ +asmlinkage void secondary_start_kernel(void); + +/* + * Perform platform specific initialisation of the specified CPU. + */ +extern void platform_secondary_init(unsigned int cpu); + +/* + * Initial data for bringing up a secondary CPU. + */ +struct secondary_data { + unsigned long pgdir; + void *stack; +}; +extern struct secondary_data secondary_data; + +extern int __cpu_disable(void); +extern int mach_cpu_disable(unsigned int cpu); + +extern void __cpu_die(unsigned int cpu); +extern void cpu_die(void); + +extern void platform_cpu_die(unsigned int cpu); +extern int platform_cpu_kill(unsigned int cpu); +extern void platform_cpu_enable(unsigned int cpu); + +extern void arch_send_call_function_single_ipi(int cpu); +extern void arch_send_call_function_ipi(cpumask_t mask); + +/* + * Local timer interrupt handling function (can be IPI'ed). + */ +extern void local_timer_interrupt(void); + +#ifdef CONFIG_LOCAL_TIMERS + +/* + * Stop a local timer interrupt. + */ +extern void local_timer_stop(unsigned int cpu); + +/* + * Platform provides this to acknowledge a local timer IRQ + */ +extern int local_timer_ack(void); + +#else + +static inline void local_timer_stop(unsigned int cpu) +{ +} + +#endif + +/* + * Setup a local timer interrupt for a CPU. + */ +extern void local_timer_setup(unsigned int cpu); + +/* + * show local interrupt info + */ +extern void show_local_irqs(struct seq_file *); + +/* + * Called from assembly, this is the local timer IRQ handler + */ +asmlinkage void do_local_timer(struct pt_regs *); + +#endif /* ifndef __ASM_ARM_SMP_H */ diff --git a/include/asm-arm/socket.h b/arch/arm/include/asm/socket.h similarity index 100% rename from include/asm-arm/socket.h rename to arch/arm/include/asm/socket.h diff --git a/include/asm-arm/sockios.h b/arch/arm/include/asm/sockios.h similarity index 100% rename from include/asm-arm/sockios.h rename to arch/arm/include/asm/sockios.h diff --git a/include/asm-arm/sparsemem.h b/arch/arm/include/asm/sparsemem.h similarity index 100% rename from include/asm-arm/sparsemem.h rename to arch/arm/include/asm/sparsemem.h diff --git a/include/asm-arm/spinlock.h b/arch/arm/include/asm/spinlock.h similarity index 100% rename from include/asm-arm/spinlock.h rename to arch/arm/include/asm/spinlock.h diff --git a/include/asm-arm/spinlock_types.h b/arch/arm/include/asm/spinlock_types.h similarity index 100% rename from include/asm-arm/spinlock_types.h rename to arch/arm/include/asm/spinlock_types.h diff --git a/include/asm-arm/stat.h b/arch/arm/include/asm/stat.h similarity index 100% rename from include/asm-arm/stat.h rename to arch/arm/include/asm/stat.h diff --git a/include/asm-arm/statfs.h b/arch/arm/include/asm/statfs.h similarity index 100% rename from include/asm-arm/statfs.h rename to arch/arm/include/asm/statfs.h diff --git a/include/asm-arm/string.h b/arch/arm/include/asm/string.h similarity index 100% rename from include/asm-arm/string.h rename to arch/arm/include/asm/string.h diff --git a/include/asm-arm/suspend.h b/arch/arm/include/asm/suspend.h similarity index 100% rename from include/asm-arm/suspend.h rename to arch/arm/include/asm/suspend.h diff --git a/include/asm-arm/system.h b/arch/arm/include/asm/system.h similarity index 100% rename from include/asm-arm/system.h rename to arch/arm/include/asm/system.h diff --git a/include/asm-arm/termbits.h b/arch/arm/include/asm/termbits.h similarity index 100% rename from include/asm-arm/termbits.h rename to arch/arm/include/asm/termbits.h diff --git a/include/asm-arm/termios.h b/arch/arm/include/asm/termios.h similarity index 100% rename from include/asm-arm/termios.h rename to arch/arm/include/asm/termios.h diff --git a/include/asm-arm/therm.h b/arch/arm/include/asm/therm.h similarity index 88% rename from include/asm-arm/therm.h rename to arch/arm/include/asm/therm.h index e51c923ecdf31..f002f0197d78a 100644 --- a/include/asm-arm/therm.h +++ b/arch/arm/include/asm/therm.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/therm.h: Definitions for Dallas Semiconductor + * arch/arm/include/asm/therm.h: Definitions for Dallas Semiconductor * DS1620 thermometer driver (as used in the Rebel.com NetWinder) */ #ifndef __ASM_THERM_H diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h new file mode 100644 index 0000000000000..e56fa48e4ae78 --- /dev/null +++ b/arch/arm/include/asm/thread_info.h @@ -0,0 +1,153 @@ +/* + * arch/arm/include/asm/thread_info.h + * + * Copyright (C) 2002 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. + */ +#ifndef __ASM_ARM_THREAD_INFO_H +#define __ASM_ARM_THREAD_INFO_H + +#ifdef __KERNEL__ + +#include +#include + +#define THREAD_SIZE_ORDER 1 +#define THREAD_SIZE 8192 +#define THREAD_START_SP (THREAD_SIZE - 8) + +#ifndef __ASSEMBLY__ + +struct task_struct; +struct exec_domain; + +#include +#include + +typedef unsigned long mm_segment_t; + +struct cpu_context_save { + __u32 r4; + __u32 r5; + __u32 r6; + __u32 r7; + __u32 r8; + __u32 r9; + __u32 sl; + __u32 fp; + __u32 sp; + __u32 pc; + __u32 extra[2]; /* Xscale 'acc' register, etc */ +}; + +/* + * low level task data that entry.S needs immediate access to. + * __switch_to() assumes cpu_context follows immediately after cpu_domain. + */ +struct thread_info { + unsigned long flags; /* low level flags */ + int preempt_count; /* 0 => preemptable, <0 => bug */ + mm_segment_t addr_limit; /* address limit */ + struct task_struct *task; /* main task structure */ + struct exec_domain *exec_domain; /* execution domain */ + __u32 cpu; /* cpu */ + __u32 cpu_domain; /* cpu domain */ + struct cpu_context_save cpu_context; /* cpu context */ + __u32 syscall; /* syscall number */ + __u8 used_cp[16]; /* thread used copro */ + unsigned long tp_value; + struct crunch_state crunchstate; + union fp_state fpstate __attribute__((aligned(8))); + union vfp_state vfpstate; +#ifdef CONFIG_ARM_THUMBEE + unsigned long thumbee_state; /* ThumbEE Handler Base register */ +#endif + struct restart_block restart_block; +}; + +#define INIT_THREAD_INFO(tsk) \ +{ \ + .task = &tsk, \ + .exec_domain = &default_exec_domain, \ + .flags = 0, \ + .preempt_count = 1, \ + .addr_limit = KERNEL_DS, \ + .cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \ + domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ + domain_val(DOMAIN_IO, DOMAIN_CLIENT), \ + .restart_block = { \ + .fn = do_no_restart_syscall, \ + }, \ +} + +#define init_thread_info (init_thread_union.thread_info) +#define init_stack (init_thread_union.stack) + +/* + * how to get the thread information struct from C + */ +static inline struct thread_info *current_thread_info(void) __attribute_const__; + +static inline struct thread_info *current_thread_info(void) +{ + register unsigned long sp asm ("sp"); + return (struct thread_info *)(sp & ~(THREAD_SIZE - 1)); +} + +#define thread_saved_pc(tsk) \ + ((unsigned long)(pc_pointer(task_thread_info(tsk)->cpu_context.pc))) +#define thread_saved_fp(tsk) \ + ((unsigned long)(task_thread_info(tsk)->cpu_context.fp)) + +extern void crunch_task_disable(struct thread_info *); +extern void crunch_task_copy(struct thread_info *, void *); +extern void crunch_task_restore(struct thread_info *, void *); +extern void crunch_task_release(struct thread_info *); + +extern void iwmmxt_task_disable(struct thread_info *); +extern void iwmmxt_task_copy(struct thread_info *, void *); +extern void iwmmxt_task_restore(struct thread_info *, void *); +extern void iwmmxt_task_release(struct thread_info *); +extern void iwmmxt_task_switch(struct thread_info *); + +#endif + +/* + * We use bit 30 of the preempt_count to indicate that kernel + * preemption is occurring. See . + */ +#define PREEMPT_ACTIVE 0x40000000 + +/* + * thread information flags: + * TIF_SYSCALL_TRACE - syscall trace active + * TIF_SIGPENDING - signal pending + * TIF_NEED_RESCHED - rescheduling necessary + * TIF_USEDFPU - FPU was used by this task this quantum (SMP) + * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED + */ +#define TIF_SIGPENDING 0 +#define TIF_NEED_RESCHED 1 +#define TIF_SYSCALL_TRACE 8 +#define TIF_POLLING_NRFLAG 16 +#define TIF_USING_IWMMXT 17 +#define TIF_MEMDIE 18 +#define TIF_FREEZE 19 + +#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) +#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) +#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) +#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) +#define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) +#define _TIF_FREEZE (1 << TIF_FREEZE) + +/* + * Change these and you break ASM code in entry-common.S + */ +#define _TIF_WORK_MASK 0x000000ff + +#endif /* __KERNEL__ */ +#endif /* __ASM_ARM_THREAD_INFO_H */ diff --git a/include/asm-arm/thread_notify.h b/arch/arm/include/asm/thread_notify.h similarity index 96% rename from include/asm-arm/thread_notify.h rename to arch/arm/include/asm/thread_notify.h index 8866e52168400..f27379d7f72a6 100644 --- a/include/asm-arm/thread_notify.h +++ b/arch/arm/include/asm/thread_notify.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/thread_notify.h + * arch/arm/include/asm/thread_notify.h * * Copyright (C) 2006 Russell King. * diff --git a/arch/arm/include/asm/timex.h b/arch/arm/include/asm/timex.h new file mode 100644 index 0000000000000..3be8de3adabae --- /dev/null +++ b/arch/arm/include/asm/timex.h @@ -0,0 +1,24 @@ +/* + * arch/arm/include/asm/timex.h + * + * Copyright (C) 1997,1998 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. + * + * Architecture Specific TIME specifications + */ +#ifndef _ASMARM_TIMEX_H +#define _ASMARM_TIMEX_H + +#include + +typedef unsigned long cycles_t; + +static inline cycles_t get_cycles (void) +{ + return 0; +} + +#endif diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h new file mode 100644 index 0000000000000..857f1dfac794c --- /dev/null +++ b/arch/arm/include/asm/tlb.h @@ -0,0 +1,94 @@ +/* + * arch/arm/include/asm/tlb.h + * + * Copyright (C) 2002 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. + * + * Experimentation shows that on a StrongARM, it appears to be faster + * to use the "invalidate whole tlb" rather than "invalidate single + * tlb" for this. + * + * This appears true for both the process fork+exit case, as well as + * the munmap-large-area case. + */ +#ifndef __ASMARM_TLB_H +#define __ASMARM_TLB_H + +#include +#include + +#ifndef CONFIG_MMU + +#include +#include + +#else /* !CONFIG_MMU */ + +#include + +/* + * TLB handling. This allows us to remove pages from the page + * tables, and efficiently handle the TLB issues. + */ +struct mmu_gather { + struct mm_struct *mm; + unsigned int fullmm; +}; + +DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); + +static inline struct mmu_gather * +tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush) +{ + struct mmu_gather *tlb = &get_cpu_var(mmu_gathers); + + tlb->mm = mm; + tlb->fullmm = full_mm_flush; + + return tlb; +} + +static inline void +tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) +{ + if (tlb->fullmm) + flush_tlb_mm(tlb->mm); + + /* keep the page table cache within bounds */ + check_pgt_cache(); + + put_cpu_var(mmu_gathers); +} + +#define tlb_remove_tlb_entry(tlb,ptep,address) do { } while (0) + +/* + * In the case of tlb vma handling, we can optimise these away in the + * case where we're doing a full MM flush. When we're doing a munmap, + * the vmas are adjusted to only cover the region to be torn down. + */ +static inline void +tlb_start_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) +{ + if (!tlb->fullmm) + flush_cache_range(vma, vma->vm_start, vma->vm_end); +} + +static inline void +tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) +{ + if (!tlb->fullmm) + flush_tlb_range(vma, vma->vm_start, vma->vm_end); +} + +#define tlb_remove_page(tlb,page) free_page_and_swap_cache(page) +#define pte_free_tlb(tlb, ptep) pte_free((tlb)->mm, ptep) +#define pmd_free_tlb(tlb, pmdp) pmd_free((tlb)->mm, pmdp) + +#define tlb_migrate_finish(mm) do { } while (0) + +#endif /* CONFIG_MMU */ +#endif diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h new file mode 100644 index 0000000000000..0d0d40f1b599e --- /dev/null +++ b/arch/arm/include/asm/tlbflush.h @@ -0,0 +1,500 @@ +/* + * arch/arm/include/asm/tlbflush.h + * + * Copyright (C) 1999-2003 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. + */ +#ifndef _ASMARM_TLBFLUSH_H +#define _ASMARM_TLBFLUSH_H + + +#ifndef CONFIG_MMU + +#define tlb_flush(tlb) ((void) tlb) + +#else /* CONFIG_MMU */ + +#include + +#define TLB_V3_PAGE (1 << 0) +#define TLB_V4_U_PAGE (1 << 1) +#define TLB_V4_D_PAGE (1 << 2) +#define TLB_V4_I_PAGE (1 << 3) +#define TLB_V6_U_PAGE (1 << 4) +#define TLB_V6_D_PAGE (1 << 5) +#define TLB_V6_I_PAGE (1 << 6) + +#define TLB_V3_FULL (1 << 8) +#define TLB_V4_U_FULL (1 << 9) +#define TLB_V4_D_FULL (1 << 10) +#define TLB_V4_I_FULL (1 << 11) +#define TLB_V6_U_FULL (1 << 12) +#define TLB_V6_D_FULL (1 << 13) +#define TLB_V6_I_FULL (1 << 14) + +#define TLB_V6_U_ASID (1 << 16) +#define TLB_V6_D_ASID (1 << 17) +#define TLB_V6_I_ASID (1 << 18) + +#define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */ +#define TLB_DCLEAN (1 << 30) +#define TLB_WB (1 << 31) + +/* + * MMU TLB Model + * ============= + * + * We have the following to choose from: + * v3 - ARMv3 + * v4 - ARMv4 without write buffer + * v4wb - ARMv4 with write buffer without I TLB flush entry instruction + * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction + * fr - Feroceon (v4wbi with non-outer-cacheable page table walks) + * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction + */ +#undef _TLB +#undef MULTI_TLB + +#define v3_tlb_flags (TLB_V3_FULL | TLB_V3_PAGE) + +#ifdef CONFIG_CPU_TLB_V3 +# define v3_possible_flags v3_tlb_flags +# define v3_always_flags v3_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v3 +# endif +#else +# define v3_possible_flags 0 +# define v3_always_flags (-1UL) +#endif + +#define v4_tlb_flags (TLB_V4_U_FULL | TLB_V4_U_PAGE) + +#ifdef CONFIG_CPU_TLB_V4WT +# define v4_possible_flags v4_tlb_flags +# define v4_always_flags v4_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v4 +# endif +#else +# define v4_possible_flags 0 +# define v4_always_flags (-1UL) +#endif + +#define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ + TLB_V4_I_FULL | TLB_V4_D_FULL | \ + TLB_V4_I_PAGE | TLB_V4_D_PAGE) + +#ifdef CONFIG_CPU_TLB_V4WBI +# define v4wbi_possible_flags v4wbi_tlb_flags +# define v4wbi_always_flags v4wbi_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v4wbi +# endif +#else +# define v4wbi_possible_flags 0 +# define v4wbi_always_flags (-1UL) +#endif + +#define fr_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_L2CLEAN_FR | \ + TLB_V4_I_FULL | TLB_V4_D_FULL | \ + TLB_V4_I_PAGE | TLB_V4_D_PAGE) + +#ifdef CONFIG_CPU_TLB_FEROCEON +# define fr_possible_flags fr_tlb_flags +# define fr_always_flags fr_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v4wbi +# endif +#else +# define fr_possible_flags 0 +# define fr_always_flags (-1UL) +#endif + +#define v4wb_tlb_flags (TLB_WB | TLB_DCLEAN | \ + TLB_V4_I_FULL | TLB_V4_D_FULL | \ + TLB_V4_D_PAGE) + +#ifdef CONFIG_CPU_TLB_V4WB +# define v4wb_possible_flags v4wb_tlb_flags +# define v4wb_always_flags v4wb_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v4wb +# endif +#else +# define v4wb_possible_flags 0 +# define v4wb_always_flags (-1UL) +#endif + +#define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ + TLB_V6_I_FULL | TLB_V6_D_FULL | \ + TLB_V6_I_PAGE | TLB_V6_D_PAGE | \ + TLB_V6_I_ASID | TLB_V6_D_ASID) + +#ifdef CONFIG_CPU_TLB_V6 +# define v6wbi_possible_flags v6wbi_tlb_flags +# define v6wbi_always_flags v6wbi_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v6wbi +# endif +#else +# define v6wbi_possible_flags 0 +# define v6wbi_always_flags (-1UL) +#endif + +#ifdef CONFIG_CPU_TLB_V7 +# define v7wbi_possible_flags v6wbi_tlb_flags +# define v7wbi_always_flags v6wbi_tlb_flags +# ifdef _TLB +# define MULTI_TLB 1 +# else +# define _TLB v7wbi +# endif +#else +# define v7wbi_possible_flags 0 +# define v7wbi_always_flags (-1UL) +#endif + +#ifndef _TLB +#error Unknown TLB model +#endif + +#ifndef __ASSEMBLY__ + +#include + +struct cpu_tlb_fns { + void (*flush_user_range)(unsigned long, unsigned long, struct vm_area_struct *); + void (*flush_kern_range)(unsigned long, unsigned long); + unsigned long tlb_flags; +}; + +/* + * Select the calling method + */ +#ifdef MULTI_TLB + +#define __cpu_flush_user_tlb_range cpu_tlb.flush_user_range +#define __cpu_flush_kern_tlb_range cpu_tlb.flush_kern_range + +#else + +#define __cpu_flush_user_tlb_range __glue(_TLB,_flush_user_tlb_range) +#define __cpu_flush_kern_tlb_range __glue(_TLB,_flush_kern_tlb_range) + +extern void __cpu_flush_user_tlb_range(unsigned long, unsigned long, struct vm_area_struct *); +extern void __cpu_flush_kern_tlb_range(unsigned long, unsigned long); + +#endif + +extern struct cpu_tlb_fns cpu_tlb; + +#define __cpu_tlb_flags cpu_tlb.tlb_flags + +/* + * TLB Management + * ============== + * + * The arch/arm/mm/tlb-*.S files implement these methods. + * + * The TLB specific code is expected to perform whatever tests it + * needs to determine if it should invalidate the TLB for each + * call. Start addresses are inclusive and end addresses are + * exclusive; it is safe to round these addresses down. + * + * flush_tlb_all() + * + * Invalidate the entire TLB. + * + * flush_tlb_mm(mm) + * + * Invalidate all TLB entries in a particular address + * space. + * - mm - mm_struct describing address space + * + * flush_tlb_range(mm,start,end) + * + * Invalidate a range of TLB entries in the specified + * address space. + * - mm - mm_struct describing address space + * - start - start address (may not be aligned) + * - end - end address (exclusive, may not be aligned) + * + * flush_tlb_page(vaddr,vma) + * + * Invalidate the specified page in the specified address range. + * - vaddr - virtual address (may not be aligned) + * - vma - vma_struct describing address range + * + * flush_kern_tlb_page(kaddr) + * + * Invalidate the TLB entry for the specified page. The address + * will be in the kernels virtual memory space. Current uses + * only require the D-TLB to be invalidated. + * - kaddr - Kernel virtual memory address + */ + +/* + * We optimise the code below by: + * - building a set of TLB flags that might be set in __cpu_tlb_flags + * - building a set of TLB flags that will always be set in __cpu_tlb_flags + * - if we're going to need __cpu_tlb_flags, access it once and only once + * + * This allows us to build optimal assembly for the single-CPU type case, + * and as close to optimal given the compiler constrants for multi-CPU + * case. We could do better for the multi-CPU case if the compiler + * implemented the "%?" method, but this has been discontinued due to too + * many people getting it wrong. + */ +#define possible_tlb_flags (v3_possible_flags | \ + v4_possible_flags | \ + v4wbi_possible_flags | \ + fr_possible_flags | \ + v4wb_possible_flags | \ + v6wbi_possible_flags) + +#define always_tlb_flags (v3_always_flags & \ + v4_always_flags & \ + v4wbi_always_flags & \ + fr_always_flags & \ + v4wb_always_flags & \ + v6wbi_always_flags) + +#define tlb_flag(f) ((always_tlb_flags & (f)) || (__tlb_flag & possible_tlb_flags & (f))) + +static inline void local_flush_tlb_all(void) +{ + const int zero = 0; + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_WB)) + dsb(); + + if (tlb_flag(TLB_V3_FULL)) + asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); + if (tlb_flag(TLB_V4_U_FULL | TLB_V6_U_FULL)) + asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc"); + if (tlb_flag(TLB_V4_D_FULL | TLB_V6_D_FULL)) + asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc"); + if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL)) + asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); + + if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL | + TLB_V6_I_PAGE | TLB_V6_D_PAGE | + TLB_V6_I_ASID | TLB_V6_D_ASID)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); + dsb(); + isb(); + } +} + +static inline void local_flush_tlb_mm(struct mm_struct *mm) +{ + const int zero = 0; + const int asid = ASID(mm); + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_WB)) + dsb(); + + if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) { + if (tlb_flag(TLB_V3_FULL)) + asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); + if (tlb_flag(TLB_V4_U_FULL)) + asm("mcr p15, 0, %0, c8, c7, 0" : : "r" (zero) : "cc"); + if (tlb_flag(TLB_V4_D_FULL)) + asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc"); + if (tlb_flag(TLB_V4_I_FULL)) + asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); + } + + if (tlb_flag(TLB_V6_U_ASID)) + asm("mcr p15, 0, %0, c8, c7, 2" : : "r" (asid) : "cc"); + if (tlb_flag(TLB_V6_D_ASID)) + asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc"); + if (tlb_flag(TLB_V6_I_ASID)) + asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc"); + + if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL | + TLB_V6_I_PAGE | TLB_V6_D_PAGE | + TLB_V6_I_ASID | TLB_V6_D_ASID)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); + dsb(); + } +} + +static inline void +local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) +{ + const int zero = 0; + const unsigned int __tlb_flag = __cpu_tlb_flags; + + uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); + + if (tlb_flag(TLB_WB)) + dsb(); + + if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) { + if (tlb_flag(TLB_V3_PAGE)) + asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (uaddr) : "cc"); + if (tlb_flag(TLB_V4_U_PAGE)) + asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc"); + if (tlb_flag(TLB_V4_D_PAGE)) + asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc"); + if (tlb_flag(TLB_V4_I_PAGE)) + asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); + if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) + asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); + } + + if (tlb_flag(TLB_V6_U_PAGE)) + asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (uaddr) : "cc"); + if (tlb_flag(TLB_V6_D_PAGE)) + asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc"); + if (tlb_flag(TLB_V6_I_PAGE)) + asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); + + if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL | + TLB_V6_I_PAGE | TLB_V6_D_PAGE | + TLB_V6_I_ASID | TLB_V6_D_ASID)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); + dsb(); + } +} + +static inline void local_flush_tlb_kernel_page(unsigned long kaddr) +{ + const int zero = 0; + const unsigned int __tlb_flag = __cpu_tlb_flags; + + kaddr &= PAGE_MASK; + + if (tlb_flag(TLB_WB)) + dsb(); + + if (tlb_flag(TLB_V3_PAGE)) + asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc"); + if (tlb_flag(TLB_V4_U_PAGE)) + asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc"); + if (tlb_flag(TLB_V4_D_PAGE)) + asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc"); + if (tlb_flag(TLB_V4_I_PAGE)) + asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); + if (!tlb_flag(TLB_V4_I_PAGE) && tlb_flag(TLB_V4_I_FULL)) + asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); + + if (tlb_flag(TLB_V6_U_PAGE)) + asm("mcr p15, 0, %0, c8, c7, 1" : : "r" (kaddr) : "cc"); + if (tlb_flag(TLB_V6_D_PAGE)) + asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (kaddr) : "cc"); + if (tlb_flag(TLB_V6_I_PAGE)) + asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); + + if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL | + TLB_V6_I_PAGE | TLB_V6_D_PAGE | + TLB_V6_I_ASID | TLB_V6_D_ASID)) { + /* flush the branch target cache */ + asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); + dsb(); + isb(); + } +} + +/* + * flush_pmd_entry + * + * Flush a PMD entry (word aligned, or double-word aligned) to + * RAM if the TLB for the CPU we are running on requires this. + * This is typically used when we are creating PMD entries. + * + * clean_pmd_entry + * + * Clean (but don't drain the write buffer) if the CPU requires + * these operations. This is typically used when we are removing + * PMD entries. + */ +static inline void flush_pmd_entry(pmd_t *pmd) +{ + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_DCLEAN)) + asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" + : : "r" (pmd) : "cc"); + + if (tlb_flag(TLB_L2CLEAN_FR)) + asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd" + : : "r" (pmd) : "cc"); + + if (tlb_flag(TLB_WB)) + dsb(); +} + +static inline void clean_pmd_entry(pmd_t *pmd) +{ + const unsigned int __tlb_flag = __cpu_tlb_flags; + + if (tlb_flag(TLB_DCLEAN)) + asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" + : : "r" (pmd) : "cc"); + + if (tlb_flag(TLB_L2CLEAN_FR)) + asm("mcr p15, 1, %0, c15, c9, 1 @ L2 flush_pmd" + : : "r" (pmd) : "cc"); +} + +#undef tlb_flag +#undef always_tlb_flags +#undef possible_tlb_flags + +/* + * Convert calls to our calling convention. + */ +#define local_flush_tlb_range(vma,start,end) __cpu_flush_user_tlb_range(start,end,vma) +#define local_flush_tlb_kernel_range(s,e) __cpu_flush_kern_tlb_range(s,e) + +#ifndef CONFIG_SMP +#define flush_tlb_all local_flush_tlb_all +#define flush_tlb_mm local_flush_tlb_mm +#define flush_tlb_page local_flush_tlb_page +#define flush_tlb_kernel_page local_flush_tlb_kernel_page +#define flush_tlb_range local_flush_tlb_range +#define flush_tlb_kernel_range local_flush_tlb_kernel_range +#else +extern void flush_tlb_all(void); +extern void flush_tlb_mm(struct mm_struct *mm); +extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr); +extern void flush_tlb_kernel_page(unsigned long kaddr); +extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); +extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); +#endif + +/* + * if PG_dcache_dirty is set for the page, we need to ensure that any + * cache entries for the kernels virtual memory range are written + * back to the page. + */ +extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte); + +#endif + +#endif /* CONFIG_MMU */ + +#endif diff --git a/include/asm-arm/topology.h b/arch/arm/include/asm/topology.h similarity index 100% rename from include/asm-arm/topology.h rename to arch/arm/include/asm/topology.h diff --git a/include/asm-arm/traps.h b/arch/arm/include/asm/traps.h similarity index 100% rename from include/asm-arm/traps.h rename to arch/arm/include/asm/traps.h diff --git a/include/asm-arm/types.h b/arch/arm/include/asm/types.h similarity index 100% rename from include/asm-arm/types.h rename to arch/arm/include/asm/types.h diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h new file mode 100644 index 0000000000000..d0f51ff900b5d --- /dev/null +++ b/arch/arm/include/asm/uaccess.h @@ -0,0 +1,444 @@ +/* + * arch/arm/include/asm/uaccess.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. + */ +#ifndef _ASMARM_UACCESS_H +#define _ASMARM_UACCESS_H + +/* + * User space memory access functions + */ +#include +#include +#include +#include +#include + +#define VERIFY_READ 0 +#define VERIFY_WRITE 1 + +/* + * The exception table consists of pairs of addresses: the first is the + * address of an instruction that is allowed to fault, and the second is + * the address at which the program should continue. No registers are + * modified, so it is entirely up to the continuation code to figure out + * what to do. + * + * All the routines below use bits of fixup code that are out of line + * with the main instruction path. This means when everything is well, + * we don't even have to jump over them. Further, they do not intrude + * on our cache or tlb entries. + */ + +struct exception_table_entry +{ + unsigned long insn, fixup; +}; + +extern int fixup_exception(struct pt_regs *regs); + +/* + * These two are intentionally not defined anywhere - if the kernel + * code generates any references to them, that's a bug. + */ +extern int __get_user_bad(void); +extern int __put_user_bad(void); + +/* + * Note that this is actually 0x1,0000,0000 + */ +#define KERNEL_DS 0x00000000 +#define get_ds() (KERNEL_DS) + +#ifdef CONFIG_MMU + +#define USER_DS TASK_SIZE +#define get_fs() (current_thread_info()->addr_limit) + +static inline void set_fs(mm_segment_t fs) +{ + current_thread_info()->addr_limit = fs; + modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER); +} + +#define segment_eq(a,b) ((a) == (b)) + +#define __addr_ok(addr) ({ \ + unsigned long flag; \ + __asm__("cmp %2, %0; movlo %0, #0" \ + : "=&r" (flag) \ + : "0" (current_thread_info()->addr_limit), "r" (addr) \ + : "cc"); \ + (flag == 0); }) + +/* We use 33-bit arithmetic here... */ +#define __range_ok(addr,size) ({ \ + unsigned long flag, roksum; \ + __chk_user_ptr(addr); \ + __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \ + : "=&r" (flag), "=&r" (roksum) \ + : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \ + : "cc"); \ + flag; }) + +/* + * Single-value transfer routines. They automatically use the right + * size if we just have the right pointer type. Note that the functions + * which read from user space (*get_*) need to take care not to leak + * kernel data even if the calling code is buggy and fails to check + * the return value. This means zeroing out the destination variable + * or buffer on error. Normally this is done out of line by the + * fixup code, but there are a few places where it intrudes on the + * main code path. When we only write to user space, there is no + * problem. + */ +extern int __get_user_1(void *); +extern int __get_user_2(void *); +extern int __get_user_4(void *); + +#define __get_user_x(__r2,__p,__e,__s,__i...) \ + __asm__ __volatile__ ( \ + __asmeq("%0", "r0") __asmeq("%1", "r2") \ + "bl __get_user_" #__s \ + : "=&r" (__e), "=r" (__r2) \ + : "0" (__p) \ + : __i, "cc") + +#define get_user(x,p) \ + ({ \ + register const typeof(*(p)) __user *__p asm("r0") = (p);\ + register unsigned long __r2 asm("r2"); \ + register int __e asm("r0"); \ + switch (sizeof(*(__p))) { \ + case 1: \ + __get_user_x(__r2, __p, __e, 1, "lr"); \ + break; \ + case 2: \ + __get_user_x(__r2, __p, __e, 2, "r3", "lr"); \ + break; \ + case 4: \ + __get_user_x(__r2, __p, __e, 4, "lr"); \ + break; \ + default: __e = __get_user_bad(); break; \ + } \ + x = (typeof(*(p))) __r2; \ + __e; \ + }) + +extern int __put_user_1(void *, unsigned int); +extern int __put_user_2(void *, unsigned int); +extern int __put_user_4(void *, unsigned int); +extern int __put_user_8(void *, unsigned long long); + +#define __put_user_x(__r2,__p,__e,__s) \ + __asm__ __volatile__ ( \ + __asmeq("%0", "r0") __asmeq("%2", "r2") \ + "bl __put_user_" #__s \ + : "=&r" (__e) \ + : "0" (__p), "r" (__r2) \ + : "ip", "lr", "cc") + +#define put_user(x,p) \ + ({ \ + register const typeof(*(p)) __r2 asm("r2") = (x); \ + register const typeof(*(p)) __user *__p asm("r0") = (p);\ + register int __e asm("r0"); \ + switch (sizeof(*(__p))) { \ + case 1: \ + __put_user_x(__r2, __p, __e, 1); \ + break; \ + case 2: \ + __put_user_x(__r2, __p, __e, 2); \ + break; \ + case 4: \ + __put_user_x(__r2, __p, __e, 4); \ + break; \ + case 8: \ + __put_user_x(__r2, __p, __e, 8); \ + break; \ + default: __e = __put_user_bad(); break; \ + } \ + __e; \ + }) + +#else /* CONFIG_MMU */ + +/* + * uClinux has only one addr space, so has simplified address limits. + */ +#define USER_DS KERNEL_DS + +#define segment_eq(a,b) (1) +#define __addr_ok(addr) (1) +#define __range_ok(addr,size) (0) +#define get_fs() (KERNEL_DS) + +static inline void set_fs(mm_segment_t fs) +{ +} + +#define get_user(x,p) __get_user(x,p) +#define put_user(x,p) __put_user(x,p) + +#endif /* CONFIG_MMU */ + +#define access_ok(type,addr,size) (__range_ok(addr,size) == 0) + +/* + * The "__xxx" versions of the user access functions do not verify the + * address space - it must have been done previously with a separate + * "access_ok()" call. + * + * The "xxx_error" versions set the third argument to EFAULT if an + * error occurs, and leave it unchanged on success. Note that these + * versions are void (ie, don't return a value as such). + */ +#define __get_user(x,ptr) \ +({ \ + long __gu_err = 0; \ + __get_user_err((x),(ptr),__gu_err); \ + __gu_err; \ +}) + +#define __get_user_error(x,ptr,err) \ +({ \ + __get_user_err((x),(ptr),err); \ + (void) 0; \ +}) + +#define __get_user_err(x,ptr,err) \ +do { \ + unsigned long __gu_addr = (unsigned long)(ptr); \ + unsigned long __gu_val; \ + __chk_user_ptr(ptr); \ + switch (sizeof(*(ptr))) { \ + case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \ + case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \ + case 4: __get_user_asm_word(__gu_val,__gu_addr,err); break; \ + default: (__gu_val) = __get_user_bad(); \ + } \ + (x) = (__typeof__(*(ptr)))__gu_val; \ +} while (0) + +#define __get_user_asm_byte(x,addr,err) \ + __asm__ __volatile__( \ + "1: ldrbt %1,[%2],#0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mov %0, %3\n" \ + " mov %1, #0\n" \ + " b 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "+r" (err), "=&r" (x) \ + : "r" (addr), "i" (-EFAULT) \ + : "cc") + +#ifndef __ARMEB__ +#define __get_user_asm_half(x,__gu_addr,err) \ +({ \ + unsigned long __b1, __b2; \ + __get_user_asm_byte(__b1, __gu_addr, err); \ + __get_user_asm_byte(__b2, __gu_addr + 1, err); \ + (x) = __b1 | (__b2 << 8); \ +}) +#else +#define __get_user_asm_half(x,__gu_addr,err) \ +({ \ + unsigned long __b1, __b2; \ + __get_user_asm_byte(__b1, __gu_addr, err); \ + __get_user_asm_byte(__b2, __gu_addr + 1, err); \ + (x) = (__b1 << 8) | __b2; \ +}) +#endif + +#define __get_user_asm_word(x,addr,err) \ + __asm__ __volatile__( \ + "1: ldrt %1,[%2],#0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mov %0, %3\n" \ + " mov %1, #0\n" \ + " b 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "+r" (err), "=&r" (x) \ + : "r" (addr), "i" (-EFAULT) \ + : "cc") + +#define __put_user(x,ptr) \ +({ \ + long __pu_err = 0; \ + __put_user_err((x),(ptr),__pu_err); \ + __pu_err; \ +}) + +#define __put_user_error(x,ptr,err) \ +({ \ + __put_user_err((x),(ptr),err); \ + (void) 0; \ +}) + +#define __put_user_err(x,ptr,err) \ +do { \ + unsigned long __pu_addr = (unsigned long)(ptr); \ + __typeof__(*(ptr)) __pu_val = (x); \ + __chk_user_ptr(ptr); \ + switch (sizeof(*(ptr))) { \ + case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \ + case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \ + case 4: __put_user_asm_word(__pu_val,__pu_addr,err); break; \ + case 8: __put_user_asm_dword(__pu_val,__pu_addr,err); break; \ + default: __put_user_bad(); \ + } \ +} while (0) + +#define __put_user_asm_byte(x,__pu_addr,err) \ + __asm__ __volatile__( \ + "1: strbt %1,[%2],#0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mov %0, %3\n" \ + " b 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "+r" (err) \ + : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ + : "cc") + +#ifndef __ARMEB__ +#define __put_user_asm_half(x,__pu_addr,err) \ +({ \ + unsigned long __temp = (unsigned long)(x); \ + __put_user_asm_byte(__temp, __pu_addr, err); \ + __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \ +}) +#else +#define __put_user_asm_half(x,__pu_addr,err) \ +({ \ + unsigned long __temp = (unsigned long)(x); \ + __put_user_asm_byte(__temp >> 8, __pu_addr, err); \ + __put_user_asm_byte(__temp, __pu_addr + 1, err); \ +}) +#endif + +#define __put_user_asm_word(x,__pu_addr,err) \ + __asm__ __volatile__( \ + "1: strt %1,[%2],#0\n" \ + "2:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "3: mov %0, %3\n" \ + " b 2b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 3b\n" \ + " .previous" \ + : "+r" (err) \ + : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ + : "cc") + +#ifndef __ARMEB__ +#define __reg_oper0 "%R2" +#define __reg_oper1 "%Q2" +#else +#define __reg_oper0 "%Q2" +#define __reg_oper1 "%R2" +#endif + +#define __put_user_asm_dword(x,__pu_addr,err) \ + __asm__ __volatile__( \ + "1: strt " __reg_oper1 ", [%1], #4\n" \ + "2: strt " __reg_oper0 ", [%1], #0\n" \ + "3:\n" \ + " .section .fixup,\"ax\"\n" \ + " .align 2\n" \ + "4: mov %0, %3\n" \ + " b 3b\n" \ + " .previous\n" \ + " .section __ex_table,\"a\"\n" \ + " .align 3\n" \ + " .long 1b, 4b\n" \ + " .long 2b, 4b\n" \ + " .previous" \ + : "+r" (err), "+r" (__pu_addr) \ + : "r" (x), "i" (-EFAULT) \ + : "cc") + + +#ifdef CONFIG_MMU +extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n); +extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n); +extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n); +#else +#define __copy_from_user(to,from,n) (memcpy(to, (void __force *)from, n), 0) +#define __copy_to_user(to,from,n) (memcpy((void __force *)to, from, n), 0) +#define __clear_user(addr,n) (memset((void __force *)addr, 0, n), 0) +#endif + +extern unsigned long __must_check __strncpy_from_user(char *to, const char __user *from, unsigned long count); +extern unsigned long __must_check __strnlen_user(const char __user *s, long n); + +static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) +{ + if (access_ok(VERIFY_READ, from, n)) + n = __copy_from_user(to, from, n); + else /* security hole - plug it */ + memzero(to, n); + return n; +} + +static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + n = __copy_to_user(to, from, n); + return n; +} + +#define __copy_to_user_inatomic __copy_to_user +#define __copy_from_user_inatomic __copy_from_user + +static inline unsigned long __must_check clear_user(void __user *to, unsigned long n) +{ + if (access_ok(VERIFY_WRITE, to, n)) + n = __clear_user(to, n); + return n; +} + +static inline long __must_check strncpy_from_user(char *dst, const char __user *src, long count) +{ + long res = -EFAULT; + if (access_ok(VERIFY_READ, src, 1)) + res = __strncpy_from_user(dst, src, count); + return res; +} + +#define strlen_user(s) strnlen_user(s, ~0UL >> 1) + +static inline long __must_check strnlen_user(const char __user *s, long n) +{ + unsigned long res = 0; + + if (__addr_ok(s)) + res = __strnlen_user(s, n); + + return res; +} + +#endif /* _ASMARM_UACCESS_H */ diff --git a/include/asm-arm/ucontext.h b/arch/arm/include/asm/ucontext.h similarity index 100% rename from include/asm-arm/ucontext.h rename to arch/arm/include/asm/ucontext.h diff --git a/include/asm-arm/unaligned.h b/arch/arm/include/asm/unaligned.h similarity index 100% rename from include/asm-arm/unaligned.h rename to arch/arm/include/asm/unaligned.h diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h new file mode 100644 index 0000000000000..f95fbb2fcb5ff --- /dev/null +++ b/arch/arm/include/asm/unistd.h @@ -0,0 +1,450 @@ +/* + * arch/arm/include/asm/unistd.h + * + * Copyright (C) 2001-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. + * + * Please forward _all_ changes to this file to rmk@arm.linux.org.uk, + * no matter what the change is. Thanks! + */ +#ifndef __ASM_ARM_UNISTD_H +#define __ASM_ARM_UNISTD_H + +#define __NR_OABI_SYSCALL_BASE 0x900000 + +#if defined(__thumb__) || defined(__ARM_EABI__) +#define __NR_SYSCALL_BASE 0 +#else +#define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE +#endif + +/* + * This file contains the system call numbers. + */ + +#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0) +#define __NR_exit (__NR_SYSCALL_BASE+ 1) +#define __NR_fork (__NR_SYSCALL_BASE+ 2) +#define __NR_read (__NR_SYSCALL_BASE+ 3) +#define __NR_write (__NR_SYSCALL_BASE+ 4) +#define __NR_open (__NR_SYSCALL_BASE+ 5) +#define __NR_close (__NR_SYSCALL_BASE+ 6) + /* 7 was sys_waitpid */ +#define __NR_creat (__NR_SYSCALL_BASE+ 8) +#define __NR_link (__NR_SYSCALL_BASE+ 9) +#define __NR_unlink (__NR_SYSCALL_BASE+ 10) +#define __NR_execve (__NR_SYSCALL_BASE+ 11) +#define __NR_chdir (__NR_SYSCALL_BASE+ 12) +#define __NR_time (__NR_SYSCALL_BASE+ 13) +#define __NR_mknod (__NR_SYSCALL_BASE+ 14) +#define __NR_chmod (__NR_SYSCALL_BASE+ 15) +#define __NR_lchown (__NR_SYSCALL_BASE+ 16) + /* 17 was sys_break */ + /* 18 was sys_stat */ +#define __NR_lseek (__NR_SYSCALL_BASE+ 19) +#define __NR_getpid (__NR_SYSCALL_BASE+ 20) +#define __NR_mount (__NR_SYSCALL_BASE+ 21) +#define __NR_umount (__NR_SYSCALL_BASE+ 22) +#define __NR_setuid (__NR_SYSCALL_BASE+ 23) +#define __NR_getuid (__NR_SYSCALL_BASE+ 24) +#define __NR_stime (__NR_SYSCALL_BASE+ 25) +#define __NR_ptrace (__NR_SYSCALL_BASE+ 26) +#define __NR_alarm (__NR_SYSCALL_BASE+ 27) + /* 28 was sys_fstat */ +#define __NR_pause (__NR_SYSCALL_BASE+ 29) +#define __NR_utime (__NR_SYSCALL_BASE+ 30) + /* 31 was sys_stty */ + /* 32 was sys_gtty */ +#define __NR_access (__NR_SYSCALL_BASE+ 33) +#define __NR_nice (__NR_SYSCALL_BASE+ 34) + /* 35 was sys_ftime */ +#define __NR_sync (__NR_SYSCALL_BASE+ 36) +#define __NR_kill (__NR_SYSCALL_BASE+ 37) +#define __NR_rename (__NR_SYSCALL_BASE+ 38) +#define __NR_mkdir (__NR_SYSCALL_BASE+ 39) +#define __NR_rmdir (__NR_SYSCALL_BASE+ 40) +#define __NR_dup (__NR_SYSCALL_BASE+ 41) +#define __NR_pipe (__NR_SYSCALL_BASE+ 42) +#define __NR_times (__NR_SYSCALL_BASE+ 43) + /* 44 was sys_prof */ +#define __NR_brk (__NR_SYSCALL_BASE+ 45) +#define __NR_setgid (__NR_SYSCALL_BASE+ 46) +#define __NR_getgid (__NR_SYSCALL_BASE+ 47) + /* 48 was sys_signal */ +#define __NR_geteuid (__NR_SYSCALL_BASE+ 49) +#define __NR_getegid (__NR_SYSCALL_BASE+ 50) +#define __NR_acct (__NR_SYSCALL_BASE+ 51) +#define __NR_umount2 (__NR_SYSCALL_BASE+ 52) + /* 53 was sys_lock */ +#define __NR_ioctl (__NR_SYSCALL_BASE+ 54) +#define __NR_fcntl (__NR_SYSCALL_BASE+ 55) + /* 56 was sys_mpx */ +#define __NR_setpgid (__NR_SYSCALL_BASE+ 57) + /* 58 was sys_ulimit */ + /* 59 was sys_olduname */ +#define __NR_umask (__NR_SYSCALL_BASE+ 60) +#define __NR_chroot (__NR_SYSCALL_BASE+ 61) +#define __NR_ustat (__NR_SYSCALL_BASE+ 62) +#define __NR_dup2 (__NR_SYSCALL_BASE+ 63) +#define __NR_getppid (__NR_SYSCALL_BASE+ 64) +#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65) +#define __NR_setsid (__NR_SYSCALL_BASE+ 66) +#define __NR_sigaction (__NR_SYSCALL_BASE+ 67) + /* 68 was sys_sgetmask */ + /* 69 was sys_ssetmask */ +#define __NR_setreuid (__NR_SYSCALL_BASE+ 70) +#define __NR_setregid (__NR_SYSCALL_BASE+ 71) +#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72) +#define __NR_sigpending (__NR_SYSCALL_BASE+ 73) +#define __NR_sethostname (__NR_SYSCALL_BASE+ 74) +#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75) +#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) /* Back compat 2GB limited rlimit */ +#define __NR_getrusage (__NR_SYSCALL_BASE+ 77) +#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78) +#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79) +#define __NR_getgroups (__NR_SYSCALL_BASE+ 80) +#define __NR_setgroups (__NR_SYSCALL_BASE+ 81) +#define __NR_select (__NR_SYSCALL_BASE+ 82) +#define __NR_symlink (__NR_SYSCALL_BASE+ 83) + /* 84 was sys_lstat */ +#define __NR_readlink (__NR_SYSCALL_BASE+ 85) +#define __NR_uselib (__NR_SYSCALL_BASE+ 86) +#define __NR_swapon (__NR_SYSCALL_BASE+ 87) +#define __NR_reboot (__NR_SYSCALL_BASE+ 88) +#define __NR_readdir (__NR_SYSCALL_BASE+ 89) +#define __NR_mmap (__NR_SYSCALL_BASE+ 90) +#define __NR_munmap (__NR_SYSCALL_BASE+ 91) +#define __NR_truncate (__NR_SYSCALL_BASE+ 92) +#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93) +#define __NR_fchmod (__NR_SYSCALL_BASE+ 94) +#define __NR_fchown (__NR_SYSCALL_BASE+ 95) +#define __NR_getpriority (__NR_SYSCALL_BASE+ 96) +#define __NR_setpriority (__NR_SYSCALL_BASE+ 97) + /* 98 was sys_profil */ +#define __NR_statfs (__NR_SYSCALL_BASE+ 99) +#define __NR_fstatfs (__NR_SYSCALL_BASE+100) + /* 101 was sys_ioperm */ +#define __NR_socketcall (__NR_SYSCALL_BASE+102) +#define __NR_syslog (__NR_SYSCALL_BASE+103) +#define __NR_setitimer (__NR_SYSCALL_BASE+104) +#define __NR_getitimer (__NR_SYSCALL_BASE+105) +#define __NR_stat (__NR_SYSCALL_BASE+106) +#define __NR_lstat (__NR_SYSCALL_BASE+107) +#define __NR_fstat (__NR_SYSCALL_BASE+108) + /* 109 was sys_uname */ + /* 110 was sys_iopl */ +#define __NR_vhangup (__NR_SYSCALL_BASE+111) + /* 112 was sys_idle */ +#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */ +#define __NR_wait4 (__NR_SYSCALL_BASE+114) +#define __NR_swapoff (__NR_SYSCALL_BASE+115) +#define __NR_sysinfo (__NR_SYSCALL_BASE+116) +#define __NR_ipc (__NR_SYSCALL_BASE+117) +#define __NR_fsync (__NR_SYSCALL_BASE+118) +#define __NR_sigreturn (__NR_SYSCALL_BASE+119) +#define __NR_clone (__NR_SYSCALL_BASE+120) +#define __NR_setdomainname (__NR_SYSCALL_BASE+121) +#define __NR_uname (__NR_SYSCALL_BASE+122) + /* 123 was sys_modify_ldt */ +#define __NR_adjtimex (__NR_SYSCALL_BASE+124) +#define __NR_mprotect (__NR_SYSCALL_BASE+125) +#define __NR_sigprocmask (__NR_SYSCALL_BASE+126) + /* 127 was sys_create_module */ +#define __NR_init_module (__NR_SYSCALL_BASE+128) +#define __NR_delete_module (__NR_SYSCALL_BASE+129) + /* 130 was sys_get_kernel_syms */ +#define __NR_quotactl (__NR_SYSCALL_BASE+131) +#define __NR_getpgid (__NR_SYSCALL_BASE+132) +#define __NR_fchdir (__NR_SYSCALL_BASE+133) +#define __NR_bdflush (__NR_SYSCALL_BASE+134) +#define __NR_sysfs (__NR_SYSCALL_BASE+135) +#define __NR_personality (__NR_SYSCALL_BASE+136) + /* 137 was sys_afs_syscall */ +#define __NR_setfsuid (__NR_SYSCALL_BASE+138) +#define __NR_setfsgid (__NR_SYSCALL_BASE+139) +#define __NR__llseek (__NR_SYSCALL_BASE+140) +#define __NR_getdents (__NR_SYSCALL_BASE+141) +#define __NR__newselect (__NR_SYSCALL_BASE+142) +#define __NR_flock (__NR_SYSCALL_BASE+143) +#define __NR_msync (__NR_SYSCALL_BASE+144) +#define __NR_readv (__NR_SYSCALL_BASE+145) +#define __NR_writev (__NR_SYSCALL_BASE+146) +#define __NR_getsid (__NR_SYSCALL_BASE+147) +#define __NR_fdatasync (__NR_SYSCALL_BASE+148) +#define __NR__sysctl (__NR_SYSCALL_BASE+149) +#define __NR_mlock (__NR_SYSCALL_BASE+150) +#define __NR_munlock (__NR_SYSCALL_BASE+151) +#define __NR_mlockall (__NR_SYSCALL_BASE+152) +#define __NR_munlockall (__NR_SYSCALL_BASE+153) +#define __NR_sched_setparam (__NR_SYSCALL_BASE+154) +#define __NR_sched_getparam (__NR_SYSCALL_BASE+155) +#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156) +#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157) +#define __NR_sched_yield (__NR_SYSCALL_BASE+158) +#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159) +#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160) +#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161) +#define __NR_nanosleep (__NR_SYSCALL_BASE+162) +#define __NR_mremap (__NR_SYSCALL_BASE+163) +#define __NR_setresuid (__NR_SYSCALL_BASE+164) +#define __NR_getresuid (__NR_SYSCALL_BASE+165) + /* 166 was sys_vm86 */ + /* 167 was sys_query_module */ +#define __NR_poll (__NR_SYSCALL_BASE+168) +#define __NR_nfsservctl (__NR_SYSCALL_BASE+169) +#define __NR_setresgid (__NR_SYSCALL_BASE+170) +#define __NR_getresgid (__NR_SYSCALL_BASE+171) +#define __NR_prctl (__NR_SYSCALL_BASE+172) +#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173) +#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174) +#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175) +#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176) +#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177) +#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178) +#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179) +#define __NR_pread64 (__NR_SYSCALL_BASE+180) +#define __NR_pwrite64 (__NR_SYSCALL_BASE+181) +#define __NR_chown (__NR_SYSCALL_BASE+182) +#define __NR_getcwd (__NR_SYSCALL_BASE+183) +#define __NR_capget (__NR_SYSCALL_BASE+184) +#define __NR_capset (__NR_SYSCALL_BASE+185) +#define __NR_sigaltstack (__NR_SYSCALL_BASE+186) +#define __NR_sendfile (__NR_SYSCALL_BASE+187) + /* 188 reserved */ + /* 189 reserved */ +#define __NR_vfork (__NR_SYSCALL_BASE+190) +#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) /* SuS compliant getrlimit */ +#define __NR_mmap2 (__NR_SYSCALL_BASE+192) +#define __NR_truncate64 (__NR_SYSCALL_BASE+193) +#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194) +#define __NR_stat64 (__NR_SYSCALL_BASE+195) +#define __NR_lstat64 (__NR_SYSCALL_BASE+196) +#define __NR_fstat64 (__NR_SYSCALL_BASE+197) +#define __NR_lchown32 (__NR_SYSCALL_BASE+198) +#define __NR_getuid32 (__NR_SYSCALL_BASE+199) +#define __NR_getgid32 (__NR_SYSCALL_BASE+200) +#define __NR_geteuid32 (__NR_SYSCALL_BASE+201) +#define __NR_getegid32 (__NR_SYSCALL_BASE+202) +#define __NR_setreuid32 (__NR_SYSCALL_BASE+203) +#define __NR_setregid32 (__NR_SYSCALL_BASE+204) +#define __NR_getgroups32 (__NR_SYSCALL_BASE+205) +#define __NR_setgroups32 (__NR_SYSCALL_BASE+206) +#define __NR_fchown32 (__NR_SYSCALL_BASE+207) +#define __NR_setresuid32 (__NR_SYSCALL_BASE+208) +#define __NR_getresuid32 (__NR_SYSCALL_BASE+209) +#define __NR_setresgid32 (__NR_SYSCALL_BASE+210) +#define __NR_getresgid32 (__NR_SYSCALL_BASE+211) +#define __NR_chown32 (__NR_SYSCALL_BASE+212) +#define __NR_setuid32 (__NR_SYSCALL_BASE+213) +#define __NR_setgid32 (__NR_SYSCALL_BASE+214) +#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215) +#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216) +#define __NR_getdents64 (__NR_SYSCALL_BASE+217) +#define __NR_pivot_root (__NR_SYSCALL_BASE+218) +#define __NR_mincore (__NR_SYSCALL_BASE+219) +#define __NR_madvise (__NR_SYSCALL_BASE+220) +#define __NR_fcntl64 (__NR_SYSCALL_BASE+221) + /* 222 for tux */ + /* 223 is unused */ +#define __NR_gettid (__NR_SYSCALL_BASE+224) +#define __NR_readahead (__NR_SYSCALL_BASE+225) +#define __NR_setxattr (__NR_SYSCALL_BASE+226) +#define __NR_lsetxattr (__NR_SYSCALL_BASE+227) +#define __NR_fsetxattr (__NR_SYSCALL_BASE+228) +#define __NR_getxattr (__NR_SYSCALL_BASE+229) +#define __NR_lgetxattr (__NR_SYSCALL_BASE+230) +#define __NR_fgetxattr (__NR_SYSCALL_BASE+231) +#define __NR_listxattr (__NR_SYSCALL_BASE+232) +#define __NR_llistxattr (__NR_SYSCALL_BASE+233) +#define __NR_flistxattr (__NR_SYSCALL_BASE+234) +#define __NR_removexattr (__NR_SYSCALL_BASE+235) +#define __NR_lremovexattr (__NR_SYSCALL_BASE+236) +#define __NR_fremovexattr (__NR_SYSCALL_BASE+237) +#define __NR_tkill (__NR_SYSCALL_BASE+238) +#define __NR_sendfile64 (__NR_SYSCALL_BASE+239) +#define __NR_futex (__NR_SYSCALL_BASE+240) +#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241) +#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242) +#define __NR_io_setup (__NR_SYSCALL_BASE+243) +#define __NR_io_destroy (__NR_SYSCALL_BASE+244) +#define __NR_io_getevents (__NR_SYSCALL_BASE+245) +#define __NR_io_submit (__NR_SYSCALL_BASE+246) +#define __NR_io_cancel (__NR_SYSCALL_BASE+247) +#define __NR_exit_group (__NR_SYSCALL_BASE+248) +#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249) +#define __NR_epoll_create (__NR_SYSCALL_BASE+250) +#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251) +#define __NR_epoll_wait (__NR_SYSCALL_BASE+252) +#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253) + /* 254 for set_thread_area */ + /* 255 for get_thread_area */ +#define __NR_set_tid_address (__NR_SYSCALL_BASE+256) +#define __NR_timer_create (__NR_SYSCALL_BASE+257) +#define __NR_timer_settime (__NR_SYSCALL_BASE+258) +#define __NR_timer_gettime (__NR_SYSCALL_BASE+259) +#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260) +#define __NR_timer_delete (__NR_SYSCALL_BASE+261) +#define __NR_clock_settime (__NR_SYSCALL_BASE+262) +#define __NR_clock_gettime (__NR_SYSCALL_BASE+263) +#define __NR_clock_getres (__NR_SYSCALL_BASE+264) +#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265) +#define __NR_statfs64 (__NR_SYSCALL_BASE+266) +#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267) +#define __NR_tgkill (__NR_SYSCALL_BASE+268) +#define __NR_utimes (__NR_SYSCALL_BASE+269) +#define __NR_arm_fadvise64_64 (__NR_SYSCALL_BASE+270) +#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271) +#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272) +#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273) +#define __NR_mq_open (__NR_SYSCALL_BASE+274) +#define __NR_mq_unlink (__NR_SYSCALL_BASE+275) +#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276) +#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277) +#define __NR_mq_notify (__NR_SYSCALL_BASE+278) +#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279) +#define __NR_waitid (__NR_SYSCALL_BASE+280) +#define __NR_socket (__NR_SYSCALL_BASE+281) +#define __NR_bind (__NR_SYSCALL_BASE+282) +#define __NR_connect (__NR_SYSCALL_BASE+283) +#define __NR_listen (__NR_SYSCALL_BASE+284) +#define __NR_accept (__NR_SYSCALL_BASE+285) +#define __NR_getsockname (__NR_SYSCALL_BASE+286) +#define __NR_getpeername (__NR_SYSCALL_BASE+287) +#define __NR_socketpair (__NR_SYSCALL_BASE+288) +#define __NR_send (__NR_SYSCALL_BASE+289) +#define __NR_sendto (__NR_SYSCALL_BASE+290) +#define __NR_recv (__NR_SYSCALL_BASE+291) +#define __NR_recvfrom (__NR_SYSCALL_BASE+292) +#define __NR_shutdown (__NR_SYSCALL_BASE+293) +#define __NR_setsockopt (__NR_SYSCALL_BASE+294) +#define __NR_getsockopt (__NR_SYSCALL_BASE+295) +#define __NR_sendmsg (__NR_SYSCALL_BASE+296) +#define __NR_recvmsg (__NR_SYSCALL_BASE+297) +#define __NR_semop (__NR_SYSCALL_BASE+298) +#define __NR_semget (__NR_SYSCALL_BASE+299) +#define __NR_semctl (__NR_SYSCALL_BASE+300) +#define __NR_msgsnd (__NR_SYSCALL_BASE+301) +#define __NR_msgrcv (__NR_SYSCALL_BASE+302) +#define __NR_msgget (__NR_SYSCALL_BASE+303) +#define __NR_msgctl (__NR_SYSCALL_BASE+304) +#define __NR_shmat (__NR_SYSCALL_BASE+305) +#define __NR_shmdt (__NR_SYSCALL_BASE+306) +#define __NR_shmget (__NR_SYSCALL_BASE+307) +#define __NR_shmctl (__NR_SYSCALL_BASE+308) +#define __NR_add_key (__NR_SYSCALL_BASE+309) +#define __NR_request_key (__NR_SYSCALL_BASE+310) +#define __NR_keyctl (__NR_SYSCALL_BASE+311) +#define __NR_semtimedop (__NR_SYSCALL_BASE+312) +#define __NR_vserver (__NR_SYSCALL_BASE+313) +#define __NR_ioprio_set (__NR_SYSCALL_BASE+314) +#define __NR_ioprio_get (__NR_SYSCALL_BASE+315) +#define __NR_inotify_init (__NR_SYSCALL_BASE+316) +#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+317) +#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+318) +#define __NR_mbind (__NR_SYSCALL_BASE+319) +#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320) +#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321) +#define __NR_openat (__NR_SYSCALL_BASE+322) +#define __NR_mkdirat (__NR_SYSCALL_BASE+323) +#define __NR_mknodat (__NR_SYSCALL_BASE+324) +#define __NR_fchownat (__NR_SYSCALL_BASE+325) +#define __NR_futimesat (__NR_SYSCALL_BASE+326) +#define __NR_fstatat64 (__NR_SYSCALL_BASE+327) +#define __NR_unlinkat (__NR_SYSCALL_BASE+328) +#define __NR_renameat (__NR_SYSCALL_BASE+329) +#define __NR_linkat (__NR_SYSCALL_BASE+330) +#define __NR_symlinkat (__NR_SYSCALL_BASE+331) +#define __NR_readlinkat (__NR_SYSCALL_BASE+332) +#define __NR_fchmodat (__NR_SYSCALL_BASE+333) +#define __NR_faccessat (__NR_SYSCALL_BASE+334) + /* 335 for pselect6 */ + /* 336 for ppoll */ +#define __NR_unshare (__NR_SYSCALL_BASE+337) +#define __NR_set_robust_list (__NR_SYSCALL_BASE+338) +#define __NR_get_robust_list (__NR_SYSCALL_BASE+339) +#define __NR_splice (__NR_SYSCALL_BASE+340) +#define __NR_arm_sync_file_range (__NR_SYSCALL_BASE+341) +#define __NR_sync_file_range2 __NR_arm_sync_file_range +#define __NR_tee (__NR_SYSCALL_BASE+342) +#define __NR_vmsplice (__NR_SYSCALL_BASE+343) +#define __NR_move_pages (__NR_SYSCALL_BASE+344) +#define __NR_getcpu (__NR_SYSCALL_BASE+345) + /* 346 for epoll_pwait */ +#define __NR_kexec_load (__NR_SYSCALL_BASE+347) +#define __NR_utimensat (__NR_SYSCALL_BASE+348) +#define __NR_signalfd (__NR_SYSCALL_BASE+349) +#define __NR_timerfd_create (__NR_SYSCALL_BASE+350) +#define __NR_eventfd (__NR_SYSCALL_BASE+351) +#define __NR_fallocate (__NR_SYSCALL_BASE+352) +#define __NR_timerfd_settime (__NR_SYSCALL_BASE+353) +#define __NR_timerfd_gettime (__NR_SYSCALL_BASE+354) + +/* + * The following SWIs are ARM private. + */ +#define __ARM_NR_BASE (__NR_SYSCALL_BASE+0x0f0000) +#define __ARM_NR_breakpoint (__ARM_NR_BASE+1) +#define __ARM_NR_cacheflush (__ARM_NR_BASE+2) +#define __ARM_NR_usr26 (__ARM_NR_BASE+3) +#define __ARM_NR_usr32 (__ARM_NR_BASE+4) +#define __ARM_NR_set_tls (__ARM_NR_BASE+5) + +/* + * The following syscalls are obsolete and no longer available for EABI. + */ +#if defined(__ARM_EABI__) && !defined(__KERNEL__) +#undef __NR_time +#undef __NR_umount +#undef __NR_stime +#undef __NR_alarm +#undef __NR_utime +#undef __NR_getrlimit +#undef __NR_select +#undef __NR_readdir +#undef __NR_mmap +#undef __NR_socketcall +#undef __NR_syscall +#undef __NR_ipc +#endif + +#ifdef __KERNEL__ + +#define __ARCH_WANT_IPC_PARSE_VERSION +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_GETHOSTNAME +#define __ARCH_WANT_SYS_PAUSE +#define __ARCH_WANT_SYS_GETPGRP +#define __ARCH_WANT_SYS_LLSEEK +#define __ARCH_WANT_SYS_NICE +#define __ARCH_WANT_SYS_SIGPENDING +#define __ARCH_WANT_SYS_SIGPROCMASK +#define __ARCH_WANT_SYS_RT_SIGACTION + +#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT) +#define __ARCH_WANT_SYS_TIME +#define __ARCH_WANT_SYS_OLDUMOUNT +#define __ARCH_WANT_SYS_ALARM +#define __ARCH_WANT_SYS_UTIME +#define __ARCH_WANT_SYS_OLD_GETRLIMIT +#define __ARCH_WANT_OLD_READDIR +#define __ARCH_WANT_SYS_SOCKETCALL +#endif + +/* + * "Conditional" syscalls + * + * What we want is __attribute__((weak,alias("sys_ni_syscall"))), + * but it doesn't work on all toolchains, so we just do it by hand + */ +#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") + +/* + * Unimplemented (or alternatively implemented) syscalls + */ +#define __IGNORE_fadvise64_64 1 + +#endif /* __KERNEL__ */ +#endif /* __ASM_ARM_UNISTD_H */ diff --git a/include/asm-arm/user.h b/arch/arm/include/asm/user.h similarity index 100% rename from include/asm-arm/user.h rename to arch/arm/include/asm/user.h diff --git a/include/asm-arm/vfp.h b/arch/arm/include/asm/vfp.h similarity index 98% rename from include/asm-arm/vfp.h rename to arch/arm/include/asm/vfp.h index 5f9a2cb3d452f..f4ab34fd4f72c 100644 --- a/include/asm-arm/vfp.h +++ b/arch/arm/include/asm/vfp.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/vfp.h + * arch/arm/include/asm/vfp.h * * VFP register definitions. * First, the standard VFP set. diff --git a/include/asm-arm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h similarity index 97% rename from include/asm-arm/vfpmacros.h rename to arch/arm/include/asm/vfpmacros.h index cccb3892e73c0..422f3cc204a27 100644 --- a/include/asm-arm/vfpmacros.h +++ b/arch/arm/include/asm/vfpmacros.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/vfpmacros.h + * arch/arm/include/asm/vfpmacros.h * * Assembler-only file containing VFP macros and register definitions. */ diff --git a/arch/arm/include/asm/vga.h b/arch/arm/include/asm/vga.h new file mode 100644 index 0000000000000..6a3cd2a2f6700 --- /dev/null +++ b/arch/arm/include/asm/vga.h @@ -0,0 +1,12 @@ +#ifndef ASMARM_VGA_H +#define ASMARM_VGA_H + +#include +#include + +#define VGA_MAP_MEM(x,s) (PCIMEM_BASE + (x)) + +#define vga_readb(x) (*((volatile unsigned char *)x)) +#define vga_writeb(x,y) (*((volatile unsigned char *)y) = (x)) + +#endif diff --git a/arch/arm/include/asm/xor.h b/arch/arm/include/asm/xor.h new file mode 100644 index 0000000000000..7604673dc4278 --- /dev/null +++ b/arch/arm/include/asm/xor.h @@ -0,0 +1,141 @@ +/* + * arch/arm/include/asm/xor.h + * + * Copyright (C) 2001 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 + +#define __XOR(a1, a2) a1 ^= a2 + +#define GET_BLOCK_2(dst) \ + __asm__("ldmia %0, {%1, %2}" \ + : "=r" (dst), "=r" (a1), "=r" (a2) \ + : "0" (dst)) + +#define GET_BLOCK_4(dst) \ + __asm__("ldmia %0, {%1, %2, %3, %4}" \ + : "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \ + : "0" (dst)) + +#define XOR_BLOCK_2(src) \ + __asm__("ldmia %0!, {%1, %2}" \ + : "=r" (src), "=r" (b1), "=r" (b2) \ + : "0" (src)); \ + __XOR(a1, b1); __XOR(a2, b2); + +#define XOR_BLOCK_4(src) \ + __asm__("ldmia %0!, {%1, %2, %3, %4}" \ + : "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \ + : "0" (src)); \ + __XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4) + +#define PUT_BLOCK_2(dst) \ + __asm__ __volatile__("stmia %0!, {%2, %3}" \ + : "=r" (dst) \ + : "0" (dst), "r" (a1), "r" (a2)) + +#define PUT_BLOCK_4(dst) \ + __asm__ __volatile__("stmia %0!, {%2, %3, %4, %5}" \ + : "=r" (dst) \ + : "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4)) + +static void +xor_arm4regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) +{ + unsigned int lines = bytes / sizeof(unsigned long) / 4; + register unsigned int a1 __asm__("r4"); + register unsigned int a2 __asm__("r5"); + register unsigned int a3 __asm__("r6"); + register unsigned int a4 __asm__("r7"); + register unsigned int b1 __asm__("r8"); + register unsigned int b2 __asm__("r9"); + register unsigned int b3 __asm__("ip"); + register unsigned int b4 __asm__("lr"); + + do { + GET_BLOCK_4(p1); + XOR_BLOCK_4(p2); + PUT_BLOCK_4(p1); + } while (--lines); +} + +static void +xor_arm4regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3) +{ + unsigned int lines = bytes / sizeof(unsigned long) / 4; + register unsigned int a1 __asm__("r4"); + register unsigned int a2 __asm__("r5"); + register unsigned int a3 __asm__("r6"); + register unsigned int a4 __asm__("r7"); + register unsigned int b1 __asm__("r8"); + register unsigned int b2 __asm__("r9"); + register unsigned int b3 __asm__("ip"); + register unsigned int b4 __asm__("lr"); + + do { + GET_BLOCK_4(p1); + XOR_BLOCK_4(p2); + XOR_BLOCK_4(p3); + PUT_BLOCK_4(p1); + } while (--lines); +} + +static void +xor_arm4regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3, unsigned long *p4) +{ + unsigned int lines = bytes / sizeof(unsigned long) / 2; + register unsigned int a1 __asm__("r8"); + register unsigned int a2 __asm__("r9"); + register unsigned int b1 __asm__("ip"); + register unsigned int b2 __asm__("lr"); + + do { + GET_BLOCK_2(p1); + XOR_BLOCK_2(p2); + XOR_BLOCK_2(p3); + XOR_BLOCK_2(p4); + PUT_BLOCK_2(p1); + } while (--lines); +} + +static void +xor_arm4regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, + unsigned long *p3, unsigned long *p4, unsigned long *p5) +{ + unsigned int lines = bytes / sizeof(unsigned long) / 2; + register unsigned int a1 __asm__("r8"); + register unsigned int a2 __asm__("r9"); + register unsigned int b1 __asm__("ip"); + register unsigned int b2 __asm__("lr"); + + do { + GET_BLOCK_2(p1); + XOR_BLOCK_2(p2); + XOR_BLOCK_2(p3); + XOR_BLOCK_2(p4); + XOR_BLOCK_2(p5); + PUT_BLOCK_2(p1); + } while (--lines); +} + +static struct xor_block_template xor_block_arm4regs = { + .name = "arm4regs", + .do_2 = xor_arm4regs_2, + .do_3 = xor_arm4regs_3, + .do_4 = xor_arm4regs_4, + .do_5 = xor_arm4regs_5, +}; + +#undef XOR_TRY_TEMPLATES +#define XOR_TRY_TEMPLATES \ + do { \ + xor_speed(&xor_block_arm4regs); \ + xor_speed(&xor_block_8regs); \ + xor_speed(&xor_block_32regs); \ + } while (0) diff --git a/arch/arm/kernel/crunch-bits.S b/arch/arm/kernel/crunch-bits.S index a26886758c673..0ec9bb48fab9c 100644 --- a/arch/arm/kernel/crunch-bits.S +++ b/arch/arm/kernel/crunch-bits.S @@ -16,7 +16,7 @@ #include #include #include -#include +#include /* * We can't use hex constants here due to a bug in gas. diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c index 627d79414c9d6..3b6a1c293ee49 100644 --- a/arch/arm/kernel/crunch.c +++ b/arch/arm/kernel/crunch.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index 5617566477b49..9550ff0ddde4f 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -80,7 +80,7 @@ #endif /* CONFIG_CPU_V6 */ #else -#include +#include #endif /* CONFIG_DEBUG_ICEDCC */ /* diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index f5cfdabcb87dc..7a50575a8d4db 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -46,7 +46,7 @@ #include #include -#include +#include #include #include #include diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 7dca225752c1c..617e509d60dfd 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include "entry-header.S" diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 84694e88b4289..060d7e2e9f640 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -10,7 +10,7 @@ #include #include -#include +#include #include "entry-header.S" diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S index 7e9c00a8a4127..1c3c6ea5f9e7e 100644 --- a/arch/arm/kernel/head-common.S +++ b/arch/arm/kernel/head-common.S @@ -181,7 +181,7 @@ ENTRY(lookup_processor_type) ldmfd sp!, {r4 - r7, r9, pc} /* - * Look in include/asm-arm/procinfo.h and arch/arm/kernel/arch.[ch] for + * Look in and arch/arm/kernel/arch.[ch] for * more information about the __proc_info and __arch_info structures. */ .long __proc_info_begin diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index 5d78ffb8a9a7f..27329bd32037a 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 11dcd52e51be3..f88efb135b702 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -38,6 +38,7 @@ #include #include +#include #include /* diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 89bfded70a1f4..3fd8823370641 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -51,7 +51,7 @@ extern void setup_mm_for_reboot(char mode); static volatile int hlt_counter; -#include +#include void disable_hlt(void) { diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 5a7c09564d134..e9842f6767f95 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -100,7 +100,7 @@ int __cpuinit __cpu_up(unsigned int cpu) * a 1:1 mapping for the physical address of the kernel. */ pgd = pgd_alloc(&init_mm); - pmd = pmd_offset(pgd, PHYS_OFFSET); + pmd = pmd_offset(pgd + pgd_index(PHYS_OFFSET), PHYS_OFFSET); *pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) | PMD_TYPE_SECT | PMD_SECT_AP_WRITE); @@ -139,7 +139,7 @@ int __cpuinit __cpu_up(unsigned int cpu) secondary_data.stack = NULL; secondary_data.pgdir = 0; - *pmd_offset(pgd, PHYS_OFFSET) = __pmd(0); + *pmd = __pmd(0); pgd_free(&init_mm, pgd); if (ret) { diff --git a/arch/arm/lib/ecard.S b/arch/arm/lib/ecard.S index c55aaa2a2088b..8678eb2b7a60a 100644 --- a/arch/arm/lib/ecard.S +++ b/arch/arm/lib/ecard.S @@ -12,7 +12,7 @@ */ #include #include -#include +#include #define CPSR2SPSR(rt) \ mrs rt, cpsr; \ diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S index 1dd8ea4f9a9c5..2034d4dbe6ad3 100644 --- a/arch/arm/lib/getuser.S +++ b/arch/arm/lib/getuser.S @@ -20,7 +20,7 @@ * r2, r3 contains the zero-extended value * lr corrupted * - * No other registers must be altered. (see include/asm-arm/uaccess.h + * No other registers must be altered. (see * for specific ASM register usage). * * Note that ADDR_LIMIT is either 0 or 0xc0000000. diff --git a/arch/arm/lib/io-readsw-armv3.S b/arch/arm/lib/io-readsw-armv3.S index 4ef9041851423..9aaf7c72065d8 100644 --- a/arch/arm/lib/io-readsw-armv3.S +++ b/arch/arm/lib/io-readsw-armv3.S @@ -9,7 +9,7 @@ */ #include #include -#include +#include .Linsw_bad_alignment: adr r0, .Linsw_bad_align_msg diff --git a/arch/arm/lib/io-writesw-armv3.S b/arch/arm/lib/io-writesw-armv3.S index 1607a29f49b71..cd34503e424d6 100644 --- a/arch/arm/lib/io-writesw-armv3.S +++ b/arch/arm/lib/io-writesw-armv3.S @@ -9,7 +9,7 @@ */ #include #include -#include +#include .Loutsw_bad_alignment: adr r0, .Loutsw_bad_align_msg diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S index 8620afe54f720..08ec7dffa52e4 100644 --- a/arch/arm/lib/putuser.S +++ b/arch/arm/lib/putuser.S @@ -20,7 +20,7 @@ * Outputs: r0 is the error code * lr corrupted * - * No other registers must be altered. (see include/asm-arm/uaccess.h + * No other registers must be altered. (see * for specific ASM register usage). * * Note that ADDR_LIMIT is either 0 or 0xc0000000 diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c index 83f57da3184cc..81a3ecc0d104d 100644 --- a/arch/arm/mach-aaec2000/aaed2000.c +++ b/arch/arm/mach-aaec2000/aaed2000.c @@ -20,14 +20,14 @@ #include #include #include -#include +#include #include #include #include #include -#include +#include #include "core.h" diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index b016be2b0e353..dfb26bc23d1a8 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include diff --git a/include/asm-arm/arch-aaec2000/aaec2000.h b/arch/arm/mach-aaec2000/include/mach/aaec2000.h similarity index 99% rename from include/asm-arm/arch-aaec2000/aaec2000.h rename to arch/arm/mach-aaec2000/include/mach/aaec2000.h index a6d1ee0980f21..bc729c42f8437 100644 --- a/include/asm-arm/arch-aaec2000/aaec2000.h +++ b/arch/arm/mach-aaec2000/include/mach/aaec2000.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/arch-aaec2000/aaec2000.h + * arch/arm/mach-aaec2000/include/mach/aaec2000.h * * AAEC-2000 registers definition * diff --git a/include/asm-arm/arch-aaec2000/aaed2000.h b/arch/arm/mach-aaec2000/include/mach/aaed2000.h similarity index 96% rename from include/asm-arm/arch-aaec2000/aaed2000.h rename to arch/arm/mach-aaec2000/include/mach/aaed2000.h index bc76d2badb91f..f821295ca71bb 100644 --- a/include/asm-arm/arch-aaec2000/aaed2000.h +++ b/arch/arm/mach-aaec2000/include/mach/aaed2000.h @@ -1,5 +1,5 @@ /* - * linux/include/asm-arm/arch-aaec2000/aaed2000.h + * arch/arm/mach-aaec2000/include/mach/aaed2000.h * * AAED-2000 specific bits definition * diff --git a/arch/arm/mach-aaec2000/include/mach/debug-macro.S b/arch/arm/mach-aaec2000/include/mach/debug-macro.S new file mode 100644 index 0000000000000..0b6351d7c3897 --- /dev/null +++ b/arch/arm/mach-aaec2000/include/mach/debug-macro.S @@ -0,0 +1,37 @@ +/* arch/arm/mach-aaec2000/include/mach/debug-macro.S + * + * Debugging macro include header + * + * Copyright (c) 2005 Nicolas Bellido Y Ortega + * + * 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 "hardware.h" + .macro addruart,rx + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + moveq \rx, #0x80000000 @ physical + movne \rx, #io_p2v(0x80000000) @ virtual + orr \rx, \rx, #0x00000800 + .endm + + .macro senduart,rd,rx + str \rd, [\rx, #0] + .endm + + .macro busyuart,rd,rx +1002: ldr \rd, [\rx, #0x10] + tst \rd, #(1 << 7) + beq 1002b + .endm + + .macro waituart,rd,rx +#if 0 +1001: ldr \rd, [\rx, #0x10] + tst \rd, #(1 << 5) + beq 1001b +#endif + .endm diff --git a/arch/arm/mach-aaec2000/include/mach/dma.h b/arch/arm/mach-aaec2000/include/mach/dma.h new file mode 100644 index 0000000000000..2da846c72fe73 --- /dev/null +++ b/arch/arm/mach-aaec2000/include/mach/dma.h @@ -0,0 +1,9 @@ +/* + * arch/arm/mach-aaec2000/include/mach/dma.h + * + * Copyright (c) 2005 Nicolas Bellido Y Ortega + * + * 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. + */ diff --git a/arch/arm/mach-aaec2000/include/mach/entry-macro.S b/arch/arm/mach-aaec2000/include/mach/entry-macro.S new file mode 100644 index 0000000000000..c8fb344690079 --- /dev/null +++ b/arch/arm/mach-aaec2000/include/mach/entry-macro.S @@ -0,0 +1,40 @@ +/* + * arch/arm/mach-aaec2000/include/mach/entry-macro.S + * + * Low-level IRQ helper for aaec-2000 based platforms + * + * Copyright (c) 2005 Nicolas Bellido Y Ortega + * + * 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 + + .macro disable_fiq + .endm + + .macro get_irqnr_preamble, base, tmp + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + mov r4, #0xf8000000 + add r4, r4, #0x00000500 + mov \base, r4 + ldr \irqstat, [\base, #0] + cmp \irqstat, #0 + bne 1001f + ldr \irqnr, =NR_IRQS+1 + b 1003f +1001: mov \irqnr, #0 +1002: ands \tmp, \irqstat, #1 + mov \irqstat, \irqstat, LSR #1 + add \irqnr, \irqnr, #1 + beq 1002b + sub \irqnr, \irqnr, #1 +1003: + .endm diff --git a/arch/arm/mach-aaec2000/include/mach/hardware.h b/arch/arm/mach-aaec2000/include/mach/hardware.h new file mode 100644 index 0000000000000..965a6f6672d64 --- /dev/null +++ b/arch/arm/mach-aaec2000/include/mach/hardware.h @@ -0,0 +1,50 @@ +/* + * arch/arm/mach-aaec2000/include/mach/hardware.h + * + * Copyright (c) 2005 Nicolas Bellido Y Ortega + * + * 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. + */ + +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include +#include + +/* The kernel is loaded at physical address 0xf8000000. + * We map the IO space a bit after + */ +#define PIO_APB_BASE 0x80000000 +#define VIO_APB_BASE 0xf8000000 +#define IO_APB_LENGTH 0x2000 +#define PIO_AHB_BASE 0x80002000 +#define VIO_AHB_BASE 0xf8002000 +#define IO_AHB_LENGTH 0x2000 + +#define VIO_BASE VIO_APB_BASE +#define PIO_BASE PIO_APB_BASE + +#define io_p2v(x) ( (x) - PIO_BASE + VIO_BASE ) +#define io_v2p(x) ( (x) + PIO_BASE - VIO_BASE ) + +#ifndef __ASSEMBLY__ + +#include + +/* FIXME: Is it needed to optimize this a la pxa ?? */ +#define __REG(x) (*((volatile u32 *)io_p2v(x))) +#define __PREG(x) (io_v2p((u32)&(x))) + +#else /* __ASSEMBLY__ */ + +#define __REG(x) io_p2v(x) +#define __PREG(x) io_v2p(x) + +#endif + +#include "aaec2000.h" + +#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-aaec2000/include/mach/io.h b/arch/arm/mach-aaec2000/include/mach/io.h new file mode 100644 index 0000000000000..c87c24de1110b --- /dev/null +++ b/arch/arm/mach-aaec2000/include/mach/io.h @@ -0,0 +1,20 @@ +/* + * arch/arm/mach-aaec2000/include/mach/io.h + * + * Copied from asm/arch/sa1100/io.h + */ +#ifndef __ASM_ARM_ARCH_IO_H +#define __ASM_ARM_ARCH_IO_H + +#include + +#define IO_SPACE_LIMIT 0xffffffff + +/* + * We don't actually have real ISA nor PCI buses, but there is so many + * drivers out there that might just work if we fake them... + */ +#define __io(a) ((void __iomem *)(a)) +#define __mem_pci(a) (a) + +#endif diff --git a/arch/arm/mach-aaec2000/include/mach/irqs.h b/arch/arm/mach-aaec2000/include/mach/irqs.h new file mode 100644 index 0000000000000..bf45c6d2f294f --- /dev/null +++ b/arch/arm/mach-aaec2000/include/mach/irqs.h @@ -0,0 +1,46 @@ +/* + * arch/arm/mach-aaec2000/include/mach/irqs.h + * + * Copyright (c) 2005 Nicolas Bellido Y Ortega + * + * 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. + */ + +#ifndef __ASM_ARCH_IRQS_H +#define __ASM_ARCH_IRQS_H + + +#define INT_GPIOF0_FIQ 0 /* External GPIO Port F O Fast Interrupt Input */ +#define INT_BL_FIQ 1 /* Battery Low Fast Interrupt */ +#define INT_WE_FIQ 2 /* Watchdog Expired Fast Interrupt */ +#define INT_MV_FIQ 3 /* Media Changed Interrupt */ +#define INT_SC 4 /* Sound Codec Interrupt */ +#define INT_GPIO1 5 /* GPIO Port F Configurable Int 1 */ +#define INT_GPIO2 6 /* GPIO Port F Configurable Int 2 */ +#define INT_GPIO3 7 /* GPIO Port F Configurable Int 3 */ +#define INT_TMR1_OFL 8 /* Timer 1 Overflow Interrupt */ +#define INT_TMR2_OFL 9 /* Timer 2 Overflow Interrupt */ +#define INT_RTC_CM 10 /* RTC Compare Match Interrupt */ +#define INT_TICK 11 /* 64Hz Tick Interrupt */ +#define INT_UART1 12 /* UART1 Interrupt */ +#define INT_UART2 13 /* UART2 & Modem State Changed Interrupt */ +#define INT_LCD 14 /* LCD Interrupt */ +#define INT_SSI 15 /* SSI End of Transfer Interrupt */ +#define INT_UART3 16 /* UART3 Interrupt */ +#define INT_SCI 17 /* SCI Interrupt */ +#define INT_AAC 18 /* Advanced Audio Codec Interrupt */ +#define INT_MMC 19 /* MMC Interrupt */ +#define INT_USB 20 /* USB Interrupt */ +#define INT_DMA 21 /* DMA Interrupt */ +#define INT_TMR3_UOFL 22 /* Timer 3 Underflow Interrupt */ +#define INT_GPIO4 23 /* GPIO Port F Configurable Int 4 */ +#define INT_GPIO5 24 /* GPIO Port F Configurable Int 4 */ +#define INT_GPIO6 25 /* GPIO Port F Configurable Int 4 */ +#define INT_GPIO7 26 /* GPIO Port F Configurable Int 4 */ +#define INT_BMI 27 /* BMI Interrupt */ + +#define NR_IRQS (INT_BMI + 1) + +#endif /* __ASM_ARCH_IRQS_H */ diff --git a/arch/arm/mach-aaec2000/include/mach/memory.h b/arch/arm/mach-aaec2000/include/mach/memory.h new file mode 100644 index 0000000000000..56ae900a482e2 --- /dev/null +++ b/arch/arm/mach-aaec2000/include/mach/memory.h @@ -0,0 +1,30 @@ +/* + * arch/arm/mach-aaec2000/include/mach/memory.h + * + * Copyright (c) 2005 Nicolas Bellido Y Ortega + * + * 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. + */ + +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + + +#define PHYS_OFFSET UL(0xf0000000) + +#define __virt_to_bus(x) __virt_to_phys(x) +#define __bus_to_virt(x) __phys_to_virt(x) + +/* + * The nodes are the followings: + * + * node 0: 0xf000.0000 - 0xf3ff.ffff + * node 1: 0xf400.0000 - 0xf7ff.ffff + * node 2: 0xf800.0000 - 0xfbff.ffff + * node 3: 0xfc00.0000 - 0xffff.ffff + */ +#define NODE_MEM_SIZE_BITS 26 + +#endif /* __ASM_ARCH_MEMORY_H */ diff --git a/arch/arm/mach-aaec2000/include/mach/system.h b/arch/arm/mach-aaec2000/include/mach/system.h new file mode 100644 index 0000000000000..8f4115d734ce1 --- /dev/null +++ b/arch/arm/mach-aaec2000/include/mach/system.h @@ -0,0 +1,24 @@ +/* + * arch/arm/mach-aaed2000/include/mach/system.h + * + * Copyright (c) 2005 Nicolas Bellido Y Ortega + * + * 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. + */ + +#ifndef __ASM_ARCH_SYSTEM_H +#define __ASM_ARCH_SYSTEM_H + +static inline void arch_idle(void) +{ + cpu_do_idle(); +} + +static inline void arch_reset(char mode) +{ + cpu_reset(0); +} + +#endif /* __ASM_ARCH_SYSTEM_H */ diff --git a/arch/arm/mach-aaec2000/include/mach/timex.h b/arch/arm/mach-aaec2000/include/mach/timex.h new file mode 100644 index 0000000000000..6c8edf4a8828a --- /dev/null +++ b/arch/arm/mach-aaec2000/include/mach/timex.h @@ -0,0 +1,18 @@ +/* + * arch/arm/mach-aaec2000/include/mach/timex.h + * + * AAEC-2000 Architecture timex specification + * + * Copyright (c) 2005 Nicolas Bellido Y Ortega + * + * 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. + */ + +#ifndef __ASM_ARCH_TIMEX_H +#define __ASM_ARCH_TIMEX_H + +#define CLOCK_TICK_RATE 508000 + +#endif /* __ASM_ARCH_TIMEX_H */ diff --git a/arch/arm/mach-aaec2000/include/mach/uncompress.h b/arch/arm/mach-aaec2000/include/mach/uncompress.h new file mode 100644 index 0000000000000..381ecad1a1bba --- /dev/null +++ b/arch/arm/mach-aaec2000/include/mach/uncompress.h @@ -0,0 +1,46 @@ +/* + * arch/arm/mach-aaec2000/include/mach/uncompress.h + * + * Copyright (c) 2005 Nicolas Bellido Y Ortega + * + * 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. + */ + +#ifndef __ASM_ARCH_UNCOMPRESS_H +#define __ASM_ARCH_UNCOMPRESS_H + +#include "hardware.h" + +#define UART(x) (*(volatile unsigned long *)(serial_port + (x))) + +static void putc(int c) +{ + unsigned long serial_port; + do { + serial_port = _UART3_BASE; + if (UART(UART_CR) & UART_CR_EN) break; + serial_port = _UART1_BASE; + if (UART(UART_CR) & UART_CR_EN) break; + serial_port = _UART2_BASE; + if (UART(UART_CR) & UART_CR_EN) break; + return; + } while (0); + + /* wait for space in the UART's transmitter */ + while ((UART(UART_SR) & UART_SR_TxFF)) + barrier(); + + /* send the character out. */ + UART(UART_DR) = c; +} + +static inline void flush(void) +{ +} + +#define arch_decomp_setup() +#define arch_decomp_wdog() + +#endif /* __ASM_ARCH_UNCOMPRESS_H */ diff --git a/arch/arm/mach-aaec2000/include/mach/vmalloc.h b/arch/arm/mach-aaec2000/include/mach/vmalloc.h new file mode 100644 index 0000000000000..551f68f666bf0 --- /dev/null +++ b/arch/arm/mach-aaec2000/include/mach/vmalloc.h @@ -0,0 +1,16 @@ +/* + * arch/arm/mach-aaec2000/include/mach/vmalloc.h + * + * Copyright (c) 2005 Nicolas Bellido Y Ortega + * + * 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. + */ + +#ifndef __ASM_ARCH_VMALLOC_H +#define __ASM_ARCH_VMALLOC_H + +#define VMALLOC_END (PAGE_OFFSET + 0x10000000) + +#endif /* __ASM_ARCH_VMALLOC_H */ diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 5bad6b9b00d77..a048b92cb4079 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -297,7 +297,7 @@ config MTD_AT91_DATAFLASH_CARD help Enable support for the DataFlash card. -config MTD_NAND_AT91_BUSWIDTH_16 +config MTD_NAND_ATMEL_BUSWIDTH_16 bool "Enable 16-bit data bus interface to NAND flash" depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK || MACH_AT91SAM9G20EK || MACH_AT91CAP9ADK) help diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c index 933fa8f55cbc7..638948c16770e 100644 --- a/arch/arm/mach-at91/at91cap9.c +++ b/arch/arm/mach-at91/at91cap9.c @@ -17,10 +17,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include "generic.h" #include "clock.h" diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c index dc8b40783d942..abb4aac8fa983 100644 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ b/arch/arm/mach-at91/at91cap9_devices.c @@ -20,11 +20,11 @@ #include