diff options
| author | Len Brown <len.brown@intel.com> | 2004-11-08 05:19:37 -0500 |
|---|---|---|
| committer | Len Brown <len.brown@intel.com> | 2004-11-08 05:19:37 -0500 |
| commit | dad99cb437e463e628e406c7c1cf2d90661abe77 (patch) | |
| tree | 0050dcba3b43e49661c61aa075dcae896f04e8c8 | |
| parent | 272dacf79cd9b36957c49b70337462b131fb293a (diff) | |
| parent | f199195e181f3c004e7a7a1b7ebfd7707c4e3e2a (diff) | |
Merge
359 files changed, 8708 insertions, 6420 deletions
diff --git a/Documentation/DocBook/procfs-guide.tmpl b/Documentation/DocBook/procfs-guide.tmpl index 669b0466a701..34206230c719 100644 --- a/Documentation/DocBook/procfs-guide.tmpl +++ b/Documentation/DocBook/procfs-guide.tmpl @@ -100,8 +100,8 @@ <para> I'd like to thank Jeff Garzik <email>jgarzik@pobox.com</email> and Alexander Viro - <email>viro@math.psu.edu</email> for their input, Tim Waugh - <email>twaugh@redhat.com</email> for his <ulink + <email>viro@parcelfarce.linux.theplanet.co.uk</email> for their input, + Tim Waugh <email>twaugh@redhat.com</email> for his <ulink url="http://people.redhat.com/twaugh/docbook/selfdocbook/">Selfdocbook</ulink>, and Marc Joosen <email>marcj@historia.et.tudelft.nl</email> for proofreading. diff --git a/Documentation/RCU/listRCU.txt b/Documentation/RCU/listRCU.txt index 46950afda25f..bda6ead69bd0 100644 --- a/Documentation/RCU/listRCU.txt +++ b/Documentation/RCU/listRCU.txt @@ -82,7 +82,7 @@ lock might be used as follows for deletion and insertion: list_for_each_entry(e, list, list) { if (!audit_compare_rule(rule, &e->rule)) { list_del(&e->list); - call_rcu(&e->rcu, audit_free_rule, e); + write_unlock(&auditsc_lock); return 0; } } diff --git a/Documentation/arm/Samsung-S3C24XX/Suspend.txt b/Documentation/arm/Samsung-S3C24XX/Suspend.txt index 59d4bad5b43e..9966156c2d50 100644 --- a/Documentation/arm/Samsung-S3C24XX/Suspend.txt +++ b/Documentation/arm/Samsung-S3C24XX/Suspend.txt @@ -33,7 +33,8 @@ Resuming code to resume Linux operation. GSTATUS4 is currently left alone by the sleep code, and is free to - use for any other purposes. + use for any other purposes (for example, the EB2410ITX uses this to + save memory configuration in). Machine Support @@ -41,9 +42,9 @@ Machine Support The machine specific functions must call the s3c2410_pm_init() function to say that it's bootloader is capable of resuming. This can be as - simple as adding the following to the file: + simple as adding the following to the machine's definition: - late_initcall(s3c2410_pm_init); + INITMACHINE(s3c2410_pm_init) A board can do its own setup before calling s3c2410_pm_init, if it needs to setup anything else for power management support. @@ -52,6 +53,23 @@ Machine Support saving the resume address, if your board requires it, then contact the maintainer and discuss what is required. + Note, the origianal method of adding an late_initcall() is wrong, + and will end up initialising all compiled machine's pm init! + + +Debugging +--------- + + There are several important things to rember when using PM suspend: + + 1) The uart drivers will disable the clocks to the UART blocks when + suspending, which means that use of printascii() or similar direct + access to the UARTs will cause the debug to stop. + + 2) Whilst the pm code itself will attempt to re-enabled the UART clocks, + care should be taken that any external clock sources that the UARTs + rely on are still enabled at that point + Configuration ------------- diff --git a/Documentation/filesystems/devfs/ChangeLog b/Documentation/filesystems/devfs/ChangeLog index 12583144e06d..e5aba5246d7c 100644 --- a/Documentation/filesystems/devfs/ChangeLog +++ b/Documentation/filesystems/devfs/ChangeLog @@ -1632,7 +1632,7 @@ Changes for patch v177 - Fixed bugs in handling symlinks: could leak or cause Oops - Cleaned up directory handling by separating fops - Thanks to Alexander Viro <viro@math.psu.edu> + Thanks to Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> =============================================================================== Changes for patch v178 diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index f9520374a47e..280720115452 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -701,7 +701,7 @@ running once the system is up. [KNL,ACPI] Mark specific memory as reserved. Region of memory to be used, from ss to ss+nn. - meye= [HW] Set MotionEye Camera parameters + meye.*= [HW] Set MotionEye Camera parameters See Documentation/video4linux/meye.txt. mga= [HW,DRM] @@ -866,6 +866,16 @@ running once the system is up. order they are specified on the command line, starting with parport0. + parport_init_mode= + [HW,PPT] Configure VIA parallel port to + operate in specific mode. This is + necessary on Pegasos computer where + firmware has no options for setting up + parallel port mode and sets it to + spp. Currently this function knows + 686a and 8231 chips. + Format: [spp|ps2|epp|ecp|ecpepp] + pas2= [HW,OSS] Format: <io>,<irq>,<dma>,<dma16>,<sb_io>,<sb_irq>,<sb_dma>,<sb_dma16> @@ -1020,10 +1030,6 @@ running once the system is up. New name for the ramdisk parameter. See Documentation/ramdisk.txt. - ramdisk_start= [RAM] Starting block of RAM disk image (so you can - place it after the kernel image on a boot floppy). - See Documentation/ramdisk.txt. - reboot= [BUGS=IA-32,BUGS=ARM,BUGS=IA-64] Rebooting mode Format: <reboot_mode>[,<reboot_mode2>[,...]] See arch/*/kernel/reboot.c. diff --git a/Documentation/prio_tree.txt b/Documentation/prio_tree.txt new file mode 100644 index 000000000000..2fbb0c49bc5b --- /dev/null +++ b/Documentation/prio_tree.txt @@ -0,0 +1,107 @@ +The prio_tree.c code indexes vmas using 3 different indexes: + * heap_index = vm_pgoff + vm_size_in_pages : end_vm_pgoff + * radix_index = vm_pgoff : start_vm_pgoff + * size_index = vm_size_in_pages + +A regular radix-priority-search-tree indexes vmas using only heap_index and +radix_index. The conditions for indexing are: + * ->heap_index >= ->left->heap_index && + ->heap_index >= ->right->heap_index + * if (->heap_index == ->left->heap_index) + then ->radix_index < ->left->radix_index; + * if (->heap_index == ->right->heap_index) + then ->radix_index < ->right->radix_index; + * nodes are hashed to left or right subtree using radix_index + similar to a pure binary radix tree. + +A regular radix-priority-search-tree helps to store and query +intervals (vmas). However, a regular radix-priority-search-tree is only +suitable for storing vmas with different radix indices (vm_pgoff). + +Therefore, the prio_tree.c extends the regular radix-priority-search-tree +to handle many vmas with the same vm_pgoff. Such vmas are handled in +2 different ways: 1) All vmas with the same radix _and_ heap indices are +linked using vm_set.list, 2) if there are many vmas with the same radix +index, but different heap indices and if the regular radix-priority-search +tree cannot index them all, we build an overflow-sub-tree that indexes such +vmas using heap and size indices instead of heap and radix indices. For +example, in the figure below some vmas with vm_pgoff = 0 (zero) are +indexed by regular radix-priority-search-tree whereas others are pushed +into an overflow-subtree. Note that all vmas in an overflow-sub-tree have +the same vm_pgoff (radix_index) and if necessary we build different +overflow-sub-trees to handle each possible radix_index. For example, +in figure we have 3 overflow-sub-trees corresponding to radix indices +0, 2, and 4. + +In the final tree the first few (prio_tree_root->index_bits) levels +are indexed using heap and radix indices whereas the overflow-sub-trees below +those levels (i.e. levels prio_tree_root->index_bits + 1 and higher) are +indexed using heap and size indices. In overflow-sub-trees the size_index +is used for hashing the nodes to appropriate places. + +Now, an example prio_tree: + + vmas are represented [radix_index, size_index, heap_index] + i.e., [start_vm_pgoff, vm_size_in_pages, end_vm_pgoff] + +level prio_tree_root->index_bits = 3 +----- + _ + 0 [0,7,7] | + / \ | + ------------------ ------------ | Regular + / \ | radix priority + 1 [1,6,7] [4,3,7] | search tree + / \ / \ | + ------- ----- ------ ----- | heap-and-radix + / \ / \ | indexed + 2 [0,6,6] [2,5,7] [5,2,7] [6,1,7] | + / \ / \ / \ / \ | + 3 [0,5,5] [1,5,6] [2,4,6] [3,4,7] [4,2,6] [5,1,6] [6,0,6] [7,0,7] | + / / / _ + / / / _ + 4 [0,4,4] [2,3,5] [4,1,5] | + / / / | + 5 [0,3,3] [2,2,4] [4,0,4] | Overflow-sub-trees + / / | + 6 [0,2,2] [2,1,3] | heap-and-size + / / | indexed + 7 [0,1,1] [2,0,2] | + / | + 8 [0,0,0] | + _ + +Note that we use prio_tree_root->index_bits to optimize the height +of the heap-and-radix indexed tree. Since prio_tree_root->index_bits is +set according to the maximum end_vm_pgoff mapped, we are sure that all +bits (in vm_pgoff) above prio_tree_root->index_bits are 0 (zero). Therefore, +we only use the first prio_tree_root->index_bits as radix_index. +Whenever index_bits is increased in prio_tree_expand, we shuffle the tree +to make sure that the first prio_tree_root->index_bits levels of the tree +is indexed properly using heap and radix indices. + +We do not optimize the height of overflow-sub-trees using index_bits. +The reason is: there can be many such overflow-sub-trees and all of +them have to be suffled whenever the index_bits increases. This may involve +walking the whole prio_tree in prio_tree_insert->prio_tree_expand code +path which is not desirable. Hence, we do not optimize the height of the +heap-and-size indexed overflow-sub-trees using prio_tree->index_bits. +Instead the overflow sub-trees are indexed using full BITS_PER_LONG bits +of size_index. This may lead to skewed sub-trees because most of the +higher significant bits of the size_index are likely to be be 0 (zero). In +the example above, all 3 overflow-sub-trees are skewed. This may marginally +affect the performance. However, processes rarely map many vmas with the +same start_vm_pgoff but different end_vm_pgoffs. Therefore, we normally +do not require overflow-sub-trees to index all vmas. + +From the above discussion it is clear that the maximum height of +a prio_tree can be prio_tree_root->index_bits + BITS_PER_LONG. +However, in most of the common cases we do not need overflow-sub-trees, +so the tree height in the common cases will be prio_tree_root->index_bits. + +It is fair to mention here that the prio_tree_root->index_bits +is increased on demand, however, the index_bits is not decreased when +vmas are removed from the prio_tree. That's tricky to do. Hence, it's +left as a home work problem. + + diff --git a/Documentation/sonypi.txt b/Documentation/sonypi.txt index a50949371b1b..0f3b2405d09e 100644 --- a/Documentation/sonypi.txt +++ b/Documentation/sonypi.txt @@ -1,6 +1,6 @@ Sony Programmable I/O Control Device Driver Readme -------------------------------------------------- - Copyright (C) 2001-2003 Stelian Pop <stelian@popies.net> + Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net> Copyright (C) 2001-2002 Alcôve <www.alcove.com> Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au> Copyright (C) 2001 Junichi Morita <jun1m@mars.dti.ne.jp> @@ -23,16 +23,18 @@ generate, like: Those events (see linux/sonypi.h) can be polled using the character device node /dev/sonypi (major 10, minor auto allocated or specified as a option). - A simple daemon which translates the jogdial movements into mouse wheel events can be downloaded at: <http://popies.net/sonypi/> +Another option to intercept the events is to get them directly through the +input layer. + This driver supports also some ioctl commands for setting the LCD screen -brightness and querying the batteries charge information (some more +brightness and querying the batteries charge information (some more commands may be added in the future). This driver can also be used to set the camera controls on Picturebook series -(brightness, contrast etc), and is used by the video4linux driver for the +(brightness, contrast etc), and is used by the video4linux driver for the Motion Eye camera. Please note that this driver was created by reverse engineering the Windows @@ -47,7 +49,7 @@ module argument syntax (<param>=<value> when passing the option to the module or sonypi.<param>=<value> on the kernel boot line when sonypi is statically linked into the kernel). Those options are: - minor: minor number of the misc device /dev/sonypi, + minor: minor number of the misc device /dev/sonypi, default is -1 (automatic allocation, see /proc/misc or kernel logs) @@ -59,14 +61,14 @@ statically linked into the kernel). Those options are: get enabled unless you set this parameter to 1. Do not use this option unless it's actually necessary, some Vaio models don't deal well with this option. - This option is available only if the kernel is + This option is available only if the kernel is compiled without ACPI support (since it conflicts - with it and it shouldn't be required anyway if + with it and it shouldn't be required anyway if ACPI is already enabled). - verbose: set to 1 to print unknown events received from the + verbose: set to 1 to print unknown events received from the sonypi device. - set to 2 to print all events received from the + set to 2 to print all events received from the sonypi device. compat: uses some compatibility code for enabling the sonypi @@ -75,14 +77,15 @@ statically linked into the kernel). Those options are: add this option and report to the author. mask: event mask telling the driver what events will be - reported to the user. This parameter is required for some - Vaio models where the hardware reuses values used in - other Vaio models (like the FX series who does not - have a jogdial but reuses the jogdial events for + reported to the user. This parameter is required for + some Vaio models where the hardware reuses values + used in other Vaio models (like the FX series who does + not have a jogdial but reuses the jogdial events for programmable keys events). The default event mask is - set to 0xffffffff, meaning that all possible events will be - tried. You can use the following bits to construct - your own event mask (from drivers/char/sonypi.h): + set to 0xffffffff, meaning that all possible events + will be tried. You can use the following bits to + construct your own event mask (from + drivers/char/sonypi.h): SONYPI_JOGGER_MASK 0x0001 SONYPI_CAPTURE_MASK 0x0002 SONYPI_FNKEY_MASK 0x0004 @@ -97,10 +100,10 @@ statically linked into the kernel). Those options are: SONYPI_MEMORYSTICK_MASK 0x0800 SONYPI_BATTERY_MASK 0x1000 - useinput: if set (which is the default) jogdial events are - forwarded to the input subsystem as mouse wheel - events. - + useinput: if set (which is the default) two input devices are + created, one which interprets the jogdial events as + mouse events, the other one which acts like a + keyboard reporting the pressing of the special keys. Module use: ----------- @@ -123,17 +126,17 @@ Bugs: external monitor on/off. There is no workaround yet, since this driver disables all APM management for those keys, by enabling the ACPI management (and the ACPI core stuff is not complete yet). If - you have one of those laptops with working Fn keys and want to + you have one of those laptops with working Fn keys and want to continue to use them, don't use this driver. - some users reported that the laptop speed is lower (dhrystone tested) when using the driver with the fnkeyinit parameter. I cannot reproduce it on my laptop and not all users have this problem. - This happens because the fnkeyinit parameter enables the ACPI - mode (but without additional ACPI control, like processor + This happens because the fnkeyinit parameter enables the ACPI + mode (but without additional ACPI control, like processor speed handling etc). Use ACPI instead of APM if it works on your laptop. - + - since all development was done by reverse engineering, there is _absolutely no guarantee_ that this driver will not crash your laptop. Permanently. diff --git a/Documentation/tipar.txt b/Documentation/tipar.txt index 773b9a2483eb..67133baef6ef 100644 --- a/Documentation/tipar.txt +++ b/Documentation/tipar.txt @@ -4,7 +4,7 @@ Author: Romain Lievin -Homepage: http://lpg.ticalc.org/prj_dev +Homepage: http://lpg.ticalc.org/prj_tidev/index.html INTRODUCTION: @@ -12,31 +12,30 @@ INTRODUCTION: This is a driver for the very common home-made parallel link cable, a cable designed for connecting TI8x/9x graphing calculators (handhelds) to a computer or workstation (Alpha, Sparc). Given that driver is built on parport, the -parallel port abstraction layer, this driver is independent of the platform. +parallel port abstraction layer, this driver is architecture-independent. It can also be used with another device plugged on the same port (such as a -ZIP drive). I have a 100MB ZIP and both of them work fine ! +ZIP drive). I have a 100MB ZIP and both of them work fine! If you need more information, please visit the 'TI drivers' homepage at the URL above. WHAT YOU NEED: -A TI calculator of course and a program capable to communicate with your -calculator. -TiLP will work for sure (since I am his developer !). yal92 may be able to use +A TI calculator and a program capable of communicating with your calculator. + +TiLP will work for sure (since I am its developer!). yal92 may be able to use it by changing tidev for tipar (may require some hacking...). HOW TO USE IT: You must have first compiled parport support (CONFIG_PARPORT_DEV): either compiled in your kernel, either as a module. -This driver supports the new device hierarchy (devfs). -Next, (as root) from your appropriate modules directory (lib/modules/2.5.XX): +Next, (as root): modprobe parport - insmod tipar.o + modprobe tipar If it is not already there (it usually is), create the device: @@ -47,14 +46,14 @@ If it is not already there (it usually is), create the device: You will have to set permissions on this device to allow you to read/write from it: - chmod 666 /dev/tipar? + chmod 666 /dev/tipar[0..2] Now you are ready to run a linking program such as TiLP. Be sure to configure it properly (RTFM). MODULE PARAMETERS: - You can set these with: insmod tipar NAME=VALUE + You can set these with: modprobe tipar NAME=VALUE There is currently no way to set these on a per-cable basis. NAME: timeout @@ -66,11 +65,12 @@ MODULE PARAMETERS: NAME: delay TYPE: integer DEFAULT: 10 - DESC: Inter-bit delay in micro-seconds. An lower value gives an higher data + DESC: Inter-bit delay in micro-seconds. A lower value gives an higher data rate but makes transmission less reliable. These parameters can be changed at run time by any program via ioctl(2) calls -as listed in ./include/linux/ticable.h +as listed in ./include/linux/ticable.h. + Rather than write 50 pages describing the ioctl() and so on, it is perhaps more useful you look at ticables library (dev_link.c) that demonstrates how to use them, and demonstrates the features of the driver. This is diff --git a/Documentation/video4linux/meye.txt b/Documentation/video4linux/meye.txt index 5adcd25024bb..2137da97552f 100644 --- a/Documentation/video4linux/meye.txt +++ b/Documentation/video4linux/meye.txt @@ -1,12 +1,12 @@ Vaio Picturebook Motion Eye Camera Driver Readme ------------------------------------------------ - Copyright (C) 2001-2003 Stelian Pop <stelian@popies.net> + Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net> Copyright (C) 2001-2002 Alcôve <www.alcove.com> Copyright (C) 2000 Andrew Tridgell <tridge@samba.org> This driver enable the use of video4linux compatible applications with the -Motion Eye camera. This driver requires the "Sony Vaio Programmable I/O -Control Device" driver (which can be found in the "Character drivers" +Motion Eye camera. This driver requires the "Sony Vaio Programmable I/O +Control Device" driver (which can be found in the "Character drivers" section of the kernel configuration utility) to be compiled and installed (using its "camera=1" parameter). @@ -24,7 +24,7 @@ This driver supports the 'second' version of the MotionEye camera :) The first version was connected directly on the video bus of the Neomagic video card and is unsupported. -The second one, made by Kawasaki Steel is fully supported by this +The second one, made by Kawasaki Steel is fully supported by this driver (PCI vendor/device is 0x136b/0xff01) The third one, present in recent (more or less last year) Picturebooks @@ -41,13 +41,12 @@ little information if any is available for this camera Driver options: --------------- -Several options can be passed to the meye driver, either by adding them -to /etc/modprobe.conf file, when the driver is compiled as a module, or -by adding the following to the kernel command line (in your bootloader): +Several options can be passed to the meye driver using the standard +module argument syntax (<param>=<value> when passing the option to the +module or meye.<param>=<value> on the kernel boot line when meye is +statically linked into the kernel). Those options are: - meye=gbuffers[,gbufsize[,video_nr]] - -where: + forcev4l1: force use of V4L1 API instead of V4L2 gbuffers: number of capture buffers, default is 2 (32 max) @@ -81,8 +80,9 @@ Usage: Private API: ------------ - The driver supports frame grabbing with the video4linux API, so - all video4linux tools (like xawtv) should work with this driver. + The driver supports frame grabbing with the video4linux API + (either v4l1 or v4l2), so all video4linux tools (like xawtv) + should work with this driver. Besides the video4linux interface, the driver has a private interface for accessing the Motion Eye extended parameters (camera sharpness, @@ -116,7 +116,7 @@ Private API: MEYEIOC_STILLJCAPT Takes a snapshot in an uncompressed or compressed jpeg format. This ioctl blocks until the snapshot is done and returns (for - jpeg snapshot) the size of the image. The image data is + jpeg snapshot) the size of the image. The image data is available from the first mmap'ed buffer. Look at the 'motioneye' application code for an actual example. @@ -124,13 +124,7 @@ Private API: Bugs / Todo: ------------ - - overlay output is not supported (although the camera is capable of). - (it should not be too hard to to it, provided we found how...) - - - mjpeg hardware playback doesn't work (depends on overlay...) + - the driver could be much cleaned up by removing the v4l1 support. + However, this means all v4l1-only applications will stop working. - - rewrite the driver to use some common video4linux API for snapshot - and mjpeg capture. Unfortunately, video4linux1 does not permit it, - the BUZ API seems to be targeted to TV cards only. The video4linux 2 - API may be an option, if it goes into the kernel (maybe 2.5 - material ?). + - 'motioneye' still uses the meye private v4l1 API extensions. diff --git a/MAINTAINERS b/MAINTAINERS index df711da15601..4bbba9382b13 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -831,7 +831,7 @@ S: Maintained FILESYSTEMS (VFS and infrastructure) P: Alexander Viro -M: viro@math.psu.edu +M: viro@parcelfarce.linux.theplanet.co.uk S: Maintained FIRMWARE LOADER (request_firmware) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b93a7d1847e5..dd96dde542bc 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -162,10 +162,10 @@ config ARCH_LH7A40X config ARCH_OMAP bool "TI OMAP" -config ARCH_VERSATILE_PB - bool "Versatile PB" +config ARCH_VERSATILE + bool "Versatile" help - This enables support for ARM Ltd Versatile PB board. + This enables support for ARM Ltd Versatile board. config ARCH_IMX bool "IMX" @@ -205,6 +205,8 @@ source "arch/arm/mach-imx/Kconfig" source "arch/arm/mach-h720x/Kconfig" +source "arch/arm/mach-versatile/Kconfig" + # Definitions to make life easier config ARCH_ACORN bool @@ -287,9 +289,14 @@ config ICST525 depends on ARCH_INTEGRATOR default y +config ICST307 + bool + depends on ARCH_VERSATILE + default y + config ARM_AMBA bool - depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB + depends on ARCH_INTEGRATOR || ARCH_VERSATILE default y config ISA @@ -547,7 +554,7 @@ config CMDLINE config LEDS bool "Timer and CPU usage LEDs" - depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE_PB || ARCH_IMX + depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE || ARCH_IMX help If you say Y here, the LEDs on your machine will be used to provide useful information about your current system status. @@ -560,8 +567,8 @@ config LEDS system, but the driver will do nothing. config LEDS_TIMER - bool "Timer LED" if LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || MACH_MAINSTONE || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE_PB || ARCH_IMX) - depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE_PB || ARCH_IMX + bool "Timer LED" if LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || MACH_MAINSTONE || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE || ARCH_IMX) + depends on ARCH_NETWINDER || ARCH_EBSA110 || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_CDB89712 || ARCH_P720T || ARCH_OMAP || ARCH_VERSATILE || ARCH_IMX default y if ARCH_EBSA110 help If you say Y here, one of the system LEDs (the green one on the @@ -576,7 +583,7 @@ config LEDS_TIMER config LEDS_CPU bool "CPU usage LED" - depends on LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE_PB || ARCH_IMX) + depends on LEDS && (ARCH_NETWINDER || ARCH_EBSA285 || ARCH_SHARK || ARCH_CO285 || ARCH_SA1100 || ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_PXA_IDP || ARCH_INTEGRATOR || ARCH_P720T || ARCH_VERSATILE || ARCH_IMX) help If you say Y here, the red LED will be used to give a good real time indication of CPU usage, by lighting whenever the idle task diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 826a3e4fe222..74aba142cf92 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -93,7 +93,7 @@ textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000 machine-$(CONFIG_ARCH_OMAP) := omap machine-$(CONFIG_ARCH_S3C2410) := s3c2410 machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x - machine-$(CONFIG_ARCH_VERSATILE_PB) := versatile + machine-$(CONFIG_ARCH_VERSATILE) := versatile machine-$(CONFIG_ARCH_IMX) := imx machine-$(CONFIG_ARCH_H720X) := h720x diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index c660c94988c2..5b9f9eddddec 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -5,6 +5,7 @@ obj-y += rtctime.o obj-$(CONFIG_ARM_AMBA) += amba.o obj-$(CONFIG_ICST525) += icst525.o +obj-$(CONFIG_ICST307) += icst307.o obj-$(CONFIG_SA1111) += sa1111.o obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o obj-$(CONFIG_DMABOUNCE) += dmabounce.o diff --git a/arch/arm/common/icst307.c b/arch/arm/common/icst307.c new file mode 100644 index 000000000000..bafe8b19be82 --- /dev/null +++ b/arch/arm/common/icst307.c @@ -0,0 +1,161 @@ +/* + * linux/arch/arm/common/icst307.c + * + * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Support functions for calculating clocks/divisors for the ICST307 + * clock generators. See http://www.icst.com/ for more information + * on these devices. + * + * This is an almost identical implementation to the ICST525 clock generator. + * The s2div and idx2s files are different + */ +#include <linux/module.h> +#include <linux/kernel.h> + +#include <asm/hardware/icst307.h> + +/* + * Divisors for each OD setting. + */ +static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 3, 6 }; + +unsigned long icst307_khz(const struct icst307_params *p, struct icst307_vco vco) +{ + return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]); +} + +EXPORT_SYMBOL(icst307_khz); + +/* + * Ascending divisor S values. + */ +static unsigned char idx2s[8] = { 1, 6, 3, 4, 7, 5, 2, 0 }; + +struct icst307_vco +icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq) +{ + struct icst307_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; + unsigned long f; + unsigned int i = 0, rd, best = (unsigned int)-1; + + /* + * First, find the PLL output divisor such + * that the PLL output is within spec. + */ + do { + f = freq * s2div[idx2s[i]]; + + /* + * f must be between 6MHz and 200MHz (3.3 or 5V) + */ + if (f > 6000 && f <= p->vco_max) + break; + } while (i < ARRAY_SIZE(idx2s)); + + if (i > ARRAY_SIZE(idx2s)) + return vco; + + vco.s = idx2s[i]; + + /* + * Now find the closest divisor combination + * which gives a PLL output of 'f'. + */ + for (rd = p->rd_min; rd <= p->rd_max; rd++) { + unsigned long fref_div, f_pll; + unsigned int vd; + int f_diff; + + fref_div = (2 * p->ref) / rd; + + vd = (f + fref_div / 2) / fref_div; + if (vd < p->vd_min || vd > p->vd_max) + continue; + + f_pll = fref_div * vd; + f_diff = f_pll - f; + if (f_diff < 0) + f_diff = -f_diff; + + if ((unsigned)f_diff < best) { + vco.v = vd - 8; + vco.r = rd - 2; + if (f_diff == 0) + break; + best = f_diff; + } + } + + return vco; +} + +EXPORT_SYMBOL(icst307_khz_to_vco); + +struct icst307_vco +icst307_ps_to_vco(const struct icst307_params *p, unsigned long period) +{ + struct icst307_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max }; + unsigned long f, ps; + unsigned int i = 0, rd, best = (unsigned int)-1; + + ps = 1000000000UL / p->vco_max; + + /* + * First, find the PLL output divisor such + * that the PLL output is within spec. + */ + do { + f = period / s2div[idx2s[i]]; + + /* + * f must be between 6MHz and 200MHz (3.3 or 5V) + */ + if (f >= ps && f < 1000000000UL / 6000 + 1) + break; + } while (i < ARRAY_SIZE(idx2s)); + + if (i > ARRAY_SIZE(idx2s)) + return vco; + + vco.s = idx2s[i]; + + ps = 500000000UL / p->ref; + + /* + * Now find the closest divisor combination + * which gives a PLL output of 'f'. + */ + for (rd = p->rd_min; rd <= p->rd_max; rd++) { + unsigned long f_in_div, f_pll; + unsigned int vd; + int f_diff; + + f_in_div = ps * rd; + + vd = (f_in_div + f / 2) / f; + if (vd < p->vd_min || vd > p->vd_max) + continue; + + f_pll = (f_in_div + vd / 2) / vd; + f_diff = f_pll - f; + if (f_diff < 0) + f_diff = -f_diff; + + if ((unsigned)f_diff < best) { + vco.v = vd - 8; + vco.r = rd - 2; + if (f_diff == 0) + break; + best = f_diff; + } + } + + return vco; +} + +EXPORT_SYMBOL(icst307_ps_to_vco); diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index 46550dddec99..32e114c834a6 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -609,17 +609,15 @@ static void __locomo_remove(struct locomo *lchip) static int locomo_probe(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); - struct resource *mem = NULL, *irq = NULL; - int i; - - for (i = 0; i < pdev->num_resources; i++) { - if (pdev->resource[i].flags & IORESOURCE_MEM) - mem = &pdev->resource[i]; - if (pdev->resource[i].flags & IORESOURCE_IRQ) - irq = &pdev->resource[i]; - } + struct resource *mem; + int irq; + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) + return -EINVAL; + irq = platform_get_irq(pdev, 0); - return __locomo_probe(dev, mem, irq ? irq->start : NO_IRQ); + return __locomo_probe(dev, mem, irq); } static int locomo_remove(struct device *dev) @@ -756,7 +754,7 @@ module_exit(locomo_exit); MODULE_DESCRIPTION("Sharp LoCoMo core driver"); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("John Lenz <jelenz@students.wisc.edu>"); +MODULE_AUTHOR("John Lenz <lenz@cs.wisc.edu>"); EXPORT_SYMBOL(locomo_driver_register); EXPORT_SYMBOL(locomo_driver_unregister); diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S index 5335e4662554..78146b6c3d4e 100644 --- a/arch/arm/kernel/debug.S +++ b/arch/arm/kernel/debug.S @@ -647,7 +647,7 @@ .endm -#elif defined(CONFIG_ARCH_VERSATILE_PB) +#elif defined(CONFIG_ARCH_VERSATILE) #include <asm/hardware/amba_serial.h> diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 5639f1b618f9..6ad406bd9c6e 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -464,7 +464,7 @@ ENTRY(soft_irq_mask) .macro irq_prio_table .endm -#elif defined(CONFIG_ARCH_VERSATILE_PB) +#elif defined(CONFIG_ARCH_VERSATILE) .macro disable_fiq .endm diff --git a/arch/arm/lib/csumpartial.S b/arch/arm/lib/csumpartial.S index c5515f3be0ad..cb5e3708f118 100644 --- a/arch/arm/lib/csumpartial.S +++ b/arch/arm/lib/csumpartial.S @@ -73,8 +73,7 @@ td3 .req lr .done: adc r0, sum, #0 @ collect up the last carry ldr td0, [sp], #4 tst td0, #1 @ check buffer alignment - movne td0, r0, lsl #8 @ rotate checksum by 8 bits - orrne r0, td0, r0, lsr #24 + movne r0, r0, ror #8 @ rotate checksum by 8 bits ldr pc, [sp], #4 @ return .not_aligned: tst buf, #1 @ odd address diff --git a/arch/arm/lib/csumpartialcopygeneric.S b/arch/arm/lib/csumpartialcopygeneric.S index b18b89715118..d3a2f4667db4 100644 --- a/arch/arm/lib/csumpartialcopygeneric.S +++ b/arch/arm/lib/csumpartialcopygeneric.S @@ -160,8 +160,7 @@ FN_ENTRY .done: adc r0, sum, #0 ldr sum, [sp, #0] @ dst tst sum, #1 - movne sum, r0, lsl #8 - orrne r0, sum, r0, lsr #24 + movne r0, r0, ror #8 load_regs ea .src_not_aligned: diff --git a/arch/arm/lib/io-readsl.S b/arch/arm/lib/io-readsl.S index 06b152a3cd7b..75a9121cb23f 100644 --- a/arch/arm/lib/io-readsl.S +++ b/arch/arm/lib/io-readsl.S @@ -27,11 +27,10 @@ ENTRY(__raw_readsl) stmia r1!, {r3, r4, ip, lr} bpl 1b ldmfd sp!, {r4, lr} -2: tst r2, #2 - ldrne r3, [r0, #0] - ldrne ip, [r0, #0] - stmneia r1!, {r3, ip} - tst r2, #1 +2: movs r2, r2, lsl #31 + ldrcs r3, [r0, #0] + ldrcs ip, [r0, #0] + stmcsia r1!, {r3, ip} ldrne r3, [r0, #0] strne r3, [r1, #0] mov pc, lr diff --git a/arch/arm/lib/io-writesl.S b/arch/arm/lib/io-writesl.S index b3c276449047..f8f14dd227ca 100644 --- a/arch/arm/lib/io-writesl.S +++ b/arch/arm/lib/io-writesl.S @@ -27,12 +27,11 @@ ENTRY(__raw_writesl) str lr, [r0, #0] bpl 1b ldmfd sp!, {r4, lr} -2: tst r2, #2 - ldmneia r1!, {r3, ip} - strne r3, [r0, #0] - strne ip, [r0, #0] - tst r2, #1 +2: movs r2, r2, lsl #31 + ldmcsia r1!, {r3, ip} + strcs r3, [r0, #0] ldrne r3, [r1, #0] + strcs ip, [r0, #0] strne r3, [r0, #0] mov pc, lr diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index d25a3a2db120..1b37ac1886d1 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c @@ -12,6 +12,7 @@ #include <linux/list.h> #include <linux/sched.h> #include <linux/init.h> +#include <linux/serial_8250.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -313,6 +314,55 @@ static struct clps7500_timer = { .offset = ioc_timer_gettimeoffset, }; +static struct plat_serial8250_port serial_platform_data[] = { + { + .mapbase = 0x03010fe0, + .irq = 10, + .uartclk = 1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST, + }, + { + .mapbase = 0x03010be0, + .irq = 0, + .uartclk = 1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST, + }, + { + .iobase = ISASLOT_IO + 0x2e8, + .irq = 41, + .uartclk = 1843200, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .iobase = ISASLOT_IO + 0x3e8, + .irq = 40, + .uartclk = 1843200, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +static int __init clps7500_init(void) +{ + return platform_register_device(&serial_device); +} + MACHINE_START(CLPS7500, "CL-PS7500") MAINTAINER("Philip Blundell") BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index e4e3ff75164c..ef362d44949d 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -12,6 +12,7 @@ #include <linux/kernel.h> #include <linux/mm.h> #include <linux/interrupt.h> +#include <linux/serial_8250.h> #include <linux/init.h> #include <asm/hardware.h> @@ -196,6 +197,41 @@ static struct sys_timer ebsa110_timer = { .offset = ebsa110_gettimeoffset, }; +static struct plat_serial8250_port serial_platform_data[] = { + { + .iobase = 0x3f8, + .irq = 1, + .uartclk = 1843200, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .iobase = 0x2f8, + .irq = 2, + .uartclk = 1843200, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +static int __init ebsa110_init(void) +{ + return platform_device_register(&serial_device); +} + +arch_initcall(ebsa110_init); + MACHINE_START(EBSA110, "EBSA110") MAINTAINER("Russell King") BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000) diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c index ddbd6f71266b..1b40340e8a21 100644 --- a/arch/arm/mach-epxa10db/arch.c +++ b/arch/arm/mach-epxa10db/arch.c @@ -20,6 +20,7 @@ */ #include <linux/types.h> #include <linux/init.h> +#include <linux/serial_8250.h> #include <asm/hardware.h> #include <asm/setup.h> @@ -27,6 +28,36 @@ #include <asm/mach/arch.h> +static struct plat_serial8250_port serial_platform_data[] = { + { + .iobase = 0x3f8, + .irq = IRQ_UARTINT0, +#error FIXME + .uartclk = 0, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .iobase = 0x2f8, + .irq = IRQ_UARTINT1, +#error FIXME + .uartclk = 0, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + extern void epxa10db_map_io(void); extern void epxa10db_init_irq(void); extern struct sys_timer epxa10db_timer; diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile index 4a6b94c6887e..0694ad6b6476 100644 --- a/arch/arm/mach-footbridge/Makefile +++ b/arch/arm/mach-footbridge/Makefile @@ -26,3 +26,5 @@ obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal.o dc21285-timer.o obj-$(CONFIG_PCI) +=$(pci-y) obj-$(CONFIG_LEDS) +=$(leds-y) + +obj-$(CONFIG_ISA) += isa.o diff --git a/arch/arm/mach-footbridge/isa.c b/arch/arm/mach-footbridge/isa.c new file mode 100644 index 000000000000..aa3a1fef563e --- /dev/null +++ b/arch/arm/mach-footbridge/isa.c @@ -0,0 +1,48 @@ +/* + * linux/arch/arm/mach-footbridge/isa.c + * + * 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. + */ +#include <linux/init.h> +#include <linux/serial_8250.h> + +#include <asm/irq.h> + +static struct plat_serial8250_port serial_platform_data[] = { + { + .iobase = 0x3f8, + .irq = IRQ_ISA_UART, + .uartclk = 1843200, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .iobase = 0x2f8, + .irq = IRQ_ISA_UART2, + .uartclk = 1843200, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +static int __init footbridge_isa_init(void) +{ + return platform_device_register(&serial_device); +} + +arch_initcall(footbridge_isa_init); diff --git a/arch/arm/mach-h720x/common.h b/arch/arm/mach-h720x/common.h new file mode 100644 index 000000000000..d8798dbc44f8 --- /dev/null +++ b/arch/arm/mach-h720x/common.h @@ -0,0 +1,29 @@ +/* + * linux/arch/arm/mach-h720x/common.h + * + * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de> + * 2003 Robert Schwebel <r.schwebel@pengutronix.de> + * 2004 Sascha Hauer <s.hauer@pengutronix.de> + * + * Architecture specific stuff for Hynix GMS30C7201 development board + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +extern unsigned long h720x_gettimeoffset(void); +extern void __init h720x_init_irq (void); +extern void __init h720x_map_io(void); + +#ifdef CONFIG_ARCH_H7202 +extern struct sys_timer h7202_timer; +extern void __init init_hw_h7202(void); +extern void __init h7202_init_irq (void); +extern void __init h7202_init_time(void); +#endif + +#ifdef CONFIG_ARCH_H7201 +extern struct sys_timer h7201_timer; +#endif diff --git a/arch/arm/mach-h720x/cpu-h7201.c b/arch/arm/mach-h720x/cpu-h7201.c index e135ba7fe1e7..743656881ed6 100644 --- a/arch/arm/mach-h720x/cpu-h7201.c +++ b/arch/arm/mach-h720x/cpu-h7201.c @@ -22,10 +22,7 @@ #include <asm/arch/irqs.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> - -extern unsigned long h720x_gettimeoffset(void); -extern void __init h720x_init_irq (void); - +#include "common.h" /* * Timer interrupt handler */ @@ -53,8 +50,6 @@ static struct irqaction h7201_timer_irq = { */ void __init h7201_init_time(void) { - gettimeoffset = h720x_gettimeoffset; - CPU_REG (TIMER_VIRT, TM0_PERIOD) = LATCH; CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_RESET; CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_REPEAT | TM_START; @@ -62,3 +57,8 @@ void __init h7201_init_time(void) setup_irq(IRQ_TIMER0, &h7201_timer_irq); } + +struct sys_timer h7201_timer = { + .init = h7201_init_time, + .offset = h720x_gettimeoffset, +}; diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c index ed6cea6a9da2..4b6968eb25a3 100644 --- a/arch/arm/mach-h720x/cpu-h7202.c +++ b/arch/arm/mach-h720x/cpu-h7202.c @@ -23,6 +23,8 @@ #include <asm/mach/irq.h> #include <asm/mach/time.h> #include <linux/device.h> +#include <linux/serial_8250.h> +#include "common.h" static struct resource h7202ps2_resources[] = { [0] = { @@ -44,13 +46,55 @@ static struct platform_device h7202ps2_device = { .resource = h7202ps2_resources, }; +static struct plat_serial8250_port serial_platform_data[] = { + { + .membase = SERIAL0_BASE, + .irq = IRQ_UART0, + .uartclk = 2*1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .membase = SERIAL1_BASE, + .irq = IRQ_UART1, + .uartclk = 2*1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .membase = SERIAL2_BASE, + .irq = IRQ_UART2, + .uartclk = 2*1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .membase = SERIAL3_BASE, + .irq = IRQ_UART3, + .uartclk = 2*1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + static struct platform_device *devices[] __initdata = { &h7202ps2_device, + &serial_device, }; -extern unsigned long h720x_gettimeoffset(void); -extern void __init h720x_init_irq (void); - /* Although we have two interrupt lines for the timers, we only have one * status register which clears all pending timer interrupts on reading. So * we have to handle all timer interrupts in one place. @@ -130,8 +174,6 @@ static struct irqaction h7202_timer_irq = { */ void __init h7202_init_time(void) { - gettimeoffset = h720x_gettimeoffset; - CPU_REG (TIMER_VIRT, TM0_PERIOD) = LATCH; CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_RESET; CPU_REG (TIMER_VIRT, TM0_CTRL) = TM_REPEAT | TM_START; @@ -140,6 +182,11 @@ void __init h7202_init_time(void) setup_irq(IRQ_TIMER0, &h7202_timer_irq); } +struct sys_timer h7202_timer = { + .init = h7202_init_time, + .offset = h720x_gettimeoffset, +}; + void __init h7202_init_irq (void) { int irq; diff --git a/arch/arm/mach-h720x/h7201-eval.c b/arch/arm/mach-h720x/h7201-eval.c index d2208c1e5b11..9b24b9b0db15 100644 --- a/arch/arm/mach-h720x/h7201-eval.c +++ b/arch/arm/mach-h720x/h7201-eval.c @@ -27,10 +27,7 @@ #include <asm/pgtable.h> #include <asm/mach/arch.h> #include <asm/hardware.h> - -extern void h720x_init_irq (void); -extern void h7201_init_time(void); -extern void __init h720x_map_io(void); +#include "common.h" MACHINE_START(H7201, "Hynix GMS30C7201") MAINTAINER("Robert Schwebel, Pengutronix") @@ -38,5 +35,5 @@ MACHINE_START(H7201, "Hynix GMS30C7201") BOOT_PARAMS(0xc0001000) MAPIO(h720x_map_io) INITIRQ(h720x_init_irq) - INITTIME(h7201_init_time) + .timer = &h7201_timer, MACHINE_END diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c index 9398731971ea..3456a00d5f5c 100644 --- a/arch/arm/mach-h720x/h7202-eval.c +++ b/arch/arm/mach-h720x/h7202-eval.c @@ -27,11 +27,7 @@ #include <asm/pgtable.h> #include <asm/mach/arch.h> #include <asm/hardware.h> - -extern void __init init_hw_h7202(void); -extern void __init h7202_init_irq (void); -extern void __init h7202_init_time(void); -extern void __init h720x_map_io(void); +#include "common.h" static struct resource cirrus_resources[] = { [0] = { @@ -80,6 +76,6 @@ MACHINE_START(H7202, "Hynix HMS30C7202") BOOT_PARAMS(0x40000100) MAPIO(h720x_map_io) INITIRQ(h7202_init_irq) - INITTIME(h7202_init_time) + .timer = &h7202_timer, INIT_MACHINE(init_eval_h7202) MACHINE_END diff --git a/arch/arm/mach-iop3xx/arch.c b/arch/arm/mach-iop3xx/arch.c deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/arch/arm/mach-iop3xx/arch.c +++ /dev/null diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index febc32412ee5..c0c8bc1ede74 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -261,7 +261,7 @@ static void __init ixp4xx_timer_init(void) setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq); } -struct ixp4xx_timer = { +struct sys_timer ixp4xx_timer = { .init = ixp4xx_timer_init, .offset = ixp4xx_gettimeoffset, }; diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig index 10fbed106d41..f8d265d7088d 100644 --- a/arch/arm/mach-omap/Kconfig +++ b/arch/arm/mach-omap/Kconfig @@ -1,3 +1,4 @@ +if ARCH_OMAP menu "TI OMAP Implementations" @@ -171,3 +172,5 @@ config OMAP_ARM_30MHZ Enable 30MHz clock for OMAP CPU. If unsure, say N. endmenu + +endif diff --git a/arch/arm/mach-omap/clock.c b/arch/arm/mach-omap/clock.c index 0f790caadfbf..39d8503c0dd7 100644 --- a/arch/arm/mach-omap/clock.c +++ b/arch/arm/mach-omap/clock.c @@ -33,6 +33,9 @@ struct mpu_rate rate_table[] = { /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv */ +#if defined(CONFIG_OMAP_ARM_216MHZ) && defined(CONFIG_ARCH_OMAP16XX) + { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */ +#endif #if defined(CONFIG_OMAP_ARM_195MHZ) && defined(CONFIG_ARCH_OMAP730) { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */ #endif @@ -95,19 +98,21 @@ static void watchdog_recalc(struct clk * clk) static struct clk ck_ref = { .name = "ck_ref", .rate = 12000000, - .flags = ALWAYS_ENABLED, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + ALWAYS_ENABLED, }; static struct clk ck_dpll1 = { .name = "ck_dpll1", .parent = &ck_ref, - .flags = RATE_PROPAGATES | ALWAYS_ENABLED, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_PROPAGATES | ALWAYS_ENABLED, }; static struct clk ck_dpll1out = { .name = "ck_dpll1out", .parent = &ck_dpll1, - .flags = DOES_NOT_EXIST_ON_1510, + .flags = CLOCK_IN_OMAP16XX, .enable_reg = ARM_IDLECT2, .enable_bit = EN_CKOUT_ARM, .recalc = &followparent_recalc, @@ -116,7 +121,8 @@ static struct clk ck_dpll1out = { static struct clk arm_ck = { .name = "arm_ck", .parent = &ck_dpll1, - .flags = RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, .rate_offset = CKCTL_ARMDIV_OFFSET, .recalc = &ckctl_recalc, }; @@ -124,7 +130,8 @@ static struct clk arm_ck = { static struct clk armper_ck = { .name = "armper_ck", .parent = &ck_dpll1, - .flags = RATE_CKCTL, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_CKCTL, .enable_reg = ARM_IDLECT2, .enable_bit = EN_PERCK, .rate_offset = CKCTL_PERDIV_OFFSET, @@ -134,7 +141,7 @@ static struct clk armper_ck = { static struct clk arm_gpio_ck = { .name = "arm_gpio_ck", .parent = &ck_dpll1, - .flags = DOES_NOT_EXIST_ON_1610, + .flags = CLOCK_IN_OMAP1510, .enable_reg = ARM_IDLECT2, .enable_bit = EN_GPIOCK, .recalc = &followparent_recalc, @@ -143,6 +150,7 @@ static struct clk arm_gpio_ck = { static struct clk armxor_ck = { .name = "armxor_ck", .parent = &ck_ref, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, .enable_reg = ARM_IDLECT2, .enable_bit = EN_XORPCK, .recalc = &followparent_recalc, @@ -151,6 +159,7 @@ static struct clk armxor_ck = { static struct clk armtim_ck = { .name = "armtim_ck", .parent = &ck_ref, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, .enable_reg = ARM_IDLECT2, .enable_bit = EN_TIMCK, .recalc = &followparent_recalc, @@ -159,6 +168,7 @@ static struct clk armtim_ck = { static struct clk armwdt_ck = { .name = "armwdt_ck", .parent = &ck_ref, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, .enable_reg = ARM_IDLECT2, .enable_bit = EN_WDTCK, .recalc = &watchdog_recalc, @@ -167,7 +177,7 @@ static struct clk armwdt_ck = { static struct clk arminth_ck1610 = { .name = "arminth_ck", .parent = &arm_ck, - .flags = DOES_NOT_EXIST_ON_1510, + .flags = CLOCK_IN_OMAP16XX, .recalc = &followparent_recalc, /* Note: On 1610/1710 frequency can be divided by 2 by programming * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1 @@ -179,7 +189,8 @@ static struct clk arminth_ck1610 = { static struct clk dsp_ck = { .name = "dsp_ck", .parent = &ck_dpll1, - .flags = RATE_CKCTL, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_CKCTL, .enable_reg = ARM_CKCTL, .enable_bit = EN_DSPCK, .rate_offset = CKCTL_DSPDIV_OFFSET, @@ -189,7 +200,8 @@ static struct clk dsp_ck = { static struct clk dspmmu_ck = { .name = "dspmmu_ck", .parent = &ck_dpll1, - .flags = RATE_CKCTL | ALWAYS_ENABLED, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_CKCTL | ALWAYS_ENABLED, .rate_offset = CKCTL_DSPMMUDIV_OFFSET, .recalc = &ckctl_recalc, }; @@ -197,7 +209,8 @@ static struct clk dspmmu_ck = { static struct clk tc_ck = { .name = "tc_ck", .parent = &ck_dpll1, - .flags = RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED, .rate_offset = CKCTL_TCDIV_OFFSET, .recalc = &ckctl_recalc, }; @@ -205,7 +218,7 @@ static struct clk tc_ck = { static struct clk arminth_ck1510 = { .name = "arminth_ck", .parent = &tc_ck, - .flags = DOES_NOT_EXIST_ON_1610, + .flags = CLOCK_IN_OMAP1510, .recalc = &followparent_recalc, /* Note: On 1510 frequency follows TC_CK * @@ -216,14 +229,14 @@ static struct clk arminth_ck1510 = { static struct clk tipb_ck = { .name = "tibp_ck", .parent = &tc_ck, - .flags = DOES_NOT_EXIST_ON_1610, + .flags = CLOCK_IN_OMAP1510, .recalc = &followparent_recalc, }; static struct clk l3_ocpi_ck = { .name = "l3_ocpi_ck", .parent = &tc_ck, - .flags = DOES_NOT_EXIST_ON_1510, + .flags = CLOCK_IN_OMAP16XX, .enable_reg = ARM_IDLECT3, .enable_bit = EN_OCPI_CK, .recalc = &followparent_recalc, @@ -232,7 +245,7 @@ static struct clk l3_ocpi_ck = { static struct clk tc1_ck = { .name = "tc1_ck", .parent = &tc_ck, - .flags = DOES_NOT_EXIST_ON_1510, + .flags = CLOCK_IN_OMAP16XX, .enable_reg = ARM_IDLECT3, .enable_bit = EN_TC1_CK, .recalc = &followparent_recalc, @@ -241,7 +254,7 @@ static struct clk tc1_ck = { static struct clk tc2_ck = { .name = "tc2_ck", .parent = &tc_ck, - .flags = DOES_NOT_EXIST_ON_1510, + .flags = CLOCK_IN_OMAP16XX, .enable_reg = ARM_IDLECT3, .enable_bit = EN_TC2_CK, .recalc = &followparent_recalc, @@ -250,19 +263,21 @@ static struct clk tc2_ck = { static struct clk dma_ck = { .name = "dma_ck", .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, .recalc = &followparent_recalc, }; static struct clk dma_lcdfree_ck = { .name = "dma_lcdfree_ck", .parent = &tc_ck, - .flags = DOES_NOT_EXIST_ON_1510, + .flags = CLOCK_IN_OMAP16XX, .recalc = &followparent_recalc, }; static struct clk api_ck = { .name = "api_ck", .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, .enable_reg = ARM_IDLECT2, .enable_bit = EN_APICK, .recalc = &followparent_recalc, @@ -271,7 +286,7 @@ static struct clk api_ck = { static struct clk lb_ck = { .name = "lb_ck", .parent = &tc_ck, - .flags = DOES_NOT_EXIST_ON_1610, + .flags = CLOCK_IN_OMAP1510, .enable_reg = ARM_IDLECT2, .enable_bit = EN_LBCK, .recalc = &followparent_recalc, @@ -280,21 +295,22 @@ static struct clk lb_ck = { static struct clk rhea1_ck = { .name = "rhea1_ck", .parent = &tc_ck, - .flags = DOES_NOT_EXIST_ON_1510, + .flags = CLOCK_IN_OMAP16XX, .recalc = &followparent_recalc, }; static struct clk rhea2_ck = { .name = "rhea2_ck", .parent = &tc_ck, - .flags = DOES_NOT_EXIST_ON_1510, + .flags = CLOCK_IN_OMAP16XX, .recalc = &followparent_recalc, }; static struct clk lcd_ck = { .name = "lcd_ck", .parent = &ck_dpll1, - .flags = RATE_CKCTL, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_CKCTL, .enable_reg = ARM_IDLECT2, .enable_bit = EN_LCDCK, .rate_offset = CKCTL_LCDDIV_OFFSET, @@ -305,7 +321,8 @@ static struct clk uart1_ck = { .name = "uart1_ck", /* Direct from ULPD, no parent */ .rate = 48000000, - .flags = RATE_FIXED | ENABLE_REG_32BIT, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, .enable_reg = MOD_CONF_CTRL_0, .enable_bit = 29, /* (Only on 1510) @@ -317,7 +334,8 @@ static struct clk uart2_ck = { .name = "uart2_ck", /* Direct from ULPD, no parent */ .rate = 48000000, - .flags = RATE_FIXED | ENABLE_REG_32BIT, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, .enable_reg = MOD_CONF_CTRL_0, .enable_bit = 30, /* (1510/1610/1710) @@ -329,7 +347,8 @@ static struct clk uart3_ck = { .name = "uart3_ck", /* Direct from ULPD, no parent */ .rate = 48000000, - .flags = RATE_FIXED | ENABLE_REG_32BIT, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, .enable_reg = MOD_CONF_CTRL_0, .enable_bit = 31, /* (Only on 1510) @@ -341,8 +360,8 @@ static struct clk usb_ck1610 = { .name = "usb_ck", /* Direct from ULPD, no parent */ .rate = 48000000, - .flags = RATE_FIXED | ENABLE_REG_32BIT | - DOES_NOT_EXIST_ON_1510, + .flags = CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, .enable_reg = ULPD_CLOCK_CTRL, .enable_bit = USB_MCLK_EN, }; @@ -351,14 +370,15 @@ static struct clk usb_ck1510 = { .name = "usb_ck", /* Direct from ULPD, no parent */ .rate = 48000000, - .flags = RATE_FIXED | DOES_NOT_EXIST_ON_1610, + .flags = CLOCK_IN_OMAP1510 | RATE_FIXED, }; static struct clk usb_hhc_ck = { .name = "usb_hhc_ck", /* Direct from ULPD, no parent */ .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ - .flags = RATE_FIXED | ENABLE_REG_32BIT, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, .enable_reg = MOD_CONF_CTRL_0, .enable_bit = USB_HOST_HHC_UHOST_EN, }; @@ -373,39 +393,32 @@ static struct clk bclk = { }; -- to be done */ -static struct clk mmc_ck = { - .name = "mmc1_ck", - .parent = &armxor_ck, /* (1510) */ - .rate = 48000000, - .flags = RATE_FIXED | ENABLE_REG_32BIT | - DOES_NOT_EXIST_ON_1610, - .enable_reg = MOD_CONF_CTRL_0, - .enable_bit = 23, -}; - static struct clk mmc1_ck = { .name = "mmc1_ck", - /* Direct from ULPD, no parent (1610/1710) */ + /* Functional clock is direct from ULPD, interface clock is ARMPER */ + .parent = &armper_ck, .rate = 48000000, - .flags = RATE_FIXED | ENABLE_REG_32BIT | - DOES_NOT_EXIST_ON_1510, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, .enable_reg = MOD_CONF_CTRL_0, .enable_bit = 23, }; static struct clk mmc2_ck = { .name = "mmc2_ck", - /* Direct from ULPD, no parent */ + /* Functional clock is direct from ULPD, interface clock is ARMPER */ + .parent = &armper_ck, .rate = 48000000, - .flags = RATE_FIXED | ENABLE_REG_32BIT | - DOES_NOT_EXIST_ON_1510, + .flags = CLOCK_IN_OMAP16XX | + RATE_FIXED | ENABLE_REG_32BIT, .enable_reg = MOD_CONF_CTRL_0, .enable_bit = 20, }; static struct clk virtual_ck_mpu = { .name = "mpu", - .flags = VIRTUAL_CLOCK | ALWAYS_ENABLED, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + VIRTUAL_CLOCK | ALWAYS_ENABLED, .parent = &arm_ck, /* Is smarter alias for */ .recalc = &followparent_recalc, .set_rate = &select_table_rate, @@ -454,8 +467,7 @@ static struct clk * onchip_clks[] = { &mclk, &bclk, -- to be done */ - &mmc_ck, /* 1510 */ - &mmc1_ck, /* 1610/1710 */ + &mmc1_ck, &mmc2_ck, /* Virtual clocks */ &virtual_ck_mpu, @@ -496,7 +508,8 @@ int __clk_enable(struct clk *clk) return 0; if (unlikely(clk->enable_reg == 0)) { - printk("Enable for %s without enable enabled\n", clk->name); + printk(KERN_ERR "clock.c: Enable for %s without enable code\n", + clk->name); return 0; } @@ -618,10 +631,6 @@ EXPORT_SYMBOL(clk_unuse); unsigned long clk_get_rate(struct clk *clk) { - if (clk->rate == 0) { - printk("Get rate for %s without cached clock\n", clk->name); - } - return clk->rate; } EXPORT_SYMBOL(clk_get_rate); @@ -869,14 +878,15 @@ int __init clk_init(void) int crystal_type = 0; /* Default 12 MHz */ for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) { - if ((((*clkp)->flags & DOES_NOT_EXIST_ON_1510) && - cpu_is_omap1510()) || - (((*clkp)->flags & DOES_NOT_EXIST_ON_1610) && - (cpu_is_omap1610() || cpu_is_omap1710()))) { - (*clkp)->parent = 0; + if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) { + clk_register(*clkp); + continue; + } + + if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) { + clk_register(*clkp); continue; } - clk_register(*clkp); } info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); @@ -897,14 +907,14 @@ int __init clk_init(void) /* Find the highest supported frequency and enable it */ if (select_table_rate(~0)) { - printk("System frequencies not set. Check your config.\n"); + printk(KERN_ERR "System frequencies not set. Check your config.\n"); /* Guess sane values (60MHz) */ omap_writew(0x2290, DPLL_CTL); omap_writew(0x1005, ARM_CKCTL); ck_dpll1.rate = 60000000; propagate_rate(&ck_dpll1); - printk("Clocking rate (xtal/DPLL1/MPU): %ld/%ld/%ld\n", - ck_ref.rate, ck_dpll1.rate, arm_ck.rate); + printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld/%ld/%ld\n", + ck_ref.rate, ck_dpll1.rate, arm_ck.rate); } /* Cache rates for clocks connected to ck_ref (not dpll1) */ @@ -941,7 +951,5 @@ int __init clk_init(void) if (cpu_is_omap1510()) clk_enable(&arm_gpio_ck); - start_mputimer1(0xffffffff); - return 0; } diff --git a/arch/arm/mach-omap/clock.h b/arch/arm/mach-omap/clock.h index 85881a3b6c3c..f3037bc0b96b 100644 --- a/arch/arm/mach-omap/clock.h +++ b/arch/arm/mach-omap/clock.h @@ -48,8 +48,8 @@ struct mpu_rate { #define VIRTUAL_CLOCK 8 #define ALWAYS_ENABLED 16 #define ENABLE_REG_32BIT 32 -#define DOES_NOT_EXIST_ON_1510 64 -#define DOES_NOT_EXIST_ON_1610 128 /* Including 1710 */ +#define CLOCK_IN_OMAP16XX 64 +#define CLOCK_IN_OMAP1510 128 /* ARM_CKCTL bit shifts */ #define CKCTL_PERDIV_OFFSET 0 diff --git a/arch/arm/mach-omap/common.c b/arch/arm/mach-omap/common.c index c1265197c240..91d9caa957bc 100644 --- a/arch/arm/mach-omap/common.c +++ b/arch/arm/mach-omap/common.c @@ -16,7 +16,8 @@ #include <linux/console.h> #include <linux/serial.h> #include <linux/tty.h> -#include <linux/serial_core.h> +#include <linux/serial_8250.h> +#include <linux/serial_reg.h> #include <asm/hardware.h> #include <asm/system.h> @@ -306,41 +307,72 @@ void omap_map_io(void) _omap_map_io(); } -static struct uart_port omap_serial_ports[] = { +static inline unsigned int omap_serial_in(struct plat_serial8250_port *up, + int offset) +{ + offset <<= up->regshift; + return (unsigned int)__raw_readb(up->membase + offset); +} + +static inline void omap_serial_outp(struct plat_serial8250_port *p, int offset, + int value) +{ + offset <<= p->regshift; + __raw_writeb(value, p->membase + offset); +} + +/* + * Internal UARTs need to be initialized for the 8250 autoconfig to work + * properly. + */ +static void __init omap_serial_reset(struct plat_serial8250_port *p) +{ + omap_serial_outp(p, UART_OMAP_MDR1, 0x07); /* disable UART */ + omap_serial_outp(p, UART_OMAP_MDR1, 0x00); /* enable UART */ + + if (!cpu_is_omap1510()) { + omap_serial_outp(p, UART_OMAP_SYSC, 0x01); + while (!(omap_serial_in(p, UART_OMAP_SYSC) & 0x01)); + } +} + +static struct plat_serial8250_port serial_platform_data[] = { { .membase = (char*)IO_ADDRESS(OMAP_UART1_BASE), .mapbase = (unsigned long)OMAP_UART1_BASE, .irq = INT_UART1, - .flags = UPF_SKIP_TEST, + .flags = UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, .regshift = 2, .uartclk = OMAP16XX_BASE_BAUD * 16, - .line = 0, - .type = PORT_OMAP, - .fifosize = 64 - } , { + }, + { .membase = (char*)IO_ADDRESS(OMAP_UART2_BASE), .mapbase = (unsigned long)OMAP_UART2_BASE, .irq = INT_UART2, - .flags = UPF_SKIP_TEST, + .flags = UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, .regshift = 2, .uartclk = OMAP16XX_BASE_BAUD * 16, - .line = 1, - .type = PORT_OMAP, - .fifosize = 64 - } , { + }, + { .membase = (char*)IO_ADDRESS(OMAP_UART3_BASE), .mapbase = (unsigned long)OMAP_UART3_BASE, .irq = INT_UART3, - .flags = UPF_SKIP_TEST, + .flags = UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, .regshift = 2, .uartclk = OMAP16XX_BASE_BAUD * 16, - .line = 2, - .type = PORT_OMAP, - .fifosize = 64 - } + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, }; /* @@ -353,25 +385,26 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS]) int i; if (cpu_is_omap730()) { - omap_serial_ports[0].regshift = 0; - omap_serial_ports[1].regshift = 0; - omap_serial_ports[0].irq = INT_730_UART_MODEM_1; - omap_serial_ports[1].irq = INT_730_UART_MODEM_IRDA_2; + serial_platform_data[0].regshift = 0; + serial_platform_data[1].regshift = 0; + serial_platform_data[0].irq = INT_730_UART_MODEM_1; + serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2; } if (cpu_is_omap1510()) { - omap_serial_ports[0].uartclk = OMAP1510_BASE_BAUD * 16; - omap_serial_ports[1].uartclk = OMAP1510_BASE_BAUD * 16; - omap_serial_ports[2].uartclk = OMAP1510_BASE_BAUD * 16; + serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16; + serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16; + serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16; } for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { - unsigned long port; - unsigned char regshift; unsigned char reg; - if (ports[i] != 1) + if (ports[i] == 0) { + serial_platform_data[i].membase = 0; + serial_platform_data[i].mapbase = 0; continue; + } switch (i) { case 0: @@ -382,7 +415,7 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS]) reg = fpga_read(OMAP1510_FPGA_POWER); reg |= OMAP1510_FPGA_PCR_COM1_EN; fpga_write(reg, OMAP1510_FPGA_POWER); - udelay(1); + udelay(10); } } break; @@ -394,7 +427,7 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS]) reg = fpga_read(OMAP1510_FPGA_POWER); reg |= OMAP1510_FPGA_PCR_COM2_EN; fpga_write(reg, OMAP1510_FPGA_POWER); - udelay(1); + udelay(10); } } break; @@ -405,19 +438,16 @@ void __init omap_serial_init(int ports[OMAP_MAX_NR_PORTS]) } break; } - - /* Reset port */ - if (!cpu_is_omap1510()) { - port = (unsigned long)omap_serial_ports[i].membase; - regshift = omap_serial_ports[i].regshift; - writeb(0x01, port + (UART_SYSC << regshift)); - while (!(readb(port + (UART_SYSC << regshift)) & 0x01)); - } - - //early_serial_setup(&omap_serial_ports[i]); + omap_serial_reset(&serial_platform_data[i]); } } +static int __init omap_init(void) +{ + return platform_device_register(&serial_device); +} +arch_initcall(omap_init); + #define NO_LENGTH_CHECK 0xffffffff extern int omap_bootloader_tag_len; diff --git a/arch/arm/mach-pxa/ssp.c b/arch/arm/mach-pxa/ssp.c index df9455e1e9dc..50132a7c640c 100644 --- a/arch/arm/mach-pxa/ssp.c +++ b/arch/arm/mach-pxa/ssp.c @@ -185,7 +185,7 @@ int ssp_init(struct ssp_dev *dev, u32 port, u32 mode, u32 flags, u32 psp_flags, { int ret, irq; - if (!request_mem_region(__PREG(SSCR0_P(dev->port)), 0x2c, "SSP")) { + if (!request_mem_region(__PREG(SSCR0_P(port)), 0x2c, "SSP")) { return -EBUSY; } diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index cfef7e72cb1b..2f60dea2a8a1 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c @@ -16,6 +16,7 @@ #include <linux/init.h> #include <linux/sched.h> #include <linux/device.h> +#include <linux/serial_8250.h> #include <asm/elf.h> #include <asm/io.h> @@ -130,9 +131,30 @@ static struct platform_device kbd_device = { }, }; +static struct plat_serial8250_port serial_platform_data[] = { + { + .mapbase = 0x03010fe0, + .irq = 10, + .uartclk = 1843200, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + static struct platform_device *devs[] __initdata = { &iomd_device, &kbd_device, + &serial_device, &acornfb_device, }; diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c index dc0a5d2bda1d..772f0309ee91 100644 --- a/arch/arm/mach-s3c2410/cpu.c +++ b/arch/arm/mach-s3c2410/cpu.c @@ -66,7 +66,7 @@ static struct cpu_table cpu_ids[] __initdata = { .name = name_s3c2410 }, { - .idcode = 0x3241002, + .idcode = 0x32410002, .idmask = 0xffffffff, .map_io = s3c2410_map_io, .init = s3c2410_init, diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c index 8996725e9b98..129f29dbd3f8 100644 --- a/arch/arm/mach-s3c2410/gpio.c +++ b/arch/arm/mach-s3c2410/gpio.c @@ -28,6 +28,7 @@ * 01-Oct-2004 BJD Fixed mask bug in pullup() call * 01-Oct-2004 BJD Added getirq() to turn pin into irqno * 04-Oct-2004 BJD Added irq filter controls for GPIO + * 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code */ @@ -66,6 +67,8 @@ void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) local_irq_restore(flags); } +EXPORT_SYMBOL(s3c2410_gpio_cfgpin); + unsigned int s3c2410_gpio_getcfg(unsigned int pin) { unsigned long base = S3C2410_GPIO_BASE(pin); @@ -80,6 +83,8 @@ unsigned int s3c2410_gpio_getcfg(unsigned int pin) return __raw_readl(base) & mask; } +EXPORT_SYMBOL(s3c2410_gpio_getcfg); + void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) { unsigned long base = S3C2410_GPIO_BASE(pin); @@ -100,6 +105,8 @@ void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) local_irq_restore(flags); } +EXPORT_SYMBOL(s3c2410_gpio_pullup); + void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) { unsigned long base = S3C2410_GPIO_BASE(pin); @@ -117,6 +124,8 @@ void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) local_irq_restore(flags); } +EXPORT_SYMBOL(s3c2410_gpio_setpin); + unsigned int s3c2410_gpio_getpin(unsigned int pin) { unsigned long base = S3C2410_GPIO_BASE(pin); @@ -125,6 +134,8 @@ unsigned int s3c2410_gpio_getpin(unsigned int pin) return __raw_readl(base + 0x04) & (1<< offs); } +EXPORT_SYMBOL(s3c2410_gpio_getpin); + unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) { unsigned long flags; @@ -140,6 +151,8 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) return misccr; } +EXPORT_SYMBOL(s3c2410_modify_misccr); + int s3c2410_gpio_getirq(unsigned int pin) { if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15_EINT23) @@ -157,6 +170,8 @@ int s3c2410_gpio_getirq(unsigned int pin) return (pin - S3C2410_GPG0) + IRQ_EINT8; } +EXPORT_SYMBOL(s3c2410_gpio_getirq); + int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, unsigned int config) { @@ -192,3 +207,5 @@ int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, return 0; } + +EXPORT_SYMBOL(s3c2410_gpio_irqfilter); diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index 02a65bbd9410..a8a48f743047 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -36,6 +36,9 @@ * * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk> * Add support for power management controls + * + * 04-Nov-2004 Ben Dooks + * Fix standard IRQ wake for EINT0..4 and RTC */ #include <linux/init.h> @@ -91,7 +94,7 @@ s3c_irq_wake(unsigned int irqno, unsigned int state) if (!state) s3c_irqwake_intmask |= irqbit; else - s3c_irqwake_intmask &= irqbit; + s3c_irqwake_intmask &= ~irqbit; return 0; } diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c index b0676661cfeb..11bf601cc5ed 100644 --- a/arch/arm/mach-s3c2410/pm.c +++ b/arch/arm/mach-s3c2410/pm.c @@ -23,6 +23,7 @@ * * Parts based on arch/arm/mach-pxa/pm.c * + * Thanks to Dimitry Andric for debugging */ #include <linux/config.h> @@ -33,10 +34,12 @@ #include <linux/interrupt.h> #include <linux/crc32.h> #include <linux/ioport.h> +#include <linux/delay.h> #include <asm/hardware.h> #include <asm/io.h> +#include <asm/arch/regs-serial.h> #include <asm/arch/regs-clock.h> #include <asm/arch/regs-gpio.h> #include <asm/arch/regs-mem.h> @@ -68,7 +71,21 @@ struct sleep_save { static struct sleep_save core_save[] = { SAVE_ITEM(S3C2410_LOCKTIME), - SAVE_ITEM(S3C2410_CLKCON) + SAVE_ITEM(S3C2410_CLKCON), + + /* we restore the timings here, with the proviso that the board + * brings the system up in an slower, or equal frequency setting + * to the original system. + * + * if we cannot guarantee this, then things are going to go very + * wrong here, as we modify the refresh and both pll settings. + */ + + SAVE_ITEM(S3C2410_REFRESH), + SAVE_ITEM(S3C2410_MPLLCON), + SAVE_ITEM(S3C2410_UPLLCON), + SAVE_ITEM(S3C2410_CLKDIVN), + SAVE_ITEM(S3C2410_CLKSLOW), }; /* this lot should be really saved by the IRQ code */ @@ -115,6 +132,20 @@ static struct sleep_save gpio_save[] = { }; #ifdef CONFIG_S3C2410_PM_DEBUG + +#define SAVE_UART(va) \ + SAVE_ITEM((va) + S3C2410_ULCON), \ + SAVE_ITEM((va) + S3C2410_UCON), \ + SAVE_ITEM((va) + S3C2410_UFCON), \ + SAVE_ITEM((va) + S3C2410_UMCON), \ + SAVE_ITEM((va) + S3C2410_UBRDIV) + +static struct sleep_save uart_save[] = { + SAVE_UART(S3C2410_VA_UART0), + SAVE_UART(S3C2410_VA_UART1), + SAVE_UART(S3C2410_VA_UART2), +}; + /* debug * * we send the debug to printascii() to allow it to be seen if the @@ -135,10 +166,24 @@ static void pm_dbg(const char *fmt, ...) printascii(buff); } +static void s3c2410_pm_debug_init(void) +{ + unsigned long tmp = __raw_readl(S3C2410_CLKCON); + + /* re-start uart clocks */ + tmp |= S3C2410_CLKCON_UART0; + tmp |= S3C2410_CLKCON_UART1; + tmp |= S3C2410_CLKCON_UART2; + + __raw_writel(tmp, S3C2410_CLKCON); + udelay(10); +} #define DBG(fmt...) pm_dbg(fmt) #else #define DBG(fmt...) printk(KERN_DEBUG fmt) + +#define s3c2410_pm_debug_init() do { } while(0) #endif #if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0 @@ -329,6 +374,9 @@ static void s3c2410_pm_check_restore(void) } #else + +static struct sleep_save uart_save[] = {}; + #define s3c2410_pm_check_prepare() do { } while(0) #define s3c2410_pm_check_restore() do { } while(0) #define s3c2410_pm_check_store() do { } while(0) @@ -344,12 +392,20 @@ static void s3c2410_pm_do_save(struct sleep_save *ptr, int count) } } +/* s3c2410_pm_do_restore + * + * restore the system from the given list of saved registers + * + * Note, we do not use DBG() in here, as the system may not have + * restore the UARTs state yet +*/ static void s3c2410_pm_do_restore(struct sleep_save *ptr, int count) { for (; count > 0; count--, ptr++) { - DBG("restore %08lx (restore %08lx, current %08x)\n", - ptr->reg, ptr->val, __raw_readl(ptr->reg)); + printk(KERN_DEBUG "restore %08lx (restore %08lx, was %08x)\n", + ptr->reg, ptr->val, __raw_readl(ptr->reg)); + __raw_writel(ptr->val, ptr->reg); } } @@ -434,11 +490,15 @@ static void s3c2410_pm_configure_extint(void) * central control for sleep/resume process */ -static int s3c2410_pm_enter(u32 state) +static int s3c2410_pm_enter(suspend_state_t state) { unsigned long regs_save[16]; unsigned long tmp; + /* ensure the debug is initialised (if enabled) */ + + s3c2410_pm_debug_init(); + DBG("s3c2410_pm_enter(%d)\n", state); if (state != PM_SUSPEND_MEM) { @@ -480,6 +540,7 @@ static int s3c2410_pm_enter(u32 state) s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save)); s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save)); + s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save)); /* set the irq configuration for wake */ @@ -493,7 +554,7 @@ static int s3c2410_pm_enter(u32 state) /* ack any outstanding external interrupts before we go to sleep */ - __raw_writel(S3C2410_EINTPEND, __raw_readl(S3C2410_EINTPEND)); + __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND); /* flush cache back to ram */ @@ -512,9 +573,18 @@ static int s3c2410_pm_enter(u32 state) /* unset the return-from-sleep flag, to ensure reset */ tmp = __raw_readl(S3C2410_GSTATUS2); - tmp &= S3C2410_GSTATUs2_OFFRESET; + tmp &= S3C2410_GSTATUS2_OFFRESET; __raw_writel(tmp, S3C2410_GSTATUS2); + /* restore the system state */ + + s3c2410_pm_do_restore(core_save, ARRAY_SIZE(core_save)); + s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); + s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); + s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save)); + + s3c2410_pm_debug_init(); + /* check what irq (if any) restored the system */ DBG("post sleep: IRQs 0x%08x, 0x%08x\n", @@ -527,12 +597,6 @@ static int s3c2410_pm_enter(u32 state) s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND), s3c_irqwake_eintmask); - DBG("post sleep, restoring state...\n"); - - s3c2410_pm_do_restore(core_save, ARRAY_SIZE(core_save)); - s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save)); - s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); - DBG("post sleep, preparing to return\n"); s3c2410_pm_check_restore(); @@ -546,7 +610,7 @@ static int s3c2410_pm_enter(u32 state) /* * Called after processes are frozen, but before we shut down devices. */ -static int s3c2410_pm_prepare(u32 state) +static int s3c2410_pm_prepare(suspend_state_t state) { return 0; } @@ -554,7 +618,7 @@ static int s3c2410_pm_prepare(u32 state) /* * Called after devices are re-setup, but before processes are thawed. */ -static int s3c2410_pm_finish(u32 state) +static int s3c2410_pm_finish(suspend_state_t state) { return 0; } diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S index f41384266e65..61768dac7fee 100644 --- a/arch/arm/mach-s3c2410/sleep.S +++ b/arch/arm/mach-s3c2410/sleep.S @@ -35,7 +35,10 @@ #include <asm/arch/regs-mem.h> #include <asm/arch/regs-serial.h> -#define CONFIG_DEBUG_RESUME +/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not + * reset the UART configuration, only enable if you really need this! +*/ +//#define CONFIG_DEBUG_RESUME .text @@ -133,6 +136,15 @@ ENTRY(s3c2410_cpu_resume) mov r2, #S3C2410_PA_UART & 0xff000000 orr r2, r2, #S3C2410_PA_UART & 0xff000 +#if 0 + /* SMDK2440 LED set */ + mov r14, #S3C2410_PA_GPIO + ldr r12, [ r14, #0x54 ] + bic r12, r12, #3<<4 + orr r12, r12, #1<<7 + str r12, [ r14, #0x54 ] +#endif + #ifdef CONFIG_DEBUG_RESUME mov r3, #'L' strb r3, [ r2, #S3C2410_UTXH ] diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 4fe5a5a4a8c8..8ea4f8fbbd89 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -161,7 +161,7 @@ static u64 sa11x0udc_dma_mask = 0xffffffffUL; static struct platform_device sa11x0udc_device = { .name = "sa11x0-udc", - .id = 0, + .id = -1, .dev = { .dma_mask = &sa11x0udc_dma_mask, .coherent_dma_mask = 0xffffffff, @@ -212,7 +212,7 @@ static u64 sa11x0mcp_dma_mask = 0xffffffffUL; static struct platform_device sa11x0mcp_device = { .name = "sa11x0-mcp", - .id = 0, + .id = -1, .dev = { .dma_mask = &sa11x0mcp_dma_mask, .coherent_dma_mask = 0xffffffff, @@ -233,7 +233,7 @@ static u64 sa11x0ssp_dma_mask = 0xffffffffUL; static struct platform_device sa11x0ssp_device = { .name = "sa11x0-ssp", - .id = 0, + .id = -1, .dev = { .dma_mask = &sa11x0ssp_dma_mask, .coherent_dma_mask = 0xffffffff, @@ -257,7 +257,7 @@ static struct resource sa11x0fb_resources[] = { static struct platform_device sa11x0fb_device = { .name = "sa11x0-fb", - .id = 0, + .id = -1, .dev = { .coherent_dma_mask = 0xffffffff, }, @@ -267,7 +267,7 @@ static struct platform_device sa11x0fb_device = { static struct platform_device sa11x0pcmcia_device = { .name = "sa11x0-pcmcia", - .id = 0, + .id = -1, }; static struct platform_device *sa11x0_devices[] __initdata = { diff --git a/arch/arm/mach-sa1100/trizeps.c b/arch/arm/mach-sa1100/trizeps.c index 8012c554b09a..2662449e0d16 100644 --- a/arch/arm/mach-sa1100/trizeps.c +++ b/arch/arm/mach-sa1100/trizeps.c @@ -20,6 +20,7 @@ #include <linux/errno.h> #include <linux/delay.h> #include <linux/pm.h> +#include <linux/serial_8250.h> #include <asm/mach-types.h> #include <asm/hardware.h> @@ -32,9 +33,6 @@ #include <asm/mach/map.h> #include <asm/mach/irq.h> #include <asm/mach/serial_sa1100.h> -#include <linux/serial_core.h> -#include <linux/serial_reg.h> -#include <asm/arch/serial.h> #include <asm/io.h> #include <asm/irq.h> @@ -178,6 +176,34 @@ static void trizeps_power_off(void) PMCR = PMCR_SF; } +static struct plat_serial8250_port serial_platform_data[] = { + { + .mapbase = TRIZEPS_UART5, + .irq = IRQ_GPIO16, + .uartclk = 24000000, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .mapbase = TRIZEPS_UART6, + .irq = IRQ_GPIO17, + .uartclk = 24000000, + .regshift = 0, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + static int __init trizeps_init(void) { if (!machine_is_trizeps()) @@ -201,6 +227,8 @@ static int __init trizeps_init(void) set_irq_type(IRQ_GPIO16, IRQT_RISING); set_irq_type(IRQ_GPIO17, IRQT_RISING); + platform_device_register(&serial_device); + return 0; } diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index 4b6b582244dd..81881e922716 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c @@ -7,6 +7,7 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/sched.h> +#include <linux/serial_8250.h> #include <asm/setup.h> #include <asm/mach-types.h> @@ -18,6 +19,46 @@ #include <asm/mach/arch.h> #include <asm/mach/time.h> +static struct plat_serial8250_port serial_platform_data[] = { + { + .iobase = 0x3f8, + .irq = 4, + .uartclk = 1843200, + .regshift = 2, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { + .iobase = 0x2f8, + .irq = 3, + .uartclk = 1843200, + .regshift = 2, + .iotype = UPIO_PORT, + .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device serial_device = { + .name = "serial8250", + .id = 0, + .dev = { + .platform_data = serial_platform_data, + }, +}; + +static int __init shark_init(void) +{ + int ret; + + if (machine_is_shark()) + ret = platform_device_register(&serial_device); + + return ret; +} + +arch_initcall(shark_init); + extern void shark_init_irq(void); static struct map_desc shark_io_desc[] __initdata = { diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig new file mode 100644 index 000000000000..3969d775b5eb --- /dev/null +++ b/arch/arm/mach-versatile/Kconfig @@ -0,0 +1,16 @@ +menu "Versatile platform type" + depends on ARCH_VERSATILE + +config ARCH_VERSATILE_PB + bool "Support Versatile/PB platform" + default y + help + Include support for the ARM(R) Versatile/PB platform. + +config ARCH_VERSATILE_AB + bool "Support Versatile/AB platform" + default n + help + Include support for the ARM(R) Versatile/AP platform. + +endmenu diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile index ff886e33ea19..931aa0d29bbd 100644 --- a/arch/arm/mach-versatile/Makefile +++ b/arch/arm/mach-versatile/Makefile @@ -3,3 +3,5 @@ # obj-y := core.o clock.o +obj-$(CONFIG_ARCH_VERSATILE_PB) += versatile_pb.o +obj-$(CONFIG_ARCH_VERSATILE_AB) += versatile_ab.o diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c index 24f12bdfb855..48025c2b9987 100644 --- a/arch/arm/mach-versatile/clock.c +++ b/arch/arm/mach-versatile/clock.c @@ -16,7 +16,7 @@ #include <asm/semaphore.h> #include <asm/hardware/clock.h> -#include <asm/hardware/icst525.h> +#include <asm/hardware/icst307.h> #include "clock.h" @@ -83,12 +83,12 @@ EXPORT_SYMBOL(clk_round_rate); int clk_set_rate(struct clk *clk, unsigned long rate) { int ret = -EIO; -#if 0 // Not yet + if (clk->setvco) { - struct icst525_vco vco; + struct icst307_vco vco; - vco = icst525_khz_to_vco(clk->params, rate / 1000); - clk->rate = icst525_khz(clk->params, vco) * 1000; + vco = icst307_khz_to_vco(clk->params, rate / 1000); + clk->rate = icst307_khz(clk->params, vco) * 1000; printk("Clock %s: setting VCO reg params: S=%d R=%d V=%d\n", clk->name, vco.s, vco.r, vco.v); @@ -96,7 +96,6 @@ int clk_set_rate(struct clk *clk, unsigned long rate) clk->setvco(clk, vco); ret = 0; } -#endif return ret; } EXPORT_SYMBOL(clk_set_rate); diff --git a/arch/arm/mach-versatile/clock.h b/arch/arm/mach-versatile/clock.h index 12e68ecdeeed..8b0b61dd17e4 100644 --- a/arch/arm/mach-versatile/clock.h +++ b/arch/arm/mach-versatile/clock.h @@ -9,16 +9,16 @@ * published by the Free Software Foundation. */ struct module; -struct icst525_params; +struct icst307_params; struct clk { struct list_head node; unsigned long rate; struct module *owner; const char *name; - const struct icst525_params *params; + const struct icst307_params *params; void *data; - void (*setvco)(struct clk *, struct icst525_vco vco); + void (*setvco)(struct clk *, struct icst307_vco vco); }; int clk_register(struct clk *clk); diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index ff9e8b34bff8..52d824f507a2 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -33,15 +33,17 @@ #include <asm/mach-types.h> #include <asm/hardware/amba.h> #include <asm/hardware/amba_clcd.h> +#include <asm/hardware/icst307.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> #include <asm/mach/map.h> -#ifdef CONFIG_MMC #include <asm/mach/mmc.h> -#endif + +#include "core.h" +#include "clock.h" /* * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx @@ -111,19 +113,17 @@ sic_handle_irq(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) #if 1 #define IRQ_MMCI0A IRQ_VICSOURCE22 -#define IRQ_MMCI1A IRQ_VICSOURCE23 #define IRQ_AACI IRQ_VICSOURCE24 #define IRQ_ETH IRQ_VICSOURCE25 #define PIC_MASK 0xFFD00000 #else #define IRQ_MMCI0A IRQ_SIC_MMCI0A -#define IRQ_MMCI1A IRQ_SIC_MMCI1A #define IRQ_AACI IRQ_SIC_AACI #define IRQ_ETH IRQ_SIC_ETH #define PIC_MASK 0 #endif -static void __init versatile_init_irq(void) +void __init versatile_init_irq(void) { unsigned int i, value; @@ -189,6 +189,10 @@ static struct map_desc versatile_io_desc[] __initdata = { { IO_ADDRESS(VERSATILE_SIC_BASE), VERSATILE_SIC_BASE, SZ_4K, MT_DEVICE }, { IO_ADDRESS(VERSATILE_VIC_BASE), VERSATILE_VIC_BASE, SZ_4K, MT_DEVICE }, { IO_ADDRESS(VERSATILE_SCTL_BASE), VERSATILE_SCTL_BASE, SZ_4K * 9, MT_DEVICE }, +#ifdef CONFIG_ARCH_VERSATILE_AB + { IO_ADDRESS(VERSATILE_GPIO0_BASE), VERSATILE_GPIO0_BASE, SZ_4K, MT_DEVICE }, + { IO_ADDRESS(VERSATILE_IB2_BASE), VERSATILE_IB2_BASE, SZ_64M, MT_DEVICE }, +#endif #ifdef CONFIG_DEBUG_LL { IO_ADDRESS(VERSATILE_UART0_BASE), VERSATILE_UART0_BASE, SZ_4K, MT_DEVICE }, #endif @@ -200,7 +204,7 @@ static struct map_desc versatile_io_desc[] __initdata = { #endif }; -static void __init versatile_map_io(void) +void __init versatile_map_io(void) { iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc)); } @@ -208,7 +212,7 @@ static void __init versatile_map_io(void) #define VERSATILE_REFCOUNTER (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET) /* - * This is the VersatilePB sched_clock implementation. This has + * This is the Versatile sched_clock implementation. This has * a resolution of 41.7ns, and a maximum value of about 179s. */ unsigned long long sched_clock(void) @@ -302,8 +306,7 @@ static struct platform_device smc91x_device = { #define VERSATILE_SYSMCI (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET) -#ifdef CONFIG_MMC -static unsigned int mmc_status(struct device *dev) +unsigned int mmc_status(struct device *dev) { struct amba_device *adev = container_of(dev, struct amba_device, dev); u32 mask; @@ -321,20 +324,50 @@ static struct mmc_platform_data mmc0_plat_data = { .status = mmc_status, }; -static struct mmc_platform_data mmc1_plat_data = { - .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, - .status = mmc_status, +/* + * Clock handling + */ +static const struct icst307_params versatile_oscvco_params = { + .ref = 24000, + .vco_max = 200000, + .vd_min = 4 + 8, + .vd_max = 511 + 8, + .rd_min = 1 + 2, + .rd_max = 127 + 2, }; + +static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco) +{ + unsigned long sys_lock = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET; +#if defined(CONFIG_ARCH_VERSATILE_PB) + unsigned long sys_osc = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC4_OFFSET; +#elif defined(CONFIG_ARCH_VERSATILE_AB) + unsigned long sys_osc = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSC1_OFFSET; #endif + u32 val; + + val = readl(sys_osc) & ~0x7ffff; + val |= vco.v | (vco.r << 9) | (vco.s << 16); + + writel(0xa05f, sys_lock); + writel(val, sys_osc); + writel(0, sys_lock); +} + +static struct clk versatile_clcd_clk = { + .name = "CLCDCLK", + .params = &versatile_oscvco_params, + .setvco = versatile_oscvco_set, +}; /* * CLCD support. */ #define SYS_CLCD_MODE_MASK (3 << 0) -#define SYS_CLCD_MODE_5551 (0 << 0) -#define SYS_CLCD_MODE_565 (1 << 0) -#define SYS_CLCD_MODE_888 (2 << 0) -#define SYS_CLCD_MODE_LT (3 << 0) +#define SYS_CLCD_MODE_888 (0 << 0) +#define SYS_CLCD_MODE_5551 (1 << 0) +#define SYS_CLCD_MODE_565_RLSB (2 << 0) +#define SYS_CLCD_MODE_565_BLSB (3 << 0) #define SYS_CLCD_NLCDIOON (1 << 2) #define SYS_CLCD_VDDPOSSWITCH (1 << 3) #define SYS_CLCD_PWR3V5SWITCH (1 << 4) @@ -342,6 +375,7 @@ static struct mmc_platform_data mmc1_plat_data = { #define SYS_CLCD_ID_SANYO_3_8 (0x00 << 8) #define SYS_CLCD_ID_UNKNOWN_8_4 (0x01 << 8) #define SYS_CLCD_ID_EPSON_2_2 (0x02 << 8) +#define SYS_CLCD_ID_SANYO_2_5 (0x07 << 8) #define SYS_CLCD_ID_VGA (0x1f << 8) static struct clcd_panel vga = { @@ -390,6 +424,29 @@ static struct clcd_panel sanyo_3_8_in = { .bpp = 16, }; +static struct clcd_panel sanyo_2_5_in = { + .mode = { + .name = "Sanyo QVGA Portrait", + .refresh = 116, + .xres = 240, + .yres = 320, + .pixclock = 100000, + .left_margin = 20, + .right_margin = 10, + .upper_margin = 2, + .lower_margin = 2, + .hsync_len = 10, + .vsync_len = 2, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, + .vmode = FB_VMODE_NONINTERLACED, + }, + .width = -1, + .height = -1, + .tim2 = TIM2_IVS | TIM2_IHS | TIM2_IPC, + .cntl = CNTL_LCDTFT | CNTL_LCDVCOMP(1), + .bpp = 16, +}; + static struct clcd_panel epson_2_2_in = { .mode = { .name = "Epson QCIF", @@ -428,6 +485,8 @@ static struct clcd_panel *versatile_clcd_panel(void) val = readl(sys_clcd) & SYS_CLCD_ID_MASK; if (val == SYS_CLCD_ID_SANYO_3_8) panel = &sanyo_3_8_in; + else if (val == SYS_CLCD_ID_SANYO_2_5) + panel = &sanyo_2_5_in; else if (val == SYS_CLCD_ID_EPSON_2_2) panel = &epson_2_2_in; else if (val == SYS_CLCD_ID_VGA) @@ -435,9 +494,10 @@ static struct clcd_panel *versatile_clcd_panel(void) else { printk(KERN_ERR "CLCD: unknown LCD panel ID 0x%08x, using VGA\n", val); + panel = &vga; } - return &vga; + return panel; } /* @@ -451,6 +511,20 @@ static void versatile_clcd_disable(struct clcd_fb *fb) val = readl(sys_clcd); val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH; writel(val, sys_clcd); + +#ifdef CONFIG_ARCH_VERSATILE_AB + /* + * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light off + */ + if (fb->panel == &sanyo_2_5_in) { + unsigned long versatile_ib2_ctrl = IO_ADDRESS(VERSATILE_IB2_CTRL); + unsigned long ctrl; + + ctrl = readl(versatile_ib2_ctrl); + ctrl &= ~0x01; + writel(ctrl, versatile_ib2_ctrl); + } +#endif } /* @@ -466,19 +540,10 @@ static void versatile_clcd_enable(struct clcd_fb *fb) switch (fb->fb.var.green.length) { case 5: -#if 0 - /* - * For some undocumented reason, we need to select 565 mode - * even when using 555 with VGA. Maybe this is only true - * for the VGA output and needs to be done for LCD panels? - * I can't get an explaination from the people who should - * know. - */ val |= SYS_CLCD_MODE_5551; break; -#endif case 6: - val |= SYS_CLCD_MODE_565; + val |= SYS_CLCD_MODE_565_BLSB; break; case 8: val |= SYS_CLCD_MODE_888; @@ -495,6 +560,20 @@ static void versatile_clcd_enable(struct clcd_fb *fb) */ val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH; writel(val, sys_clcd); + +#ifdef CONFIG_ARCH_VERSATILE_AB + /* + * If the LCD is Sanyo 2x5 in on the IB2 board, turn the back-light on + */ + if (fb->panel == &sanyo_2_5_in) { + unsigned long versatile_ib2_ctrl = IO_ADDRESS(VERSATILE_IB2_CTRL); + unsigned long ctrl; + + ctrl = readl(versatile_ib2_ctrl); + ctrl |= 0x01; + writel(ctrl, versatile_ib2_ctrl); + } +#endif } static unsigned long framesize = SZ_1M; @@ -525,7 +604,7 @@ static void versatile_clcd_remove(struct clcd_fb *fb) } static struct clcd_board clcd_plat_data = { - .name = "Versatile PB", + .name = "Versatile", .check = clcdfb_check, .decode = clcdfb_decode, .disable = versatile_clcd_disable, @@ -534,23 +613,6 @@ static struct clcd_board clcd_plat_data = { .remove = versatile_clcd_remove, }; -#define AMBA_DEVICE(name,busid,base,plat) \ -static struct amba_device name##_device = { \ - .dev = { \ - .coherent_dma_mask = ~0, \ - .bus_id = busid, \ - .platform_data = plat, \ - }, \ - .res = { \ - .start = VERSATILE_##base##_BASE, \ - .end = (VERSATILE_##base##_BASE) + SZ_4K - 1,\ - .flags = IORESOURCE_MEM, \ - }, \ - .dma_mask = ~0, \ - .irq = base##_IRQ, \ - /* .dma = base##_DMA,*/ \ -} - #define AACI_IRQ { IRQ_AACI, NO_IRQ } #define AACI_DMA { 0x80, 0x81 } #define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B } @@ -559,12 +621,6 @@ static struct amba_device name##_device = { \ #define KMI0_DMA { 0, 0 } #define KMI1_IRQ { IRQ_SIC_KMI1, NO_IRQ } #define KMI1_DMA { 0, 0 } -#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ } -#define UART3_DMA { 0x86, 0x87 } -#define SCI1_IRQ { IRQ_SIC_SCI3, NO_IRQ } -#define SCI1_DMA { 0x88, 0x89 } -#define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B } -#define MMCI1_DMA { 0x85, 0 } /* * These devices are connected directly to the multi-layer AHB switch @@ -589,10 +645,6 @@ static struct amba_device name##_device = { \ #define GPIO0_DMA { 0, 0 } #define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ } #define GPIO1_DMA { 0, 0 } -#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ } -#define GPIO2_DMA { 0, 0 } -#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ } -#define GPIO3_DMA { 0, 0 } #define RTC_IRQ { IRQ_RTCINT, NO_IRQ } #define RTC_DMA { 0, 0 } @@ -612,16 +664,9 @@ static struct amba_device name##_device = { \ /* FPGA Primecells */ AMBA_DEVICE(aaci, "fpga:04", AACI, NULL); -#ifdef CONFIG_MMC AMBA_DEVICE(mmc0, "fpga:05", MMCI0, &mmc0_plat_data); -#endif AMBA_DEVICE(kmi0, "fpga:06", KMI0, NULL); AMBA_DEVICE(kmi1, "fpga:07", KMI1, NULL); -AMBA_DEVICE(uart3, "fpga:09", UART3, NULL); -AMBA_DEVICE(sci1, "fpga:0a", SCI1, NULL); -#ifdef CONFIG_MMC -AMBA_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data); -#endif /* DevChip Primecells */ AMBA_DEVICE(smc, "dev:00", SMC, NULL); @@ -632,8 +677,6 @@ AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL); AMBA_DEVICE(wdog, "dev:e1", WATCHDOG, NULL); AMBA_DEVICE(gpio0, "dev:e4", GPIO0, NULL); AMBA_DEVICE(gpio1, "dev:e5", GPIO1, NULL); -AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); -AMBA_DEVICE(gpio3, "dev:e7", GPIO3, NULL); AMBA_DEVICE(rtc, "dev:e8", RTC, NULL); AMBA_DEVICE(sci0, "dev:f0", SCI, NULL); AMBA_DEVICE(uart0, "dev:f1", UART0, NULL); @@ -646,7 +689,6 @@ static struct amba_device *amba_devs[] __initdata = { &uart0_device, &uart1_device, &uart2_device, - &uart3_device, &smc_device, &mpmc_device, &clcd_device, @@ -654,23 +696,16 @@ static struct amba_device *amba_devs[] __initdata = { &wdog_device, &gpio0_device, &gpio1_device, - &gpio2_device, - &gpio3_device, &rtc_device, &sci0_device, &ssp0_device, &aaci_device, -#ifdef CONFIG_MMC &mmc0_device, -#endif &kmi0_device, &kmi1_device, - &sci1_device, -#ifdef CONFIG_MMC - &mmc1_device, -#endif }; +#ifdef CONFIG_LEDS #define VA_LEDS_BASE (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET) static void versatile_leds_event(led_event_t ledevt) @@ -705,11 +740,14 @@ static void versatile_leds_event(led_event_t ledevt) writel(val, VA_LEDS_BASE); local_irq_restore(flags); } +#endif /* CONFIG_LEDS */ -static void __init versatile_init(void) +void __init versatile_init(void) { int i; + clk_register(&versatile_clcd_clk); + platform_device_register(&versatile_flash_device); platform_device_register(&smc91x_device); @@ -718,7 +756,9 @@ static void __init versatile_init(void) amba_device_register(d, &iomem_resource); } +#ifdef CONFIG_LEDS leds_event = versatile_leds_event; +#endif } /* @@ -863,17 +903,7 @@ static void __init versatile_timer_init(void) setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq); } -static struct sys_timer versatile_timer = { +struct sys_timer versatile_timer = { .init = versatile_timer_init, .offset = versatile_gettimeoffset, }; - -MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000) - BOOT_PARAMS(0x00000100) - MAPIO(versatile_map_io) - INITIRQ(versatile_init_irq) - .timer = &versatile_timer, - INIT_MACHINE(versatile_init) -MACHINE_END diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h new file mode 100644 index 000000000000..588c20669d5d --- /dev/null +++ b/arch/arm/mach-versatile/core.h @@ -0,0 +1,50 @@ +/* + * linux/arch/arm/mach-versatile/core.h + * + * Copyright (C) 2004 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __ASM_ARCH_VERSATILE_H +#define __ASM_ARCH_VERSATILE_H + +#include <asm/hardware/amba.h> + +extern void __init versatile_init(void); +extern void __init versatile_init_irq(void); +extern void __init versatile_map_io(void); +extern struct sys_timer versatile_timer; +extern unsigned int mmc_status(struct device *dev); + +#define AMBA_DEVICE(name,busid,base,plat) \ +static struct amba_device name##_device = { \ + .dev = { \ + .coherent_dma_mask = ~0, \ + .bus_id = busid, \ + .platform_data = plat, \ + }, \ + .res = { \ + .start = VERSATILE_##base##_BASE, \ + .end = (VERSATILE_##base##_BASE) + SZ_4K - 1,\ + .flags = IORESOURCE_MEM, \ + }, \ + .dma_mask = ~0, \ + .irq = base##_IRQ, \ + /* .dma = base##_DMA,*/ \ +} + +#endif diff --git a/include/asm-arm/arch-versatile/serial.h b/arch/arm/mach-versatile/versatile_ab.c index f578f8910b3e..d332084586cf 100644 --- a/include/asm-arm/arch-versatile/serial.h +++ b/arch/arm/mach-versatile/versatile_ab.c @@ -1,7 +1,8 @@ /* - * linux/include/asm-arm/arch-versatile/serial.h + * linux/arch/arm/mach-versatile/versatile_ab.c * - * Copyright (C) 2003 ARM Limited + * Copyright (C) 2004 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,21 +18,28 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef __ASM_ARCH_SERIAL_H -#define __ASM_ARCH_SERIAL_H -/* - * This assumes you have a 14.7456 MHz clock UART. - */ -#define BASE_BAUD 115200 +#include <linux/config.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/sysdev.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> +#include <asm/hardware/amba.h> - /* UART CLK PORT IRQ FLAGS */ -#define STD_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0, 0, ASYNC_SKIP_TEST }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0, 0, ASYNC_SKIP_TEST }, /* ttyS1 */ \ - { 0, BASE_BAUD, 0, 0, ASYNC_SKIP_TEST }, /* ttyS2 */ \ - { 0, BASE_BAUD, 0, 0, ASYNC_SKIP_TEST }, /* ttyS3 */ +#include <asm/mach/arch.h> -#define EXTRA_SERIAL_PORT_DEFNS +#include "core.h" -#endif +MACHINE_START(VERSATILE_AB, "ARM-Versatile AB") + MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") + BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000) + BOOT_PARAMS(0x00000100) + MAPIO(versatile_map_io) + INITIRQ(versatile_init_irq) + .timer = &versatile_timer, + INIT_MACHINE(versatile_init) +MACHINE_END diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c new file mode 100644 index 000000000000..2702099a68f3 --- /dev/null +++ b/arch/arm/mach-versatile/versatile_pb.c @@ -0,0 +1,109 @@ +/* + * linux/arch/arm/mach-versatile/versatile_pb.c + * + * Copyright (C) 2004 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/config.h> +#include <linux/init.h> +#include <linux/device.h> +#include <linux/sysdev.h> + +#include <asm/hardware.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/mach-types.h> +#include <asm/hardware/amba.h> + +#include <asm/mach/arch.h> +#include <asm/mach/mmc.h> + +#include "core.h" + +#if 1 +#define IRQ_MMCI1A IRQ_VICSOURCE23 +#else +#define IRQ_MMCI1A IRQ_SIC_MMCI1A +#endif + +static struct mmc_platform_data mmc1_plat_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, + .status = mmc_status, +}; + +#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ } +#define UART3_DMA { 0x86, 0x87 } +#define SCI1_IRQ { IRQ_SIC_SCI3, NO_IRQ } +#define SCI1_DMA { 0x88, 0x89 } +#define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B } +#define MMCI1_DMA { 0x85, 0 } + +/* + * These devices are connected via the core APB bridge + */ +#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ } +#define GPIO2_DMA { 0, 0 } +#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ } +#define GPIO3_DMA { 0, 0 } + +/* + * These devices are connected via the DMA APB bridge + */ + +/* FPGA Primecells */ +AMBA_DEVICE(uart3, "fpga:09", UART3, NULL); +AMBA_DEVICE(sci1, "fpga:0a", SCI1, NULL); +AMBA_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data); + +/* DevChip Primecells */ +AMBA_DEVICE(gpio2, "dev:e6", GPIO2, NULL); +AMBA_DEVICE(gpio3, "dev:e7", GPIO3, NULL); + +static struct amba_device *amba_devs[] __initdata = { + &uart3_device, + &gpio2_device, + &gpio3_device, + &sci1_device, + &mmc1_device, +}; + +static int __init versatile_pb_init(void) +{ + int i; + + if (machine_is_versatile_pb()) { + for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { + struct amba_device *d = amba_devs[i]; + amba_device_register(d, &iomem_resource); + } + } + + return 0; +} + +arch_initcall(versatile_pb_init); + +MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") + MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") + BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000) + BOOT_PARAMS(0x00000100) + MAPIO(versatile_map_io) + INITIRQ(versatile_init_irq) + .timer = &versatile_timer, + INIT_MACHINE(versatile_init) +MACHINE_END diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index f0a87820479d..77254fe3e4fb 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -14,6 +14,7 @@ config CPU_ARM610 depends on ARCH_RPC select CPU_32v3 select CPU_CACHE_V3 + select CPU_CACHE_VIVT select CPU_COPY_V3 select CPU_TLB_V3 help @@ -29,6 +30,7 @@ config CPU_ARM710 default y if ARCH_CLPS7500 select CPU_32v3 select CPU_CACHE_V3 + select CPU_CACHE_VIVT select CPU_COPY_V3 select CPU_TLB_V3 help @@ -47,6 +49,7 @@ config CPU_ARM720T select CPU_32v4 select CPU_ABRT_LV4T select CPU_CACHE_V4 + select CPU_CACHE_VIVT select CPU_COPY_V4WT select CPU_TLB_V4WT help @@ -64,6 +67,7 @@ config CPU_ARM920T select CPU_32v4 select CPU_ABRT_EV4T select CPU_CACHE_V4WT + select CPU_CACHE_VIVT select CPU_COPY_V4WB select CPU_TLB_V4WBI help @@ -84,6 +88,7 @@ config CPU_ARM922T select CPU_32v4 select CPU_ABRT_EV4T select CPU_CACHE_V4WT + select CPU_CACHE_VIVT select CPU_COPY_V4WB select CPU_TLB_V4WBI help @@ -102,6 +107,7 @@ config CPU_ARM925T select CPU_32v4 select CPU_ABRT_EV4T select CPU_CACHE_V4WT + select CPU_CACHE_VIVT select CPU_COPY_V4WB select CPU_TLB_V4WBI help @@ -115,10 +121,11 @@ config CPU_ARM925T # ARM926T config CPU_ARM926T bool "Support ARM926T processor" if ARCH_INTEGRATOR - depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || ARCH_OMAP730 || ARCH_OMAP1610 || ARCH_OMAP5912 - default y if ARCH_VERSATILE_PB + depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || ARCH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP1610 || ARCH_OMAP5912 + default y if ARCH_VERSATILE_PB || ARCH_VERSATILE_AB select CPU_32v5 select CPU_ABRT_EV5TJ + select CPU_CACHE_VIVT select CPU_COPY_V4WB select CPU_TLB_V4WBI help @@ -136,6 +143,7 @@ config CPU_ARM1020 select CPU_32v5 select CPU_ABRT_EV4T select CPU_CACHE_V4WT + select CPU_CACHE_VIVT select CPU_COPY_V4WB select CPU_TLB_V4WBI help @@ -152,6 +160,7 @@ config CPU_ARM1020E select CPU_32v5 select CPU_ABRT_EV4T select CPU_CACHE_V4WT + select CPU_CACHE_VIVT select CPU_COPY_V4WB select CPU_TLB_V4WBI depends on n @@ -162,6 +171,7 @@ config CPU_ARM1022 depends on ARCH_INTEGRATOR select CPU_32v5 select CPU_ABRT_EV4T + select CPU_CACHE_VIVT select CPU_COPY_V4WB # can probably do better select CPU_TLB_V4WBI help @@ -178,6 +188,7 @@ config CPU_ARM1026 depends on ARCH_INTEGRATOR select CPU_32v5 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10 + select CPU_CACHE_VIVT select CPU_COPY_V4WB # can probably do better select CPU_TLB_V4WBI help @@ -195,6 +206,7 @@ config CPU_SA110 select CPU_32v4 if !ARCH_RPC select CPU_ABRT_EV4 select CPU_CACHE_V4WB + select CPU_CACHE_VIVT select CPU_COPY_V4WB select CPU_TLB_V4WB help @@ -214,6 +226,7 @@ config CPU_SA1100 select CPU_32v4 select CPU_ABRT_EV4 select CPU_CACHE_V4WB + select CPU_CACHE_VIVT select CPU_TLB_V4WB select CPU_MINICACHE @@ -224,6 +237,7 @@ config CPU_XSCALE default y select CPU_32v5 select CPU_ABRT_EV5T + select CPU_CACHE_VIVT select CPU_TLB_V4WBI select CPU_MINICACHE @@ -234,6 +248,7 @@ config CPU_V6 select CPU_32v6 select CPU_ABRT_EV6 select CPU_CACHE_V6 + select CPU_CACHE_VIPT select CPU_COPY_V6 select CPU_TLB_V6 @@ -286,6 +301,12 @@ config CPU_CACHE_V4WB config CPU_CACHE_V6 bool +config CPU_CACHE_VIVT + bool + +config CPU_CACHE_VIPT + bool + # The copy-page model config CPU_COPY_V3 bool diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 4df5b0f3059e..82bdef29919b 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -6,7 +6,7 @@ # To add an entry into this database, please see Documentation/arm/README, # or contact rmk@arm.linux.org.uk # -# Last update: Thu Sep 30 15:23:21 2004 +# Last update: Sun Nov 7 13:20:41 2004 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -595,8 +595,8 @@ pxa_dnp2110 MACH_PXA_DNP2110 PXA_DNP2110 584 xaeniax MACH_XAENIAX XAENIAX 585 somn4250 MACH_SOMN4250 SOMN4250 586 pleb2 MACH_PLEB2 PLEB2 587 -cwl MACH_CWL CWL 588 -gd MACH_GD GD 589 +cornwallis MACH_CORNWALLIS CORNWALLIS 588 +gurney_drv MACH_GURNEY_DRV GURNEY_DRV 589 chaffee MACH_CHAFFEE CHAFFEE 590 rms101 MACH_RMS101 RMS101 591 rx3715 MACH_RX3715 RX3715 592 @@ -615,3 +615,22 @@ ixdpg425 MACH_IXDPG425 IXDPG425 604 tomtomgo MACH_TOMTOMGO TOMTOMGO 605 versatile_ab MACH_VERSATILE_AB VERSATILE_AB 606 edb9307 MACH_EDB9307 EDB9307 607 +sg565 MACH_SG565 SG565 608 +lpd79524 MACH_LPD79524 LPD79524 609 +lpd79525 MACH_LPD79525 LPD79525 610 +rms100 MACH_RMS100 RMS100 611 +kb9200 MACH_KB9200 KB9200 612 +sx1 MACH_SX1 SX1 613 +hms39c7092 MACH_HMS39C7092 HMS39C7092 614 +armadillo MACH_ARMADILLO ARMADILLO 615 +ipcu MACH_IPCU IPCU 616 +loox720 MACH_LOOX720 LOOX720 617 +ixdp465 MACH_IXDP465 IXDP465 618 +ixdp2351 MACH_IXDP2351 IXDP2351 619 +adsvix MACH_ADSVIX ADSVIX 620 +dm270 MACH_DM270 DM270 621 +socltplus MACH_SOCLTPLUS SOCLTPLUS 622 +ecia MACH_ECIA ECIA 623 +cm4008 MACH_CM4008 CM4008 624 +p2001 MACH_P2001 P2001 625 +twister MACH_TWISTER TWISTER 626 diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h index 98e0f526e9c2..e5da037bf526 100644 --- a/arch/arm/vfp/vfp.h +++ b/arch/arm/vfp/vfp.h @@ -249,6 +249,12 @@ struct vfp_double { u64 significand; }; +/* + * VFP_REG_ZERO is a special register number for vfp_get_double + * which returns (double)0.0. This is useful for the compare with + * zero instructions. + */ +#define VFP_REG_ZERO 16 extern u64 vfp_get_double(unsigned int reg); extern void vfp_put_double(unsigned int reg, u64 val); diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index 3a4df3ffad3e..e78924288736 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -427,12 +427,12 @@ static u32 vfp_double_fcmpe(int dd, int unused, int dm, u32 fpscr) static u32 vfp_double_fcmpz(int dd, int unused, int dm, u32 fpscr) { - return vfp_compare(dd, 0, -1, fpscr); + return vfp_compare(dd, 0, VFP_REG_ZERO, fpscr); } static u32 vfp_double_fcmpez(int dd, int unused, int dm, u32 fpscr) { - return vfp_compare(dd, 1, -1, fpscr); + return vfp_compare(dd, 1, VFP_REG_ZERO, fpscr); } static u32 vfp_double_fcvts(int sd, int unused, int dm, u32 fpscr) diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index ad362610346e..0dcfa8a785bd 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -199,6 +199,11 @@ vfp_get_double: mov pc, lr .endr + @ virtual register 16 for compare with zero + mov r0, #0 + mov r1, #0 + mov pc, lr + .globl vfp_put_double vfp_put_double: mov r0, r0, lsr #1 diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index ae10c9635bd4..badea1fff11e 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -689,7 +689,7 @@ static int __init detect_init_APIC (void) u32 h, l, features; extern void get_cpu_vendor(struct cpuinfo_x86*); - /* Disabled by DMI scan or kernel option? */ + /* Disabled by kernel option? */ if (enable_local_apic < 0) return -1; @@ -703,8 +703,7 @@ static int __init detect_init_APIC (void) break; goto no_apic; case X86_VENDOR_INTEL: - if (boot_cpu_data.x86 == 6 || - (boot_cpu_data.x86 == 15 && (cpu_has_apic || enable_local_apic > 0)) || + if (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15 || (boot_cpu_data.x86 == 5 && cpu_has_apic)) break; goto no_apic; @@ -714,15 +713,20 @@ static int __init detect_init_APIC (void) if (!cpu_has_apic) { /* - * Over-ride BIOS and try to enable LAPIC - * only if "lapic" specified + * Over-ride BIOS and try to enable the local + * APIC only if "lapic" specified. */ - if (enable_local_apic != 1) - goto no_apic; + if (enable_local_apic <= 0) { + apic_printk(APIC_VERBOSE, + "Local APIC disabled by BIOS -- " + "you can enable it with \"lapic\"\n"); + return -1; + } /* * Some BIOSes disable the local APIC in the * APIC_BASE MSR. This can only be done in - * software for Intel P6 and AMD K7 (Model > 1). + * software for Intel P6 or later and AMD K7 + * (Model > 1) or later. */ rdmsr(MSR_IA32_APICBASE, l, h); if (!(l & MSR_IA32_APICBASE_ENABLE)) { diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index 4d066cc30ac1..f96a30d7caf7 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c @@ -42,6 +42,7 @@ static struct pt_regs jprobe_saved_regs; static long *jprobe_saved_esp; /* copy of the kernel stack at the probe fire time */ static kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; +void jprobe_return_end(void); /* * returns non-zero if opcode modifies the interrupt flag. @@ -58,9 +59,14 @@ static inline int is_IF_modifier(kprobe_opcode_t opcode) return 0; } -void arch_prepare_kprobe(struct kprobe *p) +int arch_prepare_kprobe(struct kprobe *p) +{ + memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); + return 0; +} + +void arch_remove_kprobe(struct kprobe *p) { - memcpy(p->insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); } static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) @@ -73,7 +79,7 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) { regs->eflags |= TF_MASK; regs->eflags &= ~IF_MASK; - regs->eip = (unsigned long)&p->insn; + regs->eip = (unsigned long)&p->ainsn.insn; } /* @@ -153,7 +159,7 @@ static inline int kprobe_handler(struct pt_regs *regs) * instruction. To avoid the SMP problems that can occur when we * temporarily put back the original opcode to single-step, we * single-stepped a copy of the instruction. The address of this - * copy is p->insn. + * copy is p->ainsn.insn. * * This function prepares to return from the post-single-step * interrupt. We have to fix up the stack as follows: @@ -173,10 +179,10 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs) { unsigned long *tos = (unsigned long *)®s->esp; unsigned long next_eip = 0; - unsigned long copy_eip = (unsigned long)&p->insn; + unsigned long copy_eip = (unsigned long)&p->ainsn.insn; unsigned long orig_eip = (unsigned long)p->addr; - switch (p->insn[0]) { + switch (p->ainsn.insn[0]) { case 0x9c: /* pushfl */ *tos &= ~(TF_MASK | IF_MASK); *tos |= kprobe_old_eflags; @@ -185,13 +191,13 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs) *tos = orig_eip + (*tos - copy_eip); break; case 0xff: - if ((p->insn[1] & 0x30) == 0x10) { + if ((p->ainsn.insn[1] & 0x30) == 0x10) { /* call absolute, indirect */ /* Fix return addr; eip is correct. */ next_eip = regs->eip; *tos = orig_eip + (*tos - copy_eip); - } else if (((p->insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */ - ((p->insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */ + } else if (((p->ainsn.insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */ + ((p->ainsn.insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */ /* eip is correct. */ next_eip = regs->eip; } @@ -315,12 +321,12 @@ void jprobe_return(void) { preempt_enable_no_resched(); asm volatile (" xchgl %%ebx,%%esp \n" - " int3 \n"::"b" + " int3 \n" + " .globl jprobe_return_end \n" + " jprobe_return_end: \n" + " nop \n"::"b" (jprobe_saved_esp):"memory"); } -void jprobe_return_end(void) -{ -}; int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) { diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index 77c48ce67e08..963161cda0bd 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -344,6 +344,36 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) if(addr < (long) &dummy->u_debugreg[4] && ((unsigned long) data) >= TASK_SIZE-3) break; + /* Sanity-check data. Take one half-byte at once with + * check = (val >> (16 + 4*i)) & 0xf. It contains the + * R/Wi and LENi bits; bits 0 and 1 are R/Wi, and bits + * 2 and 3 are LENi. Given a list of invalid values, + * we do mask |= 1 << invalid_value, so that + * (mask >> check) & 1 is a correct test for invalid + * values. + * + * R/Wi contains the type of the breakpoint / + * watchpoint, LENi contains the length of the watched + * data in the watchpoint case. + * + * The invalid values are: + * - LENi == 0x10 (undefined), so mask |= 0x0f00. + * - R/Wi == 0x10 (break on I/O reads or writes), so + * mask |= 0x4444. + * - R/Wi == 0x00 && LENi != 0x00, so we have mask |= + * 0x1110. + * + * Finally, mask = 0x0f00 | 0x4444 | 0x1110 == 0x5f54. + * + * See the Intel Manual "System Programming Guide", + * 15.2.4 + * + * Note that LENi == 0x10 is defined on x86_64 in long + * mode (i.e. even for 32-bit userspace software, but + * 64-bit kernel), so the x86_64 mask value is 0x5454. + * See the AMD manual no. 24593 (AMD64 System + * Programming)*/ + if(addr == (long) &dummy->u_debugreg[7]) { data &= ~DR_CONTROL_RESERVED; for(i=0; i<4; i++) diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 3878f41751d7..b43b3baf2215 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -583,7 +583,11 @@ void die_nmi (struct pt_regs *regs, const char *msg) static void default_do_nmi(struct pt_regs * regs) { - unsigned char reason = get_nmi_reason(); + unsigned char reason = 0; + + /* Only the BSP gets external NMIs from the system. */ + if (!smp_processor_id()) + reason = get_nmi_reason(); if (!(reason & 0xc0)) { if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c index 4cfc30349512..33bbf2baa1d7 100644 --- a/arch/i386/mm/pageattr.c +++ b/arch/i386/mm/pageattr.c @@ -208,7 +208,6 @@ void kernel_map_pages(struct page *page, int numpages, int enable) */ __flush_tlb_all(); } -EXPORT_SYMBOL(kernel_map_pages); #endif EXPORT_SYMBOL(change_page_attr); diff --git a/arch/m32r/kernel/io_mappi.c b/arch/m32r/kernel/io_mappi.c index 74aeca636239..179adacc7f2a 100644 --- a/arch/m32r/kernel/io_mappi.c +++ b/arch/m32r/kernel/io_mappi.c @@ -15,7 +15,7 @@ #include <asm/io.h> #include <asm/byteorder.h> -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) #include <linux/types.h> #define M32R_PCC_IOMAP_SIZE 0x1000 @@ -27,7 +27,7 @@ extern void pcc_ioread(int, unsigned long, void *, size_t, size_t, int); extern void pcc_iowrite(int, unsigned long, void *, size_t, size_t, int); -#endif /* CONFIG_PCMCIA && CONFIG_M32RPCC */ +#endif /* CONFIG_PCMCIA && CONFIG_M32R_PCC */ #define PORT2ADDR(port) _port2addr(port) @@ -80,7 +80,7 @@ unsigned char _inb(unsigned long port) if (port >= 0x300 && port < 0x320) return _ne_inb(PORT2ADDR_NE(port)); else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { unsigned char b; pcc_ioread(0, port, &b, sizeof(b), 1, 0); @@ -100,7 +100,7 @@ unsigned short _inw(unsigned long port) if (port >= 0x300 && port < 0x320) return _ne_inw(PORT2ADDR_NE(port)); else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { unsigned short w; pcc_ioread(0, port, &w, sizeof(w), 1, 0); @@ -116,7 +116,7 @@ unsigned short _inw(unsigned long port) unsigned long _inl(unsigned long port) { -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { unsigned long l; pcc_ioread(0, port, &l, sizeof(l), 1, 0); @@ -137,7 +137,7 @@ unsigned char _inb_p(unsigned long port) if (port >= 0x300 && port < 0x320) v = _ne_inb(PORT2ADDR_NE(port)); else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { unsigned char b; pcc_ioread(0, port, &b, sizeof(b), 1, 0); @@ -161,7 +161,7 @@ unsigned short _inw_p(unsigned long port) if (port >= 0x300 && port < 0x320) v = _ne_inw(PORT2ADDR_NE(port)); else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { unsigned short w; pcc_ioread(0, port, &w, sizeof(w), 1, 0); @@ -192,7 +192,7 @@ void _outb(unsigned char b, unsigned long port) if (port >= 0x300 && port < 0x320) _ne_outb(b, PORT2ADDR_NE(port)); else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite(0, port, &b, sizeof(b), 1, 0); } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { @@ -207,7 +207,7 @@ void _outw(unsigned short w, unsigned long port) if (port >= 0x300 && port < 0x320) _ne_outw(w, PORT2ADDR_NE(port)); else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite(0, port, &w, sizeof(w), 1, 0); } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { @@ -219,7 +219,7 @@ void _outw(unsigned short w, unsigned long port) void _outl(unsigned long l, unsigned long port) { -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite(0, port, &l, sizeof(l), 1, 0); } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { @@ -234,7 +234,7 @@ void _outb_p(unsigned char b, unsigned long port) if (port >= 0x300 && port < 0x320) _ne_outb(b, PORT2ADDR_NE(port)); else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite(0, port, &b, sizeof(b), 1, 0); } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { @@ -251,7 +251,7 @@ void _outw_p(unsigned short w, unsigned long port) if (port >= 0x300 && port < 0x320) _ne_outw(w, PORT2ADDR_NE(port)); else -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite(0, port, &w, sizeof(w), 1, 0); } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { @@ -277,7 +277,7 @@ void _insb(unsigned int port, void * addr, unsigned long count) if (port >= 0x300 && port < 0x320){ portp = PORT2ADDR_NE(port); while(count--) *buf++ = *(volatile unsigned char *)portp; -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_ioread(0, port, (void *)addr, sizeof(unsigned char), count, 1); } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { @@ -297,7 +297,7 @@ void _insw(unsigned int port, void * addr, unsigned long count) if (port >= 0x300 && port < 0x320) { portp = PORT2ADDR_NE(port); while (count--) *buf++ = _ne_inw(portp); -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_ioread(0, port, (void *)addr, sizeof(unsigned short), count, 1); } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { @@ -326,7 +326,7 @@ void _outsb(unsigned int port, const void * addr, unsigned long count) if (port >= 0x300 && port < 0x320) { portp = PORT2ADDR_NE(port); while (count--) _ne_outb(*buf++, portp); -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite(0, port, (void *)addr, sizeof(unsigned char), count, 1); } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { @@ -346,7 +346,7 @@ void _outsw(unsigned int port, const void * addr, unsigned long count) if (port >= 0x300 && port < 0x320) { portp = PORT2ADDR_NE(port); while (count--) _ne_outw(*buf++, portp); -#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32RPCC) +#if defined(CONFIG_PCMCIA) && defined(CONFIG_M32R_PCC) } else if (port >= M32R_PCC_IOSTART0 && port <= M32R_PCC_IOEND0) { pcc_iowrite(0, port, (void *)addr, sizeof(unsigned short), count, 1); } else if (port >= M32R_PCC_IOSTART1 && port <= M32R_PCC_IOEND1) { diff --git a/arch/m32r/kernel/setup_mappi.c b/arch/m32r/kernel/setup_mappi.c index 523cee3304d3..1e74110f0670 100644 --- a/arch/m32r/kernel/setup_mappi.c +++ b/arch/m32r/kernel/setup_mappi.c @@ -140,7 +140,7 @@ void __init init_IRQ(void) disable_mappi_irq(M32R_IRQ_SIO1_S); #endif /* CONFIG_SERIAL_M32R_SIO */ -#if defined(CONFIG_M32RPCC) +#if defined(CONFIG_M32R_PCC) /* INT1 : pccard0 interrupt */ irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; irq_desc[M32R_IRQ_INT1].handler = &mappi_irq_type; diff --git a/arch/m32r/lib/memset.S b/arch/m32r/lib/memset.S index 7fe94b6c6c88..6e26df120acb 100644 --- a/arch/m32r/lib/memset.S +++ b/arch/m32r/lib/memset.S @@ -70,16 +70,18 @@ qword_set_loop: st r1, @+r4 bnc qword_set_loop || cmpz r2 jc r14 -word_set_wrap: +set_remainder: cmpui r2, #4 - bc byte_set + bc byte_set_wrap1 addi r2, #-4 bra word_set_loop byte_set_wrap: addi r2, #4 - addi r4, #4 || cmpz r2 + cmpz r2 jc r14 +byte_set_wrap1: + addi r4, #4 #if defined(CONFIG_ISA_M32R2) byte_set: addi r2, #-1 || stb r1, @r4+ @@ -153,18 +155,19 @@ qword_set_loop: st r1, @+r4 st r1, @+r4 bnc qword_set_loop - bnez r2, word_set_wrap + bnez r2, set_remainder jmp r14 -word_set_wrap: +set_remainder: cmpui r2, #4 - bc byte_set + bc byte_set_wrap1 addi r2, #-4 bra word_set_loop byte_set_wrap: addi r2, #4 - addi r4, #4 beqz r2, end_memset +byte_set_wrap1: + addi r4, #4 byte_set: addi r2, #-1 stb r1, @r4 diff --git a/arch/ppc/boot/simple/mpc52xx_tty.c b/arch/ppc/boot/simple/mpc52xx_tty.c index 8a1c663e758c..efde532b41e0 100644 --- a/arch/ppc/boot/simple/mpc52xx_tty.c +++ b/arch/ppc/boot/simple/mpc52xx_tty.c @@ -17,6 +17,7 @@ #include <asm/mpc52xx.h> #include <asm/mpc52xx_psc.h> #include <asm/serial.h> +#include <asm/io.h> #include <asm/time.h> #if MPC52xx_PF_CONSOLE_PORT == 0 diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c index a249f88f6fa8..6b3036fb7677 100644 --- a/arch/ppc/platforms/4xx/ocotea.c +++ b/arch/ppc/platforms/4xx/ocotea.c @@ -145,13 +145,13 @@ static void __init ocotea_set_emacdata(void) } #define PCIX_READW(offset) \ - (readw((u32)pcix_reg_base+offset)) + (readw(pcix_reg_base+offset)) #define PCIX_WRITEW(value, offset) \ - (writew(value, (u32)pcix_reg_base+offset)) + (writew(value, pcix_reg_base+offset)) #define PCIX_WRITEL(value, offset) \ - (writel(value, (u32)pcix_reg_base+offset)) + (writel(value, pcix_reg_base+offset)) /* * FIXME: This is only here to "make it work". This will move @@ -321,6 +321,11 @@ ocotea_setup_arch(void) printk("IBM Ocotea port (MontaVista Software, Inc. <source@mvista.com>)\n"); } +static void __init ocotea_init(void) +{ + ibm440gx_l2c_setup(&clocks); +} + void __init platform_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { @@ -342,12 +347,11 @@ void __init platform_init(unsigned long r3, unsigned long r4, ibm440gx_get_clocks(&clocks, 33333333, 6 * 1843200); ocp_sys_info.opb_bus_freq = clocks.opb; - /* - * Always disable L2 cache. All revs/speeds of silicon - * have parity error problems despite errata claims to - * the contrary. + /* XXX Fix L2C IRQ triggerring setting (edge-sensitive). + * Firmware (at least PIBS v1.72 OCT/28/2003) sets it incorrectly + * --ebs */ - ibm440gx_l2c_disable(); + mtdcr(DCRN_UIC_TR(UIC2), mfdcr(DCRN_UIC_TR(UIC2)) | 0x00000100); ibm44x_platform_init(); @@ -365,4 +369,5 @@ void __init platform_init(unsigned long r3, unsigned long r4, #ifdef CONFIG_KGDB ppc_md.early_serial_map = ocotea_early_serial_map; #endif + ppc_md.init = ocotea_init; } diff --git a/arch/ppc/platforms/sandpoint.c b/arch/ppc/platforms/sandpoint.c index 5ab3643548b8..cef887eeed38 100644 --- a/arch/ppc/platforms/sandpoint.c +++ b/arch/ppc/platforms/sandpoint.c @@ -60,11 +60,6 @@ * of the amount of memory in the system. Once a method of determining * what version of DINK initializes the system for us, if applicable, is * found, we can hopefully stop hardcoding 32MB of RAM. - * - * It is important to note that this code only supports the Sandpoint X3 - * (all flavors) platform, and it does not support the X2 anymore. Code - * that at one time worked on the X2 can be found at: - * ftp://source.mvista.com/pub/linuxppc/obsolete/sandpoint/ */ #include <linux/config.h> @@ -107,9 +102,13 @@ #include "sandpoint.h" +/* Set non-zero if an X2 Sandpoint detected. */ +static int sandpoint_is_x2; + unsigned char __res[sizeof(bd_t)]; static void sandpoint_halt(void); +static void sandpoint_probe_type(void); /* * Define all of the IRQ senses and polarities. Taken from the @@ -129,7 +128,7 @@ static u_char sandpoint_openpic_initsenses[] __initdata = { * Motorola SPS Sandpoint interrupt routing. */ static inline int -sandpoint_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +x3_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) { static char pci_irq_table[][4] = /* @@ -149,6 +148,27 @@ sandpoint_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) return PCI_IRQ_TABLE_LOOKUP; } +static inline int +x2_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 18, 0, 0, 0 }, /* IDSEL 11 - i8259 on Windbond */ + { 0, 0, 0, 0 }, /* IDSEL 12 - unused */ + { 16, 17, 18, 19 }, /* IDSEL 13 - PCI slot 1 */ + { 17, 18, 19, 16 }, /* IDSEL 14 - PCI slot 2 */ + { 18, 19, 16, 17 }, /* IDSEL 15 - PCI slot 3 */ + { 19, 16, 17, 18 }, /* IDSEL 16 - PCI slot 4 */ + }; + + const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + static void __init sandpoint_setup_winbond_83553(struct pci_controller *hose) { @@ -216,6 +236,18 @@ sandpoint_setup_winbond_83553(struct pci_controller *hose) return; } +/* On the sandpoint X2, we must avoid sending configuration cycles to + * device #12 (IDSEL addr = AD12). + */ +static int +x2_exclude_device(u_char bus, u_char devfn) +{ + if ((bus == 0) && (PCI_SLOT(devfn) == SANDPOINT_HOST_BRIDGE_IDSEL)) + return PCIBIOS_DEVICE_NOT_FOUND; + else + return PCIBIOS_SUCCESSFUL; +} + static void __init sandpoint_find_bridges(void) { @@ -241,7 +273,11 @@ sandpoint_find_bridges(void) ppc_md.pcibios_fixup = NULL; ppc_md.pcibios_fixup_bus = NULL; ppc_md.pci_swizzle = common_swizzle; - ppc_md.pci_map_irq = sandpoint_map_irq; + if (sandpoint_is_x2) { + ppc_md.pci_map_irq = x2_map_irq; + ppc_md.pci_exclude_device = x2_exclude_device; + } else + ppc_md.pci_map_irq = x3_map_irq; } else { if (ppc_md.progress) @@ -255,6 +291,11 @@ sandpoint_find_bridges(void) static void __init sandpoint_setup_arch(void) { + /* Probe for Sandpoint model */ + sandpoint_probe_type(); + if (sandpoint_is_x2) + epic_serial_mode = 0; + loops_per_jiffy = 100000000 / HZ; #ifdef CONFIG_BLK_DEV_INITRD @@ -319,13 +360,48 @@ sandpoint_setup_arch(void) } /* + * To probe the Sandpoint type, we need to check for a connection between GPIO + * pins 6 and 7 on the NS87308 SuperIO. + */ +static void __init sandpoint_probe_type(void) +{ + u8 x; + /* First, ensure that the GPIO pins are enabled. */ + SANDPOINT_87308_SELECT_DEV(0x07); /* Select GPIO logical device */ + SANDPOINT_87308_CFG_OUTB(0x60, 0x07); /* Base address 0x700 */ + SANDPOINT_87308_CFG_OUTB(0x61, 0x00); + SANDPOINT_87308_CFG_OUTB(0x30, 0x01); /* Enable */ + + /* Now, set pin 7 to output and pin 6 to input. */ + outb((inb(0x701) | 0x80) & 0xbf, 0x701); + /* Set push-pull output */ + outb(inb(0x702) | 0x80, 0x702); + /* Set pull-up on input */ + outb(inb(0x703) | 0x40, 0x703); + /* Set output high and check */ + x = inb(0x700); + outb(x | 0x80, 0x700); + x = inb(0x700); + sandpoint_is_x2 = ! (x & 0x40); + if (ppc_md.progress && sandpoint_is_x2) + ppc_md.progress("High output says X2", 0); + /* Set output low and check */ + outb(x & 0x7f, 0x700); + sandpoint_is_x2 |= inb(0x700) & 0x40; + if (ppc_md.progress && sandpoint_is_x2) + ppc_md.progress("Low output says X2", 0); + if (ppc_md.progress && ! sandpoint_is_x2) + ppc_md.progress("Sandpoint is X3", 0); +} + +/* * Fix IDE interrupts. */ static int __init sandpoint_fix_winbond_83553(void) { - /* Make all 8259 interrupt level sensitive */ - outb(0xf8, 0x4d0); + /* Make some 8259 interrupt level sensitive */ + outb(0xe0, 0x4d0); outb(0xde, 0x4d1); return 0; @@ -398,7 +474,7 @@ sandpoint_init_IRQ(void) OpenPIC_NumInitSenses = sizeof(sandpoint_openpic_initsenses); mpc10x_set_openpic(); - openpic_hookup_cascade(NUM_8259_INTERRUPTS, "82c59 cascade", + openpic_hookup_cascade(sandpoint_is_x2 ? 17 : NUM_8259_INTERRUPTS, "82c59 cascade", i8259_irq); /* diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c index caccc9765e0f..5e2ce6bf5976 100644 --- a/arch/ppc/syslib/ibm440gx_common.c +++ b/arch/ppc/syslib/ibm440gx_common.c @@ -4,7 +4,7 @@ * PPC440GX system library * * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> - * Copyright (c) 2003 Zultys Technologies + * Copyright (c) 2003, 2004 Zultys Technologies * * 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 @@ -14,6 +14,7 @@ */ #include <linux/config.h> #include <linux/kernel.h> +#include <linux/interrupt.h> #include <asm/ibm44x.h> #include <asm/mmu.h> #include <asm/processor.h> @@ -97,10 +98,51 @@ bypass: p->uart1 = p->plb / __fix_zero(uart1 & 0xff, 256); } -/* Enable L2 cache (call with IRQs disabled) */ +/* Issue L2C diagnostic command */ +static inline u32 l2c_diag(u32 addr) +{ + mtdcr(DCRN_L2C0_ADDR, addr); + mtdcr(DCRN_L2C0_CMD, L2C_CMD_DIAG); + while (!(mfdcr(DCRN_L2C0_SR) & L2C_SR_CC)) ; + return mfdcr(DCRN_L2C0_DATA); +} + +static irqreturn_t l2c_error_handler(int irq, void* dev, struct pt_regs* regs) +{ + u32 sr = mfdcr(DCRN_L2C0_SR); + if (sr & L2C_SR_CPE){ + /* Read cache trapped address */ + u32 addr = l2c_diag(0x42000000); + printk(KERN_EMERG "L2C: Cache Parity Error, addr[16:26] = 0x%08x\n", addr); + } + if (sr & L2C_SR_TPE){ + /* Read tag trapped address */ + u32 addr = l2c_diag(0x82000000) >> 16; + printk(KERN_EMERG "L2C: Tag Parity Error, addr[16:26] = 0x%08x\n", addr); + } + + /* Clear parity errors */ + if (sr & (L2C_SR_CPE | L2C_SR_TPE)){ + mtdcr(DCRN_L2C0_ADDR, 0); + mtdcr(DCRN_L2C0_CMD, L2C_CMD_CCP | L2C_CMD_CTE); + } else + printk(KERN_EMERG "L2C: LRU error\n"); + + return IRQ_HANDLED; +} + +/* Enable L2 cache */ void __init ibm440gx_l2c_enable(void){ u32 r; + unsigned long flags; + + /* Install error handler */ + if (request_irq(87, l2c_error_handler, SA_INTERRUPT, "L2C", 0) < 0){ + printk(KERN_ERR "Cannot install L2C error handler, cache is not enabled\n"); + return; + } + local_irq_save(flags); asm volatile ("sync" ::: "memory"); /* Disable SRAM */ @@ -137,20 +179,22 @@ void __init ibm440gx_l2c_enable(void){ /* Enable ICU/DCU ports */ r = mfdcr(DCRN_L2C0_CFG); - r &= ~(L2C_CFG_DCW_MASK | L2C_CFG_CPIM | L2C_CFG_TPIM | L2C_CFG_LIM - | L2C_CFG_PMUX_MASK | L2C_CFG_PMIM | L2C_CFG_TPEI | L2C_CFG_CPEI - | L2C_CFG_NAM | L2C_CFG_NBRM); + r &= ~(L2C_CFG_DCW_MASK | L2C_CFG_PMUX_MASK | L2C_CFG_PMIM | L2C_CFG_TPEI + | L2C_CFG_CPEI | L2C_CFG_NAM | L2C_CFG_NBRM); r |= L2C_CFG_ICU | L2C_CFG_DCU | L2C_CFG_TPC | L2C_CFG_CPC | L2C_CFG_FRAN - | L2C_CFG_SMCM; + | L2C_CFG_CPIM | L2C_CFG_TPIM | L2C_CFG_LIM | L2C_CFG_SMCM; mtdcr(DCRN_L2C0_CFG, r); asm volatile ("sync; isync" ::: "memory"); + local_irq_restore(flags); } -/* Disable L2 cache (call with IRQs disabled) */ +/* Disable L2 cache */ void __init ibm440gx_l2c_disable(void){ u32 r; + unsigned long flags; + local_irq_save(flags); asm volatile ("sync" ::: "memory"); /* Disable L2C mode */ @@ -169,6 +213,7 @@ void __init ibm440gx_l2c_disable(void){ SRAM_SBCR_BAS3 | SRAM_SBCR_BS_64KB | SRAM_SBCR_BU_RW); asm volatile ("sync; isync" ::: "memory"); + local_irq_restore(flags); } void __init ibm440gx_l2c_setup(struct ibm44x_clocks* p) diff --git a/arch/ppc/syslib/mpc10x_common.c b/arch/ppc/syslib/mpc10x_common.c index 153c811b13d2..ddcb9e06f261 100644 --- a/arch/ppc/syslib/mpc10x_common.c +++ b/arch/ppc/syslib/mpc10x_common.c @@ -43,7 +43,7 @@ #ifdef CONFIG_MPC10X_OPENPIC #ifdef CONFIG_EPIC_SERIAL_MODE -#define EPIC_IRQ_BASE 16 +#define EPIC_IRQ_BASE (epic_serial_mode ? 16 : 5) #else #define EPIC_IRQ_BASE 5 #endif @@ -69,20 +69,16 @@ static struct ocp_def mpc10x_i2c_ocp = { .vendor = OCP_VENDOR_MOTOROLA, .function = OCP_FUNC_IIC, .index = 0, - .irq = MPC10X_I2C_IRQ, .additions = &mpc10x_i2c_data }; static struct ocp_def mpc10x_dma_ocp[2] = { { .vendor = OCP_VENDOR_MOTOROLA, .function = OCP_FUNC_DMA, - .index = 0, - .irq = MPC10X_DMA0_IRQ -}, + .index = 0 }, { .vendor = OCP_VENDOR_MOTOROLA, .function = OCP_FUNC_DMA, - .index = 1, - .irq = MPC10X_DMA1_IRQ } + .index = 1 } }; /* Set resources to match bridge memory map */ @@ -292,12 +288,15 @@ mpc10x_bridge_init(struct pci_controller *hose, MPC10X_EUMB_EPIC_SIZE); #endif mpc10x_i2c_ocp.paddr = phys_eumb_base + MPC10X_EUMB_I2C_OFFSET; + mpc10x_i2c_ocp.irq = MPC10X_I2C_IRQ; ocp_add_one_device(&mpc10x_i2c_ocp); mpc10x_dma_ocp[0].paddr = phys_eumb_base + MPC10X_EUMB_DMA_OFFSET + 0x100; + mpc10x_dma_ocp[0].irq = MPC10X_DMA0_IRQ; ocp_add_one_device(&mpc10x_dma_ocp[0]); mpc10x_dma_ocp[1].paddr = phys_eumb_base + MPC10X_EUMB_DMA_OFFSET + 0x200; + mpc10x_dma_ocp[1].irq = MPC10X_DMA1_IRQ; ocp_add_one_device(&mpc10x_dma_ocp[1]); } diff --git a/arch/ppc/syslib/mpc52xx_setup.c b/arch/ppc/syslib/mpc52xx_setup.c index d73e6fea542b..6bd014d7c9dc 100644 --- a/arch/ppc/syslib/mpc52xx_setup.c +++ b/arch/ppc/syslib/mpc52xx_setup.c @@ -19,6 +19,7 @@ #include <linux/config.h> +#include <asm/io.h> #include <asm/time.h> #include <asm/mpc52xx.h> #include <asm/mpc52xx_psc.h> diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index 052c10752d7e..bc5c46a30640 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c @@ -261,6 +261,9 @@ static void openpic_safe_writefield_IPI(volatile u_int *addr, u_int mask, u_int #endif /* CONFIG_SMP */ #ifdef CONFIG_EPIC_SERIAL_MODE +/* On platforms that may use EPIC serial mode, the default is enabled. */ +int epic_serial_mode = 1; + static void __init openpic_eicr_set_clk(u_int clkval) { openpic_writefield(&OpenPIC->Global.Global_Configuration1, @@ -415,8 +418,10 @@ void __init openpic_init(int offset) openpic_set_spurious(OPENPIC_VEC_SPURIOUS); openpic_disable_8259_pass_through(); #ifdef CONFIG_EPIC_SERIAL_MODE - openpic_eicr_set_clk(7); /* Slowest value until we know better */ - openpic_enable_sie(); + if (epic_serial_mode) { + openpic_eicr_set_clk(7); /* Slowest value until we know better */ + openpic_enable_sie(); + } #endif openpic_set_priority(0); diff --git a/arch/ppc/syslib/todc_time.c b/arch/ppc/syslib/todc_time.c index 1dc7e0bf5316..6730695c35fa 100644 --- a/arch/ppc/syslib/todc_time.c +++ b/arch/ppc/syslib/todc_time.c @@ -18,6 +18,7 @@ #include <linux/time.h> #include <linux/timex.h> #include <linux/bcd.h> +#include <linux/mc146818rtc.h> #include <asm/machdep.h> #include <asm/io.h> @@ -48,8 +49,6 @@ * --MAG */ -extern spinlock_t rtc_lock; - /* * 'todc_info' should be initialized in your *_setup.c file to * point to a fully initialized 'todc_info_t' structure. diff --git a/arch/ppc64/kernel/iSeries_iommu.c b/arch/ppc64/kernel/iSeries_iommu.c index c09ea2aaa189..4f0631860300 100644 --- a/arch/ppc64/kernel/iSeries_iommu.c +++ b/arch/ppc64/kernel/iSeries_iommu.c @@ -25,30 +25,14 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <linux/config.h> -#include <linux/init.h> #include <linux/types.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/spinlock.h> -#include <linux/string.h> -#include <linux/pci.h> #include <linux/dma-mapping.h> -#include <asm/io.h> -#include <asm/prom.h> -#include <asm/rtas.h> -#include <asm/ppcdebug.h> +#include <linux/list.h> -#include <asm/iSeries/HvCallXm.h> -#include <asm/iSeries/LparData.h> #include <asm/iommu.h> -#include <asm/pci-bridge.h> -#include <asm/iSeries/iSeries_pci.h> - #include <asm/machdep.h> - -#include "pci.h" - +#include <asm/iSeries/HvCallXm.h> +#include <asm/iSeries/iSeries_pci.h> extern struct list_head iSeries_Global_Device_List; @@ -76,12 +60,11 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, tce.te_bits.tb_pciwr = 1; } - rc = HvCallXm_setTce((u64)tbl->it_index, - (u64)index, - tce.te_word); + rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, + tce.te_word); if (rc) - panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", rc); - + panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", + rc); index++; uaddr += PAGE_SIZE; } @@ -90,20 +73,14 @@ static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages) { u64 rc; - union tce_entry tce; while (npages--) { - tce.te_word = 0; - rc = HvCallXm_setTce((u64)tbl->it_index, - (u64)index, - tce.te_word); - + rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, 0); if (rc) - panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", rc); - + panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", + rc); index++; } - } @@ -115,17 +92,14 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl) { struct iSeries_Device_Node *dp; - for (dp = (struct iSeries_Device_Node *)iSeries_Global_Device_List.next; - dp != (struct iSeries_Device_Node *)&iSeries_Global_Device_List; - dp = (struct iSeries_Device_Node *)dp->Device_List.next) - if (dp->iommu_table != NULL && - dp->iommu_table->it_type == TCE_PCI && - dp->iommu_table->it_offset == tbl->it_offset && - dp->iommu_table->it_index == tbl->it_index && - dp->iommu_table->it_size == tbl->it_size) + list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) { + if ((dp->iommu_table != NULL) && + (dp->iommu_table->it_type == TCE_PCI) && + (dp->iommu_table->it_offset == tbl->it_offset) && + (dp->iommu_table->it_index == tbl->it_index) && + (dp->iommu_table->it_size == tbl->it_size)) return dp->iommu_table; - - + } return NULL; } @@ -143,15 +117,14 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn, { struct iommu_table_cb *parms; - parms = (struct iommu_table_cb*)kmalloc(sizeof(*parms), GFP_KERNEL); - + parms = kmalloc(sizeof(*parms), GFP_KERNEL); if (parms == NULL) panic("PCI_DMA: TCE Table Allocation failed."); memset(parms, 0, sizeof(*parms)); - parms->itc_busno = ISERIES_BUS(dn); - parms->itc_slotno = dn->LogicalSlot; + parms->itc_busno = ISERIES_BUS(dn); + parms->itc_slotno = dn->LogicalSlot; parms->itc_virtbus = 0; HvCallXm_getTceTableParms(ISERIES_HV_ADDR(parms)); @@ -159,34 +132,32 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn, if (parms->itc_size == 0) panic("PCI_DMA: parms->size is zero, parms is 0x%p", parms); - tbl->it_size = parms->itc_size; - tbl->it_busno = parms->itc_busno; - tbl->it_offset = parms->itc_offset; - tbl->it_index = parms->itc_index; - tbl->it_entrysize = sizeof(union tce_entry); - tbl->it_blocksize = 1; - tbl->it_type = TCE_PCI; + tbl->it_size = parms->itc_size; + tbl->it_busno = parms->itc_busno; + tbl->it_offset = parms->itc_offset; + tbl->it_index = parms->itc_index; + tbl->it_entrysize = sizeof(union tce_entry); + tbl->it_blocksize = 1; + tbl->it_type = TCE_PCI; kfree(parms); } -void iommu_devnode_init(struct iSeries_Device_Node *dn) { +void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn) +{ struct iommu_table *tbl; - tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), GFP_KERNEL); + tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); iommu_table_getparms(dn, tbl); /* Look for existing tce table */ dn->iommu_table = iommu_table_find(tbl); - if (dn->iommu_table == NULL) dn->iommu_table = iommu_init_table(tbl); else kfree(tbl); - - return; } diff --git a/arch/ppc64/kernel/iSeries_pci.c b/arch/ppc64/kernel/iSeries_pci.c index 59d9ab88b3ae..5bbf3a3094cc 100644 --- a/arch/ppc64/kernel/iSeries_pci.c +++ b/arch/ppc64/kernel/iSeries_pci.c @@ -312,8 +312,7 @@ void __init iSeries_pci_final_fixup(void) mf_displaySrc(0xC9000100); printk("pcibios_final_fixup\n"); - while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) - != NULL) { + for_each_pci_dev(pdev) { node = find_Device_Node(pdev->bus->number, pdev->devfn); printk("pci dev %p (%x.%x), node %p\n", pdev, pdev->bus->number, pdev->devfn, node); @@ -329,7 +328,7 @@ void __init iSeries_pci_final_fixup(void) iSeries_Device_Information(pdev, Buffer, sizeof(Buffer)); printk("%d. %s\n", DeviceCount, Buffer); - iommu_devnode_init(node); + iommu_devnode_init_iSeries(node); } else printk("PCI: Device Tree not found for 0x%016lX\n", (unsigned long)pdev); diff --git a/arch/ppc64/kernel/iommu.c b/arch/ppc64/kernel/iommu.c index 3c476ee1d89e..4d2e45338871 100644 --- a/arch/ppc64/kernel/iommu.c +++ b/arch/ppc64/kernel/iommu.c @@ -425,6 +425,39 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl) return tbl; } +void iommu_free_table(struct device_node *dn) +{ + struct iommu_table *tbl = dn->iommu_table; + unsigned long bitmap_sz, i; + unsigned int order; + + if (!tbl || !tbl->it_map) { + printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__, + dn->full_name); + return; + } + + /* verify that table contains no entries */ + /* it_mapsize is in entries, and we're examining 64 at a time */ + for (i = 0; i < (tbl->it_mapsize/64); i++) { + if (tbl->it_map[i] != 0) { + printk(KERN_WARNING "%s: Unexpected TCEs for %s\n", + __FUNCTION__, dn->full_name); + break; + } + } + + /* calculate bitmap size in bytes */ + bitmap_sz = (tbl->it_mapsize + 7) / 8; + + /* free bitmap */ + order = get_order(bitmap_sz); + free_pages((unsigned long) tbl->it_map, order); + + /* free table */ + kfree(tbl); +} + /* Creates TCEs for a user provided buffer. The user buffer must be * contiguous real kernel storage (not vmalloc). The address of the buffer * passed here is the kernel (virtual) address of the buffer. The buffer diff --git a/arch/ppc64/kernel/pSeries_iommu.c b/arch/ppc64/kernel/pSeries_iommu.c index 5e0561bfa8c1..793ac819609b 100644 --- a/arch/ppc64/kernel/pSeries_iommu.c +++ b/arch/ppc64/kernel/pSeries_iommu.c @@ -276,7 +276,7 @@ static void iommu_buses_init(void) first_phb = 0; for (dn = first_dn; dn != NULL; dn = dn->sibling) - iommu_devnode_init(dn); + iommu_devnode_init_pSeries(dn); } } @@ -298,7 +298,7 @@ static void iommu_buses_init_lpar(struct list_head *bus_list) * Do it now because iommu_table_setparms_lpar needs it. */ busdn->bussubno = bus->number; - iommu_devnode_init(busdn); + iommu_devnode_init_pSeries(busdn); } /* look for a window on a bridge even if the PHB had one */ @@ -397,7 +397,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb, } -void iommu_devnode_init(struct device_node *dn) +void iommu_devnode_init_pSeries(struct device_node *dn) { struct iommu_table *tbl; @@ -412,39 +412,6 @@ void iommu_devnode_init(struct device_node *dn) dn->iommu_table = iommu_init_table(tbl); } -void iommu_free_table(struct device_node *dn) -{ - struct iommu_table *tbl = dn->iommu_table; - unsigned long bitmap_sz, i; - unsigned int order; - - if (!tbl || !tbl->it_map) { - printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__, - dn->full_name); - return; - } - - /* verify that table contains no entries */ - /* it_mapsize is in entries, and we're examining 64 at a time */ - for (i = 0; i < (tbl->it_mapsize/64); i++) { - if (tbl->it_map[i] != 0) { - printk(KERN_WARNING "%s: Unexpected TCEs for %s\n", - __FUNCTION__, dn->full_name); - break; - } - } - - /* calculate bitmap size in bytes */ - bitmap_sz = (tbl->it_mapsize + 7) / 8; - - /* free bitmap */ - order = get_order(bitmap_sz); - free_pages((unsigned long) tbl->it_map, order); - - /* free table */ - kfree(tbl); -} - void iommu_setup_pSeries(void) { struct pci_dev *dev = NULL; @@ -459,7 +426,7 @@ void iommu_setup_pSeries(void) * pci device_node. This means get_iommu_table() won't need to search * up the device tree to find it. */ - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + for_each_pci_dev(dev) { mydn = dn = PCI_GET_DN(dev); while (dn && dn->iommu_table == NULL) @@ -469,7 +436,6 @@ void iommu_setup_pSeries(void) } } - /* These are called very early. */ void tce_init_pSeries(void) { diff --git a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c index b8abd2a2ca4c..31e2705bb4bc 100644 --- a/arch/ppc64/kernel/pSeries_pci.c +++ b/arch/ppc64/kernel/pSeries_pci.c @@ -548,7 +548,7 @@ void __init pSeries_final_fixup(void) check_s7a(); - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + for_each_pci_dev(dev) { pci_read_irq_line(dev); if (s7a_workaround) { if (dev->irq > 16) { diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c index 618add1aa40f..cacbcd0a88dd 100644 --- a/arch/ppc64/kernel/pmac_pci.c +++ b/arch/ppc64/kernel/pmac_pci.c @@ -663,7 +663,7 @@ void __init pmac_pcibios_fixup(void) { struct pci_dev *dev = NULL; - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) + for_each_pci_dev(dev) pci_read_irq_line(dev); pci_fix_bus_sysdata(); diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index 4dc339ad9d4e..68e7c8612d4a 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c @@ -1740,7 +1740,7 @@ static int of_finish_dynamic_node(struct device_node *node) if (strcmp(node->name, "pci") == 0 && get_property(node, "ibm,dma-window", NULL)) { node->bussubno = node->busno; - iommu_devnode_init(node); + iommu_devnode_init_pSeries(node); } else node->iommu_table = parent->iommu_table; #endif /* CONFIG_PPC_PSERIES */ @@ -1802,6 +1802,15 @@ int of_add_node(const char *path, struct property *proplist) } /* + * Prepare an OF node for removal from system + */ +static void of_cleanup_node(struct device_node *np) +{ + if (np->iommu_table && get_property(np, "ibm,dma-window", NULL)) + iommu_free_table(np); +} + +/* * Remove an OF device node from the system. * Caller should have already "gotten" np. */ @@ -1818,13 +1827,7 @@ int of_remove_node(struct device_node *np) return -EBUSY; } - /* XXX This is a layering violation, should be moved to the caller - * --BenH. - */ -#ifdef CONFIG_PPC_PSERIES - if (np->iommu_table) - iommu_free_table(np); -#endif /* CONFIG_PPC_PSERIES */ + of_cleanup_node(np); write_lock(&devtree_lock); OF_MARK_STALE(np); diff --git a/arch/ppc64/kernel/u3_iommu.c b/arch/ppc64/kernel/u3_iommu.c index b1f1ffde1b10..051cac60b46f 100644 --- a/arch/ppc64/kernel/u3_iommu.c +++ b/arch/ppc64/kernel/u3_iommu.c @@ -291,7 +291,7 @@ void iommu_setup_u3(void) /* We only have one iommu table on the mac for now, which makes * things simple. Setup all PCI devices to point to this table */ - while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + for_each_pci_dev(dev) { /* We must use pci_device_to_OF_node() to make sure that * we get the real "final" pointer to the device in the * pci_dev sysdata and not the temporary PHB one diff --git a/arch/ppc64/kernel/vio.c b/arch/ppc64/kernel/vio.c index 48c4b0a0a697..ed20451775b6 100644 --- a/arch/ppc64/kernel/vio.c +++ b/arch/ppc64/kernel/vio.c @@ -521,24 +521,7 @@ static struct iommu_table * vio_build_iommu_table(struct vio_dev *dev) newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL); - /* RPA docs say that #address-cells is always 1 for virtual - devices, but some older boxes' OF returns 2. This should - be removed by GA, unless there is legacy OFs that still - have 2 for #address-cells */ - size = ((dma_window[1+vio_num_address_cells] >> PAGE_SHIFT) << 3) - >> PAGE_SHIFT; - - /* This is just an ugly kludge. Remove as soon as the OF for all - machines actually follow the spec and encodes the offset field - as phys-encode (that is, #address-cells wide)*/ - if (dma_window_property_size == 12) { - size = ((dma_window[1] >> PAGE_SHIFT) << 3) >> PAGE_SHIFT; - } else if (dma_window_property_size == 20) { - size = ((dma_window[4] >> PAGE_SHIFT) << 3) >> PAGE_SHIFT; - } else { - printk(KERN_WARNING "vio_build_iommu_table: Invalid size of ibm,my-dma-window=%i, using 0x80 for size\n", dma_window_property_size); - size = 0x80; - } + size = ((dma_window[4] >> PAGE_SHIFT) << 3) >> PAGE_SHIFT; /* There should be some code to extract the phys-encoded offset using prom_n_addr_cells(). However, according to a comment diff --git a/arch/ppc64/oprofile/common.c b/arch/ppc64/oprofile/common.c index bd0dcd2e8a55..476c857009c7 100644 --- a/arch/ppc64/oprofile/common.c +++ b/arch/ppc64/oprofile/common.c @@ -112,11 +112,16 @@ static int op_ppc64_create_files(struct super_block *sb, struct dentry *root) oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel); oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user); + oprofilefs_create_ulong(sb, root, "backtrace_spinlocks", + &sys.backtrace_spinlocks); /* Default to tracing both kernel and user */ sys.enable_kernel = 1; sys.enable_user = 1; + /* Turn on backtracing through spinlocks by default */ + sys.backtrace_spinlocks = 1; + return 0; } diff --git a/arch/ppc64/oprofile/op_impl.h b/arch/ppc64/oprofile/op_impl.h index c936c5ce646d..30c71a03b189 100644 --- a/arch/ppc64/oprofile/op_impl.h +++ b/arch/ppc64/oprofile/op_impl.h @@ -71,6 +71,7 @@ struct op_system_config { unsigned long mmcra; unsigned long enable_kernel; unsigned long enable_user; + unsigned long backtrace_spinlocks; }; /* Per-arch configuration */ diff --git a/arch/ppc64/oprofile/op_model_power4.c b/arch/ppc64/oprofile/op_model_power4.c index b2a512cdb4f1..4f8bf02fb675 100644 --- a/arch/ppc64/oprofile/op_model_power4.c +++ b/arch/ppc64/oprofile/op_model_power4.c @@ -32,6 +32,13 @@ static u32 mmcr0_val; static u64 mmcr1_val; static u32 mmcra_val; +/* + * Since we do not have an NMI, backtracing through spinlocks is + * only a best guess. In light of this, allow it to be disabled at + * runtime. + */ +static int backtrace_spinlocks; + static void power4_reg_setup(struct op_counter_config *ctr, struct op_system_config *sys, int num_ctrs) @@ -59,6 +66,8 @@ static void power4_reg_setup(struct op_counter_config *ctr, mmcr1_val = sys->mmcr1; mmcra_val = sys->mmcra; + backtrace_spinlocks = sys->backtrace_spinlocks; + for (i = 0; i < num_counters; ++i) reset_value[i] = 0x80000000UL - ctr[i].count; @@ -170,19 +179,38 @@ static void __attribute_used__ kernel_unknown_bucket(void) { } +static unsigned long check_spinlock_pc(struct pt_regs *regs, + unsigned long profile_pc) +{ + unsigned long pc = instruction_pointer(regs); + + /* + * If both the SIAR (sampled instruction) and the perfmon exception + * occurred in a spinlock region then we account the sample to the + * calling function. This isnt 100% correct, we really need soft + * IRQ disable so we always get the perfmon exception at the + * point at which the SIAR is set. + */ + if (backtrace_spinlocks && in_lock_functions(pc) && + in_lock_functions(profile_pc)) + return regs->link; + else + return profile_pc; +} + /* * On GQ and newer the MMCRA stores the HV and PR bits at the time * the SIAR was sampled. We use that to work out if the SIAR was sampled in * the hypervisor, our exception vectors or RTAS. */ -static unsigned long get_pc(void) +static unsigned long get_pc(struct pt_regs *regs) { unsigned long pc = mfspr(SPRN_SIAR); unsigned long mmcra; /* Cant do much about it */ if (!mmcra_has_sihv) - return pc; + return check_spinlock_pc(regs, pc); mmcra = mfspr(SPRN_MMCRA); @@ -196,10 +224,6 @@ static unsigned long get_pc(void) if (mmcra & MMCRA_SIPR) return pc; - /* Were we in our exception vectors? */ - if (pc < 0x4000UL) - return (unsigned long)__va(pc); - #ifdef CONFIG_PPC_PSERIES /* Were we in RTAS? */ if (pc >= rtas.base && pc < (rtas.base + rtas.size)) @@ -207,12 +231,16 @@ static unsigned long get_pc(void) return *((unsigned long *)rtas_bucket); #endif + /* Were we in our exception vectors or SLB real mode miss handler? */ + if (pc < 0x1000000UL) + return (unsigned long)__va(pc); + /* Not sure where we were */ if (pc < KERNELBASE) /* function descriptor madness */ return *((unsigned long *)kernel_unknown_bucket); - return pc; + return check_spinlock_pc(regs, pc); } static int get_kernel(unsigned long pc) @@ -239,7 +267,7 @@ static void power4_handle_interrupt(struct pt_regs *regs, unsigned int cpu = smp_processor_id(); unsigned int mmcr0; - pc = get_pc(); + pc = get_pc(regs); is_kernel = get_kernel(pc); /* set the PMM bit (see comment below) */ diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index b7a871a8906a..928ffeb0fabb 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -75,7 +75,7 @@ sys_call_table: /*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_mq_open, sys_mq_unlink /*275*/ .long sys_mq_timedsend, sys_mq_timedreceive, sys_mq_notify, sys_mq_getsetattr, sys_waitid -/*280*/ .long sys_setaltroot, sys_add_key, sys_request_key, sys_keyctl +/*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ diff --git a/arch/um/Makefile b/arch/um/Makefile index 425d138d040c..1ad959f43beb 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -5,7 +5,8 @@ ARCH_DIR = arch/um OS := $(shell uname -s) -#We require it or things break. +# We require bash because the vmlinux link and loader script cpp use bash +# features. SHELL := /bin/bash filechk_gen_header = $< @@ -62,16 +63,18 @@ ifeq ($(CONFIG_MODE_SKAS), y) $(SYS_HEADERS) : $(ARCH_DIR)/include/skas_ptregs.h endif +.PHONY: linux + all: linux linux: vmlinux - $(RM) $@ - ln $< $@ + ln -f $< $@ define archhelp echo '* linux - Binary kernel image (./linux) - for backward' - echo ' compatibility only: now you can simply run' - echo ' the vmlinux binary you find in the kernel root.' + echo ' compatibility only, this creates a hard link to the' + echo ' real kernel binary, the the "vmlinux" binary you' + echo ' find in the kernel root.' endef prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) \ @@ -117,7 +120,8 @@ define cmd_vmlinux__ -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ -Wl,--start-group $(vmlinux-main) -Wl,--end-group \ -L/usr/lib -lutil \ - $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE ,$^) + $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \ + FORCE ,$^) ; rm -f linux endef USER_CFLAGS := $(patsubst -I%,,$(CFLAGS)) diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 8a5180a779e5..b62f8e28379a 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -27,14 +27,26 @@ int generic_console_write(int fd, const char *buf, int n, void *unused) int err; if(isatty(fd)){ - tcgetattr(fd, &save); + CATCH_EINTR(err = tcgetattr(fd, &save)); + if (err) + goto error; new = save; + /* The terminal becomes a bit less raw, to handle \n also as + * "Carriage Return", not only as "New Line". Otherwise, the new + * line won't start at the first column.*/ new.c_oflag |= OPOST; - tcsetattr(fd, TCSAFLUSH, &new); + CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &new)); + if (err) + goto error; } err = generic_write(fd, buf, n, NULL); - if(isatty(fd)) tcsetattr(fd, TCSAFLUSH, &save); + /* Restore raw mode, in any case; we *must* ignore any error apart + * EINTR, except for debug.*/ + if(isatty(fd)) + CATCH_EINTR(tcsetattr(fd, TCSAFLUSH, &save)); return(err); +error: + return(-errno); } static void winch_handler(int sig) diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index ac116724f05d..0c87589c0781 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -119,12 +119,98 @@ void mconsole_log(struct mc_request *req) mconsole_reply(req, "", 0, 0); } +/* This is a more convoluted version of mconsole_proc, which has some stability + * problems; however, we need it fixed, because it is expected that UML users + * mount HPPFS instead of procfs on /proc. And we want mconsole_proc to still + * show the real procfs content, not the ones from hppfs.*/ +#if 0 +void mconsole_proc(struct mc_request *req) +{ + struct nameidata nd; + struct file_system_type *proc; + struct super_block *super; + struct file *file; + int n, err; + char *ptr = req->request.data, *buf; + + ptr += strlen("proc"); + while(isspace(*ptr)) ptr++; + + proc = get_fs_type("proc"); + if(proc == NULL){ + mconsole_reply(req, "procfs not registered", 1, 0); + goto out; + } + + super = (*proc->get_sb)(proc, 0, NULL, NULL); + put_filesystem(proc); + if(super == NULL){ + mconsole_reply(req, "Failed to get procfs superblock", 1, 0); + goto out; + } + up_write(&super->s_umount); + + nd.dentry = super->s_root; + nd.mnt = NULL; + nd.flags = O_RDONLY + 1; + nd.last_type = LAST_ROOT; + + /* START: it was experienced that the stability problems are closed + * if commenting out these two calls + the below read cycle. To + * make UML crash again, it was enough to readd either one.*/ + err = link_path_walk(ptr, &nd); + if(err){ + mconsole_reply(req, "Failed to look up file", 1, 0); + goto out_kill; + } + + file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); + if(IS_ERR(file)){ + mconsole_reply(req, "Failed to open file", 1, 0); + goto out_kill; + } + /*END*/ + + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if(buf == NULL){ + mconsole_reply(req, "Failed to allocate buffer", 1, 0); + goto out_fput; + } + + if((file->f_op != NULL) && (file->f_op->read != NULL)){ + do { + n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, + &file->f_pos); + if(n >= 0){ + buf[n] = '\0'; + mconsole_reply(req, buf, 0, (n > 0)); + } + else { + mconsole_reply(req, "Read of file failed", + 1, 0); + goto out_free; + } + } while(n > 0); + } + else mconsole_reply(req, "", 0, 0); + + out_free: + kfree(buf); + out_fput: + fput(file); + out_kill: + deactivate_super(super); + out: ; +} +#endif + void mconsole_proc(struct mc_request *req) { char path[64]; char *buf; int len; int fd; + int first_chunk = 1; char *ptr = req->request.data; ptr += strlen("proc"); @@ -149,7 +235,13 @@ void mconsole_proc(struct mc_request *req) if (len < 0) { mconsole_reply(req, "Read of file failed", 1, 0); goto out_free; - } else if (len == PAGE_SIZE-1) { + } + /*Begin the file content on his own line.*/ + if (first_chunk) { + mconsole_reply(req, "\n", 0, 1); + first_chunk = 0; + } + if (len == PAGE_SIZE-1) { buf[len] = '\0'; mconsole_reply(req, buf, 0, 1); } else { diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c index 1e8592ec1158..996e817f3a3f 100644 --- a/arch/um/drivers/port_user.c +++ b/arch/um/drivers/port_user.c @@ -123,12 +123,18 @@ struct chan_ops port_ops = { int port_listen_fd(int port) { struct sockaddr_in addr; - int fd, err; + int fd, err, arg; fd = socket(PF_INET, SOCK_STREAM, 0); if(fd == -1) return(-errno); + arg = 1; + if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0){ + err = -errno; + goto out; + } + addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = htonl(INADDR_ANY); diff --git a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h index f530ac3f81ed..d6404bb64662 100644 --- a/arch/um/include/mem_user.h +++ b/arch/um/include/mem_user.h @@ -67,6 +67,7 @@ extern void map_memory(unsigned long virt, unsigned long phys, extern int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, int must_succeed); extern unsigned long get_kmem_end(void); +extern void check_tmpexec(void); #endif diff --git a/arch/um/include/mode.h b/arch/um/include/mode.h index 23b95f999b23..786cf563eb05 100644 --- a/arch/um/include/mode.h +++ b/arch/um/include/mode.h @@ -9,11 +9,11 @@ #include "uml-config.h" #ifdef UML_CONFIG_MODE_TT -#include "../kernel/tt/include/mode.h" +#include "mode-tt.h" #endif #ifdef UML_CONFIG_MODE_SKAS -#include "../kernel/skas/include/mode.h" +#include "mode-skas.h" #endif #endif diff --git a/arch/um/include/mode_kern.h b/arch/um/include/mode_kern.h index 562174bf48a0..2d88afd0cf16 100644 --- a/arch/um/include/mode_kern.h +++ b/arch/um/include/mode_kern.h @@ -9,11 +9,11 @@ #include "linux/config.h" #ifdef CONFIG_MODE_TT -#include "../kernel/tt/include/mode_kern.h" +#include "mode_kern-tt.h" #endif #ifdef CONFIG_MODE_SKAS -#include "../kernel/skas/include/mode_kern.h" +#include "mode_kern-skas.h" #endif #endif diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 8c4011265830..07340c8cf203 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -157,6 +157,7 @@ extern unsigned long os_process_pc(int pid); extern int os_process_parent(int pid); extern void os_stop_process(int pid); extern void os_kill_process(int pid, int reap_child); +extern void os_kill_ptraced_process(int pid, int reap_child); extern void os_usr1_process(int pid); extern int os_getpid(void); diff --git a/arch/um/include/ptrace_user.h b/arch/um/include/ptrace_user.h index ad35d0c2b9c1..227cef5fa7ab 100644 --- a/arch/um/include/ptrace_user.h +++ b/arch/um/include/ptrace_user.h @@ -15,4 +15,15 @@ extern void arch_enter_kernel(void *task, int pid); extern void arch_leave_kernel(void *task, int pid); extern void ptrace_pokeuser(unsigned long addr, unsigned long data); + +/* syscall emulation path in ptrace */ + +#ifndef PTRACE_SYSEMU +#define PTRACE_SYSEMU 31 +#endif + +void set_using_sysemu(int value); +int get_using_sysemu(void); +extern int sysemu_supported; + #endif diff --git a/arch/um/include/um_mmu.h b/arch/um/include/um_mmu.h index 3c5660ff97d7..5243f455fc3a 100644 --- a/arch/um/include/um_mmu.h +++ b/arch/um/include/um_mmu.h @@ -10,11 +10,11 @@ #include "choose-mode.h" #ifdef CONFIG_MODE_TT -#include "../kernel/tt/include/mmu.h" +#include "mmu-tt.h" #endif #ifdef CONFIG_MODE_SKAS -#include "../kernel/skas/include/mmu.h" +#include "mmu-skas.h" #endif typedef union { diff --git a/arch/um/include/um_uaccess.h b/arch/um/include/um_uaccess.h index c9b3574c6ea9..0924fcc95f1c 100644 --- a/arch/um/include/um_uaccess.h +++ b/arch/um/include/um_uaccess.h @@ -10,11 +10,11 @@ #include "choose-mode.h" #ifdef CONFIG_MODE_TT -#include "../kernel/tt/include/uaccess.h" +#include "uaccess-tt.h" #endif #ifdef CONFIG_MODE_SKAS -#include "../kernel/skas/include/uaccess.h" +#include "uaccess-skas.h" #endif #define access_ok(type, addr, size) \ diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index ab089d7a7389..4fc088eb73fa 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -8,7 +8,7 @@ #include "sysdep/ptrace.h" -#define CATCH_EINTR(expr) while (((expr) < 0) && (errno == EINTR)) +#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) extern int mode_tt; diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c index 2dc2f431fab7..d323cbf60d75 100644 --- a/arch/um/kernel/main.c +++ b/arch/um/kernel/main.c @@ -17,6 +17,8 @@ #include "kern_util.h" #include "mem_user.h" #include "signal_user.h" +#include "time_user.h" +#include "irq_user.h" #include "user.h" #include "init.h" #include "mode.h" diff --git a/arch/um/kernel/mem_user.c b/arch/um/kernel/mem_user.c index ec15ba43d537..67357fa51714 100644 --- a/arch/um/kernel/mem_user.c +++ b/arch/um/kernel/mem_user.c @@ -83,6 +83,26 @@ static int create_tmp_file(unsigned long len) return(fd); } +void check_tmpexec(void) +{ + void *addr; + int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); + + addr = mmap(NULL, UM_KERN_PAGE_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); + printf("Checking PROT_EXEC mmap in /tmp..."); + fflush(stdout); + if(addr == MAP_FAILED){ + err = errno; + perror("failed"); + if(err == EPERM) + printf("/tmp must be not mounted noexec\n"); + exit(1); + } + printf("OK\n"); + munmap(addr, UM_KERN_PAGE_SIZE); +} + static int have_devanon = 0; void check_devanon(void) @@ -111,7 +131,7 @@ static int create_anon_file(unsigned long len) exit(1); } - addr = mmap(NULL, len, PROT_READ | PROT_WRITE , MAP_PRIVATE, fd, 0); + addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if(addr == MAP_FAILED){ os_print_error((int) addr, "mapping physmem file"); exit(1); @@ -208,6 +228,39 @@ int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, return(0); } +#if 0 +/* Debugging facility for dumping stuff out to the host, avoiding the timing + * problems that come with printf and breakpoints. + * Enable in case of emergency. + */ + +int logging = 1; +int logging_fd = -1; + +int logging_line = 0; +char logging_buf[512]; + +void log(char *fmt, ...) +{ + va_list ap; + struct timeval tv; + struct openflags flags; + + if(logging == 0) return; + if(logging_fd < 0){ + flags = of_create(of_trunc(of_rdwr(OPENFLAGS()))); + logging_fd = os_open_file("log", flags, 0644); + } + gettimeofday(&tv, NULL); + sprintf(logging_buf, "%d\t %u.%u ", logging_line++, tv.tv_sec, + tv.tv_usec); + va_start(ap, fmt); + vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap); + va_end(ap); + write(logging_fd, logging_buf, strlen(logging_buf)); +} +#endif + /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index bb081c6ca88f..d2f0e82cacf3 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -137,14 +137,31 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack, static int ptrace_child(void *arg) { - int pid = os_getpid(); + int ret; + int pid = os_getpid(), ppid = getppid(); + int sc_result; if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ perror("ptrace"); os_kill_process(pid, 0); } os_stop_process(pid); - _exit(os_getpid() == pid); + + /*This syscall will be intercepted by the parent. Don't call more than + * once, please.*/ + sc_result = os_getpid(); + + if (sc_result == pid) + ret = 1; /*Nothing modified by the parent, we are running + normally.*/ + else if (sc_result == ppid) + ret = 0; /*Expected in check_ptrace and check_sysemu when they + succeed in modifying the stack frame*/ + else + ret = 2; /*Serious trouble! This could be caused by a bug in + host 2.6 SKAS3/2.6 patch before release -V6, together + with a bug in the UML code itself.*/ + _exit(ret); } static int start_ptraced_child(void **stack_out) @@ -172,18 +189,36 @@ static int start_ptraced_child(void **stack_out) return(pid); } -static void stop_ptraced_child(int pid, void *stack, int exitcode) +/* When testing for SYSEMU support, if it is one of the broken versions, we must + * just avoid using sysemu, not panic, but only if SYSEMU features are broken. + * So only for SYSEMU features we test mustpanic, while normal host features + * must work anyway!*/ +static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) { - int status, n; + int status, n, ret = 0; if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) panic("check_ptrace : ptrace failed, errno = %d", errno); CATCH_EINTR(n = waitpid(pid, &status, 0)); - if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) - panic("check_ptrace : child exited with status 0x%x", status); + if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { + int exit_with = WEXITSTATUS(status); + if (exit_with == 2) + printk("check_ptrace : child exited with status 2. " + "Serious trouble happening! Try updating your " + "host skas patch!\nDisabling SYSEMU support."); + printk("check_ptrace : child exited with exitcode %d, while " + "expecting %d; status 0x%x", exit_with, + exitcode, status); + if (mustpanic) + panic("\n"); + else + printk("\n"); + ret = -1; + } if(munmap(stack, PAGE_SIZE) < 0) panic("check_ptrace : munmap failed, errno = %d", errno); + return ret; } static int force_sysemu_disabled = 0; @@ -200,63 +235,46 @@ __uml_setup("nosysemu", nosysemu_cmd_param, " SYSEMU is a performance-patch introduced by Laurent Vivier. It changes\n" " behaviour of ptrace() and helps reducing host context switch rate.\n" " To make it working, you need a kernel patch for your host, too.\n" - " See http://perso.wanadoo.fr/laurent.vivier/UML/ for further information.\n"); - -/* Ugly hack for now... --cw */ -#ifndef PTRACE_SYSEMU -#define PTRACE_SYSEMU 31 -#endif + " See http://perso.wanadoo.fr/laurent.vivier/UML/ for further information.\n\n"); static void __init check_sysemu(void) { void *stack; int pid, n, status; - if (mode_tt) - return; - printk("Checking syscall emulation patch for ptrace..."); -#ifdef CONFIG_MODE_SKAS sysemu_supported = 0; -#endif /* CONFIG_MODE_SKAS */ pid = start_ptraced_child(&stack); - if(ptrace(PTRACE_SYSEMU, pid, 0, 0) >= 0) { - struct user_regs_struct regs; - - CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); - if (n < 0) - panic("check_ptrace : wait failed, errno = %d", errno); - if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) - panic("check_ptrace : expected SIGTRAP, " - "got status = %d", status); - if (ptrace(PTRACE_GETREGS, pid, 0, ®s) < 0) - panic("check_ptrace : failed to read child " - "registers, errno = %d", errno); - regs.orig_eax = pid; - if (ptrace(PTRACE_SETREGS, pid, 0, ®s) < 0) - panic("check_ptrace : failed to modify child " - "registers, errno = %d", errno); + if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) + goto fail; - stop_ptraced_child(pid, stack, 0); + CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); + if (n < 0) + panic("check_sysemu : wait failed, errno = %d", errno); + if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) + panic("check_sysemu : expected SIGTRAP, " + "got status = %d", status); + + n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, + os_getpid()); + if(n < 0) + panic("check_sysemu : failed to modify system " + "call return, errno = %d", errno); -#ifdef CONFIG_MODE_SKAS - sysemu_supported = 1; -#endif /* CONFIG_MODE_SKAS */ - printk("found\n"); - } - else - { - stop_ptraced_child(pid, stack, 1); -#ifdef CONFIG_MODE_SKAS - sysemu_supported = 0; -#endif /* CONFIG_MODE_SKAS */ - printk("missing\n"); - } + if (stop_ptraced_child(pid, stack, 0, 0) < 0) + goto fail_stopped; -#ifdef CONFIG_MODE_SKAS + sysemu_supported = 1; + printk("OK\n"); set_using_sysemu(!force_sysemu_disabled); -#endif + return; + +fail: + stop_ptraced_child(pid, stack, 1, 0); +fail_stopped: + sysemu_supported = 0; + printk("missing\n"); } void __init check_ptrace(void) @@ -289,7 +307,7 @@ void __init check_ptrace(void) break; } } - stop_ptraced_child(pid, stack, 0); + stop_ptraced_child(pid, stack, 0, 1); printk("OK\n"); check_sysemu(); } @@ -337,7 +355,7 @@ int can_do_skas(void) else printf("found\n"); init_registers(pid); - stop_ptraced_child(pid, stack, 1); + stop_ptraced_child(pid, stack, 1, 1); printf("Checking for /proc/mm..."); if(os_access("/proc/mm", OS_ACC_W_OK) < 0){ diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index 5b240256f67c..02370164f7fa 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c @@ -18,6 +18,8 @@ #include "linux/capability.h" #include "linux/vmalloc.h" #include "linux/spinlock.h" +#include "linux/proc_fs.h" +#include "linux/ptrace.h" #include "asm/unistd.h" #include "asm/mman.h" #include "asm/segment.h" @@ -398,6 +400,74 @@ int cpu(void) return(current_thread->cpu); } +static atomic_t using_sysemu = ATOMIC_INIT(0); +int sysemu_supported; + +void set_using_sysemu(int value) +{ + atomic_set(&using_sysemu, sysemu_supported && value); +} + +int get_using_sysemu(void) +{ + return atomic_read(&using_sysemu); +} + +static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data) +{ + if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/ + *eof = 1; + + return strlen(buf); +} + +static int proc_write_sysemu(struct file *file,const char *buf, unsigned long count,void *data) +{ + char tmp[2]; + + if (copy_from_user(tmp, buf, 1)) + return -EFAULT; + + if (tmp[0] == '0' || tmp[0] == '1') + set_using_sysemu(tmp[0] - '0'); + return count; /*We use the first char, but pretend to write everything*/ +} + +int __init make_proc_sysemu(void) +{ + struct proc_dir_entry *ent; + if (!sysemu_supported) + return 0; + + ent = create_proc_entry("sysemu", 0600, &proc_root); + + if (ent == NULL) + { + printk("Failed to register /proc/sysemu\n"); + return(0); + } + + ent->read_proc = proc_read_sysemu; + ent->write_proc = proc_write_sysemu; + + return 0; +} + +late_initcall(make_proc_sysemu); + +int singlestepping(void * t) +{ + struct task_struct *task = t ? t : current; + + if ( ! (task->ptrace & PT_DTRACE) ) + return(0); + + if (task->thread.singlestep_syscall) + return(0); + + return 1; +} + /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index b4efb669be41..536ae67f1ef1 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -22,6 +22,8 @@ */ void ptrace_disable(struct task_struct *child) { + child->ptrace &= ~PT_DTRACE; + child->thread.singlestep_syscall = 0; } int sys_ptrace(long request, long pid, long addr, long data) @@ -139,6 +141,9 @@ int sys_ptrace(long request, long pid, long addr, long data) ret = -EIO; if ((unsigned long) data > _NSIG) break; + + child->ptrace &= ~PT_DTRACE; + child->thread.singlestep_syscall = 0; if (request == PTRACE_SYSCALL) { set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); } @@ -160,6 +165,9 @@ int sys_ptrace(long request, long pid, long addr, long data) ret = 0; if (child->exit_state == EXIT_ZOMBIE) /* already dead */ break; + + child->ptrace &= ~PT_DTRACE; + child->thread.singlestep_syscall = 0; child->exit_code = SIGKILL; wake_up_process(child); break; @@ -171,6 +179,7 @@ int sys_ptrace(long request, long pid, long addr, long data) break; clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->ptrace |= PT_DTRACE; + child->thread.singlestep_syscall = 0; child->exit_code = data; /* give it a chance to run. */ wake_up_process(child); @@ -299,6 +308,9 @@ int sys_ptrace(long request, long pid, long addr, long data) void syscall_trace(union uml_pt_regs *regs, int entryexit) { + int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit; + int tracesysgood; + if (unlikely(current->audit_context)) { if (!entryexit) audit_syscall_entry(current, regs->orig_eax, @@ -308,18 +320,20 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit) audit_syscall_exit(current, regs->eax); } - if (!test_thread_flag(TIF_SYSCALL_TRACE)) + if (!test_thread_flag(TIF_SYSCALL_TRACE) && !is_singlestep) return; if (!(current->ptrace & PT_PTRACED)) return; /* the 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); + tracesysgood = (current->ptrace & PT_TRACESYSGOOD) && !is_singlestep; + ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0)); + + /* force do_signal() --> is_syscall() */ + set_thread_flag(TIF_SIGPENDING); - /* - * this isn't the same as continuing with a signal, but it will do + /* this isn't the same as continuing with a signal, but it will do * for normal use. strace only continues with a signal if the * stopping signal is not SIGTRAP. -brl */ diff --git a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c index fbffae415459..9704c138f561 100644 --- a/arch/um/kernel/sigio_kern.c +++ b/arch/um/kernel/sigio_kern.c @@ -28,7 +28,7 @@ int write_sigio_irq(int fd) int err; err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, - SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio", + SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio", NULL); if(err){ printk("write_sigio_irq : um_request_irq failed, err = %d\n", diff --git a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c index 23aefcbea7a2..5c406914e9e9 100644 --- a/arch/um/kernel/signal_kern.c +++ b/arch/um/kernel/signal_kern.c @@ -38,16 +38,17 @@ EXPORT_SYMBOL(unblock_signals); /* * OK, we're invoking a handler */ -static int handle_signal(struct pt_regs *regs, unsigned long signr, - struct k_sigaction *ka, siginfo_t *info, - sigset_t *oldset, int error) +static void handle_signal(struct pt_regs *regs, unsigned long signr, + struct k_sigaction *ka, siginfo_t *info, + sigset_t *oldset) { __sighandler_t handler; void (*restorer)(void); unsigned long sp; sigset_t save; - int err, ret; + int error, err, ret; + error = PT_REGS_SYSCALL_RET(¤t->thread.regs); ret = 0; /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; @@ -109,31 +110,25 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, else err = setup_signal_stack_sc(sp, signr, (unsigned long) handler, restorer, regs, &save); - if(err) goto segv; - - return(0); - segv: - force_sigsegv(signr, current); - return(1); + if(err) + force_sigsegv(signr, current); } -static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error) +static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset) { struct k_sigaction ka_copy; siginfo_t info; - int err, sig; + int sig; if (!oldset) oldset = ¤t->blocked; sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL); - if(sig == 0) - return(0); - - /* Whee! Actually deliver the signal. */ - err = handle_signal(regs, sig, &ka_copy, &info, oldset, error); - if(!err) + if(sig > 0){ + /* Whee! Actually deliver the signal. */ + handle_signal(regs, sig, &ka_copy, &info, oldset); return(1); + } /* Did we come from a system call? */ if(PT_REGS_SYSCALL_NR(regs) >= 0){ @@ -157,15 +152,15 @@ static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error) * on the host. The tracing thread will check this flag and * PTRACE_SYSCALL if necessary. */ - if((current->ptrace & PT_DTRACE) && - is_syscall(PT_REGS_IP(¤t->thread.regs))) - (void) CHOOSE_MODE(current->thread.mode.tt.singlestep_syscall = 1, 0); + if(current->ptrace & PT_DTRACE) + current->thread.singlestep_syscall = + is_syscall(PT_REGS_IP(¤t->thread.regs)); return(0); } int do_signal(int error) { - return(kern_do_signal(¤t->thread.regs, NULL, error)); + return(kern_do_signal(¤t->thread.regs, NULL)); } /* @@ -182,10 +177,11 @@ int sys_sigsuspend(int history0, int history1, old_sigset_t mask) recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + PT_REGS_SYSCALL_RET(¤t->thread.regs) = -EINTR; while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if(kern_do_signal(¤t->thread.regs, &saveset, -EINTR)) + if(kern_do_signal(¤t->thread.regs, &saveset)) return(-EINTR); } } @@ -208,10 +204,11 @@ int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize) recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); + PT_REGS_SYSCALL_RET(¤t->thread.regs) = -EINTR; while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if (kern_do_signal(¤t->thread.regs, &saveset, -EINTR)) + if (kern_do_signal(¤t->thread.regs, &saveset)) return(-EINTR); } } diff --git a/arch/um/kernel/signal_user.c b/arch/um/kernel/signal_user.c index 74a69e491e00..2468cd6a625d 100644 --- a/arch/um/kernel/signal_user.c +++ b/arch/um/kernel/signal_user.c @@ -57,6 +57,10 @@ int change_sig(int signal, int on) return(!sigismember(&old, signal)); } +/* Both here and in set/get_signal we don't touch SIGPROF, because we must not + * disable profiling; it's safe because the profiling code does not interact + * with the kernel code at all.*/ + static void change_signals(int type) { sigset_t mask; @@ -65,7 +69,6 @@ static void change_signals(int type) sigaddset(&mask, SIGVTALRM); sigaddset(&mask, SIGALRM); sigaddset(&mask, SIGIO); - sigaddset(&mask, SIGPROF); if(sigprocmask(type, &mask, NULL) < 0) panic("Failed to change signal mask - errno = %d", errno); } diff --git a/arch/um/kernel/skas/exec_kern.c b/arch/um/kernel/skas/exec_kern.c index 49356d26ac28..c6b4d5dba789 100644 --- a/arch/um/kernel/skas/exec_kern.c +++ b/arch/um/kernel/skas/exec_kern.c @@ -12,7 +12,7 @@ #include "asm/mmu_context.h" #include "tlb.h" #include "skas.h" -#include "mmu.h" +#include "um_mmu.h" #include "os.h" void flush_thread_skas(void) diff --git a/arch/um/kernel/skas/include/mmu.h b/arch/um/kernel/skas/include/mmu-skas.h index cfbc062bd9dc..4cd60d7213f3 100644 --- a/arch/um/kernel/skas/include/mmu.h +++ b/arch/um/kernel/skas/include/mmu-skas.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -6,9 +6,6 @@ #ifndef __SKAS_MMU_H #define __SKAS_MMU_H -#include "linux/list.h" -#include "linux/spinlock.h" - struct mmu_context_skas { int mm_fd; }; diff --git a/arch/um/kernel/skas/include/mode.h b/arch/um/kernel/skas/include/mode-skas.h index 285edc50a27f..f19838880407 100644 --- a/arch/um/kernel/skas/include/mode.h +++ b/arch/um/kernel/skas/include/mode-skas.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -6,6 +6,8 @@ #ifndef __MODE_SKAS_H__ #define __MODE_SKAS_H__ +#include <sysdep/ptrace.h> + extern unsigned long exec_regs[]; extern unsigned long exec_fp_regs[]; extern unsigned long exec_fpx_regs[]; @@ -15,7 +17,7 @@ extern void user_time_init_skas(void); extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr); extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, - union uml_pt_regs *regs, + union uml_pt_regs *regs, unsigned long fault_addr, int fault_type); extern void sig_handler_common_skas(int sig, void *sc_ptr); extern void halt_skas(void); diff --git a/arch/um/kernel/skas/include/mode_kern.h b/arch/um/kernel/skas/include/mode_kern-skas.h index 3597c0908b1c..94c564962378 100644 --- a/arch/um/kernel/skas/include/mode_kern.h +++ b/arch/um/kernel/skas/include/mode_kern-skas.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -12,20 +12,20 @@ extern void flush_thread_skas(void); extern void *switch_to_skas(void *prev, void *next); -extern void start_thread_skas(struct pt_regs *regs, unsigned long eip, +extern void start_thread_skas(struct pt_regs *regs, unsigned long eip, unsigned long esp); -extern int copy_thread_skas(int nr, unsigned long clone_flags, - unsigned long sp, unsigned long stack_top, +extern int copy_thread_skas(int nr, unsigned long clone_flags, + unsigned long sp, unsigned long stack_top, struct task_struct *p, struct pt_regs *regs); extern void release_thread_skas(struct task_struct *task); extern void exit_thread_skas(void); extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); extern void init_idle_skas(void); -extern void flush_tlb_kernel_range_skas(unsigned long start, +extern void flush_tlb_kernel_range_skas(unsigned long start, unsigned long end); extern void flush_tlb_kernel_vm_skas(void); extern void __flush_tlb_one_skas(unsigned long addr); -extern void flush_tlb_range_skas(struct vm_area_struct *vma, +extern void flush_tlb_range_skas(struct vm_area_struct *vma, unsigned long start, unsigned long end); extern void flush_tlb_mm_skas(struct mm_struct *mm); extern void force_flush_all_skas(void); diff --git a/arch/um/kernel/skas/include/ptrace-skas.h b/arch/um/kernel/skas/include/ptrace-skas.h index be043e8f7e78..f5c5268cc492 100644 --- a/arch/um/kernel/skas/include/ptrace-skas.h +++ b/arch/um/kernel/skas/include/ptrace-skas.h @@ -10,16 +10,6 @@ #ifdef UML_CONFIG_MODE_SKAS -/* syscall emulation path in ptrace */ - -#ifndef PTRACE_SYSEMU -#define PTRACE_SYSEMU 31 -#endif - -void set_using_sysemu(int value); -int get_using_sysemu(void); -extern int sysemu_supported; - #include "skas_ptregs.h" #define HOST_FRAME_SIZE 17 diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h index 0bbc97540815..2f6eaa37455d 100644 --- a/arch/um/kernel/skas/include/skas.h +++ b/arch/um/kernel/skas/include/skas.h @@ -28,7 +28,6 @@ extern int unmap(int fd, void *addr, int len); extern int protect(int fd, unsigned long addr, unsigned long len, int r, int w, int x, int must_succeed); extern void user_signal(int sig, union uml_pt_regs *regs); -extern int singlestepping_skas(void); extern int new_mm(int from); extern void save_registers(union uml_pt_regs *regs); extern void restore_registers(union uml_pt_regs *regs); diff --git a/arch/um/kernel/skas/include/uaccess.h b/arch/um/kernel/skas/include/uaccess-skas.h index 0d6f30bf718f..da9c52ce424f 100644 --- a/arch/um/kernel/skas/include/uaccess.h +++ b/arch/um/kernel/skas/include/uaccess-skas.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -13,7 +13,7 @@ (((unsigned long) (addr) < TASK_SIZE) && \ ((unsigned long) (addr) + (size) <= TASK_SIZE))) -static inline int verify_area_skas(int type, const void * addr, +static inline int verify_area_skas(int type, const void * addr, unsigned long size) { return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index cb748f85dace..c404c37f4c9e 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -139,17 +139,16 @@ void start_userspace(int cpu) void userspace(union uml_pt_regs *regs) { - int err, status, op, pid = userspace_pid[0]; + int err, status, op, pt_syscall_parm, pid = userspace_pid[0]; int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/ restore_registers(regs); local_using_sysemu = get_using_sysemu(); - if (local_using_sysemu) - err = ptrace(PTRACE_SYSEMU, pid, 0, 0); - else - err = ptrace(PTRACE_SYSCALL, pid, 0, 0); + pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL; + err = ptrace(pt_syscall_parm, pid, 0, 0); + if(err) panic("userspace - PTRACE_%s failed, errno = %d\n", local_using_sysemu ? "SYSEMU" : "SYSCALL", errno); @@ -189,13 +188,10 @@ void userspace(union uml_pt_regs *regs) /*Now we ended the syscall, so re-read local_using_sysemu.*/ local_using_sysemu = get_using_sysemu(); + pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL; - if (local_using_sysemu) - op = singlestepping_skas() ? PTRACE_SINGLESTEP : - PTRACE_SYSEMU; - else - op = singlestepping_skas() ? PTRACE_SINGLESTEP : - PTRACE_SYSCALL; + op = singlestepping(NULL) ? PTRACE_SINGLESTEP : + pt_syscall_parm; err = ptrace(op, pid, 0, 0); if(err) @@ -389,7 +385,7 @@ void switch_mm_skas(int mm_fd) void kill_off_processes_skas(void) { #warning need to loop over userspace_pids in kill_off_processes_skas - os_kill_process(userspace_pid[0], 1); + os_kill_ptraced_process(userspace_pid[0], 1); } void init_registers(int pid) diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index 5418f0862889..b0c53a48e1b0 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c @@ -24,69 +24,6 @@ #include "mode.h" #include "proc_mm.h" -static atomic_t using_sysemu; -int sysemu_supported; - -void set_using_sysemu(int value) -{ - atomic_set(&using_sysemu, sysemu_supported && value); -} - -int get_using_sysemu(void) -{ - return atomic_read(&using_sysemu); -} - -int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data) -{ - if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/ - *eof = 1; - - return strlen(buf); -} - -int proc_write_sysemu(struct file *file,const char *buf, unsigned long count,void *data) -{ - char tmp[2]; - - if (copy_from_user(tmp, buf, 1)) - return -EFAULT; - - if (tmp[0] == '0' || tmp[0] == '1') - set_using_sysemu(tmp[0] - '0'); - return count; /*We use the first char, but pretend to write everything*/ -} - -int __init make_proc_sysemu(void) -{ - struct proc_dir_entry *ent; - if (mode_tt || !sysemu_supported) - return 0; - - ent = create_proc_entry("sysemu", 0600, &proc_root); - - if (ent == NULL) - { - printk("Failed to register /proc/sysemu\n"); - return(0); - } - - ent->read_proc = proc_read_sysemu; - ent->write_proc = proc_write_sysemu; - - return 0; -} - -late_initcall(make_proc_sysemu); - -int singlestepping_skas(void) -{ - int ret = current->ptrace & PT_DTRACE; - - current->ptrace &= ~PT_DTRACE; - return(ret); -} - void *switch_to_skas(void *prev, void *next) { struct task_struct *from, *to; diff --git a/arch/um/kernel/skas/syscall_kern.c b/arch/um/kernel/skas/syscall_kern.c index 1d7eca5a8d9a..bdf040ce5b8e 100644 --- a/arch/um/kernel/skas/syscall_kern.c +++ b/arch/um/kernel/skas/syscall_kern.c @@ -4,6 +4,7 @@ */ #include "linux/sys.h" +#include "linux/ptrace.h" #include "asm/errno.h" #include "asm/unistd.h" #include "asm/ptrace.h" diff --git a/arch/um/kernel/skas/syscall_user.c b/arch/um/kernel/skas/syscall_user.c index 34fd5f94e2f4..da1fb12372d6 100644 --- a/arch/um/kernel/skas/syscall_user.c +++ b/arch/um/kernel/skas/syscall_user.c @@ -22,7 +22,7 @@ void handle_syscall(union uml_pt_regs *regs) index = record_syscall_start(UPT_SYSCALL_NR(regs)); - syscall_trace(regs, 1); + syscall_trace(regs, 0); result = execute_syscall(regs); REGS_SET_SYSCALL_RETURN(regs->skas.regs, result); @@ -30,7 +30,7 @@ void handle_syscall(union uml_pt_regs *regs) (result == -ERESTARTNOINTR)) do_signal(result); - syscall_trace(regs, 0); + syscall_trace(regs, 1); record_syscall_end(index, result); } diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c index f74e1422d5c8..ea24ebf53341 100644 --- a/arch/um/kernel/sysrq.c +++ b/arch/um/kernel/sysrq.c @@ -14,23 +14,23 @@ void show_trace(unsigned long * stack) { - int i; + /* XXX: Copy the CONFIG_FRAME_POINTER stack-walking backtrace from + * arch/i386/kernel/traps.c. */ unsigned long addr; if (!stack) stack = (unsigned long*) &stack; - printk("Call Trace:\n"); - i = 1; + printk("Call Trace: \n"); while (((long) stack & (THREAD_SIZE-1)) != 0) { addr = *stack++; if (__kernel_text_address(addr)) { - printk("[<%08lx>] ", addr); - print_symbol("%s", addr); + printk(" [<%08lx>]", addr); + print_symbol(" %s", addr); printk("\n"); - i++; } } + printk("\n"); } /* @@ -48,4 +48,3 @@ void show_stack(struct task_struct *task, unsigned long *sp) { show_trace(sp); } - diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile index 33416e889e5c..1fa49c49bc6e 100644 --- a/arch/um/kernel/tt/Makefile +++ b/arch/um/kernel/tt/Makefile @@ -4,6 +4,7 @@ # extra-y := unmap_fin.o +clean-files := unmap_tmp.o obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \ @@ -20,10 +21,9 @@ UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS)) $(USER_OBJS) : %.o: %.c $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $< -$(O_TARGET) : $(obj)/unmap_fin.o - $(obj)/unmap.o: $(src)/unmap.c $(CC) $(UNMAP_CFLAGS) -c -o $@ $< -$(obj)/unmap_fin.o : $(src)/unmap.o - ld -r -o $@ $< -lc -L/usr/lib +$(obj)/unmap_fin.o : $(obj)/unmap.o + ld -r -o $(obj)/unmap_tmp.o $< -lc -L/usr/lib + objcopy $(obj)/unmap_tmp.o $@ -G switcheroo diff --git a/arch/um/kernel/tt/include/mmu.h b/arch/um/kernel/tt/include/mmu-tt.h index 6b146bd84ca7..0440510ab3fe 100644 --- a/arch/um/kernel/tt/include/mmu.h +++ b/arch/um/kernel/tt/include/mmu-tt.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ diff --git a/arch/um/kernel/tt/include/mode.h b/arch/um/kernel/tt/include/mode-tt.h index 1a64e753ea96..fb5cfd318d47 100644 --- a/arch/um/kernel/tt/include/mode.h +++ b/arch/um/kernel/tt/include/mode-tt.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -15,7 +15,7 @@ extern int tracing_pid; extern int tracer(int (*init_proc)(void *), void *sp); extern void user_time_init_tt(void); extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data); -extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, +extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data); extern void sig_handler_common_tt(int sig, void *sc); extern void syscall_handler_tt(int sig, union uml_pt_regs *regs); diff --git a/arch/um/kernel/tt/include/mode_kern.h b/arch/um/kernel/tt/include/mode_kern-tt.h index a8c31340d7a2..28aaab3448fa 100644 --- a/arch/um/kernel/tt/include/mode_kern.h +++ b/arch/um/kernel/tt/include/mode_kern-tt.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -13,10 +13,10 @@ extern void *switch_to_tt(void *prev, void *next); extern void flush_thread_tt(void); -extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, +extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, unsigned long esp); extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, - unsigned long stack_top, struct task_struct *p, + unsigned long stack_top, struct task_struct *p, struct pt_regs *regs); extern void release_thread_tt(struct task_struct *task); extern void exit_thread_tt(void); @@ -25,13 +25,13 @@ extern void init_idle_tt(void); extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); extern void flush_tlb_kernel_vm_tt(void); extern void __flush_tlb_one_tt(unsigned long addr); -extern void flush_tlb_range_tt(struct vm_area_struct *vma, +extern void flush_tlb_range_tt(struct vm_area_struct *vma, unsigned long start, unsigned long end); extern void flush_tlb_mm_tt(struct mm_struct *mm); extern void force_flush_all_tt(void); extern long execute_syscall_tt(void *r); extern void before_mem_tt(unsigned long brk_start); -extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, +extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, unsigned long *task_size_out); extern int start_uml_tt(void); extern int external_pid_tt(struct task_struct *task); diff --git a/arch/um/kernel/tt/include/tt.h b/arch/um/kernel/tt/include/tt.h index b7c474518e7f..e6d64eb86f53 100644 --- a/arch/um/kernel/tt/include/tt.h +++ b/arch/um/kernel/tt/include/tt.h @@ -24,11 +24,9 @@ extern void set_init_pid(int pid); extern int set_user_mode(void *task); extern void set_tracing(void *t, int tracing); extern int is_tracing(void *task); -extern int singlestepping_tt(void *t); -extern void clear_singlestep(void *t); extern void syscall_handler(int sig, union uml_pt_regs *regs); extern void exit_kernel(int pid, void *task); -extern int do_syscall(void *task, int pid); +extern int do_syscall(void *task, int pid, int local_using_sysemu); extern int is_valid_pid(int pid); extern void remap_data(void *segment_start, void *segment_end, int w); diff --git a/arch/um/kernel/tt/include/uaccess.h b/arch/um/kernel/tt/include/uaccess-tt.h index 7399836cb8d8..f0bad010cebd 100644 --- a/arch/um/kernel/tt/include/uaccess.h +++ b/arch/um/kernel/tt/include/uaccess-tt.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) * Licensed under the GPL */ @@ -33,7 +33,7 @@ extern unsigned long uml_physmem; (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ (under_task_size(addr, size) || is_stack(addr, size)))) -static inline int verify_area_tt(int type, const void * addr, +static inline int verify_area_tt(int type, const void * addr, unsigned long size) { return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index c287db9c189c..b6a6153fd883 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c @@ -82,7 +82,7 @@ void *switch_to_tt(void *prev, void *next, void *last) prev_sched = current->thread.prev_sched; if((prev_sched->exit_state == EXIT_ZOMBIE) || (prev_sched->exit_state == EXIT_DEAD)) - os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); + os_kill_ptraced_process(prev_sched->thread.mode.tt.extern_pid, 1); /* This works around a nasty race with 'jail'. If we are switching * between two threads of a threaded app and the incoming process @@ -523,22 +523,6 @@ void set_init_pid(int pid) -err); } -int singlestepping_tt(void *t) -{ - struct task_struct *task = t; - - if(task->thread.mode.tt.singlestep_syscall) - return(0); - return(task->ptrace & PT_DTRACE); -} - -void clear_singlestep(void *t) -{ - struct task_struct *task = t; - - task->ptrace &= ~PT_DTRACE; -} - int start_uml_tt(void) { void *sp; diff --git a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c index 555ffd0ee347..891045bb966a 100644 --- a/arch/um/kernel/tt/syscall_kern.c +++ b/arch/um/kernel/tt/syscall_kern.c @@ -123,12 +123,6 @@ long execute_syscall_tt(void *r) set_fs(USER_DS); - if(current->thread.mode.tt.singlestep_syscall){ - current->thread.mode.tt.singlestep_syscall = 0; - current->ptrace &= ~PT_DTRACE; - force_sig(SIGTRAP, current); - } - return(res); } diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c index 1cabbd866901..b3a66eb7ef7d 100644 --- a/arch/um/kernel/tt/syscall_user.c +++ b/arch/um/kernel/tt/syscall_user.c @@ -33,7 +33,7 @@ void syscall_handler_tt(int sig, union uml_pt_regs *regs) SC_START_SYSCALL(sc); index = record_syscall_start(syscall); - syscall_trace(regs, 1); + syscall_trace(regs, 0); result = execute_syscall(regs); /* regs->sc may have changed while the system call ran (there may @@ -46,11 +46,11 @@ void syscall_handler_tt(int sig, union uml_pt_regs *regs) (result == -ERESTARTNOINTR)) do_signal(result); - syscall_trace(regs, 0); + syscall_trace(regs, 1); record_syscall_end(index, result); } -int do_syscall(void *task, int pid) +int do_syscall(void *task, int pid, int local_using_sysemu) { unsigned long proc_regs[FRAME_SIZE]; union uml_pt_regs *regs; @@ -70,6 +70,9 @@ int do_syscall(void *task, int pid) ((unsigned long *) PT_IP(proc_regs) <= &_etext)) tracer_panic("I'm tracing myself and I can't get out"); + if(local_using_sysemu) + return(1); + if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid) < 0) tracer_panic("do_syscall : Nullifying syscall failed, " diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index deef43bb558d..33b9209a1d8c 100644 --- a/arch/um/kernel/tt/tracer.c +++ b/arch/um/kernel/tt/tracer.c @@ -184,6 +184,7 @@ int tracer(int (*init_proc)(void *), void *sp) unsigned long eip = 0; int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0; int last_index, proc_id = 0, n, err, old_tracing = 0, strace = 0; + int pt_syscall_parm, local_using_sysemu; capture_signal_stack(); signal(SIGPIPE, SIG_IGN); @@ -297,6 +298,9 @@ int tracer(int (*init_proc)(void *), void *sp) tracing = is_tracing(task); old_tracing = tracing; + local_using_sysemu = get_using_sysemu(); + pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL; + switch(sig){ case SIGUSR1: sig = 0; @@ -330,9 +334,8 @@ int tracer(int (*init_proc)(void *), void *sp) continue; } tracing = 0; - if(do_syscall(task, pid)) + if(do_syscall(task, pid, local_using_sysemu)) sig = SIGUSR2; - else clear_singlestep(task); break; case SIGPROF: if(tracing) sig = 0; @@ -349,6 +352,7 @@ int tracer(int (*init_proc)(void *), void *sp) case SIGBUS: case SIGILL: case SIGWINCH: + default: tracing = 0; break; @@ -368,9 +372,9 @@ int tracer(int (*init_proc)(void *), void *sp) } if(tracing){ - if(singlestepping_tt(task)) + if(singlestepping(task)) cont_type = PTRACE_SINGLESTEP; - else cont_type = PTRACE_SYSCALL; + else cont_type = pt_syscall_parm; } else cont_type = PTRACE_CONT; diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c index 00bacacfcc35..81b911fcd06e 100644 --- a/arch/um/kernel/tt/trap_user.c +++ b/arch/um/kernel/tt/trap_user.c @@ -30,6 +30,13 @@ void sig_handler_common_tt(int sig, void *sc_ptr) if(sig == SIGSEGV) change_sig(SIGSEGV, 1); + /* This is done because to allow SIGSEGV to be delivered inside a SEGV + * handler. This can happen in copy_user, and if SEGV is disabled, + * the process will die. + */ + if(sig == SIGSEGV) + change_sig(SIGSEGV, 1); + r = &TASK_REGS(get_current())->tt; save_regs = *r; is_user = user_context(SC_SP(sc)); diff --git a/arch/um/kernel/tty_log.c b/arch/um/kernel/tty_log.c index 0a70c5e663c0..9ada656f68ce 100644 --- a/arch/um/kernel/tty_log.c +++ b/arch/um/kernel/tty_log.c @@ -205,6 +205,8 @@ static int __init set_tty_log_fd(char *name, int *add) printf("set_tty_log_fd - strtoul failed on '%s'\n", name); tty_log_fd = -1; } + + *add = 0; return 0; } diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 9146c11e5069..8a33c9d4a818 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -321,6 +321,11 @@ int linux_main(int argc, char **argv) uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0, &host_task_size, &task_size); + /* Need to check this early because mmapping happens before the + * kernel is running. + */ + check_tmpexec(); + brk_start = (unsigned long) sbrk(0); CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start); /* Increase physical memory size for exec-shield users @@ -400,9 +405,9 @@ extern int uml_exitcode; static int panic_exit(struct notifier_block *self, unsigned long unused1, void *unused2) { -#ifdef CONFIG_MAGIC_SYSRQ - handle_sysrq('p', ¤t->thread.regs, NULL); -#endif + bust_spinlocks(1); + show_regs(&(current->thread.regs)); + bust_spinlocks(0); uml_exitcode = 1; machine_halt(); return(0); diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c index 78c8dc45c61e..aab119319b5d 100644 --- a/arch/um/kernel/umid.c +++ b/arch/um/kernel/umid.c @@ -54,6 +54,7 @@ static int __init set_umid(char *name, int is_random, static int __init set_umid_arg(char *name, int *add) { + *add = 0; return(set_umid(name, 0, printf)); } diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 514ab984cfb3..77d4066d1af8 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -308,7 +308,8 @@ int os_seek_file(int fd, __u64 offset) __u64 actual; actual = lseek64(fd, offset, SEEK_SET); - if(actual != offset) return(-errno); + if(actual != offset) + return(-errno); return(0); } diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index ec4617b42886..65f66bb9956b 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -8,6 +8,7 @@ #include <errno.h> #include <signal.h> #include <linux/unistd.h> +#include <sys/ptrace.h> #include <sys/mman.h> #include <sys/wait.h> #include "os.h" @@ -94,6 +95,13 @@ void os_kill_process(int pid, int reap_child) } +void os_kill_ptraced_process(int pid, int reap_child) +{ + ptrace(PTRACE_KILL, pid); + if(reap_child) + CATCH_EINTR(waitpid(pid, NULL, 0)); +} + void os_usr1_process(int pid) { kill(pid, SIGUSR1); diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index 817ef7479d3f..42322d888503 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c @@ -7,6 +7,7 @@ #include "asm/elf.h" #include "asm/ptrace.h" #include "asm/uaccess.h" +#include "asm/unistd.h" #include "ptrace_user.h" #include "sysdep/sigcontext.h" #include "sysdep/sc.h" @@ -23,11 +24,12 @@ int is_syscall(unsigned long addr) n = copy_from_user(&instr, (void *) addr, sizeof(instr)); if(n){ - printk("is_syscall : failed to read instruction from 0x%lu\n", + printk("is_syscall : failed to read instruction from 0x%lx\n", addr); return(0); } - return(instr == 0x80cd); + /* int 0x80 or sysenter */ + return((instr == 0x80cd) || (instr == 0x340f)); } /* determines which flags the user has access to. */ diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug index d584ecc27ea1..9cf1410d2f5a 100644 --- a/arch/x86_64/Kconfig.debug +++ b/arch/x86_64/Kconfig.debug @@ -33,6 +33,16 @@ config IOMMU_DEBUG options. See Documentation/x86_64/boot-options.txt for more details. +config KPROBES + bool "Kprobes" + depends on DEBUG_KERNEL + help + Kprobes allows you to trap at almost any kernel address and + execute a callback function. register_kprobe() establishes + a probepoint and specifies the callback. Kprobes is useful + for kernel debugging, non-intrusive instrumentation and testing. + If in doubt, say "N". + config IOMMU_LEAK bool "IOMMU leak tracing" depends on DEBUG_KERNEL diff --git a/arch/x86_64/ia32/ptrace32.c b/arch/x86_64/ia32/ptrace32.c index 4445da812ecf..81d4a9883fe6 100644 --- a/arch/x86_64/ia32/ptrace32.c +++ b/arch/x86_64/ia32/ptrace32.c @@ -109,7 +109,8 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 val) case offsetof(struct user32, u_debugreg[7]): val &= ~DR_CONTROL_RESERVED; - /* You are not expected to understand this ... I don't neither. */ + /* See arch/i386/kernel/ptrace.c for an explanation of + * this awkward check.*/ for(i=0; i<4; i++) if ((0x5454 >> ((val >> (16 + 4*i)) & 0xf)) & 1) return -EIO; diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index 718374303550..2c0f3af82e5e 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o obj-$(CONFIG_SWIOTLB) += swiotlb.o +obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_MODULES) += module.o diff --git a/arch/x86_64/kernel/cpufreq/Kconfig b/arch/x86_64/kernel/cpufreq/Kconfig index a87fc0dd3e4a..d3075cda3302 100644 --- a/arch/x86_64/kernel/cpufreq/Kconfig +++ b/arch/x86_64/kernel/cpufreq/Kconfig @@ -88,5 +88,29 @@ config X86_ACPI_CPUFREQ_PROC_INTF If in doubt, say N. +config X86_P4_CLOCKMOD + tristate "Intel Pentium 4 clock modulation" + depends on CPU_FREQ_TABLE && EMBEDDED + help + This adds the clock modulation driver for Intel Pentium 4 / XEON + processors. When enabled it will lower CPU temperature by skipping + clocks. + + This driver should be only used in exceptional + circumstances when very low power is needed because it causes severe + slowdowns and noticeable latencies. Normally Speedstep should be used + instead. + + For details, take a look at <file:Documentation/cpu-freq/>. + + Unless you are absolutely sure say N. + + +config X86_SPEEDSTEP_LIB + tristate + depends on (X86_P4_CLOCKMOD) + default (X86_P4_CLOCKMOD) + + endmenu diff --git a/arch/x86_64/kernel/cpufreq/Makefile b/arch/x86_64/kernel/cpufreq/Makefile index d0f0b2cf343b..30c07dc637f7 100644 --- a/arch/x86_64/kernel/cpufreq/Makefile +++ b/arch/x86_64/kernel/cpufreq/Makefile @@ -7,7 +7,11 @@ SRCDIR := ../../../i386/kernel/cpu/cpufreq obj-$(CONFIG_X86_POWERNOW_K8) += powernow-k8.o obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO) += speedstep-centrino.o obj-$(CONFIG_X86_ACPI_CPUFREQ) += acpi.o +obj-$(CONFIG_X86_P4_CLOCKMOD) += p4-clockmod.o +obj-$(CONFIG_X86_SPEEDSTEP_LIB) += speedstep-lib.o powernow-k8-objs := ${SRCDIR}/powernow-k8.o speedstep-centrino-objs := ${SRCDIR}/speedstep-centrino.o acpi-objs := ${SRCDIR}/acpi.o +p4-clockmod-objs := ${SRCDIR}/p4-clockmod.o +speedstep-lib-objs := ${SRCDIR}/speedstep-lib.o diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c new file mode 100644 index 000000000000..dfef3128ff63 --- /dev/null +++ b/arch/x86_64/kernel/kprobes.c @@ -0,0 +1,481 @@ +/* + * Kernel Probes (KProbes) + * arch/x86_64/kernel/kprobes.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) IBM Corporation, 2002, 2004 + * + * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel + * Probes initial implementation ( includes contributions from + * Rusty Russell). + * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes + * interface to access function arguments. + * 2004-Oct Jim Keniston <kenistoj@us.ibm.com> and Prasanna S Panchamukhi + * <prasanna@in.ibm.com> adapted for x86_64 + */ + +#include <linux/config.h> +#include <linux/kprobes.h> +#include <linux/ptrace.h> +#include <linux/spinlock.h> +#include <linux/string.h> +#include <linux/slab.h> +#include <linux/preempt.h> +#include <linux/vmalloc.h> + +#include <asm/pgtable.h> +#include <asm/kdebug.h> + +/* kprobe_status settings */ +#define KPROBE_HIT_ACTIVE 0x00000001 +#define KPROBE_HIT_SS 0x00000002 + +static struct kprobe *current_kprobe; +static unsigned long kprobe_status, kprobe_old_rflags, kprobe_saved_rflags; +static struct pt_regs jprobe_saved_regs; +static long *jprobe_saved_rsp; +static kprobe_opcode_t *get_insn_slot(void); +static void free_insn_slot(kprobe_opcode_t *slot); +void jprobe_return_end(void); + +/* copy of the kernel stack at the probe fire time */ +static kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; + +/* + * returns non-zero if opcode modifies the interrupt flag. + */ +static inline int is_IF_modifier(kprobe_opcode_t *insn) +{ + switch (*insn) { + case 0xfa: /* cli */ + case 0xfb: /* sti */ + case 0xcf: /* iret/iretd */ + case 0x9d: /* popf/popfd */ + return 1; + } + + if (*insn >= 0x40 && *insn <= 0x4f && *++insn == 0xcf) + return 1; + return 0; +} + +int arch_prepare_kprobe(struct kprobe *p) +{ + /* insn: must be on special executable page on x86_64. */ + p->ainsn.insn = get_insn_slot(); + if (!p->ainsn.insn) { + return -ENOMEM; + } + memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE); + return 0; +} + +void arch_remove_kprobe(struct kprobe *p) +{ + free_insn_slot(p->ainsn.insn); +} + +static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) +{ + *p->addr = p->opcode; + regs->rip = (unsigned long)p->addr; +} + +static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) +{ + regs->eflags |= TF_MASK; + regs->eflags &= ~IF_MASK; + + regs->rip = (unsigned long)p->ainsn.insn; +} + +/* + * Interrupts are disabled on entry as trap3 is an interrupt gate and they + * remain disabled thorough out this function. + */ +int kprobe_handler(struct pt_regs *regs) +{ + struct kprobe *p; + int ret = 0; + kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->rip - sizeof(kprobe_opcode_t)); + + /* We're in an interrupt, but this is clear and BUG()-safe. */ + preempt_disable(); + + /* Check we're not actually recursing */ + if (kprobe_running()) { + /* We *are* holding lock here, so this is safe. + Disarm the probe we just hit, and ignore it. */ + p = get_kprobe(addr); + if (p) { + disarm_kprobe(p, regs); + ret = 1; + } else { + p = current_kprobe; + if (p->break_handler && p->break_handler(p, regs)) { + goto ss_probe; + } + } + /* If it's not ours, can't be delete race, (we hold lock). */ + goto no_kprobe; + } + + lock_kprobes(); + p = get_kprobe(addr); + if (!p) { + unlock_kprobes(); + if (*addr != BREAKPOINT_INSTRUCTION) { + /* + * The breakpoint instruction was removed right + * after we hit it. Another cpu has removed + * either a probepoint or a debugger breakpoint + * at this address. In either case, no further + * handling of this interrupt is appropriate. + */ + ret = 1; + } + /* Not one of ours: let kernel handle it */ + goto no_kprobe; + } + + kprobe_status = KPROBE_HIT_ACTIVE; + current_kprobe = p; + kprobe_saved_rflags = kprobe_old_rflags + = (regs->eflags & (TF_MASK | IF_MASK)); + if (is_IF_modifier(p->ainsn.insn)) + kprobe_saved_rflags &= ~IF_MASK; + + if (p->pre_handler(p, regs)) { + /* handler has already set things up, so skip ss setup */ + return 1; + } + + ss_probe: + prepare_singlestep(p, regs); + kprobe_status = KPROBE_HIT_SS; + return 1; + + no_kprobe: + preempt_enable_no_resched(); + return ret; +} + +/* + * Called after single-stepping. p->addr is the address of the + * instruction whose first byte has been replaced by the "int 3" + * instruction. To avoid the SMP problems that can occur when we + * temporarily put back the original opcode to single-step, we + * single-stepped a copy of the instruction. The address of this + * copy is p->ainsn.insn. + * + * This function prepares to return from the post-single-step + * interrupt. We have to fix up the stack as follows: + * + * 0) Except in the case of absolute or indirect jump or call instructions, + * the new rip is relative to the copied instruction. We need to make + * it relative to the original instruction. + * + * 1) If the single-stepped instruction was pushfl, then the TF and IF + * flags are set in the just-pushed eflags, and may need to be cleared. + * + * 2) If the single-stepped instruction was a call, the return address + * that is atop the stack is the address following the copied instruction. + * We need to make it the address following the original instruction. + */ +static void resume_execution(struct kprobe *p, struct pt_regs *regs) +{ + unsigned long *tos = (unsigned long *)regs->rsp; + unsigned long next_rip = 0; + unsigned long copy_rip = (unsigned long)p->ainsn.insn; + unsigned long orig_rip = (unsigned long)p->addr; + kprobe_opcode_t *insn = p->ainsn.insn; + + /*skip the REX prefix*/ + if (*insn >= 0x40 && *insn <= 0x4f) + insn++; + + switch (*insn) { + case 0x9c: /* pushfl */ + *tos &= ~(TF_MASK | IF_MASK); + *tos |= kprobe_old_rflags; + break; + case 0xe8: /* call relative - Fix return addr */ + *tos = orig_rip + (*tos - copy_rip); + break; + case 0xff: + if ((*insn & 0x30) == 0x10) { + /* call absolute, indirect */ + /* Fix return addr; rip is correct. */ + next_rip = regs->rip; + *tos = orig_rip + (*tos - copy_rip); + } else if (((*insn & 0x31) == 0x20) || /* jmp near, absolute indirect */ + ((*insn & 0x31) == 0x21)) { /* jmp far, absolute indirect */ + /* rip is correct. */ + next_rip = regs->rip; + } + break; + case 0xea: /* jmp absolute -- rip is correct */ + next_rip = regs->rip; + break; + default: + break; + } + + regs->eflags &= ~TF_MASK; + if (next_rip) { + regs->rip = next_rip; + } else { + regs->rip = orig_rip + (regs->rip - copy_rip); + } +} + +/* + * Interrupts are disabled on entry as trap1 is an interrupt gate and they + * remain disabled thoroughout this function. And we hold kprobe lock. + */ +int post_kprobe_handler(struct pt_regs *regs) +{ + if (!kprobe_running()) + return 0; + + if (current_kprobe->post_handler) + current_kprobe->post_handler(current_kprobe, regs, 0); + + resume_execution(current_kprobe, regs); + regs->eflags |= kprobe_saved_rflags; + + unlock_kprobes(); + preempt_enable_no_resched(); + + /* + * if somebody else is singlestepping across a probe point, eflags + * will have TF set, in which case, continue the remaining processing + * of do_debug, as if this is not a probe hit. + */ + if (regs->eflags & TF_MASK) + return 0; + + return 1; +} + +/* Interrupts disabled, kprobe_lock held. */ +int kprobe_fault_handler(struct pt_regs *regs, int trapnr) +{ + if (current_kprobe->fault_handler + && current_kprobe->fault_handler(current_kprobe, regs, trapnr)) + return 1; + + if (kprobe_status & KPROBE_HIT_SS) { + resume_execution(current_kprobe, regs); + regs->eflags |= kprobe_old_rflags; + + unlock_kprobes(); + preempt_enable_no_resched(); + } + return 0; +} + +/* + * Wrapper routine for handling exceptions. + */ +int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, + void *data) +{ + struct die_args *args = (struct die_args *)data; + switch (val) { + case DIE_INT3: + if (kprobe_handler(args->regs)) + return NOTIFY_STOP; + break; + case DIE_DEBUG: + if (post_kprobe_handler(args->regs)) + return NOTIFY_STOP; + break; + case DIE_GPF: + if (kprobe_running() && + kprobe_fault_handler(args->regs, args->trapnr)) + return NOTIFY_STOP; + break; + case DIE_PAGE_FAULT: + if (kprobe_running() && + kprobe_fault_handler(args->regs, args->trapnr)) + return NOTIFY_STOP; + break; + default: + break; + } + return NOTIFY_DONE; +} + +int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) +{ + struct jprobe *jp = container_of(p, struct jprobe, kp); + unsigned long addr; + + jprobe_saved_regs = *regs; + jprobe_saved_rsp = (long *) regs->rsp; + addr = (unsigned long)jprobe_saved_rsp; + /* + * As Linus pointed out, gcc assumes that the callee + * owns the argument space and could overwrite it, e.g. + * tailcall optimization. So, to be absolutely safe + * we also save and restore enough stack bytes to cover + * the argument area. + */ + memcpy(jprobes_stack, (kprobe_opcode_t *) addr, MIN_STACK_SIZE(addr)); + regs->eflags &= ~IF_MASK; + regs->rip = (unsigned long)(jp->entry); + return 1; +} + +void jprobe_return(void) +{ + preempt_enable_no_resched(); + asm volatile (" xchg %%rbx,%%rsp \n" + " int3 \n" + " .globl jprobe_return_end \n" + " jprobe_return_end: \n" + " nop \n"::"b" + (jprobe_saved_rsp):"memory"); +} + +int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) +{ + u8 *addr = (u8 *) (regs->rip - 1); + unsigned long stack_addr = (unsigned long)jprobe_saved_rsp; + struct jprobe *jp = container_of(p, struct jprobe, kp); + + if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { + if ((long *)regs->rsp != jprobe_saved_rsp) { + struct pt_regs *saved_regs = + container_of(jprobe_saved_rsp, struct pt_regs, rsp); + printk("current rsp %p does not match saved rsp %p\n", + (long *)regs->rsp, jprobe_saved_rsp); + printk("Saved registers for jprobe %p\n", jp); + show_registers(saved_regs); + printk("Current registers\n"); + show_registers(regs); + BUG(); + } + *regs = jprobe_saved_regs; + memcpy((kprobe_opcode_t *) stack_addr, jprobes_stack, + MIN_STACK_SIZE(stack_addr)); + return 1; + } + return 0; +} + +/* + * kprobe->ainsn.insn points to the copy of the instruction to be single-stepped. + * By default on x86_64, pages we get from kmalloc or vmalloc are not + * executable. Single-stepping an instruction on such a page yields an + * oops. So instead of storing the instruction copies in their respective + * kprobe objects, we allocate a page, map it executable, and store all the + * instruction copies there. (We can allocate additional pages if somebody + * inserts a huge number of probes.) Each page can hold up to INSNS_PER_PAGE + * instruction slots, each of which is MAX_INSN_SIZE*sizeof(kprobe_opcode_t) + * bytes. + */ +#define INSNS_PER_PAGE (PAGE_SIZE/(MAX_INSN_SIZE*sizeof(kprobe_opcode_t))) +struct kprobe_insn_page { + struct hlist_node hlist; + kprobe_opcode_t *insns; /* page of instruction slots */ + char slot_used[INSNS_PER_PAGE]; + int nused; +}; + +static struct hlist_head kprobe_insn_pages; + +/** + * get_insn_slot() - Find a slot on an executable page for an instruction. + * We allocate an executable page if there's no room on existing ones. + */ +static kprobe_opcode_t *get_insn_slot(void) +{ + struct kprobe_insn_page *kip; + struct hlist_node *pos; + + hlist_for_each(pos, &kprobe_insn_pages) { + kip = hlist_entry(pos, struct kprobe_insn_page, hlist); + if (kip->nused < INSNS_PER_PAGE) { + int i; + for (i = 0; i < INSNS_PER_PAGE; i++) { + if (!kip->slot_used[i]) { + kip->slot_used[i] = 1; + kip->nused++; + return kip->insns + (i*MAX_INSN_SIZE); + } + } + /* Surprise! No unused slots. Fix kip->nused. */ + kip->nused = INSNS_PER_PAGE; + } + } + + /* All out of space. Need to allocate a new page. Use slot 0.*/ + kip = kmalloc(sizeof(struct kprobe_insn_page), GFP_ATOMIC); + if (!kip) { + return NULL; + } + kip->insns = (kprobe_opcode_t*) __vmalloc(PAGE_SIZE, + GFP_ATOMIC|__GFP_HIGHMEM, __pgprot(__PAGE_KERNEL_EXEC)); + if (!kip->insns) { + kfree(kip); + return NULL; + } + INIT_HLIST_NODE(&kip->hlist); + hlist_add_head(&kip->hlist, &kprobe_insn_pages); + memset(kip->slot_used, 0, INSNS_PER_PAGE); + kip->slot_used[0] = 1; + kip->nused = 1; + return kip->insns; +} + +/** + * free_insn_slot() - Free instruction slot obtained from get_insn_slot(). + */ +static void free_insn_slot(kprobe_opcode_t *slot) +{ + struct kprobe_insn_page *kip; + struct hlist_node *pos; + + hlist_for_each(pos, &kprobe_insn_pages) { + kip = hlist_entry(pos, struct kprobe_insn_page, hlist); + if (kip->insns <= slot + && slot < kip->insns+(INSNS_PER_PAGE*MAX_INSN_SIZE)) { + int i = (slot - kip->insns) / MAX_INSN_SIZE; + kip->slot_used[i] = 0; + kip->nused--; + if (kip->nused == 0) { + /* + * Page is no longer in use. Free it unless + * it's the last one. We keep the last one + * so as not to have to set it up again the + * next time somebody inserts a probe. + */ + hlist_del(&kip->hlist); + if (hlist_empty(&kprobe_insn_pages)) { + INIT_HLIST_NODE(&kip->hlist); + hlist_add_head(&kip->hlist, + &kprobe_insn_pages); + } else { + vfree(kip->insns); + kfree(kip); + } + } + return; + } + } +} diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c index ebd621e96787..17a4bd966213 100644 --- a/arch/x86_64/kernel/ptrace.c +++ b/arch/x86_64/kernel/ptrace.c @@ -323,6 +323,8 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data ret = 0; break; case offsetof(struct user, u_debugreg[7]): + /* See arch/i386/kernel/ptrace.c for an explanation of + * this awkward check.*/ data &= ~DR_CONTROL_RESERVED; for(i=0; i<4; i++) if ((0x5454 >> ((data >> (16 + 4*i)) & 0xf)) & 1) diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index fb6ae8436b23..50e9621b0273 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -47,6 +47,7 @@ #include <linux/irq.h> + extern struct gate_struct idt_table[256]; asmlinkage void divide_error(void); @@ -73,6 +74,17 @@ asmlinkage void spurious_interrupt_bug(void); asmlinkage void call_debug(void); struct notifier_block *die_chain; +static spinlock_t die_notifier_lock = SPIN_LOCK_UNLOCKED; + +int register_die_notifier(struct notifier_block *nb) +{ + int err = 0; + unsigned long flags; + spin_lock_irqsave(&die_notifier_lock, flags); + err = notifier_chain_register(&die_chain, nb); + spin_unlock_irqrestore(&die_notifier_lock, flags); + return err; +} static inline void conditional_sti(struct pt_regs *regs) { @@ -475,7 +487,6 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \ } DO_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->rip) -DO_ERROR( 3, SIGTRAP, "int3", int3); DO_ERROR( 4, SIGSEGV, "overflow", overflow) DO_ERROR( 5, SIGSEGV, "bounds", bounds) DO_ERROR_INFO( 6, SIGILL, "invalid operand", invalid_op, ILL_ILLOPN, regs->rip) @@ -580,9 +591,13 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) printk("Do you have a strange power saving mode enabled?\n"); } -asmlinkage void default_do_nmi(struct pt_regs * regs) +asmlinkage void default_do_nmi(struct pt_regs *regs) { - unsigned char reason = get_nmi_reason(); + unsigned char reason = 0; + + /* Only the BSP gets external NMIs from the system. */ + if (!smp_processor_id()) + reason = get_nmi_reason(); if (!(reason & 0xc0)) { if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) @@ -621,6 +636,15 @@ asmlinkage void default_do_nmi(struct pt_regs * regs) inb(0x71); /* dummy */ } +asmlinkage void do_int3(struct pt_regs * regs, long error_code) +{ + if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) { + return; + } + do_trap(3, SIGTRAP, "int3", regs, error_code, NULL); + return; +} + /* runs on IST stack. */ asmlinkage void *do_debug(struct pt_regs * regs, unsigned long error_code) { @@ -650,6 +674,10 @@ asmlinkage void *do_debug(struct pt_regs * regs, unsigned long error_code) asm("movq %%db6,%0" : "=r" (condition)); + if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, + SIGTRAP) == NOTIFY_STOP) { + return regs; + } conditional_sti(regs); /* Mask out spurious debug traps due to lazy DR7 setting */ @@ -882,8 +910,8 @@ void __init trap_init(void) set_intr_gate(0,÷_error); set_intr_gate_ist(1,&debug,DEBUG_STACK); set_intr_gate_ist(2,&nmi,NMI_STACK); - set_system_gate(3,&int3); /* int3-5 can be called from all */ - set_system_gate(4,&overflow); + set_intr_gate(3,&int3); + set_system_gate(4,&overflow); /* int4-5 can be called from all */ set_system_gate(5,&bounds); set_intr_gate(6,&invalid_op); set_intr_gate(7,&device_not_available); diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c index 6c359943593e..032c0e23896e 100644 --- a/arch/x86_64/kernel/x8664_ksyms.c +++ b/arch/x86_64/kernel/x8664_ksyms.c @@ -32,6 +32,7 @@ #include <asm/unistd.h> #include <asm/delay.h> #include <asm/tlbflush.h> +#include <asm/kdebug.h> extern spinlock_t rtc_lock; @@ -197,6 +198,7 @@ EXPORT_SYMBOL(_atomic_dec_and_lock); #endif EXPORT_SYMBOL(die_chain); +EXPORT_SYMBOL(register_die_notifier); #ifdef CONFIG_SMP EXPORT_SYMBOL(cpu_sibling_map); diff --git a/arch/x86_64/mm/Makefile b/arch/x86_64/mm/Makefile index b8cf5d94c14b..14bbe9e77878 100644 --- a/arch/x86_64/mm/Makefile +++ b/arch/x86_64/mm/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux x86_64-specific parts of the memory manager. # -obj-y := init.o fault.o ioremap.o extable.o pageattr.o mmap.o +obj-y := init.o fault.o ioremap.o extable.o pageattr.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_DISCONTIGMEM) += numa.o obj-$(CONFIG_K8_NUMA) += k8topology.o diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 4e12a56c9321..98d54f2ec76b 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c @@ -23,6 +23,7 @@ #include <linux/vt_kern.h> /* For unblank_screen() */ #include <linux/compiler.h> #include <linux/module.h> +#include <linux/kprobes.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -32,6 +33,7 @@ #include <asm/proto.h> #include <asm/kdebug.h> #include <asm-generic/sections.h> +#include <asm/kdebug.h> void bust_spinlocks(int yes) { @@ -268,6 +270,9 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) /* get the address */ __asm__("movq %%cr2,%0":"=r" (address)); + if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, + SIGSEGV) == NOTIFY_STOP) + return; if (likely(regs->eflags & X86_EFLAGS_IF)) local_irq_enable(); diff --git a/arch/x86_64/mm/mmap.c b/arch/x86_64/mm/mmap.c deleted file mode 100644 index 20e09d5a2391..000000000000 --- a/arch/x86_64/mm/mmap.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * linux/arch/x86-64/mm/mmap.c - * - * flexible mmap layout support - * - * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina. - * All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This 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 - * - * - * Started by Ingo Molnar <mingo@elte.hu> - */ - -#include <linux/personality.h> -#include <linux/mm.h> - -/* - * Top of mmap area (just below the process stack). - * - * Leave an at least ~128 MB hole, 4GB for 64bit. - */ -#define MIN_GAP (test_thread_flag(TIF_IA32) ? 4UL*1024*1024*1024 : 128*1024*1024) -#define MAX_GAP (TASK_SIZE/6*5) - -static inline unsigned long mmap_base(void) -{ - unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur; - - if (gap < MIN_GAP) - gap = MIN_GAP; - else if (gap > MAX_GAP) - gap = MAX_GAP; - - return TASK_SIZE - (gap & PAGE_MASK); -} - -static inline int mmap_is_legacy(void) -{ - if (current->personality & ADDR_COMPAT_LAYOUT) - return 1; - - if (current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) - return 1; - - return sysctl_legacy_va_layout; -} - -/* - * This function, called very early during the creation of a new - * process VM image, sets up which VM layout function to use: - */ -void arch_pick_mmap_layout(struct mm_struct *mm) -{ - /* - * Fall back to the standard layout if the personality - * bit is set, or if the expected stack growth is unlimited: - */ - if (mmap_is_legacy()) { - mm->mmap_base = TASK_UNMAPPED_BASE; - mm->get_unmapped_area = arch_get_unmapped_area; - mm->unmap_area = arch_unmap_area; - } else { - mm->mmap_base = mmap_base(); - mm->get_unmapped_area = arch_get_unmapped_area_topdown; - mm->unmap_area = arch_unmap_area_topdown; - } -} diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index d07a346048f2..9804402805f3 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -94,19 +94,17 @@ firmware_class_hotplug(struct class_device *class_dev, char **envp, int num_envp, char *buffer, int buffer_size) { struct firmware_priv *fw_priv = class_get_devdata(class_dev); - int i = 0; - char *scratch = buffer; + int i = 0, len = 0; if (!test_bit(FW_STATUS_READY, &fw_priv->status)) return -ENODEV; - if (buffer_size < (FIRMWARE_NAME_MAX + 10)) - return -ENOMEM; - if (num_envp < 1) + if (add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &len, + "FIRMWARE=%s", fw_priv->fw_id)) return -ENOMEM; - envp[i++] = scratch; - scratch += sprintf(scratch, "FIRMWARE=%s", fw_priv->fw_id) + 1; + envp[i++] = NULL; + return 0; } diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c index 09873fa1b3c0..162486f9de1c 100644 --- a/drivers/cdrom/cdu31a.c +++ b/drivers/cdrom/cdu31a.c @@ -65,14 +65,6 @@ * This section describes features beyond the normal audio and CD-ROM * functions of the drive. * - * 2048 byte buffer mode - * - * If a disk is mounted with -o block=2048, data is copied straight - * from the drive data port to the buffer. Otherwise, the readahead - * buffer must be involved to hold the other 1K of data when a 1K - * block operation is done. Note that with 2048 byte blocks you - * cannot execute files from the CD. - * * XA compatibility * * The driver should support XA disks for both the CDU31A and CDU33A. @@ -147,6 +139,13 @@ * Removed init_module & cleanup_module in favor of * module_init & module_exit. * Torben Mathiasen <tmm@image.dk> + * + * 22 October 2004 -- Make the driver work in 2.6.X + * Added workaround to fix hard lockups on eject + * Fixed door locking problem after mounting empty drive + * Set double-speed drives to double speed by default + * Removed all readahead things - not needed anymore + * Ondrej Zary <rainbow@rainbow-software.org> */ #include <linux/major.h> @@ -179,10 +178,9 @@ #define MAJOR_NR CDU31A_CDROM_MAJOR #include <linux/blkdev.h> -#define CDU31A_READAHEAD 4 /* 128 sector, 64kB, 32 reads read-ahead */ #define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10 -#define DEBUG 0 +#define DEBUG 1 /* Define the following if you have data corruption problems. */ #undef SONY_POLL_EACH_BYTE @@ -279,7 +277,6 @@ static struct task_struct *has_cd_task = NULL; /* The task that is currently NULL if none. */ static int is_double_speed = 0; /* does the drive support double speed ? */ -static int is_a_cdu31a = 1; /* Is the drive a CDU31A? */ static int is_auto_eject = 1; /* Door has been locked? 1=No/0=Yes */ @@ -314,12 +311,8 @@ static int curr_control_reg = 0; /* Current value of the control register */ it will be cleared. */ static char disk_changed; -/* Variable for using the readahead buffer. The readahead buffer - is used for raw sector reads and for blocksizes that are smaller - than 2048 bytes. */ -static char readahead_buffer[CD_FRAMESIZE_RAW]; -static int readahead_dataleft = 0; -static int readahead_bad = 0; +/* This was readahead_buffer once... Now it's used only for audio reads */ +static char audio_buffer[CD_FRAMESIZE_RAW]; /* Used to time a short period to abort an operation after the drive has been idle for a while. This keeps the light on @@ -440,7 +433,6 @@ static inline int is_result_reg_not_empty(void) static inline void reset_drive(void) { curr_control_reg = 0; - readahead_dataleft = 0; sony_toc_read = 0; outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg); } @@ -556,82 +548,47 @@ static unsigned char *translate_error(unsigned char err_code) static unsigned char errbuf[80]; switch (err_code) { - case 0x10: - return "illegal command "; - case 0x11: - return "illegal parameter "; - - case 0x20: - return "not loaded "; - case 0x21: - return "no disc "; - case 0x22: - return "not spinning "; - case 0x23: - return "spinning "; - case 0x25: - return "spindle servo "; - case 0x26: - return "focus servo "; - case 0x29: - return "eject mechanism "; - case 0x2a: - return "audio playing "; - case 0x2c: - return "emergency eject "; - - case 0x30: - return "focus "; - case 0x31: - return "frame sync "; - case 0x32: - return "subcode address "; - case 0x33: - return "block sync "; - case 0x34: - return "header address "; - - case 0x40: - return "illegal track read "; - case 0x41: - return "mode 0 read "; - case 0x42: - return "illegal mode read "; - case 0x43: - return "illegal block size read "; - case 0x44: - return "mode read "; - case 0x45: - return "form read "; - case 0x46: - return "leadout read "; - case 0x47: - return "buffer overrun "; - - case 0x53: - return "unrecoverable CIRC "; - case 0x57: - return "unrecoverable LECC "; - - case 0x60: - return "no TOC "; - case 0x61: - return "invalid subcode data "; - case 0x63: - return "focus on TOC read "; - case 0x64: - return "frame sync on TOC read "; - case 0x65: - return "TOC data "; - - case 0x70: - return "hardware failure "; - case 0x91: - return "leadin "; - case 0x92: - return "leadout "; - case 0x93: - return "data track "; + case 0x10: return "illegal command "; + case 0x11: return "illegal parameter "; + + case 0x20: return "not loaded "; + case 0x21: return "no disc "; + case 0x22: return "not spinning "; + case 0x23: return "spinning "; + case 0x25: return "spindle servo "; + case 0x26: return "focus servo "; + case 0x29: return "eject mechanism "; + case 0x2a: return "audio playing "; + case 0x2c: return "emergency eject "; + + case 0x30: return "focus "; + case 0x31: return "frame sync "; + case 0x32: return "subcode address "; + case 0x33: return "block sync "; + case 0x34: return "header address "; + + case 0x40: return "illegal track read "; + case 0x41: return "mode 0 read "; + case 0x42: return "illegal mode read "; + case 0x43: return "illegal block size read "; + case 0x44: return "mode read "; + case 0x45: return "form read "; + case 0x46: return "leadout read "; + case 0x47: return "buffer overrun "; + + case 0x53: return "unrecoverable CIRC "; + case 0x57: return "unrecoverable LECC "; + + case 0x60: return "no TOC "; + case 0x61: return "invalid subcode data "; + case 0x63: return "focus on TOC read "; + case 0x64: return "frame sync on TOC read "; + case 0x65: return "TOC data "; + + case 0x70: return "hardware failure "; + case 0x91: return "leadin "; + case 0x92: return "leadout "; + case 0x93: return "data track "; } sprintf(errbuf, "unknown 0x%02x ", err_code); return errbuf; @@ -696,8 +653,7 @@ static int scd_select_speed(struct cdrom_device_info *cdi, int speed) */ static int scd_lock_door(struct cdrom_device_info *cdi, int lock) { - if (lock == 0 && sony_usage == 1) { - /* Unlock the door, only if nobody is using the drive */ + if (lock == 0) { is_auto_eject = 1; } else { is_auto_eject = 0; @@ -1143,10 +1099,9 @@ static void size_to_buf(unsigned int size, unsigned char *buf) operation if the requested sector is not the next one from the drive. */ static int -start_request(unsigned int sector, unsigned int nsect, int read_nsect_only) +start_request(unsigned int sector, unsigned int nsect) { unsigned char params[6]; - unsigned int read_size; unsigned long retry_count; @@ -1154,22 +1109,7 @@ start_request(unsigned int sector, unsigned int nsect, int read_nsect_only) printk("Entering start_request\n"); #endif log_to_msf(sector, params); - /* If requested, read exactly what was asked. */ - if (read_nsect_only) { - read_size = nsect; - } - /* - * If the full read-ahead would go beyond the end of the media, trim - * it back to read just till the end of the media. - */ - else if ((sector + nsect) >= sony_toc.lead_out_start_lba) { - read_size = sony_toc.lead_out_start_lba - sector; - } - /* Read the full readahead amount. */ - else { - read_size = CDU31A_READAHEAD / 4; - } - size_to_buf(read_size, ¶ms[3]); + size_to_buf(nsect, ¶ms[3]); /* * Clear any outstanding attentions and wait for the drive to @@ -1198,10 +1138,8 @@ start_request(unsigned int sector, unsigned int nsect, int read_nsect_only) write_params(params, 6); write_cmd(SONY_READ_BLKERR_STAT_CMD); - sony_blocks_left = read_size * 4; + sony_blocks_left = nsect * 4; sony_next_block = sector * 4; - readahead_dataleft = 0; - readahead_bad = 0; #if DEBUG printk("Leaving start_request at %d\n", __LINE__); #endif @@ -1212,8 +1150,7 @@ start_request(unsigned int sector, unsigned int nsect, int read_nsect_only) #endif } -/* Abort a pending read operation. Clear all the drive status and - readahead variables. */ +/* Abort a pending read operation. Clear all the drive status variables. */ static void abort_read(void) { unsigned char result_reg[2]; @@ -1238,8 +1175,6 @@ static void abort_read(void) } sony_blocks_left = 0; - readahead_dataleft = 0; - readahead_bad = 0; } /* Called when the timer times out. This will abort the @@ -1264,8 +1199,6 @@ static void handle_abort_timeout(unsigned long data) write_cmd(SONY_ABORT_CMD); sony_blocks_left = 0; - readahead_dataleft = 0; - readahead_bad = 0; abort_read_started = 1; } restore_flags(flags); @@ -1274,60 +1207,30 @@ static void handle_abort_timeout(unsigned long data) #endif } -/* Actually get data and status from the drive. */ +/* Actually get one sector of data from the drive. */ static void -input_data(char *buffer, - unsigned int bytesleft, - unsigned int nblocks, unsigned int offset, unsigned int skip) +input_data_sector(char *buffer) { - int i; - volatile unsigned char val; - - #if DEBUG - printk("Entering input_data\n"); + printk("Entering input_data_sector\n"); #endif + /* If an XA disk on a CDU31A, skip the first 12 bytes of data from - the disk. The real data is after that. */ - if (sony_xa_mode) { - for (i = 0; i < CD_XA_HEAD; i++) { - val = read_data_register(); - } - } + the disk. The real data is after that. We can use audio_buffer. */ + if (sony_xa_mode) + insb(sony_cd_read_reg, audio_buffer, CD_XA_HEAD); clear_data_ready(); - if (bytesleft == 2048) { /* 2048 byte direct buffer transfer */ - insb(sony_cd_read_reg, buffer, 2048); - readahead_dataleft = 0; - } else { - /* If the input read did not align with the beginning of the block, - skip the necessary bytes. */ - if (skip != 0) { - insb(sony_cd_read_reg, readahead_buffer, skip); - } - - /* Get the data into the buffer. */ - insb(sony_cd_read_reg, &buffer[offset], bytesleft); - - /* Get the rest of the data into the readahead buffer at the - proper location. */ - readahead_dataleft = (2048 - skip) - bytesleft; - insb(sony_cd_read_reg, - readahead_buffer + bytesleft, readahead_dataleft); - } - sony_blocks_left -= nblocks; - sony_next_block += nblocks; + insb(sony_cd_read_reg, buffer, 2048); /* If an XA disk, we have to clear out the rest of the unused - error correction data. */ - if (sony_xa_mode) { - for (i = 0; i < CD_XA_TAIL; i++) { - val = read_data_register(); - } - } + error correction data. We can use audio_buffer for that. */ + if (sony_xa_mode) + insb(sony_cd_read_reg, audio_buffer, CD_XA_TAIL); + #if DEBUG - printk("Leaving input_data at %d\n", __LINE__); + printk("Leaving input_data_sector\n"); #endif } @@ -1339,10 +1242,6 @@ read_data_block(char *buffer, unsigned char res_reg[], int *res_size) { unsigned long retry_count; - unsigned int bytesleft; - unsigned int offset; - unsigned int skip; - #if DEBUG printk("Entering read_data_block\n"); @@ -1351,67 +1250,6 @@ read_data_block(char *buffer, res_reg[0] = 0; res_reg[1] = 0; *res_size = 0; - bytesleft = nblocks * 512; - offset = 0; - - /* If the data in the read-ahead does not match the block offset, - then fix things up. */ - if (((block % 4) * 512) != ((2048 - readahead_dataleft) % 2048)) { - sony_next_block += block % 4; - sony_blocks_left -= block % 4; - skip = (block % 4) * 512; - } else { - skip = 0; - } - - /* We have readahead data in the buffer, get that first before we - decide if a read is necessary. */ - if (readahead_dataleft != 0) { - if (bytesleft > readahead_dataleft) { - /* The readahead will not fill the requested buffer, but - get the data out of the readahead into the buffer. */ - memcpy(buffer, - readahead_buffer + (2048 - - readahead_dataleft), - readahead_dataleft); - bytesleft -= readahead_dataleft; - offset += readahead_dataleft; - readahead_dataleft = 0; - } else { - /* The readahead will fill the whole buffer, get the data - and return. */ - memcpy(buffer, - readahead_buffer + (2048 - - readahead_dataleft), - bytesleft); - readahead_dataleft -= bytesleft; - bytesleft = 0; - sony_blocks_left -= nblocks; - sony_next_block += nblocks; - - /* If the data in the readahead is bad, return an error so the - driver will abort the buffer. */ - if (readahead_bad) { - res_reg[0] = 0x20; - res_reg[1] = SONY_BAD_DATA_ERR; - *res_size = 2; - } - - if (readahead_dataleft == 0) { - readahead_bad = 0; - } - - /* Final transfer is done for read command, get final result. */ - if (sony_blocks_left == 0) { - get_result(res_reg, res_size); - } -#if DEBUG - printk("Leaving read_data_block at %d\n", - __LINE__); -#endif - return; - } - } /* Wait for the drive to tell us we have something */ retry_count = jiffies + SONY_JIFFIES_TIMEOUT; @@ -1442,7 +1280,9 @@ read_data_block(char *buffer, abort_read(); } } else { - input_data(buffer, bytesleft, nblocks, offset, skip); + input_data_sector(buffer); + sony_blocks_left -= nblocks; + sony_next_block += nblocks; /* Wait for the status from the drive. */ retry_count = jiffies + SONY_JIFFIES_TIMEOUT; @@ -1473,16 +1313,7 @@ read_data_block(char *buffer, SONY_NO_LECC_ERR_BLK_STAT) || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)) { - /* The data was successful, but if data was read from - the readahead and it was bad, set the whole - buffer as bad. */ - if (readahead_bad) { - readahead_bad = 0; - res_reg[0] = 0x20; - res_reg[1] = - SONY_BAD_DATA_ERR; - *res_size = 2; - } + /* nothing here */ } else { printk ("CDU31A: Data block error: 0x%x\n", @@ -1490,12 +1321,6 @@ read_data_block(char *buffer, res_reg[0] = 0x20; res_reg[1] = SONY_BAD_DATA_ERR; *res_size = 2; - - /* Data is in the readahead buffer but an error was returned. - Make sure future requests don't use the data. */ - if (bytesleft != 2048) { - readahead_bad = 1; - } } /* Final transfer is done for read command, get final result. */ @@ -1531,11 +1356,9 @@ read_data_block(char *buffer, static void do_cdu31a_request(request_queue_t * q) { struct request *req; - int block; - int nblock; + int block, nblock, num_retries; unsigned char res_reg[12]; unsigned int res_size; - int num_retries; unsigned long flags; @@ -1591,7 +1414,10 @@ static void do_cdu31a_request(request_queue_t * q) block = req->sector; nblock = req->nr_sectors; - +#if DEBUG + printk("CDU31A: request at block %d, length %d blocks\n", + block, nblock); +#endif if (!sony_toc_read) { printk("CDU31A: TOC not read\n"); end_request(req, 0); @@ -1611,17 +1437,14 @@ static void do_cdu31a_request(request_queue_t * q) * If the block address is invalid or the request goes beyond the end of * the media, return an error. */ - if ((block / 4) >= sony_toc.lead_out_start_lba) { - printk("CDU31A: Request past end of media\n"); - end_request(req, 0); - continue; - } if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba) { printk("CDU31A: Request past end of media\n"); end_request(req, 0); continue; } + if (nblock > 4) + nblock = 4; num_retries = 0; try_read_again: @@ -1636,7 +1459,7 @@ static void do_cdu31a_request(request_queue_t * q) /* If no data is left to be read from the drive, start the next request. */ if (sony_blocks_left == 0) { - if (start_request(block / 4, CDU31A_READAHEAD / 4, 0)) { + if (start_request(block / 4, nblock / 4)) { end_request(req, 0); continue; } @@ -1655,7 +1478,7 @@ static void do_cdu31a_request(request_queue_t * q) end_request(req, 0); continue; } - if (start_request(block / 4, CDU31A_READAHEAD / 4, 0)) { + if (start_request(block / 4, nblock / 4)) { printk("CDU31a: start request failed\n"); end_request(req, 0); continue; @@ -1665,7 +1488,12 @@ static void do_cdu31a_request(request_queue_t * q) read_data_block(req->buffer, block, nblock, res_reg, &res_size); if (res_reg[0] != 0x20) { - end_request(req, 1); + if (!end_that_request_first(req, 1, nblock)) { + spin_lock_irq(q->queue_lock); + blkdev_dequeue_request(req); + end_that_request_last(req); + spin_unlock_irq(q->queue_lock); + } continue; } @@ -1774,7 +1602,7 @@ static void sony_get_toc(void) /* This seems to slow things down enough to make it work. This * appears to be a problem in do_sony_cd_cmd. This printk seems * to address the symptoms... -Erik */ -#if 1 +#if DEBUG printk("cdu31a: Trying session %d\n", session); #endif parms[0] = session; @@ -2529,8 +2357,7 @@ static int read_audio(struct cdrom_read_audio *ra) return. */ retval = 0; - /* start_request clears out any readahead data, so it should be safe. */ - if (start_request(ra->addr.lba, ra->nframes, 1)) { + if (start_request(ra->addr.lba, ra->nframes)) { retval = -EIO; goto exit_read_audio; } @@ -2538,7 +2365,7 @@ static int read_audio(struct cdrom_read_audio *ra) /* For every requested frame. */ cframe = 0; while (cframe < ra->nframes) { - read_audio_data(readahead_buffer, res_reg, &res_size); + read_audio_data(audio_buffer, res_reg, &res_size); if ((res_reg[0] & 0xf0) == 0x20) { if (res_reg[1] == SONY_BAD_DATA_ERR) { printk @@ -2567,7 +2394,7 @@ static int read_audio(struct cdrom_read_audio *ra) /* Restart the request on the current frame. */ if (start_request (ra->addr.lba + cframe, - ra->nframes - cframe, 1)) { + ra->nframes - cframe)) { retval = -EIO; goto exit_read_audio; } @@ -2575,7 +2402,7 @@ static int read_audio(struct cdrom_read_audio *ra) /* Don't go back to the top because don't want to get into and infinite loop. A lot of code gets duplicated, but that's no big deal, I don't guess. */ - read_audio_data(readahead_buffer, res_reg, + read_audio_data(audio_buffer, res_reg, &res_size); if ((res_reg[0] & 0xf0) == 0x20) { if (res_reg[1] == @@ -2596,7 +2423,7 @@ static int read_audio(struct cdrom_read_audio *ra) } else if (copy_to_user(ra->buf + (CD_FRAMESIZE_RAW * cframe), - readahead_buffer, + audio_buffer, CD_FRAMESIZE_RAW)) { retval = -EFAULT; goto exit_read_audio; @@ -2610,7 +2437,7 @@ static int read_audio(struct cdrom_read_audio *ra) goto exit_read_audio; } } else if (copy_to_user(ra->buf + (CD_FRAMESIZE_RAW * cframe), - (char *)readahead_buffer, + (char *)audio_buffer, CD_FRAMESIZE_RAW)) { retval = -EFAULT; goto exit_read_audio; @@ -3061,12 +2888,18 @@ static int scd_spinup(void) * Open the drive for operations. Spin the drive up and read the table of * contents if these have not already been done. */ -static int scd_open(struct cdrom_device_info *cdi, int openmode) +static int scd_open(struct cdrom_device_info *cdi, int purpose) { unsigned char res_reg[12]; unsigned int res_size; unsigned char params[2]; + if (purpose == 1) { + /* Open for IOCTLs only - no media check */ + sony_usage++; + return 0; + } + if (sony_usage == 0) { if (scd_spinup() != 0) return -EIO; @@ -3151,8 +2984,7 @@ static struct cdrom_device_ops scd_dops = { .dev_ioctl = scd_dev_ioctl, .capability = CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_MULTI_SESSION | - CDC_MULTI_SESSION | CDC_MCN | - CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | + CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS, .n_minors = 1, }; @@ -3177,7 +3009,19 @@ static int scd_block_release(struct inode *inode, struct file *file) static int scd_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, unsigned long arg) { - return cdrom_ioctl(file, &scd_info, inode, cmd, arg); + /* The eject and close commands should be handled by Uniform CD-ROM + * driver - but I always got hard lockup instead of eject + * until I put this here. + */ + switch (cmd) { + case CDROMEJECT: + scd_lock_door(&scd_info, 0); + return scd_tray_move(&scd_info, 1); + case CDROMCLOSETRAY: + return scd_tray_move(&scd_info, 0); + default: + return cdrom_ioctl(file, &scd_info, inode, cmd, arg); + } } static int scd_block_media_changed(struct gendisk *disk) @@ -3372,6 +3216,7 @@ int __init cdu31a_init(void) tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */ cdu31a_irq = 0; + sony_speed = is_double_speed; /* Set 2X drives to 2X by default */ set_drive_params(sony_speed); cdu31a_irq = tmp_irq; @@ -3417,13 +3262,12 @@ int __init cdu31a_init(void) strcat(msg, buf); } strcat(msg, "\n"); - - is_a_cdu31a = - strcmp("CD-ROM CDU31A", drive_config.product_id) == 0; - + printk("%s",msg); + cdu31a_queue = blk_init_queue(do_cdu31a_request, &cdu31a_lock); if (!cdu31a_queue) goto errout0; + blk_queue_hardsect_size(cdu31a_queue, 2048); init_timer(&cdu31a_abort_timer); cdu31a_abort_timer.function = handle_abort_timeout; diff --git a/drivers/cdrom/cdu31a.h b/drivers/cdrom/cdu31a.h index a04d0b3a249c..61d4768c412e 100644 --- a/drivers/cdrom/cdu31a.h +++ b/drivers/cdrom/cdu31a.h @@ -72,10 +72,10 @@ from drive (in 1/100th's of seconds). */ -#define SONY_JIFFIES_TIMEOUT 1000 /* Maximum number of times the +#define SONY_JIFFIES_TIMEOUT (10*HZ) /* Maximum number of times the drive will wait/try for an operation */ -#define SONY_RESET_TIMEOUT 100 /* Maximum number of times the +#define SONY_RESET_TIMEOUT HZ /* Maximum number of times the drive will wait/try a reset operation */ #define SONY_READY_RETRIES 20000 /* How many times to retry a diff --git a/drivers/char/README.computone b/drivers/char/README.computone deleted file mode 100644 index d4d3f13b3a08..000000000000 --- a/drivers/char/README.computone +++ /dev/null @@ -1,10 +0,0 @@ -Computone Intelliport II/Plus Multiport Serial Driver ------------------------------------------------------ - -Release Notes For Linux Kernel 2.2 and higher - -This file is now deprecated and will be removed at some point. - -Please refer to the file Documentation/computone.txt instead. - -Michael H. Warfield 08/12/2001 diff --git a/drivers/char/README.cyclomY b/drivers/char/README.cyclomY deleted file mode 100644 index 9ccf2e8b1887..000000000000 --- a/drivers/char/README.cyclomY +++ /dev/null @@ -1,23 +0,0 @@ - -NOTE: Earlier versions of the driver mapped ttyC0 to minor -number 32, but this is changed in this distribution. Port ttyC0 -now maps to minor number 0.) The following patch should be -applied to /dev/MAKEDEV and the script should then be re-run -to create new entries for the ports. ---------------------------- CUT HERE ---------------------------- ---- /dev/MAKEDEV Sun Aug 20 10:51:55 1995 -+++ MAKEDEV.new Fri Apr 19 06:48:12 1996 -@@ -206,8 +206,8 @@ - major2=`Major cub` || continue - for i in 0 1 2 3 4 5 6 7 # 8 9 10 11 12 13 14 15 - do -- makedev ttyC$i c $major1 `expr 32 + $i` $tty -- makedev cub$i c $major2 `expr 32 + $i` $dialout -+ makedev ttyC$i c $major1 $i $tty -+ makedev cub$i c $major2 $i $dialout - done - ;; - par[0-2]) ---------------------------- CUT HERE ---------------------------- - - diff --git a/drivers/char/README.epca b/drivers/char/README.epca deleted file mode 100644 index 77c3886935bd..000000000000 --- a/drivers/char/README.epca +++ /dev/null @@ -1,532 +0,0 @@ -user.doc -Digi International driver package for the PC/Xe, PC/Xi, PC/Xr, PC/Xem as well -the EISA and PCI variants of these boards where applicable. -Copyright (C) 1996 Digi International. Written by Ronnie Sanford digilnux@dgii.com - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2 of the License, or (At your - option) any later version. - - This 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., - 675 Mass Ave, Cambridge, MA 02139, USA. - - -This document describes the software used with the Digi/Linux driver package. -The four user programs listed below are described in this document: - - 1. digiConfig -> Application that configures the Digi driver. - - 2. digiDload -> Application which initializes the Digi hardware. - - 3. buildPCI -> Application which provides the user a method of - building device nodes for PCI devices. - - 4. ditty -> Application which provides the user a method of - configuring terminal options on Digi hardware. - - - --------------------------------------------------------------------------- -1. Configuring driver/kernel for Digi products --------------------------------------------------------------------------- - - The Digi driver must be configured each time Digi hardware is added - or removed. There are two supported methods of doing this. The - first method configures the driver dynamically at boot time but requires - the user to utilize the lilo loader. This method is the preffered method - as it does not require the rebuilding of the kernel. In order to use lilo - to configure Digi boards at boot time an appropriate append command should - be added to /etc/lilo.conf below the appropriate label decleration. - See footer 4. The append commands format is a string of comma separated - identifiers or integers used to configure supported boards. These six - values in order are: - - Enable/Disable this card or Override, - Type of card: PC/Xe (AccelePort) (0), PC/Xeve (1), PC/Xem or PC/Xr (2), - EISA/Xem (3), PC/Xe (64K) (4), PC/Xi (5). - Enable/Disable alternate pin arrangement, - Number of ports on this card, - I/O Port where card is configured (in HEX if using string identifiers), - Base of memory window (in HEX if using string identifiers) - - A sample append command is given below which if used would configure and - enable a PC/Xe with 8 ports, at i/o address 200, memory address 0xd0000 - with alt pin turned off. The lilo.conf file should look like this: - - image = /vmlinuz - root = /dev/hda2 - label = vmlinuz - append="digiepca=E,PC/Xe,D,8,200,D0000" - - likewise the below will perform the same function: - - image = /vmlinuz - root = /dev/hda2 - label = vmlinuz - append="digiepca=1,0,0,8,512,851968" - - Note: - - PCI boards are auto-detected and configured (Hence their codes are - not given here). Do not attempt to configure PCI boards with the lilo - append command. - - If configuration data has been specified by using digiConfig (Described - below), and you wish to override this configuration using lilo without - specifying a specific card (Example if there are PCI cards in the system) - the following override command will accomplish this: - - -> append="digiepca=2" - - If lilo is not enabled, the second method of configuring Digi hardware - will have to be used. digiConfig is an application that can be used - to inform the system of any additions, deletions, or modifications - involving Digi hardware. To use this method the operator executes - digiConfig anytime an EISA or ISA card is added that he wishes to use. - This routine is also used to remove cards from the system, and to modify - parameters of those cards already present in the system. Upon being - executed digiConfig modifies files accessed by the Digi driver. To make - these changes permanent; the operating system must be recompiled. After - the operating system has been recompiled and booted, the changes made with - digiConfig will be introduced to the user. This program MUST be executed - every time Digi EISA/ISA hardware configuration changes. Note, it is not - necessary to execute digiConfig in order to configure the Digi PCI cards. - These cards are self-identifying and will be recognized by the driver. - They cannot be displayed using digiConfig nor will digiConfig build the - device nodes their device nodes. See footer 1. - - To execute digiConfig; simply type: digiConfig - - The application will query you for the type, memory address, port - address, number of ports, alt pin disposition and status of each board - that exist on the system. Note, currently this driver only supports - PC/Xe, PC/Xeve, PC/Xi, PC/Xr, and PC/Xem as well as their EISA and PCI - implementations if applicable. All supported cards (Other than PCI) that - are present should be registered via digiConfig. See footer 2. - - After all cards have been configured select exit. The system will then - inform you if any changes have been made, and ask you if it is okay to - make these changes permanent. If the data entered is correct, select okay. - Selecting cancel will prevent the changes from becoming active. digiConfig - can then be re-executed to configure the system again. - --------------------------------------------------------------------------- -2. Initializing Digi hardware with digiDload --------------------------------------------------------------------------- - - digiDload is the application executed after the Digi driver has been - loaded. It is responsible for initializing the hardware and leaving - it in a state such that the Digi board may be operated by the user. - The application may be placed anywhere on the path, but its related - support files must be located in /etc/digi. The related files are: - - sxfep.bin - sxbios.bin - xxfep.bin - xxbios.bin - - The format for this command is "digiDload [v]". If given the "v" - option turns on verbosity. If not given the application runs in quite - mode. To execute the program simply type: - - digiDload - - Upon completion digiDload will generate the below message: - - "digiDload complete: Card initialized" - - At this point the card is configured and ready for normal usage. See - technotes.doc for information on how how ports are determined and - assigned. - --------------------------------------------------------------------------- -3. Build PCI device nodes with buildPCI --------------------------------------------------------------------------- - - buildPCI is an application useful for building the necessary device nodes - for Digi PCI cards. It is reccomended that this tool be used because the - current digiConfig application does not provide this function for PCI cards - (Though it does build device nodes for non-PCI cards). To use this program - execute the following:first install the driver, and execute digiDload (See above). After digiDload - has successfully loaded, execute the following: - - buildPCI <arg1> <arg2> - - Where arg1 is the number of ports connected to Digi cards that are not PCI - (As shown by the digiConfig utility), and arg2 is the number of ports - connected to Digi cards that are PCI. - - Note, buildPCI only has to be ran once to build the necessary device - nodes. Though this program may be executed at anytime, we reccomend - delaying execution until the first time you install the package and after - digiDload has been executed. - --------------------------------------------------------------------------- -4. Setting Terminal Options with ditty --------------------------------------------------------------------------- - -ditty is a utility program that sets and displays the terminal options -for Digi intelligent serial products. See man ditty for detailed information. - - -Footnotes: - -1. The 1.2.x kernel does not provide a method of mapping the high - addresses (Normally higher than RAM) associated with PCI. For this - reason, this driver disables PCI support while running under the 1.2.x - kernels. - -2. PCI cards should not and cannot be registered with digiConfig. After - the driver has been loaded buildPCI may be executed to construct the - necessary device nodes. This step is not necessary for system not - having Digi PCI cards. - -3. This is because we forsee a time when buildPCI may auto-detect the - available Digi PCI cards and this would only work if the program is - executed after digiDload. - -4. A complete example is given in install.doc. - --------------CHANGES-------------------- - -All changes should be recorded here. All changes should be explained in -verbose detail. ------------------------------------------------------------------------ -Programmer : Ronnie Sanford -Date : June 1, 1996 -Description (Verbose) : Initial release of driver package. -Files affected : all -Release version : 1.0.0f (BETA) ------------------------------------------------------------------------ ------------------------------------------------------------------------ -Programmer : Ronnie Sanford -Date : August 7, 1996 -Description (Verbose) : Made several modifications to provide PCI and EISA - support: - - 1. We now allocate the termios structures based on - the maximum number of channels that COULD be - available to the system. We no longer use the - number of channels declared in epcaconfig.h - (NBDEVS) as the total channel number. This is - because this value does not represent channels - available to potential PCI cards. This new - larger value is also passed back to the os in - the num field of tty_driver. - - 2. Added code to copy the previous board structure - (Now called static_boards) into a new local - copy of the boards structure. This has been - done so that PCI cards may be added to this - board array and later referenced (And even - queried.). - - 3. Added code to pc_init that checks for supported - PCI cards. If found this code initializes a new - entry into the drivers local board structure - with the PCI cards address, and type, etc.. It - also bumps the card count (num_cards). - - 4. Modified code in post_fep_init so that when this - routine is executed the number of ports supported - by a particular PCI card will be determined and - loaded into the board structure. It would be - much better if this code was placed in pc_init - (Because we could then report to the os the true - number of ports available; not just the max), but - since the card has to be booted to determine the - number of ports it supports, we are forced to do it - after DIGI_INIT has called post_fep_init. In the - future we may attempt to read the num ports - attached directly (address 0x1ac). - - 5. Added board types to epca.h in support of various - PCI boards (Some of which do not exist yet). - Added procedures for these boards throughout the - code. Note, windowing is not necessary for PCI - boards. - - 6. Added code supporting the EISA/XEM. This included - modifying epca.h with the new board type and - adding this type into the driver. The EISA/XEM - is basically identical to the PC/XEM, other than - it's base address does not have to be (And cannot - be configured directly). - - 7. Modified digiConfig to prompt for EISA/XEM cards. - -Files affected : epca.c, epca.h, digi1.h, digiConfig -Release version : 1.0.0g (BETA) ------------------------------------------------------------------------ ------------------------------------------------------------------------ -Programmer : Ronnie Sanford -Date : August 21, 1996 -Description (Verbose) : Made the following modifications: - - 1. A problem affecting hard flow control was found - in the termios2digi_h routine. Specifically, - when the user activated hard flow control using - the CRTSCTS specification, the values used to - program hard flow control on the board were - incorrect. The solution was to change a line - that read "res |= ((ch->m_dtr) | (ch->m_rts));" - to "res |= ((ch->m_cts) | (ch->m_rts));" This - line only applies if cflag & CRTSCTS. Special - thanks to Matt Robinson (matt@mania.com.au) who - found and fixed this problem. - - 2. In previous betas the cud device was set to CLOCAL - on driver boot up. Likewise the ttyD device was - set to ~CLOCAL. This has been fixed in this driver. - Now ttyD is CLOCAL and cud is ~CLOCAL. The fix - for this can be found in pc_init. - - 3. In ditty.c many changes were made to eliminate bugs - and warning messages. Two ioctl calls were eliminated - as well a problem involving using the returned baud - index to determine the drivers baud rate. Newer - Linux kernels support higher baud rates by using - 0x1000 bit. When the returned value (ored with - 0x1000) was used to reference our fbaud table a - serious memory problem occurred. This has been fixed. - - 4. Added a request_region call to post_fep_init. This - should cause the i/o ports being used to be - registered with proc. - - 5. Modified digiConfig to set all cud and ttyD devices - to read/write all permission. - - 6. Developed a new apps called buildPCI that provides - an easy way to build device nodes for PCI cards. - - 7. Modified user.doc and technotes.doc document the - use of buildPCI. - -Files affected : epca.c, ditty.c, digiConfig, user.doc, technotes.doc -Release version : 1.0.0 (Official release) ------------------------------------------------------------------------ -Programmer : Ronnie Sanford -Date : August 21, 1996 -Description (Verbose) : Made the following modifications: - - 1. Removed code from pc_close which closes the - drivers line discipline and restores its original - line discipline. This is currently unnecessary, - though future fast cook enhancements may require - this. - - 2. Removed code in block_til_ready that set the - asyncflags to either ASYNC_CALLOUT_ACTIVE, or - ASYNC_NORMAL_ACTIVE. This code was redundant - as it already existed in block_til_ready. - - 3. Added code in block_til_ready to cause a return - prior to schedule being called if the device - was a CALLOUT device. CALLOUT devices never - block on CD. (This was a serious bug that - prevented the CALLOUT devices (ttyD) from - functioning properly in some instances. - - Make a change in the MODEMCHG_IND case of doevent - such that it does not require ASYNC_CALLOUT_ACTIVE - or ASYNC_NORMAL_ACTIVE to be set in order to - unblock an open (Using wait_interruptible). - - Thanks to Mike McLagan (mike.mclagan@linux.org) - for diagnosing and fixing this problem. - - 4. Made changes to the disposition of CLOCAL on - both SERIAL NORMAL and CALLOUT devices. Both - device types now have CLOCAL active at default. - This may be changed with a stty command. - - 5. Made changes to digiConfig such that it checks - major.h (If valid) for the correct major - numbers to use. - -Files affected : epca.c, digiConfig -Release version : 1.0.1a - - ------------------------------------------------------------------------ -Programmer : Ronnie Sanford -Date : September 17, 1996 -Description (Verbose) : Made the following modifications: - - 1. Modified pc_open such that it no longer checks - the cflag value returned by termios2digi_c for - CLOCAL. Digi hardware does not use this value - and thus termios2digi_c rightly screens this - value out. This driver checks for CLOCAL using - the drivers cflag value as known by the Linux OS. - (The value passed into termios2digi_c) - - 2. Modified termios2digi_c to screen out the - CBAUDEX in CBAUD. This error caused parity to - automaticaly be enabled on at higher baud rates. - - - 3. Added the "disable_bh()" call to the shutdown - subroutine. Hopefully this will allow the driver - to correctly clean up after itself when used as a - module. - - 4. Added support for the PC/XI and 64K PC/XE cards. - This involved primarily modifying digiDload to - initialize and boot the new cards; however - driver modifications were also required to - provide the proper windowing for the newly - supported cards. (Code was also added to - determine the memory segment of the XI card as - that card may have more than 64K. Currently - digiDload assumes a 64K XI card.) - - 5. Added subroutine called epca_setup that can be - called during LILO boot up. This provides the - user an easy way to change cards; without - running digiConfig and without recompiling the - kernel. Added code in pc_init and pc_open to - support the epca_setup routine. pc_init checks - the liloconfig flag (Which is set by epca_setup) - to determine if the driver is using the LILO - arguments. If not pc_init loads the board data - found in epcaconfig.h; if so it DOESN'T load - epcaconfig data depending on epca_setup to handle - board configuration. pc_open has been modified - such that it checks to ensure that no errors - occurred during the LILO boot process. If a - user attempts to boot the driver (via. LILO) - with incorrect data, the open will fail. - - 6. Modified the windowing routines pcxe_rxwinon - and pcxe_txwinon routines. A bug existed such - that those routines checked to see if the rxwin - and txwin flags were reset. If so they assumed - the board was an XI or 64K XE. Furthermore since - these flags were never initialized in our driver - sometimes they were 0 and therefore caused a - memory fault (Or at least a window overrun). This - code has been removed since the pcxe shares - nothing in common with the 64K XI and XE. - - 7. Added code in pc_init to set the memory_seg for - the various boards. This code was necessary to - correct a bug in the PCXE, PCXEVE code where - receive and transmit pointers were being calculated - from an uninitialized variable (memory_seg). - - 8. Modified digiConfig to allow 64K PC/XI and 64K - PC/XE cards to be configured. - - 9. Made changes to support the new 2.1.x development - kernel. In particular this required changing all - references to vremap to ioremap. - - 10. Modified digiConfig such that it now generates - node names corresponding to their internal - as opposed to the label on the port itself. Nodes - (ttyD?? and cud??) now start at 0. Example: - ttyD0 and cud0 represent port 1 on any supported - Digi product. A similar change has been made - in buildPCI.c. - - 12. At the early portion of post_fep_init if a PCI - card is detected a warning message could be given - incorrectly if 64 ports were attached to a PCI - card. The below line : - - epcaassert(bd->numports > 64,"PCI returned a invalid number of ports"); - - was changed to : - - epcaassert(bd->numports <= 64,"PCI returned a invalid number of ports"); - - Remember that epcaassert checks for NOT true. - Special thanks to Daniel Taylor for fixing this. - - 13. Modified the epcaparam routine. In version 100 - and 101a there was a line that looked like the - below: - - if (ch->omodem != mval) - - The problem with this line was that the first time - through omodem was not initialized. Secondly, since - many TIOC commands did not alter mval (They use - a different variable) changes made by these commands - could be lost. This line was changed to: - - mval ^= ch->modemfake & (mval ^ ch->modem); - - if (ch->omodem ^ mval) - - 14. Modified digiConfig in such a way that it checks - the version number of the kernel and if it finds - a 2.x.x kernel or higher it reads the necessary - major numbers for cud and ttyD devices from major.h. - This was also done in prior versions but these - versions required a #define which identified the - kernel as a version which did not have major numbers - assigned to Digi systems. This #define is no - longer required allowing the same source tree for - multiple kernel releases. - - 15. Used macros to replace kernel specific calls such - as put_fs_long, get_fs_long, put_user, and get_user - the kernel version is now detected and the macro - is defined as to correspond with the kernel it - is being compiled into. Again this was done to - allow one source tree for multiple kernel releases. - - 16. Added support for the new 2.1.x development kernels - to digiInstall. - -Files affected : epca.c, digiConfig -Release version : 1.1.0 ------------------------------------------------------------------------ -Programmer : Daniel Taylor -Date : April 25, 1997 -Description (Verbose) : Updated driver: - 1. Fixed DCD bug. (&tq scheduler) - 2. Removed BH handler code, as it was only handling - hangups, and not being called for that. - 3. Namespace cleanup (DIGI_TIMER2 => DIGI_TIMER) - 4. Updated to 2.1.36, removed #ifdefs for earlier - kernel revisions. -Files affected : epca.c -Release version : 1.1.1 (BETA) ------------------------------------------------------------------------ -Programmer : Daniel Taylor -Date : March 11, 1999 -Description (Verbose) : Updated driver: - 1. Simultaneous data and modem change events were - resulting in the modem change events not being - recognized. Fixed. - 2. Modified pc_info device name to work better - with devfs. -Files affected : epca.c -Release version : 1.3.0-K ------------------------------------------------------------------------ -Programmer : Jeff Garzik -Date : February 26, 2000 -Description (Verbose) : Updated driver: - 1. Use new kernel PCI interfaces. - 2. Updated list of includes. -Files affected : epca.c -Release version : 1.3.0.1-LK ------------------------------------------------------------------------ -Programmer : Arjan van de Ven <adve@oce.nl> -Date : March 10, 2000 -Description (Verbose) : Fixed includes to make it actually compile - for kernel 2.3.51 -Files affected : epca.c -Release version : 1.3.0.2-LK ------------------------------------------------------------------------ diff --git a/drivers/char/README.scc b/drivers/char/README.scc deleted file mode 100644 index 90fa4b8aed10..000000000000 --- a/drivers/char/README.scc +++ /dev/null @@ -1,5 +0,0 @@ -The z8530drv is now a network device driver, you can find it in - ../net/scc.c - -A subset of the documentation is in - Documentation/networking/z8530drv.txt diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 364e3831c8ff..ca7d88a6e304 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -712,6 +712,7 @@ static void hpet_register_interpolator(struct hpets *hpetp) ti->addr = &hpetp->hp_hpet->hpet_mc; ti->frequency = hpet_time_div(hpets->hp_period); ti->drift = ti->frequency * HPET_DRIFT / 1000000; + ti->mask = -1; hpetp->hp_interpolator = ti; register_time_interpolator(ti); diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index fff5212b7eff..a92cba73559a 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -13,6 +13,9 @@ * * 11/01/01 - jbarnes - initial revision * 9/10/04 - Christoph Lameter - remove interrupt support for kernel inclusion + * 10/1/04 - Christoph Lameter - provide posix clock CLOCK_SGI_CYCLE + * 10/13/04 - Christoph Lameter, Dimitri Sivanich - provide timer interrupt support + * via the posix timer interface */ #include <linux/types.h> @@ -26,23 +29,34 @@ #include <linux/mmtimer.h> #include <linux/miscdevice.h> #include <linux/posix-timers.h> +#include <linux/interrupt.h> #include <asm/uaccess.h> #include <asm/sn/addrs.h> -#include <asm/sn/clksupport.h> +#include <asm/sn/intr.h> #include <asm/sn/shub_mmr.h> +#include <asm/sn/nodepda.h> + +/* This is ugly and jbarnes has promised me to fix this later */ +#include "../../arch/ia64/sn/include/shubio.h" MODULE_AUTHOR("Jesse Barnes <jbarnes@sgi.com>"); -MODULE_DESCRIPTION("Multimedia timer support"); +MODULE_DESCRIPTION("SGI Altix RTC Timer"); MODULE_LICENSE("GPL"); /* name of the device, usually in /dev */ #define MMTIMER_NAME "mmtimer" -#define MMTIMER_DESC "IA-PC Multimedia Timer" -#define MMTIMER_VERSION "1.0" +#define MMTIMER_DESC "SGI Altix RTC Timer" +#define MMTIMER_VERSION "2.0" #define RTC_BITS 55 /* 55 bits for this implementation */ +extern unsigned long sn_rtc_cycles_per_second; + +#define RTC_COUNTER_ADDR ((long *)LOCAL_MMR_ADDR(SH_RTC)) + +#define rtc_time() (*RTC_COUNTER_ADDR) + static int mmtimer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); static int mmtimer_mmap(struct file *file, struct vm_area_struct *vma); @@ -58,6 +72,200 @@ static struct file_operations mmtimer_fops = { .ioctl = mmtimer_ioctl, }; +/* + * Comparators and their associated info. Shub has + * three comparison registers. + */ + +/* + * We only have comparison registers RTC1-4 currently available per + * node. RTC0 is used by SAL. + */ +#define NUM_COMPARATORS 3 +/* + * Check for an interrupt and clear the pending bit if + * one is waiting. +*/ +static int inline mmtimer_int_pending(int comparator) +{ + int pending = 0; + + switch (comparator) { + case 0: + if (HUB_L((unsigned long *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED)) & + SH_EVENT_OCCURRED_RTC1_INT_MASK) { + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), + SH_EVENT_OCCURRED_RTC1_INT_MASK); + pending = 1; + } + break; + case 1: + if (HUB_L((unsigned long *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED)) & + SH_EVENT_OCCURRED_RTC2_INT_MASK) { + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), + SH_EVENT_OCCURRED_RTC2_INT_MASK); + pending = 1; + } + break; + case 2: + if (HUB_L((unsigned long *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED)) & + SH_EVENT_OCCURRED_RTC3_INT_MASK) { + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), + SH_EVENT_OCCURRED_RTC3_INT_MASK); + pending = 1; + } + break; + default: + return -EFAULT; + } + return pending; +} + +static void inline mmtimer_setup_int_0(u64 expires) +{ + u64 val; + + /* Disable interrupt */ + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC1_INT_ENABLE), 0UL); + + /* Initialize comparator value */ + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_INT_CMPB), -1L); + + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), + SH_EVENT_OCCURRED_RTC1_INT_MASK); + + val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC1_INT_CONFIG_IDX_SHFT) | + ((u64)cpu_physical_id(smp_processor_id()) << + SH_RTC1_INT_CONFIG_PID_SHFT); + + /* Set configuration */ + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC1_INT_CONFIG), val); + + /* Enable RTC interrupts */ + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC1_INT_ENABLE), 1UL); + + /* Initialize comparator value */ + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_INT_CMPB), expires); + + +} + +static void inline mmtimer_setup_int_1(u64 expires) +{ + u64 val; + + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC2_INT_ENABLE), 0UL); + + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_INT_CMPC), -1L); + + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), + SH_EVENT_OCCURRED_RTC2_INT_MASK); + + val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC2_INT_CONFIG_IDX_SHFT) | + ((u64)cpu_physical_id(smp_processor_id()) << + SH_RTC2_INT_CONFIG_PID_SHFT); + + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC2_INT_CONFIG), val); + + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC2_INT_ENABLE), 1UL); + + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_INT_CMPC), expires); +} + +static void inline mmtimer_setup_int_2(u64 expires) +{ + u64 val; + + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC3_INT_ENABLE), 0UL); + + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_INT_CMPD), -1L); + + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), + SH_EVENT_OCCURRED_RTC3_INT_MASK); + + val = ((u64)SGI_MMTIMER_VECTOR << SH_RTC3_INT_CONFIG_IDX_SHFT) | + ((u64)cpu_physical_id(smp_processor_id()) << + SH_RTC3_INT_CONFIG_PID_SHFT); + + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC3_INT_CONFIG), val); + + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC3_INT_ENABLE), 1UL); + + HUB_S((u64 *)LOCAL_MMR_ADDR(SH_INT_CMPD), expires); +} + +/* + * This function must be called with interrupts disabled and preemption off + * in order to insure that the setup succeeds in a deterministic time frame. + * It will check if the interrupt setup succeeded. + * mmtimer_setup will return the cycles that we were too late if the + * initialization failed. + */ +static int inline mmtimer_setup(int comparator, unsigned long expires) +{ + + long diff; + + switch (comparator) { + case 0: + mmtimer_setup_int_0(expires); + break; + case 1: + mmtimer_setup_int_1(expires); + break; + case 2: + mmtimer_setup_int_2(expires); + break; + } + /* We might've missed our expiration time */ + diff = rtc_time() - expires; + if (diff > 0) { + if (HUB_L((unsigned long *)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED)) & + (SH_EVENT_OCCURRED_RTC1_INT_MASK << comparator)) { + /* We'll get an interrupt for this once we're done */ + return 0; + } + /* Looks like we missed it */ + return diff; + } + + return 0; +} + +static int inline mmtimer_disable_int(long nasid, int comparator) +{ + switch (comparator) { + case 0: + nasid == -1 ? HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC1_INT_ENABLE), + 0UL) : REMOTE_HUB_S(nasid, SH_RTC1_INT_ENABLE, 0UL); + break; + case 1: + nasid == -1 ? HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC2_INT_ENABLE), + 0UL) : REMOTE_HUB_S(nasid, SH_RTC2_INT_ENABLE, 0UL); + break; + case 2: + nasid == -1 ? HUB_S((u64 *)LOCAL_MMR_ADDR(SH_RTC3_INT_ENABLE), + 0UL) : REMOTE_HUB_S(nasid, SH_RTC3_INT_ENABLE, 0UL); + break; + default: + return -EFAULT; + } + return 0; +} + +#define TIMER_OFF 0xbadcabLL + +/* There is one of these for each comparator */ +typedef struct mmtimer { + spinlock_t lock ____cacheline_aligned; + struct k_itimer *timer; +} mmtimer_t; + +/* + * Total number of comparators is comparators/node * MAX nodes/running kernel + */ +static mmtimer_t timers[NUM_COMPARATORS*MAX_COMPACT_NODES]; + /** * mmtimer_ioctl - ioctl interface for /dev/mmtimer * @inode: inode of the device @@ -183,22 +391,31 @@ static struct miscdevice mmtimer_miscdev = { static struct timespec sgi_clock_offset; static int sgi_clock_period; -static int sgi_clock_get(struct timespec *tp) { +/* + * Posix Timer Interface + */ + +static struct timespec sgi_clock_offset; +static int sgi_clock_period; + +static int sgi_clock_get(struct timespec *tp) +{ u64 nsec; - nsec = readq(RTC_COUNTER_ADDR) * sgi_clock_period + nsec = rtc_time() * sgi_clock_period + sgi_clock_offset.tv_nsec; tp->tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &tp->tv_nsec) + sgi_clock_offset.tv_sec; return 0; }; -static int sgi_clock_set(struct timespec *tp) { +static int sgi_clock_set(struct timespec *tp) +{ u64 nsec; u64 rem; - nsec = readq(RTC_COUNTER_ADDR) * sgi_clock_period; + nsec = rtc_time() * sgi_clock_period; sgi_clock_offset.tv_sec = tp->tv_sec - div_long_long_rem(nsec, NSEC_PER_SEC, &rem); @@ -211,12 +428,254 @@ static int sgi_clock_set(struct timespec *tp) { return 0; } +/* + * Schedule the next periodic interrupt. This function will attempt + * to schedule a periodic interrupt later if necessary. If the scheduling + * of an interrupt fails then the time to skip is lengthened + * exponentially in order to ensure that the next interrupt + * can be properly scheduled.. + */ +static int inline reschedule_periodic_timer(mmtimer_t *base, struct k_itimer *t, int i) +{ + int n; + + t->it_timer.magic = i; + base[i].timer = t; + t->it_overrun--; + + n = 0; + do { + + t->it_timer.expires += t->it_incr << n; + t->it_overrun += 1 << n; + n++; + if (n > 20) + return 1; + + } while (mmtimer_setup(i, t->it_timer.expires)); + + return 0; +} + +/** + * mmtimer_interrupt - timer interrupt handler + * @irq: irq received + * @dev_id: device the irq came from + * @regs: register state upon receipt of the interrupt + * + * Called when one of the comarators matches the counter, This + * routine will send signals to processes that have requested + * them. + * + * This interrupt is run in an interrupt context + * by the SHUB. It is therefore safe to locally access SHub + * registers. + */ +static irqreturn_t +mmtimer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + int i; + mmtimer_t *base = timers + cpuid_to_cnodeid(smp_processor_id()) * NUM_COMPARATORS; + int result = IRQ_NONE; + + /* + * Do this once for each comparison register + */ + for (i = 0; i < NUM_COMPARATORS; i++) { + unsigned long flags; + + if (mmtimer_int_pending(i) > 0) { + struct k_itimer *t; + int m = 0; + + mmtimer_disable_int(-1, i); + spin_lock(&base[i].lock); + t = base[i].timer; + base[i].timer = NULL; + if (t) { + m = t->it_timer.magic; + t->it_timer.magic = TIMER_OFF; + } + spin_unlock(&base[i].lock); + + if (t == NULL || m == TIMER_OFF) + /* No timer left here, bail out */ + goto out; + + spin_lock_irqsave(&t->it_lock, flags); + t->it_overrun = 0; + + if (posix_timer_event(t, 0) == 0) { + + if(t->it_incr) { + /* Periodic timer */ + spin_lock(&base[i].lock); + if (base[i].timer == NULL) + reschedule_periodic_timer(base, t, i); + spin_unlock(&base[i].lock); + } + + } else { + printk(KERN_WARNING "mmtimer: unable to deliver signal"); + t->it_overrun++; + } + t->it_overrun_last = t->it_overrun; + spin_unlock_irqrestore(&t->it_lock, flags); +out: + result = IRQ_HANDLED; + } + } + return result; +} + +static int sgi_timer_create(struct k_itimer *timer) +{ + /* Insure that a newly created timer is off */ + timer->it_timer.magic = TIMER_OFF; + return 0; +} + +/* This does not really delete a timer. It just insures + * that the timer is not active + * + * Assumption: it_lock is already held with irq's disabled + */ +static int sgi_timer_del(struct k_itimer *timr) +{ + int i = timr->it_timer.magic; + cnodeid_t nodeid = timr->it_timer.data; + mmtimer_t *t = timers + nodeid * NUM_COMPARATORS +i; + unsigned long irqflags; + + if (i != TIMER_OFF) { + spin_lock_irqsave(&t->lock, irqflags); + mmtimer_disable_int(cnodeid_to_nasid(nodeid),i); + t->timer = NULL; + timr->it_timer.magic = TIMER_OFF; + spin_unlock_irqrestore(&t->lock, irqflags); + } + return 0; +} + +#define timespec_to_ns(x) ((x).tv_nsec + (x).tv_sec * NSEC_PER_SEC) +#define ns_to_timespec(ts, nsec) (ts).tv_sec = div_long_long_rem(nsec, NSEC_PER_SEC, &(ts).tv_nsec) + +/* Assumption: it_lock is already held with irq's disabled */ +static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) +{ + + if (timr->it_timer.magic == TIMER_OFF) { + cur_setting->it_interval.tv_nsec = 0; + cur_setting->it_interval.tv_sec = 0; + cur_setting->it_value.tv_nsec = 0; + cur_setting->it_value.tv_sec =0; + return; + } + + ns_to_timespec(cur_setting->it_interval, timr->it_incr * sgi_clock_period); + ns_to_timespec(cur_setting->it_value, (timr->it_timer.expires - rtc_time())* sgi_clock_period); + return; +} + + +static int sgi_timer_set(struct k_itimer *timr, int flags, + struct itimerspec * new_setting, + struct itimerspec * old_setting) +{ + + int i; + unsigned long when, period, irqflags; + int err = 0; + cnodeid_t nodeid; + mmtimer_t *base; + + if (old_setting) + sgi_timer_get(timr, old_setting); + + sgi_timer_del(timr); + when = timespec_to_ns(new_setting->it_value); + period = timespec_to_ns(new_setting->it_interval); + + if (when == 0) + /* Clear timer */ + return 0; + + if (flags & TIMER_ABSTIME) { + struct timespec n; + + getnstimeofday(&n); + when -= timespec_to_ns(n); + } + + /* + * Convert to sgi clock period. Need to keep rtc_time() as near as possible + * to getnstimeofday() in order to be as faithful as possible to the time + * specified. + */ + when = (when + sgi_clock_period - 1) / sgi_clock_period + rtc_time(); + period = (period + sgi_clock_period - 1) / sgi_clock_period; + + /* + * We are allocating a local SHub comparator. If we would be moved to another + * cpu then another SHub may be local to us. Prohibit that by switching off + * preemption. + */ + preempt_disable(); + + nodeid = cpuid_to_cnodeid(smp_processor_id()); + base = timers + nodeid * NUM_COMPARATORS; +retry: + for(i = 0; i< NUM_COMPARATORS; i++) { + if (!base[i].timer) { + break; + } + } + + if (i == NUM_COMPARATORS) { + preempt_enable(); + return -EBUSY; + } + + spin_lock_irqsave(&base[i].lock, irqflags); + + if (base[i].timer) { + spin_unlock_irqrestore(&base[i].lock, irqflags); + goto retry; + } + base[i].timer = timr; + + timr->it_timer.magic = i; + timr->it_timer.data = nodeid; + timr->it_incr = period; + timr->it_timer.expires = when; + + if (period == 0) { + if (mmtimer_setup(i, when)) { + mmtimer_disable_int(-1, i); + posix_timer_event(timr, 0); + } + } else { + timr->it_timer.expires -= period; + if (reschedule_periodic_timer(base, timr, i)) + err = -EINVAL; + } + + spin_unlock_irqrestore(&base[i].lock, irqflags); + + preempt_enable(); + + return err; +} + static struct k_clock sgi_clock = { .res = 0, .clock_set = sgi_clock_set, .clock_get = sgi_clock_get, - .timer_create = do_posix_clock_notimer_create, - .nsleep = do_posix_clock_nonanosleep + .timer_create = sgi_timer_create, + .nsleep = do_posix_clock_nonanosleep, + .timer_set = sgi_timer_set, + .timer_del = sgi_timer_del, + .timer_get = sgi_timer_get }; /** @@ -226,6 +685,8 @@ static struct k_clock sgi_clock = { */ static int __init mmtimer_init(void) { + unsigned i; + if (!ia64_platform_is("sn2")) return -1; @@ -241,6 +702,17 @@ static int __init mmtimer_init(void) mmtimer_femtoperiod = ((unsigned long)1E15 + sn_rtc_cycles_per_second / 2) / sn_rtc_cycles_per_second; + for (i=0; i< NUM_COMPARATORS*MAX_COMPACT_NODES; i++) { + spin_lock_init(&timers[i].lock); + timers[i].timer = NULL; + } + + if (request_irq(SGI_MMTIMER_VECTOR, mmtimer_interrupt, SA_PERCPU_IRQ, MMTIMER_NAME, NULL)) { + printk(KERN_WARNING "%s: unable to allocate interrupt.", + MMTIMER_NAME); + return -1; + } + strcpy(mmtimer_miscdev.devfs_name, MMTIMER_NAME); if (misc_register(&mmtimer_miscdev)) { printk(KERN_ERR "%s: failed to register device\n", diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 63ae225c6296..749590b6affd 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c @@ -676,7 +676,6 @@ static void moxa_flush_buffer(struct tty_struct *tty) return; MoxaPortFlushData(ch->port, 1); tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); } static int moxa_chars_in_buffer(struct tty_struct *tty) @@ -935,7 +934,6 @@ static void moxa_poll(unsigned long ignored) if (!tp->stopped) { ch->statusflags &= ~LOWWAIT; tty_wakeup(tp); - wake_up_interruptible(&tp->write_wait); } } } @@ -1102,7 +1100,6 @@ static void check_xmit_empty(unsigned long data) if (MoxaPortTxQueue(ch->port) == 0) { ch->statusflags &= ~EMPTYWAIT; tty_wakeup(ch->tty); - wake_up_interruptible(&ch->tty->write_wait); return; } moxaEmptyTimer[ch->port].expires = jiffies + HZ; diff --git a/drivers/char/random.c b/drivers/char/random.c index cde68a2d4f10..f867eee30bd4 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -698,7 +698,7 @@ static int __init batch_entropy_init(int size, struct entropy_store *r) * hashing calculations during an interrupt in add_timer_randomness(). * Instead, the entropy is only added to the pool by keventd. */ -void batch_entropy_store(u32 a, u32 b, int num) +static void batch_entropy_store(u32 a, u32 b, int num) { int new; unsigned long flags; @@ -729,8 +729,6 @@ void batch_entropy_store(u32 a, u32 b, int num) spin_unlock_irqrestore(&batch_lock, flags); } -EXPORT_SYMBOL(batch_entropy_store); - /* * Flush out the accumulated entropy operations, adding entropy to the passed * store (normally random_state). If that store has enough entropy, alternate @@ -874,8 +872,6 @@ void add_keyboard_randomness(unsigned char scancode) } } -EXPORT_SYMBOL(add_keyboard_randomness); - void add_mouse_randomness(__u32 mouse_data) { add_timer_randomness(&mouse_timer_state, mouse_data); @@ -891,8 +887,6 @@ void add_interrupt_randomness(int irq) add_timer_randomness(irq_timer_state[irq], 0x100+irq); } -EXPORT_SYMBOL(add_interrupt_randomness); - void add_disk_randomness(struct gendisk *disk) { if (!disk || !disk->random) diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index da52bff37f97..fb4c59faad07 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -216,6 +216,16 @@ static struct sysrq_key_op sysrq_kill_op = { /* END SIGNAL SYSRQ HANDLERS BLOCK */ +static void sysrq_handle_unrt(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) +{ + normalize_rt_tasks(); +} +static struct sysrq_key_op sysrq_unrt_op = { + .handler = sysrq_handle_unrt, + .help_msg = "Nice", + .action_msg = "Nice All RT Tasks" +}; /* Key Operations table and lock */ static spinlock_t sysrq_key_table_lock = SPIN_LOCK_UNLOCKED; @@ -250,7 +260,7 @@ static struct sysrq_key_op *sysrq_key_table[SYSRQ_KEY_TABLE_LENGTH] = { #endif /* l */ NULL, /* m */ &sysrq_showmem_op, -/* n */ NULL, +/* n */ &sysrq_unrt_op, /* o */ NULL, /* This will often be registered as 'Off' at init time */ /* p */ &sysrq_showregs_op, @@ -284,14 +294,6 @@ static int sysrq_key_table_key2index(int key) { } /* - * table lock and unlocking functions, exposed to modules - */ - -void __sysrq_lock_table (void) { spin_lock(&sysrq_key_table_lock); } - -void __sysrq_unlock_table (void) { spin_unlock(&sysrq_key_table_lock); } - -/* * get and put functions for the table, exposed to modules. */ @@ -323,8 +325,9 @@ void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty) struct sysrq_key_op *op_p; int orig_log_level; int i, j; + unsigned long flags; - __sysrq_lock_table(); + spin_lock_irqsave(&sysrq_key_table_lock, flags); orig_log_level = console_loglevel; console_loglevel = 7; printk(KERN_INFO "SysRq : "); @@ -346,7 +349,7 @@ void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty) printk ("\n"); console_loglevel = orig_log_level; } - __sysrq_unlock_table(); + spin_unlock_irqrestore(&sysrq_key_table_lock, flags); } /* @@ -361,8 +364,34 @@ void handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty) __handle_sysrq(key, pt_regs, tty); } +int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p, + struct sysrq_key_op *remove_op_p) { + + int retval; + unsigned long flags; + + spin_lock_irqsave(&sysrq_key_table_lock, flags); + if (__sysrq_get_key_op(key) == remove_op_p) { + __sysrq_put_key_op(key, insert_op_p); + retval = 0; + } else { + retval = -1; + } + spin_unlock_irqrestore(&sysrq_key_table_lock, flags); + + return retval; +} + +int register_sysrq_key(int key, struct sysrq_key_op *op_p) +{ + return __sysrq_swap_key_ops(key, op_p, NULL); +} + +int unregister_sysrq_key(int key, struct sysrq_key_op *op_p) +{ + return __sysrq_swap_key_ops(key, NULL, op_p); +} + EXPORT_SYMBOL(handle_sysrq); -EXPORT_SYMBOL(__sysrq_lock_table); -EXPORT_SYMBOL(__sysrq_unlock_table); -EXPORT_SYMBOL(__sysrq_get_key_op); -EXPORT_SYMBOL(__sysrq_put_key_op); +EXPORT_SYMBOL(register_sysrq_key); +EXPORT_SYMBOL(unregister_sysrq_key); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index ca53e05a88ed..7b6d9c991ca2 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -652,6 +652,43 @@ static int wait_hwif_ready(ide_hwif_t *hwif) return rc; } +/** + * ide_undecoded_slave - look for bad CF adapters + * @hwif: interface + * + * Analyse the drives on the interface and attempt to decide if we + * have the same drive viewed twice. This occurs with crap CF adapters + * and PCMCIA sometimes. + */ + +void ide_undecoded_slave(ide_hwif_t *hwif) +{ + ide_drive_t *drive0 = &hwif->drives[0]; + ide_drive_t *drive1 = &hwif->drives[1]; + + if (drive0->present == 0 || drive1->present == 0) + return; + + /* If the models don't match they are not the same product */ + if (strcmp(drive0->id->model, drive1->id->model)) + return; + + /* Serial numbers do not match */ + if (strncmp(drive0->id->serial_no, drive1->id->serial_no, 20)) + return; + + /* No serial number, thankfully very rare for CF */ + if (drive0->id->serial_no[0] == 0) + return; + + /* Appears to be an IDE flash adapter with decode bugs */ + printk(KERN_WARNING "ide-probe: ignoring undecoded slave\n"); + + drive1->present = 0; +} + +EXPORT_SYMBOL_GPL(ide_undecoded_slave); + /* * This routine only knows how to look for drive units 0 and 1 * on an interface, so any setting of MAX_DRIVES > 2 won't work here. @@ -723,20 +760,6 @@ static void probe_hwif(ide_hwif_t *hwif) ide_drive_t *drive = &hwif->drives[unit]; drive->dn = (hwif->channel ? 2 : 0) + unit; (void) probe_for_drive(drive); - if (drive->present && hwif->present && unit == 1) { - if (strcmp(hwif->drives[0].id->model, drive->id->model) == 0 && - /* Don't do this for noprobe or non ATA */ - strcmp(drive->id->model, "UNKNOWN") && - /* And beware of confused Maxtor drives that go "M0000000000" - "The SN# is garbage in the ID block..." [Eric] */ - strncmp(drive->id->serial_no, "M0000000000000000000", 20) && - /* Same goes for another set of Maxtor drives that say "D3000000" */ - strncmp(drive->id->serial_no, "D3000000", 8) && - strncmp(hwif->drives[0].id->serial_no, drive->id->serial_no, 20) == 0) { - printk(KERN_WARNING "ide-probe: ignoring undecoded slave\n"); - drive->present = 0; - } - } if (drive->present && !hwif->present) { hwif->present = 1; if (hwif->chipset != ide_4drives || @@ -810,9 +833,14 @@ static void probe_hwif(ide_hwif_t *hwif) } static int hwif_init(ide_hwif_t *hwif); -int probe_hwif_init (ide_hwif_t *hwif) + +int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif)) { probe_hwif(hwif); + + if (fixup) + fixup(hwif); + hwif_init(hwif); if (hwif->present) { @@ -830,6 +858,11 @@ int probe_hwif_init (ide_hwif_t *hwif) return 0; } +int probe_hwif_init(ide_hwif_t *hwif) +{ + return probe_hwif_init_with_fixup(hwif, NULL); +} + EXPORT_SYMBOL(probe_hwif_init); #if MAX_HWIFS > 1 diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 427f633dc441..1dd413ae439b 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -985,9 +985,10 @@ void ide_setup_ports ( hw_regs_t *hw, } /** - * ide_register_hw - register IDE interface + * ide_register_hw_with_fixup - register IDE interface * @hw: hardware registers * @hwifp: pointer to returned hwif + * @fixup: fixup function * * Register an IDE interface, specifying exactly the registers etc. * Set init=1 iff calling before probes have taken place. @@ -995,7 +996,7 @@ void ide_setup_ports ( hw_regs_t *hw, * Returns -1 on error. */ -int ide_register_hw (hw_regs_t *hw, ide_hwif_t **hwifp) +int ide_register_hw_with_fixup(hw_regs_t *hw, ide_hwif_t **hwifp, void(*fixup)(ide_hwif_t *hwif)) { int index, retry = 1; ide_hwif_t *hwif; @@ -1034,7 +1035,7 @@ found: hwif->chipset = hw->chipset; if (!initializing) { - probe_hwif_init(hwif); + probe_hwif_init_with_fixup(hwif, fixup); create_proc_ide_interfaces(); } @@ -1044,6 +1045,13 @@ found: return (initializing || hwif->present) ? index : -1; } +EXPORT_SYMBOL(ide_register_hw_with_fixup); + +int ide_register_hw(hw_regs_t *hw, ide_hwif_t **hwifp) +{ + return ide_register_hw_with_fixup(hw, hwifp, NULL); +} + EXPORT_SYMBOL(ide_register_hw); /* diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index dda2a17e0c6e..36426f72cb3f 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -206,7 +206,7 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq ide_init_hwif_ports(&hw, io, ctl, NULL); hw.irq = irq; hw.chipset = ide_pci; - return ide_register_hw(&hw, NULL); + return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave); } /*====================================================================== diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index 8f9de206c9e6..4625fc099360 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c @@ -241,8 +241,6 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic ide_pci_setup_ports(dev, d, 14, &index); - printk("Index.b %d %d\n", index.b.low, index.b.high); - mdelay(2000); if((index.b.low & 0xf0) != 0xf0) probe_hwif_init(&ide_hwifs[index.b.low]); if((index.b.high & 0xf0) != 0xf0) diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index b2efe20585e5..bae33e385fdd 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -4,6 +4,7 @@ * Copyright (C) 1997-1998 Mark Lord <mlord@pobox.com> * Copyright (C) 1998 Eddie C. Dost <ecd@skynet.be> * Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org> + * Copyright (C) 2004 Grant Grundler <grundler at parisc-linux.org> * * Inspired by an earlier effort from David S. Miller <davem@redhat.com> */ @@ -25,6 +26,81 @@ #include <asm/io.h> +#ifdef CONFIG_SUPERIO +/* SUPERIO 87560 is a PoS chip that NatSem denies exists. + * Unfortunately, it's built-in on all Astro-based PA-RISC workstations + * which use the integrated NS87514 cell for CD-ROM support. + * i.e we have to support for CD-ROM installs. + * See drivers/parisc/superio.c for more gory details. + */ +#include <asm/superio.h> + +static unsigned long superio_ide_status[2]; +static unsigned long superio_ide_select[2]; +static unsigned long superio_ide_dma_status[2]; + +#define SUPERIO_IDE_MAX_RETRIES 25 + +/* Because of a defect in Super I/O, all reads of the PCI DMA status + * registers, IDE status register and the IDE select register need to be + * retried + */ +static u8 superio_ide_inb (unsigned long port) +{ + if (port == superio_ide_status[0] || + port == superio_ide_status[1] || + port == superio_ide_select[0] || + port == superio_ide_select[1] || + port == superio_ide_dma_status[0] || + port == superio_ide_dma_status[1]) { + u8 tmp; + int retries = SUPERIO_IDE_MAX_RETRIES; + + /* printk(" [ reading port 0x%x with retry ] ", port); */ + + do { + tmp = inb(port); + if (tmp == 0) + udelay(50); + } while (tmp == 0 && retries-- > 0); + + return tmp; + } + + return inb(port); +} + +static void __devinit superio_ide_init_iops (struct hwif_s *hwif) +{ + u32 base, dmabase; + u8 tmp; + struct pci_dev *pdev = hwif->pci_dev; + u8 port = hwif->channel; + + base = pci_resource_start(pdev, port * 2) & ~3; + dmabase = pci_resource_start(pdev, 4) & ~3; + + superio_ide_status[port] = base + IDE_STATUS_OFFSET; + superio_ide_select[port] = base + IDE_SELECT_OFFSET; + superio_ide_dma_status[port] = dmabase + (!port ? 2 : 0xa); + + /* Clear error/interrupt, enable dma */ + tmp = superio_ide_inb(superio_ide_dma_status[port]); + outb(tmp | 0x66, superio_ide_dma_status[port]); + + /* We need to override inb to workaround a SuperIO errata */ + hwif->INB = superio_ide_inb; +} + +static void __devinit init_iops_ns87415(ide_hwif_t *hwif) +{ + if (PCI_SLOT(hwif->pci_dev->devfn) == 0xE) { + /* Built-in - assume it's under superio. */ + superio_ide_init_iops(hwif); + } +} +#endif + static unsigned int ns87415_count = 0, ns87415_control[MAX_HWIFS] = { 0 }; /* @@ -132,10 +208,6 @@ static void __init init_hwif_ns87415 (ide_hwif_t *hwif) hwif->autodma = 0; hwif->selectproc = &ns87415_selectproc; - /* Set a good latency timer and cache line size value. */ - (void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); - /* FIXME: use pci_set_master() to ensure good latency timer value */ - /* * We cannot probe for IRQ: both ports share common IRQ on INTA. * Also, leave IRQ masked during drive probing, to prevent infinite @@ -205,6 +277,9 @@ static void __init init_hwif_ns87415 (ide_hwif_t *hwif) static ide_pci_device_t ns87415_chipset __devinitdata = { .name = "NS87415", +#ifdef CONFIG_SUPERIO + .init_iops = init_iops_ns87415, +#endif .init_hwif = init_hwif_ns87415, .channels = 2, .autodma = AUTODMA, diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index e3b48785e5fa..17089f3eb350 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c @@ -871,12 +871,11 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) * the MMIO layout isnt the same as the the standard port * based I/O */ - + memset(&hw, 0, sizeof(hw_regs_t)); - hw.priv = addr; - base = (unsigned long)addr; - if(ch) + base = (unsigned long)addr; + if (ch) base += 0xC0; else base += 0x80; @@ -901,16 +900,16 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) hw.io_ports[IDE_IRQ_OFFSET] = 0; - if (pdev_is_sata(dev)) { - base = (unsigned long) addr; - if(ch) - base += 0x80; - hw.sata_scr[SATA_STATUS_OFFSET] = base + 0x104; - hw.sata_scr[SATA_ERROR_OFFSET] = base + 0x108; - hw.sata_scr[SATA_CONTROL_OFFSET]= base + 0x100; - hw.sata_misc[SATA_MISC_OFFSET] = base + 0x140; - hw.sata_misc[SATA_PHY_OFFSET] = base + 0x144; - hw.sata_misc[SATA_IEN_OFFSET] = base + 0x148; + if (pdev_is_sata(dev)) { + base = (unsigned long)addr; + if (ch) + base += 0x80; + hwif->sata_scr[SATA_STATUS_OFFSET] = base + 0x104; + hwif->sata_scr[SATA_ERROR_OFFSET] = base + 0x108; + hwif->sata_scr[SATA_CONTROL_OFFSET] = base + 0x100; + hwif->sata_misc[SATA_MISC_OFFSET] = base + 0x140; + hwif->sata_misc[SATA_PHY_OFFSET] = base + 0x144; + hwif->sata_misc[SATA_IEN_OFFSET] = base + 0x148; } hw.irq = hwif->pci_dev->irq; @@ -918,11 +917,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) memcpy(&hwif->hw, &hw, sizeof(hw)); memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports)); - if (is_sata(hwif)) { - memcpy(hwif->sata_scr, hwif->hw.sata_scr, sizeof(hwif->hw.sata_scr)); - memcpy(hwif->sata_misc, hwif->hw.sata_misc, sizeof(hwif->hw.sata_misc)); - } - hwif->irq = hw.irq; base = (unsigned long) addr; @@ -961,6 +955,22 @@ static int is_dev_seagate_sata(ide_drive_t *drive) } /** + * siimage_fixup - post probe fixups + * @hwif: interface to fix up + * + * Called after drive probe we use this to decide whether the + * Seagate fixup must be applied. This used to be in init_iops but + * that can occur before we know what drives are present. + */ + +static void __devinit siimage_fixup(ide_hwif_t *hwif) +{ + /* Try and raise the rqsize */ + if (!is_sata(hwif) || !is_dev_seagate_sata(&hwif->drives[0])) + hwif->rqsize = 128; +} + +/** * init_iops_siimage - set up iops * @hwif: interface to set up * @@ -980,9 +990,8 @@ static void __devinit init_iops_siimage(ide_hwif_t *hwif) hwif->hwif_data = NULL; - hwif->rqsize = 128; - if (is_sata(hwif) && is_dev_seagate_sata(&hwif->drives[0])) - hwif->rqsize = 15; + /* Pessimal until we finish probing */ + hwif->rqsize = 15; if (pci_get_drvdata(dev) == NULL) return; @@ -1070,6 +1079,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) .init_chipset = init_chipset_siimage, \ .init_iops = init_iops_siimage, \ .init_hwif = init_hwif_siimage, \ + .fixup = siimage_fixup, \ .channels = 2, \ .autodma = AUTODMA, \ .bootable = ON_BOARD, \ diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 126c51dc2925..5ccb60e40839 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -707,9 +707,9 @@ void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d) ata_index_t index_list = do_ide_setup_pci_device(dev, d, 1); if ((index_list.b.low & 0xf0) != 0xf0) - probe_hwif_init(&ide_hwifs[index_list.b.low]); + probe_hwif_init_with_fixup(&ide_hwifs[index_list.b.low], d->fixup); if ((index_list.b.high & 0xf0) != 0xf0) - probe_hwif_init(&ide_hwifs[index_list.b.high]); + probe_hwif_init_with_fixup(&ide_hwifs[index_list.b.high], d->fixup); create_proc_ide_interfaces(); } diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c index fa8cff3df391..0c74918fe254 100644 --- a/drivers/input/mouse/pc110pad.c +++ b/drivers/input/mouse/pc110pad.c @@ -38,6 +38,7 @@ #include <linux/input.h> #include <linux/init.h> #include <linux/interrupt.h> +#include <linux/pci.h> #include <asm/io.h> #include <asm/irq.h> @@ -107,8 +108,22 @@ static int pc110pad_open(struct input_dev *dev) return 0; } +/* + * We try to avoid enabling the hardware if it's not + * there, but we don't know how to test. But we do know + * that the PC110 is not a PCI system. So if we find any + * PCI devices in the machine, we don't have a PC110. + */ static int __init pc110pad_init(void) { + struct pci_dev *dev; + + dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL); + if (dev) { + pci_dev_put(dev); + return -ENOENT; + } + if (!request_region(pc110pad_io, 4, "pc110pad")) { printk(KERN_ERR "pc110pad: I/O area %#x-%#x in use.\n", pc110pad_io, pc110pad_io + 4); diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 76eed9178615..1e22dbd9433f 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -219,8 +219,8 @@ config VIDEO_ZR36120 module will be called zr36120. config VIDEO_MEYE - tristate "Sony Vaio Picturebook Motion Eye Video For Linux (EXPERIMENTAL)" - depends on VIDEO_DEV && SONYPI && !HIGHMEM64G + tristate "Sony Vaio Picturebook Motion Eye Video For Linux" + depends on VIDEO_DEV && PCI && SONYPI && !HIGHMEM64G ---help--- This is the video4linux driver for the Motion Eye camera found in the Vaio Picturebook laptops. Please read the material in diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 7174fc934c6b..2a00c1ccf202 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c @@ -1,7 +1,7 @@ -/* +/* * Motion Eye video4linux driver for Sony Vaio PictureBook * - * Copyright (C) 2001-2003 Stelian Pop <stelian@popies.net> + * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net> * * Copyright (C) 2001-2002 Alcôve <www.alcove.com> * @@ -11,17 +11,17 @@ * * Some parts borrowed from various video4linux drivers, especially * bttv-driver.c and zoran.c, see original files for credits. - * + * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -39,91 +39,50 @@ #include <linux/vmalloc.h> #include "meye.h" -#include "linux/meye.h" +#include <linux/meye.h> + +MODULE_AUTHOR("Stelian Pop <stelian@popies.net>"); +MODULE_DESCRIPTION("v4l/v4l2 driver for the MotionEye camera"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(MEYE_DRIVER_VERSION); + +/* force usage of V4L1 API */ +static int forcev4l1; /* = 0 */ +module_param(forcev4l1, int, 0644); +MODULE_PARM_DESC(forcev4l1, "force use of V4L1 instead of V4L2"); -/* driver structure - only one possible */ -static struct meye meye; /* number of grab buffers */ static unsigned int gbuffers = 2; +module_param(gbuffers, int, 0444); +MODULE_PARM_DESC(gbuffers, "number of capture buffers, default is 2 (32 max)"); + /* size of a grab buffer */ static unsigned int gbufsize = MEYE_MAX_BUFSIZE; +module_param(gbufsize, int, 0444); +MODULE_PARM_DESC(gbufsize, "size of the capture buffers, default is 614400" + " (will be rounded up to a page multiple)"); + /* /dev/videoX registration number */ static int video_nr = -1; +module_param(video_nr, int, 0444); +MODULE_PARM_DESC(video_nr, "video device to register (0=/dev/video0, etc)"); -/****************************************************************************/ -/* Queue routines */ -/****************************************************************************/ - -/* Inits the queue */ -static inline void meye_initq(struct meye_queue *queue) { - queue->head = queue->tail = 0; - queue->len = 0; - queue->s_lock = SPIN_LOCK_UNLOCKED; - init_waitqueue_head(&queue->proc_list); -} - -/* Pulls an element from the queue */ -static inline int meye_pullq(struct meye_queue *queue) { - int result; - unsigned long flags; - - spin_lock_irqsave(&queue->s_lock, flags); - if (!queue->len) { - spin_unlock_irqrestore(&queue->s_lock, flags); - return -1; - } - result = queue->buf[queue->head]; - queue->head++; - queue->head &= (MEYE_QUEUE_SIZE - 1); - queue->len--; - spin_unlock_irqrestore(&queue->s_lock, flags); - return result; -} - -/* Pushes an element into the queue */ -static inline void meye_pushq(struct meye_queue *queue, int element) { - unsigned long flags; - - spin_lock_irqsave(&queue->s_lock, flags); - if (queue->len == MEYE_QUEUE_SIZE) { - /* remove the first element */ - queue->head++; - queue->head &= (MEYE_QUEUE_SIZE - 1); - queue->len--; - } - queue->buf[queue->tail] = element; - queue->tail++; - queue->tail &= (MEYE_QUEUE_SIZE - 1); - queue->len++; - - spin_unlock_irqrestore(&queue->s_lock, flags); -} - -/* Tests if the queue is empty */ -static inline int meye_emptyq(struct meye_queue *queue, int *elem) { - int result; - unsigned long flags; - - spin_lock_irqsave(&queue->s_lock, flags); - result = (queue->len == 0); - if (!result && elem) - *elem = queue->buf[queue->head]; - spin_unlock_irqrestore(&queue->s_lock, flags); - return result; -} +/* driver structure - only one possible */ +static struct meye meye; /****************************************************************************/ /* Memory allocation routines (stolen from bttv-driver.c) */ /****************************************************************************/ -static void *rvmalloc(unsigned long size) { +static void *rvmalloc(unsigned long size) +{ void *mem; unsigned long adr; size = PAGE_ALIGN(size); mem = vmalloc_32(size); if (mem) { - memset(mem, 0, size); /* Clear the ram out, no junk to the user */ - adr = (unsigned long)mem; + memset(mem, 0, size); + adr = (unsigned long) mem; while (size > 0) { SetPageReserved(vmalloc_to_page((void *)adr)); adr += PAGE_SIZE; @@ -133,11 +92,12 @@ static void *rvmalloc(unsigned long size) { return mem; } -static void rvfree(void * mem, unsigned long size) { - unsigned long adr; +static void rvfree(void * mem, unsigned long size) +{ + unsigned long adr; if (mem) { - adr = (unsigned long) mem; + adr = (unsigned long) mem; while ((long) size > 0) { ClearPageReserved(vmalloc_to_page((void *)adr)); adr += PAGE_SIZE; @@ -156,7 +116,8 @@ static void rvfree(void * mem, unsigned long size) { * dma_addr_t for correctness but the compilation of this driver is * disabled for HIGHMEM64G=y, where sizeof(dma_addr_t) != 4 */ -static int ptable_alloc(void) { +static int ptable_alloc(void) +{ dma_addr_t *pt; int i; @@ -173,7 +134,7 @@ static int ptable_alloc(void) { pt = meye.mchip_ptable_toc; for (i = 0; i < MCHIP_NB_PAGES; i++) { - meye.mchip_ptable[i] = dma_alloc_coherent(&meye.mchip_dev->dev, + meye.mchip_ptable[i] = dma_alloc_coherent(&meye.mchip_dev->dev, PAGE_SIZE, pt, GFP_KERNEL); @@ -199,22 +160,23 @@ static int ptable_alloc(void) { return 0; } -static void ptable_free(void) { +static void ptable_free(void) +{ dma_addr_t *pt; int i; pt = meye.mchip_ptable_toc; for (i = 0; i < MCHIP_NB_PAGES; i++) { if (meye.mchip_ptable[i]) - dma_free_coherent(&meye.mchip_dev->dev, - PAGE_SIZE, + dma_free_coherent(&meye.mchip_dev->dev, + PAGE_SIZE, meye.mchip_ptable[i], *pt); pt++; } if (meye.mchip_ptable_toc) - dma_free_coherent(&meye.mchip_dev->dev, - PAGE_SIZE, + dma_free_coherent(&meye.mchip_dev->dev, + PAGE_SIZE, meye.mchip_ptable_toc, meye.mchip_dmahandle); @@ -224,9 +186,10 @@ static void ptable_free(void) { } /* copy data from ptable into buf */ -static void ptable_copy(u8 *buf, int start, int size, int pt_pages) { +static void ptable_copy(u8 *buf, int start, int size, int pt_pages) +{ int i; - + for (i = 0; i < (size / PAGE_SIZE) * PAGE_SIZE; i += PAGE_SIZE) { memcpy(buf + i, meye.mchip_ptable[start++], PAGE_SIZE); if (start >= pt_pages) @@ -235,224 +198,193 @@ static void ptable_copy(u8 *buf, int start, int size, int pt_pages) { memcpy(buf + i, meye.mchip_ptable[start], size % PAGE_SIZE); } - /****************************************************************************/ /* JPEG tables at different qualities to load into the VRJ chip */ /****************************************************************************/ /* return a set of quantisation tables based on a quality from 1 to 10 */ -static u16 *jpeg_quantisation_tables(int *size, int quality) { - static u16 tables0[] = { - 0xdbff, 0x4300, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, - 0xdbff, 0x4300, 0xff01, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, - }; - static u16 tables1[] = { - 0xdbff, 0x4300, 0x5000, 0x3c37, 0x3c46, 0x5032, 0x4146, 0x5a46, - 0x5055, 0x785f, 0x82c8, 0x6e78, 0x786e, 0xaff5, 0x91b9, 0xffc8, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, - 0xdbff, 0x4300, 0x5501, 0x5a5a, 0x6978, 0xeb78, 0x8282, 0xffeb, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, - 0xffff, 0xffff, 0xffff, - }; - static u16 tables2[] = { - 0xdbff, 0x4300, 0x2800, 0x1e1c, 0x1e23, 0x2819, 0x2123, 0x2d23, - 0x282b, 0x3c30, 0x4164, 0x373c, 0x3c37, 0x587b, 0x495d, 0x9164, - 0x9980, 0x8f96, 0x8c80, 0xa08a, 0xe6b4, 0xa0c3, 0xdaaa, 0x8aad, - 0xc88c, 0xcbff, 0xeeda, 0xfff5, 0xffff, 0xc19b, 0xffff, 0xfaff, - 0xe6ff, 0xfffd, 0xfff8, - 0xdbff, 0x4300, 0x2b01, 0x2d2d, 0x353c, 0x763c, 0x4141, 0xf876, - 0x8ca5, 0xf8a5, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, - 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, - 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, - 0xf8f8, 0xf8f8, 0xfff8, - }; - static u16 tables3[] = { - 0xdbff, 0x4300, 0x1b00, 0x1412, 0x1417, 0x1b11, 0x1617, 0x1e17, - 0x1b1c, 0x2820, 0x2b42, 0x2528, 0x2825, 0x3a51, 0x303d, 0x6042, - 0x6555, 0x5f64, 0x5d55, 0x6a5b, 0x9978, 0x6a81, 0x9071, 0x5b73, - 0x855d, 0x86b5, 0x9e90, 0xaba3, 0xabad, 0x8067, 0xc9bc, 0xa6ba, - 0x99c7, 0xaba8, 0xffa4, - 0xdbff, 0x4300, 0x1c01, 0x1e1e, 0x2328, 0x4e28, 0x2b2b, 0xa44e, - 0x5d6e, 0xa46e, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, - 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, - 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, - 0xa4a4, 0xa4a4, 0xffa4, - }; - static u16 tables4[] = { - 0xdbff, 0x4300, 0x1400, 0x0f0e, 0x0f12, 0x140d, 0x1012, 0x1712, - 0x1415, 0x1e18, 0x2132, 0x1c1e, 0x1e1c, 0x2c3d, 0x242e, 0x4932, - 0x4c40, 0x474b, 0x4640, 0x5045, 0x735a, 0x5062, 0x6d55, 0x4556, - 0x6446, 0x6588, 0x776d, 0x817b, 0x8182, 0x604e, 0x978d, 0x7d8c, - 0x7396, 0x817e, 0xff7c, - 0xdbff, 0x4300, 0x1501, 0x1717, 0x1a1e, 0x3b1e, 0x2121, 0x7c3b, - 0x4653, 0x7c53, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, - 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, - 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, - 0x7c7c, 0x7c7c, 0xff7c, - }; - static u16 tables5[] = { - 0xdbff, 0x4300, 0x1000, 0x0c0b, 0x0c0e, 0x100a, 0x0d0e, 0x120e, - 0x1011, 0x1813, 0x1a28, 0x1618, 0x1816, 0x2331, 0x1d25, 0x3a28, - 0x3d33, 0x393c, 0x3833, 0x4037, 0x5c48, 0x404e, 0x5744, 0x3745, - 0x5038, 0x516d, 0x5f57, 0x6762, 0x6768, 0x4d3e, 0x7971, 0x6470, - 0x5c78, 0x6765, 0xff63, - 0xdbff, 0x4300, 0x1101, 0x1212, 0x1518, 0x2f18, 0x1a1a, 0x632f, - 0x3842, 0x6342, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, - 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, - 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, - 0x6363, 0x6363, 0xff63, - }; - static u16 tables6[] = { - 0xdbff, 0x4300, 0x0d00, 0x0a09, 0x0a0b, 0x0d08, 0x0a0b, 0x0e0b, - 0x0d0e, 0x130f, 0x1520, 0x1213, 0x1312, 0x1c27, 0x171e, 0x2e20, - 0x3129, 0x2e30, 0x2d29, 0x332c, 0x4a3a, 0x333e, 0x4636, 0x2c37, - 0x402d, 0x4157, 0x4c46, 0x524e, 0x5253, 0x3e32, 0x615a, 0x505a, - 0x4a60, 0x5251, 0xff4f, - 0xdbff, 0x4300, 0x0e01, 0x0e0e, 0x1113, 0x2613, 0x1515, 0x4f26, - 0x2d35, 0x4f35, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, - 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, - 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, - 0x4f4f, 0x4f4f, 0xff4f, - }; - static u16 tables7[] = { - 0xdbff, 0x4300, 0x0a00, 0x0707, 0x0708, 0x0a06, 0x0808, 0x0b08, - 0x0a0a, 0x0e0b, 0x1018, 0x0d0e, 0x0e0d, 0x151d, 0x1116, 0x2318, - 0x251f, 0x2224, 0x221f, 0x2621, 0x372b, 0x262f, 0x3429, 0x2129, - 0x3022, 0x3141, 0x3934, 0x3e3b, 0x3e3e, 0x2e25, 0x4944, 0x3c43, - 0x3748, 0x3e3d, 0xff3b, - 0xdbff, 0x4300, 0x0a01, 0x0b0b, 0x0d0e, 0x1c0e, 0x1010, 0x3b1c, - 0x2228, 0x3b28, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, - 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, - 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, - 0x3b3b, 0x3b3b, 0xff3b, - }; - static u16 tables8[] = { - 0xdbff, 0x4300, 0x0600, 0x0504, 0x0506, 0x0604, 0x0506, 0x0706, - 0x0607, 0x0a08, 0x0a10, 0x090a, 0x0a09, 0x0e14, 0x0c0f, 0x1710, - 0x1814, 0x1718, 0x1614, 0x1a16, 0x251d, 0x1a1f, 0x231b, 0x161c, - 0x2016, 0x202c, 0x2623, 0x2927, 0x292a, 0x1f19, 0x302d, 0x282d, - 0x2530, 0x2928, 0xff28, - 0xdbff, 0x4300, 0x0701, 0x0707, 0x080a, 0x130a, 0x0a0a, 0x2813, - 0x161a, 0x281a, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, - 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, - 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, - 0x2828, 0x2828, 0xff28, - }; - static u16 tables9[] = { - 0xdbff, 0x4300, 0x0300, 0x0202, 0x0203, 0x0302, 0x0303, 0x0403, - 0x0303, 0x0504, 0x0508, 0x0405, 0x0504, 0x070a, 0x0607, 0x0c08, - 0x0c0a, 0x0b0c, 0x0b0a, 0x0d0b, 0x120e, 0x0d10, 0x110e, 0x0b0e, - 0x100b, 0x1016, 0x1311, 0x1514, 0x1515, 0x0f0c, 0x1817, 0x1416, - 0x1218, 0x1514, 0xff14, - 0xdbff, 0x4300, 0x0301, 0x0404, 0x0405, 0x0905, 0x0505, 0x1409, - 0x0b0d, 0x140d, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, - 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, - 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, - 0x1414, 0x1414, 0xff14, - }; - static u16 tables10[] = { - 0xdbff, 0x4300, 0x0100, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, - 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, - 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, - 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, - 0x0101, 0x0101, 0xff01, - 0xdbff, 0x4300, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, - 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, - 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, - 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, - 0x0101, 0x0101, 0xff01, - }; - - switch (quality) { - case 0: - *size = sizeof(tables0); - return tables0; - case 1: - *size = sizeof(tables1); - return tables1; - case 2: - *size = sizeof(tables2); - return tables2; - case 3: - *size = sizeof(tables3); - return tables3; - case 4: - *size = sizeof(tables4); - return tables4; - case 5: - *size = sizeof(tables5); - return tables5; - case 6: - *size = sizeof(tables6); - return tables6; - case 7: - *size = sizeof(tables7); - return tables7; - case 8: - *size = sizeof(tables8); - return tables8; - case 9: - *size = sizeof(tables9); - return tables9; - case 10: - *size = sizeof(tables10); - return tables10; - default: - printk(KERN_WARNING "meye: invalid quality level %d - using 8\n", quality); - *size = sizeof(tables8); - return tables8; +static u16 *jpeg_quantisation_tables(int *length, int quality) +{ + static u16 jpeg_tables[][70] = { { + 0xdbff, 0x4300, 0xff00, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, + 0xdbff, 0x4300, 0xff01, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, + }, + { + 0xdbff, 0x4300, 0x5000, 0x3c37, 0x3c46, 0x5032, 0x4146, 0x5a46, + 0x5055, 0x785f, 0x82c8, 0x6e78, 0x786e, 0xaff5, 0x91b9, 0xffc8, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, + 0xdbff, 0x4300, 0x5501, 0x5a5a, 0x6978, 0xeb78, 0x8282, 0xffeb, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, + }, + { + 0xdbff, 0x4300, 0x2800, 0x1e1c, 0x1e23, 0x2819, 0x2123, 0x2d23, + 0x282b, 0x3c30, 0x4164, 0x373c, 0x3c37, 0x587b, 0x495d, 0x9164, + 0x9980, 0x8f96, 0x8c80, 0xa08a, 0xe6b4, 0xa0c3, 0xdaaa, 0x8aad, + 0xc88c, 0xcbff, 0xeeda, 0xfff5, 0xffff, 0xc19b, 0xffff, 0xfaff, + 0xe6ff, 0xfffd, 0xfff8, + 0xdbff, 0x4300, 0x2b01, 0x2d2d, 0x353c, 0x763c, 0x4141, 0xf876, + 0x8ca5, 0xf8a5, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, + 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, + 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, 0xf8f8, + 0xf8f8, 0xf8f8, 0xfff8, + }, + { + 0xdbff, 0x4300, 0x1b00, 0x1412, 0x1417, 0x1b11, 0x1617, 0x1e17, + 0x1b1c, 0x2820, 0x2b42, 0x2528, 0x2825, 0x3a51, 0x303d, 0x6042, + 0x6555, 0x5f64, 0x5d55, 0x6a5b, 0x9978, 0x6a81, 0x9071, 0x5b73, + 0x855d, 0x86b5, 0x9e90, 0xaba3, 0xabad, 0x8067, 0xc9bc, 0xa6ba, + 0x99c7, 0xaba8, 0xffa4, + 0xdbff, 0x4300, 0x1c01, 0x1e1e, 0x2328, 0x4e28, 0x2b2b, 0xa44e, + 0x5d6e, 0xa46e, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, + 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, + 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, + 0xa4a4, 0xa4a4, 0xffa4, + }, + { + 0xdbff, 0x4300, 0x1400, 0x0f0e, 0x0f12, 0x140d, 0x1012, 0x1712, + 0x1415, 0x1e18, 0x2132, 0x1c1e, 0x1e1c, 0x2c3d, 0x242e, 0x4932, + 0x4c40, 0x474b, 0x4640, 0x5045, 0x735a, 0x5062, 0x6d55, 0x4556, + 0x6446, 0x6588, 0x776d, 0x817b, 0x8182, 0x604e, 0x978d, 0x7d8c, + 0x7396, 0x817e, 0xff7c, + 0xdbff, 0x4300, 0x1501, 0x1717, 0x1a1e, 0x3b1e, 0x2121, 0x7c3b, + 0x4653, 0x7c53, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, + 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, + 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, 0x7c7c, + 0x7c7c, 0x7c7c, 0xff7c, + }, + { + 0xdbff, 0x4300, 0x1000, 0x0c0b, 0x0c0e, 0x100a, 0x0d0e, 0x120e, + 0x1011, 0x1813, 0x1a28, 0x1618, 0x1816, 0x2331, 0x1d25, 0x3a28, + 0x3d33, 0x393c, 0x3833, 0x4037, 0x5c48, 0x404e, 0x5744, 0x3745, + 0x5038, 0x516d, 0x5f57, 0x6762, 0x6768, 0x4d3e, 0x7971, 0x6470, + 0x5c78, 0x6765, 0xff63, + 0xdbff, 0x4300, 0x1101, 0x1212, 0x1518, 0x2f18, 0x1a1a, 0x632f, + 0x3842, 0x6342, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, + 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, + 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, 0x6363, + 0x6363, 0x6363, 0xff63, + }, + { + 0xdbff, 0x4300, 0x0d00, 0x0a09, 0x0a0b, 0x0d08, 0x0a0b, 0x0e0b, + 0x0d0e, 0x130f, 0x1520, 0x1213, 0x1312, 0x1c27, 0x171e, 0x2e20, + 0x3129, 0x2e30, 0x2d29, 0x332c, 0x4a3a, 0x333e, 0x4636, 0x2c37, + 0x402d, 0x4157, 0x4c46, 0x524e, 0x5253, 0x3e32, 0x615a, 0x505a, + 0x4a60, 0x5251, 0xff4f, + 0xdbff, 0x4300, 0x0e01, 0x0e0e, 0x1113, 0x2613, 0x1515, 0x4f26, + 0x2d35, 0x4f35, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, + 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, + 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, 0x4f4f, + 0x4f4f, 0x4f4f, 0xff4f, + }, + { + 0xdbff, 0x4300, 0x0a00, 0x0707, 0x0708, 0x0a06, 0x0808, 0x0b08, + 0x0a0a, 0x0e0b, 0x1018, 0x0d0e, 0x0e0d, 0x151d, 0x1116, 0x2318, + 0x251f, 0x2224, 0x221f, 0x2621, 0x372b, 0x262f, 0x3429, 0x2129, + 0x3022, 0x3141, 0x3934, 0x3e3b, 0x3e3e, 0x2e25, 0x4944, 0x3c43, + 0x3748, 0x3e3d, 0xff3b, + 0xdbff, 0x4300, 0x0a01, 0x0b0b, 0x0d0e, 0x1c0e, 0x1010, 0x3b1c, + 0x2228, 0x3b28, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, + 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, + 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, 0x3b3b, + 0x3b3b, 0x3b3b, 0xff3b, + }, + { + 0xdbff, 0x4300, 0x0600, 0x0504, 0x0506, 0x0604, 0x0506, 0x0706, + 0x0607, 0x0a08, 0x0a10, 0x090a, 0x0a09, 0x0e14, 0x0c0f, 0x1710, + 0x1814, 0x1718, 0x1614, 0x1a16, 0x251d, 0x1a1f, 0x231b, 0x161c, + 0x2016, 0x202c, 0x2623, 0x2927, 0x292a, 0x1f19, 0x302d, 0x282d, + 0x2530, 0x2928, 0xff28, + 0xdbff, 0x4300, 0x0701, 0x0707, 0x080a, 0x130a, 0x0a0a, 0x2813, + 0x161a, 0x281a, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, + 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, + 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, 0x2828, + 0x2828, 0x2828, 0xff28, + }, + { + 0xdbff, 0x4300, 0x0300, 0x0202, 0x0203, 0x0302, 0x0303, 0x0403, + 0x0303, 0x0504, 0x0508, 0x0405, 0x0504, 0x070a, 0x0607, 0x0c08, + 0x0c0a, 0x0b0c, 0x0b0a, 0x0d0b, 0x120e, 0x0d10, 0x110e, 0x0b0e, + 0x100b, 0x1016, 0x1311, 0x1514, 0x1515, 0x0f0c, 0x1817, 0x1416, + 0x1218, 0x1514, 0xff14, + 0xdbff, 0x4300, 0x0301, 0x0404, 0x0405, 0x0905, 0x0505, 0x1409, + 0x0b0d, 0x140d, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, + 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, + 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, 0x1414, + 0x1414, 0x1414, 0xff14, + }, + { + 0xdbff, 0x4300, 0x0100, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, + 0x0101, 0x0101, 0xff01, + 0xdbff, 0x4300, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, + 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, + 0x0101, 0x0101, 0xff01, + } }; + + if (quality < 0 || quality > 10) { + printk(KERN_WARNING + "meye: invalid quality level %d - using 8\n", quality); + quality = 8; } - return NULL; + + *length = ARRAY_SIZE(jpeg_tables[quality]); + return jpeg_tables[quality]; } /* return a generic set of huffman tables */ -static u16 *jpeg_huffman_tables(int *size) { +static u16 *jpeg_huffman_tables(int *length) +{ static u16 tables[] = { - 0xC4FF, 0xB500, 0x0010, 0x0102, 0x0303, 0x0402, 0x0503, 0x0405, - 0x0004, 0x0100, 0x017D, 0x0302, 0x0400, 0x0511, 0x2112, 0x4131, - 0x1306, 0x6151, 0x2207, 0x1471, 0x8132, 0xA191, 0x2308, 0xB142, - 0x15C1, 0xD152, 0x24F0, 0x6233, 0x8272, 0x0A09, 0x1716, 0x1918, - 0x251A, 0x2726, 0x2928, 0x342A, 0x3635, 0x3837, 0x3A39, 0x4443, - 0x4645, 0x4847, 0x4A49, 0x5453, 0x5655, 0x5857, 0x5A59, 0x6463, - 0x6665, 0x6867, 0x6A69, 0x7473, 0x7675, 0x7877, 0x7A79, 0x8483, - 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, 0xA29A, - 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, 0xB9B8, - 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, 0xD7D6, - 0xD9D8, 0xE1DA, 0xE3E2, 0xE5E4, 0xE7E6, 0xE9E8, 0xF1EA, 0xF3F2, - 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA, - 0xC4FF, 0xB500, 0x0011, 0x0102, 0x0402, 0x0304, 0x0704, 0x0405, - 0x0004, 0x0201, 0x0077, 0x0201, 0x1103, 0x0504, 0x3121, 0x1206, - 0x5141, 0x6107, 0x1371, 0x3222, 0x0881, 0x4214, 0xA191, 0xC1B1, - 0x2309, 0x5233, 0x15F0, 0x7262, 0x0AD1, 0x2416, 0xE134, 0xF125, - 0x1817, 0x1A19, 0x2726, 0x2928, 0x352A, 0x3736, 0x3938, 0x433A, - 0x4544, 0x4746, 0x4948, 0x534A, 0x5554, 0x5756, 0x5958, 0x635A, - 0x6564, 0x6766, 0x6968, 0x736A, 0x7574, 0x7776, 0x7978, 0x827A, - 0x8483, 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, - 0xA29A, 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, - 0xB9B8, 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, - 0xD7D6, 0xD9D8, 0xE2DA, 0xE4E3, 0xE6E5, 0xE8E7, 0xEAE9, 0xF3F2, - 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA, - 0xC4FF, 0x1F00, 0x0000, 0x0501, 0x0101, 0x0101, 0x0101, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09, - 0xFF0B, - 0xC4FF, 0x1F00, 0x0001, 0x0103, 0x0101, 0x0101, 0x0101, 0x0101, - 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09, + 0xC4FF, 0xB500, 0x0010, 0x0102, 0x0303, 0x0402, 0x0503, 0x0405, + 0x0004, 0x0100, 0x017D, 0x0302, 0x0400, 0x0511, 0x2112, 0x4131, + 0x1306, 0x6151, 0x2207, 0x1471, 0x8132, 0xA191, 0x2308, 0xB142, + 0x15C1, 0xD152, 0x24F0, 0x6233, 0x8272, 0x0A09, 0x1716, 0x1918, + 0x251A, 0x2726, 0x2928, 0x342A, 0x3635, 0x3837, 0x3A39, 0x4443, + 0x4645, 0x4847, 0x4A49, 0x5453, 0x5655, 0x5857, 0x5A59, 0x6463, + 0x6665, 0x6867, 0x6A69, 0x7473, 0x7675, 0x7877, 0x7A79, 0x8483, + 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, 0xA29A, + 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, 0xB9B8, + 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, 0xD7D6, + 0xD9D8, 0xE1DA, 0xE3E2, 0xE5E4, 0xE7E6, 0xE9E8, 0xF1EA, 0xF3F2, + 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA, + 0xC4FF, 0xB500, 0x0011, 0x0102, 0x0402, 0x0304, 0x0704, 0x0405, + 0x0004, 0x0201, 0x0077, 0x0201, 0x1103, 0x0504, 0x3121, 0x1206, + 0x5141, 0x6107, 0x1371, 0x3222, 0x0881, 0x4214, 0xA191, 0xC1B1, + 0x2309, 0x5233, 0x15F0, 0x7262, 0x0AD1, 0x2416, 0xE134, 0xF125, + 0x1817, 0x1A19, 0x2726, 0x2928, 0x352A, 0x3736, 0x3938, 0x433A, + 0x4544, 0x4746, 0x4948, 0x534A, 0x5554, 0x5756, 0x5958, 0x635A, + 0x6564, 0x6766, 0x6968, 0x736A, 0x7574, 0x7776, 0x7978, 0x827A, + 0x8483, 0x8685, 0x8887, 0x8A89, 0x9392, 0x9594, 0x9796, 0x9998, + 0xA29A, 0xA4A3, 0xA6A5, 0xA8A7, 0xAAA9, 0xB3B2, 0xB5B4, 0xB7B6, + 0xB9B8, 0xC2BA, 0xC4C3, 0xC6C5, 0xC8C7, 0xCAC9, 0xD3D2, 0xD5D4, + 0xD7D6, 0xD9D8, 0xE2DA, 0xE4E3, 0xE6E5, 0xE8E7, 0xEAE9, 0xF3F2, + 0xF5F4, 0xF7F6, 0xF9F8, 0xFFFA, + 0xC4FF, 0x1F00, 0x0000, 0x0501, 0x0101, 0x0101, 0x0101, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09, + 0xFF0B, + 0xC4FF, 0x1F00, 0x0001, 0x0103, 0x0101, 0x0101, 0x0101, 0x0101, + 0x0000, 0x0000, 0x0000, 0x0201, 0x0403, 0x0605, 0x0807, 0x0A09, 0xFF0B }; - *size = sizeof(tables); + *length = ARRAY_SIZE(tables); return tables; } @@ -461,23 +393,27 @@ static u16 *jpeg_huffman_tables(int *size) { /****************************************************************************/ /* returns the horizontal capture size */ -static inline int mchip_hsize(void) { +static inline int mchip_hsize(void) +{ return meye.params.subsample ? 320 : 640; } /* returns the vertical capture size */ -static inline int mchip_vsize(void) { +static inline int mchip_vsize(void) +{ return meye.params.subsample ? 240 : 480; } /* waits for a register to be available */ -static void mchip_sync(int reg) { +static void mchip_sync(int reg) +{ u32 status; int i; if (reg == MCHIP_MM_FIFO_DATA) { for (i = 0; i < MCHIP_REG_TIMEOUT; i++) { - status = readl(meye.mchip_mmregs + MCHIP_MM_FIFO_STATUS); + status = readl(meye.mchip_mmregs + + MCHIP_MM_FIFO_STATUS); if (!(status & MCHIP_MM_FIFO_WAIT)) { printk(KERN_WARNING "meye: fifo not ready\n"); return; @@ -486,44 +422,48 @@ static void mchip_sync(int reg) { return; udelay(1); } - } - else if (reg > 0x80) { + } else if (reg > 0x80) { u32 mask = (reg < 0x100) ? MCHIP_HIC_STATUS_MCC_RDY - : MCHIP_HIC_STATUS_VRJ_RDY; + : MCHIP_HIC_STATUS_VRJ_RDY; for (i = 0; i < MCHIP_REG_TIMEOUT; i++) { status = readl(meye.mchip_mmregs + MCHIP_HIC_STATUS); if (status & mask) return; udelay(1); } - } - else + } else return; - printk(KERN_WARNING "meye: mchip_sync() timeout on reg 0x%x status=0x%x\n", reg, status); + printk(KERN_WARNING + "meye: mchip_sync() timeout on reg 0x%x status=0x%x\n", + reg, status); } /* sets a value into the register */ -static inline void mchip_set(int reg, u32 v) { +static inline void mchip_set(int reg, u32 v) +{ mchip_sync(reg); writel(v, meye.mchip_mmregs + reg); } /* get the register value */ -static inline u32 mchip_read(int reg) { +static inline u32 mchip_read(int reg) +{ mchip_sync(reg); return readl(meye.mchip_mmregs + reg); } /* wait for a register to become a particular value */ -static inline int mchip_delay(u32 reg, u32 v) { +static inline int mchip_delay(u32 reg, u32 v) +{ int n = 10; - while (--n && mchip_read(reg) != v) + while (--n && mchip_read(reg) != v) udelay(1); return n; } /* setup subsampling */ -static void mchip_subsample(void) { +static void mchip_subsample(void) +{ mchip_set(MCHIP_MCC_R_SAMPLING, meye.params.subsample); mchip_set(MCHIP_MCC_R_XRANGE, mchip_hsize()); mchip_set(MCHIP_MCC_R_YRANGE, mchip_vsize()); @@ -533,29 +473,31 @@ static void mchip_subsample(void) { } /* set the framerate into the mchip */ -static void mchip_set_framerate(void) { +static void mchip_set_framerate(void) +{ mchip_set(MCHIP_HIC_S_RATE, meye.params.framerate); } /* load some huffman and quantisation tables into the VRJ chip ready for JPEG compression */ -static void mchip_load_tables(void) { +static void mchip_load_tables(void) +{ int i; - int size; + int length; u16 *tables; - tables = jpeg_huffman_tables(&size); - for (i = 0; i < size / 2; i++) + tables = jpeg_huffman_tables(&length); + for (i = 0; i < length; i++) writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA); - tables = jpeg_quantisation_tables(&size, meye.params.quality); - for (i = 0; i < size / 2; i++) + tables = jpeg_quantisation_tables(&length, meye.params.quality); + for (i = 0; i < length; i++) writel(tables[i], meye.mchip_mmregs + MCHIP_VRJ_TABLE_DATA); } /* setup the VRJ parameters in the chip */ -static void mchip_vrj_setup(u8 mode) { - +static void mchip_vrj_setup(u8 mode) +{ mchip_set(MCHIP_VRJ_BUS_MODE, 5); mchip_set(MCHIP_VRJ_SIGNAL_ACTIVE_LEVEL, 0x1f); mchip_set(MCHIP_VRJ_PDAT_USE, 1); @@ -572,13 +514,14 @@ static void mchip_vrj_setup(u8 mode) { mchip_set(MCHIP_VRJ_SOF2, 0x1502); mchip_set(MCHIP_VRJ_SOF3, 0x1503); mchip_set(MCHIP_VRJ_SOF4, 0x1596); - mchip_set(MCHIP_VRJ_SOS, 0x0ed0); + mchip_set(MCHIP_VRJ_SOS, 0x0ed0); mchip_load_tables(); } /* sets the DMA parameters into the chip */ -static void mchip_dma_setup(u32 dma_addr) { +static void mchip_dma_setup(u32 dma_addr) +{ int i; mchip_set(MCHIP_MM_PT_ADDR, dma_addr); @@ -588,7 +531,8 @@ static void mchip_dma_setup(u32 dma_addr) { } /* setup for DMA transfers - also zeros the framebuffer */ -static int mchip_dma_alloc(void) { +static int mchip_dma_alloc(void) +{ if (!meye.mchip_dmahandle) if (ptable_alloc()) return -1; @@ -596,7 +540,8 @@ static int mchip_dma_alloc(void) { } /* frees the DMA buffer */ -static void mchip_dma_free(void) { +static void mchip_dma_free(void) +{ if (meye.mchip_dmahandle) { mchip_dma_setup(0); ptable_free(); @@ -605,7 +550,8 @@ static void mchip_dma_free(void) { /* stop any existing HIC action and wait for any dma to complete then reset the dma engine */ -static void mchip_hic_stop(void) { +static void mchip_hic_stop(void) +{ int i, j; meye.mchip_mode = MCHIP_HIC_MODE_NOOP; @@ -615,12 +561,13 @@ static void mchip_hic_stop(void) { mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_STOP); mchip_delay(MCHIP_HIC_CMD, 0); for (j = 0; j < 100; ++j) { - if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE)) + if (mchip_delay(MCHIP_HIC_STATUS, + MCHIP_HIC_STATUS_IDLE)) return; msleep(1); } printk(KERN_ERR "meye: need to reset HIC!\n"); - + mchip_set(MCHIP_HIC_CTL, MCHIP_HIC_CTL_SOFT_RESET); msleep(250); } @@ -632,15 +579,17 @@ static void mchip_hic_stop(void) { /****************************************************************************/ /* get the next ready frame from the dma engine */ -static u32 mchip_get_frame(void) { +static u32 mchip_get_frame(void) +{ u32 v; - + v = mchip_read(MCHIP_MM_FIR(meye.mchip_fnum)); return v; } /* frees the current frame from the dma engine */ -static void mchip_free_frame(void) { +static void mchip_free_frame(void) +{ mchip_set(MCHIP_MM_FIR(meye.mchip_fnum), 0); meye.mchip_fnum++; meye.mchip_fnum %= 4; @@ -648,17 +597,18 @@ static void mchip_free_frame(void) { /* read one frame from the framebuffer assuming it was captured using a uncompressed transfer */ -static void mchip_cont_read_frame(u32 v, u8 *buf, int size) { +static void mchip_cont_read_frame(u32 v, u8 *buf, int size) +{ int pt_id; pt_id = (v >> 17) & 0x3FF; ptable_copy(buf, pt_id, size, MCHIP_NB_PAGES); - } /* read a compressed frame from the framebuffer */ -static int mchip_comp_read_frame(u32 v, u8 *buf, int size) { +static int mchip_comp_read_frame(u32 v, u8 *buf, int size) +{ int pt_start, pt_end, trailer; int fsize; int i; @@ -674,18 +624,17 @@ static int mchip_comp_read_frame(u32 v, u8 *buf, int size) { fsize = (pt_end - pt_start) * PAGE_SIZE + trailer * 4; if (fsize > size) { - printk(KERN_WARNING "meye: oversized compressed frame %d\n", + printk(KERN_WARNING "meye: oversized compressed frame %d\n", fsize); return -1; } ptable_copy(buf, pt_start, fsize, MCHIP_NB_PAGES_MJPEG); - #ifdef MEYE_JPEG_CORRECTION /* Some mchip generated jpeg frames are incorrect. In most - * (all ?) of those cases, the final EOI (0xff 0xd9) marker + * (all ?) of those cases, the final EOI (0xff 0xd9) marker * is not present at the end of the frame. * * Since adding the final marker is not enough to restore @@ -703,9 +652,10 @@ static int mchip_comp_read_frame(u32 v, u8 *buf, int size) { } /* take a picture into SDRAM */ -static void mchip_take_picture(void) { +static void mchip_take_picture(void) +{ int i; - + mchip_hic_stop(); mchip_subsample(); mchip_dma_setup(meye.mchip_dmahandle); @@ -723,7 +673,8 @@ static void mchip_take_picture(void) { } /* dma a previously taken picture into a buffer */ -static void mchip_get_picture(u8 *buf, int bufsize) { +static void mchip_get_picture(u8 *buf, int bufsize) +{ u32 v; int i; @@ -736,7 +687,7 @@ static void mchip_get_picture(u8 *buf, int bufsize) { break; msleep(1); } - for (i = 0; i < 4 ; ++i) { + for (i = 0; i < 4; ++i) { v = mchip_get_frame(); if (v & MCHIP_MM_FIR_RDY) { mchip_cont_read_frame(v, buf, bufsize); @@ -747,7 +698,8 @@ static void mchip_get_picture(u8 *buf, int bufsize) { } /* start continuous dma capture */ -static void mchip_continuous_start(void) { +static void mchip_continuous_start(void) +{ mchip_hic_stop(); mchip_subsample(); mchip_set_framerate(); @@ -762,7 +714,8 @@ static void mchip_continuous_start(void) { } /* compress one frame into a buffer */ -static int mchip_compress_frame(u8 *buf, int bufsize) { +static int mchip_compress_frame(u8 *buf, int bufsize) +{ u32 v; int len = -1, i; @@ -771,7 +724,7 @@ static int mchip_compress_frame(u8 *buf, int bufsize) { mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_COMP); mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START); - + mchip_delay(MCHIP_HIC_CMD, 0); for (i = 0; i < 100; ++i) { if (mchip_delay(MCHIP_HIC_STATUS, MCHIP_HIC_STATUS_IDLE)) @@ -779,7 +732,7 @@ static int mchip_compress_frame(u8 *buf, int bufsize) { msleep(1); } - for (i = 0; i < 4 ; ++i) { + for (i = 0; i < 4; ++i) { v = mchip_get_frame(); if (v & MCHIP_MM_FIR_RDY) { len = mchip_comp_read_frame(v, buf, bufsize); @@ -792,13 +745,14 @@ static int mchip_compress_frame(u8 *buf, int bufsize) { #if 0 /* uncompress one image into a buffer */ -static int mchip_uncompress_frame(u8 *img, int imgsize, u8 *buf, int bufsize) { +static int mchip_uncompress_frame(u8 *img, int imgsize, u8 *buf, int bufsize) +{ mchip_vrj_setup(0x3f); udelay(50); mchip_set(MCHIP_HIC_MODE, MCHIP_HIC_MODE_STILL_DECOMP); mchip_set(MCHIP_HIC_CMD, MCHIP_HIC_CMD_START); - + mchip_delay(MCHIP_HIC_CMD, 0); return mchip_comp_read_frame(buf, bufsize); @@ -806,7 +760,8 @@ static int mchip_uncompress_frame(u8 *img, int imgsize, u8 *buf, int bufsize) { #endif /* start continuous compressed capture */ -static void mchip_cont_compression_start(void) { +static void mchip_cont_compression_start(void) +{ mchip_hic_stop(); mchip_vrj_setup(0x3f); mchip_subsample(); @@ -825,88 +780,100 @@ static void mchip_cont_compression_start(void) { /* Interrupt handling */ /****************************************************************************/ -static irqreturn_t meye_irq(int irq, void *dev_id, struct pt_regs *regs) { +static irqreturn_t meye_irq(int irq, void *dev_id, struct pt_regs *regs) +{ u32 v; int reqnr; + static int sequence = 0; + v = mchip_read(MCHIP_MM_INTA); - while (1) { - v = mchip_get_frame(); - if (!(v & MCHIP_MM_FIR_RDY)) - return IRQ_NONE; - switch (meye.mchip_mode) { + if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT && + meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP) + return IRQ_NONE; - case MCHIP_HIC_MODE_CONT_OUT: - if (!meye_emptyq(&meye.grabq, NULL)) { - int nr = meye_pullq(&meye.grabq); - mchip_cont_read_frame( - v, - meye.grab_fbuffer + gbufsize * nr, - mchip_hsize() * mchip_vsize() * 2); - meye.grab_buffer[nr].state = MEYE_BUF_DONE; - wake_up_interruptible(&meye.grabq.proc_list); - } - break; +again: + v = mchip_get_frame(); + if (!(v & MCHIP_MM_FIR_RDY)) + return IRQ_HANDLED; - case MCHIP_HIC_MODE_CONT_COMP: - if (!meye_emptyq(&meye.grabq, &reqnr)) { - int size; - size = mchip_comp_read_frame( - v, - meye.grab_fbuffer + gbufsize * reqnr, - gbufsize); - if (size == -1) - break; - reqnr = meye_pullq(&meye.grabq); - meye.grab_buffer[reqnr].size = size; - meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; - wake_up_interruptible(&meye.grabq.proc_list); - } - break; - - default: - /* do not free frame, since it can be a snap */ - return IRQ_NONE; - } /* switch */ - - mchip_free_frame(); + if (meye.mchip_mode == MCHIP_HIC_MODE_CONT_OUT) { + if (kfifo_get(meye.grabq, (unsigned char *)&reqnr, + sizeof(int)) != sizeof(int)) { + mchip_free_frame(); + return IRQ_HANDLED; + } + mchip_cont_read_frame(v, meye.grab_fbuffer + gbufsize * reqnr, + mchip_hsize() * mchip_vsize() * 2); + meye.grab_buffer[reqnr].size = mchip_hsize() * mchip_vsize() * 2; + meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; + do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); + meye.grab_buffer[reqnr].sequence = sequence++; + kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int)); + wake_up_interruptible(&meye.proc_list); + } else { + int size; + size = mchip_comp_read_frame(v, meye.grab_temp, gbufsize); + if (size == -1) { + mchip_free_frame(); + goto again; + } + if (kfifo_get(meye.grabq, (unsigned char *)&reqnr, + sizeof(int)) != sizeof(int)) { + mchip_free_frame(); + goto again; + } + memcpy(meye.grab_fbuffer + gbufsize * reqnr, meye.grab_temp, + size); + meye.grab_buffer[reqnr].size = size; + meye.grab_buffer[reqnr].state = MEYE_BUF_DONE; + do_gettimeofday(&meye.grab_buffer[reqnr].timestamp); + meye.grab_buffer[reqnr].sequence = sequence++; + kfifo_put(meye.doneq, (unsigned char *)&reqnr, sizeof(int)); + wake_up_interruptible(&meye.proc_list); } - return IRQ_HANDLED; + mchip_free_frame(); + goto again; } /****************************************************************************/ /* video4linux integration */ /****************************************************************************/ -static int meye_open(struct inode *inode, struct file *file) { +static int meye_open(struct inode *inode, struct file *file) +{ int i, err; - err = video_exclusive_open(inode,file); + err = video_exclusive_open(inode, file); if (err < 0) return err; - + + mchip_hic_stop(); + if (mchip_dma_alloc()) { printk(KERN_ERR "meye: mchip framebuffer allocation failed\n"); - video_exclusive_release(inode,file); + video_exclusive_release(inode, file); return -ENOBUFS; } - mchip_hic_stop(); - meye_initq(&meye.grabq); + for (i = 0; i < MEYE_MAX_BUFNBRS; i++) meye.grab_buffer[i].state = MEYE_BUF_UNUSED; + kfifo_reset(meye.grabq); + kfifo_reset(meye.doneq); return 0; } -static int meye_release(struct inode *inode, struct file *file) { +static int meye_release(struct inode *inode, struct file *file) +{ mchip_hic_stop(); mchip_dma_free(); - video_exclusive_release(inode,file); + video_exclusive_release(inode, file); return 0; } static int meye_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) { - + unsigned int cmd, void *arg) +{ switch (cmd) { case VIDIOCGCAP: { @@ -948,18 +915,18 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, case VIDIOCSPICT: { struct video_picture *p = arg; - if (p->depth != 2) + if (p->depth != 16) return -EINVAL; if (p->palette != VIDEO_PALETTE_YUV422) return -EINVAL; down(&meye.lock); - sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, + sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, p->brightness >> 10); - sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, + sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, p->hue >> 10); - sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR, + sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR, p->colour >> 10); - sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST, + sonypi_camera_command(SONYPI_COMMAND_SETCAMERACONTRAST, p->contrast >> 10); meye.picture = *p; up(&meye.lock); @@ -968,22 +935,34 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, case VIDIOCSYNC: { int *i = arg; + int unused; if (*i < 0 || *i >= gbuffers) return -EINVAL; + down(&meye.lock); + switch (meye.grab_buffer[*i].state) { case MEYE_BUF_UNUSED: + up(&meye.lock); return -EINVAL; case MEYE_BUF_USING: - if (wait_event_interruptible(meye.grabq.proc_list, - (meye.grab_buffer[*i].state != MEYE_BUF_USING))) + if (file->f_flags & O_NONBLOCK) { + up(&meye.lock); + return -EAGAIN; + } + if (wait_event_interruptible(meye.proc_list, + (meye.grab_buffer[*i].state != MEYE_BUF_USING))) { + up(&meye.lock); return -EINTR; + } /* fall through */ case MEYE_BUF_DONE: meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; + kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); } + up(&meye.lock); break; } @@ -1008,14 +987,12 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, meye.params.subsample = 0; restart = 1; } - } - else if (vm->width == 320 && vm->height == 240) { + } else if (vm->width == 320 && vm->height == 240) { if (!meye.params.subsample) { meye.params.subsample = 1; restart = 1; } - } - else { + } else { up(&meye.lock); return -EINVAL; } @@ -1023,7 +1000,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, if (restart || meye.mchip_mode != MCHIP_HIC_MODE_CONT_OUT) mchip_continuous_start(); meye.grab_buffer[vm->frame].state = MEYE_BUF_USING; - meye_pushq(&meye.grabq, vm->frame); + kfifo_put(meye.grabq, (unsigned char *)&vm->frame, sizeof(int)); up(&meye.lock); break; } @@ -1074,7 +1051,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, case MEYEIOC_QBUF_CAPT: { int *nb = arg; - if (!meye.grab_fbuffer) + if (!meye.grab_fbuffer) return -EINVAL; if (*nb >= gbuffers) return -EINVAL; @@ -1089,36 +1066,47 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, if (meye.mchip_mode != MCHIP_HIC_MODE_CONT_COMP) mchip_cont_compression_start(); meye.grab_buffer[*nb].state = MEYE_BUF_USING; - meye_pushq(&meye.grabq, *nb); + kfifo_put(meye.grabq, (unsigned char *)nb, sizeof(int)); up(&meye.lock); break; } case MEYEIOC_SYNC: { int *i = arg; + int unused; if (*i < 0 || *i >= gbuffers) return -EINVAL; + down(&meye.lock); switch (meye.grab_buffer[*i].state) { case MEYE_BUF_UNUSED: + up(&meye.lock); return -EINVAL; case MEYE_BUF_USING: - if (wait_event_interruptible(meye.grabq.proc_list, - (meye.grab_buffer[*i].state != MEYE_BUF_USING))) + if (file->f_flags & O_NONBLOCK) { + up(&meye.lock); + return -EAGAIN; + } + if (wait_event_interruptible(meye.proc_list, + (meye.grab_buffer[*i].state != MEYE_BUF_USING))) { + up(&meye.lock); return -EINTR; + } /* fall through */ case MEYE_BUF_DONE: meye.grab_buffer[*i].state = MEYE_BUF_UNUSED; + kfifo_get(meye.doneq, (unsigned char *)&unused, sizeof(int)); } *i = meye.grab_buffer[*i].size; + up(&meye.lock); break; } case MEYEIOC_STILLCAPT: { - if (!meye.grab_fbuffer) + if (!meye.grab_fbuffer) return -EINVAL; if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) return -EBUSY; @@ -1136,7 +1124,7 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, case MEYEIOC_STILLJCAPT: { int *len = arg; - if (!meye.grab_fbuffer) + if (!meye.grab_fbuffer) return -EINVAL; if (meye.grab_buffer[0].state != MEYE_BUF_UNUSED) return -EBUSY; @@ -1152,10 +1140,518 @@ static int meye_do_ioctl(struct inode *inode, struct file *file, break; } + case VIDIOC_QUERYCAP: { + struct v4l2_capability *cap = arg; + + if (forcev4l1) + return -EINVAL; + + memset(cap, 0, sizeof(*cap)); + strcpy(cap->driver, "meye"); + strcpy(cap->card, "meye"); + sprintf(cap->bus_info, "PCI:%s", meye.mchip_dev->slot_name); + cap->version = (MEYE_DRIVER_MAJORVERSION << 8) + + MEYE_DRIVER_MINORVERSION; + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_STREAMING; + break; + } + + case VIDIOC_ENUMINPUT: { + struct v4l2_input *i = arg; + + if (i->index != 0) + return -EINVAL; + memset(i, 0, sizeof(*i)); + i->index = 0; + strcpy(i->name, "Camera"); + i->type = V4L2_INPUT_TYPE_CAMERA; + break; + } + + case VIDIOC_G_INPUT: { + int *i = arg; + + *i = 0; + break; + } + + case VIDIOC_S_INPUT: { + int *i = arg; + + if (*i != 0) + return -EINVAL; + break; + } + + case VIDIOC_QUERYCTRL: { + struct v4l2_queryctrl *c = arg; + + switch (c->id) { + + case V4L2_CID_BRIGHTNESS: + c->type = V4L2_CTRL_TYPE_INTEGER; + strcpy(c->name, "Brightness"); + c->minimum = 0; + c->maximum = 63; + c->step = 1; + c->default_value = 32; + c->flags = 0; + break; + case V4L2_CID_HUE: + c->type = V4L2_CTRL_TYPE_INTEGER; + strcpy(c->name, "Hue"); + c->minimum = 0; + c->maximum = 63; + c->step = 1; + c->default_value = 32; + c->flags = 0; + break; + case V4L2_CID_CONTRAST: + c->type = V4L2_CTRL_TYPE_INTEGER; + strcpy(c->name, "Contrast"); + c->minimum = 0; + c->maximum = 63; + c->step = 1; + c->default_value = 32; + c->flags = 0; + break; + case V4L2_CID_SATURATION: + c->type = V4L2_CTRL_TYPE_INTEGER; + strcpy(c->name, "Saturation"); + c->minimum = 0; + c->maximum = 63; + c->step = 1; + c->default_value = 32; + c->flags = 0; + break; + case V4L2_CID_AGC: + c->type = V4L2_CTRL_TYPE_INTEGER; + strcpy(c->name, "Agc"); + c->minimum = 0; + c->maximum = 63; + c->step = 1; + c->default_value = 48; + c->flags = 0; + break; + case V4L2_CID_SHARPNESS: + c->type = V4L2_CTRL_TYPE_INTEGER; + strcpy(c->name, "Sharpness"); + c->minimum = 0; + c->maximum = 63; + c->step = 1; + c->default_value = 32; + c->flags = 0; + break; + case V4L2_CID_PICTURE: + c->type = V4L2_CTRL_TYPE_INTEGER; + strcpy(c->name, "Picture"); + c->minimum = 0; + c->maximum = 63; + c->step = 1; + c->default_value = 0; + c->flags = 0; + break; + case V4L2_CID_JPEGQUAL: + c->type = V4L2_CTRL_TYPE_INTEGER; + strcpy(c->name, "JPEG quality"); + c->minimum = 0; + c->maximum = 10; + c->step = 1; + c->default_value = 8; + c->flags = 0; + break; + case V4L2_CID_FRAMERATE: + c->type = V4L2_CTRL_TYPE_INTEGER; + strcpy(c->name, "Framerate"); + c->minimum = 0; + c->maximum = 31; + c->step = 1; + c->default_value = 0; + c->flags = 0; + break; + default: + return -EINVAL; + } + break; + } + + case VIDIOC_S_CTRL: { + struct v4l2_control *c = arg; + + down(&meye.lock); + switch (c->id) { + case V4L2_CID_BRIGHTNESS: + sonypi_camera_command( + SONYPI_COMMAND_SETCAMERABRIGHTNESS, c->value); + meye.picture.brightness = c->value << 10; + break; + case V4L2_CID_HUE: + sonypi_camera_command( + SONYPI_COMMAND_SETCAMERAHUE, c->value); + meye.picture.hue = c->value << 10; + break; + case V4L2_CID_CONTRAST: + sonypi_camera_command( + SONYPI_COMMAND_SETCAMERACONTRAST, c->value); + meye.picture.contrast = c->value << 10; + break; + case V4L2_CID_SATURATION: + sonypi_camera_command( + SONYPI_COMMAND_SETCAMERACOLOR, c->value); + meye.picture.colour = c->value << 10; + break; + case V4L2_CID_AGC: + sonypi_camera_command( + SONYPI_COMMAND_SETCAMERAAGC, c->value); + meye.params.agc = c->value; + break; + case V4L2_CID_SHARPNESS: + sonypi_camera_command( + SONYPI_COMMAND_SETCAMERASHARPNESS, c->value); + meye.params.sharpness = c->value; + break; + case V4L2_CID_PICTURE: + sonypi_camera_command( + SONYPI_COMMAND_SETCAMERAPICTURE, c->value); + meye.params.picture = c->value; + break; + case V4L2_CID_JPEGQUAL: + meye.params.quality = c->value; + break; + case V4L2_CID_FRAMERATE: + meye.params.framerate = c->value; + break; + default: + up(&meye.lock); + return -EINVAL; + } + up(&meye.lock); + break; + } + + case VIDIOC_G_CTRL: { + struct v4l2_control *c = arg; + + down(&meye.lock); + switch (c->id) { + case V4L2_CID_BRIGHTNESS: + c->value = meye.picture.brightness >> 10; + break; + case V4L2_CID_HUE: + c->value = meye.picture.hue >> 10; + break; + case V4L2_CID_CONTRAST: + c->value = meye.picture.contrast >> 10; + break; + case V4L2_CID_SATURATION: + c->value = meye.picture.colour >> 10; + break; + case V4L2_CID_AGC: + c->value = meye.params.agc; + break; + case V4L2_CID_SHARPNESS: + c->value = meye.params.sharpness; + break; + case V4L2_CID_PICTURE: + c->value = meye.params.picture; + break; + case V4L2_CID_JPEGQUAL: + c->value = meye.params.quality; + break; + case V4L2_CID_FRAMERATE: + c->value = meye.params.framerate; + break; + default: + up(&meye.lock); + return -EINVAL; + } + up(&meye.lock); + break; + } + + case VIDIOC_ENUM_FMT: { + struct v4l2_fmtdesc *f = arg; + + if (f->index > 1) + return -EINVAL; + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (f->index == 0) { + /* standard YUV 422 capture */ + memset(f, 0, sizeof(*f)); + f->index = 0; + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + f->flags = 0; + strcpy(f->description, "YUV422"); + f->pixelformat = V4L2_PIX_FMT_YUYV; + } else { + /* compressed MJPEG capture */ + memset(f, 0, sizeof(*f)); + f->index = 1; + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + f->flags = V4L2_FMT_FLAG_COMPRESSED; + strcpy(f->description, "MJPEG"); + f->pixelformat = V4L2_PIX_FMT_MJPEG; + } + break; + } + + case VIDIOC_TRY_FMT: { + struct v4l2_format *f = arg; + + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV && + f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) + return -EINVAL; + if (f->fmt.pix.field != V4L2_FIELD_ANY && + f->fmt.pix.field != V4L2_FIELD_NONE) + return -EINVAL; + f->fmt.pix.field = V4L2_FIELD_NONE; + if (f->fmt.pix.width <= 320) { + f->fmt.pix.width = 320; + f->fmt.pix.height = 240; + } else { + f->fmt.pix.width = 640; + f->fmt.pix.height = 480; + } + f->fmt.pix.bytesperline = f->fmt.pix.width * 2; + f->fmt.pix.sizeimage = f->fmt.pix.height * + f->fmt.pix.bytesperline; + f->fmt.pix.colorspace = 0; + f->fmt.pix.priv = 0; + break; + } + + case VIDIOC_G_FMT: { + struct v4l2_format *f = arg; + + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format)); + f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + switch (meye.mchip_mode) { + case MCHIP_HIC_MODE_CONT_OUT: + default: + f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; + break; + case MCHIP_HIC_MODE_CONT_COMP: + f->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; + break; + } + f->fmt.pix.field = V4L2_FIELD_NONE; + f->fmt.pix.width = mchip_hsize(); + f->fmt.pix.height = mchip_vsize(); + f->fmt.pix.bytesperline = f->fmt.pix.width * 2; + f->fmt.pix.sizeimage = f->fmt.pix.height * + f->fmt.pix.bytesperline; + f->fmt.pix.colorspace = 0; + f->fmt.pix.priv = 0; + break; + } + + case VIDIOC_S_FMT: { + struct v4l2_format *f = arg; + + if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV && + f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG) + return -EINVAL; + if (f->fmt.pix.field != V4L2_FIELD_ANY && + f->fmt.pix.field != V4L2_FIELD_NONE) + return -EINVAL; + f->fmt.pix.field = V4L2_FIELD_NONE; + down(&meye.lock); + if (f->fmt.pix.width <= 320) { + f->fmt.pix.width = 320; + f->fmt.pix.height = 240; + meye.params.subsample = 1; + } else { + f->fmt.pix.width = 640; + f->fmt.pix.height = 480; + meye.params.subsample = 0; + } + switch (f->fmt.pix.pixelformat) { + case V4L2_PIX_FMT_YUYV: + meye.mchip_mode = MCHIP_HIC_MODE_CONT_OUT; + break; + case V4L2_PIX_FMT_MJPEG: + meye.mchip_mode = MCHIP_HIC_MODE_CONT_COMP; + break; + } + up(&meye.lock); + f->fmt.pix.bytesperline = f->fmt.pix.width * 2; + f->fmt.pix.sizeimage = f->fmt.pix.height * + f->fmt.pix.bytesperline; + f->fmt.pix.colorspace = 0; + f->fmt.pix.priv = 0; + + break; + } + + case VIDIOC_REQBUFS: { + struct v4l2_requestbuffers *req = arg; + int i; + + if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (req->memory != V4L2_MEMORY_MMAP) + return -EINVAL; + if (meye.grab_fbuffer && req->count == gbuffers) { + /* already allocated, no modifications */ + break; + } + down(&meye.lock); + if (meye.grab_fbuffer) { + for (i = 0; i < gbuffers; i++) + if (meye.vma_use_count[i]) { + up(&meye.lock); + return -EINVAL; + } + rvfree(meye.grab_fbuffer, gbuffers * gbufsize); + meye.grab_fbuffer = NULL; + } + gbuffers = max(2, min((int)req->count, MEYE_MAX_BUFNBRS)); + req->count = gbuffers; + meye.grab_fbuffer = rvmalloc(gbuffers * gbufsize); + if (!meye.grab_fbuffer) { + printk(KERN_ERR "meye: v4l framebuffer allocation" + " failed\n"); + up(&meye.lock); + return -ENOMEM; + } + for (i = 0; i < gbuffers; i++) + meye.vma_use_count[i] = 0; + up(&meye.lock); + break; + } + + case VIDIOC_QUERYBUF: { + struct v4l2_buffer *buf = arg; + int index = buf->index; + + if (index < 0 || index >= gbuffers) + return -EINVAL; + memset(buf, 0, sizeof(*buf)); + buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf->index = index; + buf->bytesused = meye.grab_buffer[index].size; + buf->flags = V4L2_BUF_FLAG_MAPPED; + if (meye.grab_buffer[index].state == MEYE_BUF_USING) + buf->flags |= V4L2_BUF_FLAG_QUEUED; + if (meye.grab_buffer[index].state == MEYE_BUF_DONE) + buf->flags |= V4L2_BUF_FLAG_DONE; + buf->field = V4L2_FIELD_NONE; + buf->timestamp = meye.grab_buffer[index].timestamp; + buf->sequence = meye.grab_buffer[index].sequence; + buf->memory = V4L2_MEMORY_MMAP; + buf->m.offset = index * gbufsize; + buf->length = gbufsize; + break; + } + + case VIDIOC_QBUF: { + struct v4l2_buffer *buf = arg; + + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (buf->memory != V4L2_MEMORY_MMAP) + return -EINVAL; + if (buf->index < 0 || buf->index >= gbuffers) + return -EINVAL; + if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED) + return -EINVAL; + down(&meye.lock); + buf->flags |= V4L2_BUF_FLAG_QUEUED; + buf->flags &= ~V4L2_BUF_FLAG_DONE; + meye.grab_buffer[buf->index].state = MEYE_BUF_USING; + kfifo_put(meye.grabq, (unsigned char *)&buf->index, sizeof(int)); + up(&meye.lock); + break; + } + + case VIDIOC_DQBUF: { + struct v4l2_buffer *buf = arg; + int reqnr; + + if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + if (buf->memory != V4L2_MEMORY_MMAP) + return -EINVAL; + + down(&meye.lock); + if (kfifo_len(meye.doneq) == 0 && file->f_flags & O_NONBLOCK) { + up(&meye.lock); + return -EAGAIN; + } + if (wait_event_interruptible(meye.proc_list, + kfifo_len(meye.doneq) != 0) < 0) { + up(&meye.lock); + return -EINTR; + } + if (!kfifo_get(meye.doneq, (unsigned char *)&reqnr, + sizeof(int))) { + up(&meye.lock); + return -EBUSY; + } + if (meye.grab_buffer[reqnr].state != MEYE_BUF_DONE) { + up(&meye.lock); + return -EINVAL; + } + buf->index = reqnr; + buf->bytesused = meye.grab_buffer[reqnr].size; + buf->flags = V4L2_BUF_FLAG_MAPPED; + buf->field = V4L2_FIELD_NONE; + buf->timestamp = meye.grab_buffer[reqnr].timestamp; + buf->sequence = meye.grab_buffer[reqnr].sequence; + buf->memory = V4L2_MEMORY_MMAP; + buf->m.offset = reqnr * gbufsize; + buf->length = gbufsize; + meye.grab_buffer[reqnr].state = MEYE_BUF_UNUSED; + up(&meye.lock); + break; + } + + case VIDIOC_STREAMON: { + down(&meye.lock); + switch (meye.mchip_mode) { + case MCHIP_HIC_MODE_CONT_OUT: + mchip_continuous_start(); + break; + case MCHIP_HIC_MODE_CONT_COMP: + mchip_cont_compression_start(); + break; + default: + up(&meye.lock); + return -EINVAL; + } + up(&meye.lock); + break; + } + + case VIDIOC_STREAMOFF: { + int i; + + down(&meye.lock); + mchip_hic_stop(); + kfifo_reset(meye.grabq); + kfifo_reset(meye.doneq); + for (i = 0; i < MEYE_MAX_BUFNBRS; i++) + meye.grab_buffer[i].state = MEYE_BUF_UNUSED; + up(&meye.lock); + break; + } + + /* + * XXX what about private snapshot ioctls ? + * Do they need to be converted to V4L2 ? + */ + default: return -ENOIOCTLCMD; - - } /* switch */ + } return 0; } @@ -1166,9 +1662,40 @@ static int meye_ioctl(struct inode *inode, struct file *file, return video_usercopy(inode, file, cmd, arg, meye_do_ioctl); } -static int meye_mmap(struct file *file, struct vm_area_struct *vma) { +static unsigned int meye_poll(struct file *file, poll_table *wait) +{ + unsigned int res = 0; + + down(&meye.lock); + poll_wait(file, &meye.proc_list, wait); + if (kfifo_len(meye.doneq)) + res = POLLIN | POLLRDNORM; + up(&meye.lock); + return res; +} + +static void meye_vm_open(struct vm_area_struct *vma) +{ + int idx = (int)vma->vm_private_data; + meye.vma_use_count[idx]++; +} + +static void meye_vm_close(struct vm_area_struct *vma) +{ + int idx = (int)vma->vm_private_data; + meye.vma_use_count[idx]--; +} + +static struct vm_operations_struct meye_vm_ops = { + .open = meye_vm_open, + .close = meye_vm_close, +}; + +static int meye_mmap(struct file *file, struct vm_area_struct *vma) +{ unsigned long start = vma->vm_start; - unsigned long size = vma->vm_end - vma->vm_start; + unsigned long size = vma->vm_end - vma->vm_start; + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; unsigned long page, pos; down(&meye.lock); @@ -1177,6 +1704,8 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) { return -EINVAL; } if (!meye.grab_fbuffer) { + int i; + /* lazy allocation */ meye.grab_fbuffer = rvmalloc(gbuffers*gbufsize); if (!meye.grab_fbuffer) { @@ -1184,8 +1713,10 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) { up(&meye.lock); return -ENOMEM; } + for (i = 0; i < gbuffers; i++) + meye.vma_use_count[i] = 0; } - pos = (unsigned long)meye.grab_fbuffer; + pos = (unsigned long)meye.grab_fbuffer + offset; while (size > 0) { page = vmalloc_to_pfn((void *)pos); @@ -1195,8 +1726,18 @@ static int meye_mmap(struct file *file, struct vm_area_struct *vma) { } start += PAGE_SIZE; pos += PAGE_SIZE; - size -= PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; } + + vma->vm_ops = &meye_vm_ops; + vma->vm_flags &= ~VM_IO; /* not I/O memory */ + vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ + vma->vm_private_data = (void *) (offset / gbufsize); + meye_vm_open(vma); + up(&meye.lock); return 0; } @@ -1207,6 +1748,7 @@ static struct file_operations meye_fops = { .release = meye_release, .mmap = meye_mmap, .ioctl = meye_ioctl, + .poll = meye_poll, .llseek = no_llseek, }; @@ -1256,70 +1798,88 @@ static int meye_resume(struct pci_dev *pdev) } #endif -static int __devinit meye_probe(struct pci_dev *pcidev, - const struct pci_device_id *ent) { - int ret; +static int __devinit meye_probe(struct pci_dev *pcidev, + const struct pci_device_id *ent) +{ + int ret = -EBUSY; unsigned long mchip_adr; u8 revision; if (meye.mchip_dev != NULL) { printk(KERN_ERR "meye: only one device allowed!\n"); - ret = -EBUSY; - goto out1; + goto outnotdev; } meye.mchip_dev = pcidev; meye.video_dev = video_device_alloc(); if (!meye.video_dev) { printk(KERN_ERR "meye: video_device_alloc() failed!\n"); - ret = -EBUSY; - goto out1; + goto outnotdev; + } + + ret = -ENOMEM; + meye.grab_temp = vmalloc(MCHIP_NB_PAGES_MJPEG * PAGE_SIZE); + if (!meye.grab_temp) { + printk(KERN_ERR "meye: grab buffer allocation failed\n"); + goto outvmalloc; } + + meye.grabq_lock = SPIN_LOCK_UNLOCKED; + meye.grabq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, + &meye.grabq_lock); + if (IS_ERR(meye.grabq)) { + printk(KERN_ERR "meye: fifo allocation failed\n"); + goto outkfifoalloc1; + } + meye.doneq_lock = SPIN_LOCK_UNLOCKED; + meye.doneq = kfifo_alloc(sizeof(int) * MEYE_MAX_BUFNBRS, GFP_KERNEL, + &meye.doneq_lock); + if (IS_ERR(meye.doneq)) { + printk(KERN_ERR "meye: fifo allocation failed\n"); + goto outkfifoalloc2; + } + memcpy(meye.video_dev, &meye_template, sizeof(meye_template)); meye.video_dev->dev = &meye.mchip_dev->dev; sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 1); + ret = -EIO; if ((ret = pci_enable_device(meye.mchip_dev))) { printk(KERN_ERR "meye: pci_enable_device failed\n"); - goto out2; + goto outenabledev; } - meye.mchip_irq = pcidev->irq; mchip_adr = pci_resource_start(meye.mchip_dev,0); if (!mchip_adr) { printk(KERN_ERR "meye: mchip has no device base address\n"); - ret = -EIO; - goto out3; + goto outregions; } if (!request_mem_region(pci_resource_start(meye.mchip_dev, 0), - pci_resource_len(meye.mchip_dev, 0), + pci_resource_len(meye.mchip_dev, 0), "meye")) { - ret = -EIO; printk(KERN_ERR "meye: request_mem_region failed\n"); - goto out3; + goto outregions; + } + meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS); + if (!meye.mchip_mmregs) { + printk(KERN_ERR "meye: ioremap failed\n"); + goto outremap; } - pci_read_config_byte(meye.mchip_dev, PCI_REVISION_ID, &revision); - - pci_set_master(meye.mchip_dev); + meye.mchip_irq = pcidev->irq; + if (request_irq(meye.mchip_irq, meye_irq, + SA_INTERRUPT | SA_SHIRQ, "meye", meye_irq)) { + printk(KERN_ERR "meye: request_irq failed\n"); + goto outreqirq; + } + pci_read_config_byte(meye.mchip_dev, PCI_REVISION_ID, &revision); pci_write_config_byte(meye.mchip_dev, PCI_CACHE_LINE_SIZE, 8); pci_write_config_byte(meye.mchip_dev, PCI_LATENCY_TIMER, 64); - if ((ret = request_irq(meye.mchip_irq, meye_irq, - SA_INTERRUPT | SA_SHIRQ, "meye", meye_irq))) { - printk(KERN_ERR "meye: request_irq failed (ret=%d)\n", ret); - goto out4; - } + pci_set_master(meye.mchip_dev); - meye.mchip_mmregs = ioremap(mchip_adr, MCHIP_MM_REGS); - if (!meye.mchip_mmregs) { - printk(KERN_ERR "meye: ioremap failed\n"); - ret = -EIO; - goto out5; - } - /* Ask the camera to perform a soft reset. */ pci_write_config_word(meye.mchip_dev, MCHIP_PCI_SOFTRESET_SET, 1); @@ -1335,23 +1895,15 @@ static int __devinit meye_probe(struct pci_dev *pcidev, msleep(1); mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); - if (video_register_device(meye.video_dev, VFL_TYPE_GRABBER, video_nr) < 0) { - + if (video_register_device(meye.video_dev, VFL_TYPE_GRABBER, + video_nr) < 0) { printk(KERN_ERR "meye: video_register_device failed\n"); - ret = -EIO; - goto out6; + goto outvideoreg; } - - printk(KERN_INFO "meye: Motion Eye Camera Driver v%d.%d.\n", - MEYE_DRIVER_MAJORVERSION, - MEYE_DRIVER_MINORVERSION); - printk(KERN_INFO "meye: mchip KL5A72002 rev. %d, base %lx, irq %d\n", - revision, mchip_adr, meye.mchip_irq); - /* init all fields */ init_MUTEX(&meye.lock); - - meye.picture.depth = 2; + init_waitqueue_head(&meye.proc_list); + meye.picture.depth = 16; meye.picture.palette = VIDEO_PALETTE_YUV422; meye.picture.brightness = 32 << 10; meye.picture.hue = 32 << 10; @@ -1359,11 +1911,12 @@ static int __devinit meye_probe(struct pci_dev *pcidev, meye.picture.contrast = 32 << 10; meye.picture.whiteness = 0; meye.params.subsample = 0; - meye.params.quality = 7; + meye.params.quality = 8; meye.params.sharpness = 32; meye.params.agc = 48; meye.params.picture = 0; meye.params.framerate = 0; + sonypi_camera_command(SONYPI_COMMAND_SETCAMERABRIGHTNESS, 32); sonypi_camera_command(SONYPI_COMMAND_SETCAMERAHUE, 32); sonypi_camera_command(SONYPI_COMMAND_SETCAMERACOLOR, 32); @@ -1372,27 +1925,37 @@ static int __devinit meye_probe(struct pci_dev *pcidev, sonypi_camera_command(SONYPI_COMMAND_SETCAMERAPICTURE, 0); sonypi_camera_command(SONYPI_COMMAND_SETCAMERAAGC, 48); + printk(KERN_INFO "meye: Motion Eye Camera Driver v%s.\n", + MEYE_DRIVER_VERSION); + printk(KERN_INFO "meye: mchip KL5A72002 rev. %d, base %lx, irq %d\n", + revision, mchip_adr, meye.mchip_irq); + return 0; -out6: - iounmap(meye.mchip_mmregs); -out5: + +outvideoreg: free_irq(meye.mchip_irq, meye_irq); -out4: +outreqirq: + iounmap(meye.mchip_mmregs); +outremap: release_mem_region(pci_resource_start(meye.mchip_dev, 0), pci_resource_len(meye.mchip_dev, 0)); -out3: +outregions: pci_disable_device(meye.mchip_dev); -out2: - video_device_release(meye.video_dev); - meye.video_dev = NULL; - +outenabledev: sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0); -out1: + kfifo_free(meye.doneq); +outkfifoalloc2: + kfifo_free(meye.grabq); +outkfifoalloc1: + vfree(meye.grab_temp); +outvmalloc: + video_device_release(meye.video_dev); +outnotdev: return ret; } -static void __devexit meye_remove(struct pci_dev *pcidev) { - +static void __devexit meye_remove(struct pci_dev *pcidev) +{ video_unregister_device(meye.video_dev); mchip_hic_stop(); @@ -1411,16 +1974,23 @@ static void __devexit meye_remove(struct pci_dev *pcidev) { pci_disable_device(meye.mchip_dev); - if (meye.grab_fbuffer) - rvfree(meye.grab_fbuffer, gbuffers*gbufsize); - sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 0); + kfifo_free(meye.doneq); + kfifo_free(meye.grabq); + + vfree(meye.grab_temp); + + if (meye.grab_fbuffer) { + rvfree(meye.grab_fbuffer, gbuffers*gbufsize); + meye.grab_fbuffer = NULL; + } + printk(KERN_INFO "meye: removed\n"); } static struct pci_device_id meye_pci_tbl[] = { - { PCI_VENDOR_ID_KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002, + { PCI_VENDOR_ID_KAWASAKI, PCI_DEVICE_ID_MCHIP_KL5A72002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { } }; @@ -1438,54 +2008,23 @@ static struct pci_driver meye_driver = { #endif }; -static int __init meye_init_module(void) { - if (gbuffers < 2) - gbuffers = 2; - if (gbuffers > MEYE_MAX_BUFNBRS) - gbuffers = MEYE_MAX_BUFNBRS; +static int __init meye_init(void) +{ + gbuffers = max(2, min((int)gbuffers, MEYE_MAX_BUFNBRS)); if (gbufsize < 0 || gbufsize > MEYE_MAX_BUFSIZE) gbufsize = MEYE_MAX_BUFSIZE; - printk(KERN_INFO "meye: using %d buffers with %dk (%dk total) for capture\n", - gbuffers, gbufsize/1024, gbuffers*gbufsize/1024); - return pci_module_init(&meye_driver); + gbufsize = PAGE_ALIGN(gbufsize); + printk(KERN_INFO "meye: using %d buffers with %dk (%dk total)" + "for capture\n", + gbuffers, + gbufsize / 1024, gbuffers * gbufsize / 1024); + return pci_register_driver(&meye_driver); } -static void __exit meye_cleanup_module(void) { +static void __exit meye_exit(void) +{ pci_unregister_driver(&meye_driver); } -#ifndef MODULE -static int __init meye_setup(char *str) { - int ints[4]; - - str = get_options(str, ARRAY_SIZE(ints), ints); - if (ints[0] <= 0) - goto out; - gbuffers = ints[1]; - if (ints[0] == 1) - goto out; - gbufsize = ints[2]; - if (ints[0] == 2) - goto out; - video_nr = ints[3]; -out: - return 1; -} - -__setup("meye=", meye_setup); -#endif - -MODULE_AUTHOR("Stelian Pop <stelian@popies.net>"); -MODULE_DESCRIPTION("video4linux driver for the MotionEye camera"); -MODULE_LICENSE("GPL"); - -MODULE_PARM(gbuffers,"i"); -MODULE_PARM_DESC(gbuffers,"number of capture buffers, default is 2 (32 max)"); -MODULE_PARM(gbufsize,"i"); -MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 614400"); -MODULE_PARM(video_nr,"i"); -MODULE_PARM_DESC(video_nr,"video device to register (0=/dev/video0, etc)"); - -/* Module entry points */ -module_init(meye_init_module); -module_exit(meye_cleanup_module); +module_init(meye_init); +module_exit(meye_exit); diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h index f5a40345d1c8..102318086772 100644 --- a/drivers/media/video/meye.h +++ b/drivers/media/video/meye.h @@ -1,27 +1,27 @@ -/* +/* * Motion Eye video4linux driver for Sony Vaio PictureBook * - * Copyright (C) 2001-2003 Stelian Pop <stelian@popies.net> + * Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net> * * Copyright (C) 2001-2002 Alcôve <www.alcove.com> * * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com> * * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras. - * + * * Some parts borrowed from various video4linux drivers, especially * bttv-driver.c and zoran.c, see original files for credits. - * + * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -30,12 +30,16 @@ #ifndef _MEYE_PRIV_H_ #define _MEYE_PRIV_H_ -#define MEYE_DRIVER_MAJORVERSION 1 -#define MEYE_DRIVER_MINORVERSION 10 +#define MEYE_DRIVER_MAJORVERSION 1 +#define MEYE_DRIVER_MINORVERSION 11 + +#define MEYE_DRIVER_VERSION __stringify(MEYE_DRIVER_MAJORVERSION) "." \ + __stringify(MEYE_DRIVER_MINORVERSION) #include <linux/config.h> #include <linux/types.h> #include <linux/pci.h> +#include <linux/kfifo.h> /****************************************************************************/ /* Motion JPEG chip registers */ @@ -43,7 +47,7 @@ /* Motion JPEG chip PCI configuration registers */ #define MCHIP_PCI_POWER_CSR 0x54 -#define MCHIP_PCI_MCORE_STATUS 0x60 /* see HIC_STATUS */ +#define MCHIP_PCI_MCORE_STATUS 0x60 /* see HIC_STATUS */ #define MCHIP_PCI_HOSTUSEREQ_SET 0x64 #define MCHIP_PCI_HOSTUSEREQ_CLR 0x68 #define MCHIP_PCI_LOWPOWER_SET 0x6c @@ -73,7 +77,7 @@ #define MCHIP_MM_INTA_PCI_ERR 0x00000040 /* PCI error */ #define MCHIP_MM_INTA_PCI_ERR_MASK 0x00004000 -#define MCHIP_MM_PT_ADDR 0x08 /* page table address */ +#define MCHIP_MM_PT_ADDR 0x08 /* page table address*/ /* n*4kB */ #define MCHIP_NB_PAGES 1024 /* pages for display */ #define MCHIP_NB_PAGES_MJPEG 256 /* pages for mjpeg */ @@ -275,42 +279,34 @@ struct meye_grab_buffer { int state; /* state of buffer */ unsigned long size; /* size of jpg frame */ + struct timeval timestamp; /* timestamp */ + unsigned long sequence; /* sequence number */ }; -/* queues containing the buffer indices */ +/* size of kfifos containings buffer indices */ #define MEYE_QUEUE_SIZE MEYE_MAX_BUFNBRS -struct meye_queue { - unsigned int head; /* queue head */ - unsigned int tail; /* queue tail */ - unsigned int len; /* queue length */ - spinlock_t s_lock; /* spinlock protecting the queue */ - wait_queue_head_t proc_list; /* wait queue */ - int buf[MEYE_QUEUE_SIZE]; /* queue contents */ -}; /* Motion Eye device structure */ struct meye { - - /* mchip related */ struct pci_dev *mchip_dev; /* pci device */ u8 mchip_irq; /* irq */ u8 mchip_mode; /* actual mchip mode: HIC_MODE... */ u8 mchip_fnum; /* current mchip frame number */ - unsigned char *mchip_mmregs; /* mchip: memory mapped registers */ u8 *mchip_ptable[MCHIP_NB_PAGES];/* mchip: ptable */ dma_addr_t *mchip_ptable_toc; /* mchip: ptable toc */ dma_addr_t mchip_dmahandle; /* mchip: dma handle to ptable toc */ - unsigned char *grab_fbuffer; /* capture framebuffer */ + unsigned char *grab_temp; /* temporary buffer */ /* list of buffers */ struct meye_grab_buffer grab_buffer[MEYE_MAX_BUFNBRS]; - - /* other */ + int vma_use_count[MEYE_MAX_BUFNBRS]; /* mmap count */ struct semaphore lock; /* semaphore for open/mmap... */ - - struct meye_queue grabq; /* queue for buffers to be grabbed */ - + struct kfifo *grabq; /* queue for buffers to be grabbed */ + spinlock_t grabq_lock; /* lock protecting the queue */ + struct kfifo *doneq; /* queue for grabbed buffers */ + spinlock_t doneq_lock; /* lock protecting the queue */ + wait_queue_head_t proc_list; /* wait queue */ struct video_device *video_dev; /* video device parameters */ struct video_picture picture; /* video picture parameters */ struct meye_params params; /* additional parameters */ diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index 16d0aee6b412..5c785191bd9f 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c @@ -1,5 +1,5 @@ /* - mxb.c - v4l2 driver for the Multimedia eXtension Board + mxb - v4l2 driver for the Multimedia eXtension Board Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> @@ -43,12 +43,12 @@ static int mxb_num = 0; in verden (lower saxony, germany) 4148 is a channel called "phoenix" */ static int freq = 4148; -MODULE_PARM(freq,"i"); +module_param(freq, int, 0644); MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup"); static int debug = 0; -MODULE_PARM(debug,"i"); -MODULE_PARM_DESC(debug, "debug verbosity"); +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); #define MXB_INPUTS 4 enum { TUNER, AUX1, AUX3, AUX3_YC }; diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index f9805363ca34..cb53427d3fb1 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c @@ -60,7 +60,7 @@ MODULE_LICENSE("GPL"); #include <linux/video_decoder.h> static int debug = 0; -MODULE_PARM(debug, "i"); +module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); #define dprintk(num, format, args...) \ diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index fd8ac116c863..c0438989d28b 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c @@ -1,5 +1,5 @@ /* - tda9840.h - i2c-driver for the tda9840 by SGS Thomson + tda9840 - i2c-driver for the tda9840 by SGS Thomson Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> @@ -8,7 +8,7 @@ For detailed informations download the specifications directly from SGS Thomson at http://www.st.com - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -22,21 +22,19 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ + */ -#include <linux/version.h> #include <linux/module.h> -#include <linux/kernel.h> -#include <linux/poll.h> -#include <linux/slab.h> +#include <linux/ioctl.h> #include <linux/i2c.h> -#include <linux/init.h> #include "tda9840.h" -static int debug = 0; /* insmod parameter */ -MODULE_PARM(debug,"i"); -#define dprintk if (debug) printk +static int debug = 0; /* insmod parameter */ +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); +#define dprintk(args...) \ + do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0) #define SWITCH 0x00 #define LEVEL_ADJUST 0x02 @@ -44,168 +42,146 @@ MODULE_PARM(debug,"i"); #define TEST 0x04 /* addresses to scan, found only at 0x42 (7-Bit) */ -static unsigned short normal_i2c[] = {I2C_TDA9840, I2C_CLIENT_END}; -static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; +static unsigned short normal_i2c[] = { I2C_TDA9840, I2C_CLIENT_END }; +static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; +static struct i2c_driver driver; +static struct i2c_client client_template; + /* unique ID allocation */ static int tda9840_id = 0; -static struct i2c_driver driver; - -static int tda9840_command(struct i2c_client *client, unsigned int cmd, void* arg) +static int command(struct i2c_client *client, unsigned int cmd, void *arg) { - int result = 0; + int result; + int byte = *(int *)arg; switch (cmd) { - case TDA9840_SWITCH: - { - int byte = *(int*)arg; - - dprintk("tda9840.o: TDA9840_SWITCH: 0x%02x\n",byte); - - if ( byte != TDA9840_SET_MONO - && byte != TDA9840_SET_MUTE - && byte != TDA9840_SET_STEREO - && byte != TDA9840_SET_LANG1 - && byte != TDA9840_SET_LANG2 - && byte != TDA9840_SET_BOTH - && byte != TDA9840_SET_BOTH_R - && byte != TDA9840_SET_EXTERNAL ) { - return -EINVAL; - } - - if ( 0 != (result = i2c_smbus_write_byte_data(client, SWITCH, byte))) { - printk("tda9840.o: TDA9840_SWITCH error.\n"); - return -EFAULT; - } - - return 0; + case TDA9840_SWITCH: + + dprintk("TDA9840_SWITCH: 0x%02x\n", byte); + + if (byte != TDA9840_SET_MONO + && byte != TDA9840_SET_MUTE + && byte != TDA9840_SET_STEREO + && byte != TDA9840_SET_LANG1 + && byte != TDA9840_SET_LANG2 + && byte != TDA9840_SET_BOTH + && byte != TDA9840_SET_BOTH_R + && byte != TDA9840_SET_EXTERNAL) { + return -EINVAL; } - case TDA9840_LEVEL_ADJUST: - { - int byte = *(int*)arg; - - dprintk("tda9840.o: TDA9840_LEVEL_ADJUST: %d\n",byte); - - /* check for correct range */ - if ( byte > 25 || byte < -20 ) - return -EINVAL; - - /* calculate actual value to set, see specs, page 18 */ - byte /= 5; - if ( 0 < byte ) - byte += 0x8; - else - byte = -byte; - - if ( 0 != (result = i2c_smbus_write_byte_data(client, LEVEL_ADJUST, byte))) { - printk("tda9840.o: TDA9840_LEVEL_ADJUST error.\n"); - return -EFAULT; - } - - return 0; - } + result = i2c_smbus_write_byte_data(client, SWITCH, byte); + if (result) + dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); + break; - case TDA9840_STEREO_ADJUST: - { - int byte = *(int*)arg; - - dprintk("tda9840.o: TDA9840_STEREO_ADJUST: %d\n",byte); - - /* check for correct range */ - if ( byte > 25 || byte < -24 ) - return -EINVAL; - - /* calculate actual value to set */ - byte /= 5; - if ( 0 < byte ) - byte += 0x20; - else - byte = -byte; - - if ( 0 != (result = i2c_smbus_write_byte_data(client, STEREO_ADJUST, byte))) { - printk("tda9840.o: TDA9840_STEREO_ADJUST error.\n"); - return -EFAULT; - } - - return 0; - } + case TDA9840_LEVEL_ADJUST: - case TDA9840_DETECT: - { - int byte = 0x0; + dprintk("TDA9840_LEVEL_ADJUST: %d\n", byte); - if ( -1 == (byte = i2c_smbus_read_byte_data(client, STEREO_ADJUST))) { - printk("tda9840.o: TDA9840_DETECT error while reading.\n"); - return -EFAULT; - } + /* check for correct range */ + if (byte > 25 || byte < -20) + return -EINVAL; - if( 0 != (byte & 0x80)) { - dprintk("tda9840.o: TDA9840_DETECT, register contents invalid.\n"); - return -EFAULT; - } + /* calculate actual value to set, see specs, page 18 */ + byte /= 5; + if (0 < byte) + byte += 0x8; + else + byte = -byte; - dprintk("tda9840.o: TDA9840_DETECT, result: 0x%02x (original byte)\n",byte); + result = i2c_smbus_write_byte_data(client, LEVEL_ADJUST, byte); + if (result) + dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); + break; - return ((byte & 0x60) >> 5); - } + case TDA9840_STEREO_ADJUST: + + dprintk("TDA9840_STEREO_ADJUST: %d\n", byte); - case TDA9840_TEST: - { - int byte = *(int*)arg; + /* check for correct range */ + if (byte > 25 || byte < -24) + return -EINVAL; - dprintk("tda9840.o: TDA9840_TEST: 0x%02x\n",byte); + /* calculate actual value to set */ + byte /= 5; + if (0 < byte) + byte += 0x20; + else + byte = -byte; - /* mask out irrelevant bits */ - byte &= 0x3; + result = i2c_smbus_write_byte_data(client, STEREO_ADJUST, byte); + if (result) + dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); + break; - if ( 0 != (result = i2c_smbus_write_byte_data(client, TEST, byte))) { - printk("tda9840.o: TDA9840_TEST error.\n"); - return -EFAULT; - } - - return 0; + case TDA9840_DETECT: + + byte = i2c_smbus_read_byte_data(client, STEREO_ADJUST); + if (byte == -1) { + dprintk("i2c_smbus_read_byte_data() failed\n"); + return -EIO; } - default: - return -ENOIOCTLCMD; + if (0 != (byte & 0x80)) { + dprintk("TDA9840_DETECT: register contents invalid\n"); + return -EINVAL; + } + + dprintk("TDA9840_DETECT: byte: 0x%02x\n", byte); + return ((byte & 0x60) >> 5); + + case TDA9840_TEST: + dprintk("TDA9840_TEST: 0x%02x\n", byte); + + /* mask out irrelevant bits */ + byte &= 0x3; + + result = i2c_smbus_write_byte_data(client, TEST, byte); + if (result) + dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result); + break; + default: + return -ENOIOCTLCMD; } + if (result) + return -EIO; + return 0; } -static int tda9840_detect(struct i2c_adapter *adapter, int address, int kind) +static int detect(struct i2c_adapter *adapter, int address, int kind) { - struct i2c_client *client; + struct i2c_client *client; int result = 0; int byte = 0x0; - + /* let's see whether this adapter can support what we need */ - if ( 0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA|I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + if (0 == i2c_check_functionality(adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA | + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { return 0; } /* allocate memory for client structure */ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (0 == client) { - printk("tda9840.o: not enough kernel memory.\n"); + if (0 == client) { + printk("not enough kernel memory\n"); return -ENOMEM; } - memset(client, 0, sizeof(struct i2c_client)); - + /* fill client structure */ - sprintf(client->name,"tda9840 (0x%02x)", address); + memcpy(client, &client_template, sizeof(struct i2c_client)); client->id = tda9840_id++; - client->flags = 0; client->addr = address; client->adapter = adapter; - client->driver = &driver; - i2c_set_clientdata(client, NULL); /* tell the i2c layer a new client has arrived */ if (0 != (result = i2c_attach_client(client))) { @@ -215,71 +191,64 @@ static int tda9840_detect(struct i2c_adapter *adapter, int address, int kind) /* set initial values for level & stereo - adjustment, mode */ byte = 0; - if ( 0 != (result = tda9840_command(client, TDA9840_LEVEL_ADJUST, &byte))) { - printk("tda9840.o: could not initialize ic #1. continuing anyway. (result:%d)\n",result); - } - - if ( 0 != (result = tda9840_command(client, TDA9840_STEREO_ADJUST, &byte))) { - printk("tda9840.o: could not initialize ic #2. continuing anyway. (result:%d)\n",result); - } - + result = command(client, TDA9840_LEVEL_ADJUST, &byte); + result += command(client, TDA9840_STEREO_ADJUST, &byte); byte = TDA9840_SET_MONO; - if ( 0 != (result = tda9840_command(client, TDA9840_SWITCH, &byte))) { - printk("tda9840.o: could not initialize ic #3. continuing anyway. (result:%d)\n",result); - } - - printk("tda9840.o: detected @ 0x%02x on adapter %s\n",2*address,&client->adapter->name[0]); + result = command(client, TDA9840_SWITCH, &byte); + if (result) { + dprintk("could not initialize tda9840\n"); + return -ENODEV; + } + printk("tda9840: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]); return 0; } -static int tda9840_attach(struct i2c_adapter *adapter) +static int attach(struct i2c_adapter *adapter) { /* let's see whether this is a know adapter we can attach to */ - if( adapter->id != I2C_ALGO_SAA7146 ) { - dprintk("tda9840.o: refusing to probe on unknown adapter [name='%s',id=0x%x]\n",adapter->name,adapter->id); + if (adapter->id != I2C_ALGO_SAA7146) { + dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); return -ENODEV; } - return i2c_probe(adapter,&addr_data,&tda9840_detect); + return i2c_probe(adapter, &addr_data, &detect); } -static int tda9840_detach(struct i2c_client *client) +static int detach(struct i2c_client *client) { - int err = 0; - - if ( 0 != (err = i2c_detach_client(client))) { - printk("tda9840.o: Client deregistration failed, client not detached.\n"); - return err; - } - + int ret = i2c_detach_client(client); kfree(client); - - return 0; + return ret; } static struct i2c_driver driver = { - .owner = THIS_MODULE, - .name = "tda9840 driver", - .id = I2C_DRIVERID_TDA9840, - .flags = I2C_DF_NOTIFY, - .attach_adapter = tda9840_attach, - .detach_client = tda9840_detach, - .command = tda9840_command, + .owner = THIS_MODULE, + .name = "tda9840", + .id = I2C_DRIVERID_TDA9840, + .flags = I2C_DF_NOTIFY, + .attach_adapter = attach, + .detach_client = detach, + .command = command, +}; + +static struct i2c_client client_template = { + I2C_DEVNAME("tda9840"), + .driver = &driver, }; -static int __init tda9840_init_module(void) +static int __init this_module_init(void) { - return i2c_add_driver(&driver); + return i2c_add_driver(&driver); } -static void __exit tda9840_cleanup_module(void) +static void __exit this_module_exit(void) { - i2c_del_driver(&driver); + i2c_del_driver(&driver); } -module_init(tda9840_init_module); -module_exit(tda9840_cleanup_module); +module_init(this_module_init); +module_exit(this_module_exit); MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); MODULE_DESCRIPTION("tda9840 driver"); diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index fe64e64e3e59..807fd7ecd599 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c @@ -1,5 +1,5 @@ /* - tea6415c.h - i2c-driver for the tea6415c by SGS Thomson + tea6415c - i2c-driver for the tea6415c by SGS Thomson Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> @@ -7,10 +7,10 @@ with 8 inputs and 6 outputs. It is cascadable, i.e. it can be found at the addresses 0x86 and 0x06 on the i2c-bus. - + For detailed informations download the specifications directly from SGS Thomson at http://www.st.com - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License vs published by the Free Software Foundation; either version 2 of the License, or @@ -24,61 +24,58 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mvss Ave, Cambridge, MA 02139, USA. - */ + */ -#include <linux/version.h> #include <linux/module.h> -#include <linux/kernel.h> -#include <linux/poll.h> -#include <linux/slab.h> +#include <linux/ioctl.h> #include <linux/i2c.h> -#include <linux/init.h> + #include "tea6415c.h" -static int debug = 0; /* insmod parameter */ -MODULE_PARM(debug,"i"); -#define dprintk if (debug) printk +static int debug = 0; /* insmod parameter */ +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); +#define dprintk(args...) \ + do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0) #define TEA6415C_NUM_INPUTS 8 #define TEA6415C_NUM_OUTPUTS 6 /* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */ -static unsigned short normal_i2c[] = {I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END}; -static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; +static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END }; +static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; static struct i2c_driver driver; +static struct i2c_client client_template; /* unique ID allocation */ static int tea6415c_id = 0; /* this function is called by i2c_probe */ -static int tea6415c_detect(struct i2c_adapter *adapter, int address, int kind) +static int detect(struct i2c_adapter *adapter, int address, int kind) { - struct i2c_client *client = NULL; + struct i2c_client *client = NULL; int err = 0; /* let's see whether this adapter can support what we need */ - if ( 0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) { + if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) { return 0; } /* allocate memory for client structure */ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (0 == client) { + if (0 == client) { return -ENOMEM; } - memset(client, 0, sizeof(struct i2c_client)); /* fill client structure */ - sprintf(client->name,"tea6415c (0x%02x)", address); + memcpy(client, &client_template, sizeof(struct i2c_client)); client->id = tea6415c_id++; - client->flags = 0; client->addr = address; client->adapter = adapter; - client->driver = &driver; /* tell the i2c layer a new client has arrived */ if (0 != (err = i2c_attach_client(client))) { @@ -86,151 +83,145 @@ static int tea6415c_detect(struct i2c_adapter *adapter, int address, int kind) return err; } - printk("tea6415c.o: detected @ 0x%02x on adapter %s\n",2*address,&client->adapter->name[0]); + printk("tea6415c: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]); return 0; } -static int tea6415c_attach(struct i2c_adapter *adapter) +static int attach(struct i2c_adapter *adapter) { /* let's see whether this is a know adapter we can attach to */ - if( adapter->id != I2C_ALGO_SAA7146 ) { - dprintk("tea6415c.o: refusing to probe on unknown adapter [name='%s',id=0x%x]\n",adapter->name,adapter->id); + if (adapter->id != I2C_ALGO_SAA7146) { + dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); return -ENODEV; } - return i2c_probe(adapter,&addr_data,&tea6415c_detect); + return i2c_probe(adapter, &addr_data, &detect); } -static int tea6415c_detach(struct i2c_client *client) +static int detach(struct i2c_client *client) { - int err = 0; - - if ( 0 != (err = i2c_detach_client(client))) { - printk("tea6415c.o: Client deregistration failed, client not detached.\n"); - return err; - } - + int ret = i2c_detach_client(client); kfree(client); - - return 0; + return ret; } /* makes a connection between the input-pin 'i' and the output-pin 'o' for the tea6415c-client 'client' */ -static int tea6415c_switch(struct i2c_client *client, int i, int o) +static int switch_matrix(struct i2c_client *client, int i, int o) { - u8 byte = 0; + u8 byte = 0; + int ret; - dprintk("tea6415c.o: tea6415c_switch: adr:0x%02x, i:%d, o:%d\n", client->addr, i, o); - + dprintk("adr:0x%02x, i:%d, o:%d\n", client->addr, i, o); + /* check if the pins are valid */ - if ( 0 == (( 1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i ) && - (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o ))) + if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i) + && (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o))) return -1; /* to understand this, have a look at the tea6415c-specs (p.5) */ - switch(o) { - case 18: - byte = 0x00; - break; - case 14: - byte = 0x20; - break; - case 16: - byte = 0x10; - break; - case 17: - byte = 0x08; - break; - case 15: - byte = 0x18; - break; - case 13: - byte = 0x28; - break; + switch (o) { + case 18: + byte = 0x00; + break; + case 14: + byte = 0x20; + break; + case 16: + byte = 0x10; + break; + case 17: + byte = 0x08; + break; + case 15: + byte = 0x18; + break; + case 13: + byte = 0x28; + break; }; - - switch(i) { - case 5: - byte |= 0x00; - break; - case 8: - byte |= 0x04; - break; - case 3: - byte |= 0x02; - break; - case 20: - byte |= 0x06; - break; - case 6: - byte |= 0x01; - break; - case 10: - byte |= 0x05; - break; - case 1: - byte |= 0x03; - break; - case 11: - byte |= 0x07; - break; + + switch (i) { + case 5: + byte |= 0x00; + break; + case 8: + byte |= 0x04; + break; + case 3: + byte |= 0x02; + break; + case 20: + byte |= 0x06; + break; + case 6: + byte |= 0x01; + break; + case 10: + byte |= 0x05; + break; + case 1: + byte |= 0x03; + break; + case 11: + byte |= 0x07; + break; }; - if ( 0 != i2c_smbus_write_byte(client,byte)) { - dprintk("tea6415c.o: tea6415c_switch: could not write to tea6415c\n"); - return -1; + ret = i2c_smbus_write_byte(client, byte); + if (ret) { + dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret); + return -EIO; } - return 0; + return ret; } -static int tea6415c_command(struct i2c_client *client, unsigned int cmd, void* arg) +static int command(struct i2c_client *client, unsigned int cmd, void *arg) { - struct tea6415c_multiplex *v = (struct tea6415c_multiplex*)arg; + struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg; int result = 0; switch (cmd) { - case TEA6415C_SWITCH: { - result = tea6415c_switch(client,v->in,v->out); - break; - } - default: { - return -ENOIOCTLCMD; - } + case TEA6415C_SWITCH: + result = switch_matrix(client, v->in, v->out); + break; + default: + return -ENOIOCTLCMD; } - if ( 0 != result ) - return result; - - return 0; + return result; } static struct i2c_driver driver = { - .owner = THIS_MODULE, - .name = "tea6415c driver", - .id = I2C_DRIVERID_TEA6415C, - .flags = I2C_DF_NOTIFY, - .attach_adapter = tea6415c_attach, - .detach_client = tea6415c_detach, - .command = tea6415c_command, + .owner = THIS_MODULE, + .name = "tea6415c", + .id = I2C_DRIVERID_TEA6415C, + .flags = I2C_DF_NOTIFY, + .attach_adapter = attach, + .detach_client = detach, + .command = command, +}; + +static struct i2c_client client_template = { + I2C_DEVNAME("tea6415c"), + .driver = &driver, }; -static int __init tea6415c_init_module(void) +static int __init this_module_init(void) { return i2c_add_driver(&driver); } -static void __exit tea6415c_cleanup_module(void) +static void __exit this_module_exit(void) { - i2c_del_driver(&driver); + i2c_del_driver(&driver); } -module_init(tea6415c_init_module); -module_exit(tea6415c_cleanup_module); +module_init(this_module_init); +module_exit(this_module_exit); MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); MODULE_DESCRIPTION("tea6415c driver"); MODULE_LICENSE("GPL"); - diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 93acdc635f67..f46b2196448e 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c @@ -1,5 +1,5 @@ /* - tea6420.o - i2c-driver for the tea6420 by SGS Thomson + tea6420 - i2c-driver for the tea6420 by SGS Thomson Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> @@ -7,10 +7,10 @@ 4 stereo outputs and gain control for each output. It is cascadable, i.e. it can be found at the adresses 0x98 and 0x9a on the i2c-bus. - + For detailed informations download the specifications directly from SGS Thomson at http://www.st.com - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -24,30 +24,29 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ + */ -#include <linux/version.h> #include <linux/module.h> -#include <linux/kernel.h> -#include <linux/poll.h> -#include <linux/slab.h> +#include <linux/ioctl.h> #include <linux/i2c.h> -#include <linux/init.h> #include "tea6420.h" -static int debug = 0; /* insmod parameter */ -MODULE_PARM(debug,"i"); -#define dprintk if (debug) printk +static int debug = 0; /* insmod parameter */ +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); +#define dprintk(args...) \ + do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0) /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ -static unsigned short normal_i2c[] = {I2C_TEA6420_1, I2C_TEA6420_2, I2C_CLIENT_END}; -static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; +static unsigned short normal_i2c[] = { I2C_TEA6420_1, I2C_TEA6420_2, I2C_CLIENT_END }; +static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; /* magic definition of all other variables and things */ I2C_CLIENT_INSMOD; static struct i2c_driver driver; +static struct i2c_client client_template; /* unique ID allocation */ static int tea6420_id = 0; @@ -56,39 +55,37 @@ static int tea6420_id = 0; with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) { - u8 byte = 0; - - int result = 0; - - dprintk("tea6420.o: tea6420_switch: adr:0x%02x, i:%d, o:%d, g:%d\n",client->addr,i,o,g); + u8 byte = 0; + int ret; + + dprintk("adr:0x%02x, i:%d, o:%d, g:%d\n", client->addr, i, o, g); /* check if the paramters are valid */ - if ( i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g%2 != 0 ) + if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0) return -1; - byte = ((o-1)<<5); - byte |= (i-1); + byte = ((o - 1) << 5); + byte |= (i - 1); /* to understand this, have a look at the tea6420-specs (p.5) */ - switch(g) { - case 0: - byte |= (3<<3); - break; - case 2: - byte |= (2<<3); - break; - case 4: - byte |= (1<<3); - break; - case 6: - break; + switch (g) { + case 0: + byte |= (3 << 3); + break; + case 2: + byte |= (2 << 3); + break; + case 4: + byte |= (1 << 3); + break; + case 6: + break; } - /* fixme?: 1 != ... => 0 != */ - if ( 0 != (result = i2c_smbus_write_byte(client,byte))) { - printk("tea6402:%d\n",result); - dprintk(KERN_ERR "tea6420.o: could not switch, result:%d\n",result); - return -EFAULT; + ret = i2c_smbus_write_byte(client, byte); + if (ret) { + dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret); + return -EIO; } return 0; @@ -97,29 +94,26 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) /* this function is called by i2c_probe */ static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind) { - struct i2c_client *client; + struct i2c_client *client; int err = 0, i = 0; /* let's see whether this adapter can support what we need */ - if ( 0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) { + if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) { return 0; } /* allocate memory for client structure */ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (0 == client) { + if (0 == client) { return -ENOMEM; } - memset(client, 0x0, sizeof(struct i2c_client)); + memset(client, 0x0, sizeof(struct i2c_client)); /* fill client structure */ - sprintf(client->name,"tea6420 (0x%02x)", address); + memcpy(client, &client_template, sizeof(struct i2c_client)); client->id = tea6420_id++; - client->flags = 0; client->addr = address; client->adapter = adapter; - client->driver = &driver; - i2c_set_clientdata(client, NULL); /* tell the i2c layer a new client has arrived */ if (0 != (err = i2c_attach_client(client))) { @@ -129,86 +123,81 @@ static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind) /* set initial values: set "mute"-input to all outputs at gain 0 */ err = 0; - for(i = 1; i < 5; i++) { + for (i = 1; i < 5; i++) { err += tea6420_switch(client, 6, i, 0); } - if( 0 != err) { - printk("tea6420.o: could not initialize chipset. continuing anyway.\n"); + if (err) { + dprintk("could not initialize tea6420\n"); + kfree(client); + return -ENODEV; } - - printk("tea6420.o: detected @ 0x%02x on adapter %s\n",2*address,&client->adapter->name[0]); + + printk("tea6420: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]); return 0; } -static int tea6420_attach(struct i2c_adapter *adapter) +static int attach(struct i2c_adapter *adapter) { /* let's see whether this is a know adapter we can attach to */ - if( adapter->id != I2C_ALGO_SAA7146 ) { - dprintk("tea6420.o: refusing to probe on unknown adapter [name='%s',id=0x%x]\n",adapter->name,adapter->id); + if (adapter->id != I2C_ALGO_SAA7146) { + dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id); return -ENODEV; } - return i2c_probe(adapter,&addr_data,&tea6420_detect); + return i2c_probe(adapter, &addr_data, &tea6420_detect); } -static int tea6420_detach(struct i2c_client *client) +static int detach(struct i2c_client *client) { - int err = 0; - - if ( 0 != (err = i2c_detach_client(client))) { - printk("tea6420.o: Client deregistration failed, client not detached.\n"); - return err; - } - + int ret = i2c_detach_client(client); kfree(client); - - return 0; + return ret; } -static int tea6420_command(struct i2c_client *client, unsigned int cmd, void* arg) +static int command(struct i2c_client *client, unsigned int cmd, void *arg) { - struct tea6420_multiplex *a = (struct tea6420_multiplex*)arg; + struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg; int result = 0; switch (cmd) { - case TEA6420_SWITCH: { - result = tea6420_switch(client,a->in,a->out,a->gain); - break; - } - default: { - return -ENOIOCTLCMD; - } + case TEA6420_SWITCH: + result = tea6420_switch(client, a->in, a->out, a->gain); + break; + default: + return -ENOIOCTLCMD; } - if ( 0 != result ) - return result; - - return 0; + return result; } static struct i2c_driver driver = { - .owner = THIS_MODULE, - .name = "tea6420 driver", - .id = I2C_DRIVERID_TEA6420, - .flags = I2C_DF_NOTIFY, - .attach_adapter = tea6420_attach, - .detach_client = tea6420_detach, - .command = tea6420_command, + .owner = THIS_MODULE, + .name = "tea6420", + .id = I2C_DRIVERID_TEA6420, + .flags = I2C_DF_NOTIFY, + .attach_adapter = attach, + .detach_client = detach, + .command = command, +}; + +static struct i2c_client client_template = { + I2C_DEVNAME("tea6420"), + .driver = &driver, }; -static int __init tea6420_init_module(void) +static int __init this_module_init(void) { return i2c_add_driver(&driver); } -static void __exit tea6420_cleanup_module(void) +static void __exit this_module_exit(void) { - i2c_del_driver(&driver); + i2c_del_driver(&driver); } -module_init(tea6420_init_module); -module_exit(tea6420_cleanup_module); +module_init(this_module_init); +module_exit(this_module_exit); MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); MODULE_DESCRIPTION("tea6420 driver"); diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index dc9069a6e3b5..b9f948d1a83e 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c @@ -1497,6 +1497,10 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) static int chip_probe(struct i2c_adapter *adap) { + /* don't attach on saa7146 based cards, + because dedicated drivers are used */ + if ((adap->id & I2C_ALGO_SAA7146)) + return 0; #ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, chip_attach); diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c index 4058bac11ede..300531d84b87 100644 --- a/drivers/media/video/video-buf.c +++ b/drivers/media/video/video-buf.c @@ -1063,7 +1063,7 @@ videobuf_vm_close(struct vm_area_struct *vma) continue; map->q->bufs[i]->map = NULL; map->q->bufs[i]->baddr = 0; - map->q->ops->buf_release(vma->vm_file,map->q->bufs[i]); + map->q->ops->buf_release(vma->vm_file->private_data,map->q->bufs[i]); } kfree(map); } diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index 46fa7dfd6eb1..e0ce5254f249 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c @@ -810,7 +810,7 @@ static int i2o_iop_systab_set(struct i2o_controller *c) writel(c->unit + 2, &msg->body[0]); writel(0, &msg->body[1]); - writel(0x54000000 | i2o_systab.phys, &msg->body[2]); + writel(0x54000000 | i2o_systab.len, &msg->body[2]); writel(i2o_systab.phys, &msg->body[3]); writel(0x54000000 | sb->current_mem_size, &msg->body[4]); writel(sb->current_mem_base, &msg->body[5]); diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 13c33ba20813..0200cb7bb194 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1681,7 +1681,7 @@ config VIA_RHINE (e.g. VT8235). To compile this driver as a module, choose M here. The module - will be called via-velocity. + will be called via-rhine. config VIA_RHINE_MMIO bool "Use MMIO instead of PIO" diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c index 3c17cc7f18fc..8e115b5a6a11 100644 --- a/drivers/net/hamradio/hdlcdrv.c +++ b/drivers/net/hamradio/hdlcdrv.c @@ -549,8 +549,6 @@ static int hdlcdrv_close(struct net_device *dev) netif_stop_queue(dev); - netif_stop_queue(dev); - if (s->ops && s->ops->close) i = s->ops->close(dev); if (s->skb) diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c index d02286d6471d..e8be5a26db81 100644 --- a/drivers/net/ppp_async.c +++ b/drivers/net/ppp_async.c @@ -911,7 +911,9 @@ ppp_async_input(struct asyncppp *ap, const unsigned char *buf, break; c = buf[n]; - if (c == PPP_FLAG) { + if (flags != NULL && flags[n] != 0) { + ap->state |= SC_TOSS; + } else if (c == PPP_FLAG) { process_input_packet(ap); } else if (c == PPP_ESCAPE) { ap->state |= SC_ESCAPE; diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 85c1e1e5e89b..38e94961e1a4 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -2681,7 +2681,7 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return rc; } -#if (!defined(__sparc__) && !defined(CONFIG_PPC)) +#if (!defined(__sparc__) && !defined(CONFIG_PPC_PMAC)) /* Fetch MAC address from vital product data of PCI ROM. */ static void find_eth_addr_in_vpd(void __iomem *rom_base, int len, unsigned char *dev_addr) { diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index b26723426dac..f136ff777d07 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -62,6 +62,7 @@ #include <linux/parport.h> #include <linux/parport_pc.h> +#include <linux/via.h> #include <asm/parport.h> #define PARPORT_PC_MAX_PORTS PARPORT_MAX @@ -2378,7 +2379,7 @@ EXPORT_SYMBOL (parport_pc_unregister_port); /* ITE support maintained by Rich Liu <richliu@poorman.org> */ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq, - int autodma) + int autodma, struct parport_pc_via_data *via) { short inta_addr[6] = { 0x2A0, 0x2C0, 0x220, 0x240, 0x1E0 }; struct resource *base_res; @@ -2481,71 +2482,161 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq, return 0; } -/* Via support maintained by Jeff Garzik <jgarzik@pobox.com> */ -static int __devinit sio_via_686a_probe (struct pci_dev *pdev, int autoirq, - int autodma) +/* VIA 8231 support by Pavel Fedin <sonic_amiga@rambler.ru> + based on VIA 686a support code by Jeff Garzik <jgarzik@pobox.com> */ +static int __initdata parport_init_mode = 0; + +/* Data for two known VIA chips */ +static struct parport_pc_via_data via_686a_data __devinitdata = { + 0x51, + 0x50, + 0x85, + 0x02, + 0xE2, + 0xF0, + 0xE6 +}; +static struct parport_pc_via_data via_8231_data __devinitdata = { + 0x45, + 0x44, + 0x50, + 0x04, + 0xF2, + 0xFA, + 0xF6 +}; + +static int __devinit sio_via_probe (struct pci_dev *pdev, int autoirq, + int autodma, struct parport_pc_via_data *via) { - u8 tmp; + u8 tmp, tmp2, siofunc; + u8 ppcontrol = 0; int dma, irq; - unsigned port1, port2, have_eppecp; + unsigned port1, port2; + unsigned have_epp = 0; + printk(KERN_DEBUG "parport_pc: VIA 686A/8231 detected\n"); + + switch(parport_init_mode) + { + case 1: + printk(KERN_DEBUG "parport_pc: setting SPP mode\n"); + siofunc = VIA_FUNCTION_PARPORT_SPP; + break; + case 2: + printk(KERN_DEBUG "parport_pc: setting PS/2 mode\n"); + siofunc = VIA_FUNCTION_PARPORT_SPP; + ppcontrol = VIA_PARPORT_BIDIR; + break; + case 3: + printk(KERN_DEBUG "parport_pc: setting EPP mode\n"); + siofunc = VIA_FUNCTION_PARPORT_EPP; + ppcontrol = VIA_PARPORT_BIDIR; + have_epp = 1; + break; + case 4: + printk(KERN_DEBUG "parport_pc: setting ECP mode\n"); + siofunc = VIA_FUNCTION_PARPORT_ECP; + ppcontrol = VIA_PARPORT_BIDIR; + break; + case 5: + printk(KERN_DEBUG "parport_pc: setting EPP+ECP mode\n"); + siofunc = VIA_FUNCTION_PARPORT_ECP; + ppcontrol = VIA_PARPORT_BIDIR|VIA_PARPORT_ECPEPP; + have_epp = 1; + break; + default: + printk(KERN_DEBUG "parport_pc: probing current configuration\n"); + siofunc = VIA_FUNCTION_PROBE; + break; + } /* - * unlock super i/o configuration, set 0x85_1 - */ - pci_read_config_byte (pdev, 0x85, &tmp); - tmp |= (1 << 1); - pci_write_config_byte (pdev, 0x85, tmp); - - /* - * Super I/O configuration, index port == 3f0h, data port == 3f1h + * unlock super i/o configuration */ + pci_read_config_byte(pdev, via->via_pci_superio_config_reg, &tmp); + tmp |= via->via_pci_superio_config_data; + pci_write_config_byte(pdev, via->via_pci_superio_config_reg, tmp); + + /* Bits 1-0: Parallel Port Mode / Enable */ + outb(via->viacfg_function, VIA_CONFIG_INDEX); + tmp = inb (VIA_CONFIG_DATA); + /* Bit 5: EPP+ECP enable; bit 7: PS/2 bidirectional port enable */ + outb(via->viacfg_parport_control, VIA_CONFIG_INDEX); + tmp2 = inb (VIA_CONFIG_DATA); + if (siofunc == VIA_FUNCTION_PROBE) + { + siofunc = tmp & VIA_FUNCTION_PARPORT_DISABLE; + ppcontrol = tmp2; + } + else + { + tmp &= ~VIA_FUNCTION_PARPORT_DISABLE; + tmp |= siofunc; + outb(via->viacfg_function, VIA_CONFIG_INDEX); + outb(tmp, VIA_CONFIG_DATA); + tmp2 &= ~(VIA_PARPORT_BIDIR|VIA_PARPORT_ECPEPP); + tmp2 |= ppcontrol; + outb(via->viacfg_parport_control, VIA_CONFIG_INDEX); + outb(tmp2, VIA_CONFIG_DATA); + } - /* 0xE2_1-0: Parallel Port Mode / Enable */ - outb (0xE2, 0x3F0); - tmp = inb (0x3F1); + /* Parallel Port I/O Base Address, bits 9-2 */ + outb(via->viacfg_parport_base, VIA_CONFIG_INDEX); + port1 = inb(VIA_CONFIG_DATA) << 2; - if ((tmp & 0x03) == 0x03) { - printk (KERN_INFO "parport_pc: Via 686A parallel port disabled in BIOS\n"); + printk (KERN_DEBUG "parport_pc: Current parallel port base: 0x%X\n",port1); + if ((port1 == 0x3BC) && have_epp) + { + outb(via->viacfg_parport_base, VIA_CONFIG_INDEX); + outb((0x378 >> 2), VIA_CONFIG_DATA); + printk(KERN_DEBUG "parport_pc: Parallel port base changed to 0x378\n"); + port1 = 0x378; + } + + /* + * lock super i/o configuration + */ + pci_read_config_byte(pdev, via->via_pci_superio_config_reg, &tmp); + tmp &= ~via->via_pci_superio_config_data; + pci_write_config_byte(pdev, via->via_pci_superio_config_reg, tmp); + + if (siofunc == VIA_FUNCTION_PARPORT_DISABLE) { + printk(KERN_INFO "parport_pc: VIA parallel port disabled in BIOS\n"); return 0; } - /* 0xE6: Parallel Port I/O Base Address, bits 9-2 */ - outb (0xE6, 0x3F0); - port1 = inb (0x3F1) << 2; - + /* Bits 7-4: PnP Routing for Parallel Port IRQ */ + pci_read_config_byte(pdev, via->via_pci_parport_irq_reg, &tmp); + irq = ((tmp & VIA_IRQCONTROL_PARALLEL) >> 4); + + if (siofunc == VIA_FUNCTION_PARPORT_ECP) + { + /* Bits 3-2: PnP Routing for Parallel Port DMA */ + pci_read_config_byte(pdev, via->via_pci_parport_dma_reg, &tmp); + dma = ((tmp & VIA_DMACONTROL_PARALLEL) >> 2); + } + else + /* if ECP not enabled, DMA is not enabled, assumed bogus 'dma' value */ + dma = PARPORT_DMA_NONE; + + /* Let the user (or defaults) steer us away from interrupts and DMA */ + if (autoirq == PARPORT_IRQ_NONE) { + irq = PARPORT_IRQ_NONE; + dma = PARPORT_DMA_NONE; + } + if (autodma == PARPORT_DMA_NONE) + dma = PARPORT_DMA_NONE; + switch (port1) { case 0x3bc: port2 = 0x7bc; break; case 0x378: port2 = 0x778; break; case 0x278: port2 = 0x678; break; default: - printk (KERN_INFO "parport_pc: Weird Via 686A parport base 0x%X, ignoring\n", + printk(KERN_INFO "parport_pc: Weird VIA parport base 0x%X, ignoring\n", port1); return 0; } - /* 0xF0_5: EPP+ECP enable */ - outb (0xF0, 0x3F0); - have_eppecp = (inb (0x3F1) & (1 << 5)); - - /* - * lock super i/o configuration, clear 0x85_1 - */ - pci_read_config_byte (pdev, 0x85, &tmp); - tmp &= ~(1 << 1); - pci_write_config_byte (pdev, 0x85, tmp); - - /* - * Get DMA and IRQ from PCI->ISA bridge PCI config registers - */ - - /* 0x50_3-2: PnP Routing for Parallel Port DRQ */ - pci_read_config_byte (pdev, 0x50, &tmp); - dma = ((tmp >> 2) & 0x03); - - /* 0x51_7-4: PnP Routing for Parallel Port IRQ */ - pci_read_config_byte (pdev, 0x51, &tmp); - irq = ((tmp >> 4) & 0x0F); - /* filter bogus IRQs */ switch (irq) { case 0: @@ -2559,22 +2650,10 @@ static int __devinit sio_via_686a_probe (struct pci_dev *pdev, int autoirq, break; } - /* if ECP not enabled, DMA is not enabled, assumed bogus 'dma' value */ - if (!have_eppecp) - dma = PARPORT_DMA_NONE; - - /* Let the user (or defaults) steer us away from interrupts and DMA */ - if (autoirq != PARPORT_IRQ_AUTO) { - irq = PARPORT_IRQ_NONE; - dma = PARPORT_DMA_NONE; - } - if (autodma != PARPORT_DMA_AUTO) - dma = PARPORT_DMA_NONE; - /* finally, do the probe with values obtained */ if (parport_pc_probe_port (port1, port2, irq, dma, NULL)) { printk (KERN_INFO - "parport_pc: Via 686A parallel port: io=0x%X", port1); + "parport_pc: VIA parallel port: io=0x%X", port1); if (irq != PARPORT_IRQ_NONE) printk (", irq=%d", irq); if (dma != PARPORT_DMA_NONE) @@ -2583,7 +2662,7 @@ static int __devinit sio_via_686a_probe (struct pci_dev *pdev, int autoirq, return 1; } - printk (KERN_WARNING "parport_pc: Strange, can't probe Via 686A parallel port: io=0x%X, irq=%d, dma=%d\n", + printk(KERN_WARNING "parport_pc: Strange, can't probe VIA parallel port: io=0x%X, irq=%d, dma=%d\n", port1, irq, dma); return 0; } @@ -2591,19 +2670,21 @@ static int __devinit sio_via_686a_probe (struct pci_dev *pdev, int autoirq, enum parport_pc_sio_types { sio_via_686a = 0, /* Via VT82C686A motherboard Super I/O */ + sio_via_8231, /* Via VT8231 south bridge integrated Super IO */ sio_ite_8872, last_sio }; /* each element directly indexed from enum list, above */ static struct parport_pc_superio { - int (*probe) (struct pci_dev *pdev, int autoirq, int autodma); + int (*probe) (struct pci_dev *pdev, int autoirq, int autodma, struct parport_pc_via_data *via); + struct parport_pc_via_data *via; } parport_pc_superio_info[] __devinitdata = { - { sio_via_686a_probe, }, - { sio_ite_8872_probe, }, + { sio_via_probe, &via_686a_data, }, + { sio_via_probe, &via_8231_data, }, + { sio_ite_8872_probe, NULL, }, }; - enum parport_pc_pci_cards { siig_1p_10x = last_sio, siig_2p_10x, @@ -2737,6 +2818,7 @@ static struct parport_pc_pci { static struct pci_device_id parport_pc_pci_tbl[] = { /* Super-IO onboard chips */ { 0x1106, 0x0686, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sio_via_686a }, + { 0x1106, 0x8231, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sio_via_8231 }, { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8872, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sio_ite_8872 }, @@ -2886,7 +2968,7 @@ static int __init parport_pc_init_superio (int autoirq, int autodma) continue; if (parport_pc_superio_info[id->driver_data].probe - (pdev, autoirq, autodma)) { + (pdev, autoirq, autodma,parport_pc_superio_info[id->driver_data].via)) { ret++; } } @@ -3072,9 +3154,27 @@ static int __init parport_parse_dma(const char *dmastr, int *val) PARPORT_DMA_NONE, PARPORT_DMA_NOFIFO); } +static int __init parport_init_mode_setup(const char *str) { + + printk(KERN_DEBUG "parport_pc.c: Specified parameter parport_init_mode=%s\n", str); + + if (!strcmp (str, "spp")) + parport_init_mode=1; + if (!strcmp (str, "ps2")) + parport_init_mode=2; + if (!strcmp (str, "epp")) + parport_init_mode=3; + if (!strcmp (str, "ecp")) + parport_init_mode=4; + if (!strcmp (str, "ecpepp")) + parport_init_mode=5; + return 1; +} + #ifdef MODULE static const char *irq[PARPORT_PC_MAX_PORTS]; static const char *dma[PARPORT_PC_MAX_PORTS]; +static const char *init_mode; MODULE_PARM_DESC(io, "Base I/O address (SPP regs)"); MODULE_PARM(io, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "i"); @@ -3089,12 +3189,17 @@ MODULE_PARM(dma, "1-" __MODULE_STRING(PARPORT_PC_MAX_PORTS) "s"); MODULE_PARM_DESC(verbose_probing, "Log chit-chat during initialisation"); MODULE_PARM(verbose_probing, "i"); #endif +MODULE_PARM_DESC(init_mode, "Initialise mode for VIA VT8231 port (spp, ps2, epp, ecp or ecpepp)"); +MODULE_PARM(init_mode, "s"); static int __init parse_parport_params(void) { unsigned int i; int val; + if (init_mode) + parport_init_mode_setup(init_mode); + for (i = 0; i < PARPORT_PC_MAX_PORTS && io[i]; i++) { if (parport_parse_irq(irq[i], &val)) return 1; @@ -3202,6 +3307,15 @@ static int __init parse_parport_params(void) } __setup ("parport=", parport_setup); + +/* + * Acceptable parameters: + * + * parport_init_mode=[spp|ps2|epp|ecp|ecpepp] + */ + +__setup("parport_init_mode=",parport_init_mode_setup); + #endif /* "Parser" ends here */ diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c index ca7996d4bdb3..6b7583f497d0 100644 --- a/drivers/pnp/pnpbios/bioscalls.c +++ b/drivers/pnp/pnpbios/bioscalls.c @@ -165,7 +165,7 @@ static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3, if(pnp_bios_is_utter_crap) { printk(KERN_ERR "PnPBIOS: Warning! Your PnP BIOS caused a fatal error. Attempting to continue\n"); - printk(KERN_ERR "PnPBIOS: You may need to reboot with the \"nobiospnp\" option to operate stably\n"); + printk(KERN_ERR "PnPBIOS: You may need to reboot with the \"pnpbios=off\" option to operate stably\n"); printk(KERN_ERR "PnPBIOS: Check with your vendor for an updated BIOS\n"); } diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index b99b68df8a8f..bf196291dd42 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -386,6 +386,29 @@ config SERIAL_SA1100_CONSOLE your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) +config SERIAL_IMX + bool "IMX serial port support" + depends on ARM && ARCH_IMX + select SERIAL_CORE + help + If you have a machine based on a Motorola IMX CPU you + can enable its onboard serial port by enabling this option. + +config SERIAL_IMX_CONSOLE + bool "Console on IMX serial port" + depends on SERIAL_IMX + select SERIAL_CORE_CONSOLE + help + If you have enabled the serial port on the Motorola IMX + CPU you can make it the console by answering Y to this option. + + Even if you say Y here, the currently visible virtual console + (/dev/tty0) will still be used as the system console by default, but + you can alter that using a kernel command line option such as + "console=ttySA0". (Try "man bootparam" or see the documentation of + your boot loader (lilo or loadlin) about how to pass options to the + kernel at boot time.) + config SERIAL_SUNCORE bool depends on SPARC32 || SPARC64 diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 5183a9ce517d..186595b69310 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -41,5 +41,7 @@ obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o obj-$(CONFIG_SERIAL_BAST_SIO) += bast_sio.o obj-$(CONFIG_SERIAL_SGI_L1_CONSOLE) += sn_console.o obj-$(CONFIG_SERIAL_CPM) += cpm_uart/ +obj-$(CONFIG_SERIAL_IMX) += imx.o obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o +obj-$(CONFIG_SERIAL_ICOM) += icom.o obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c new file mode 100644 index 000000000000..c52fd3928882 --- /dev/null +++ b/drivers/serial/imx.c @@ -0,0 +1,905 @@ +/* + * linux/drivers/serial/imx.c + * + * Driver for Motorola IMX serial ports + * + * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. + * + * Author: Sascha Hauer <sascha@saschahauer.de> + * Copyright (C) 2004 Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include <linux/config.h> +#include <linux/module.h> +#include <linux/tty.h> +#include <linux/ioport.h> +#include <linux/init.h> +#include <linux/serial.h> +#include <linux/console.h> +#include <linux/sysrq.h> +#include <linux/device.h> + +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/hardware.h> +#include <asm/arch/serial.h> +#include <asm/mach-types.h> + +#if defined(CONFIG_SERIAL_IMX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +#include <linux/serial_core.h> + +/* We've been assigned a range on the "Low-density serial ports" major */ +#define SERIAL_IMX_MAJOR 204 +#define MINOR_START 41 + +#define NR_PORTS 2 + +#define IMX_ISR_PASS_LIMIT 256 + +/* + * This is the size of our serial port register set. + */ +#define UART_PORT_SIZE 0x100 + +/* + * This determines how often we check the modem status signals + * for any change. They generally aren't connected to an IRQ + * so we have to poll them. We also check immediately before + * filling the TX fifo incase CTS has been dropped. + */ +#define MCTRL_TIMEOUT (250*HZ/1000) + +#define DRIVER_NAME "IMX-uart" + +struct imx_port { + struct uart_port port; + struct timer_list timer; + unsigned int old_status; + int txirq,rxirq; +}; + +/* + * Handle any change of modem status signal since we were last called. + */ +static void imx_mctrl_check(struct imx_port *sport) +{ + unsigned int status, changed; + + status = sport->port.ops->get_mctrl(&sport->port); + changed = status ^ sport->old_status; + + if (changed == 0) + return; + + sport->old_status = status; + + if (changed & TIOCM_RI) + sport->port.icount.rng++; + if (changed & TIOCM_DSR) + sport->port.icount.dsr++; + if (changed & TIOCM_CAR) + uart_handle_dcd_change(&sport->port, status & TIOCM_CAR); + if (changed & TIOCM_CTS) + uart_handle_cts_change(&sport->port, status & TIOCM_CTS); + + wake_up_interruptible(&sport->port.info->delta_msr_wait); +} + +/* + * This is our per-port timeout handler, for checking the + * modem status signals. + */ +static void imx_timeout(unsigned long data) +{ + struct imx_port *sport = (struct imx_port *)data; + unsigned long flags; + + if (sport->port.info) { + spin_lock_irqsave(&sport->port.lock, flags); + imx_mctrl_check(sport); + spin_unlock_irqrestore(&sport->port.lock, flags); + + mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT); + } +} + +/* + * interrupts disabled on entry + */ +static void imx_stop_tx(struct uart_port *port, unsigned int tty_stop) +{ + struct imx_port *sport = (struct imx_port *)port; + UCR1((u32)sport->port.membase) &= ~UCR1_TXMPTYEN; +} + +/* + * interrupts disabled on entry + */ +static void imx_stop_rx(struct uart_port *port) +{ + struct imx_port *sport = (struct imx_port *)port; + UCR2((u32)sport->port.membase) &= ~UCR2_RXEN; +} + +/* + * Set the modem control timer to fire immediately. + */ +static void imx_enable_ms(struct uart_port *port) +{ + struct imx_port *sport = (struct imx_port *)port; + + mod_timer(&sport->timer, jiffies); +} + +static inline void imx_transmit_buffer(struct imx_port *sport) +{ + struct circ_buf *xmit = &sport->port.info->xmit; + + do { + /* send xmit->buf[xmit->tail] + * out the port here */ + URTX0((u32)sport->port.membase) = xmit->buf[xmit->tail]; + xmit->tail = (xmit->tail + 1) & + (UART_XMIT_SIZE - 1); + sport->port.icount.tx++; + if (uart_circ_empty(xmit)) + break; + } while (!(UTS((u32)sport->port.membase) & UTS_TXFULL)); + + if (uart_circ_empty(xmit)) + imx_stop_tx(&sport->port, 0); +} + +/* + * interrupts disabled on entry + */ +static void imx_start_tx(struct uart_port *port, unsigned int tty_start) +{ + struct imx_port *sport = (struct imx_port *)port; + + UCR1((u32)sport->port.membase) |= UCR1_TXMPTYEN; + + if(UTS((u32)sport->port.membase) & UTS_TXEMPTY) + imx_transmit_buffer(sport); +} + +static irqreturn_t imx_txint(int irq, void *dev_id, struct pt_regs *regs) +{ + struct imx_port *sport = (struct imx_port *)dev_id; + struct circ_buf *xmit = &sport->port.info->xmit; + unsigned long flags; + + spin_lock_irqsave(&sport->port.lock,flags); + if (sport->port.x_char) + { + /* Send next char */ + URTX0((u32)sport->port.membase) = sport->port.x_char; + goto out; + } + + if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) { + imx_stop_tx(&sport->port, 0); + goto out; + } + + imx_transmit_buffer(sport); + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(&sport->port); + +out: + spin_unlock_irqrestore(&sport->port.lock,flags); + return IRQ_HANDLED; +} + +static irqreturn_t imx_rxint(int irq, void *dev_id, struct pt_regs *regs) +{ + struct imx_port *sport = dev_id; + unsigned int rx,flg,ignored = 0; + struct tty_struct *tty = sport->port.info->tty; + unsigned long flags; + + rx = URXD0((u32)sport->port.membase); + spin_lock_irqsave(&sport->port.lock,flags); + + do { + flg = TTY_NORMAL; + sport->port.icount.rx++; + + if( USR2((u32)sport->port.membase) & USR2_BRCD ) { + USR2((u32)sport->port.membase) |= USR2_BRCD; + if(uart_handle_break(&sport->port)) + goto ignore_char; + } + + if (uart_handle_sysrq_char + (&sport->port, (unsigned char)rx, regs)) + goto ignore_char; + + if( rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) + goto handle_error; + + error_return: + *tty->flip.flag_buf_ptr++ = flg; + *tty->flip.char_buf_ptr++ = (unsigned char)rx; + tty->flip.count++; + + if (tty->flip.count >= TTY_FLIPBUF_SIZE) + goto out; + + ignore_char: + rx = URXD0((u32)sport->port.membase); + } while(rx & URXD_CHARRDY); + +out: + spin_unlock_irqrestore(&sport->port.lock,flags); + tty_flip_buffer_push(tty); + return IRQ_HANDLED; + +handle_error: + if (rx & URXD_PRERR) + sport->port.icount.parity++; + else if (rx & URXD_FRMERR) + sport->port.icount.frame++; + if (rx & URXD_OVRRUN) + sport->port.icount.overrun++; + + if (rx & sport->port.ignore_status_mask) { + if (++ignored > 100) + goto out; + goto ignore_char; + } + + rx &= sport->port.read_status_mask; + + if (rx & URXD_PRERR) + flg = TTY_PARITY; + else if (rx & URXD_FRMERR) + flg = TTY_FRAME; + if (rx & URXD_OVRRUN) + flg = TTY_OVERRUN; + +#ifdef SUPPORT_SYSRQ + sport->port.sysrq = 0; +#endif + goto error_return; +} + +/* + * Return TIOCSER_TEMT when transmitter is not busy. + */ +static unsigned int imx_tx_empty(struct uart_port *port) +{ + struct imx_port *sport = (struct imx_port *)port; + + return USR2((u32)sport->port.membase) & USR2_TXDC ? TIOCSER_TEMT : 0; +} + +static unsigned int imx_get_mctrl(struct uart_port *port) +{ + return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; +} + +static void imx_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ +} + +/* + * Interrupts always disabled. + */ +static void imx_break_ctl(struct uart_port *port, int break_state) +{ + struct imx_port *sport = (struct imx_port *)port; + unsigned long flags; + + spin_lock_irqsave(&sport->port.lock, flags); + + if ( break_state != 0 ) + UCR1((u32)sport->port.membase) |= UCR1_SNDBRK; + else + UCR1((u32)sport->port.membase) &= ~UCR1_SNDBRK; + + spin_unlock_irqrestore(&sport->port.lock, flags); +} + +#define TXTL 2 /* reset default */ +#define RXTL 1 /* reset default */ + +static int imx_startup(struct uart_port *port) +{ + struct imx_port *sport = (struct imx_port *)port; + int retval; + unsigned int val; + unsigned long flags; + + /* set receiver / transmitter trigger level. We assume + * that RFDIV has been set by the arch setup or by the bootloader. + */ + val = (UFCR((u32)sport->port.membase) & UFCR_RFDIV) | TXTL<<10 | RXTL; + UFCR((u32)sport->port.membase) = val; + + /* disable the DREN bit (Data Ready interrupt enable) before + * requesting IRQs + */ + UCR4((u32)sport->port.membase) &= ~UCR4_DREN; + + /* + * Allocate the IRQ + */ + retval = request_irq(sport->rxirq, imx_rxint, 0, + DRIVER_NAME, sport); + if (retval) goto error_out2; + + retval = request_irq(sport->txirq, imx_txint, 0, + "imx-uart", sport); + if (retval) goto error_out1; + + /* + * Finally, clear and enable interrupts + */ + + UCR1((u32)sport->port.membase) |= + (UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN); + + UCR2((u32)sport->port.membase) |= (UCR2_RXEN | UCR2_TXEN); + /* + * Enable modem status interrupts + */ + spin_lock_irqsave(&sport->port.lock,flags); + imx_enable_ms(&sport->port); + spin_unlock_irqrestore(&sport->port.lock,flags); + + return 0; + +error_out1: + free_irq(sport->rxirq, sport); +error_out2: + free_irq(sport->txirq, sport); + return retval; +} + +static void imx_shutdown(struct uart_port *port) +{ + struct imx_port *sport = (struct imx_port *)port; + + /* + * Stop our timer. + */ + del_timer_sync(&sport->timer); + + /* + * Free the interrupts + */ + free_irq(sport->txirq, sport); + free_irq(sport->rxirq, sport); + + /* + * Disable all interrupts, port and break condition. + */ + + UCR1((u32)sport->port.membase) &= + ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_UARTEN); +} + +static void +imx_set_termios(struct uart_port *port, struct termios *termios, + struct termios *old) +{ + struct imx_port *sport = (struct imx_port *)port; + unsigned long flags; + unsigned int ucr2, old_ucr1, old_txrxen, baud, quot; + unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; + + /* + * If we don't support modem control lines, don't allow + * these to be set. + */ + if (0) { + termios->c_cflag &= ~(HUPCL | CRTSCTS | CMSPAR); + termios->c_cflag |= CLOCAL; + } + + /* + * We only support CS7 and CS8. + */ + while ((termios->c_cflag & CSIZE) != CS7 && + (termios->c_cflag & CSIZE) != CS8) { + termios->c_cflag &= ~CSIZE; + termios->c_cflag |= old_csize; + old_csize = CS8; + } + + if ((termios->c_cflag & CSIZE) == CS8) + ucr2 = UCR2_WS | UCR2_SRST | UCR2_IRTS; + else + ucr2 = UCR2_SRST | UCR2_IRTS; + + if (termios->c_cflag & CSTOPB) + ucr2 |= UCR2_STPB; + if (termios->c_cflag & PARENB) { + ucr2 |= UCR2_PREN; + if (!(termios->c_cflag & PARODD)) + ucr2 |= UCR2_PROE; + } + + /* + * Ask the core to calculate the divisor for us. + */ + baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); + quot = uart_get_divisor(port, baud); + + spin_lock_irqsave(&sport->port.lock, flags); + + sport->port.read_status_mask = 0; + if (termios->c_iflag & INPCK) + sport->port.read_status_mask |= (URXD_FRMERR | URXD_PRERR); + if (termios->c_iflag & (BRKINT | PARMRK)) + sport->port.read_status_mask |= URXD_BRK; + + /* + * Characters to ignore + */ + sport->port.ignore_status_mask = 0; + if (termios->c_iflag & IGNPAR) + sport->port.ignore_status_mask |= URXD_PRERR; + if (termios->c_iflag & IGNBRK) { + sport->port.ignore_status_mask |= URXD_BRK; + /* + * If we're ignoring parity and break indicators, + * ignore overruns too (for real raw support). + */ + if (termios->c_iflag & IGNPAR) + sport->port.ignore_status_mask |= URXD_OVRRUN; + } + + del_timer_sync(&sport->timer); + + /* + * Update the per-port timeout. + */ + uart_update_timeout(port, termios->c_cflag, baud); + + /* + * disable interrupts and drain transmitter + */ + old_ucr1 = UCR1((u32)sport->port.membase); + UCR1((u32)sport->port.membase) &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN); + + while ( !(USR2((u32)sport->port.membase) & USR2_TXDC)) + barrier(); + + /* then, disable everything */ + old_txrxen = UCR2((u32)sport->port.membase) & ( UCR2_TXEN | UCR2_RXEN ); + UCR2((u32)sport->port.membase) &= ~( UCR2_TXEN | UCR2_RXEN); + + /* set the parity, stop bits and data size */ + UCR2((u32)sport->port.membase) = ucr2; + + /* set the baud rate. We assume uartclk = 16 MHz + * + * baud * 16 UBIR - 1 + * --------- = -------- + * uartclk UBMR - 1 + */ + UBIR((u32)sport->port.membase) = (baud / 100) - 1; + UBMR((u32)sport->port.membase) = 10000 - 1; + + UCR1((u32)sport->port.membase) = old_ucr1; + UCR2((u32)sport->port.membase) |= old_txrxen; + + if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) + imx_enable_ms(&sport->port); + + spin_unlock_irqrestore(&sport->port.lock, flags); +} + +static const char *imx_type(struct uart_port *port) +{ + struct imx_port *sport = (struct imx_port *)port; + + return sport->port.type == PORT_IMX ? "IMX" : NULL; +} + +/* + * Release the memory region(s) being used by 'port'. + */ +static void imx_release_port(struct uart_port *port) +{ + struct imx_port *sport = (struct imx_port *)port; + + release_mem_region(sport->port.mapbase, UART_PORT_SIZE); +} + +/* + * Request the memory region(s) being used by 'port'. + */ +static int imx_request_port(struct uart_port *port) +{ + struct imx_port *sport = (struct imx_port *)port; + + return request_mem_region(sport->port.mapbase, UART_PORT_SIZE, + "imx-uart") != NULL ? 0 : -EBUSY; +} + +/* + * Configure/autoconfigure the port. + */ +static void imx_config_port(struct uart_port *port, int flags) +{ + struct imx_port *sport = (struct imx_port *)port; + + if (flags & UART_CONFIG_TYPE && + imx_request_port(&sport->port) == 0) + sport->port.type = PORT_IMX; +} + +/* + * Verify the new serial_struct (for TIOCSSERIAL). + * The only change we allow are to the flags and type, and + * even then only between PORT_IMX and PORT_UNKNOWN + */ +static int +imx_verify_port(struct uart_port *port, struct serial_struct *ser) +{ + struct imx_port *sport = (struct imx_port *)port; + int ret = 0; + + if (ser->type != PORT_UNKNOWN && ser->type != PORT_IMX) + ret = -EINVAL; + if (sport->port.irq != ser->irq) + ret = -EINVAL; + if (ser->io_type != UPIO_MEM) + ret = -EINVAL; + if (sport->port.uartclk / 16 != ser->baud_base) + ret = -EINVAL; + if ((void *)sport->port.mapbase != ser->iomem_base) + ret = -EINVAL; + if (sport->port.iobase != ser->port) + ret = -EINVAL; + if (ser->hub6 != 0) + ret = -EINVAL; + return ret; +} + +static struct uart_ops imx_pops = { + .tx_empty = imx_tx_empty, + .set_mctrl = imx_set_mctrl, + .get_mctrl = imx_get_mctrl, + .stop_tx = imx_stop_tx, + .start_tx = imx_start_tx, + .stop_rx = imx_stop_rx, + .enable_ms = imx_enable_ms, + .break_ctl = imx_break_ctl, + .startup = imx_startup, + .shutdown = imx_shutdown, + .set_termios = imx_set_termios, + .type = imx_type, + .release_port = imx_release_port, + .request_port = imx_request_port, + .config_port = imx_config_port, + .verify_port = imx_verify_port, +}; + +static struct imx_port imx_ports[] = { + { + .txirq = UART1_MINT_TX, + .rxirq = UART1_MINT_RX, + .port = { + .type = PORT_IMX, + .iotype = SERIAL_IO_MEM, + .membase = (void *)IMX_UART1_BASE, + .mapbase = IMX_UART1_BASE, /* FIXME */ + .irq = UART1_MINT_RX, + .uartclk = 16000000, + .fifosize = 8, + .flags = ASYNC_BOOT_AUTOCONF, + .ops = &imx_pops, + .line = 0, + }, + }, { + .txirq = UART2_MINT_TX, + .rxirq = UART2_MINT_RX, + .port = { + .type = PORT_IMX, + .iotype = SERIAL_IO_MEM, + .membase = (void *)IMX_UART2_BASE, + .mapbase = IMX_UART2_BASE, /* FIXME */ + .irq = UART2_MINT_RX, + .uartclk = 16000000, + .fifosize = 8, + .flags = ASYNC_BOOT_AUTOCONF, + .ops = &imx_pops, + .line = 1, + }, + } +}; + +/* + * Setup the IMX serial ports. + * Note also that we support "console=ttySMXx" where "x" is either 0 or 1. + * Which serial port this ends up being depends on the machine you're + * running this kernel on. I'm not convinced that this is a good idea, + * but that's the way it traditionally works. + * + */ +static void __init imx_init_ports(void) +{ + static int first = 1; + int i; + + if (!first) + return; + first = 0; + + for (i = 0; i < ARRAY_SIZE(imx_ports); i++) { + init_timer(&imx_ports[i].timer); + imx_ports[i].timer.function = imx_timeout; + imx_ports[i].timer.data = (unsigned long)&imx_ports[i]; + } + + imx_gpio_mode(PC9_PF_UART1_CTS); + imx_gpio_mode(PC10_PF_UART1_RTS); + imx_gpio_mode(PC11_PF_UART1_TXD); + imx_gpio_mode(PC12_PF_UART1_RXD); + imx_gpio_mode(PB28_PF_UART2_CTS); + imx_gpio_mode(PB29_PF_UART2_RTS); + + imx_gpio_mode(PB30_PF_UART2_TXD); + imx_gpio_mode(PB31_PF_UART2_RXD); + +#if 0 /* We don't need these, on the mx1 the _modem_ side of the uart + * is implemented. + */ + imx_gpio_mode(PD7_AF_UART2_DTR); + imx_gpio_mode(PD8_AF_UART2_DCD); + imx_gpio_mode(PD9_AF_UART2_RI); + imx_gpio_mode(PD10_AF_UART2_DSR); +#endif + + +} + +#ifdef CONFIG_SERIAL_IMX_CONSOLE + +/* + * Interrupts are disabled on entering + */ +static void +imx_console_write(struct console *co, const char *s, unsigned int count) +{ + struct imx_port *sport = &imx_ports[co->index]; + unsigned int old_ucr1, old_ucr2, i; + + /* + * First, save UCR1/2 and then disable interrupts + */ + old_ucr1 = UCR1((u32)sport->port.membase); + old_ucr2 = UCR2((u32)sport->port.membase); + + UCR1((u32)sport->port.membase) = + (old_ucr1 | UCR1_UARTCLKEN | UCR1_UARTEN) + & ~(UCR1_TXMPTYEN | UCR1_RRDYEN); + UCR2((u32)sport->port.membase) = old_ucr2 | UCR2_TXEN; + + /* + * Now, do each character + */ + for (i = 0; i < count; i++) { + + while ((UTS((u32)sport->port.membase) & UTS_TXFULL)) + barrier(); + + URTX0((u32)sport->port.membase) = s[i]; + + if (s[i] == '\n') { + while ((UTS((u32)sport->port.membase) & UTS_TXFULL)) + barrier(); + URTX0((u32)sport->port.membase) = '\r'; + } + } + + /* + * Finally, wait for transmitter to become empty + * and restore UCR1/2 + */ + while (!(USR2((u32)sport->port.membase) & USR2_TXDC)); + + UCR1((u32)sport->port.membase) = old_ucr1; + UCR2((u32)sport->port.membase) = old_ucr2; +} + +/* + * If the port was already initialised (eg, by a boot loader), + * try to determine the current setup. + */ +static void __init +imx_console_get_options(struct imx_port *sport, int *baud, + int *parity, int *bits) +{ + if ( UCR1((u32)sport->port.membase) | UCR1_UARTEN ) { + /* ok, the port was enabled */ + unsigned int ucr2, ubir,ubmr, uartclk; + + ucr2 = UCR2((u32)sport->port.membase); + + *parity = 'n'; + if (ucr2 & UCR2_PREN) { + if (ucr2 & UCR2_PROE) + *parity = 'o'; + else + *parity = 'e'; + } + + if (ucr2 & UCR2_WS) + *bits = 8; + else + *bits = 7; + + ubir = UBIR((u32)sport->port.membase) & 0xffff; + ubmr = UBMR((u32)sport->port.membase) & 0xffff; + uartclk = sport->port.uartclk; + + *baud = ((uartclk/16) * (ubir + 1)) / (ubmr + 1); + } +} + +static int __init +imx_console_setup(struct console *co, char *options) +{ + struct imx_port *sport; + int baud = 9600; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + + /* + * Check whether an invalid uart number has been specified, and + * if so, search for the first available port that does have + * console support. + */ + if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports)) + co->index = 0; + sport = &imx_ports[co->index]; + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + else + imx_console_get_options(sport, &baud, &parity, &bits); + + return uart_set_options(&sport->port, co, baud, parity, bits, flow); +} + +extern struct uart_driver imx_reg; +static struct console imx_console = { + .name = "ttySMX", + .write = imx_console_write, + .device = uart_console_device, + .setup = imx_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &imx_reg, +}; + +static int __init imx_rs_console_init(void) +{ + imx_init_ports(); + register_console(&imx_console); + return 0; +} +console_initcall(imx_rs_console_init); + +#define IMX_CONSOLE &imx_console +#else +#define IMX_CONSOLE NULL +#endif + +static struct uart_driver imx_reg = { + .owner = THIS_MODULE, + .driver_name = DRIVER_NAME, + .dev_name = "ttySMX", + .devfs_name = "ttsmx/", + .major = SERIAL_IMX_MAJOR, + .minor = MINOR_START, + .nr = ARRAY_SIZE(imx_ports), + .cons = IMX_CONSOLE, +}; + +static int serial_imx_suspend(struct device *_dev, u32 state, u32 level) +{ + struct imx_port *sport = dev_get_drvdata(_dev); + + if (sport && level == SUSPEND_DISABLE) + uart_suspend_port(&imx_reg, &sport->port); + + return 0; +} + +static int serial_imx_resume(struct device *_dev, u32 level) +{ + struct imx_port *sport = dev_get_drvdata(_dev); + + if (sport && level == RESUME_ENABLE) + uart_resume_port(&imx_reg, &sport->port); + + return 0; +} + +static int serial_imx_probe(struct device *_dev) +{ + struct platform_device *dev = to_platform_device(_dev); + + imx_ports[dev->id].port.dev = _dev; + uart_add_one_port(&imx_reg, &imx_ports[dev->id].port); + dev_set_drvdata(_dev, &imx_ports[dev->id]); + return 0; +} + +static int serial_imx_remove(struct device *_dev) +{ + struct imx_port *sport = dev_get_drvdata(_dev); + + dev_set_drvdata(_dev, NULL); + + if (sport) + uart_remove_one_port(&imx_reg, &sport->port); + + return 0; +} + +static struct device_driver serial_imx_driver = { + .name = "imx-uart", + .bus = &platform_bus_type, + .probe = serial_imx_probe, + .remove = serial_imx_remove, + + .suspend = serial_imx_suspend, + .resume = serial_imx_resume, +}; + +static int __init imx_serial_init(void) +{ + int ret; + + printk(KERN_INFO "Serial: IMX driver\n"); + + imx_init_ports(); + + ret = uart_register_driver(&imx_reg); + if (ret) + return ret; + + ret = driver_register(&serial_imx_driver); + if (ret != 0) + uart_unregister_driver(&imx_reg); + + return 0; +} + +static void __exit imx_serial_exit(void) +{ + uart_unregister_driver(&imx_reg); +} + +module_init(imx_serial_init); +module_exit(imx_serial_exit); + +MODULE_AUTHOR("Sascha Hauer"); +MODULE_DESCRIPTION("IMX generic serial port driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 411e63d07626..8939a08d5b16 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -29,6 +29,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * + * 2004-08-06 Harald Welte <laforge@gnumonks.org> + * - Enable BREAK interrupt + * - Add support for sysreq + * * TODO: - Add DMA support * - Defer port shutdown to a few seconds after close * - maybe put something right into uap->clk_divisor @@ -36,6 +40,7 @@ #undef DEBUG #undef DEBUG_HARD +#undef USE_CTRL_O_SYSRQ #include <linux/config.h> #include <linux/module.h> @@ -54,6 +59,7 @@ #include <linux/adb.h> #include <linux/pmu.h> #include <linux/bitops.h> +#include <linux/sysrq.h> #include <asm/sections.h> #include <asm/io.h> #include <asm/irq.h> @@ -64,6 +70,10 @@ #include <asm/macio.h> #include <asm/semaphore.h> +#if defined (CONFIG_SERIAL_PMACZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + #include <linux/serial.h> #include <linux/serial_core.h> @@ -259,8 +269,27 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap, } ch &= uap->parity_mask; - if (ch == 0 && uap->prev_status & BRK_ABRT) - r1 |= BRK_ABRT; + if (ch == 0 && uap->flags & PMACZILOG_FLAG_BREAK) { + uap->flags &= ~PMACZILOG_FLAG_BREAK; + } + +#ifdef CONFIG_MAGIC_SYSRQ +#ifdef USE_CTRL_O_SYSRQ + /* Handle the SysRq ^O Hack */ + if (ch == '\x0f') { + uap->port.sysrq = jiffies + HZ*5; + goto next_char; + } +#endif /* USE_CTRL_O_SYSRQ */ + if (uap->port.sysrq) { + int swallow; + spin_unlock(&uap->port.lock); + swallow = uart_handle_sysrq_char(&uap->port, ch, regs); + spin_lock(&uap->port.lock); + if (swallow) + goto next_char; + } +#endif /* CONFIG_MAGIC_SYSRQ */ /* A real serial line, record the character and status. */ if (drop) @@ -276,10 +305,8 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap, pmz_debug("pmz: got break !\n"); r1 &= ~(PAR_ERR | CRC_ERR); uap->port.icount.brk++; - if (uart_handle_break(&uap->port)) { - pmz_debug("pmz: do handle break !\n"); + if (uart_handle_break(&uap->port)) goto next_char; - } } else if (r1 & PAR_ERR) uap->port.icount.parity++; @@ -295,10 +322,6 @@ static struct tty_struct *pmz_receive_chars(struct uart_pmac_port *uap, else if (r1 & CRC_ERR) *tty->flip.flag_buf_ptr = TTY_FRAME; } - if (uart_handle_sysrq_char(&uap->port, ch, regs)) { - pmz_debug("pmz: sysrq swallowed the char\n"); - goto next_char; - } if (uap->port.ignore_status_mask == 0xff || (r1 & uap->port.ignore_status_mask) == 0) { @@ -364,6 +387,9 @@ static void pmz_status_handle(struct uart_pmac_port *uap, struct pt_regs *regs) wake_up_interruptible(&uap->port.info->delta_msr_wait); } + if (status & BRK_ABRT) + uap->flags |= PMACZILOG_FLAG_BREAK; + uap->prev_status = status; } @@ -872,8 +898,8 @@ static int __pmz_startup(struct uart_pmac_port *uap) uap->curregs[R13] = 0; uap->curregs[R14] = BRENAB; - /* Clear handshaking */ - uap->curregs[R15] = 0; + /* Clear handshaking, enable BREAK interrupts */ + uap->curregs[R15] = BRKIE; /* Master interrupt enable */ uap->curregs[R9] |= NV | MIE; @@ -1308,6 +1334,8 @@ static void __pmz_set_termios(struct uart_port *port, struct termios *termios, /* Load registers to the chip */ pmz_maybe_update_regs(uap); } + uart_update_timeout(port, termios->c_cflag, baud); + pmz_debug("pmz: set_termios() done.\n"); } diff --git a/drivers/serial/pmac_zilog.h b/drivers/serial/pmac_zilog.h index 63bb9716c42b..9be17fd3778d 100644 --- a/drivers/serial/pmac_zilog.h +++ b/drivers/serial/pmac_zilog.h @@ -47,6 +47,7 @@ struct uart_pmac_port { #define PMACZILOG_FLAG_IS_OPEN 0x00002000 #define PMACZILOG_FLAG_IS_IRQ_ON 0x00004000 #define PMACZILOG_FLAG_IS_EXTCLK 0x00008000 +#define PMACZILOG_FLAG_BREAK 0x00010000 unsigned char parity_mask; unsigned char prev_status; diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index d863368e45e2..8aa264f4cb42 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c @@ -45,8 +45,6 @@ #include <linux/serial_core.h> -#include <asm/arch/serial.h> - #define DEV_MAJOR 204 #define DEV_MINOR 16 #define DEV_NR 3 @@ -60,6 +58,15 @@ #define UART_REG_SIZE 32 +#define UART_R_DATA (0x00) +#define UART_R_FCON (0x04) +#define UART_R_BRCON (0x08) +#define UART_R_CON (0x0c) +#define UART_R_STATUS (0x10) +#define UART_R_RAWISR (0x14) +#define UART_R_INTEN (0x18) +#define UART_R_ISR (0x1c) + #define UARTEN (0x01) /* UART enable */ #define SIRDIS (0x02) /* Serial IR disable (UART1 only) */ diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c index 3d7275c2ab6b..9e1a835f7e5c 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/acornfb.c @@ -1326,7 +1326,6 @@ static int __init acornfb_probe(struct device *dev) } } - fb_info.currcon = -1; fb_info.screen_base = (char *)SCREEN_BASE; fb_info.fix.smem_start = SCREEN_START; current_par.using_vram = 0; diff --git a/drivers/video/aty/Makefile b/drivers/video/aty/Makefile index 8aa5368736ac..5538f3cf6bff 100644 --- a/drivers/video/aty/Makefile +++ b/drivers/video/aty/Makefile @@ -2,9 +2,9 @@ obj-$(CONFIG_FB_ATY) += atyfb.o obj-$(CONFIG_FB_ATY128) += aty128fb.o obj-$(CONFIG_FB_RADEON) += radeonfb.o -atyfb-y := atyfb_base.o mach64_accel.o +atyfb-y := atyfb_base.o mach64_accel.o mach64_cursor.o atyfb-$(CONFIG_FB_ATY_GX) += mach64_gx.o -atyfb-$(CONFIG_FB_ATY_CT) += mach64_ct.o mach64_cursor.o +atyfb-$(CONFIG_FB_ATY_CT) += mach64_ct.o atyfb-objs := $(atyfb-y) radeonfb-y := radeon_base.o radeon_pm.o radeon_monitor.o radeon_accel.o diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 064c0b12bc7f..83545ae8d122 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -939,7 +939,7 @@ static void __iomem * __devinit aty128_find_mem_vbios(struct aty128fb_par *par) rom_base = ioremap(segstart, 0x10000); if (rom_base == NULL) return NULL; - if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa)) + if (readb(rom_base) == 0x55 && readb(rom_base + 1) == 0xaa) break; iounmap(rom_base); rom_base = NULL; diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 37c40d724b34..87ea3ef14ba3 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -292,7 +292,7 @@ static struct fb_ops atyfb_ops = { .fb_fillrect = atyfb_fillrect, .fb_copyarea = atyfb_copyarea, .fb_imageblit = atyfb_imageblit, - .fb_cursor = atyfb_cursor, + .fb_cursor = soft_cursor, #ifdef __sparc__ .fb_mmap = atyfb_mmap, #endif @@ -2191,6 +2191,14 @@ static int __init aty_init(struct fb_info *info, const char *name) par->aty_cmap_regs = (struct aty_cmap_regs __iomem *) (par->ati_regbase + 0xc0); +#ifdef CONFIG_PPC_PMAC + /* The Apple iBook1 uses non-standard memory frequencies. We detect it + * and set the frequency manually. */ + if (machine_is_compatible("PowerBook2,1")) { + par->pll_limits.mclk = 70; + par->pll_limits.xclk = 53; + } +#endif if (pll) par->pll_limits.pll_max = pll; if (mclk) diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index b51f966c6851..639ca7223ee4 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -1749,7 +1749,6 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) { struct fb_info *info = rinfo->info; - info->currcon = -1; info->par = rinfo; info->pseudo_palette = rinfo->pseudo_palette; info->flags = FBINFO_DEFAULT diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 3b2c5a5e6c12..17c75483e179 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -361,7 +361,6 @@ static void bw2_init_one(struct sbus_dev *sdev) if (!all->info.screen_base) all->info.screen_base = (char *) sbus_ioremap(resp, 0, all->par.fbsize, "bw2 ram"); - all->info.currcon = -1; all->info.par = &all->par; bw2_blank(0, &all->info); diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index c43322b2d666..4ead66f95efe 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c @@ -552,7 +552,6 @@ static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node) all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; all->info.fbops = &cg14_ops; - all->info.currcon = -1; all->info.par = &all->par; __cg14_reset(&all->par); diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index 078394109714..295624ded17f 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -408,7 +408,6 @@ static void cg3_init_one(struct sbus_dev *sdev) all->info.screen_base = (char *) sbus_ioremap(&sdev->resource[0], CG3_RAM_OFFSET, all->par.fbsize, "cg3 ram"); - all->info.currcon = -1; all->info.par = &all->par; cg3_blank(0, &all->info); diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c index be87a66f1f06..9b8a465e588d 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/cg6.c @@ -723,7 +723,6 @@ static void cg6_init_one(struct sbus_dev *sdev) all->info.screen_base = (char *) sbus_ioremap(&sdev->resource[0], CG6_RAM_OFFSET, all->par.fbsize, "cgsix ram"); - all->info.currcon = -1; all->info.par = &all->par; all->info.var.accel_flags = FB_ACCELF_TEXT; diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index a8d97b857698..3bbee5a9c9bf 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -2246,7 +2246,6 @@ static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo) struct fb_info *info = cinfo->info; struct fb_var_screeninfo *var = &info->var; - info->currcon = -1; info->par = cinfo; info->pseudo_palette = cinfo->pseudo_palette; info->flags = FBINFO_DEFAULT diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 5e07c6270512..dda691682c3a 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -200,12 +200,24 @@ static irqreturn_t fb_vbl_detect(int irq, void *dummy, struct pt_regs *fp) } #endif +static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info) +{ + return (info->state != FBINFO_STATE_RUNNING || + vt_cons[vc->vc_num]->vc_mode != KD_TEXT); +} + static inline int get_color(struct vc_data *vc, struct fb_info *info, u16 c, int is_fg) { int depth = fb_get_color_depth(info); int color = 0; + if (!info->fbops->fb_blank && console_blanked) { + unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + + c = vc->vc_video_erase_char & charmask; + } + if (depth != 1) color = (is_fg) ? attr_fgcol((vc->vc_hi_font_mask) ? 9 : 8, c) : attr_bgcol((vc->vc_hi_font_mask) ? 13 : 12, c); @@ -217,6 +229,9 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info, int fg = (info->fix.visual != FB_VISUAL_MONO01) ? 1 : 0; int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : 1; + if (!info->fbops->fb_blank && console_blanked) + fg = bg; + color = (is_fg) ? fg : bg; break; } @@ -237,6 +252,7 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info, break; } + return color; } @@ -249,12 +265,11 @@ static void fb_flashcursor(void *private) int c; int mode; - if (info->currcon != -1) - vc = vc_cons[info->currcon].d; + if (ops->currcon != -1) + vc = vc_cons[ops->currcon].d; - if (info->state != FBINFO_STATE_RUNNING || - !vc || !CON_IS_VISIBLE(vc) || - vt_cons[vc->vc_num]->vc_mode != KD_TEXT || + if (!vc || !CON_IS_VISIBLE(vc) || + fbcon_is_inactive(vc, info) || registered_fb[con2fb_map[vc->vc_num]] != info) return; acquire_console_sem(); @@ -284,9 +299,10 @@ static irqreturn_t fb_vbl_handler(int irq, void *dev_id, struct pt_regs *fp) static void cursor_timer_handler(unsigned long dev_addr) { struct fb_info *info = (struct fb_info *) dev_addr; - + struct fbcon_ops *ops = info->fbcon_par; + schedule_work(&info->queue); - mod_timer(&info->cursor_timer, jiffies + HZ/5); + mod_timer(&ops->cursor_timer, jiffies + HZ/5); } int __init fb_console_setup(char *this_opt) @@ -502,6 +518,7 @@ static int set_con2fb_map(int unit, int newidx, int user) int oldidx = con2fb_map[unit]; struct fb_info *info = registered_fb[newidx]; struct fb_info *oldinfo = NULL; + struct fbcon_ops *ops; int found; if (oldidx == newidx) @@ -524,8 +541,10 @@ static int set_con2fb_map(int unit, int newidx, int user) con2fb_map[unit] = newidx; if (!found) { - struct fbcon_ops *ops = NULL; int err = 0; + + ops = NULL; + if (!try_module_get(info->fbops->owner)) { err = -ENODEV; } @@ -560,7 +579,8 @@ static int set_con2fb_map(int unit, int newidx, int user) * fbcon should release it. */ if (oldinfo && !search_fb_in_map(oldidx)) { - struct fbcon_ops *ops = (struct fbcon_ops *) oldinfo->fbcon_par; + + ops = oldinfo->fbcon_par; if (oldinfo->fbops->fb_release && oldinfo->fbops->fb_release(oldinfo, 0)) { @@ -574,28 +594,33 @@ static int set_con2fb_map(int unit, int newidx, int user) } if (oldinfo->queue.func == fb_flashcursor) - del_timer_sync(&oldinfo->cursor_timer); + del_timer_sync(&ops->cursor_timer); kfree(ops->cursor_state.mask); kfree(ops->cursor_data); kfree(oldinfo->fbcon_par); + oldinfo->fbcon_par = NULL; module_put(oldinfo->fbops->owner); } if (!found) { if (!info->queue.func || info->queue.func == fb_flashcursor) { + + ops = info->fbcon_par; + if (!info->queue.func) INIT_WORK(&info->queue, fb_flashcursor, info); - init_timer(&info->cursor_timer); - info->cursor_timer.function = cursor_timer_handler; - info->cursor_timer.expires = jiffies + HZ / 5; - info->cursor_timer.data = (unsigned long ) info; - add_timer(&info->cursor_timer); + init_timer(&ops->cursor_timer); + ops->cursor_timer.function = cursor_timer_handler; + ops->cursor_timer.expires = jiffies + HZ / 5; + ops->cursor_timer.data = (unsigned long ) info; + add_timer(&ops->cursor_timer); } } - info->currcon = fg_console; + ops = info->fbcon_par; + ops->currcon = fg_console; con2fb_map_boot[unit] = newidx; if (info->fbops->fb_set_par) @@ -690,7 +715,6 @@ static const char *fbcon_startup(void) info = registered_fb[info_idx]; if (!info) return NULL; - info->currcon = -1; owner = info->fbops->owner; if (!try_module_get(owner)) @@ -707,6 +731,7 @@ static const char *fbcon_startup(void) } memset(ops, 0, sizeof(struct fbcon_ops)); + ops->currcon = -1; info->fbcon_par = ops; set_blitting_type(vc, info, NULL); @@ -821,11 +846,11 @@ static const char *fbcon_startup(void) if (!info->queue.func) { INIT_WORK(&info->queue, fb_flashcursor, info); - init_timer(&info->cursor_timer); - info->cursor_timer.function = cursor_timer_handler; - info->cursor_timer.expires = jiffies + HZ / 5; - info->cursor_timer.data = (unsigned long ) info; - add_timer(&info->cursor_timer); + init_timer(&ops->cursor_timer); + ops->cursor_timer.function = cursor_timer_handler; + ops->cursor_timer.expires = jiffies + HZ / 5; + ops->cursor_timer.data = (unsigned long ) info; + add_timer(&ops->cursor_timer); } return display_desc; } @@ -978,9 +1003,7 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height, struct display *p = &fb_display[vc->vc_num]; u_int y_break; - if (!info->fbops->fb_blank && console_blanked) - return; - if (info->state != FBINFO_STATE_RUNNING) + if (fbcon_is_inactive(vc, info)) return; if (!height || !width) @@ -1005,17 +1028,10 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s, struct display *p = &fb_display[vc->vc_num]; struct fbcon_ops *ops = info->fbcon_par; - if (!info->fbops->fb_blank && console_blanked) - return; - if (info->state != FBINFO_STATE_RUNNING) - return; - - if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT) - return; - - ops->putcs(vc, info, s, count, real_y(p, ypos), xpos, - get_color(vc, info, scr_readw(s), 1), - get_color(vc, info, scr_readw(s), 0)); + if (!fbcon_is_inactive(vc, info)) + ops->putcs(vc, info, s, count, real_y(p, ypos), xpos, + get_color(vc, info, scr_readw(s), 1), + get_color(vc, info, scr_readw(s), 0)); } static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos) @@ -1031,7 +1047,8 @@ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only) struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = info->fbcon_par; - ops->clear_margins(vc, info, bottom_only); + if (!fbcon_is_inactive(vc, info)) + ops->clear_margins(vc, info, bottom_only); } static void fbcon_cursor(struct vc_data *vc, int mode) @@ -1042,6 +1059,9 @@ static void fbcon_cursor(struct vc_data *vc, int mode) int y = real_y(p, vc->vc_y); int c = scr_readw((u16 *) vc->vc_pos); + if (fbcon_is_inactive(vc, info)) + return; + ops->cursor_flash = 1; if (mode & CM_SOFTBACK) { mode &= ~CM_SOFTBACK; @@ -1067,7 +1087,7 @@ static int scrollback_current = 0; int update_var(int con, struct fb_info *info) { - if (con == info->currcon) + if (con == ((struct fbcon_ops *)info->fbcon_par)->currcon) return fb_pan_display(info, &info->var); return 0; } @@ -1494,11 +1514,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, struct fbcon_ops *ops = info->fbcon_par; int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK; - if (!info->fbops->fb_blank && console_blanked) - return 0; - - if (!count || vt_cons[vc->vc_num]->vc_mode != KD_TEXT) - return 0; + if (fbcon_is_inactive(vc, info)) + return -EINVAL; fbcon_cursor(vc, CM_ERASE); @@ -1687,7 +1704,7 @@ static void fbcon_bmove(struct vc_data *vc, int sy, int sx, int dy, int dx, struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct display *p = &fb_display[vc->vc_num]; - if (!info->fbops->fb_blank && console_blanked) + if (fbcon_is_inactive(vc, info)) return; if (!width || !height) @@ -1867,7 +1884,7 @@ static int fbcon_switch(struct vc_data *vc) logo_shown = FBCON_LOGO_CANSHOW; } - prev_console = info->currcon; + prev_console = ((struct fbcon_ops *)info->fbcon_par)->currcon; /* * FIXME: If we have multiple fbdev's loaded, we need to @@ -1878,10 +1895,12 @@ static int fbcon_switch(struct vc_data *vc) * info->currcon = vc->vc_num; */ for (i = 0; i < FB_MAX; i++) { - if (registered_fb[i] != NULL) - registered_fb[i]->currcon = vc->vc_num; - } + if (registered_fb[i] != NULL && registered_fb[i]->fbcon_par) { + struct fbcon_ops *ops = registered_fb[i]->fbcon_par; + ops->currcon = vc->vc_num; + } + } memset(&var, 0, sizeof(struct fb_var_screeninfo)); display_to_var(&var, p); var.activate = FB_ACTIVATE_NOW; @@ -1929,9 +1948,8 @@ static int fbcon_switch(struct vc_data *vc) update_var(vc->vc_num, info); fbcon_set_palette(vc, color_table); + fbcon_clear_margins(vc, 0); - if (vt_cons[vc->vc_num]->vc_mode == KD_TEXT) - fbcon_clear_margins(vc, 0); if (logo_shown == FBCON_LOGO_DRAW) { logo_shown = fg_console; @@ -1950,8 +1968,9 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) { unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; - struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; + struct fbcon_ops *ops = info->fbcon_par; struct display *p = &fb_display[vc->vc_num]; + int retval = 0; if (mode_switch) { struct fb_var_screeninfo var = info->var; @@ -1968,15 +1987,12 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) if (info->flags & FBINFO_MISC_MODESWITCHLATE) info->flags |= FBINFO_MISC_MODESWITCH; - if (blank) { - fbcon_cursor(vc, CM_ERASE); - return 0; - } - - if (!(info->flags & FBINFO_MISC_MODESWITCHLATE)) { + if (!blank && !(info->flags & FBINFO_MISC_MODESWITCHLATE)) { var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; fb_set_var(info, &var); } + + return 0; } fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); @@ -1999,11 +2015,12 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch) } else fbcon_clear(vc, 0, 0, height, vc->vc_cols); vc->vc_video_erase_char = oldc; - } else + } else if (!fbcon_is_inactive(vc, info)) update_screen(vc->vc_num); - return 0; - } else - return fb_blank(info, blank); + } else if (vt_cons[vc->vc_num]->vc_mode == KD_TEXT) + retval = info->fbops->fb_blank(blank, info); + + return retval; } static void fbcon_free_font(struct display *p) @@ -2307,8 +2324,9 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table) int i, j, k, depth; u8 val; - if (!info->fbops->fb_blank && console_blanked) + if (fbcon_is_inactive(vc, info)) return -EINVAL; + depth = fb_get_color_depth(info); if (depth > 3) { for (i = j = 0; i < 16; i++) { @@ -2468,10 +2486,9 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines) if (scrollback_current == scrollback_old) return 0; - if (!info->fbops->fb_blank && - (console_blanked || vt_cons[vc->vc_num]->vc_mode != KD_TEXT - || !lines)) + if (fbcon_is_inactive(vc, info)) return 0; + fbcon_cursor(vc, CM_ERASE); offset = p->yscroll - scrollback_current; @@ -2500,7 +2517,7 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines) static int fbcon_set_origin(struct vc_data *vc) { - if (softback_lines && !console_blanked) + if (softback_lines) fbcon_scrolldelta(vc, softback_lines); return 0; } @@ -2508,10 +2525,11 @@ static int fbcon_set_origin(struct vc_data *vc) static void fbcon_suspended(struct fb_info *info) { struct vc_data *vc = NULL; + struct fbcon_ops *ops = info->fbcon_par; - if (info->currcon < 0) + if (!ops || ops->currcon < 0) return; - vc = vc_cons[info->currcon].d; + vc = vc_cons[ops->currcon].d; /* Clear cursor, restore saved data */ fbcon_cursor(vc, CM_ERASE); @@ -2520,21 +2538,28 @@ static void fbcon_suspended(struct fb_info *info) static void fbcon_resumed(struct fb_info *info) { struct vc_data *vc; + struct fbcon_ops *ops = info->fbcon_par; - if (info->currcon < 0) + if (!ops || ops->currcon < 0) return; - vc = vc_cons[info->currcon].d; + vc = vc_cons[ops->currcon].d; update_screen(vc->vc_num); } static void fbcon_modechanged(struct fb_info *info) { - struct vc_data *vc = vc_cons[info->currcon].d; + struct fbcon_ops *ops = info->fbcon_par; + struct vc_data *vc; struct display *p; int rows, cols; - if (info->currcon < 0 || vt_cons[info->currcon]->vc_mode != + if (!ops) + return; + + vc = vc_cons[ops->currcon].d; + + if (ops->currcon < 0 || vt_cons[ops->currcon]->vc_mode != KD_TEXT) return; p = &fb_display[vc->vc_num]; diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index 095378eb8e19..fabf64c8501f 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h @@ -61,7 +61,9 @@ struct fbcon_ops { void (*cursor)(struct vc_data *vc, struct fb_info *info, struct display *p, int mode, int fg, int bg); + struct timer_list cursor_timer; /* Cursor timer */ struct fb_cursor cursor_state; + int currcon; /* Current VC. */ int cursor_flash; char *cursor_data; }; diff --git a/drivers/video/console/font_6x11.c b/drivers/video/console/font_6x11.c index 32ff420cf840..c52f1294044a 100644 --- a/drivers/video/console/font_6x11.c +++ b/drivers/video/console/font_6x11.c @@ -10,7 +10,7 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { - /* 0 0x00 '^A' */ + /* 0 0x00 '^@' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -23,405 +23,405 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 1 0x01 '^B' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + /* 1 0x01 '^A' */ 0x00, /* 00000000 */ + 0x78, /* 0 000 */ + 0x84, /* 0000 00 */ + 0xcc, /* 00 00 */ + 0x84, /* 0000 00 */ + 0xb4, /* 0 0 00 */ + 0x84, /* 0000 00 */ + 0x78, /* 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 2 0x02 '^C' */ - 0x00, /* 00000000 */ + /* 2 0x02 '^B' */ 0x00, /* 00000000 */ + 0x78, /* 0 000 */ + 0xfc, /* 00 */ + 0xb4, /* 0 0 00 */ + 0xfc, /* 00 */ + 0xcc, /* 00 00 */ + 0xfc, /* 00 */ + 0x78, /* 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + + /* 3 0x03 '^C' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x7c, /* 0 00 */ + 0x7c, /* 0 00 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 3 0x03 '^D' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + /* 4 0x04 '^D' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x7c, /* 0 00 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 4 0x04 '^E' */ - 0x00, /* 00000000 */ + /* 5 0x05 '^E' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x38, /* 00 000 */ + 0x6c, /* 0 0 00 */ + 0x6c, /* 0 0 00 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + + /* 6 0x06 '^F' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x7c, /* 0 00 */ + 0x7c, /* 0 00 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 5 0x05 '^F' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + /* 7 0x07 '^G' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0x30, /* 00 0000 */ + 0x78, /* 0 000 */ + 0x30, /* 00 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 6 0x06 '^G' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ + /* 8 0x08 '^H' */ + 0xff, /* */ + 0xff, /* */ + 0xff, /* */ + 0xcf, /* 00 */ + 0x87, /* 0000 */ + 0xcf, /* 00 */ + 0xff, /* */ + 0xff, /* */ + 0xff, /* */ + 0xff, /* */ + 0xff, /* */ + + /* 9 0x09 '^I' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - - /* 7 0x07 '^H' */ + 0x30, /* 00 0000 */ + 0x48, /* 0 00 000 */ + 0x84, /* 0000 00 */ + 0x48, /* 0 00 000 */ + 0x30, /* 00 0000 */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 8 0x08 '^I' */ + /* 10 0x0a '^J' */ + 0xff, /* */ + 0xff, /* */ + 0xcf, /* 00 */ + 0xb7, /* 0 0 */ + 0x7b, /* 0 0 */ + 0xb7, /* 0 0 */ + 0xcf, /* 00 */ + 0xff, /* */ + 0xff, /* */ + 0xff, /* */ + 0xff, /* */ + + /* 11 0x0b '^K' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x14, /* 000 0 00 */ + 0x20, /* 00 00000 */ + 0x78, /* 0 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 9 0x09 '^J' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + /* 12 0x0c '^L' */ 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x7c, /* 0 00 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 10 0x0a '^K' */ + /* 13 0x0d '^M' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ + 0x24, /* 00 00 00 */ 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x20, /* 00 00000 */ + 0x20, /* 00 00000 */ + 0xe0, /* 00000 */ + 0xc0, /* 000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 11 0x0b '^L' */ + /* 14 0x0e '^N' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x7c, /* 0 00 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0xcc, /* 00 00 */ + 0xcc, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 12 0x0c '^M' */ + /* 15 0x0f '^O' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x10, /* 000 0000 */ + 0x54, /* 0 0 0 00 */ + 0x38, /* 00 000 */ + 0x6c, /* 0 0 00 */ + 0x38, /* 00 000 */ + 0x54, /* 0 0 0 00 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 13 0x0d '^N' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + /* 16 0x10 '^P' */ 0x00, /* 00000000 */ + 0x40, /* 0 000000 */ + 0x60, /* 0 00000 */ + 0x70, /* 0 0000 */ + 0x7c, /* 0 00 */ + 0x70, /* 0 0000 */ + 0x60, /* 0 00000 */ + 0x40, /* 0 000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + + /* 17 0x11 '^Q' */ 0x00, /* 00000000 */ + 0x04, /* 00000 00 */ + 0x0c, /* 0000 00 */ + 0x1c, /* 000 00 */ + 0x7c, /* 0 00 */ + 0x1c, /* 000 00 */ + 0x0c, /* 0000 00 */ + 0x04, /* 00000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 14 0x0e '^O' */ + /* 18 0x12 '^R' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x54, /* 0 0 0 00 */ + 0x10, /* 000 0000 */ + 0x54, /* 0 0 0 00 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 15 0x0f '^P' */ + /* 19 0x13 '^S' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ 0x00, /* 00000000 */ + 0x48, /* 0 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - - /* 16 0x10 '^Q' */ 0x00, /* 00000000 */ + + /* 20 0x14 '^T' */ 0x3c, /* 00 00 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x14, /* 000 0 00 */ + 0x14, /* 000 0 00 */ + 0x14, /* 000 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 17 0x11 '^R' */ + /* 21 0x15 '^U' */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x24, /* 00 00 00 */ + 0x50, /* 0 0 0000 */ + 0x48, /* 0 00 000 */ + 0x24, /* 00 00 00 */ + 0x14, /* 000 0 00 */ + 0x48, /* 0 00 000 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ 0x00, /* 00000000 */ + + /* 22 0x16 '^V' */ 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x54, /* 0 0 0 00 */ - 0x38, /* 00 000 */ - 0x54, /* 0 0 0 00 */ - 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - - /* 18 0x12 '^S' */ - 0x04, /* 00000 00 */ - 0x04, /* 00000 00 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x50, /* 0 0 0000 */ - 0x50, /* 0 0 0000 */ - 0x20, /* 00 00000 */ - 0x20, /* 00 00000 */ + 0xf8, /* 000 */ + 0xf8, /* 000 */ + 0xf8, /* 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 19 0x13 '^T' */ - 0x00, /* 00000000 */ + /* 23 0x17 '^W' */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x38, /* 00 000 */ - 0x7c, /* 0 00 */ - 0x38, /* 00 000 */ + 0x54, /* 0 0 0 00 */ 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 20 0x14 '^U' */ - 0x18, /* 000 000 */ + 0x54, /* 0 0 0 00 */ + 0x38, /* 00 000 */ 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ 0x7c, /* 0 00 */ - 0x78, /* 0 000 */ - 0x78, /* 0 000 */ - 0x7c, /* 0 00 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 21 0x15 '^V' */ + /* 24 0x18 '^X' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x54, /* 0 0 0 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 22 0x16 '^W' */ + /* 25 0x19 '^Y' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x54, /* 0 0 0 00 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 23 0x17 '^X' */ + /* 26 0x1a '^Z' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x7c, /* 0 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - - /* 24 0x18 '^Y' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ + + /* 27 0x1b '^[' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - - /* 25 0x19 '^Z' */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x7c, /* 0 00 */ + 0x20, /* 00 00000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 26 0x1a '^[' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + /* 28 0x1c '^\' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - - /* 27 0x1b '^\' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x78, /* 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 28 0x1c '^]' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ + /* 29 0x1d '^]' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - - /* 29 0x1d '^^' */ + 0x48, /* 0 00 000 */ + 0x84, /* 0000 00 */ + 0xfc, /* 00 */ + 0x84, /* 0000 00 */ + 0x48, /* 0 00 000 */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 30 0x1e '^_' */ + /* 30 0x1e '^^' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x38, /* 00 000 */ + 0x7c, /* 0 00 */ + 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 31 0x1f '^`' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x7c, /* 0 00 */ + 0x38, /* 00 000 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -467,16 +467,16 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { /* 35 0x23 '#' */ 0x00, /* 00000000 */ + 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x7c, /* 0 00 */ 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ 0x7c, /* 0 00 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ /* 36 0x24 '$' */ 0x10, /* 000 0000 */ @@ -493,13 +493,13 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { /* 37 0x25 '%' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x58, /* 0 0 000 */ - 0x28, /* 00 0 000 */ - 0x34, /* 00 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x48, /* 0 00 000 */ + 0x64, /* 0 00 00 */ + 0x64, /* 0 00 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x4c, /* 0 00 00 */ + 0x4c, /* 0 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1610,6 +1610,7 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ /* 123 0x7b '{' */ + 0x04, /* 00000 00 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ @@ -1620,7 +1621,6 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x08, /* 0000 000 */ 0x08, /* 0000 000 */ 0x04, /* 00000 00 */ - 0x00, /* 00000000 */ /* 124 0x7c '|' */ 0x10, /* 000 0000 */ @@ -1636,6 +1636,7 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ /* 125 0x7d '}' */ + 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ @@ -1646,7 +1647,6 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x20, /* 00 00000 */ - 0x00, /* 00000000 */ /* 126 0x7e '~' */ 0x00, /* 00000000 */ @@ -1665,42 +1665,16 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 128 0x80 '\200' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 129 0x81 '\201' */ + 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ - 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x7c, /* 0 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 130 0x82 '\202' */ + /* 128 0x80 '\200' */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ @@ -1709,89 +1683,37 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x40, /* 0 000000 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 131 0x83 '\203' */ 0x10, /* 000 0000 */ - 0x7c, /* 0 00 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x78, /* 0 000 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 132 0x84 '\204' */ - 0x58, /* 0 0 000 */ - 0x44, /* 0 000 00 */ - 0x64, /* 0 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x4c, /* 0 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + 0x20, /* 00 00000 */ 0x00, /* 00000000 */ - /* 133 0x85 '\205' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + /* 129 0x81 '\201' */ 0x00, /* 00000000 */ - - /* 134 0x86 '\206' */ + 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 135 0x87 '\207' */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 136 0x88 '\210' */ - 0x10, /* 000 0000 */ + /* 130 0x82 '\202' */ 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ + 0x7c, /* 0 00 */ + 0x40, /* 0 000000 */ + 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 137 0x89 '\211' */ + /* 131 0x83 '\203' */ 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ @@ -1804,7 +1726,7 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 138 0x8a '\212' */ + /* 132 0x84 '\204' */ 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ @@ -1817,9 +1739,9 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 139 0x8b '\213' */ - 0x34, /* 00 0 00 */ - 0x58, /* 0 0 000 */ + /* 133 0x85 '\205' */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ 0x44, /* 0 000 00 */ @@ -1830,7 +1752,7 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 140 0x8c '\214' */ + /* 134 0x86 '\206' */ 0x18, /* 000 000 */ 0x24, /* 00 00 00 */ 0x18, /* 000 000 */ @@ -1843,7 +1765,7 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 141 0x8d '\215' */ + /* 135 0x87 '\207' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -1856,9 +1778,9 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x20, /* 00 00000 */ 0x00, /* 00000000 */ - /* 142 0x8e '\216' */ - 0x08, /* 0000 000 */ + /* 136 0x88 '\210' */ 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ @@ -1869,9 +1791,9 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 143 0x8f '\217' */ - 0x20, /* 00 00000 */ - 0x10, /* 000 0000 */ + /* 137 0x89 '\211' */ + 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ @@ -1882,9 +1804,9 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 144 0x90 '\220' */ + /* 138 0x8a '\212' */ + 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ @@ -1895,23 +1817,10 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 145 0x91 '\221' */ + /* 139 0x8b '\213' */ 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x40, /* 0 000000 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 146 0x92 '\222' */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ @@ -1921,9 +1830,9 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 147 0x93 '\223' */ - 0x20, /* 00 00000 */ + /* 140 0x8c '\214' */ 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ @@ -1934,9 +1843,9 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 148 0x94 '\224' */ + /* 141 0x8d '\215' */ + 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ @@ -1947,25 +1856,25 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 149 0x95 '\225' */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ + /* 142 0x8e '\216' */ + 0x84, /* 0000 00 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 150 0x96 '\226' */ - 0x34, /* 00 0 00 */ - 0x58, /* 0 0 000 */ - 0x00, /* 00000000 */ + /* 143 0x8f '\217' */ 0x58, /* 0 0 000 */ - 0x64, /* 0 00 00 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x7c, /* 0 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ @@ -1973,33 +1882,46 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 151 0x97 '\227' */ - 0x08, /* 0000 000 */ + /* 144 0x90 '\220' */ 0x10, /* 000 0000 */ + 0x7c, /* 0 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x78, /* 0 000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + + /* 145 0x91 '\221' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ + 0x54, /* 0 0 0 00 */ + 0x5c, /* 0 0 00 */ + 0x50, /* 0 0 0000 */ + 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 152 0x98 '\230' */ - 0x20, /* 00 00000 */ - 0x10, /* 000 0000 */ + /* 146 0x92 '\222' */ 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ + 0x3c, /* 00 00 */ + 0x50, /* 0 0 0000 */ + 0x50, /* 0 0 0000 */ + 0x78, /* 0 000 */ + 0x50, /* 0 0 0000 */ + 0x50, /* 0 0 0000 */ + 0x5c, /* 0 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 153 0x99 '\231' */ + /* 147 0x93 '\223' */ 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ @@ -2012,7 +1934,7 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 154 0x9a '\232' */ + /* 148 0x94 '\224' */ 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ @@ -2025,9 +1947,9 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 155 0x9b '\233' */ - 0x34, /* 00 0 00 */ - 0x58, /* 0 0 000 */ + /* 149 0x95 '\225' */ + 0x20, /* 00 00000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x38, /* 00 000 */ 0x44, /* 0 000 00 */ @@ -2038,9 +1960,9 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 156 0x9c '\234' */ - 0x08, /* 0000 000 */ + /* 150 0x96 '\226' */ 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ @@ -2051,7 +1973,7 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 157 0x9d '\235' */ + /* 151 0x97 '\227' */ 0x20, /* 00 00000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ @@ -2064,59 +1986,46 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 158 0x9e '\236' */ - 0x10, /* 000 0000 */ + /* 152 0x98 '\230' */ + 0x00, /* 00000000 */ 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x3c, /* 00 00 */ + 0x04, /* 00000 00 */ + 0x38, /* 00 000 */ 0x00, /* 00000000 */ - /* 159 0x9f '\237' */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ + /* 153 0x99 '\231' */ + 0x84, /* 0000 00 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x34, /* 00 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 160 0xa0 '\240' */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ 0x38, /* 00 000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 161 0xa1 '\241' */ - 0x18, /* 000 000 */ - 0x24, /* 00 00 00 */ - 0x24, /* 00 00 00 */ - 0x18, /* 000 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + /* 154 0x9a '\232' */ + 0x88, /* 000 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 162 0xa2 '\242' */ + /* 155 0x9b '\233' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x10, /* 000 0000 */ @@ -2129,7 +2038,7 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 163 0xa3 '\243' */ + /* 156 0x9c '\234' */ 0x30, /* 00 0000 */ 0x48, /* 0 00 000 */ 0x40, /* 0 000000 */ @@ -2142,354 +2051,445 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 164 0xa4 '\244' */ - 0x44, /* 0 000 00 */ - 0x24, /* 00 00 00 */ - 0x50, /* 0 0 0000 */ - 0x48, /* 0 00 000 */ - 0x24, /* 00 00 00 */ - 0x14, /* 000 0 00 */ - 0x48, /* 0 00 000 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 165 0xa5 '\245' */ - 0x00, /* 00000000 */ + /* 157 0x9d '\235' */ 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x7c, /* 0 00 */ + 0x44, /* 0 000 00 */ + 0x28, /* 00 0 000 */ 0x7c, /* 0 00 */ + 0x10, /* 000 0000 */ 0x7c, /* 0 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 166 0xa6 '\246' */ - 0x3c, /* 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x3c, /* 00 00 */ - 0x14, /* 000 0 00 */ - 0x14, /* 000 0 00 */ - 0x14, /* 000 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + /* 158 0x9e '\236' */ 0x00, /* 00000000 */ - - /* 167 0xa7 '\247' */ - 0x18, /* 000 000 */ - 0x24, /* 00 00 00 */ - 0x44, /* 0 000 00 */ + 0x70, /* 0 0000 */ 0x48, /* 0 00 000 */ + 0x70, /* 0 0000 */ + 0x48, /* 0 00 000 */ + 0x5c, /* 0 0 00 */ 0x48, /* 0 00 000 */ 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x58, /* 0 0 000 */ - 0x40, /* 0 000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - - /* 168 0xa8 '\250' */ 0x00, /* 00000000 */ - 0x70, /* 0 0000 */ - 0x08, /* 0000 000 */ - 0x64, /* 0 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x64, /* 0 00 00 */ - 0x58, /* 0 0 000 */ + + /* 159 0x9f '\237' */ 0x00, /* 00000000 */ + 0x0c, /* 0000 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x60, /* 0 00000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 169 0xa9 '\251' */ - 0x00, /* 00000000 */ - 0x70, /* 0 0000 */ + /* 160 0xa0 '\240' */ 0x08, /* 0000 000 */ - 0x34, /* 00 0 00 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x44, /* 0 000 00 */ 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ 0x34, /* 00 0 00 */ - 0x08, /* 0000 000 */ - 0x70, /* 0 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 170 0xaa '\252' */ + /* 161 0xa1 '\241' */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ - 0xf4, /* 0 00 */ - 0x5c, /* 0 0 00 */ - 0x5c, /* 0 0 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + + /* 162 0xa2 '\242' */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 171 0xab '\253' */ - 0x00, /* 00000000 */ + /* 163 0xa3 '\243' */ 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ 0x00, /* 00000000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x4c, /* 0 00 00 */ + 0x34, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + + /* 164 0xa4 '\244' */ + 0x34, /* 00 0 00 */ + 0x58, /* 0 0 000 */ 0x00, /* 00000000 */ + 0x58, /* 0 0 000 */ + 0x64, /* 0 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 172 0xac '\254' */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ + /* 165 0xa5 '\245' */ + 0x58, /* 0 0 000 */ + 0x44, /* 0 000 00 */ + 0x64, /* 0 00 00 */ + 0x54, /* 0 0 0 00 */ + 0x4c, /* 0 00 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + + /* 166 0xa6 '\246' */ 0x00, /* 00000000 */ + 0x1c, /* 000 00 */ + 0x24, /* 00 00 00 */ + 0x24, /* 00 00 00 */ + 0x1c, /* 000 00 */ 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 173 0xad '\255' */ + /* 167 0xa7 '\247' */ 0x00, /* 00000000 */ + 0x18, /* 000 000 */ + 0x24, /* 00 00 00 */ + 0x24, /* 00 00 00 */ + 0x18, /* 000 000 */ 0x00, /* 00000000 */ - 0x08, /* 0000 000 */ - 0x7c, /* 0 00 */ - 0x10, /* 000 0000 */ - 0x7c, /* 0 00 */ - 0x20, /* 00 00000 */ + 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 174 0xae '\256' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x50, /* 0 0 0000 */ - 0x50, /* 0 0 0000 */ - 0x78, /* 0 000 */ - 0x50, /* 0 0 0000 */ - 0x50, /* 0 0 0000 */ - 0x5c, /* 0 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + /* 168 0xa8 '\250' */ 0x00, /* 00000000 */ - - /* 175 0xaf '\257' */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x4c, /* 0 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x64, /* 0 00 00 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x40, /* 0 000000 */ 0x44, /* 0 000 00 */ 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 176 0xb0 '\260' */ + /* 169 0xa9 '\251' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x6c, /* 0 0 00 */ - 0x54, /* 0 0 0 00 */ - 0x6c, /* 0 0 00 */ 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 177 0xb1 '\261' */ + /* 170 0xaa '\252' */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x7c, /* 0 00 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ 0x7c, /* 0 00 */ + 0x04, /* 00000 00 */ + 0x04, /* 00000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - - /* 178 0xb2 '\262' */ 0x00, /* 00000000 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ + + /* 171 0xab '\253' */ 0x20, /* 00 00000 */ + 0x60, /* 0 00000 */ + 0x24, /* 00 00 00 */ + 0x28, /* 00 0 000 */ 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ + 0x44, /* 0 000 00 */ 0x08, /* 0000 000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ + 0x1c, /* 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 179 0xb3 '\263' */ - 0x00, /* 00000000 */ + /* 172 0xac '\254' */ + 0x20, /* 00 00000 */ + 0x60, /* 0 00000 */ + 0x24, /* 00 00 00 */ + 0x28, /* 00 0 000 */ 0x10, /* 000 0000 */ + 0x28, /* 00 0 000 */ + 0x58, /* 0 0 000 */ + 0x3c, /* 00 00 */ 0x08, /* 0000 000 */ - 0x04, /* 00000 00 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x1c, /* 000 00 */ - 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 180 0xb4 '\264' */ + /* 173 0xad '\255' */ 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x28, /* 00 0 000 */ - 0x7c, /* 0 00 */ - 0x10, /* 000 0000 */ - 0x7c, /* 0 00 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x00, /* 00000000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ + 0x08, /* 0000 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 181 0xb5 '\265' */ + /* 174 0xae '\256' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x48, /* 0 00 000 */ - 0x48, /* 0 00 000 */ - 0x48, /* 0 00 000 */ - 0x48, /* 0 00 000 */ - 0x74, /* 0 0 00 */ - 0x40, /* 0 000000 */ - 0x40, /* 0 000000 */ - 0x00, /* 00000000 */ - - /* 182 0xb6 '\266' */ 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x0c, /* 0000 00 */ - 0x14, /* 000 0 00 */ 0x24, /* 00 00 00 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ 0x24, /* 00 00 00 */ - 0x18, /* 000 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 183 0xb7 '\267' */ + /* 175 0xaf '\257' */ 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x48, /* 0 00 000 */ 0x24, /* 00 00 00 */ - 0x10, /* 000 0000 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ 0x24, /* 00 00 00 */ - 0x7c, /* 0 00 */ + 0x48, /* 0 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 184 0xb8 '\270' */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ + /* 176 0xb0 '\260' */ + 0x11, /* 000 000 */ + 0x44, /* 0 000 00 */ + 0x11, /* 000 000 */ + 0x44, /* 0 000 00 */ + 0x11, /* 000 000 */ + 0x44, /* 0 000 00 */ + 0x11, /* 000 000 */ + 0x44, /* 0 000 00 */ + 0x11, /* 000 000 */ + 0x44, /* 0 000 00 */ + 0x11, /* 000 000 */ + + /* 177 0xb1 '\261' */ + 0x55, /* 0 0 0 0 */ + 0xaa, /* 0 0 0 0 */ + 0x55, /* 0 0 0 0 */ + 0xaa, /* 0 0 0 0 */ + 0x55, /* 0 0 0 0 */ + 0xaa, /* 0 0 0 0 */ + 0x55, /* 0 0 0 0 */ + 0xaa, /* 0 0 0 0 */ + 0x55, /* 0 0 0 0 */ + 0xaa, /* 0 0 0 0 */ + 0x55, /* 0 0 0 0 */ + + /* 178 0xb2 '\262' */ + 0xdd, /* 0 0 */ + 0x77, /* 0 0 */ + 0xdd, /* 0 0 */ + 0x77, /* 0 0 */ + 0xdd, /* 0 0 */ + 0x77, /* 0 0 */ + 0xdd, /* 0 0 */ + 0x77, /* 0 0 */ + 0xdd, /* 0 0 */ + 0x77, /* 0 0 */ + 0xdd, /* 0 0 */ + + /* 179 0xb3 '\263' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + + /* 180 0xb4 '\264' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0xf0, /* 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + + /* 181 0xb5 '\265' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0xf0, /* 0000 */ + 0x10, /* 000 0000 */ + 0xf0, /* 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + + /* 182 0xb6 '\266' */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0xe8, /* 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - /* 185 0xb9 '\271' */ + /* 183 0xb7 '\267' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0xf8, /* 000 */ + 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + + /* 184 0xb8 '\270' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - - /* 186 0xba '\272' */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ + 0xf0, /* 0000 */ 0x10, /* 000 0000 */ + 0xf0, /* 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x60, /* 0 00000 */ - 0x00, /* 00000000 */ + + /* 185 0xb9 '\271' */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0xe8, /* 0 000 */ + 0x08, /* 0000 000 */ + 0xe8, /* 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + + /* 186 0xba '\272' */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ /* 187 0xbb '\273' */ 0x00, /* 00000000 */ - 0x1c, /* 000 00 */ - 0x24, /* 00 00 00 */ - 0x24, /* 00 00 00 */ - 0x1c, /* 000 00 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0xf8, /* 000 */ + 0x08, /* 0000 000 */ + 0xe8, /* 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ /* 188 0xbc '\274' */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0xe8, /* 0 000 */ + 0x08, /* 0000 000 */ + 0xf8, /* 000 */ 0x00, /* 00000000 */ - 0x18, /* 000 000 */ - 0x24, /* 00 00 00 */ - 0x24, /* 00 00 00 */ - 0x18, /* 000 000 */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 189 0xbd '\275' */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ 0x28, /* 00 0 000 */ - 0x6c, /* 0 0 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0xf8, /* 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 190 0xbe '\276' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0xf0, /* 0000 */ + 0x10, /* 000 0000 */ + 0xf0, /* 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x54, /* 0 0 0 00 */ - 0x5c, /* 0 0 00 */ - 0x50, /* 0 0 0000 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2497,152 +2497,152 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x38, /* 00 000 */ - 0x4c, /* 0 00 00 */ - 0x54, /* 0 0 0 00 */ - 0x64, /* 0 00 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0xf0, /* 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ /* 192 0xc0 '\300' */ - 0x00, /* 00000000 */ 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ 0x10, /* 000 0000 */ - 0x20, /* 00 00000 */ - 0x40, /* 0 000000 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x1c, /* 000 00 */ 0x00, /* 00000000 */ - - /* 193 0xc1 '\301' */ 0x00, /* 00000000 */ - 0x08, /* 0000 000 */ 0x00, /* 00000000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ - 0x08, /* 0000 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 194 0xc2 '\302' */ - 0x00, /* 00000000 */ + /* 193 0xc1 '\301' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0xfc, /* 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x04, /* 00000 00 */ - 0x04, /* 00000 00 */ - 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - /* 195 0xc3 '\303' */ + /* 194 0xc2 '\302' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x0c, /* 0000 00 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x50, /* 0 0 0000 */ - 0x20, /* 00 00000 */ - 0x20, /* 00 00000 */ - 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0xfc, /* 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ - /* 196 0xc4 '\304' */ + /* 195 0xc3 '\303' */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ - 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x1c, /* 000 00 */ + 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ - 0x60, /* 0 00000 */ - 0x00, /* 00000000 */ - /* 197 0xc5 '\305' */ + /* 196 0xc4 '\304' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x04, /* 00000 00 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ - 0x40, /* 0 000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0xfc, /* 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - - /* 198 0xc6 '\306' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ - 0x10, /* 000 0000 */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + /* 197 0xc5 '\305' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0xfc, /* 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + + /* 198 0xc6 '\306' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x1c, /* 000 00 */ + 0x10, /* 000 0000 */ + 0x1c, /* 000 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + /* 199 0xc7 '\307' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x24, /* 00 00 00 */ - 0x48, /* 0 00 000 */ - 0x48, /* 0 00 000 */ - 0x24, /* 00 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x2c, /* 00 0 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ /* 200 0xc8 '\310' */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x2c, /* 00 0 00 */ + 0x20, /* 00 00000 */ + 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x48, /* 0 00 000 */ - 0x24, /* 00 00 00 */ - 0x24, /* 00 00 00 */ - 0x48, /* 0 00 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 201 0xc9 '\311' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x54, /* 0 0 0 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x20, /* 00 00000 */ + 0x2c, /* 00 0 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ /* 202 0xca '\312' */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0xec, /* 0 00 */ 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + 0xfc, /* 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2650,76 +2650,76 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ /* 203 0xcb '\313' */ - 0x10, /* 000 0000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0xfc, /* 00 */ + 0x00, /* 00000000 */ + 0xec, /* 0 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ /* 204 0xcc '\314' */ - 0x58, /* 0 0 000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x7c, /* 0 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x2c, /* 00 0 00 */ + 0x20, /* 00 00000 */ + 0x2c, /* 00 0 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + + /* 205 0xcd '\315' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - - /* 205 0xcd '\315' */ - 0x58, /* 0 0 000 */ - 0x38, /* 00 000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x38, /* 00 000 */ + 0xfc, /* 00 */ 0x00, /* 00000000 */ + 0xfc, /* 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - - /* 206 0xce '\316' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x50, /* 0 0 0000 */ - 0x50, /* 0 0 0000 */ - 0x58, /* 0 0 000 */ - 0x50, /* 0 0 0000 */ - 0x50, /* 0 0 0000 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + + /* 206 0xce '\316' */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0xec, /* 0 00 */ 0x00, /* 00000000 */ + 0xec, /* 0 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ /* 207 0xcf '\317' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0xfc, /* 00 */ 0x00, /* 00000000 */ + 0xfc, /* 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x54, /* 0 0 0 00 */ - 0x5c, /* 0 0 00 */ - 0x50, /* 0 0 0000 */ - 0x2c, /* 00 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 208 0xd0 '\320' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x38, /* 00 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0xfc, /* 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2731,34 +2731,34 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x00, /* 00000000 */ 0xfc, /* 00 */ 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + 0xfc, /* 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ /* 210 0xd2 '\322' */ 0x00, /* 00000000 */ - 0x14, /* 000 0 00 */ - 0x28, /* 00 0 000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0xfc, /* 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ /* 211 0xd3 '\323' */ - 0x00, /* 00000000 */ - 0x14, /* 000 0 00 */ - 0x14, /* 000 0 00 */ 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2767,12 +2767,12 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { 0x00, /* 00000000 */ /* 212 0xd4 '\324' */ - 0x00, /* 00000000 */ - 0x08, /* 0000 000 */ 0x10, /* 000 0000 */ - 0x18, /* 000 000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x1c, /* 000 00 */ + 0x10, /* 000 0000 */ + 0x1c, /* 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2781,64 +2781,64 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { /* 213 0xd5 '\325' */ 0x00, /* 00000000 */ - 0x18, /* 000 000 */ - 0x08, /* 0000 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - - /* 214 0xd6 '\326' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0x1c, /* 000 00 */ + 0x10, /* 000 0000 */ + 0x1c, /* 000 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x7c, /* 0 00 */ - 0x00, /* 00000000 */ 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + + /* 214 0xd6 '\326' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0x3c, /* 00 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ /* 215 0xd7 '\327' */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x10, /* 000 0000 */ 0x28, /* 00 0 000 */ - 0x44, /* 0 000 00 */ 0x28, /* 00 0 000 */ - 0x10, /* 000 0000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0xfc, /* 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ /* 216 0xd8 '\330' */ - 0x00, /* 00000000 */ - 0x28, /* 00 0 000 */ - 0x00, /* 00000000 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x44, /* 0 000 00 */ - 0x3c, /* 00 00 */ - 0x04, /* 00000 00 */ - 0x38, /* 00 000 */ - 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0xfc, /* 00 */ + 0x10, /* 000 0000 */ + 0xfc, /* 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ /* 217 0xd9 '\331' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0xf0, /* 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0xfc, /* 00 */ - 0x00, /* 00000000 */ - 0xfc, /* 00 */ - 0x00, /* 00000000 */ - 0xfc, /* 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -2846,260 +2846,260 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { /* 218 0xda '\332' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0x1f, /* 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ /* 219 0xdb '\333' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ /* 220 0xdc '\334' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ /* 221 0xdd '\335' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + 0xe0, /* 00000 */ + 0xe0, /* 00000 */ + 0xe0, /* 00000 */ + 0xe0, /* 00000 */ + 0xe0, /* 00000 */ + 0xe0, /* 00000 */ + 0xe0, /* 00000 */ + 0xe0, /* 00000 */ + 0xe0, /* 00000 */ + 0xe0, /* 00000 */ + 0xe0, /* 00000 */ /* 222 0xde '\336' */ - 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + 0x1c, /* 000 00 */ + 0x1c, /* 000 00 */ + 0x1c, /* 000 00 */ + 0x1c, /* 000 00 */ + 0x1c, /* 000 00 */ + 0x1c, /* 000 00 */ + 0x1c, /* 000 00 */ + 0x1c, /* 000 00 */ + 0x1c, /* 000 00 */ + 0x1c, /* 000 00 */ + 0x1c, /* 000 00 */ /* 223 0xdf '\337' */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0xfc, /* 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 224 0xe0 '\340' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0x24, /* 00 00 00 */ + 0x58, /* 0 0 000 */ + 0x50, /* 0 0 0000 */ + 0x54, /* 0 0 0 00 */ + 0x2c, /* 00 0 00 */ 0x00, /* 00000000 */ - - /* 225 0xe1 '\341' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ + + /* 225 0xe1 '\341' */ + 0x18, /* 000 000 */ + 0x24, /* 00 00 00 */ + 0x44, /* 0 000 00 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x58, /* 0 0 000 */ + 0x40, /* 0 000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 226 0xe2 '\342' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x7c, /* 0 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 227 0xe3 '\343' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x7c, /* 0 00 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 228 0xe4 '\344' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x7c, /* 0 00 */ + 0x24, /* 00 00 00 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x24, /* 00 00 00 */ + 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 229 0xe5 '\345' */ 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x30, /* 00 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 230 0xe6 '\346' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x48, /* 0 00 000 */ + 0x74, /* 0 0 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ 0x00, /* 00000000 */ /* 231 0xe7 '\347' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x6c, /* 0 0 00 */ + 0x98, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 232 0xe8 '\350' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 233 0xe9 '\351' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x4c, /* 0 00 00 */ + 0x54, /* 0 0 0 00 */ + 0x64, /* 0 00 00 */ + 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 234 0xea '\352' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x28, /* 00 0 000 */ + 0x6c, /* 0 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 235 0xeb '\353' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x0c, /* 0000 00 */ + 0x14, /* 000 0 00 */ + 0x24, /* 00 00 00 */ + 0x24, /* 00 00 00 */ + 0x18, /* 000 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 236 0xec '\354' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x54, /* 0 0 0 00 */ + 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 237 0xed '\355' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x04, /* 00000 00 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x38, /* 00 000 */ + 0x40, /* 0 000000 */ + 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3107,11 +3107,11 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { /* 238 0xee '\356' */ 0x00, /* 00000000 */ 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ + 0x78, /* 0 000 */ + 0x40, /* 0 000000 */ + 0x40, /* 0 000000 */ 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ @@ -3119,221 +3119,221 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = { /* 239 0xef '\357' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x38, /* 00 000 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ + 0x44, /* 0 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 240 0xf0 '\360' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0xfc, /* 00 */ + 0x00, /* 00000000 */ + 0xfc, /* 00 */ + 0x00, /* 00000000 */ + 0xfc, /* 00 */ + 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 241 0xf1 '\361' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x7c, /* 0 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x7c, /* 0 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 242 0xf2 '\362' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x04, /* 00000 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x1c, /* 000 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 243 0xf3 '\363' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x20, /* 00 00000 */ + 0x10, /* 000 0000 */ + 0x08, /* 0000 000 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 244 0xf4 '\364' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ - 0x00, /* 00000000 */ + 0x0c, /* 0000 00 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ /* 245 0xf5 '\365' */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x10, /* 000 0000 */ + 0x60, /* 0 00000 */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + + /* 246 0xf6 '\366' */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ - - /* 246 0xf6 '\366' */ + 0x7c, /* 0 00 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 247 0xf7 '\367' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x34, /* 00 0 00 */ + 0x48, /* 0 00 000 */ + 0x00, /* 00000000 */ + 0x34, /* 00 0 00 */ + 0x48, /* 0 00 000 */ + 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 248 0xf8 '\370' */ + 0x18, /* 000 000 */ + 0x24, /* 00 00 00 */ + 0x24, /* 00 00 00 */ + 0x18, /* 000 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 249 0xf9 '\371' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x38, /* 00 000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 250 0xfa '\372' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x10, /* 000 0000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 251 0xfb '\373' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x0c, /* 0000 00 */ + 0x08, /* 0000 000 */ + 0x10, /* 000 0000 */ + 0x50, /* 0 0 0000 */ + 0x20, /* 00 00000 */ + 0x20, /* 00 00000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 252 0xfc '\374' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x50, /* 0 0 0000 */ + 0x28, /* 00 0 000 */ + 0x28, /* 00 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 253 0xfd '\375' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x70, /* 0 0000 */ + 0x08, /* 0000 000 */ + 0x20, /* 00 00000 */ + 0x78, /* 0 000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 254 0xfe '\376' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x38, /* 00 000 */ + 0x38, /* 00 000 */ + 0x38, /* 00 000 */ + 0x38, /* 00 000 */ + 0x38, /* 00 000 */ + 0x38, /* 00 000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ /* 255 0xff '\377' */ 0x00, /* 00000000 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ - 0x3c, /* 00 00 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ + 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ 0x00, /* 00000000 */ diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index eef49864fcd4..cb6fe2187b54 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -743,33 +743,14 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) int fb_blank(struct fb_info *info, int blank) { - /* ??? Variable sized stack allocation. */ - struct fb_cmap cmap; - u16 *black = NULL; - int err = 0; + int err = -EINVAL; /* Workaround for broken X servers */ if (blank > VESA_POWERDOWN) blank = VESA_POWERDOWN; - if (info->fbops->fb_blank && !info->fbops->fb_blank(blank, info)) - return 0; - - cmap = info->cmap; - - if (blank) { - black = kmalloc(sizeof(u16) * info->cmap.len, GFP_KERNEL); - if (black) { - memset(black, 0, info->cmap.len * sizeof(u16)); - cmap.red = cmap.green = cmap.blue = black; - cmap.transp = info->cmap.transp ? black : NULL; - cmap.start = info->cmap.start; - cmap.len = info->cmap.len; - } - } - - err = fb_set_cmap(&cmap, info); - kfree(black); + if (info->fbops->fb_blank) + err = info->fbops->fb_blank(blank, info); return err; } diff --git a/drivers/video/ffb.c b/drivers/video/ffb.c index 349499ef4cc9..31e55def0732 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/ffb.c @@ -969,7 +969,6 @@ static void ffb_init_one(int node, int parent) FBINFO_HWACCEL_IMAGEBLIT); all->info.fbops = &ffb_ops; all->info.screen_base = (char *) all->par.physbase + FFB_DFB24_POFF; - all->info.currcon = -1; all->info.par = &all->par; all->info.pseudo_palette = all->pseudo_palette; diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c index 15d9e998f23f..6d7a635fb69e 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/gbefb.c @@ -1140,7 +1140,6 @@ int __init gbefb_init(void) for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++) gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i; - fb_info.currcon = -1; fb_info.fbops = &gbefb_ops; fb_info.pseudo_palette = pseudo_palette; fb_info.flags = FBINFO_DEFAULT; diff --git a/drivers/video/intelfb/builtinmodes.c b/drivers/video/intelfb/builtinmodes.c deleted file mode 100644 index cd24c5d7c119..000000000000 --- a/drivers/video/intelfb/builtinmodes.c +++ /dev/null @@ -1,222 +0,0 @@ - -/* - * THIS FILE IS AUTOMATICALLY GENERATED BY fbmode.pl -- DO NOT EDIT - */ - -static struct fb_videomode modedb[] = { - { - /* 640x350 @ 85 Hz, 37.9 kHz hsync */ - "640x350@85", 85, 640, 350, 31746, 96, 32, 60, 32, 64, 3, - FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 640x400 @ 85 Hz, 37.9 kHz hsync */ - "640x400@85", 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 720x400 @ 85 Hz, 37.9 kHz hsync */ - "720x400@85", 85, 720, 400, 28169, 108, 36, 42, 1, 72, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 640x480 @ 60 Hz, 31.5 kHz hsync */ - "640x480@60", 60, 640, 480, 39683, 48, 16, 33, 10, 96, 2, - 0, FB_VMODE_NONINTERLACED - }, - { - /* 640x480 @ 73 Hz, 37.9 kHz hsync */ - "640x480@73", 73, 640, 480, 31746, 128, 24, 29, 9, 40, 2, - 0, FB_VMODE_NONINTERLACED - }, - { - /* 640x480 @ 75 Hz, 37.5 kHz hsync */ - "640x480@75", 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3, - 0, FB_VMODE_NONINTERLACED - }, - { - /* 640x480 @ 85 Hz, 43.3 kHz hsync */ - "640x480@85", 85, 640, 480, 27778, 80, 56, 25, 1, 56, 3, - 0, FB_VMODE_NONINTERLACED - }, - { - /* 800x600 @ 56 Hz, 35.2 kHz hsync */ - "800x600@56", 56, 800, 600, 27778, 128, 24, 22, 1, 72, 2, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 800x600 @ 60 Hz, 37.9 kHz hsync */ - "800x600@60", 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 800x600 @ 72 Hz, 48.1 kHz hsync */ - "800x600@72", 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 800x600 @ 75 Hz, 46.9 kHz hsync */ - "800x600@75", 75, 800, 600, 20202, 160, 16, 21, 1, 80, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 800x600 @ 85 Hz, 53.7 kHz hsync */ - "800x600@85", 85, 800, 600, 17762, 152, 32, 27, 1, 64, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1024x768 @ 60 Hz, 48.4 kHz hsync */ - "1024x768@60", 60, 1024, 768, 15385, 160, 24, 29, 3, 136, 6, - 0, FB_VMODE_NONINTERLACED - }, - { - /* 1024x768 @ 70 Hz, 56.5 kHz hsync */ - "1024x768@70", 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6, - 0, FB_VMODE_NONINTERLACED - }, - { - /* 1024x768 @ 75 Hz, 60.1 kHz hsync */ - "1024x768@75", 75, 1024, 768, 12690, 176, 16, 28, 1, 96, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1024x768 @ 85 Hz, 68.7 kHz hsync */ - "1024x768@85", 85, 1024, 768, 10582, 208, 48, 36, 1, 96, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1152x864 @ 75 Hz, 67.5 kHz hsync */ - "1152x864@75", 75, 1152, 864, 9259, 256, 64, 32, 1, 128, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1280x960 @ 60 Hz, 60.0 kHz hsync */ - "1280x960@60", 60, 1280, 960, 9259, 312, 96, 36, 1, 112, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1280x960 @ 85 Hz, 85.9 kHz hsync */ - "1280x960@85", 85, 1280, 960, 6734, 224, 64, 47, 1, 160, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1280x1024 @ 60 Hz, 64.0 kHz hsync */ - "1280x1024@60", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1280x1024 @ 75 Hz, 80.0 kHz hsync */ - "1280x1024@75", 75, 1280, 1024, 7407, 248, 16, 38, 1, 144, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1280x1024 @ 85 Hz, 91.1 kHz hsync */ - "1280x1024@85", 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1600x1200 @ 60 Hz, 75.0 kHz hsync */ - "1600x1200@60", 60, 1600, 1200, 6173, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1600x1200 @ 65 Hz, 81.2 kHz hsync */ - "1600x1200@65", 65, 1600, 1200, 5698, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1600x1200 @ 70 Hz, 87.5 kHz hsync */ - "1600x1200@70", 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1600x1200 @ 75 Hz, 93.8 kHz hsync */ - "1600x1200@75", 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1600x1200 @ 85 Hz, 106.2 kHz hsync */ - "1600x1200@85", 85, 1600, 1200, 4357, 304, 64, 46, 1, 192, 3, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1792x1344 @ 60 Hz, 83.7 kHz hsync */ - "1792x1344@60", 60, 1792, 1344, 4883, 328, 128, 46, 1, 200, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1792x1344 @ 75 Hz, 106.3 kHz hsync */ - "1792x1344@75", 75, 1792, 1344, 3831, 352, 96, 69, 1, 216, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1856x1392 @ 60 Hz, 86.4 kHz hsync */ - "1856x1392@60", 60, 1856, 1392, 4581, 352, 96, 43, 1, 224, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1856x1392 @ 75 Hz, 112.5 kHz hsync */ - "1856x1392@75", 75, 1856, 1392, 3472, 352, 128, 104, 1, 224, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1920x1440 @ 60 Hz, 90.0 kHz hsync */ - "1920x1440@60", 60, 1920, 1440, 4274, 344, 128, 56, 1, 208, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1920x1440 @ 75 Hz, 112.5 kHz hsync */ - "1920x1440@75", 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 832x624 @ 75 Hz, 49.7 kHz hsync */ - "832x624@75", 75, 832, 624, 17457, 224, 32, 39, 1, 64, 3, - 0, FB_VMODE_NONINTERLACED - }, - { - /* 1152x768 @ 55 Hz, 44.2 kHz hsync */ - "1152x768@55", 55, 1152, 768, 15386, 158, 26, 29, 3, 136, 6, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1400x1050 @ 60 Hz, 64.9 kHz hsync */ - "1400x1050@60", 60, 1400, 1050, 8197, 240, 88, 18, 2, 152, 12, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1400x1050 @ 75 Hz, 81.5 kHz hsync */ - "1400x1050@75", 75, 1400, 1050, 6418, 128, 64, 26, 2, 320, 12, - FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 1600x1024 @ 60 Hz, 64.0 kHz hsync */ - "1600x1024@60", 60, 1600, 1024, 9354, 30, 20, 37, 3, 20, 3, - 0, FB_VMODE_NONINTERLACED - }, - { - /* 1920x1440 @ 85 Hz, 128.5 kHz hsync */ - "1920x1440@85", 85, 1920, 1440, 2930, 368, 152, 68, 1, 216, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 2048x1536 @ 60 Hz, 95.3 kHz hsync */ - "2048x1536@60", 60, 2048, 1536, 3746, 376, 152, 49, 1, 224, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 2048x1536 @ 75 Hz, 120.2 kHz hsync */ - "2048x1536@75", 75, 2048, 1536, 2937, 392, 168, 63, 1, 224, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - }, - { - /* 2048x1536 @ 85 Hz, 137.0 kHz hsync */ - "2048x1536@85", 85, 2048, 1536, 2577, 392, 168, 72, 1, 224, 3, - FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED - } -}; - -static int num_modes = sizeof(modedb) / sizeof(modedb[0]); - -#define DFLT_MODE 3 - diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h index 3e4854fe56f9..4b331bc09c6a 100644 --- a/drivers/video/intelfb/intelfb.h +++ b/drivers/video/intelfb/intelfb.h @@ -8,7 +8,7 @@ /*** Version/name ***/ -#define INTELFB_VERSION "0.9.0" +#define INTELFB_VERSION "0.9.1" #define INTELFB_MODULE_NAME "intelfb" #define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G" @@ -35,14 +35,6 @@ #define ALLOCATE_FOR_PANNING 1 #endif -#ifndef BAILOUT_EARLY -#define BAILOUT_EARLY 0 -#endif - -#ifndef TEST_MODE_TO_HW -#define TEST_MODE_TO_HW 0 -#endif - #ifndef PREFERRED_MODE #define PREFERRED_MODE "1024x768-16@60" #endif @@ -94,21 +86,10 @@ /* get commonly used pointers */ #define GET_DINFO(info) (info)->par -/* module parameters */ -#define INTELFB_INT_PARAM(name, default, desc) \ - static int name = default; \ - module_param(name, int, default); \ - MODULE_PARM_DESC(name, desc); - -#define INTELFB_STR_PARAM(name, default, desc) \ - static char *name = (char *) default; \ - module_param(name, charp, default); \ - MODULE_PARM_DESC(name, desc); - /* misc macros */ -#define TEXT_ACCEL(d, v) \ - ((d)->accel && (d)->ring_active && \ - ((v)->accel_flags & FB_ACCELF_TEXT)) +#define ACCEL(d, i) \ + ((d)->accel && !(d)->ring_lockup && \ + ((i)->var.accel_flags & FB_ACCELF_TEXT)) /*#define NOACCEL_CHIPSET(d) \ ((d)->chipset != INTEL_865G)*/ @@ -205,7 +186,7 @@ struct intelfb_hwstate { struct intelfb_heap_data { u32 physical; - u32 __iomem *virtual; + u8 __iomem *virtual; u32 offset; // in GATT pages u32 size; // in bytes }; @@ -234,13 +215,13 @@ struct intelfb_info { /* mmio regs */ u32 mmio_base_phys; - u32 __iomem *mmio_base; + u8 __iomem *mmio_base; /* fb start offset (in bytes) */ u32 fb_start; /* ring buffer */ - u32 __iomem *ring_head; + u8 __iomem *ring_head; u32 ring_tail; u32 ring_tail_mask; u32 ring_space; diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index b5aadd7f1f12..ac1af26f658d 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -87,10 +87,13 @@ * 09/2004 - Version 0.9.0 - by Sylvain Meyer * Port to linux 2.6 kernel fbdev * Fix HW accel and HW cursor on i845G - * Add TV-Out functionality (tested with a ch7011 tv encoder) * Use of agpgart for fb memory reservation * Add mtrr support * + * 10/2004 - Version 0.9.1 + * Use module_param instead of old MODULE_PARM + * Some cleanup + * * TODO: * * @@ -130,10 +133,6 @@ #include "intelfbdrv.h" #include "intelfbhw.h" -#include "builtinmodes.c" - -#define FB_ACCEL_I830 42 - /* * Limiting the class to PCI_CLASS_DISPLAY_VGA prevents function 1 of the * mobile chipsets from being registered. @@ -187,18 +186,38 @@ MODULE_DESCRIPTION( MODULE_LICENSE("Dual BSD/GPL"); MODULE_DEVICE_TABLE(pci, intelfb_pci_table); -INTELFB_INT_PARAM(accel, 1, "Enable console acceleration"); -INTELFB_INT_PARAM(hwcursor, 1, "Enable HW cursor"); -INTELFB_INT_PARAM(mtrr, 1, "Enable MTRR support"); -INTELFB_INT_PARAM(fixed, 0, "Disable mode switching"); -INTELFB_INT_PARAM(noinit, 0, "Don't initialise graphics mode when loading"); -INTELFB_INT_PARAM(noregister, 0, "Don't register, just probe and exit (debug)"); -INTELFB_INT_PARAM(probeonly, 0, "Do a minimal probe (debug)"); -INTELFB_INT_PARAM(idonly, 0, - "Just identify without doing anything else (debug)"); -INTELFB_INT_PARAM(bailearly, 0, "Bail out early, depending on value (debug)"); -INTELFB_STR_PARAM(mode, 0, - "Initial video mode \"<xres>x<yres>[-<depth>][@<refresh>]\""); +static int accel = 1; +static int hwcursor = 1; +static int mtrr = 1; +static int fixed = 0; +static int noinit = 0; +static int noregister = 0; +static int probeonly = 0; +static int idonly = 0; +static int bailearly = 0; +static char *mode = NULL; + +module_param(accel, bool, S_IRUGO); +MODULE_PARM_DESC(accel, "Enable console acceleration"); +module_param(hwcursor, bool, S_IRUGO); +MODULE_PARM_DESC(hwcursor, "Enable HW cursor"); +module_param(mtrr, bool, S_IRUGO); +MODULE_PARM_DESC(mtrr, "Enable MTRR support"); +module_param(fixed, bool, S_IRUGO); +MODULE_PARM_DESC(fixed, "Disable mode switching"); +module_param(noinit, bool, 0); +MODULE_PARM_DESC(noinit, "Don't initialise graphics mode when loading"); +module_param(noregister, bool, 0); +MODULE_PARM_DESC(noregister, "Don't register, just probe and exit (debug)"); +module_param(probeonly, bool, 0); +MODULE_PARM_DESC(probeonly, "Do a minimal probe (debug)"); +module_param(idonly, bool, 0); +MODULE_PARM_DESC(idonly, "Just identify without doing anything else (debug)"); +module_param(bailearly, bool, 0); +MODULE_PARM_DESC(bailearly, "Bail out early, depending on value (debug)"); +module_param(mode, charp, S_IRUGO); +MODULE_PARM_DESC(mode, + "Initial video mode \"<xres>x<yres>[-<depth>][@<refresh>]\""); /*************************************************************** * modules entry points * ***************************************************************/ @@ -224,7 +243,6 @@ intelfb_init(void) if (fb_get_options("intelfb", &option)) return -ENODEV; intelfb_setup(option); - #endif return pci_module_init(&intelfb_driver); @@ -239,7 +257,6 @@ intelfb_exit(void) #ifndef MODULE #define OPT_EQUAL(opt, name) (!strncmp(opt, name, strlen(name))) -#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name), NULL, 0) #define OPT_STRVAL(opt, name) (opt + strlen(name)) static __inline__ char * @@ -282,19 +299,6 @@ get_opt_bool(const char *this_opt, const char *name, int *ret) return 1; } -static __inline__ int -get_opt_int(const char *this_opt, const char *name, int *ret) -{ - if (!ret) - return 0; - - if (!OPT_EQUAL(this_opt, name)) - return 0; - - *ret = OPT_INTVAL(this_opt, name); - return 1; -} - int __init intelfb_setup(char *options) { @@ -510,7 +514,7 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) } /* Map the fb and MMIO regions */ - dinfo->aperture.virtual = (u32 __iomem *)ioremap_nocache + dinfo->aperture.virtual = (u8 __iomem *)ioremap_nocache (dinfo->aperture.physical, dinfo->aperture.size); if (!dinfo->aperture.virtual) { ERR_MSG("Cannot remap FB region.\n"); @@ -518,7 +522,7 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) return -ENODEV; } dinfo->mmio_base = - (u32 __iomem *)ioremap_nocache(dinfo->mmio_base_phys, + (u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys, INTEL_REG_SIZE); if (!dinfo->mmio_base) { ERR_MSG("Cannot remap MMIO region.\n"); @@ -759,27 +763,6 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) if (bailearly == 18) bailout(dinfo); -#if TEST_MODE_TO_HW - { - struct intelfb_hwstate hw; - struct fb_var_screeninfo var; - int i; - - for (i = 0; i < num_modes; i++) { - mode_to_var(&modedb[i], &var, 8); - intelfbhw_read_hw_state(dinfo, &hw, 0); - if (intelfbhw_mode_to_hw(dinfo, &hw, &var)) { - DBG_MSG("Failed to set hw for mode %dx%d\n", - var.xres, var.yres); - } else { - DBG_MSG("HW state for mode %dx%d\n", - var.xres, var.yres); - intelfbhw_print_hw_state(dinfo, &hw); - } - } - } -#endif - /* Cursor initialisation */ if (dinfo->hwcursor) { intelfbhw_cursor_init(dinfo); @@ -835,79 +818,7 @@ intelfb_pci_unregister(struct pci_dev *pdev) * helper functions * ***************************************************************/ -/* - * A simplified version of fb_find_mode. The latter doesn't seem to work - * too well -- haven't figured out why yet. - */ -static int -intelfb_find_mode(struct fb_var_screeninfo *var, - struct fb_info *info, const char *mode_option, - const struct fb_videomode *db, unsigned int dbsize, - const struct fb_videomode *default_mode, - unsigned int default_bpp) -{ - int i; - char mname[20] = "", tmp[20] = "", *p, *q; - unsigned int bpp = 0; - - DBG_MSG("intelfb_find_mode\n"); - - /* Set up defaults */ - if (!db) { - db = modedb; - dbsize = sizeof(modedb) / sizeof(*modedb); - } - - if (!default_bpp) - default_bpp = 16; - - var->activate = FB_ACTIVATE_TEST; - if (mode_option && *mode_option) { - if (strlen(mode_option) < sizeof(tmp) - 1) { - strcat(tmp, mode_option); - q = tmp; - p = strsep(&q, "-"); - strcat(mname, p); - if (q) { - p = strsep(&q, "@"); - bpp = simple_strtoul(p, NULL, 10); - if (q) { - strcat(mname, "@"); - strcat(mname, q); - } - } - } - if (!bpp) - bpp = default_bpp; - DBG_MSG("Mode is %s, bpp %d\n", mname, bpp); - } - if (*mname) { - for (i = 0; i < dbsize; i++) { - if (!strncmp(db[i].name, mname, strlen(mname))) { - mode_to_var(&db[i], var, bpp); - if (!intelfb_check_var(var, info)) - return 1; - } - } - } - - if (!default_mode) - return 0; - - mode_to_var(default_mode, var, default_bpp); - if (!intelfb_check_var(var, info)) - return 3; - - for (i = 0; i < dbsize; i++) { - mode_to_var(&db[i], var, default_bpp); - if (!intelfb_check_var(var, info)) - return 4; - } - - return 0; -} - -int +int __inline__ intelfb_var_to_depth(const struct fb_var_screeninfo *var) { DBG_MSG("intelfb_var_to_depth: bpp: %d, green.length is %d\n", @@ -923,7 +834,23 @@ intelfb_var_to_depth(const struct fb_var_screeninfo *var) } } -static void + +static __inline__ int +var_to_refresh(const struct fb_var_screeninfo *var) +{ + int xtot = var->xres + var->left_margin + var->right_margin + + var->hsync_len; + int ytot = var->yres + var->upper_margin + var->lower_margin + + var->vsync_len; + + return (1000000000 / var->pixclock * 1000 + 500) / xtot / ytot; +} + +/*************************************************************** + * Various intialisation functions * + ***************************************************************/ + +static void __devinit get_initial_mode(struct intelfb_info *dinfo) { struct fb_var_screeninfo *var; @@ -940,16 +867,6 @@ get_initial_mode(struct intelfb_info *dinfo) memset(var, 0, sizeof(*var)); var->xres = screen_info.lfb_width; var->yres = screen_info.lfb_height; - var->xres_virtual = var->xres; -#if ALLOCATE_FOR_PANNING - /* Allow use of half of the video ram for panning */ - var->yres_virtual = - dinfo->initial_video_ram / 2 / dinfo->initial_pitch; - if (var->yres_virtual < var->yres) - var->yres_virtual = var->yres; -#else - var->yres_virtual = var->yres; -#endif var->bits_per_pixel = screen_info.lfb_depth; switch (screen_info.lfb_depth) { case 15: @@ -1001,84 +918,29 @@ get_initial_mode(struct intelfb_info *dinfo) } } -/* Convert a mode to a var, also making the bpp a supported value. */ -static void -mode_to_var(const struct fb_videomode *mode, struct fb_var_screeninfo *var, - u32 bpp) -{ - if (!mode || !var) - return; - - var->xres = mode->xres; - var->yres = mode->yres; - var->xres_virtual = mode->xres; - var->yres_virtual = mode->yres; - var->xoffset = 0; - var->yoffset = 0; - if (bpp <= 8) - var->bits_per_pixel = 8; - else if (bpp <= 16) { - if (bpp == 16) - var->green.length = 6; - var->bits_per_pixel = 16; - } else if (bpp <= 32) - var->bits_per_pixel = 32; - else { - WRN_MSG("var_to_mode: bad bpp: %d\n", bpp); - var->bits_per_pixel = bpp; - } - var->pixclock = mode->pixclock; - var->left_margin = mode->left_margin; - var->right_margin = mode->right_margin; - var->upper_margin = mode->upper_margin; - var->lower_margin = mode->lower_margin; - var->hsync_len = mode->hsync_len; - var->vsync_len = mode->vsync_len; - var->sync = mode->sync; - var->vmode = mode->vmode; - var->width = -1; - var->height = -1; -} - -static __inline__ int -var_to_refresh(const struct fb_var_screeninfo *var) -{ - int xtot = var->xres + var->left_margin + var->right_margin + - var->hsync_len; - int ytot = var->yres + var->upper_margin + var->lower_margin + - var->vsync_len; - - return (1000000000 / var->pixclock * 1000 + 500) / xtot / ytot; -} - -/*************************************************************** - * Various intialisation functions * - ***************************************************************/ - static int __devinit intelfb_init_var(struct intelfb_info *dinfo) { + struct fb_var_screeninfo *var; int msrc = 0; - DBG_MSG("intelfb_init_disp_var\n"); + DBG_MSG("intelfb_init_var\n"); - if (dinfo->fixed_mode) { - memcpy(&dinfo->info->var, &dinfo->initial_var, + var = &dinfo->info->var; + if (FIXED_MODE(dinfo)) { + memcpy(var, &dinfo->initial_var, sizeof(struct fb_var_screeninfo)); msrc = 5; } else { if (mode) { - msrc = intelfb_find_mode(&dinfo->info->var, - dinfo->info, mode, - modedb, num_modes, NULL, 0); + msrc = fb_find_mode(var, dinfo->info, mode, + NULL, 0, NULL, 0); if (msrc) msrc |= 8; } if (!msrc) { - msrc = intelfb_find_mode(&dinfo->info->var, - dinfo->info, PREFERRED_MODE, - modedb, num_modes, - &modedb[DFLT_MODE], 0); + msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE, + NULL, 0, NULL, 0); } } @@ -1087,16 +949,26 @@ intelfb_init_var(struct intelfb_info *dinfo) return 1; } - INF_MSG("Initial video mode is %dx%d-%d@%d.\n", dinfo->info->var.xres, - dinfo->info->var.yres, intelfb_var_to_depth(&dinfo->info->var), - var_to_refresh(&dinfo->info->var)); + INF_MSG("Initial video mode is %dx%d-%d@%d.\n", var->xres, var->yres, + var->bits_per_pixel, var_to_refresh(var)); DBG_MSG("Initial video mode is from %d.\n", msrc); +#if ALLOCATE_FOR_PANNING + /* Allow use of half of the video ram for panning */ + var->xres_virtual = var->xres; + var->yres_virtual = + dinfo->fb.size / 2 / (var->bits_per_pixel * var->xres); + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; +#else + var->yres_virtual = var->yres; +#endif + if (dinfo->accel) - dinfo->info->var.accel_flags |= FB_ACCELF_TEXT; + var->accel_flags |= FB_ACCELF_TEXT; else - dinfo->info->var.accel_flags &= ~FB_ACCELF_TEXT; + var->accel_flags &= ~FB_ACCELF_TEXT; return 0; } @@ -1108,7 +980,6 @@ intelfb_set_fbinfo(struct intelfb_info *dinfo) DBG_MSG("intelfb_set_fbinfo\n"); - //info->currcon = -1; info->flags = FBINFO_FLAG_DEFAULT; info->fbops = &intel_fb_ops; info->pseudo_palette = dinfo->pseudo_palette; @@ -1212,7 +1083,7 @@ intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) if (intelfbhw_validate_mode(dinfo, var) != 0) return -EINVAL; - memcpy(&v, var, sizeof(v)); + v = *var; /* Check for a supported bpp. */ if (v.bits_per_pixel <= 8) { @@ -1300,7 +1171,7 @@ intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) v.red.msb_right = v.green.msb_right = v.blue.msb_right = v.transp.msb_right = 0; - memcpy(var, &v, sizeof(v)); + *var = v; return 0; } @@ -1318,16 +1189,14 @@ intelfb_set_par(struct fb_info *info) } DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres, - info->var.yres, intelfb_var_to_depth(&info->var)); + info->var.yres, info->var.bits_per_pixel); intelfb_blank(1, info); if (dinfo->accel) intelfbhw_2d_stop(dinfo); - mdelay(100); - - memcpy(&hw, &dinfo->save_state, sizeof(hw)); + hw = dinfo->save_state; if (intelfbhw_mode_to_hw(dinfo, &hw, &info->var)) return -EINVAL; if (intelfbhw_program_mode(dinfo, &hw, 0)) @@ -1340,15 +1209,20 @@ intelfb_set_par(struct fb_info *info) update_dinfo(dinfo, &info->var); - mdelay(100); - if (dinfo->accel) intelfbhw_2d_start(dinfo); - intelfbhw_pan_display(&info->var, info); + intelfb_pan_display(&info->var, info); intelfb_blank(0, info); + if (ACCEL(dinfo, info)) { + info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | + FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | + FBINFO_HWACCEL_IMAGEBLIT; + } else { + info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; + } return 0; } @@ -1433,7 +1307,7 @@ intelfb_fillrect (struct fb_info *info, const struct fb_fillrect *rect) DBG_MSG("intelfb_fillrect\n"); #endif - if (!dinfo->accel || dinfo->ring_lockup || dinfo->depth == 4) + if (!ACCEL(dinfo, info) || dinfo->depth == 4) return cfb_fillrect(info, rect); if (rect->rop == ROP_COPY) @@ -1461,7 +1335,7 @@ intelfb_copyarea(struct fb_info *info, const struct fb_copyarea *region) DBG_MSG("intelfb_copyarea\n"); #endif - if (!dinfo->accel || dinfo->ring_lockup || dinfo->depth == 4) + if (!ACCEL(dinfo, info) || dinfo->depth == 4) return cfb_copyarea(info, region); intelfbhw_do_bitblt(dinfo, region->sx, region->sy, region->dx, @@ -1479,7 +1353,7 @@ intelfb_imageblit(struct fb_info *info, const struct fb_image *image) DBG_MSG("intelfb_imageblit\n"); #endif - if (!dinfo->accel || dinfo->ring_lockup || dinfo->depth == 4 + if (!ACCEL(dinfo, info) || dinfo->depth == 4 || image->depth != 1) return cfb_imageblit(info, image); @@ -1513,7 +1387,7 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor) intelfbhw_cursor_hide(dinfo); /* If XFree killed the cursor - restore it */ - if (INREG(CURSOR_A_BASEADDR) != dinfo->cursor.physical) { + if (INREG(CURSOR_A_BASEADDR) != dinfo->cursor.offset << 12) { u32 fg, bg; DBG_MSG("the cursor was killed - restore it !!\n"); @@ -1573,7 +1447,7 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor) intelfbhw_cursor_setcolor(dinfo, bg, fg); } - if (cursor->set & (FB_CUR_SETSHAPE & FB_CUR_SETIMAGE)) { + if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) { u32 s_pitch = (ROUND_UP_TO(cursor->image.width, 8) / 8); u32 size = s_pitch * cursor->image.height; u8 *dat = (u8 *) cursor->image.data; diff --git a/drivers/video/intelfb/intelfbdrv.h b/drivers/video/intelfb/intelfbdrv.h index 50a3c597eb54..f05dffae0533 100644 --- a/drivers/video/intelfb/intelfbdrv.h +++ b/drivers/video/intelfb/intelfbdrv.h @@ -29,19 +29,11 @@ */ int __init intelfb_setup(char *options); -static void get_initial_mode(struct intelfb_info *dinfo); +static void __devinit get_initial_mode(struct intelfb_info *dinfo); static void update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var); static int intelfb_get_fix(struct fb_fix_screeninfo *fix, struct fb_info *info); -static void mode_to_var(const struct fb_videomode *mode, - struct fb_var_screeninfo *var, u32 bpp); -static int -intelfb_find_mode(struct fb_var_screeninfo *var, - struct fb_info *info, const char *mode_option, - const struct fb_videomode *db, unsigned int dbsize, - const struct fb_videomode *default_mode, - unsigned int default_bpp); static int intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info); @@ -69,8 +61,8 @@ static int intelfb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg, struct fb_info *info); -static int intelfb_pci_register(struct pci_dev *pdev, - const struct pci_device_id *ent); +static int __devinit intelfb_pci_register(struct pci_dev *pdev, + const struct pci_device_id *ent); static void __devexit intelfb_pci_unregister(struct pci_dev *pdev); static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo); diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index 09326a64e2c6..d8dba0bd2fad 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c @@ -290,7 +290,7 @@ intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) if ((xoffset + var->xres > var->xres_virtual) || (yoffset + var->yres > var->yres_virtual)) - return EINVAL; + return -EINVAL; offset = (yoffset * dinfo->pitch) + (xoffset * var->bits_per_pixel) / 8; @@ -1240,7 +1240,7 @@ wait_ring(struct intelfb_info *dinfo, int n) end = jiffies + (HZ * 3); while (dinfo->ring_space < n) { - dinfo->ring_head = (u32 __iomem *)(INREG(PRI_RING_HEAD) & + dinfo->ring_head = (u8 __iomem *)(INREG(PRI_RING_HEAD) & RING_HEAD_MASK); if (dinfo->ring_tail + RING_MIN_FREE < (u32 __iomem) dinfo->ring_head) @@ -1312,8 +1312,8 @@ refresh_ring(struct intelfb_info *dinfo) DBG_MSG("refresh_ring\n"); #endif - dinfo->ring_head = (u32 __iomem *) (INREG(PRI_RING_HEAD) & - RING_HEAD_MASK); + dinfo->ring_head = (u8 __iomem *) (INREG(PRI_RING_HEAD) & + RING_HEAD_MASK); dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK; if (dinfo->ring_tail + RING_MIN_FREE < (u32 __iomem)dinfo->ring_head) dinfo->ring_space = (u32 __iomem) dinfo->ring_head @@ -1605,7 +1605,7 @@ intelfbhw_cursor_init(struct intelfb_info *dinfo) CURSOR_ENABLE | CURSOR_STRIDE_MASK); tmp = CURSOR_FORMAT_3C; OUTREG(CURSOR_CONTROL, tmp); - OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); + OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.offset << 12); tmp = (64 << CURSOR_SIZE_H_SHIFT) | (64 << CURSOR_SIZE_V_SHIFT); OUTREG(CURSOR_SIZE, tmp); diff --git a/drivers/video/leo.c b/drivers/video/leo.c index 99fb72aa184d..35b03302ad10 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c @@ -590,7 +590,6 @@ static void leo_init_one(struct sbus_dev *sdev) all->info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; all->info.fbops = &leo_ops; - all->info.currcon = -1; all->info.par = &all->par; leo_init_wids(&all->info); diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c index 47439c4d276a..4f14d0b91f09 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/matrox/matroxfb_base.c @@ -835,6 +835,7 @@ static int matroxfb_set_par(struct fb_info *info) matrox_cfbX_init(PMINFO2); } } + ACCESS_FBINFO(initialized) = 1; return 0; } @@ -1712,7 +1713,6 @@ static int initMatrox2(WPMINFO struct board* b){ } ACCESS_FBINFO(devflags.ydstorg) = 0; - ACCESS_FBINFO(fbcon.currcon) = -1; ACCESS_FBINFO(video.base) = video_base_phys; ACCESS_FBINFO(video.len_usable) = ACCESS_FBINFO(video.len); if (ACCESS_FBINFO(video.len_usable) > b->base->maxdisplayable) @@ -1877,16 +1877,18 @@ static int initMatrox2(WPMINFO struct board* b){ } printk("fb%d: %s frame buffer device\n", ACCESS_FBINFO(fbcon.node), ACCESS_FBINFO(fbcon.fix.id)); - if (ACCESS_FBINFO(fbcon.currcon) < 0) { - /* there is no console on this fb... but we have to initialize hardware - * until someone tells me what is proper thing to do */ - printk(KERN_INFO "fb%d: initializing hardware\n", - ACCESS_FBINFO(fbcon.node)); - /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var - * already before, so register_framebuffer works correctly. */ - vesafb_defined.activate |= FB_ACTIVATE_FORCE; - fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined); - } + + /* there is no console on this fb... but we have to initialize hardware + * until someone tells me what is proper thing to do */ + if (!ACCESS_FBINFO(initialized)) { + printk(KERN_INFO "fb%d: initializing hardware\n", + ACCESS_FBINFO(fbcon.node)); + /* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var + * already before, so register_framebuffer works correctly. */ + vesafb_defined.activate |= FB_ACTIVATE_FORCE; + fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined); + } + return 0; failVideoIO:; matroxfb_g450_shutdown(PMINFO2); diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index e62fcc84054b..72709cf22335 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h @@ -372,6 +372,7 @@ struct matrox_fb_info { struct list_head next_fb; int dead; + int initialized; unsigned int usecount; unsigned int userusecount; diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c index c5230bbe1da4..610c4aebc71c 100644 --- a/drivers/video/matrox/matroxfb_crtc2.c +++ b/drivers/video/matrox/matroxfb_crtc2.c @@ -387,6 +387,7 @@ static int matroxfb_dh_set_par(struct fb_info* info) { up_read(&ACCESS_FBINFO(altout).lock); matroxfb_dh_cfbX_init(m2info); } + m2info->initialized = 1; return 0; #undef m2info } @@ -605,7 +606,6 @@ static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) { m2info->fbcon.flags = FBINFO_FLAG_DEFAULT; m2info->fbcon.flags |= FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; - m2info->fbcon.currcon = -1; m2info->fbcon.pseudo_palette = m2info->cmap; fb_alloc_cmap(&m2info->fbcon.cmap, 256, 1); @@ -634,9 +634,8 @@ static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) { if (register_framebuffer(&m2info->fbcon)) { return -ENXIO; } - if (m2info->fbcon.currcon < 0) { + if (!m2info->initialized) fb_set_var(&m2info->fbcon, &matroxfb_dh_defined); - } down_write(&ACCESS_FBINFO(crtc2.lock)); oldcrtc2 = ACCESS_FBINFO(crtc2.info); ACCESS_FBINFO(crtc2.info) = m2info; diff --git a/drivers/video/matrox/matroxfb_crtc2.h b/drivers/video/matrox/matroxfb_crtc2.h index 9d92dda90771..608e40bb20e9 100644 --- a/drivers/video/matrox/matroxfb_crtc2.h +++ b/drivers/video/matrox/matroxfb_crtc2.h @@ -9,6 +9,7 @@ struct matroxfb_dh_fb_info { struct fb_info fbcon; int fbcon_registered; + int initialized; struct matrox_fb_info* primary_dev; diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index e75687893752..11e9e6c5d251 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c @@ -1534,7 +1534,7 @@ neo2200_imageblit(struct fb_info *info, const struct fb_image *image) &par->neo2200->xyExt); for (i = 0; i < data_len; i++) - writeb(image->data[i], par->mmio_vbase + 0x100000); + writeb(image->data[i], par->mmio_vbase + 0x100000 + i); } static void diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c index 7fbbef4619df..3048f02e6167 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/p9100.c @@ -307,7 +307,6 @@ static void p9100_init_one(struct sbus_dev *sdev) all->info.screen_base = (char *) sbus_ioremap(&sdev->resource[2], 0, all->par.fbsize, "p9100 ram"); - all->info.currcon = -1; all->info.par = &all->par; p9100_blank(0, &all->info); diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 3e2bb2d887ac..8d0c933ce1d1 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -1043,7 +1043,6 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev) fbi->fb.fbops = &pxafb_ops; fbi->fb.flags = FBINFO_DEFAULT; fbi->fb.node = -1; - fbi->fb.currcon = -1; addr = fbi; addr = addr + sizeof(struct pxafb_info); diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c index 82f8e1529498..ca8d3c3b3efa 100644 --- a/drivers/video/radeonfb.c +++ b/drivers/video/radeonfb.c @@ -2247,7 +2247,6 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo) info = &rinfo->info; - info->currcon = -1; info->par = rinfo; info->pseudo_palette = rinfo->pseudo_palette; info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 81fb07db3c0d..e0df120aa644 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -717,7 +717,7 @@ static void riva_load_video_mode(struct fb_info *info) newmode.ext.interlace = 0xff; /* interlace off */ if (par->riva.Architecture >= NV_ARCH_10) - par->riva.CURSOR = (U032 *)(info->screen_base + par->riva.CursorStart); + par->riva.CURSOR = (U032 __iomem *)(info->screen_base + par->riva.CursorStart); if (info->var.sync & FB_SYNC_HOR_HIGH_ACT) newmode.misc_output &= ~0x40; @@ -731,22 +731,27 @@ static void riva_load_video_mode(struct fb_info *info) par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width, hDisplaySize, height, dotClock); - newmode.ext.scale = par->riva.PRAMDAC[0x00000848/4] & 0xfff000ff; + newmode.ext.scale = NV_RD32(par->riva.PRAMDAC, 0x00000848) & + 0xfff000ff; if (par->FlatPanel == 1) { newmode.ext.pixel |= (1 << 7); newmode.ext.scale |= (1 << 8); } if (par->SecondCRTC) { - newmode.ext.head = par->riva.PCRTC0[0x00000860/4] & ~0x00001000; - newmode.ext.head2 = par->riva.PCRTC0[0x00002860/4] | 0x00001000; + newmode.ext.head = NV_RD32(par->riva.PCRTC0, 0x00000860) & + ~0x00001000; + newmode.ext.head2 = NV_RD32(par->riva.PCRTC0, 0x00002860) | + 0x00001000; newmode.ext.crtcOwner = 3; newmode.ext.pllsel |= 0x20000800; newmode.ext.vpll2 = newmode.ext.vpll; } else if (par->riva.twoHeads) { - newmode.ext.head = par->riva.PCRTC0[0x00000860/4] | 0x00001000; - newmode.ext.head2 = par->riva.PCRTC0[0x00002860/4] & ~0x00001000; + newmode.ext.head = NV_RD32(par->riva.PCRTC0, 0x00000860) | + 0x00001000; + newmode.ext.head2 = NV_RD32(par->riva.PCRTC0, 0x00002860) & + ~0x00001000; newmode.ext.crtcOwner = 0; - newmode.ext.vpll2 = par->riva.PRAMDAC0[0x00000520/4]; + newmode.ext.vpll2 = NV_RD32(par->riva.PRAMDAC0, 0x00000520); } if (par->FlatPanel == 1) { newmode.ext.pixel |= (1 << 7); @@ -887,10 +892,10 @@ static void riva_set_pattern(struct riva_par *par, int clr0, int clr1, int pat0, int pat1) { RIVA_FIFO_FREE(par->riva, Patt, 4); - par->riva.Patt->Color0 = clr0; - par->riva.Patt->Color1 = clr1; - par->riva.Patt->Monochrome[0] = pat0; - par->riva.Patt->Monochrome[1] = pat1; + NV_WR32(&par->riva.Patt->Color0, 0, clr0); + NV_WR32(&par->riva.Patt->Color1, 0, clr1); + NV_WR32(par->riva.Patt->Monochrome, 0, pat0); + NV_WR32(par->riva.Patt->Monochrome, 4, pat1); } /* acceleration routines */ @@ -907,7 +912,7 @@ riva_set_rop_solid(struct riva_par *par, int rop) { riva_set_pattern(par, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF); RIVA_FIFO_FREE(par->riva, Rop, 1); - par->riva.Rop->Rop3 = rop; + NV_WR32(&par->riva.Rop->Rop3, 0, rop); } @@ -916,9 +921,10 @@ void riva_setup_accel(struct fb_info *info) struct riva_par *par = (struct riva_par *) info->par; RIVA_FIFO_FREE(par->riva, Clip, 2); - par->riva.Clip->TopLeft = 0x0; - par->riva.Clip->WidthHeight = (info->var.xres_virtual & 0xffff) | - (info->var.yres_virtual << 16); + NV_WR32(&par->riva.Clip->TopLeft, 0, 0x0); + NV_WR32(&par->riva.Clip->WidthHeight, 0, + (info->var.xres_virtual & 0xffff) | + (info->var.yres_virtual << 16)); riva_set_rop_solid(par, 0xcc); wait_for_idle(par); } @@ -1405,14 +1411,14 @@ static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect riva_set_rop_solid(par, rop); RIVA_FIFO_FREE(par->riva, Bitmap, 1); - par->riva.Bitmap->Color1A = color; + NV_WR32(&par->riva.Bitmap->Color1A, 0, color); RIVA_FIFO_FREE(par->riva, Bitmap, 2); - par->riva.Bitmap->UnclippedRectangle[0].TopLeft = - (rect->dx << 16) | rect->dy; + NV_WR32(&par->riva.Bitmap->UnclippedRectangle[0].TopLeft, 0, + (rect->dx << 16) | rect->dy); mb(); - par->riva.Bitmap->UnclippedRectangle[0].WidthHeight = - (rect->width << 16) | rect->height; + NV_WR32(&par->riva.Bitmap->UnclippedRectangle[0].WidthHeight, 0, + (rect->width << 16) | rect->height); mb(); riva_set_rop_solid(par, 0xcc); @@ -1439,10 +1445,13 @@ static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *regi } RIVA_FIFO_FREE(par->riva, Blt, 3); - par->riva.Blt->TopLeftSrc = (region->sy << 16) | region->sx; - par->riva.Blt->TopLeftDst = (region->dy << 16) | region->dx; + NV_WR32(&par->riva.Blt->TopLeftSrc, 0, + (region->sy << 16) | region->sx); + NV_WR32(&par->riva.Blt->TopLeftDst, 0, + (region->dy << 16) | region->dx); mb(); - par->riva.Blt->WidthHeight = (region->height << 16) | region->width; + NV_WR32(&par->riva.Blt->WidthHeight, 0, + (region->height << 16) | region->width); mb(); } @@ -1477,7 +1486,7 @@ static void rivafb_imageblit(struct fb_info *info, struct riva_par *par = (struct riva_par *) info->par; u32 fgx = 0, bgx = 0, width, tmp; u8 *cdat = (u8 *) image->data; - volatile u32 *d; + volatile u32 __iomem *d; int i, size; if ((info->flags & FBINFO_HWACCEL_DISABLED) || image->depth != 1) { @@ -1505,19 +1514,19 @@ static void rivafb_imageblit(struct fb_info *info, } RIVA_FIFO_FREE(par->riva, Bitmap, 7); - par->riva.Bitmap->ClipE.TopLeft = - (image->dy << 16) | (image->dx & 0xFFFF); - par->riva.Bitmap->ClipE.BottomRight = + NV_WR32(&par->riva.Bitmap->ClipE.TopLeft, 0, + (image->dy << 16) | (image->dx & 0xFFFF)); + NV_WR32(&par->riva.Bitmap->ClipE.BottomRight, 0, (((image->dy + image->height) << 16) | - ((image->dx + image->width) & 0xffff)); - par->riva.Bitmap->Color0E = bgx; - par->riva.Bitmap->Color1E = fgx; - par->riva.Bitmap->WidthHeightInE = - (image->height << 16) | ((image->width + 31) & ~31); - par->riva.Bitmap->WidthHeightOutE = - (image->height << 16) | ((image->width + 31) & ~31); - par->riva.Bitmap->PointE = - (image->dy << 16) | (image->dx & 0xFFFF); + ((image->dx + image->width) & 0xffff))); + NV_WR32(&par->riva.Bitmap->Color0E, 0, bgx); + NV_WR32(&par->riva.Bitmap->Color1E, 0, fgx); + NV_WR32(&par->riva.Bitmap->WidthHeightInE, 0, + (image->height << 16) | ((image->width + 31) & ~31)); + NV_WR32(&par->riva.Bitmap->WidthHeightOutE, 0, + (image->height << 16) | ((image->width + 31) & ~31)); + NV_WR32(&par->riva.Bitmap->PointE, 0, + (image->dy << 16) | (image->dx & 0xFFFF)); d = &par->riva.Bitmap->MonochromeData01E; @@ -1529,7 +1538,7 @@ static void rivafb_imageblit(struct fb_info *info, tmp = *((u32 *)cdat); cdat = (u8 *)((u32 *)cdat + 1); reverse_order(&tmp); - d[i] = tmp; + NV_WR32(d, i*4, tmp); } size -= 16; } @@ -1539,7 +1548,7 @@ static void rivafb_imageblit(struct fb_info *info, tmp = *((u32 *) cdat); cdat = (u8 *)((u32 *)cdat + 1); reverse_order(&tmp); - d[i] = tmp; + NV_WR32(d, i*4, tmp); } } } @@ -1582,7 +1591,7 @@ static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor) temp = xx & 0xFFFF; temp |= yy << 16; - par->riva.PRAMDAC[0x0000300/4] = temp; + NV_WR32(par->riva.PRAMDAC, 0x0000300, temp); } @@ -1960,8 +1969,10 @@ static int __devinit rivafb_probe(struct pci_dev *pd, case NV_ARCH_10: case NV_ARCH_20: case NV_ARCH_30: - default_par->riva.PCRTC0 = (unsigned *)(default_par->ctrl_base + 0x00600000); - default_par->riva.PRAMIN = (unsigned *)(default_par->ctrl_base + 0x00710000); + default_par->riva.PCRTC0 = + (u32 __iomem *)(default_par->ctrl_base + 0x00600000); + default_par->riva.PRAMIN = + (u32 __iomem *)(default_par->ctrl_base + 0x00710000); break; } riva_common_setup(default_par); @@ -2037,7 +2048,7 @@ err_out_iounmap_fb: iounmap(info->screen_base); err_out_free_base1: if (default_par->riva.Architecture == NV_ARCH_03) - iounmap((caddr_t)default_par->riva.PRAMIN); + iounmap(default_par->riva.PRAMIN); err_out_free_nv3_pramin: iounmap(default_par->ctrl_base); err_out_free_base0: @@ -2077,7 +2088,7 @@ static void __exit rivafb_remove(struct pci_dev *pd) iounmap(par->ctrl_base); iounmap(info->screen_base); if (par->riva.Architecture == NV_ARCH_03) - iounmap((caddr_t)par->riva.PRAMIN); + iounmap(par->riva.PRAMIN); pci_release_regions(pd); pci_disable_device(pd); kfree(info->pixmap.addr); diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/riva/riva_hw.c index cf74b90f3cf2..8bb31abd45fc 100644 --- a/drivers/video/riva/riva_hw.c +++ b/drivers/video/riva/riva_hw.c @@ -62,21 +62,24 @@ static int nv3Busy RIVA_HW_INST *chip ) { - return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x000006B0/4] & 0x01)); + return ((NV_RD32(&chip->Rop->FifoFree, 0) < chip->FifoEmptyCount) || + NV_RD32(&chip->PGRAPH[0x000006B0/4], 0) & 0x01); } static int nv4Busy ( RIVA_HW_INST *chip ) { - return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x00000700/4] & 0x01)); + return ((NV_RD32(&chip->Rop->FifoFree, 0) < chip->FifoEmptyCount) || + NV_RD32(&chip->PGRAPH[0x00000700/4], 0) & 0x01); } static int nv10Busy ( RIVA_HW_INST *chip ) { - return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x00000700/4] & 0x01)); + return ((NV_RD32(&chip->Rop->FifoFree, 0) < chip->FifoEmptyCount) || + NV_RD32(&chip->PGRAPH[0x00000700/4], 0) & 0x01); } static void vgaLockUnlock @@ -616,14 +619,15 @@ static void nv3UpdateArbitrationSettings nv3_sim_state sim_data; unsigned int M, N, P, pll, MClk; - pll = chip->PRAMDAC0[0x00000504/4]; + pll = NV_RD32(&chip->PRAMDAC0[0x00000504/4], 0); M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; MClk = (N * chip->CrystalFreqKHz / M) >> P; sim_data.pix_bpp = (char)pixelDepth; sim_data.enable_video = 0; sim_data.enable_mp = 0; sim_data.video_scale = 1; - sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64; + sim_data.memory_width = (NV_RD32(&chip->PEXTDEV[0x00000000/4], 0) & 0x10) ? + 128 : 64; sim_data.memory_width = 128; sim_data.mem_latency = 9; @@ -637,7 +641,10 @@ static void nv3UpdateArbitrationSettings { int b = fifo_data.graphics_burst_size >> 4; *burst = 0; - while (b >>= 1) (*burst)++; + while (b) { + (*burst)++; + b >>= 1; + } *lwm = fifo_data.graphics_lwm >> 3; } else @@ -803,17 +810,18 @@ static void nv4UpdateArbitrationSettings nv4_sim_state sim_data; unsigned int M, N, P, pll, MClk, NVClk, cfg1; - pll = chip->PRAMDAC0[0x00000504/4]; + pll = NV_RD32(&chip->PRAMDAC0[0x00000504/4], 0); M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; MClk = (N * chip->CrystalFreqKHz / M) >> P; - pll = chip->PRAMDAC0[0x00000500/4]; + pll = NV_RD32(&chip->PRAMDAC0[0x00000500/4], 0); M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; NVClk = (N * chip->CrystalFreqKHz / M) >> P; - cfg1 = chip->PFB[0x00000204/4]; + cfg1 = NV_RD32(&chip->PFB[0x00000204/4], 0); sim_data.pix_bpp = (char)pixelDepth; sim_data.enable_video = 0; sim_data.enable_mp = 0; - sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64; + sim_data.memory_width = (NV_RD32(&chip->PEXTDEV[0x00000000/4], 0) & 0x10) ? + 128 : 64; sim_data.mem_latency = (char)cfg1 & 0x0F; sim_data.mem_aligned = 1; sim_data.mem_page_miss = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01)); @@ -826,7 +834,10 @@ static void nv4UpdateArbitrationSettings { int b = fifo_data.graphics_burst_size >> 4; *burst = 0; - while (b >>= 1) (*burst)++; + while (b) { + (*burst)++; + b >>= 1; + } *lwm = fifo_data.graphics_lwm >> 3; } } @@ -1064,18 +1075,20 @@ static void nv10UpdateArbitrationSettings nv10_sim_state sim_data; unsigned int M, N, P, pll, MClk, NVClk, cfg1; - pll = chip->PRAMDAC0[0x00000504/4]; + pll = NV_RD32(&chip->PRAMDAC0[0x00000504/4], 0); M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; MClk = (N * chip->CrystalFreqKHz / M) >> P; - pll = chip->PRAMDAC0[0x00000500/4]; + pll = NV_RD32(&chip->PRAMDAC0[0x00000500/4], 0); M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; NVClk = (N * chip->CrystalFreqKHz / M) >> P; - cfg1 = chip->PFB[0x00000204/4]; + cfg1 = NV_RD32(&chip->PFB[0x00000204/4], 0); sim_data.pix_bpp = (char)pixelDepth; sim_data.enable_video = 0; sim_data.enable_mp = 0; - sim_data.memory_type = (chip->PFB[0x00000200/4] & 0x01) ? 1 : 0; - sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64; + sim_data.memory_type = (NV_RD32(&chip->PFB[0x00000200/4], 0) & 0x01) ? + 1 : 0; + sim_data.memory_width = (NV_RD32(&chip->PEXTDEV[0x00000000/4], 0) & 0x10) ? + 128 : 64; sim_data.mem_latency = (char)cfg1 & 0x0F; sim_data.mem_aligned = 1; sim_data.mem_page_miss = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01)); @@ -1088,7 +1101,10 @@ static void nv10UpdateArbitrationSettings { int b = fifo_data.graphics_burst_size >> 4; *burst = 0; - while (b >>= 1) (*burst)++; + while (b) { + (*burst)++; + b >>= 1; + } *lwm = fifo_data.graphics_lwm >> 3; } } @@ -1115,7 +1131,7 @@ static void nForceUpdateArbitrationSettings if(!uMClkPostDiv) uMClkPostDiv = 4; MClk = 400000 / uMClkPostDiv; - pll = chip->PRAMDAC0[0x00000500/4]; + pll = NV_RD32(&chip->PRAMDAC0[0x00000500/4], 0); M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F; NVClk = (N * chip->CrystalFreqKHz / M) >> P; sim_data.pix_bpp = (char)pixelDepth; @@ -1139,7 +1155,10 @@ static void nForceUpdateArbitrationSettings { int b = fifo_data.graphics_burst_size >> 4; *burst = 0; - while (b >>= 1) (*burst)++; + while (b) { + (*burst)++; + b >>= 1; + } *lwm = fifo_data.graphics_lwm >> 3; } } @@ -1294,7 +1313,7 @@ static void CalcStateExt state->cursor1 = (chip->CursorStart >> 11) << 2; state->cursor2 = chip->CursorStart >> 24; state->pllsel = 0x10000700; - state->config = chip->PFB[0x00000200/4]; + state->config = NV_RD32(&chip->PFB[0x00000200/4], 0); state->general = bpp == 16 ? 0x00101100 : 0x00100100; state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00; break; @@ -1320,6 +1339,7 @@ static void CalcStateExt /* * Load fixed function state and pre-calculated/stored state. */ +#if 0 #define LOAD_FIXED_STATE(tbl,dev) \ for (i = 0; i < sizeof(tbl##Table##dev)/8; i++) \ chip->dev[tbl##Table##dev[i][0]] = tbl##Table##dev[i][1] @@ -1335,6 +1355,24 @@ static void CalcStateExt #define LOAD_FIXED_STATE_32BPP(tbl,dev) \ for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++) \ chip->dev[tbl##Table##dev##_32BPP[i][0]] = tbl##Table##dev##_32BPP[i][1] +#endif + +#define LOAD_FIXED_STATE(tbl,dev) \ + for (i = 0; i < sizeof(tbl##Table##dev)/8; i++) \ + NV_WR32(&chip->dev[tbl##Table##dev[i][0]], 0, tbl##Table##dev[i][1]) +#define LOAD_FIXED_STATE_8BPP(tbl,dev) \ + for (i = 0; i < sizeof(tbl##Table##dev##_8BPP)/8; i++) \ + NV_WR32(&chip->dev[tbl##Table##dev##_8BPP[i][0]], 0, tbl##Table##dev##_8BPP[i][1]) +#define LOAD_FIXED_STATE_15BPP(tbl,dev) \ + for (i = 0; i < sizeof(tbl##Table##dev##_15BPP)/8; i++) \ + NV_WR32(&chip->dev[tbl##Table##dev##_15BPP[i][0]], 0, tbl##Table##dev##_15BPP[i][1]) +#define LOAD_FIXED_STATE_16BPP(tbl,dev) \ + for (i = 0; i < sizeof(tbl##Table##dev##_16BPP)/8; i++) \ + NV_WR32(&chip->dev[tbl##Table##dev##_16BPP[i][0]], 0, tbl##Table##dev##_16BPP[i][1]) +#define LOAD_FIXED_STATE_32BPP(tbl,dev) \ + for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++) \ + NV_WR32(&chip->dev[tbl##Table##dev##_32BPP[i][0]], 0, tbl##Table##dev##_32BPP[i][1]) + static void UpdateFifoState ( RIVA_HW_INST *chip @@ -1347,7 +1385,7 @@ static void UpdateFifoState case NV_ARCH_04: LOAD_FIXED_STATE(nv4,FIFO); chip->Tri03 = NULL; - chip->Tri05 = (RivaTexturedTriangle05 *)&(chip->FIFO[0x0000E000/4]); + chip->Tri05 = (RivaTexturedTriangle05 __iomem *)&(chip->FIFO[0x0000E000/4]); break; case NV_ARCH_10: case NV_ARCH_20: @@ -1358,7 +1396,7 @@ static void UpdateFifoState LOAD_FIXED_STATE(nv10tri05,PGRAPH); LOAD_FIXED_STATE(nv10,FIFO); chip->Tri03 = NULL; - chip->Tri05 = (RivaTexturedTriangle05 *)&(chip->FIFO[0x0000E000/4]); + chip->Tri05 = (RivaTexturedTriangle05 __iomem *)&(chip->FIFO[0x0000E000/4]); break; } } @@ -1381,7 +1419,7 @@ static void LoadStateExt /* * Make sure frame buffer config gets set before loading PRAMIN. */ - chip->PFB[0x00000200/4] = state->config; + NV_WR32(chip->PFB, 0x00000200, state->config); LOAD_FIXED_STATE(nv3,PFIFO); LOAD_FIXED_STATE(nv3,PRAMIN); LOAD_FIXED_STATE(nv3,PGRAPH); @@ -1391,7 +1429,7 @@ static void LoadStateExt case 16: LOAD_FIXED_STATE_15BPP(nv3,PRAMIN); LOAD_FIXED_STATE_15BPP(nv3,PGRAPH); - chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]); + chip->Tri03 = (RivaTexturedTriangle03 __iomem *)&(chip->FIFO[0x0000E000/4]); break; case 24: case 32: @@ -1407,21 +1445,21 @@ static void LoadStateExt break; } for (i = 0x00000; i < 0x00800; i++) - chip->PRAMIN[0x00000502 + i] = (i << 12) | 0x03; - chip->PGRAPH[0x00000630/4] = state->offset0; - chip->PGRAPH[0x00000634/4] = state->offset1; - chip->PGRAPH[0x00000638/4] = state->offset2; - chip->PGRAPH[0x0000063C/4] = state->offset3; - chip->PGRAPH[0x00000650/4] = state->pitch0; - chip->PGRAPH[0x00000654/4] = state->pitch1; - chip->PGRAPH[0x00000658/4] = state->pitch2; - chip->PGRAPH[0x0000065C/4] = state->pitch3; + NV_WR32(&chip->PRAMIN[0x00000502 + i], 0, (i << 12) | 0x03); + NV_WR32(chip->PGRAPH, 0x00000630, state->offset0); + NV_WR32(chip->PGRAPH, 0x00000634, state->offset1); + NV_WR32(chip->PGRAPH, 0x00000638, state->offset2); + NV_WR32(chip->PGRAPH, 0x0000063C, state->offset3); + NV_WR32(chip->PGRAPH, 0x00000650, state->pitch0); + NV_WR32(chip->PGRAPH, 0x00000654, state->pitch1); + NV_WR32(chip->PGRAPH, 0x00000658, state->pitch2); + NV_WR32(chip->PGRAPH, 0x0000065C, state->pitch3); break; case NV_ARCH_04: /* * Make sure frame buffer config gets set before loading PRAMIN. */ - chip->PFB[0x00000200/4] = state->config; + NV_WR32(chip->PFB, 0x00000200, state->config); LOAD_FIXED_STATE(nv4,PFIFO); LOAD_FIXED_STATE(nv4,PRAMIN); LOAD_FIXED_STATE(nv4,PGRAPH); @@ -1430,12 +1468,12 @@ static void LoadStateExt case 15: LOAD_FIXED_STATE_15BPP(nv4,PRAMIN); LOAD_FIXED_STATE_15BPP(nv4,PGRAPH); - chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]); + chip->Tri03 = (RivaTexturedTriangle03 __iomem *)&(chip->FIFO[0x0000E000/4]); break; case 16: LOAD_FIXED_STATE_16BPP(nv4,PRAMIN); LOAD_FIXED_STATE_16BPP(nv4,PGRAPH); - chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]); + chip->Tri03 = (RivaTexturedTriangle03 __iomem *)&(chip->FIFO[0x0000E000/4]); break; case 24: case 32: @@ -1450,14 +1488,14 @@ static void LoadStateExt chip->Tri03 = NULL; break; } - chip->PGRAPH[0x00000640/4] = state->offset0; - chip->PGRAPH[0x00000644/4] = state->offset1; - chip->PGRAPH[0x00000648/4] = state->offset2; - chip->PGRAPH[0x0000064C/4] = state->offset3; - chip->PGRAPH[0x00000670/4] = state->pitch0; - chip->PGRAPH[0x00000674/4] = state->pitch1; - chip->PGRAPH[0x00000678/4] = state->pitch2; - chip->PGRAPH[0x0000067C/4] = state->pitch3; + NV_WR32(chip->PGRAPH, 0x00000640, state->offset0); + NV_WR32(chip->PGRAPH, 0x00000644, state->offset1); + NV_WR32(chip->PGRAPH, 0x00000648, state->offset2); + NV_WR32(chip->PGRAPH, 0x0000064C, state->offset3); + NV_WR32(chip->PGRAPH, 0x00000670, state->pitch0); + NV_WR32(chip->PGRAPH, 0x00000674, state->pitch1); + NV_WR32(chip->PGRAPH, 0x00000678, state->pitch2); + NV_WR32(chip->PGRAPH, 0x0000067C, state->pitch3); break; case NV_ARCH_10: case NV_ARCH_20: @@ -1476,12 +1514,12 @@ static void LoadStateExt case 15: LOAD_FIXED_STATE_15BPP(nv10,PRAMIN); LOAD_FIXED_STATE_15BPP(nv10,PGRAPH); - chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]); + chip->Tri03 = (RivaTexturedTriangle03 __iomem *)&(chip->FIFO[0x0000E000/4]); break; case 16: LOAD_FIXED_STATE_16BPP(nv10,PRAMIN); LOAD_FIXED_STATE_16BPP(nv10,PGRAPH); - chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]); + chip->Tri03 = (RivaTexturedTriangle03 __iomem *)&(chip->FIFO[0x0000E000/4]); break; case 24: case 32: @@ -1498,134 +1536,134 @@ static void LoadStateExt } if(chip->Architecture == NV_ARCH_10) { - chip->PGRAPH[0x00000640/4] = state->offset0; - chip->PGRAPH[0x00000644/4] = state->offset1; - chip->PGRAPH[0x00000648/4] = state->offset2; - chip->PGRAPH[0x0000064C/4] = state->offset3; - chip->PGRAPH[0x00000670/4] = state->pitch0; - chip->PGRAPH[0x00000674/4] = state->pitch1; - chip->PGRAPH[0x00000678/4] = state->pitch2; - chip->PGRAPH[0x0000067C/4] = state->pitch3; - chip->PGRAPH[0x00000680/4] = state->pitch3; + NV_WR32(chip->PGRAPH, 0x00000640, state->offset0); + NV_WR32(chip->PGRAPH, 0x00000644, state->offset1); + NV_WR32(chip->PGRAPH, 0x00000648, state->offset2); + NV_WR32(chip->PGRAPH, 0x0000064C, state->offset3); + NV_WR32(chip->PGRAPH, 0x00000670, state->pitch0); + NV_WR32(chip->PGRAPH, 0x00000674, state->pitch1); + NV_WR32(chip->PGRAPH, 0x00000678, state->pitch2); + NV_WR32(chip->PGRAPH, 0x0000067C, state->pitch3); + NV_WR32(chip->PGRAPH, 0x00000680, state->pitch3); } else { - chip->PGRAPH[0x00000820/4] = state->offset0; - chip->PGRAPH[0x00000824/4] = state->offset1; - chip->PGRAPH[0x00000828/4] = state->offset2; - chip->PGRAPH[0x0000082C/4] = state->offset3; - chip->PGRAPH[0x00000850/4] = state->pitch0; - chip->PGRAPH[0x00000854/4] = state->pitch1; - chip->PGRAPH[0x00000858/4] = state->pitch2; - chip->PGRAPH[0x0000085C/4] = state->pitch3; - chip->PGRAPH[0x00000860/4] = state->pitch3; - chip->PGRAPH[0x00000864/4] = state->pitch3; - chip->PGRAPH[0x000009A4/4] = chip->PFB[0x00000200/4]; - chip->PGRAPH[0x000009A8/4] = chip->PFB[0x00000204/4]; + NV_WR32(chip->PGRAPH, 0x00000820, state->offset0); + NV_WR32(chip->PGRAPH, 0x00000824, state->offset1); + NV_WR32(chip->PGRAPH, 0x00000828, state->offset2); + NV_WR32(chip->PGRAPH, 0x0000082C, state->offset3); + NV_WR32(chip->PGRAPH, 0x00000850, state->pitch0); + NV_WR32(chip->PGRAPH, 0x00000854, state->pitch1); + NV_WR32(chip->PGRAPH, 0x00000858, state->pitch2); + NV_WR32(chip->PGRAPH, 0x0000085C, state->pitch3); + NV_WR32(chip->PGRAPH, 0x00000860, state->pitch3); + NV_WR32(chip->PGRAPH, 0x00000864, state->pitch3); + NV_WR32(chip->PGRAPH, 0x000009A, NV_RD32(chip->PFB, 0x00000200)); + NV_WR32(chip->PGRAPH, 0x000009A8, NV_RD32(chip->PFB, 0x00000204)); } if(chip->twoHeads) { - chip->PCRTC0[0x00000860/4] = state->head; - chip->PCRTC0[0x00002860/4] = state->head2; + NV_WR32(chip->PCRTC0, 0x00000860, state->head); + NV_WR32(chip->PCRTC0, 0x00002860, state->head2); } - chip->PRAMDAC[0x00000404/4] |= (1 << 25); - - chip->PMC[0x00008704/4] = 1; - chip->PMC[0x00008140/4] = 0; - chip->PMC[0x00008920/4] = 0; - chip->PMC[0x00008924/4] = 0; - chip->PMC[0x00008908/4] = 0x01ffffff; - chip->PMC[0x0000890C/4] = 0x01ffffff; - chip->PMC[0x00001588/4] = 0; - - chip->PFB[0x00000240/4] = 0; - chip->PFB[0x00000250/4] = 0; - chip->PFB[0x00000260/4] = 0; - chip->PFB[0x00000270/4] = 0; - chip->PFB[0x00000280/4] = 0; - chip->PFB[0x00000290/4] = 0; - chip->PFB[0x000002A0/4] = 0; - chip->PFB[0x000002B0/4] = 0; - - chip->PGRAPH[0x00000B00/4] = chip->PFB[0x00000240/4]; - chip->PGRAPH[0x00000B04/4] = chip->PFB[0x00000244/4]; - chip->PGRAPH[0x00000B08/4] = chip->PFB[0x00000248/4]; - chip->PGRAPH[0x00000B0C/4] = chip->PFB[0x0000024C/4]; - chip->PGRAPH[0x00000B10/4] = chip->PFB[0x00000250/4]; - chip->PGRAPH[0x00000B14/4] = chip->PFB[0x00000254/4]; - chip->PGRAPH[0x00000B18/4] = chip->PFB[0x00000258/4]; - chip->PGRAPH[0x00000B1C/4] = chip->PFB[0x0000025C/4]; - chip->PGRAPH[0x00000B20/4] = chip->PFB[0x00000260/4]; - chip->PGRAPH[0x00000B24/4] = chip->PFB[0x00000264/4]; - chip->PGRAPH[0x00000B28/4] = chip->PFB[0x00000268/4]; - chip->PGRAPH[0x00000B2C/4] = chip->PFB[0x0000026C/4]; - chip->PGRAPH[0x00000B30/4] = chip->PFB[0x00000270/4]; - chip->PGRAPH[0x00000B34/4] = chip->PFB[0x00000274/4]; - chip->PGRAPH[0x00000B38/4] = chip->PFB[0x00000278/4]; - chip->PGRAPH[0x00000B3C/4] = chip->PFB[0x0000027C/4]; - chip->PGRAPH[0x00000B40/4] = chip->PFB[0x00000280/4]; - chip->PGRAPH[0x00000B44/4] = chip->PFB[0x00000284/4]; - chip->PGRAPH[0x00000B48/4] = chip->PFB[0x00000288/4]; - chip->PGRAPH[0x00000B4C/4] = chip->PFB[0x0000028C/4]; - chip->PGRAPH[0x00000B50/4] = chip->PFB[0x00000290/4]; - chip->PGRAPH[0x00000B54/4] = chip->PFB[0x00000294/4]; - chip->PGRAPH[0x00000B58/4] = chip->PFB[0x00000298/4]; - chip->PGRAPH[0x00000B5C/4] = chip->PFB[0x0000029C/4]; - chip->PGRAPH[0x00000B60/4] = chip->PFB[0x000002A0/4]; - chip->PGRAPH[0x00000B64/4] = chip->PFB[0x000002A4/4]; - chip->PGRAPH[0x00000B68/4] = chip->PFB[0x000002A8/4]; - chip->PGRAPH[0x00000B6C/4] = chip->PFB[0x000002AC/4]; - chip->PGRAPH[0x00000B70/4] = chip->PFB[0x000002B0/4]; - chip->PGRAPH[0x00000B74/4] = chip->PFB[0x000002B4/4]; - chip->PGRAPH[0x00000B78/4] = chip->PFB[0x000002B8/4]; - chip->PGRAPH[0x00000B7C/4] = chip->PFB[0x000002BC/4]; - chip->PGRAPH[0x00000F40/4] = 0x10000000; - chip->PGRAPH[0x00000F44/4] = 0x00000000; - chip->PGRAPH[0x00000F50/4] = 0x00000040; - chip->PGRAPH[0x00000F54/4] = 0x00000008; - chip->PGRAPH[0x00000F50/4] = 0x00000200; + NV_WR32(chip->PRAMDAC, 0x00000404, NV_RD32(chip->PRAMDAC, 0x00000404) | (1 << 25)); + + NV_WR32(chip->PMC, 0x00008704, 1); + NV_WR32(chip->PMC, 0x00008140, 0); + NV_WR32(chip->PMC, 0x00008920, 0); + NV_WR32(chip->PMC, 0x00008924, 0); + NV_WR32(chip->PMC, 0x00008908, 0x01ffffff); + NV_WR32(chip->PMC, 0x0000890C, 0x01ffffff); + NV_WR32(chip->PMC, 0x00001588, 0); + + NV_WR32(chip->PFB, 0x00000240, 0); + NV_WR32(chip->PFB, 0x00000250, 0); + NV_WR32(chip->PFB, 0x00000260, 0); + NV_WR32(chip->PFB, 0x00000270, 0); + NV_WR32(chip->PFB, 0x00000280, 0); + NV_WR32(chip->PFB, 0x00000290, 0); + NV_WR32(chip->PFB, 0x000002A0, 0); + NV_WR32(chip->PFB, 0x000002B0, 0); + + NV_WR32(chip->PGRAPH, 0x00000B00, NV_RD32(chip->PFB, 0x00000240)); + NV_WR32(chip->PGRAPH, 0x00000B04, NV_RD32(chip->PFB, 0x00000244)); + NV_WR32(chip->PGRAPH, 0x00000B08, NV_RD32(chip->PFB, 0x00000248)); + NV_WR32(chip->PGRAPH, 0x00000B0C, NV_RD32(chip->PFB, 0x0000024C)); + NV_WR32(chip->PGRAPH, 0x00000B10, NV_RD32(chip->PFB, 0x00000250)); + NV_WR32(chip->PGRAPH, 0x00000B14, NV_RD32(chip->PFB, 0x00000254)); + NV_WR32(chip->PGRAPH, 0x00000B18, NV_RD32(chip->PFB, 0x00000258)); + NV_WR32(chip->PGRAPH, 0x00000B1C, NV_RD32(chip->PFB, 0x0000025C)); + NV_WR32(chip->PGRAPH, 0x00000B20, NV_RD32(chip->PFB, 0x00000260)); + NV_WR32(chip->PGRAPH, 0x00000B24, NV_RD32(chip->PFB, 0x00000264)); + NV_WR32(chip->PGRAPH, 0x00000B28, NV_RD32(chip->PFB, 0x00000268)); + NV_WR32(chip->PGRAPH, 0x00000B2C, NV_RD32(chip->PFB, 0x0000026C)); + NV_WR32(chip->PGRAPH, 0x00000B30, NV_RD32(chip->PFB, 0x00000270)); + NV_WR32(chip->PGRAPH, 0x00000B34, NV_RD32(chip->PFB, 0x00000274)); + NV_WR32(chip->PGRAPH, 0x00000B38, NV_RD32(chip->PFB, 0x00000278)); + NV_WR32(chip->PGRAPH, 0x00000B3C, NV_RD32(chip->PFB, 0x0000027C)); + NV_WR32(chip->PGRAPH, 0x00000B40, NV_RD32(chip->PFB, 0x00000280)); + NV_WR32(chip->PGRAPH, 0x00000B44, NV_RD32(chip->PFB, 0x00000284)); + NV_WR32(chip->PGRAPH, 0x00000B48, NV_RD32(chip->PFB, 0x00000288)); + NV_WR32(chip->PGRAPH, 0x00000B4C, NV_RD32(chip->PFB, 0x0000028C)); + NV_WR32(chip->PGRAPH, 0x00000B50, NV_RD32(chip->PFB, 0x00000290)); + NV_WR32(chip->PGRAPH, 0x00000B54, NV_RD32(chip->PFB, 0x00000294)); + NV_WR32(chip->PGRAPH, 0x00000B58, NV_RD32(chip->PFB, 0x00000298)); + NV_WR32(chip->PGRAPH, 0x00000B5C, NV_RD32(chip->PFB, 0x0000029C)); + NV_WR32(chip->PGRAPH, 0x00000B60, NV_RD32(chip->PFB, 0x000002A0)); + NV_WR32(chip->PGRAPH, 0x00000B64, NV_RD32(chip->PFB, 0x000002A4)); + NV_WR32(chip->PGRAPH, 0x00000B68, NV_RD32(chip->PFB, 0x000002A8)); + NV_WR32(chip->PGRAPH, 0x00000B6C, NV_RD32(chip->PFB, 0x000002AC)); + NV_WR32(chip->PGRAPH, 0x00000B70, NV_RD32(chip->PFB, 0x000002B0)); + NV_WR32(chip->PGRAPH, 0x00000B74, NV_RD32(chip->PFB, 0x000002B4)); + NV_WR32(chip->PGRAPH, 0x00000B78, NV_RD32(chip->PFB, 0x000002B8)); + NV_WR32(chip->PGRAPH, 0x00000B7C, NV_RD32(chip->PFB, 0x000002BC)); + NV_WR32(chip->PGRAPH, 0x00000F40, 0x10000000); + NV_WR32(chip->PGRAPH, 0x00000F44, 0x00000000); + NV_WR32(chip->PGRAPH, 0x00000F50, 0x00000040); + NV_WR32(chip->PGRAPH, 0x00000F54, 0x00000008); + NV_WR32(chip->PGRAPH, 0x00000F50, 0x00000200); for (i = 0; i < (3*16); i++) - chip->PGRAPH[0x00000F54/4] = 0x00000000; - chip->PGRAPH[0x00000F50/4] = 0x00000040; - chip->PGRAPH[0x00000F54/4] = 0x00000000; - chip->PGRAPH[0x00000F50/4] = 0x00000800; + NV_WR32(chip->PGRAPH, 0x00000F54, 0x00000000); + NV_WR32(chip->PGRAPH, 0x00000F50, 0x00000040); + NV_WR32(chip->PGRAPH, 0x00000F54, 0x00000000); + NV_WR32(chip->PGRAPH, 0x00000F50, 0x00000800); for (i = 0; i < (16*16); i++) - chip->PGRAPH[0x00000F54/4] = 0x00000000; - chip->PGRAPH[0x00000F40/4] = 0x30000000; - chip->PGRAPH[0x00000F44/4] = 0x00000004; - chip->PGRAPH[0x00000F50/4] = 0x00006400; + NV_WR32(chip->PGRAPH, 0x00000F54, 0x00000000); + NV_WR32(chip->PGRAPH, 0x00000F40, 0x30000000); + NV_WR32(chip->PGRAPH, 0x00000F44, 0x00000004); + NV_WR32(chip->PGRAPH, 0x00000F50, 0x00006400); for (i = 0; i < (59*4); i++) - chip->PGRAPH[0x00000F54/4] = 0x00000000; - chip->PGRAPH[0x00000F50/4] = 0x00006800; + NV_WR32(chip->PGRAPH, 0x00000F54, 0x00000000); + NV_WR32(chip->PGRAPH, 0x00000F50, 0x00006800); for (i = 0; i < (47*4); i++) - chip->PGRAPH[0x00000F54/4] = 0x00000000; - chip->PGRAPH[0x00000F50/4] = 0x00006C00; + NV_WR32(chip->PGRAPH, 0x00000F54, 0x00000000); + NV_WR32(chip->PGRAPH, 0x00000F50, 0x00006C00); for (i = 0; i < (3*4); i++) - chip->PGRAPH[0x00000F54/4] = 0x00000000; - chip->PGRAPH[0x00000F50/4] = 0x00007000; + NV_WR32(chip->PGRAPH, 0x00000F54, 0x00000000); + NV_WR32(chip->PGRAPH, 0x00000F50, 0x00007000); for (i = 0; i < (19*4); i++) - chip->PGRAPH[0x00000F54/4] = 0x00000000; - chip->PGRAPH[0x00000F50/4] = 0x00007400; + NV_WR32(chip->PGRAPH, 0x00000F54, 0x00000000); + NV_WR32(chip->PGRAPH, 0x00000F50, 0x00007400); for (i = 0; i < (12*4); i++) - chip->PGRAPH[0x00000F54/4] = 0x00000000; - chip->PGRAPH[0x00000F50/4] = 0x00007800; + NV_WR32(chip->PGRAPH, 0x00000F54, 0x00000000); + NV_WR32(chip->PGRAPH, 0x00000F50, 0x00007800); for (i = 0; i < (12*4); i++) - chip->PGRAPH[0x00000F54/4] = 0x00000000; - chip->PGRAPH[0x00000F50/4] = 0x00004400; + NV_WR32(chip->PGRAPH, 0x00000F54, 0x00000000); + NV_WR32(chip->PGRAPH, 0x00000F50, 0x00004400); for (i = 0; i < (8*4); i++) - chip->PGRAPH[0x00000F54/4] = 0x00000000; - chip->PGRAPH[0x00000F50/4] = 0x00000000; + NV_WR32(chip->PGRAPH, 0x00000F54, 0x00000000); + NV_WR32(chip->PGRAPH, 0x00000F50, 0x00000000); for (i = 0; i < 16; i++) - chip->PGRAPH[0x00000F54/4] = 0x00000000; - chip->PGRAPH[0x00000F50/4] = 0x00000040; + NV_WR32(chip->PGRAPH, 0x00000F54, 0x00000000); + NV_WR32(chip->PGRAPH, 0x00000F50, 0x00000040); for (i = 0; i < 4; i++) - chip->PGRAPH[0x00000F54/4] = 0x00000000; + NV_WR32(chip->PGRAPH, 0x00000F54, 0x00000000); - chip->PCRTC[0x00000810/4] = state->cursorConfig; + NV_WR32(chip->PCRTC, 0x00000810, state->cursorConfig); if(chip->flatPanel) { if((chip->Chipset & 0x0ff0) == 0x0110) { - chip->PRAMDAC[0x0528/4] = state->dither; + NV_WR32(chip->PRAMDAC, 0x0528, state->dither); } else if((chip->Chipset & 0x0ff0) >= 0x0170) { - chip->PRAMDAC[0x083C/4] = state->dither; + NV_WR32(chip->PRAMDAC, 0x083C, state->dither); } VGA_WR08(chip->PCIO, 0x03D4, 0x53); @@ -1668,24 +1706,24 @@ static void LoadStateExt VGA_WR08(chip->PCIO, 0x03D5, state->interlace); if(!chip->flatPanel) { - chip->PRAMDAC0[0x00000508/4] = state->vpll; - chip->PRAMDAC0[0x0000050C/4] = state->pllsel; + NV_WR32(chip->PRAMDAC0, 0x00000508, state->vpll); + NV_WR32(chip->PRAMDAC0, 0x0000050C, state->pllsel); if(chip->twoHeads) - chip->PRAMDAC0[0x00000520/4] = state->vpll2; + NV_WR32(chip->PRAMDAC0, 0x00000520, state->vpll2); } else { - chip->PRAMDAC[0x00000848/4] = state->scale; + NV_WR32(chip->PRAMDAC, 0x00000848 , state->scale); } - chip->PRAMDAC[0x00000600/4] = state->general; + NV_WR32(chip->PRAMDAC, 0x00000600 , state->general); /* * Turn off VBlank enable and reset. */ - chip->PCRTC[0x00000140/4] = 0; - chip->PCRTC[0x00000100/4] = chip->VBlankBit; + NV_WR32(chip->PCRTC, 0x00000140, 0); + NV_WR32(chip->PCRTC, 0x00000100, chip->VBlankBit); /* * Set interrupt enable. */ - chip->PMC[0x00000140/4] = chip->EnableIRQ & 0x01; + NV_WR32(chip->PMC, 0x00000140, chip->EnableIRQ & 0x01); /* * Set current state pointer. */ @@ -1695,7 +1733,7 @@ static void LoadStateExt */ chip->FifoFreeCount = 0; /* Free count from first subchannel */ - chip->FifoEmptyCount = chip->Rop->FifoFree; + chip->FifoEmptyCount = NV_RD32(&chip->Rop->FifoFree, 0); } static void UnloadStateExt ( @@ -1728,60 +1766,60 @@ static void UnloadStateExt state->cursor2 = VGA_RD08(chip->PCIO, 0x03D5); VGA_WR08(chip->PCIO, 0x03D4, 0x39); state->interlace = VGA_RD08(chip->PCIO, 0x03D5); - state->vpll = chip->PRAMDAC0[0x00000508/4]; - state->vpll2 = chip->PRAMDAC0[0x00000520/4]; - state->pllsel = chip->PRAMDAC0[0x0000050C/4]; - state->general = chip->PRAMDAC[0x00000600/4]; - state->scale = chip->PRAMDAC[0x00000848/4]; - state->config = chip->PFB[0x00000200/4]; + state->vpll = NV_RD32(chip->PRAMDAC0, 0x00000508); + state->vpll2 = NV_RD32(chip->PRAMDAC0, 0x00000520); + state->pllsel = NV_RD32(chip->PRAMDAC0, 0x0000050C); + state->general = NV_RD32(chip->PRAMDAC, 0x00000600); + state->scale = NV_RD32(chip->PRAMDAC, 0x00000848); + state->config = NV_RD32(chip->PFB, 0x00000200); switch (chip->Architecture) { case NV_ARCH_03: - state->offset0 = chip->PGRAPH[0x00000630/4]; - state->offset1 = chip->PGRAPH[0x00000634/4]; - state->offset2 = chip->PGRAPH[0x00000638/4]; - state->offset3 = chip->PGRAPH[0x0000063C/4]; - state->pitch0 = chip->PGRAPH[0x00000650/4]; - state->pitch1 = chip->PGRAPH[0x00000654/4]; - state->pitch2 = chip->PGRAPH[0x00000658/4]; - state->pitch3 = chip->PGRAPH[0x0000065C/4]; + state->offset0 = NV_RD32(chip->PGRAPH, 0x00000630); + state->offset1 = NV_RD32(chip->PGRAPH, 0x00000634); + state->offset2 = NV_RD32(chip->PGRAPH, 0x00000638); + state->offset3 = NV_RD32(chip->PGRAPH, 0x0000063C); + state->pitch0 = NV_RD32(chip->PGRAPH, 0x00000650); + state->pitch1 = NV_RD32(chip->PGRAPH, 0x00000654); + state->pitch2 = NV_RD32(chip->PGRAPH, 0x00000658); + state->pitch3 = NV_RD32(chip->PGRAPH, 0x0000065C); break; case NV_ARCH_04: - state->offset0 = chip->PGRAPH[0x00000640/4]; - state->offset1 = chip->PGRAPH[0x00000644/4]; - state->offset2 = chip->PGRAPH[0x00000648/4]; - state->offset3 = chip->PGRAPH[0x0000064C/4]; - state->pitch0 = chip->PGRAPH[0x00000670/4]; - state->pitch1 = chip->PGRAPH[0x00000674/4]; - state->pitch2 = chip->PGRAPH[0x00000678/4]; - state->pitch3 = chip->PGRAPH[0x0000067C/4]; + state->offset0 = NV_RD32(chip->PGRAPH, 0x00000640); + state->offset1 = NV_RD32(chip->PGRAPH, 0x00000644); + state->offset2 = NV_RD32(chip->PGRAPH, 0x00000648); + state->offset3 = NV_RD32(chip->PGRAPH, 0x0000064C); + state->pitch0 = NV_RD32(chip->PGRAPH, 0x00000670); + state->pitch1 = NV_RD32(chip->PGRAPH, 0x00000674); + state->pitch2 = NV_RD32(chip->PGRAPH, 0x00000678); + state->pitch3 = NV_RD32(chip->PGRAPH, 0x0000067C); break; case NV_ARCH_10: case NV_ARCH_20: case NV_ARCH_30: - state->offset0 = chip->PGRAPH[0x00000640/4]; - state->offset1 = chip->PGRAPH[0x00000644/4]; - state->offset2 = chip->PGRAPH[0x00000648/4]; - state->offset3 = chip->PGRAPH[0x0000064C/4]; - state->pitch0 = chip->PGRAPH[0x00000670/4]; - state->pitch1 = chip->PGRAPH[0x00000674/4]; - state->pitch2 = chip->PGRAPH[0x00000678/4]; - state->pitch3 = chip->PGRAPH[0x0000067C/4]; + state->offset0 = NV_RD32(chip->PGRAPH, 0x00000640); + state->offset1 = NV_RD32(chip->PGRAPH, 0x00000644); + state->offset2 = NV_RD32(chip->PGRAPH, 0x00000648); + state->offset3 = NV_RD32(chip->PGRAPH, 0x0000064C); + state->pitch0 = NV_RD32(chip->PGRAPH, 0x00000670); + state->pitch1 = NV_RD32(chip->PGRAPH, 0x00000674); + state->pitch2 = NV_RD32(chip->PGRAPH, 0x00000678); + state->pitch3 = NV_RD32(chip->PGRAPH, 0x0000067C); if(chip->twoHeads) { - state->head = chip->PCRTC0[0x00000860/4]; - state->head2 = chip->PCRTC0[0x00002860/4]; + state->head = NV_RD32(chip->PCRTC0, 0x00000860); + state->head2 = NV_RD32(chip->PCRTC0, 0x00002860); VGA_WR08(chip->PCIO, 0x03D4, 0x44); state->crtcOwner = VGA_RD08(chip->PCIO, 0x03D5); } VGA_WR08(chip->PCIO, 0x03D4, 0x41); state->extra = VGA_RD08(chip->PCIO, 0x03D5); - state->cursorConfig = chip->PCRTC[0x00000810/4]; + state->cursorConfig = NV_RD32(chip->PCRTC, 0x00000810); if((chip->Chipset & 0x0ff0) == 0x0110) { - state->dither = chip->PRAMDAC[0x0528/4]; + state->dither = NV_RD32(chip->PRAMDAC, 0x0528); } else if((chip->Chipset & 0x0ff0) >= 0x0170) { - state->dither = chip->PRAMDAC[0x083C/4]; + state->dither = NV_RD32(chip->PRAMDAC, 0x083C); } break; } @@ -1792,7 +1830,7 @@ static void SetStartAddress unsigned start ) { - chip->PCRTC[0x800/4] = start; + NV_WR32(chip->PCRTC, 0x800, start); } static void SetStartAddress3 @@ -1834,14 +1872,15 @@ static void nv3SetSurfaces2D unsigned surf1 ) { - RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]); + RivaSurface __iomem *Surface = + (RivaSurface __iomem *)&(chip->FIFO[0x0000E000/4]); RIVA_FIFO_FREE(*chip,Tri03,5); - chip->FIFO[0x00003800] = 0x80000003; - Surface->Offset = surf0; - chip->FIFO[0x00003800] = 0x80000004; - Surface->Offset = surf1; - chip->FIFO[0x00003800] = 0x80000013; + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000003); + NV_WR32(&Surface->Offset, 0, surf0); + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000004); + NV_WR32(&Surface->Offset, 0, surf1); + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000013); } static void nv4SetSurfaces2D ( @@ -1850,13 +1889,14 @@ static void nv4SetSurfaces2D unsigned surf1 ) { - RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]); - - chip->FIFO[0x00003800] = 0x80000003; - Surface->Offset = surf0; - chip->FIFO[0x00003800] = 0x80000004; - Surface->Offset = surf1; - chip->FIFO[0x00003800] = 0x80000014; + RivaSurface __iomem *Surface = + (RivaSurface __iomem *)&(chip->FIFO[0x0000E000/4]); + + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000003); + NV_WR32(&Surface->Offset, 0, surf0); + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000004); + NV_WR32(&Surface->Offset, 0, surf1); + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000014); } static void nv10SetSurfaces2D ( @@ -1865,13 +1905,14 @@ static void nv10SetSurfaces2D unsigned surf1 ) { - RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]); - - chip->FIFO[0x00003800] = 0x80000003; - Surface->Offset = surf0; - chip->FIFO[0x00003800] = 0x80000004; - Surface->Offset = surf1; - chip->FIFO[0x00003800] = 0x80000014; + RivaSurface __iomem *Surface = + (RivaSurface __iomem *)&(chip->FIFO[0x0000E000/4]); + + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000003); + NV_WR32(&Surface->Offset, 0, surf0); + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000004); + NV_WR32(&Surface->Offset, 0, surf1); + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000014); } static void nv3SetSurfaces3D ( @@ -1880,14 +1921,15 @@ static void nv3SetSurfaces3D unsigned surf1 ) { - RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]); + RivaSurface __iomem *Surface = + (RivaSurface __iomem *)&(chip->FIFO[0x0000E000/4]); RIVA_FIFO_FREE(*chip,Tri03,5); - chip->FIFO[0x00003800] = 0x80000005; - Surface->Offset = surf0; - chip->FIFO[0x00003800] = 0x80000006; - Surface->Offset = surf1; - chip->FIFO[0x00003800] = 0x80000013; + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000005); + NV_WR32(&Surface->Offset, 0, surf0); + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000006); + NV_WR32(&Surface->Offset, 0, surf1); + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000013); } static void nv4SetSurfaces3D ( @@ -1896,13 +1938,14 @@ static void nv4SetSurfaces3D unsigned surf1 ) { - RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]); - - chip->FIFO[0x00003800] = 0x80000005; - Surface->Offset = surf0; - chip->FIFO[0x00003800] = 0x80000006; - Surface->Offset = surf1; - chip->FIFO[0x00003800] = 0x80000014; + RivaSurface __iomem *Surface = + (RivaSurface __iomem *)&(chip->FIFO[0x0000E000/4]); + + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000005); + NV_WR32(&Surface->Offset, 0, surf0); + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000006); + NV_WR32(&Surface->Offset, 0, surf1); + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000014); } static void nv10SetSurfaces3D ( @@ -1911,13 +1954,14 @@ static void nv10SetSurfaces3D unsigned surf1 ) { - RivaSurface3D *Surfaces3D = (RivaSurface3D *)&(chip->FIFO[0x0000E000/4]); + RivaSurface3D __iomem *Surfaces3D = + (RivaSurface3D __iomem *)&(chip->FIFO[0x0000E000/4]); RIVA_FIFO_FREE(*chip,Tri03,4); - chip->FIFO[0x00003800] = 0x80000007; - Surfaces3D->RenderBufferOffset = surf0; - Surfaces3D->ZBufferOffset = surf1; - chip->FIFO[0x00003800] = 0x80000014; + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000007); + NV_WR32(&Surfaces3D->RenderBufferOffset, 0, surf0); + NV_WR32(&Surfaces3D->ZBufferOffset, 0, surf1); + NV_WR32(&chip->FIFO[0x00003800], 0, 0x80000014); } /****************************************************************************\ @@ -1934,16 +1978,16 @@ static void nv3GetConfig /* * Fill in chip configuration. */ - if (chip->PFB[0x00000000/4] & 0x00000020) + if (NV_RD32(&chip->PFB[0x00000000/4], 0) & 0x00000020) { - if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20) - && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02)) + if (((NV_RD32(chip->PMC, 0x00000000) & 0xF0) == 0x20) + && ((NV_RD32(chip->PMC, 0x00000000) & 0x0F) >= 0x02)) { /* * SDRAM 128 ZX. */ chip->RamBandwidthKBytesPerSec = 800000; - switch (chip->PFB[0x00000000/4] & 0x03) + switch (NV_RD32(chip->PFB, 0x00000000) & 0x03) { case 2: chip->RamAmountKBytes = 1024 * 4; @@ -1968,7 +2012,7 @@ static void nv3GetConfig * SGRAM 128. */ chip->RamBandwidthKBytesPerSec = 1000000; - switch (chip->PFB[0x00000000/4] & 0x00000003) + switch (NV_RD32(chip->PFB, 0x00000000) & 0x00000003) { case 0: chip->RamAmountKBytes = 1024 * 8; @@ -1981,7 +2025,7 @@ static void nv3GetConfig break; } } - chip->CrystalFreqKHz = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500; + chip->CrystalFreqKHz = (NV_RD32(chip->PEXTDEV, 0x00000000) & 0x00000040) ? 14318 : 13500; chip->CURSOR = &(chip->PRAMIN[0x00008000/4 - 0x0800/4]); chip->VBlankBit = 0x00000100; chip->MaxVClockFreqKHz = 256000; @@ -2006,14 +2050,14 @@ static void nv4GetConfig /* * Fill in chip configuration. */ - if (chip->PFB[0x00000000/4] & 0x00000100) + if (NV_RD32(chip->PFB, 0x00000000) & 0x00000100) { - chip->RamAmountKBytes = ((chip->PFB[0x00000000/4] >> 12) & 0x0F) * 1024 * 2 + chip->RamAmountKBytes = ((NV_RD32(chip->PFB, 0x00000000) >> 12) & 0x0F) * 1024 * 2 + 1024 * 2; } else { - switch (chip->PFB[0x00000000/4] & 0x00000003) + switch (NV_RD32(chip->PFB, 0x00000000) & 0x00000003) { case 0: chip->RamAmountKBytes = 1024 * 32; @@ -2030,7 +2074,7 @@ static void nv4GetConfig break; } } - switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003) + switch ((NV_RD32(chip->PFB, 0x00000000) >> 3) & 0x00000003) { case 3: chip->RamBandwidthKBytesPerSec = 800000; @@ -2039,7 +2083,7 @@ static void nv4GetConfig chip->RamBandwidthKBytesPerSec = 1000000; break; } - chip->CrystalFreqKHz = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500; + chip->CrystalFreqKHz = (NV_RD32(chip->PEXTDEV, 0x00000000) & 0x00000040) ? 14318 : 13500; chip->CURSOR = &(chip->PRAMIN[0x00010000/4 - 0x0800/4]); chip->VBlankBit = 0x00000001; chip->MaxVClockFreqKHz = 350000; @@ -2067,8 +2111,8 @@ static void nv10GetConfig #ifdef __BIG_ENDIAN /* turn on big endian register access */ - if(!(chip->PMC[0x00000004/4] & 0x01000001)) - chip->PMC[0x00000004/4] = 0x01000001; + if(!(NV_RD32(chip->PMC, 0x00000004) & 0x01000001)) + NV_WR32(chip->PMC, 0x00000004, 0x01000001); #endif /* @@ -2083,7 +2127,7 @@ static void nv10GetConfig pci_read_config_dword(dev, 0x84, &amt); chip->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024; } else { - switch ((chip->PFB[0x0000020C/4] >> 20) & 0x000000FF) + switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) & 0x000000FF) { case 0x02: chip->RamAmountKBytes = 1024 * 2; @@ -2111,7 +2155,7 @@ static void nv10GetConfig break; } } - switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003) + switch ((NV_RD32(chip->PFB, 0x00000000) >> 3) & 0x00000003) { case 3: chip->RamBandwidthKBytesPerSec = 800000; @@ -2120,8 +2164,8 @@ static void nv10GetConfig chip->RamBandwidthKBytesPerSec = 1000000; break; } - chip->CrystalFreqKHz = (chip->PEXTDEV[0x0000/4] & (1 << 6)) ? 14318 : - 13500; + chip->CrystalFreqKHz = (NV_RD32(chip->PEXTDEV, 0x0000) & (1 << 6)) ? + 14318 : 13500; switch (chipset & 0x0ff0) { case 0x0170: @@ -2134,7 +2178,7 @@ static void nv10GetConfig case 0x0320: case 0x0330: case 0x0340: - if(chip->PEXTDEV[0x0000/4] & (1 << 22)) + if(NV_RD32(chip->PEXTDEV, 0x0000) & (1 << 22)) chip->CrystalFreqKHz = 27000; break; default: @@ -2210,14 +2254,14 @@ int RivaGetConfig /* * Fill in FIFO pointers. */ - chip->Rop = (RivaRop *)&(chip->FIFO[0x00000000/4]); - chip->Clip = (RivaClip *)&(chip->FIFO[0x00002000/4]); - chip->Patt = (RivaPattern *)&(chip->FIFO[0x00004000/4]); - chip->Pixmap = (RivaPixmap *)&(chip->FIFO[0x00006000/4]); - chip->Blt = (RivaScreenBlt *)&(chip->FIFO[0x00008000/4]); - chip->Bitmap = (RivaBitmap *)&(chip->FIFO[0x0000A000/4]); - chip->Line = (RivaLine *)&(chip->FIFO[0x0000C000/4]); - chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]); + chip->Rop = (RivaRop __iomem *)&(chip->FIFO[0x00000000/4]); + chip->Clip = (RivaClip __iomem *)&(chip->FIFO[0x00002000/4]); + chip->Patt = (RivaPattern __iomem *)&(chip->FIFO[0x00004000/4]); + chip->Pixmap = (RivaPixmap __iomem *)&(chip->FIFO[0x00006000/4]); + chip->Blt = (RivaScreenBlt __iomem *)&(chip->FIFO[0x00008000/4]); + chip->Bitmap = (RivaBitmap __iomem *)&(chip->FIFO[0x0000A000/4]); + chip->Line = (RivaLine __iomem *)&(chip->FIFO[0x0000C000/4]); + chip->Tri03 = (RivaTexturedTriangle03 __iomem *)&(chip->FIFO[0x0000E000/4]); return (0); } diff --git a/drivers/video/riva/riva_hw.h b/drivers/video/riva/riva_hw.h index 35cc506b0920..2fd8d139fc4d 100644 --- a/drivers/video/riva/riva_hw.h +++ b/drivers/video/riva/riva_hw.h @@ -78,13 +78,13 @@ typedef unsigned int U032; #define NV_WR08(p,i,d) out_8(p+i, d) #define NV_RD08(p,i) in_8(p+i) #else -#define NV_WR08(p,i,d) (((U008 *)(p))[i]=(d)) -#define NV_RD08(p,i) (((U008 *)(p))[i]) +#define NV_WR08(p,i,d) (writeb((d), (u8 __iomem *)(p) + (i))) +#define NV_RD08(p,i) (readb((u8 __iomem *)(p) + (i))) #endif -#define NV_WR16(p,i,d) (((U016 *)(p))[(i)/2]=(d)) -#define NV_RD16(p,i) (((U016 *)(p))[(i)/2]) -#define NV_WR32(p,i,d) (((U032 *)(p))[(i)/4]=(d)) -#define NV_RD32(p,i) (((U032 *)(p))[(i)/4]) +#define NV_WR16(p,i,d) (writew((d), (u16 __iomem *)(p) + (i)/2)) +#define NV_RD16(p,i) (readw((u16 __iomem *)(p) + (i)/2)) +#define NV_WR32(p,i,d) (writel((d), (u32 __iomem *)(p) + (i)/4)) +#define NV_RD32(p,i) (readl((u32 __iomem *)(p) + (i)/4)) #define VGA_WR08(p,i,d) NV_WR08(p,i,d) #define VGA_RD08(p,i) NV_RD08(p,i) @@ -444,24 +444,24 @@ typedef struct _riva_hw_inst /* * Non-FIFO registers. */ - volatile U032 *PCRTC0; - volatile U032 *PCRTC; - volatile U032 *PRAMDAC0; - volatile U032 *PFB; - volatile U032 *PFIFO; - volatile U032 *PGRAPH; - volatile U032 *PEXTDEV; - volatile U032 *PTIMER; - volatile U032 *PMC; - volatile U032 *PRAMIN; - volatile U032 *FIFO; - volatile U032 *CURSOR; - volatile U008 *PCIO0; - volatile U008 *PCIO; - volatile U008 *PVIO; - volatile U008 *PDIO0; - volatile U008 *PDIO; - volatile U032 *PRAMDAC; + volatile U032 __iomem *PCRTC0; + volatile U032 __iomem *PCRTC; + volatile U032 __iomem *PRAMDAC0; + volatile U032 __iomem *PFB; + volatile U032 __iomem *PFIFO; + volatile U032 __iomem *PGRAPH; + volatile U032 __iomem *PEXTDEV; + volatile U032 __iomem *PTIMER; + volatile U032 __iomem *PMC; + volatile U032 __iomem *PRAMIN; + volatile U032 __iomem *FIFO; + volatile U032 __iomem *CURSOR; + volatile U008 __iomem *PCIO0; + volatile U008 __iomem *PCIO; + volatile U008 __iomem *PVIO; + volatile U008 __iomem *PDIO0; + volatile U008 __iomem *PDIO; + volatile U032 __iomem *PRAMDAC; /* * Common chip functions. */ @@ -481,15 +481,15 @@ typedef struct _riva_hw_inst /* * FIFO registers. */ - RivaRop *Rop; - RivaPattern *Patt; - RivaClip *Clip; - RivaPixmap *Pixmap; - RivaScreenBlt *Blt; - RivaBitmap *Bitmap; - RivaLine *Line; - RivaTexturedTriangle03 *Tri03; - RivaTexturedTriangle05 *Tri05; + RivaRop __iomem *Rop; + RivaPattern __iomem *Patt; + RivaClip __iomem *Clip; + RivaPixmap __iomem *Pixmap; + RivaScreenBlt __iomem *Blt; + RivaBitmap __iomem *Bitmap; + RivaLine __iomem *Line; + RivaTexturedTriangle03 __iomem *Tri03; + RivaTexturedTriangle05 __iomem *Tri05; } RIVA_HW_INST; /* * Extended mode state information. @@ -543,7 +543,7 @@ int RivaGetConfig(RIVA_HW_INST *, unsigned int); { \ while ((hwinst).FifoFreeCount < (cnt)) { \ mb();mb(); \ - (hwinst).FifoFreeCount = (hwinst).hwptr->FifoFree >> 2; \ + (hwinst).FifoFreeCount = NV_RD32(&(hwinst).hwptr->FifoFree, 0) >> 2; \ } \ (hwinst).FifoFreeCount -= (cnt); \ } diff --git a/drivers/video/riva/rivafb.h b/drivers/video/riva/rivafb.h index 5e4fde5ac3b1..440ff445689b 100644 --- a/drivers/video/riva/rivafb.h +++ b/drivers/video/riva/rivafb.h @@ -46,7 +46,7 @@ struct riva_par { RIVA_HW_INST riva; /* interface to riva_hw.c */ u32 pseudo_palette[16]; /* default palette */ u32 palette[16]; /* for Riva128 */ - caddr_t ctrl_base; /* virtual control register base addr */ + u8 __iomem *ctrl_base; /* virtual control register base addr */ unsigned dclk_max; /* max DCLK */ struct riva_regs initial_state; /* initial startup video mode */ diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index b2c7aa10449a..7c4ae200e110 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c @@ -1673,7 +1673,6 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev) fbi->fb.fbops = &sa1100fb_ops; fbi->fb.flags = FBINFO_DEFAULT; fbi->fb.monspecs = monspecs; - fbi->fb.currcon = -1; fbi->fb.pseudo_palette = (fbi + 1); fbi->rgb[RGB_8] = &rgb_8; diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 72afe0838937..1ece9b6b4b85 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c @@ -1813,8 +1813,11 @@ sisfb_set_par(struct fb_info *info) return err; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) sisfb_get_fix(&info->fix, info->currcon, info); - +#else + sisfb_get_fix(&info->fix, -1, info); +#endif return 0; } diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index 0e915d7ea3f7..52686d849926 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c @@ -1471,7 +1471,6 @@ static int __devinit sstfb_probe(struct pci_dev *pdev, info->flags = FBINFO_DEFAULT; info->fbops = &sstfb_ops; - info->currcon = -1; info->pseudo_palette = &all->pseudo_palette; fix->type = FB_TYPE_PACKED_PIXELS; diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index d64d6a6bf6ff..8b76a919297e 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -1335,7 +1335,6 @@ stifb_init_fb(struct sti_struct *sti, int force_bpp) info->fbops = &stifb_ops; info->screen_base = (void*) REGION_BASE(fb,1); info->flags = FBINFO_DEFAULT; - info->currcon = -1; info->pseudo_palette = &fb->pseudo_palette; /* This has to been done !!! */ diff --git a/drivers/video/tcx.c b/drivers/video/tcx.c index e3e43ca2f6fe..de628c72e7d6 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/tcx.c @@ -422,7 +422,6 @@ static void tcx_init_one(struct sbus_dev *sdev) all->info.screen_base = (char *) sbus_ioremap(&sdev->resource[0], 0, all->par.fbsize, "tcx ram"); - all->info.currcon = -1; all->info.par = &all->par; /* Initialize brooktree DAC. */ diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c index ffe811038a9a..b38c09c8b444 100644 --- a/drivers/video/tgafb.c +++ b/drivers/video/tgafb.c @@ -1430,7 +1430,6 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) FBINFO_HWACCEL_IMAGEBLIT | FBINFO_HWACCEL_FILLRECT; all->info.fbops = &tgafb_ops; all->info.screen_base = (char *) all->par.tga_fb_base; - all->info.currcon = -1; all->info.par = &all->par; all->info.pseudo_palette = all->pseudo_palette; diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c index f2b053c0f214..6c15be9ea39b 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/vga16fb.c @@ -859,7 +859,6 @@ static int vga16fb_blank(int blank, struct fb_info *info) par->vesa_blanked = 0; } if (par->palette_blanked) { - //do_install_cmap(info->currcon, info); par->palette_blanked = 0; } break; diff --git a/fs/Kconfig b/fs/Kconfig index 1b2b74d45b17..88e92f15445c 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -819,8 +819,8 @@ config PROC_FS programs depend on this, so everyone should say Y here. config PROC_KCORE - bool - default y if !ARM + bool "/proc/kcore support" if !ARM + depends on PROC_FS config SYSFS bool "sysfs file system support" if EMBEDDED @@ -118,8 +118,6 @@ static int aio_setup_ring(struct kioctx *ctx) if (nr_pages < 0) return -EINVAL; - info->nr_pages = nr_pages; - nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event); info->nr = 0; diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index d5d03d0407d0..cf8c035180e1 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -96,6 +96,7 @@ #include <asm/module.h> #include <linux/soundcard.h> #include <linux/lp.h> +#include <linux/ppdev.h> #include <linux/atm.h> #include <linux/atmarp.h> diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 661a751d15f0..4c616671ce73 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -2,7 +2,8 @@ * linux/fs/ext2/namei.c * * Rewrite to pagecache. Almost all code had been changed, so blame me - * if the things go wrong. Please, send bug reports to viro@math.psu.edu + * if the things go wrong. Please, send bug reports to + * viro@parcelfarce.linux.theplanet.co.uk * * Stuff here is basically a glue between the VFS and generic UNIXish * filesystem that keeps everything in pagecache. All knowledge of the diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index b2bb90817371..2e2af5cba1ce 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c @@ -418,7 +418,7 @@ static int call_filldir(struct file * filp, void * dirent, get_dtype(sb, fname->file_type)); if (error) { filp->f_pos = curr_pos; - info->extra_fname = fname->next; + info->extra_fname = fname; return error; } fname = fname->next; @@ -457,9 +457,12 @@ static int ext3_dx_readdir(struct file * filp, * If there are any leftover names on the hash collision * chain, return them first. */ - if (info->extra_fname && - call_filldir(filp, dirent, filldir, info->extra_fname)) - goto finished; + if (info->extra_fname) { + if(call_filldir(filp, dirent, filldir, info->extra_fname)) + goto finished; + else + goto next_entry; + } if (!info->curr_node) info->curr_node = rb_first(&info->root); @@ -492,7 +495,7 @@ static int ext3_dx_readdir(struct file * filp, info->curr_minor_hash = fname->minor_hash; if (call_filldir(filp, dirent, filldir, fname)) break; - +next_entry: info->curr_node = rb_next(info->curr_node); if (!info->curr_node) { if (info->next_hash == ~0) { diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index 2615ad1d86ed..85c874177f05 100644 --- a/fs/jbd/checkpoint.c +++ b/fs/jbd/checkpoint.c @@ -616,7 +616,6 @@ void __journal_drop_transaction(journal_t *journal, transaction_t *transaction) J_ASSERT(transaction->t_log_list == NULL); J_ASSERT(transaction->t_checkpoint_list == NULL); J_ASSERT(transaction->t_updates == 0); - J_ASSERT(list_empty(&transaction->t_jcb)); J_ASSERT(journal->j_committing_transaction != transaction); J_ASSERT(journal->j_running_transaction != transaction); diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index b4d6654ef7f2..875e06ba9aba 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c @@ -686,30 +686,6 @@ skip_commit: /* The journal should be unlocked by now. */ if (err) __journal_abort_hard(journal); - /* - * Call any callbacks that had been registered for handles in this - * transaction. It is up to the callback to free any allocated - * memory. - * - * The spinlocking (t_jcb_lock) here is surely unnecessary... - */ - spin_lock(&commit_transaction->t_jcb_lock); - if (!list_empty(&commit_transaction->t_jcb)) { - struct list_head *p, *n; - int error = is_journal_aborted(journal); - - list_for_each_safe(p, n, &commit_transaction->t_jcb) { - struct journal_callback *jcb; - - jcb = list_entry(p, struct journal_callback, jcb_list); - list_del(p); - spin_unlock(&commit_transaction->t_jcb_lock); - jcb->jcb_func(jcb, error); - spin_lock(&commit_transaction->t_jcb_lock); - } - } - spin_unlock(&commit_transaction->t_jcb_lock); - jbd_debug(3, "JBD: commit phase 7\n"); J_ASSERT(commit_transaction->t_sync_datalist == NULL); diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index cb9d794cc588..66ef3f81d7fc 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c @@ -55,7 +55,6 @@ EXPORT_SYMBOL(journal_sync_buffer); #endif EXPORT_SYMBOL(journal_flush); EXPORT_SYMBOL(journal_revoke); -EXPORT_SYMBOL(journal_callback_set); EXPORT_SYMBOL(journal_init_dev); EXPORT_SYMBOL(journal_init_inode); @@ -79,7 +78,6 @@ EXPORT_SYMBOL(journal_wipe); EXPORT_SYMBOL(journal_blocks_per_page); EXPORT_SYMBOL(journal_invalidatepage); EXPORT_SYMBOL(journal_try_to_free_buffers); -EXPORT_SYMBOL(journal_bmap); EXPORT_SYMBOL(journal_force_commit); static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index a168757d26af..eba3a475ee4b 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c @@ -50,9 +50,7 @@ get_transaction(journal_t *journal, transaction_t *transaction) transaction->t_state = T_RUNNING; transaction->t_tid = journal->j_transaction_sequence++; transaction->t_expires = jiffies + journal->j_commit_interval; - INIT_LIST_HEAD(&transaction->t_jcb); spin_lock_init(&transaction->t_handle_lock); - spin_lock_init(&transaction->t_jcb_lock); /* Set up the commit timer for the new transaction. */ journal->j_commit_timer->expires = transaction->t_expires; @@ -243,7 +241,6 @@ static handle_t *new_handle(int nblocks) memset(handle, 0, sizeof(*handle)); handle->h_buffer_credits = nblocks; handle->h_ref = 1; - INIT_LIST_HEAD(&handle->h_jcb); return handle; } @@ -1277,36 +1274,6 @@ not_jbd: } /** - * void journal_callback_set() - Register a callback function for this handle. - * @handle: handle to attach the callback to. - * @func: function to callback. - * @jcb: structure with additional information required by func() , and - * some space for jbd internal information. - * - * The function will be - * called when the transaction that this handle is part of has been - * committed to disk with the original callback data struct and the - * error status of the journal as parameters. There is no guarantee of - * ordering between handles within a single transaction, nor between - * callbacks registered on the same handle. - * - * The caller is responsible for allocating the journal_callback struct. - * This is to allow the caller to add as much extra data to the callback - * as needed, but reduce the overhead of multiple allocations. The caller - * allocated struct must start with a struct journal_callback at offset 0, - * and has the caller-specific data afterwards. - */ -void journal_callback_set(handle_t *handle, - void (*func)(struct journal_callback *jcb, int error), - struct journal_callback *jcb) -{ - spin_lock(&handle->h_transaction->t_jcb_lock); - list_add_tail(&jcb->jcb_list, &handle->h_jcb); - spin_unlock(&handle->h_transaction->t_jcb_lock); - jcb->jcb_func = func; -} - -/** * int journal_stop() - complete a transaction * @handle: tranaction to complete. * @@ -1372,11 +1339,6 @@ int journal_stop(handle_t *handle) wake_up(&journal->j_wait_transaction_locked); } - /* Move callbacks from the handle to the transaction. */ - spin_lock(&transaction->t_jcb_lock); - list_splice(&handle->h_jcb, &transaction->t_jcb); - spin_unlock(&transaction->t_jcb_lock); - /* * If the handle is marked SYNC, we need to set another commit * going! We also want to force a commit if the current diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index 4a4a74326959..36bc60288b75 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c @@ -160,7 +160,8 @@ minix_V2_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh) static void minix_clear_inode(struct inode *inode) { - struct buffer_head *bh; + struct buffer_head *bh = NULL; + if (INODE_VERSION(inode) == MINIX_V1) { struct minix_inode *raw_inode; raw_inode = minix_V1_raw_inode(inode->i_sb, inode->i_ino, &bh); @@ -188,24 +189,26 @@ void minix_free_inode(struct inode * inode) struct buffer_head * bh; unsigned long ino; - if (inode->i_ino < 1 || inode->i_ino > sbi->s_ninodes) { - printk("free_inode: inode 0 or nonexistent inode\n"); - return; - } ino = inode->i_ino; + if (ino < 1 || ino > sbi->s_ninodes) { + printk("minix_free_inode: inode 0 or nonexistent inode\n"); + goto out; + } if ((ino >> 13) >= sbi->s_imap_blocks) { - printk("free_inode: nonexistent imap in superblock\n"); - return; + printk("minix_free_inode: nonexistent imap in superblock\n"); + goto out; } + minix_clear_inode(inode); /* clear on-disk copy */ + bh = sbi->s_imap[ino >> 13]; - minix_clear_inode(inode); - clear_inode(inode); lock_kernel(); if (!minix_test_and_clear_bit(ino & 8191, bh->b_data)) - printk("free_inode: bit %lu already cleared.\n",ino); + printk("minix_free_inode: bit %lu already cleared.\n", ino); unlock_kernel(); mark_buffer_dirty(bh); + out: + clear_inode(inode); /* clear in-memory copy */ } struct inode * minix_new_inode(const struct inode * dir, int * error) diff --git a/fs/namespace.c b/fs/namespace.c index b09b08807f2c..140530d09e78 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -106,8 +106,6 @@ struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry) return found; } -EXPORT_SYMBOL(lookup_mnt); - static inline int check_mnt(struct vfsmount *mnt) { return mnt->mnt_namespace == current->namespace; diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig index 7d74b006796a..682cbecb4e6f 100644 --- a/fs/partitions/Kconfig +++ b/fs/partitions/Kconfig @@ -219,7 +219,7 @@ config SUN_PARTITION config EFI_PARTITION bool "EFI GUID Partition support" - depends on PARTITION_ADVANCED + depends on PARTITION_ADVANCED && IA64 select CRC32 help Say Y here if you would like to use hard disks under Linux which diff --git a/fs/sysv/CHANGES b/fs/sysv/CHANGES index 3cbcd7b9da18..66ea6e92be66 100644 --- a/fs/sysv/CHANGES +++ b/fs/sysv/CHANGES @@ -19,7 +19,7 @@ Wed, 4 Feb 1998 Krzysztof G. Baranowski <kgb@manjak.knm.org.pl> * namei.c: removed static subdir(); is_subdir() from dcache.c is used instead. Cosmetic changes. -Thu, 3 Dec 1998 Al Viro (viro@math.psu.edu) +Thu, 3 Dec 1998 Al Viro (viro@parcelfarce.linux.theplanet.co.uk) * namei.c (sysv_rmdir): Bugectomy: old check for victim being busy (inode->i_count) wasn't replaced (with checking diff --git a/fs/sysv/ChangeLog b/fs/sysv/ChangeLog index 19abd51ca7a0..18e3487debdb 100644 --- a/fs/sysv/ChangeLog +++ b/fs/sysv/ChangeLog @@ -4,7 +4,7 @@ Thu Feb 14 2002 Andrew Morton <akpm@zip.com.au> waitfor_one_page() for IS_SYNC directories, so that we actually do sync the directory. (forward-port from 2.4). -Thu Feb 7 2002 Alexander Viro <viro@math.psu.edu> +Thu Feb 7 2002 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> * super.c: switched to ->get_sb() * ChangeLog: fixed dates ;-) @@ -13,7 +13,7 @@ Thu Feb 7 2002 Alexander Viro <viro@math.psu.edu> * inode.c: Include linux/init.h -Mon Jan 21 2002 Alexander Viro <viro@math.psu.edu> +Mon Jan 21 2002 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> * ialloc.c (sysv_new_inode): zero SYSV_I(inode)->i_data out. * i_vnode renamed to vfs_inode. Sorry, but let's keep that consistent. @@ -43,7 +43,7 @@ Sat Jan 19 2002 Christoph Hellwig <hch@infradead.org> * symlink.c (sysv_readlink): Likewise. (sysv_follow_link): Likewise. -Fri Jan 4 2002 Alexander Viro <viro@math.psu.edu> +Fri Jan 4 2002 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> * ialloc.c (sysv_free_inode): Use sb->s_id instead of bdevname(). * inode.c (sysv_read_inode): Likewise. @@ -59,16 +59,16 @@ Sun Dec 30 2001 Manfred Spraul <manfreds@colorfullife.com> * dir.c (dir_commit_chunk): Do not set dir->i_version. (sysv_readdir): Likewise. -Thu Dec 27 2001 Alexander Viro <viro@math.psu.edu> +Thu Dec 27 2001 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> * itree.c (get_block): Use map_bh() to fill out bh_result. -Tue Dec 25 2001 Alexander Viro <viro@math.psu.edu> +Tue Dec 25 2001 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> * super.c (sysv_read_super): Use sb_set_blocksize() to set blocksize. (v7_read_super): Likewise. -Tue Nov 27 2001 Alexander Viro <viro@math.psu.edu> +Tue Nov 27 2001 Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> * itree.c (get_block): Change type for iblock argument to sector_t. * super.c (sysv_read_super): Set s_blocksize early. diff --git a/include/asm-alpha/hardirq.h b/include/asm-alpha/hardirq.h index 10be402fcb26..de7e476ff7a9 100644 --- a/include/asm-alpha/hardirq.h +++ b/include/asm-alpha/hardirq.h @@ -16,29 +16,8 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-27 are the hardirq count (max # of hardirqs: 4096) - * - * - ( bit 30 is the PREEMPT_ACTIVE flag. ) - * - * PREEMPT_MASK: 0x000000ff - * SOFTIRQ_MASK: 0x0000ff00 - * HARDIRQ_MASK: 0x0fff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 12 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - /* * The hardirq mask has to be large enough to have * space for potentially nestable IRQ sources in the system diff --git a/include/asm-arm/arch-cl7500/serial.h b/include/asm-arm/arch-cl7500/serial.h deleted file mode 100644 index 1d9fbc9d616e..000000000000 --- a/include/asm-arm/arch-cl7500/serial.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * linux/include/asm-arm/arch-cl7500/serial.h - * - * Copyright (c) 1996 Russell King. - * Copyright (C) 1999 Nexus Electronics Ltd. - * - * Changelog: - * 15-10-1996 RMK Created - * 10-08-1999 PJB Added COM3/COM4 for CL7500 - */ -#ifndef __ASM_ARCH_SERIAL_H -#define __ASM_ARCH_SERIAL_H - -#include <asm/arch/hardware.h> - -/* - * This assumes you have a 1.8432 MHz clock for your UART. - * - * It'd be nice if someone built a serial card with a 24.576 MHz - * clock, since the 16550A is capable of handling a top speed of 1.5 - * megabits/second; but this requires the faster clock. - */ -#define BASE_BAUD (1843200 / 16) - -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) - - /* UART CLK PORT IRQ FLAGS */ -#define STD_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x3F8, 10, STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0x2F8, 0, STD_COM_FLAGS }, /* ttyS1 */ \ - /* ISA Slot Serial ports */ \ - { 0, BASE_BAUD, ISASLOT_IO + 0x2e8, 41, STD_COM_FLAGS }, /* ttyS2 */ \ - { 0, BASE_BAUD, ISASLOT_IO + 0x3e8, 40, STD_COM_FLAGS }, /* ttyS3 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS13 */ - -#define EXTRA_SERIAL_PORT_DEFNS - -#endif diff --git a/include/asm-arm/arch-ebsa110/serial.h b/include/asm-arm/arch-ebsa110/serial.h deleted file mode 100644 index 17aff6692501..000000000000 --- a/include/asm-arm/arch-ebsa110/serial.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/serial.h - * - * Copyright (C) 1996,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. - * - * Changelog: - * 15-10-1996 RMK Created - */ -#ifndef __ASM_ARCH_SERIAL_H -#define __ASM_ARCH_SERIAL_H - -/* - * This assumes you have a 1.8432 MHz clock for your UART. - * - * It'd be nice if someone built a serial card with a 24.576 MHz - * clock, since the 16550A is capable of handling a top speed of 1.5 - * megabits/second; but this requires the faster clock. - */ -#define BASE_BAUD (1843200 / 16) - -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) - - /* UART CLK PORT IRQ FLAGS */ -#define STD_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x3F8, 1, STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0x2F8, 2, STD_COM_FLAGS } /* ttyS1 */ - -#define EXTRA_SERIAL_PORT_DEFNS - -#endif - diff --git a/include/asm-arm/arch-ebsa285/serial.h b/include/asm-arm/arch-ebsa285/serial.h deleted file mode 100644 index 409b30a0e013..000000000000 --- a/include/asm-arm/arch-ebsa285/serial.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa285/serial.h - * - * Copyright (C) 1996,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. - * - * Changelog: - * 15-10-1996 RMK Created - * 25-05-1998 PJB CATS support - */ -#ifndef __ASM_ARCH_SERIAL_H -#define __ASM_ARCH_SERIAL_H - -#include <asm/irq.h> - -/* - * This assumes you have a 1.8432 MHz clock for your UART. - * - * It'd be nice if someone built a serial card with a 24.576 MHz - * clock, since the 16550A is capable of handling a top speed of 1.5 - * megabits/second; but this requires the faster clock. - */ -#define BASE_BAUD (1843200 / 16) - -#define _SER_IRQ0 IRQ_ISA_UART -#define _SER_IRQ1 IRQ_ISA_UART2 - -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) - - /* UART CLK PORT IRQ FLAGS */ -#define STD_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x3F8, _SER_IRQ0, STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0x2F8, _SER_IRQ1, STD_COM_FLAGS }, /* ttyS1 */ - -#define EXTRA_SERIAL_PORT_DEFNS - -#endif diff --git a/include/asm-arm/arch-epxa10db/serial.h b/include/asm-arm/arch-epxa10db/serial.h deleted file mode 100644 index 08f2d31cae95..000000000000 --- a/include/asm-arm/arch-epxa10db/serial.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * linux/include/asm-arm/arch-epxa10db/serial.h - * - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2001 Altera Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARCH_SERIAL_H -#define __ASM_ARCH_SERIAL_H - -#include <asm/arch/platform.h> -#include <asm/irq.h> - -/* - * This assumes you have a 1.8432 MHz clock for your UART. - * - * It'd be nice if someone built a serial card with a 24.576 MHz - * clock, since the 16550A is capable of handling a top speed of 1.5 - * megabits/second; but this requires the faster clock. - */ -#define BASE_BAUD (1 / 16) - -#define _SER_IRQ0 IRQ_UARTINT0 -#define _SER_IRQ1 IRQ_UARTINT1 - -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) - - /* UART CLK PORT IRQ FLAGS */ -#define STD_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x3F8, _SER_IRQ0, STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0x2F8, _SER_IRQ1, STD_COM_FLAGS }, /* ttyS1 */ - -#define EXTRA_SERIAL_PORT_DEFNS - -#endif diff --git a/include/asm-arm/arch-h720x/serial.h b/include/asm-arm/arch-h720x/serial.h deleted file mode 100644 index c91c9f0c5cd7..000000000000 --- a/include/asm-arm/arch-h720x/serial.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * linux/include/asm-arm/arch-h72x/serial.h - * - * Copyright (C) 2003 Thomas Gleixner <tglx@linutronix.de> - * 2003 Robert Schwebel <r.schwebel@pengutronix.de> - * - * Serial port setup for Hynix boards - * - * 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_SERIAL_H -#define __ASM_ARCH_SERIAL_H - -#include <asm/arch/irqs.h> - -/* - * Standard COM flags - */ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) -#define RS_TABLE_SIZE - -/* Base clock is 3.6864 MHz */ -#define BASE_BAUD (115200*2) -#define EXTRA_SERIAL_PORT_DEFNS - -/* - * Board dependend defines - */ -#if defined (CONFIG_CPU_H7201) -#define BASE_BAUD_P3C (115200) - -#define STD_SERIAL_PORT_DEFNS \ - { \ - .baud_base = BASE_BAUD, \ - .port = SERIAL0_BASE, \ - .iomem_base = (u8*)SERIAL0_BASE, \ - .io_type = UPIO_MEM, \ - .irq = IRQ_UART0, \ - .flags = STD_COM_FLAGS, \ - .iomem_reg_shift = 2,\ - }, \ - { \ - .baud_base = BASE_BAUD, \ - .port = SERIAL1_BASE, \ - .iomem_base = (u8*)SERIAL1_BASE, \ - .io_type = UPIO_MEM, \ - .irq = IRQ_UART1, \ - .flags = STD_COM_FLAGS, \ - .iomem_reg_shift = 2,\ - } - -#elif defined (CONFIG_CPU_H7202) - -#define STD_SERIAL_PORT_DEFNS \ - { \ - .baud_base = BASE_BAUD, \ - .port = SERIAL0_BASE, \ - .iomem_base = (u8*)SERIAL0_BASE, \ - .io_type = UPIO_MEM, \ - .irq = IRQ_UART0, \ - .flags = STD_COM_FLAGS, \ - .iomem_reg_shift = 2,\ - }, \ - { \ - .baud_base = BASE_BAUD, \ - .port = SERIAL1_BASE, \ - .iomem_base = (u8*)SERIAL1_BASE, \ - .io_type = UPIO_MEM, \ - .irq = IRQ_UART1, \ - .flags = STD_COM_FLAGS, \ - .iomem_reg_shift = 2,\ - }, \ - { \ - .baud_base = BASE_BAUD, \ - .port = SERIAL2_BASE, \ - .iomem_base = (u8*)SERIAL2_BASE, \ - .io_type = UPIO_MEM, \ - .irq = IRQ_UART2, \ - .flags = STD_COM_FLAGS, \ - .iomem_reg_shift = 2,\ - }, \ - { \ - .baud_base = BASE_BAUD, \ - .port = SERIAL3_BASE, \ - .iomem_base = (u8*)SERIAL3_BASE, \ - .io_type = UPIO_MEM, \ - .irq = IRQ_UART3, \ - .flags = STD_COM_FLAGS, \ - .iomem_reg_shift = 2,\ - } - -#else -#error machine definition mismatch -#endif - -/* __ASM_ARCH_SERIAL_H */ -#endif diff --git a/include/asm-arm/arch-imx/serial.h b/include/asm-arm/arch-imx/serial.h deleted file mode 100644 index c885c48a59ab..000000000000 --- a/include/asm-arm/arch-imx/serial.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * linux/include/asm-arm/arch-imx/serial.h - * - * Copyright (C) 1999 ARM Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARCH_SERIAL_H -#define __ASM_ARCH_SERIAL_H - -#define STD_SERIAL_PORT_DEFNS -#define EXTRA_SERIAL_PORT_DEFNS - -#endif /* __ASM_ARCH_SERIAL_H */ diff --git a/include/asm-arm/arch-integrator/serial.h b/include/asm-arm/arch-integrator/serial.h deleted file mode 100644 index 8ee6f88a03c9..000000000000 --- a/include/asm-arm/arch-integrator/serial.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * linux/include/asm-arm/arch-integrator/serial.h - * - * Copyright (C) 1999 ARM Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#ifndef __ASM_ARCH_SERIAL_H -#define __ASM_ARCH_SERIAL_H - -#include <asm/arch/platform.h> -#include <asm/irq.h> - -/* - * This assumes you have a 1.8432 MHz clock for your UART. - * - * It'd be nice if someone built a serial card with a 24.576 MHz - * clock, since the 16550A is capable of handling a top speed of 1.5 - * megabits/second; but this requires the faster clock. - */ -#define BASE_BAUD (1843200 / 16) - -#define _SER_IRQ0 IRQ_UARTINT0 -#define _SER_IRQ1 IRQ_UARTINT1 - -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) - - /* UART CLK PORT IRQ FLAGS */ -#define STD_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x3F8, _SER_IRQ0, STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0x2F8, _SER_IRQ1, STD_COM_FLAGS }, /* ttyS1 */ - -#define EXTRA_SERIAL_PORT_DEFNS - -#endif diff --git a/include/asm-arm/arch-ixp2000/serial.h b/include/asm-arm/arch-ixp2000/serial.h deleted file mode 100644 index 98eebf187eef..000000000000 --- a/include/asm-arm/arch-ixp2000/serial.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * include/asm-arm/arch-ixp2000/serial.h - * - * Serial port defn for ixp2000 based systems. - * - * Author: Deepak Saxena <dsaxena@plexity.net> - * - * Copyright (c) 2002-2004 MontaVista Software, Inc. - * - * We do not register serial ports staticly b/c there is no easy way - * to autodetect an XScale port. Instead we register them at runtime - * via early_serial_init(). - */ - -#ifndef _ARCH_SERIAL_H_ -#define _ARCH_SERIAL_H_ - -#define BASE_BAUD (50000000/ 16) - -/* - * Currently no IXP2000 systems with > 3 serial ports. - * If you add a system that does, just up this. - */ -#define STD_SERIAL_PORT_DEFNS -#define EXTRA_SERIAL_PORT_DEFNS - -#endif // __ARCH_SERIAL_H_ diff --git a/include/asm-arm/arch-ixp4xx/serial.h b/include/asm-arm/arch-ixp4xx/serial.h deleted file mode 100644 index 93d6c38503a9..000000000000 --- a/include/asm-arm/arch-ixp4xx/serial.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * include/asm-arm/arch-ixp4xx/serial.h - * - * Author: Deepak Saxena <dsaxena@plexity.net> - * - * Copyright (C) 2002-2004 MontaVista Software, Inc. - * - */ - -#ifndef _ARCH_SERIAL_H_ -#define _ARCH_SERIAL_H_ - -/* - * We don't hardcode our serial port information but instead - * fill it in dynamically based on our platform in arch->map_io. - * This allows for per-board serial ports w/o a bunch of - * #ifdefs in this file. - */ -#define STD_SERIAL_PORT_DEFNS -#define EXTRA_SERIAL_PORT_DEFNS - -/* - * IXP4XX uses 15.6MHz clock for uart - */ -#define BASE_BAUD ( IXP4XX_UART_XTAL / 16 ) - -#endif // _ARCH_SERIAL_H_ diff --git a/include/asm-arm/arch-lh7a40x/serial.h b/include/asm-arm/arch-lh7a40x/serial.h deleted file mode 100644 index 64783c05fb92..000000000000 --- a/include/asm-arm/arch-lh7a40x/serial.h +++ /dev/null @@ -1,25 +0,0 @@ -/* include/asm-arm/arch-lh7a40x/serial.h - * - * Copyright (C) 2004 Coastal Environmental Systems - * - * 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_SERIAL_H -#define __ASM_ARCH_SERIAL_H - -#include <asm/arch/registers.h> - -#define UART_R_DATA (0x00) -#define UART_R_FCON (0x04) -#define UART_R_BRCON (0x08) -#define UART_R_CON (0x0c) -#define UART_R_STATUS (0x10) -#define UART_R_RAWISR (0x14) -#define UART_R_INTEN (0x18) -#define UART_R_ISR (0x1c) - -#endif /* _ASM_ARCH_SERIAL_H */ diff --git a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h index febce77d3209..4ead9942a30b 100644 --- a/include/asm-arm/arch-omap/hardware.h +++ b/include/asm-arm/arch-omap/hardware.h @@ -283,6 +283,26 @@ /* * --------------------------------------------------------------------------- + * Serial ports + * --------------------------------------------------------------------------- + */ +#define OMAP_UART1_BASE (unsigned char *)0xfffb0000 +#define OMAP_UART2_BASE (unsigned char *)0xfffb0800 +#define OMAP_UART3_BASE (unsigned char *)0xfffb9800 +#define OMAP_MAX_NR_PORTS 3 +#define OMAP1510_BASE_BAUD (12000000/16) +#define OMAP16XX_BASE_BAUD (48000000/16) + +#define is_omap_port(p) ({int __ret = 0; \ + if (p == (char*)IO_ADDRESS(OMAP_UART1_BASE) || \ + p == (char*)IO_ADDRESS(OMAP_UART2_BASE) || \ + p == (char*)IO_ADDRESS(OMAP_UART3_BASE)) \ + __ret = 1; \ + __ret; \ + }) + +/* + * --------------------------------------------------------------------------- * Processor specific defines * --------------------------------------------------------------------------- */ diff --git a/include/asm-arm/arch-omap/serial.h b/include/asm-arm/arch-omap/serial.h deleted file mode 100644 index 0f4b83b807e7..000000000000 --- a/include/asm-arm/arch-omap/serial.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * linux/include/asm-arm/arch-omap/serial.h - * - * BRIEF MODULE DESCRIPTION - * serial definitions - * - */ - -#ifndef __ASM_ARCH_SERIAL_H -#define __ASM_ARCH_SERIAL_H - -#define OMAP_UART1_BASE (unsigned char *)0xfffb0000 -#define OMAP_UART2_BASE (unsigned char *)0xfffb0800 -#define OMAP_UART3_BASE (unsigned char *)0xfffb9800 -#define OMAP_MAX_NR_PORTS 3 -#define PORT_OMAP 16 /* Temporary */ - -#ifndef __ASSEMBLY__ - -#include <asm/arch/hardware.h> -#include <asm/irq.h> - -#define OMAP1510_BASE_BAUD (12000000/16) -#define OMAP16XX_BASE_BAUD (48000000/16) - -#define UART_SYSC 0x15 - -/* OMAP FCR trigger redefinitions */ -#define UART_FCR_R_TRIGGER_8 0x00 /* Mask for receive trigger set at 8 */ -#define UART_FCR_R_TRIGGER_16 0x40 /* Mask for receive trigger set at 16 */ -#define UART_FCR_R_TRIGGER_56 0x80 /* Mask for receive trigger set at 56 */ -#define UART_FCR_R_TRIGGER_60 0xC0 /* Mask for receive trigger set at 60 */ - -/* There is an error in the description of the transmit trigger levels of - OMAP5910 TRM from January 2003. The transmit trigger level 56 is not - 56 but 32, the transmit trigger level 60 is not 60 but 56! - Additionally, the descritption of these trigger levels is - a little bit unclear. The trigger level define the number of EMPTY - entries in the FIFO. Thus, if TRIGGER_8 is used, an interrupt is requested - if 8 FIFO entries are empty (and 56 entries are still filled [the FIFO - size is 64]). Or: If TRIGGER_56 is selected, everytime there are less than - 8 characters in the FIFO, an interrrupt is spawned. In other words: The - trigger number is equal the number of characters which can be - written without FIFO overrun */ - -#define UART_FCR_T_TRIGGER_8 0x00 /* Mask for transmit trigger set at 8 */ -#define UART_FCR_T_TRIGGER_16 0x10 /* Mask for transmit trigger set at 16 */ -#define UART_FCR_T_TRIGGER_32 0x20 /* Mask for transmit trigger set at 32 */ -#define UART_FCR_T_TRIGGER_56 0x30 /* Mask for transmit trigger set at 56 */ - -#define STD_SERIAL_PORT_DEFNS -#define EXTRA_SERIAL_PORT_DEFNS -#define BASE_BAUD 0 - -#endif /* __ASSEMBLY__ */ -#endif /* __ASM_ARCH_SERIAL_H */ diff --git a/include/asm-arm/arch-omap/uncompress.h b/include/asm-arm/arch-omap/uncompress.h index abcb5fa12f0b..3e640aba8c20 100644 --- a/include/asm-arm/arch-omap/uncompress.h +++ b/include/asm-arm/arch-omap/uncompress.h @@ -20,7 +20,7 @@ #include <linux/config.h> #include <linux/types.h> #include <linux/serial_reg.h> -#include <asm/arch/serial.h> +#include <asm/arch/hardware.h> unsigned int system_rev; diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 1e0aecd81a5f..1f36b66be63c 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -1518,6 +1518,25 @@ #define RCSR_WDR (1 << 1) /* Watchdog Reset */ #define RCSR_HWR (1 << 0) /* Hardware Reset */ +#define PWER_GPIO(Nb) (1 << Nb) /* GPIO [0..15] wake-up enable */ +#define PWER_GPIO0 PWER_GPIO (0) /* GPIO [0] wake-up enable */ +#define PWER_GPIO1 PWER_GPIO (1) /* GPIO [1] wake-up enable */ +#define PWER_GPIO2 PWER_GPIO (2) /* GPIO [2] wake-up enable */ +#define PWER_GPIO3 PWER_GPIO (3) /* GPIO [3] wake-up enable */ +#define PWER_GPIO4 PWER_GPIO (4) /* GPIO [4] wake-up enable */ +#define PWER_GPIO5 PWER_GPIO (5) /* GPIO [5] wake-up enable */ +#define PWER_GPIO6 PWER_GPIO (6) /* GPIO [6] wake-up enable */ +#define PWER_GPIO7 PWER_GPIO (7) /* GPIO [7] wake-up enable */ +#define PWER_GPIO8 PWER_GPIO (8) /* GPIO [8] wake-up enable */ +#define PWER_GPIO9 PWER_GPIO (9) /* GPIO [9] wake-up enable */ +#define PWER_GPIO10 PWER_GPIO (10) /* GPIO [10] wake-up enable */ +#define PWER_GPIO11 PWER_GPIO (11) /* GPIO [11] wake-up enable */ +#define PWER_GPIO12 PWER_GPIO (12) /* GPIO [12] wake-up enable */ +#define PWER_GPIO13 PWER_GPIO (13) /* GPIO [13] wake-up enable */ +#define PWER_GPIO14 PWER_GPIO (14) /* GPIO [14] wake-up enable */ +#define PWER_GPIO15 PWER_GPIO (15) /* GPIO [15] wake-up enable */ +#define PWER_RTC 0x80000000 /* RTC alarm wake-up enable */ + /* * SSP Serial Port Registers diff --git a/include/asm-arm/arch-pxa/serial.h b/include/asm-arm/arch-pxa/serial.h deleted file mode 100644 index 1d06b3b23891..000000000000 --- a/include/asm-arm/arch-pxa/serial.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * linux/include/asm-arm/arch-pxa/serial.h - * - * Author: Nicolas Pitre - * Copyright: (C) 2001 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. - */ - -#include <asm/arch/pxa-regs.h> - -#define BAUD_BASE 921600 - -/* Standard COM flags */ -#define STD_COM_FLAGS (ASYNC_SKIP_TEST) - -#define STD_SERIAL_PORT_DEFNS \ - { \ - type: PORT_PXA, \ - xmit_fifo_size: 64, \ - baud_base: BAUD_BASE, \ - iomem_base: &FFUART, \ - iomem_reg_shift: 2, \ - io_type: SERIAL_IO_MEM, \ - irq: IRQ_FFUART, \ - flags: STD_COM_FLAGS, \ - }, { \ - type: PORT_PXA, \ - xmit_fifo_size: 64, \ - baud_base: BAUD_BASE, \ - iomem_base: &STUART, \ - iomem_reg_shift: 2, \ - io_type: SERIAL_IO_MEM, \ - irq: IRQ_STUART, \ - flags: STD_COM_FLAGS, \ - }, { \ - type: PORT_PXA, \ - xmit_fifo_size: 64, \ - baud_base: BAUD_BASE, \ - iomem_base: &BTUART, \ - iomem_reg_shift: 2, \ - io_type: SERIAL_IO_MEM, \ - irq: IRQ_BTUART, \ - flags: STD_COM_FLAGS, \ - } - -#define EXTRA_SERIAL_PORT_DEFNS - diff --git a/include/asm-arm/arch-rpc/serial.h b/include/asm-arm/arch-rpc/serial.h deleted file mode 100644 index 854304f5a642..000000000000 --- a/include/asm-arm/arch-rpc/serial.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * linux/include/asm-arm/arch-rpc/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_ARCH_SERIAL_H -#define __ASM_ARCH_SERIAL_H - -/* - * This assumes you have a 1.8432 MHz clock for your UART. - * - * It'd be nice if someone built a serial card with a 24.576 MHz - * clock, since the 16550A is capable of handling a top speed of 1.5 - * megabits/second; but this requires the faster clock. - */ -#define BASE_BAUD (1843200 / 16) - -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) - - /* UART CLK PORT IRQ FLAGS */ -#define STD_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x3F8, 10, STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS1 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS2 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS3 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS } /* ttyS13 */ - -#define EXTRA_SERIAL_PORT_DEFNS - -#endif diff --git a/include/asm-arm/arch-s3c2410/dma.h b/include/asm-arm/arch-s3c2410/dma.h index f18a19198df6..8e5a9e1a7a70 100644 --- a/include/asm-arm/arch-s3c2410/dma.h +++ b/include/asm-arm/arch-s3c2410/dma.h @@ -199,8 +199,8 @@ struct s3c2410_dma_chan_s { /* channel's hardware position and configuration */ void __iomem *regs; /* channels registers */ + void __iomem *addr_reg; /* data address register */ unsigned int irq; /* channel irq */ - unsigned long addr_reg; /* data address register */ unsigned long dcon; /* default value of DCON */ /* driver handles */ diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h index 0c1498d3401f..20a0836672ff 100644 --- a/include/asm-arm/arch-s3c2410/regs-gpio.h +++ b/include/asm-arm/arch-s3c2410/regs-gpio.h @@ -812,7 +812,7 @@ #define S3C2410_GSTATUS1_2440 (0x32440000) #define S3C2410_GSTATUS2_WTRESET (1<<2) -#define S3C2410_GSTATUs2_OFFRESET (1<<1) +#define S3C2410_GSTATUS2_OFFRESET (1<<1) #define S3C2410_GSTATUS2_PONRESET (1<<0) #endif /* __ASM_ARCH_REGS_GPIO_H */ diff --git a/include/asm-arm/arch-s3c2410/regs-rtc.h b/include/asm-arm/arch-s3c2410/regs-rtc.h index bbe2b6759daa..408cf04266e8 100644 --- a/include/asm-arm/arch-s3c2410/regs-rtc.h +++ b/include/asm-arm/arch-s3c2410/regs-rtc.h @@ -21,6 +21,8 @@ #define S3C2410_RTCCON S3C2410_RTCREG(0x40) #define S3C2410_RTCCON_RTCEN (1<<0) +#define S3C2410_RTCCON_CLKSEL (1<<1) +#define S3C2410_RTCCON_CNTSEL (1<<2) #define S3C2410_RTCCON_CLKRST (1<<3) #define S3C2410_TICNT S3C2410_RTCREG(0x44) diff --git a/include/asm-arm/arch-s3c2410/serial.h b/include/asm-arm/arch-s3c2410/serial.h deleted file mode 100644 index e85948bd8f21..000000000000 --- a/include/asm-arm/arch-s3c2410/serial.h +++ /dev/null @@ -1,28 +0,0 @@ -/* linux/include/asm-arm/arch-s3c2410/serial.h - * - * (c) 2003 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * - * S3C2410 - serial port definitions - * - * 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: - * 03-Sep-2003 BJD Created file - * 19-Mar-2004 BJD Removed serial port definitions, inserted elsewhere -*/ - -#ifndef __ASM_ARCH_SERIAL_H -#define __ASM_ARCH_SERIAL_H - -/* Standard COM flags */ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) - -#define BASE_BAUD ( 1843200 / 16 ) - -#define STD_SERIAL_PORT_DEFNS -#define EXTRA_SERIAL_PORT_DEFNS - -#endif /* __ASM_ARCH_SERIAL_H */ diff --git a/include/asm-arm/arch-sa1100/serial.h b/include/asm-arm/arch-sa1100/serial.h deleted file mode 100644 index 47dc77ecd6dc..000000000000 --- a/include/asm-arm/arch-sa1100/serial.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * include/asm-arm/arch-sa1100/serial.h - * (C) 1999 Nicolas Pitre <nico@cam.org> - * - * All this is intended to be used with a 16550-like UART on the SA1100's - * PCMCIA bus. It has nothing to do with the SA1100's internal serial ports. - * This is included by serial.c -- serial_sa1100.c makes no use of it. - */ - -#include <linux/config.h> - -/* Standard COM flags */ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) - -/* - * Rather empty table... - * Hardwired serial ports should be defined here. - * PCMCIA will fill it dynamically. - */ -#ifdef CONFIG_SA1100_TRIZEPS - -#define STD_SERIAL_PORT_DEFNS \ - /* UART CLK PORT IRQ FLAGS */ \ - { 0, 1500000, TRIZEPS_UART5, IRQ_GPIO16, STD_COM_FLAGS }, \ - { 0, 1500000, TRIZEPS_UART6, IRQ_GPIO17, STD_COM_FLAGS } - -#else - -/* - * This assumes you have a 1.8432 MHz clock for your UART. - * - * It'd be nice if someone built a serial card with a 24.576 MHz - * clock, since the 16550A is capable of handling a top speed of 1.5 - * megabits/second; but this requires the faster clock. - */ -#define BASE_BAUD ( 1843200 / 16 ) - -#define STD_SERIAL_PORT_DEFNS \ - /* UART CLK PORT IRQ FLAGS */ \ - { 0, BASE_BAUD, 0, 0, STD_COM_FLAGS }, \ - { 0, BASE_BAUD, 0, 0, STD_COM_FLAGS }, \ - { 0, BASE_BAUD, 0, 0, STD_COM_FLAGS }, \ - { 0, BASE_BAUD, 0, 0, STD_COM_FLAGS } - -#endif - -#define EXTRA_SERIAL_PORT_DEFNS diff --git a/include/asm-arm/arch-shark/serial.h b/include/asm-arm/arch-shark/serial.h deleted file mode 100644 index 2edfa7540eb6..000000000000 --- a/include/asm-arm/arch-shark/serial.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/serial.h - * - * Copyright (c) 1996,1997,1998 Russell King. - * - * Changelog: - * 15-10-1996 RMK Created - */ -#ifndef __ASM_ARCH_SERIAL_H -#define __ASM_ARCH_SERIAL_H - -/* - * This assumes you have a 1.8432 MHz clock for your UART. - * - * It'd be nice if someone built a serial card with a 24.576 MHz - * clock, since the 16550A is capable of handling a top speed of 1.5 - * megabits/second; but this requires the faster clock. - */ -#define BASE_BAUD (1843200 / 16) - -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) - - /* UART CLK PORT IRQ FLAGS */ -#define STD_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ - -#define EXTRA_SERIAL_PORT_DEFNS - -#endif - diff --git a/include/asm-arm/arch-versatile/hardware.h b/include/asm-arm/arch-versatile/hardware.h index 535b1f041b73..d5fb4a251e7f 100644 --- a/include/asm-arm/arch-versatile/hardware.h +++ b/include/asm-arm/arch-versatile/hardware.h @@ -1,7 +1,7 @@ /* * linux/include/asm-arm/arch-versatile/hardware.h * - * This file contains the hardware definitions of the Versatile PB board. + * This file contains the hardware definitions of the Versatile boards. * * Copyright (C) 2003 ARM Limited. * diff --git a/include/asm-arm/arch-versatile/platform.h b/include/asm-arm/arch-versatile/platform.h index 68be3f036600..bc75b3ca0e67 100644 --- a/include/asm-arm/arch-versatile/platform.h +++ b/include/asm-arm/arch-versatile/platform.h @@ -47,7 +47,7 @@ /* ------------------------------------------------------------------------ - * Versatile PB Registers + * Versatile Registers * ------------------------------------------------------------------------ * */ @@ -55,10 +55,16 @@ #define VERSATILE_SYS_SW_OFFSET 0x04 #define VERSATILE_SYS_LED_OFFSET 0x08 #define VERSATILE_SYS_OSC0_OFFSET 0x0C + +#if defined(CONFIG_ARCH_VERSATILE_PB) #define VERSATILE_SYS_OSC1_OFFSET 0x10 #define VERSATILE_SYS_OSC2_OFFSET 0x14 #define VERSATILE_SYS_OSC3_OFFSET 0x18 #define VERSATILE_SYS_OSC4_OFFSET 0x1C +#elif defined(CONFIG_ARCH_VERSATILE_AB) +#define VERSATILE_SYS_OSC1_OFFSET 0x1C +#endif + #define VERSATILE_SYS_LOCK_OFFSET 0x20 #define VERSATILE_SYS_100HZ_OFFSET 0x24 #define VERSATILE_SYS_CFGDATA1_OFFSET 0x28 @@ -90,9 +96,13 @@ #define VERSATILE_SYS_LED (VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET) #define VERSATILE_SYS_OSC0 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC0_OFFSET) #define VERSATILE_SYS_OSC1 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC1_OFFSET) + +#if defined(CONFIG_ARCH_VERSATILE_PB) #define VERSATILE_SYS_OSC2 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC2_OFFSET) #define VERSATILE_SYS_OSC3 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC3_OFFSET) #define VERSATILE_SYS_OSC4 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC4_OFFSET) +#endif + #define VERSATILE_SYS_LOCK (VERSATILE_SYS_BASE + VERSATILE_SYS_LOCK_OFFSET) #define VERSATILE_SYS_100HZ (VERSATILE_SYS_BASE + VERSATILE_SYS_100HZ_OFFSET) #define VERSATILE_SYS_CFGDATA1 (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA1_OFFSET) @@ -132,7 +142,7 @@ /* ------------------------------------------------------------------------ - * Versatile PB control registers + * Versatile control registers * ------------------------------------------------------------------------ */ @@ -213,6 +223,7 @@ #define VERSATILE_SSP_BASE 0x101F4000 /* Synchronous Serial Port */ #define VERSATILE_SSMC_BASE 0x20000000 /* SSMC */ +#define VERSATILE_IB2_BASE 0x24000000 /* IB2 module */ #define VERSATILE_MBX_BASE 0x40000000 /* MBX */ #define VERSATILE_PCI_BASE 0x41000000 /* PCI Interface */ #define VERSATILE_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */ @@ -255,7 +266,7 @@ /* ------------------------------------------------------------------------ - * Versatile PB Interrupt Controller - control registers + * Versatile Interrupt Controller - control registers * ------------------------------------------------------------------------ * * Offsets from interrupt controller base @@ -483,6 +494,17 @@ #define VERSATILE_CSR_BASE 0x10000000 #define VERSATILE_CSR_SIZE 0x10000000 +#ifdef CONFIG_ARCH_VERSATILE_AB +/* + * IB2 Versatile/AB expansion board definitions + */ +#define VERSATILE_IB2_CAMERA_BANK 0x24000000 +#define VERSATILE_IB2_KBD_DATAREG 0x25000000 +#define VERSATILE_IB2_IER 0x26000000 /* for VICINTSOURCE27 */ +#define VERSATILE_IB2_CTRL 0x27000000 +#define VERSATILE_IB2_STAT 0x27000004 +#endif + #endif /* END */ diff --git a/include/asm-arm/arch-versatile/timex.h b/include/asm-arm/arch-versatile/timex.h index 61da0c6ab38a..38fd04fc9141 100644 --- a/include/asm-arm/arch-versatile/timex.h +++ b/include/asm-arm/arch-versatile/timex.h @@ -1,7 +1,7 @@ /* * linux/include/asm-arm/arch-versatile/timex.h * - * Versatile PB architecture timex specifications + * Versatile architecture timex specifications * * Copyright (C) 2003 ARM Limited * diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h index c70f6de1d2ba..d38a1cadf0b7 100644 --- a/include/asm-arm/cacheflush.h +++ b/include/asm-arm/cacheflush.h @@ -325,4 +325,63 @@ extern void flush_dcache_page(struct page *); */ #define flush_icache_page(vma,page) do { } while (0) +#define __cacheid_present(val) (val != read_cpuid(CPUID_ID)) +#define __cacheid_vivt(val) ((val & (15 << 25)) != (14 << 25)) +#define __cacheid_vipt(val) ((val & (15 << 25)) == (14 << 25)) +#define __cacheid_vipt_nonaliasing(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25)) +#define __cacheid_vipt_aliasing(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25 | 1 << 23)) + +#if defined(CONFIG_CPU_CACHE_VIVT) && !defined(CONFIG_CPU_CACHE_VIPT) + +#define cache_is_vivt() 1 +#define cache_is_vipt() 0 +#define cache_is_vipt_nonaliasing() 0 +#define cache_is_vipt_aliasing() 0 + +#elif defined(CONFIG_CPU_CACHE_VIPT) + +#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); \ + }) + +#else + +#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); \ + }) + +#endif + #endif diff --git a/include/asm-arm/hardirq.h b/include/asm-arm/hardirq.h index 8cf189b44f33..a808f3c4f283 100644 --- a/include/asm-arm/hardirq.h +++ b/include/asm-arm/hardirq.h @@ -12,31 +12,12 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-24 are the hardirq count (max # of hardirqs: 512) - * - bit 26 is the PREEMPT_ACTIVE flag - * - * We optimize HARDIRQ_BITS for immediate constant, and only - * increase it if really needed. - */ -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 - #if NR_IRQS > 256 #define HARDIRQ_BITS 9 #else #define HARDIRQ_BITS 8 #endif -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - /* * The hardirq mask has to be large enough to have space * for potentially all IRQ sources in the system nesting diff --git a/include/asm-arm/hardware/amba_clcd.h b/include/asm-arm/hardware/amba_clcd.h index d8a8456fb835..97681e3590f8 100644 --- a/include/asm-arm/hardware/amba_clcd.h +++ b/include/asm-arm/hardware/amba_clcd.h @@ -22,7 +22,7 @@ #define CLCD_UBAS 0x00000010 #define CLCD_LBAS 0x00000014 -#ifndef CONFIG_ARCH_VERSATILE_PB +#ifndef CONFIG_ARCH_VERSATILE #define CLCD_IENB 0x00000018 #define CLCD_CNTL 0x0000001c #else diff --git a/include/asm-arm/hardware/icst307.h b/include/asm-arm/hardware/icst307.h new file mode 100644 index 000000000000..ff8618a441c0 --- /dev/null +++ b/include/asm-arm/hardware/icst307.h @@ -0,0 +1,38 @@ +/* + * linux/include/asm-arm/hardware/icst307.h + * + * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Support functions for calculating clocks/divisors for the ICS307 + * clock generators. See http://www.icst.com/ for more information + * on these devices. + * + * This file is similar to the icst525.h file + */ +#ifndef ASMARM_HARDWARE_ICST307_H +#define ASMARM_HARDWARE_ICST307_H + +struct icst307_params { + unsigned long ref; + unsigned long vco_max; /* inclusive */ + unsigned short vd_min; /* inclusive */ + unsigned short vd_max; /* inclusive */ + unsigned char rd_min; /* inclusive */ + unsigned char rd_max; /* inclusive */ +}; + +struct icst307_vco { + unsigned short v; + unsigned char r; + unsigned char s; +}; + +unsigned long icst307_khz(const struct icst307_params *p, struct icst307_vco vco); +struct icst307_vco icst307_khz_to_vco(const struct icst307_params *p, unsigned long freq); +struct icst307_vco icst307_ps_to_vco(const struct icst307_params *p, unsigned long period); + +#endif diff --git a/include/asm-arm/serial.h b/include/asm-arm/serial.h index 1cce84a8cd48..015b262dc145 100644 --- a/include/asm-arm/serial.h +++ b/include/asm-arm/serial.h @@ -14,10 +14,6 @@ #ifndef __ASM_SERIAL_H #define __ASM_SERIAL_H -#include <asm/arch/serial.h> - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS +#define BASE_BAUD (1843200 / 16) #endif diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index d7dfe2e1ba99..53cd8d3a08f2 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -57,38 +57,6 @@ __val; \ }) -#define __cacheid_present(val) (val != read_cpuid(CPUID_ID)) -#define __cacheid_vivt(val) ((val & (15 << 25)) != (14 << 25)) -#define __cacheid_vipt(val) ((val & (15 << 25)) == (14 << 25)) -#define __cacheid_vipt_nonaliasing(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25)) -#define __cacheid_vipt_aliasing(val) ((val & (15 << 25 | 1 << 23)) == (14 << 25 | 1 << 23)) - -#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); \ - }) - /* * This is used to ensure the compiler did actually allocate the register we * asked it for some inline assembly sequences. Apparently we can't trust diff --git a/include/asm-arm26/hardirq.h b/include/asm-arm26/hardirq.h index 52feb957f3e7..bb5a5faba266 100644 --- a/include/asm-arm26/hardirq.h +++ b/include/asm-arm26/hardirq.h @@ -15,23 +15,8 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-23 are the hardirq count (max # of hardirqs: 256) - * - bit 26 is the PREEMPT_ACTIVE flag - */ -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 8 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - /* * The hardirq mask has to be large enough to have space * for potentially all IRQ sources in the system nesting diff --git a/include/asm-arm26/linux_logo.h b/include/asm-arm26/linux_logo.h deleted file mode 100644 index 4a3b802d498d..000000000000 --- a/include/asm-arm26/linux_logo.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * linux/include/asm-arm/linux_logo.h - * - * Copyright (C) 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. - * - * Linux console driver logo definitions for ARM - */ - -#include <linux/init.h> -#include <linux/version.h> - -#define linux_logo_banner "ARM Linux version " UTS_RELEASE - -#include <linux/linux_logo.h> - diff --git a/include/asm-cris/hardirq.h b/include/asm-cris/hardirq.h index 4e28c83324ad..502aed5ec1af 100644 --- a/include/asm-cris/hardirq.h +++ b/include/asm-cris/hardirq.h @@ -17,29 +17,8 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-23 are the hardirq count (max # of hardirqs: 256) - * - * - ( bit 26 is the PREEMPT_ACTIVE flag. ) - * - * PREEMPT_MASK: 0x000000ff - * SOFTIRQ_MASK: 0x0000ff00 - * HARDIRQ_MASK: 0x00ff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 8 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - /* * The hardirq mask has to be large enough to have * space for potentially all IRQ sources in the system diff --git a/include/asm-h8300/hardirq.h b/include/asm-h8300/hardirq.h index c878cc44b6cb..5b16e797b497 100644 --- a/include/asm-h8300/hardirq.h +++ b/include/asm-h8300/hardirq.h @@ -15,29 +15,8 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-23 are the hardirq count (max # of hardirqs: 256) - * - * - ( bit 26 is the PREEMPT_ACTIVE flag. ) - * - * PREEMPT_MASK: 0x000000ff - * HARDIRQ_MASK: 0x0000ff00 - * SOFTIRQ_MASK: 0x00ff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 8 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - /* * The hardirq mask has to be large enough to have * space for potentially all IRQ sources in the system diff --git a/include/asm-h8300/linux_logo.h b/include/asm-h8300/linux_logo.h deleted file mode 100644 index 9c22ccb9051b..000000000000 --- a/include/asm-h8300/linux_logo.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * include/asm-h8300/linux_logo.h: This is a linux logo - * to be displayed on boot. - */ - -#include <linux/config.h> -#include <linux/init.h> -#include <linux/version.h> - -#define linux_logo_banner "Linux/m68knommu version " UTS_RELEASE - diff --git a/include/asm-i386/kprobes.h b/include/asm-i386/kprobes.h index 566e34a19996..c0e8ad379ee6 100644 --- a/include/asm-i386/kprobes.h +++ b/include/asm-i386/kprobes.h @@ -38,6 +38,13 @@ typedef u8 kprobe_opcode_t; ? (MAX_STACK_SIZE) \ : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) +/* Architecture specific copy of original instruction*/ +struct arch_specific_insn { + /* copy of the original instruction */ + kprobe_opcode_t insn[MAX_INSN_SIZE]; +}; + + /* trap3/1 are intr gates for kprobes. So, restore the status of IF, * if necessary, before executing the original int3/1 (trap) handler. */ diff --git a/include/asm-ia64/hardirq.h b/include/asm-ia64/hardirq.h index 491996a79251..602471e51aab 100644 --- a/include/asm-ia64/hardirq.h +++ b/include/asm-ia64/hardirq.h @@ -29,29 +29,8 @@ #define local_ksoftirqd_task() (local_cpu_data->ksoftirqd) #define local_nmi_count() 0 -/* - * We put the hardirq and softirq counter into the preemption counter. The bitmask has the - * following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-29 are the hardirq count (max # of hardirqs: 16384) - * - * - (bit 63 is the PREEMPT_ACTIVE flag---not currently implemented.) - * - * PREEMPT_MASK: 0x000000ff - * SOFTIRQ_MASK: 0x0000ff00 - * HARDIRQ_MASK: 0x3fff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 14 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - /* * The hardirq mask has to be large enough to have space for potentially all IRQ sources * in the system nesting on a single CPU: diff --git a/include/asm-ia64/sn/intr.h b/include/asm-ia64/sn/intr.h index 3d2f6c3143d1..3e23a7457ef5 100644 --- a/include/asm-ia64/sn/intr.h +++ b/include/asm-ia64/sn/intr.h @@ -18,6 +18,7 @@ #define SGI_XBOW_ERROR (0x32) #define SGI_PCIBR_ERROR (0x33) #define SGI_ACPI_SCI_INT (0x34) +#define SGI_MMTIMER_VECTOR (0x35) #define SGI_TIO_ERROR (0x36) #define SGI_XPC_NOTIFY (0xe7) diff --git a/include/asm-ia64/sn/shub_mmr.h b/include/asm-ia64/sn/shub_mmr.h index 430c50fd1485..ddb265c91efb 100644 --- a/include/asm-ia64/sn/shub_mmr.h +++ b/include/asm-ia64/sn/shub_mmr.h @@ -196,4 +196,209 @@ #define SH_PTC_1_START_SHFT 63 #define SH_PTC_1_START_MASK 0x8000000000000000 +/* + * Register definitions + */ + +/* ==================================================================== */ +/* Register "SH_RTC1_INT_CONFIG" */ +/* SHub RTC 1 Interrupt Config Registers */ +/* ==================================================================== */ + +#define SH_RTC1_INT_CONFIG 0x0000000110001480 +#define SH_RTC1_INT_CONFIG_MASK 0x0ff3ffffffefffff +#define SH_RTC1_INT_CONFIG_INIT 0x0000000000000000 + +/* SH_RTC1_INT_CONFIG_TYPE */ +/* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ +#define SH_RTC1_INT_CONFIG_TYPE_SHFT 0 +#define SH_RTC1_INT_CONFIG_TYPE_MASK 0x0000000000000007 + +/* SH_RTC1_INT_CONFIG_AGT */ +/* Description: Agent, must be 0 for SHub */ +#define SH_RTC1_INT_CONFIG_AGT_SHFT 3 +#define SH_RTC1_INT_CONFIG_AGT_MASK 0x0000000000000008 + +/* SH_RTC1_INT_CONFIG_PID */ +/* Description: Processor ID, same setting as on targeted McKinley */ +#define SH_RTC1_INT_CONFIG_PID_SHFT 4 +#define SH_RTC1_INT_CONFIG_PID_MASK 0x00000000000ffff0 + +/* SH_RTC1_INT_CONFIG_BASE */ +/* Description: Optional interrupt vector area, 2MB aligned */ +#define SH_RTC1_INT_CONFIG_BASE_SHFT 21 +#define SH_RTC1_INT_CONFIG_BASE_MASK 0x0003ffffffe00000 + +/* SH_RTC1_INT_CONFIG_IDX */ +/* Description: Targeted McKinley interrupt vector */ +#define SH_RTC1_INT_CONFIG_IDX_SHFT 52 +#define SH_RTC1_INT_CONFIG_IDX_MASK 0x0ff0000000000000 + +/* ==================================================================== */ +/* Register "SH_RTC1_INT_ENABLE" */ +/* SHub RTC 1 Interrupt Enable Registers */ +/* ==================================================================== */ + +#define SH_RTC1_INT_ENABLE 0x0000000110001500 +#define SH_RTC1_INT_ENABLE_MASK 0x0000000000000001 +#define SH_RTC1_INT_ENABLE_INIT 0x0000000000000000 + +/* SH_RTC1_INT_ENABLE_RTC1_ENABLE */ +/* Description: Enable RTC 1 Interrupt */ +#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_SHFT 0 +#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_MASK 0x0000000000000001 + +/* ==================================================================== */ +/* Register "SH_RTC2_INT_CONFIG" */ +/* SHub RTC 2 Interrupt Config Registers */ +/* ==================================================================== */ + +#define SH_RTC2_INT_CONFIG 0x0000000110001580 +#define SH_RTC2_INT_CONFIG_MASK 0x0ff3ffffffefffff +#define SH_RTC2_INT_CONFIG_INIT 0x0000000000000000 + +/* SH_RTC2_INT_CONFIG_TYPE */ +/* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ +#define SH_RTC2_INT_CONFIG_TYPE_SHFT 0 +#define SH_RTC2_INT_CONFIG_TYPE_MASK 0x0000000000000007 + +/* SH_RTC2_INT_CONFIG_AGT */ +/* Description: Agent, must be 0 for SHub */ +#define SH_RTC2_INT_CONFIG_AGT_SHFT 3 +#define SH_RTC2_INT_CONFIG_AGT_MASK 0x0000000000000008 + +/* SH_RTC2_INT_CONFIG_PID */ +/* Description: Processor ID, same setting as on targeted McKinley */ +#define SH_RTC2_INT_CONFIG_PID_SHFT 4 +#define SH_RTC2_INT_CONFIG_PID_MASK 0x00000000000ffff0 + +/* SH_RTC2_INT_CONFIG_BASE */ +/* Description: Optional interrupt vector area, 2MB aligned */ +#define SH_RTC2_INT_CONFIG_BASE_SHFT 21 +#define SH_RTC2_INT_CONFIG_BASE_MASK 0x0003ffffffe00000 + +/* SH_RTC2_INT_CONFIG_IDX */ +/* Description: Targeted McKinley interrupt vector */ +#define SH_RTC2_INT_CONFIG_IDX_SHFT 52 +#define SH_RTC2_INT_CONFIG_IDX_MASK 0x0ff0000000000000 + +/* ==================================================================== */ +/* Register "SH_RTC2_INT_ENABLE" */ +/* SHub RTC 2 Interrupt Enable Registers */ +/* ==================================================================== */ + +#define SH_RTC2_INT_ENABLE 0x0000000110001600 +#define SH_RTC2_INT_ENABLE_MASK 0x0000000000000001 +#define SH_RTC2_INT_ENABLE_INIT 0x0000000000000000 + +/* SH_RTC2_INT_ENABLE_RTC2_ENABLE */ +/* Description: Enable RTC 2 Interrupt */ +#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_SHFT 0 +#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_MASK 0x0000000000000001 + +/* ==================================================================== */ +/* Register "SH_RTC3_INT_CONFIG" */ +/* SHub RTC 3 Interrupt Config Registers */ +/* ==================================================================== */ + +#define SH_RTC3_INT_CONFIG 0x0000000110001680 +#define SH_RTC3_INT_CONFIG_MASK 0x0ff3ffffffefffff +#define SH_RTC3_INT_CONFIG_INIT 0x0000000000000000 + +/* SH_RTC3_INT_CONFIG_TYPE */ +/* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ +#define SH_RTC3_INT_CONFIG_TYPE_SHFT 0 +#define SH_RTC3_INT_CONFIG_TYPE_MASK 0x0000000000000007 + +/* SH_RTC3_INT_CONFIG_AGT */ +/* Description: Agent, must be 0 for SHub */ +#define SH_RTC3_INT_CONFIG_AGT_SHFT 3 +#define SH_RTC3_INT_CONFIG_AGT_MASK 0x0000000000000008 + +/* SH_RTC3_INT_CONFIG_PID */ +/* Description: Processor ID, same setting as on targeted McKinley */ +#define SH_RTC3_INT_CONFIG_PID_SHFT 4 +#define SH_RTC3_INT_CONFIG_PID_MASK 0x00000000000ffff0 + +/* SH_RTC3_INT_CONFIG_BASE */ +/* Description: Optional interrupt vector area, 2MB aligned */ +#define SH_RTC3_INT_CONFIG_BASE_SHFT 21 +#define SH_RTC3_INT_CONFIG_BASE_MASK 0x0003ffffffe00000 + +/* SH_RTC3_INT_CONFIG_IDX */ +/* Description: Targeted McKinley interrupt vector */ +#define SH_RTC3_INT_CONFIG_IDX_SHFT 52 +#define SH_RTC3_INT_CONFIG_IDX_MASK 0x0ff0000000000000 + +/* ==================================================================== */ +/* Register "SH_RTC3_INT_ENABLE" */ +/* SHub RTC 3 Interrupt Enable Registers */ +/* ==================================================================== */ + +#define SH_RTC3_INT_ENABLE 0x0000000110001700 +#define SH_RTC3_INT_ENABLE_MASK 0x0000000000000001 +#define SH_RTC3_INT_ENABLE_INIT 0x0000000000000000 + +/* SH_RTC3_INT_ENABLE_RTC3_ENABLE */ +/* Description: Enable RTC 3 Interrupt */ +#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_SHFT 0 +#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_MASK 0x0000000000000001 + +/* SH_EVENT_OCCURRED_RTC1_INT */ +/* Description: Pending RTC 1 Interrupt */ +#define SH_EVENT_OCCURRED_RTC1_INT_SHFT 24 +#define SH_EVENT_OCCURRED_RTC1_INT_MASK 0x0000000001000000 + +/* SH_EVENT_OCCURRED_RTC2_INT */ +/* Description: Pending RTC 2 Interrupt */ +#define SH_EVENT_OCCURRED_RTC2_INT_SHFT 25 +#define SH_EVENT_OCCURRED_RTC2_INT_MASK 0x0000000002000000 + +/* SH_EVENT_OCCURRED_RTC3_INT */ +/* Description: Pending RTC 3 Interrupt */ +#define SH_EVENT_OCCURRED_RTC3_INT_SHFT 26 +#define SH_EVENT_OCCURRED_RTC3_INT_MASK 0x0000000004000000 + +/* ==================================================================== */ +/* Register "SH_INT_CMPB" */ +/* RTC Compare Value for Processor B */ +/* ==================================================================== */ + +#define SH_INT_CMPB 0x00000001101b0080 +#define SH_INT_CMPB_MASK 0x007fffffffffffff +#define SH_INT_CMPB_INIT 0x0000000000000000 + +/* SH_INT_CMPB_REAL_TIME_CMPB */ +/* Description: Real Time Clock Compare */ +#define SH_INT_CMPB_REAL_TIME_CMPB_SHFT 0 +#define SH_INT_CMPB_REAL_TIME_CMPB_MASK 0x007fffffffffffff + +/* ==================================================================== */ +/* Register "SH_INT_CMPC" */ +/* RTC Compare Value for Processor C */ +/* ==================================================================== */ + +#define SH_INT_CMPC 0x00000001101b0100 +#define SH_INT_CMPC_MASK 0x007fffffffffffff +#define SH_INT_CMPC_INIT 0x0000000000000000 + +/* SH_INT_CMPC_REAL_TIME_CMPC */ +/* Description: Real Time Clock Compare */ +#define SH_INT_CMPC_REAL_TIME_CMPC_SHFT 0 +#define SH_INT_CMPC_REAL_TIME_CMPC_MASK 0x007fffffffffffff + +/* ==================================================================== */ +/* Register "SH_INT_CMPD" */ +/* RTC Compare Value for Processor D */ +/* ==================================================================== */ + +#define SH_INT_CMPD 0x00000001101b0180 +#define SH_INT_CMPD_MASK 0x007fffffffffffff +#define SH_INT_CMPD_INIT 0x0000000000000000 + +/* SH_INT_CMPD_REAL_TIME_CMPD */ +/* Description: Real Time Clock Compare */ +#define SH_INT_CMPD_REAL_TIME_CMPD_SHFT 0 +#define SH_INT_CMPD_REAL_TIME_CMPD_MASK 0x007fffffffffffff + #endif /* _ASM_IA64_SN_SHUB_MMR_H */ diff --git a/include/asm-m32r/hardirq.h b/include/asm-m32r/hardirq.h index b46a265d683a..78cb4c96d1e3 100644 --- a/include/asm-m32r/hardirq.h +++ b/include/asm-m32r/hardirq.h @@ -13,34 +13,12 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-23 are the hardirq count (max # of hardirqs: 256) - * - * - ( bit 26 is the PREEMPT_ACTIVE flag. ) - * - * PREEMPT_MASK: 0x000000ff - * SOFTIRQ_MASK: 0x0000ff00 - * HARDIRQ_MASK: 0x00ff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 - #if NR_IRQS > 256 #define HARDIRQ_BITS 9 #else #define HARDIRQ_BITS 8 #endif -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - /* * The hardirq mask has to be large enough to have * space for potentially all IRQ sources in the system diff --git a/include/asm-m68k/hardirq.h b/include/asm-m68k/hardirq.h index c74ad7709210..5bc0577931f5 100644 --- a/include/asm-m68k/hardirq.h +++ b/include/asm-m68k/hardirq.h @@ -12,29 +12,8 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-23 are the hardirq count (max # of hardirqs: 256) - * - * - ( bit 26 is the PREEMPT_ACTIVE flag. ) - * - * PREEMPT_MASK: 0x000000ff - * HARDIRQ_MASK: 0x0000ff00 - * SOFTIRQ_MASK: 0x00ff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 8 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - /* * The hardirq mask has to be large enough to have * space for potentially all IRQ sources in the system diff --git a/include/asm-m68knommu/hardirq.h b/include/asm-m68knommu/hardirq.h index 840eac2812ae..79327f540b09 100644 --- a/include/asm-m68knommu/hardirq.h +++ b/include/asm-m68knommu/hardirq.h @@ -13,29 +13,8 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-23 are the hardirq count (max # of hardirqs: 256) - * - * - ( bit 26 is the PREEMPT_ACTIVE flag. ) - * - * PREEMPT_MASK: 0x000000ff - * HARDIRQ_MASK: 0x0000ff00 - * SOFTIRQ_MASK: 0x00ff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 8 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - /* * The hardirq mask has to be large enough to have * space for potentially all IRQ sources in the system diff --git a/include/asm-mips/hardirq.h b/include/asm-mips/hardirq.h index 7562703b44e2..47a0237ac136 100644 --- a/include/asm-mips/hardirq.h +++ b/include/asm-mips/hardirq.h @@ -20,29 +20,8 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-23 are the hardirq count (max # of hardirqs: 256) - * - * - ( bit 26 is the PREEMPT_ACTIVE flag. ) - * - * PREEMPT_MASK: 0x000000ff - * SOFTIRQ_MASK: 0x0000ff00 - * HARDIRQ_MASK: 0x00ff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 8 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - /* * The hardirq mask has to be large enough to have * space for potentially all IRQ sources in the system diff --git a/include/asm-parisc/hardirq.h b/include/asm-parisc/hardirq.h index 7ebdebbe539e..39f4698d6ecc 100644 --- a/include/asm-parisc/hardirq.h +++ b/include/asm-parisc/hardirq.h @@ -28,29 +28,8 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption counter. The bitmask has the - * following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-31 are the hardirq count (max # of hardirqs: 65536) - * - * - (bit 63 is the PREEMPT_ACTIVE flag---not currently implemented.) - * - * PREEMPT_MASK: 0x000000ff - * SOFTIRQ_MASK: 0x0000ff00 - * HARDIRQ_MASK: 0xffff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 16 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - /* * The hardirq mask has to be large enough to have space for potentially all IRQ sources * in the system nesting on a single CPU: diff --git a/include/asm-ppc/immap_cpm2.h b/include/asm-ppc/immap_cpm2.h index 4d5651534128..3c23d9cb47a6 100644 --- a/include/asm-ppc/immap_cpm2.h +++ b/include/asm-ppc/immap_cpm2.h @@ -133,7 +133,7 @@ typedef struct sys_int_timers { u8 res5[2]; u32 sit_pitc; u32 sit_pitr; - u8 res6[92]; + u8 res6[94]; u8 res7[390]; } sit_cpm2_t; diff --git a/include/asm-ppc/open_pic.h b/include/asm-ppc/open_pic.h index 289761f853a4..6d5130bbdbd5 100644 --- a/include/asm-ppc/open_pic.h +++ b/include/asm-ppc/open_pic.h @@ -36,6 +36,7 @@ extern struct hw_interrupt_type open_pic_ipi; extern u_int OpenPIC_NumInitSenses; extern u_char *OpenPIC_InitSenses; extern void* OpenPIC_Addr; +extern int epic_serial_mode; /* Exported functions */ extern void openpic_set_sources(int first_irq, int num_irqs, void *isr); diff --git a/include/asm-ppc/time.h b/include/asm-ppc/time.h index 73f4fcd5555b..ce09b47fa819 100644 --- a/include/asm-ppc/time.h +++ b/include/asm-ppc/time.h @@ -10,7 +10,8 @@ #define __ASM_TIME_H__ #include <linux/config.h> -#include <linux/mc146818rtc.h> +#include <linux/types.h> +#include <linux/rtc.h> #include <linux/threads.h> #include <asm/reg.h> diff --git a/include/asm-ppc64/iommu.h b/include/asm-ppc64/iommu.h index 406f8ae8e0ad..aea9a3b5f23f 100644 --- a/include/asm-ppc64/iommu.h +++ b/include/asm-ppc64/iommu.h @@ -110,22 +110,18 @@ struct scatterlist; extern void iommu_setup_pSeries(void); extern void iommu_setup_u3(void); -/* Creates table for an individual device node */ -/* XXX: This isn't generic, please name it accordingly or add - * some ppc_md. hooks for iommu implementations to do what they - * need to do. --BenH. - */ -extern void iommu_devnode_init(struct device_node *dn); - /* Frees table for an individual device node */ -/* XXX: This isn't generic, please name it accordingly or add - * some ppc_md. hooks for iommu implementations to do what they - * need to do. --BenH. - */ extern void iommu_free_table(struct device_node *dn); #endif /* CONFIG_PPC_MULTIPLATFORM */ +#ifdef CONFIG_PPC_PSERIES + +/* Creates table for an individual device node */ +extern void iommu_devnode_init_pSeries(struct device_node *dn); + +#endif /* CONFIG_PPC_PSERIES */ + #ifdef CONFIG_PPC_ISERIES /* Walks all buses and creates iommu tables */ @@ -136,7 +132,7 @@ extern void __init iommu_vio_init(void); struct iSeries_Device_Node; /* Creates table for an individual device node */ -extern void iommu_devnode_init(struct iSeries_Device_Node *dn); +extern void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn); #endif /* CONFIG_PPC_ISERIES */ diff --git a/include/asm-s390/hardirq.h b/include/asm-s390/hardirq.h index 363b0a89711a..05670c2149de 100644 --- a/include/asm-s390/hardirq.h +++ b/include/asm-s390/hardirq.h @@ -38,29 +38,8 @@ softirq_pending(unsigned int cpu) #define __ARCH_IRQ_STAT -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-23 are the hardirq count (max # of hardirqs: 256) - * - * - ( bit 26 is the PREEMPT_ACTIVE flag. ) - * - * PREEMPT_MASK: 0x000000ff - * SOFTIRQ_MASK: 0x0000ff00 - * HARDIRQ_MASK: 0x00ff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 8 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - extern void account_ticks(struct pt_regs *); #define __ARCH_HAS_DO_SOFTIRQ diff --git a/include/asm-sh/hardirq.h b/include/asm-sh/hardirq.h index 1d7135a7dcde..f63336a9b292 100644 --- a/include/asm-sh/hardirq.h +++ b/include/asm-sh/hardirq.h @@ -12,29 +12,8 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-23 are the hardirq count (max # of hardirqs: 256) - * - * - ( bit 26 is the PREEMPT_ACTIVE flag. ) - * - * PREEMPT_MASK: 0x000000ff - * SOFTIRQ_MASK: 0x0000ff00 - * HARDIRQ_MASK: 0x00ff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 8 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - /* * The hardirq mask has to be large enough to have * space for potentially all IRQ sources in the system diff --git a/include/asm-sparc/hardirq.h b/include/asm-sparc/hardirq.h index 548b44167a9d..a741114a7efb 100644 --- a/include/asm-sparc/hardirq.h +++ b/include/asm-sparc/hardirq.h @@ -19,29 +19,8 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-23 are the hardirq count (max # of hardirqs: 256) - * - * - ( bit 26 is the PREEMPT_ACTIVE flag. ) - * - * PREEMPT_MASK: 0x000000ff - * SOFTIRQ_MASK: 0x0000ff00 - * HARDIRQ_MASK: 0x00ff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 8 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - #define irq_enter() (preempt_count() += HARDIRQ_OFFSET) #define irq_exit() \ do { \ diff --git a/include/asm-sparc64/hardirq.h b/include/asm-sparc64/hardirq.h index ac63de550508..260db1e3d5dc 100644 --- a/include/asm-sparc64/hardirq.h +++ b/include/asm-sparc64/hardirq.h @@ -18,29 +18,8 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-23 are the hardirq count (max # of hardirqs: 256) - * - * - ( bit 26 is the PREEMPT_ACTIVE flag. ) - * - * PREEMPT_MASK: 0x000000ff - * SOFTIRQ_MASK: 0x0000ff00 - * HARDIRQ_MASK: 0x00ff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 8 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - #define irq_enter() (preempt_count() += HARDIRQ_OFFSET) #define irq_exit() \ do { \ diff --git a/include/asm-um/atomic.h b/include/asm-um/atomic.h index 5e297acc8da5..b683f1034d1e 100644 --- a/include/asm-um/atomic.h +++ b/include/asm-um/atomic.h @@ -1,6 +1,11 @@ #ifndef __UM_ATOMIC_H #define __UM_ATOMIC_H +/* The i386 atomic.h calls printk, but doesn't include kernel.h, so we + * include it here. + */ +#include "linux/kernel.h" + #include "asm/arch/atomic.h" #endif diff --git a/include/asm-um/current.h b/include/asm-um/current.h index 72a4cbd91483..8fd72f69ce65 100644 --- a/include/asm-um/current.h +++ b/include/asm-um/current.h @@ -8,18 +8,13 @@ #ifndef __ASSEMBLY__ -struct thread_info; - -#include "linux/config.h" #include "asm/page.h" +#include "linux/thread_info.h" -#define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \ - (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER)) - -#define current_thread \ - ({ int dummy; ((struct thread_info *) CURRENT_THREAD(dummy)); }) +#define current (current_thread_info()->task) -#define current (current_thread->task) +/*Backward compatibility - it's used inside arch/um.*/ +#define current_thread current_thread_info() #endif /* __ASSEMBLY__ */ diff --git a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h index fa39a3985394..ec58334fb2c7 100644 --- a/include/asm-um/processor-generic.h +++ b/include/asm-um/processor-generic.h @@ -25,6 +25,7 @@ struct thread_struct { unsigned long cr2; int err; unsigned long trap_no; + int singlestep_syscall; void *fault_addr; void *fault_catcher; struct task_struct *prev_sched; @@ -37,7 +38,6 @@ struct thread_struct { int extern_pid; int tracing; int switch_pipe[2]; - int singlestep_syscall; int vm_seq; } tt; #endif diff --git a/include/asm-um/ptrace-generic.h b/include/asm-um/ptrace-generic.h index 8c472ebbb540..a1bb25f8e85b 100644 --- a/include/asm-um/ptrace-generic.h +++ b/include/asm-um/ptrace-generic.h @@ -10,8 +10,6 @@ #include "linux/config.h" -#include "asm/current.h" - #define pt_regs pt_regs_subarch #define show_regs show_regs_subarch diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h index c52830772a33..6550ed4355c2 100644 --- a/include/asm-um/thread_info.h +++ b/include/asm-um/thread_info.h @@ -8,6 +8,7 @@ #ifndef __ASSEMBLY__ +#include <linux/config.h> #include <asm/processor.h> #include <asm/types.h> diff --git a/include/asm-v850/hardirq.h b/include/asm-v850/hardirq.h index 7493d6d48682..974fc08818c2 100644 --- a/include/asm-v850/hardirq.h +++ b/include/asm-v850/hardirq.h @@ -13,29 +13,8 @@ typedef struct { #include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */ -/* - * We put the hardirq and softirq counter into the preemption - * counter. The bitmask has the following meaning: - * - * - bits 0-7 are the preemption count (max preemption depth: 256) - * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-23 are the hardirq count (max # of hardirqs: 256) - * - * - ( bit 26 is the PREEMPT_ACTIVE flag. ) - * - * PREEMPT_MASK: 0x000000ff - * HARDIRQ_MASK: 0x0000ff00 - * SOFTIRQ_MASK: 0x00ff0000 - */ - -#define PREEMPT_BITS 8 -#define SOFTIRQ_BITS 8 #define HARDIRQ_BITS 8 -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) - /* * The hardirq mask has to be large enough to have * space for potentially all IRQ sources in the system diff --git a/include/asm-x86_64/kdebug.h b/include/asm-x86_64/kdebug.h index f0de26738ba0..6277f75cbb4b 100644 --- a/include/asm-x86_64/kdebug.h +++ b/include/asm-x86_64/kdebug.h @@ -16,8 +16,8 @@ struct die_args { /* Note - you should never unregister because that can race with NMIs. If you really want to do it first unregister - then synchronize_kernel - then free. */ +int register_die_notifier(struct notifier_block *nb); extern struct notifier_block *die_chain; - /* Grossly misnamed. */ enum die_val { DIE_OOPS = 1, @@ -32,6 +32,7 @@ enum die_val { DIE_GPF, DIE_CALL, DIE_NMI_IPI, + DIE_PAGE_FAULT, }; static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig) diff --git a/include/asm-x86_64/kprobes.h b/include/asm-x86_64/kprobes.h new file mode 100644 index 000000000000..3f82412bce5c --- /dev/null +++ b/include/asm-x86_64/kprobes.h @@ -0,0 +1,61 @@ +#ifndef _ASM_KPROBES_H +#define _ASM_KPROBES_H +/* + * Kernel Probes (KProbes) + * include/asm-x86_64/kprobes.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 02111-1307, USA. + * + * Copyright (C) IBM Corporation, 2002, 2004 + * + * 2004-Oct Prasanna S Panchamukhi <prasanna@in.ibm.com> and Jim Keniston + * kenistoj@us.ibm.com adopted from i386. + */ +#include <linux/types.h> +#include <linux/ptrace.h> + +struct pt_regs; + +typedef u8 kprobe_opcode_t; +#define BREAKPOINT_INSTRUCTION 0xcc +#define MAX_INSN_SIZE 15 +#define MAX_STACK_SIZE 64 +#define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \ + (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) \ + ? (MAX_STACK_SIZE) \ + : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) + +/* Architecture specific copy of original instruction*/ +struct arch_specific_insn { + /* copy of the original instruction */ + kprobe_opcode_t *insn; +}; + +/* trap3/1 are intr gates for kprobes. So, restore the status of IF, + * if necessary, before executing the original int3/1 (trap) handler. + */ +static inline void restore_interrupts(struct pt_regs *regs) +{ + if (regs->eflags & IF_MASK) + local_irq_enable(); +} + +extern int post_kprobe_handler(struct pt_regs *regs); +extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); +extern int kprobe_handler(struct pt_regs *regs); + +extern int kprobe_exceptions_notify(struct notifier_block *self, + unsigned long val, void *data); +#endif /* _ASM_KPROBES_H */ diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h index 7099c89e1014..0fc76da585f5 100644 --- a/include/asm-x86_64/processor.h +++ b/include/asm-x86_64/processor.h @@ -164,6 +164,10 @@ static inline void clear_in_cr4 (unsigned long mask) #define MCA_bus__is_a_macro +/* + * User space process size: 512GB - 1GB (default). + */ +#define TASK_SIZE (0x0000007fc0000000UL) /* This decides where the kernel will search for a free chunk of vm * space during mmap's. @@ -174,14 +178,6 @@ static inline void clear_in_cr4 (unsigned long mask) #define TASK_UNMAPPED_BASE \ (test_thread_flag(TIF_IA32) ? TASK_UNMAPPED_32 : TASK_UNMAPPED_64) - -/* - * User space process size: 512GB - 1GB (default). - */ -#define TASK_SIZE_64 (0x0000007fc0000000UL) - -#define TASK_SIZE (test_thread_flag(TIF_IA32) ? IA32_PAGE_OFFSET : TASK_SIZE_64) - /* * Size of io_bitmap. */ @@ -465,8 +461,6 @@ static inline void __mwait(unsigned long eax, unsigned long ecx) #define cache_line_size() (boot_cpu_data.x86_cache_alignment) -#define HAVE_ARCH_PICK_MMAP_LAYOUT - extern unsigned long boot_option_idle_override; #endif /* __ASM_X86_64_PROCESSOR_H */ diff --git a/include/linux/ata.h b/include/linux/ata.h index 52c5fc6bb4ac..b6d8e8681603 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -24,6 +24,8 @@ #ifndef __LINUX_ATA_H__ #define __LINUX_ATA_H__ +#include <linux/types.h> + /* defines only for the constants which don't work well as enums */ #define ATA_DMA_BOUNDARY 0xffffUL #define ATA_DMA_MASK 0xffffffffULL @@ -33,8 +35,6 @@ enum { ATA_MAX_DEVICES = 2, /* per bus/port */ ATA_MAX_PRD = 256, /* we could make these 256/256 */ ATA_SECT_SIZE = 512, - ATA_SECT_SIZE_MASK = (ATA_SECT_SIZE - 1), - ATA_SECT_DWORDS = ATA_SECT_SIZE / sizeof(u32), ATA_ID_WORDS = 256, ATA_ID_PROD_OFS = 27, @@ -142,6 +142,10 @@ enum { XFER_PIO_2 = 0x0A, XFER_PIO_1 = 0x09, XFER_PIO_0 = 0x08, + XFER_SW_DMA_2 = 0x12, + XFER_SW_DMA_1 = 0x11, + XFER_SW_DMA_0 = 0x10, + XFER_PIO_SLOW = 0x00, /* ATAPI stuff */ ATAPI_PKT_DMA = (1 << 0), diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h index a9d099134bf2..c8c2cea10623 100644 --- a/include/linux/compat_ioctl.h +++ b/include/linux/compat_ioctl.h @@ -340,6 +340,11 @@ COMPATIBLE_IOCTL(PPPOEIOCSFWD) COMPATIBLE_IOCTL(PPPOEIOCDFWD) /* LP */ COMPATIBLE_IOCTL(LPGETSTATUS) +/* ppdev */ +COMPATIBLE_IOCTL(PPCLAIM) +COMPATIBLE_IOCTL(PPRELEASE) +COMPATIBLE_IOCTL(PPEXCL) +COMPATIBLE_IOCTL(PPYIELD) /* CDROM stuff */ COMPATIBLE_IOCTL(CDROMPAUSE) COMPATIBLE_IOCTL(CDROMRESUME) diff --git a/include/linux/crc-ccitt.h b/include/linux/crc-ccitt.h index f52696a1ff0d..90037617da8f 100644 --- a/include/linux/crc-ccitt.h +++ b/include/linux/crc-ccitt.h @@ -1,5 +1,6 @@ #ifndef _LINUX_CRC_CCITT_H #define _LINUX_CRC_CCITT_H +#ifdef __KERNEL__ #include <linux/types.h> @@ -12,4 +13,5 @@ static inline u16 crc_ccitt_byte(u16 crc, const u8 c) return (crc >> 8) ^ crc_ccitt_table[(crc ^ c) & 0xff]; } +#endif /* __KERNEL__ */ #endif /* _LINUX_CRC_CCITT_H */ diff --git a/include/linux/fb.h b/include/linux/fb.h index bd9e42e356d0..d8f4789dce45 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -685,7 +685,6 @@ struct fb_info { struct fb_fix_screeninfo fix; /* Current fix */ struct fb_monspecs monspecs; /* Current Monitor specs */ struct work_struct queue; /* Framebuffer event queue */ - struct timer_list cursor_timer; /* Cursor timer */ struct fb_pixmap pixmap; /* Image hardware mapper */ struct fb_pixmap sprite; /* Cursor hardware mapper */ struct fb_cmap cmap; /* Current cmap */ @@ -697,7 +696,6 @@ struct fb_info { #endif char __iomem *screen_base; /* Virtual address */ unsigned long screen_size; /* Amount of ioremapped VRAM or 0 */ - int currcon; /* Current VC. */ void *pseudo_palette; /* Fake palette of 16 colors */ #define FBINFO_STATE_RUNNING 0 #define FBINFO_STATE_SUSPENDED 1 diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 7969257bc87a..eae45cc3ea7a 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -5,39 +5,39 @@ #include <linux/smp_lock.h> #include <asm/hardirq.h> -#ifdef CONFIG_GENERIC_HARDIRQS /* * We put the hardirq and softirq counter into the preemption * counter. The bitmask has the following meaning: * * - bits 0-7 are the preemption count (max preemption depth: 256) * - bits 8-15 are the softirq count (max # of softirqs: 256) - * - bits 16-27 are the hardirq count (max # of hardirqs: 4096) * + * The hardirq count can be overridden per architecture, the default is: + * + * - bits 16-27 are the hardirq count (max # of hardirqs: 4096) * - ( bit 28 is the PREEMPT_ACTIVE flag. ) * * PREEMPT_MASK: 0x000000ff * SOFTIRQ_MASK: 0x0000ff00 * HARDIRQ_MASK: 0x0fff0000 */ - #define PREEMPT_BITS 8 #define SOFTIRQ_BITS 8 -#define HARDIRQ_BITS 12 - -#define PREEMPT_SHIFT 0 -#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) -#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) +#ifndef HARDIRQ_BITS +#define HARDIRQ_BITS 12 /* - * The hardirq mask has to be large enough to have - * space for potentially all IRQ sources in the system - * nesting on a single CPU: + * The hardirq mask has to be large enough to have space for potentially + * all IRQ sources in the system nesting on a single CPU. */ #if (1 << HARDIRQ_BITS) < NR_IRQS # error HARDIRQ_BITS is too low! #endif -#endif /* CONFIG_GENERIC_HARDIRQS */ +#endif + +#define PREEMPT_SHIFT 0 +#define SOFTIRQ_SHIFT (PREEMPT_SHIFT + PREEMPT_BITS) +#define HARDIRQ_SHIFT (SOFTIRQ_SHIFT + SOFTIRQ_BITS) #define __IRQ_MASK(x) ((1UL << (x))-1) diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h index 54ad63b1d02c..c94de12a5ee1 100644 --- a/include/linux/hdreg.h +++ b/include/linux/hdreg.h @@ -1,6 +1,8 @@ #ifndef _LINUX_HDREG_H #define _LINUX_HDREG_H +#include <linux/ata.h> + /* * This file contains some defines for the AT-hd-controller. * Various sources. @@ -328,27 +330,6 @@ typedef struct hd_drive_hob_hdr { /* WIN_SETFEATURES sub-commands */ #define SETFEATURES_EN_8BIT 0x01 /* Enable 8-Bit Transfers */ #define SETFEATURES_EN_WCACHE 0x02 /* Enable write cache */ -#define SETFEATURES_XFER 0x03 /* Set transfer mode */ -# define XFER_UDMA_7 0x47 /* 0100|0111 */ -# define XFER_UDMA_6 0x46 /* 0100|0110 */ -# define XFER_UDMA_5 0x45 /* 0100|0101 */ -# define XFER_UDMA_4 0x44 /* 0100|0100 */ -# define XFER_UDMA_3 0x43 /* 0100|0011 */ -# define XFER_UDMA_2 0x42 /* 0100|0010 */ -# define XFER_UDMA_1 0x41 /* 0100|0001 */ -# define XFER_UDMA_0 0x40 /* 0100|0000 */ -# define XFER_MW_DMA_2 0x22 /* 0010|0010 */ -# define XFER_MW_DMA_1 0x21 /* 0010|0001 */ -# define XFER_MW_DMA_0 0x20 /* 0010|0000 */ -# define XFER_SW_DMA_2 0x12 /* 0001|0010 */ -# define XFER_SW_DMA_1 0x11 /* 0001|0001 */ -# define XFER_SW_DMA_0 0x10 /* 0001|0000 */ -# define XFER_PIO_4 0x0C /* 0000|1100 */ -# define XFER_PIO_3 0x0B /* 0000|1011 */ -# define XFER_PIO_2 0x0A /* 0000|1010 */ -# define XFER_PIO_1 0x09 /* 0000|1001 */ -# define XFER_PIO_0 0x08 /* 0000|1000 */ -# define XFER_PIO_SLOW 0x00 /* 0000|0000 */ #define SETFEATURES_DIS_DEFECT 0x04 /* Disable Defect Management */ #define SETFEATURES_EN_APM 0x05 /* Enable advanced power management */ #define SETFEATURES_EN_SAME_R 0x22 /* for a region ATA-1 */ diff --git a/include/linux/ide.h b/include/linux/ide.h index 3d9bc0542b7d..ec81a19ec550 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -39,7 +39,6 @@ * * REALLY_SLOW_IO can be defined in ide.c and ide-cd.c, if necessary */ -#define REALLY_FAST_IO /* define if ide ports are perfect */ #define INITIAL_MULT_COUNT 0 /* off=0; on=2,4,8,16,32, etc.. */ #ifndef SUPPORT_SLOW_DATA_PORTS /* 1 to support slow data ports */ @@ -64,18 +63,6 @@ #define IDE_NO_IRQ (-1) /* - * IDE_DRIVE_CMD is used to implement many features of the hdparm utility - */ -#define IDE_DRIVE_CMD 99 /* (magic) undef to reduce kernel size*/ - -#define IDE_DRIVE_TASK 98 - -/* - * IDE_DRIVE_TASKFILE is used to implement many features needed for raw tasks - */ -#define IDE_DRIVE_TASKFILE 97 - -/* * "No user-serviceable parts" beyond this point :) *****************************************************************************/ @@ -101,13 +88,6 @@ typedef unsigned char byte; /* used everywhere */ #define DMA_PIO_RETRY 1 /* retrying in PIO */ -/* - * Ensure that various configuration flags have compatible settings - */ -#ifdef REALLY_SLOW_IO -#undef REALLY_FAST_IO -#endif - #define HWIF(drive) ((ide_hwif_t *)((drive)->hwif)) #define HWGROUP(drive) ((ide_hwgroup_t *)(HWIF(drive)->hwgroup)) @@ -197,10 +177,7 @@ typedef unsigned char byte; /* used everywhere */ /* * Some more useful definitions */ -#define IDE_MAJOR_NAME "hd" /* the same for all i/f; see also genhd.c */ -#define MAJOR_NAME IDE_MAJOR_NAME #define PARTN_BITS 6 /* number of minor dev bits for partitions */ -#define PARTN_MASK ((1<<PARTN_BITS)-1) /* a useful bit mask */ #define MAX_DRIVES 2 /* per interface; 2 assumed by lots of code */ #define SECTOR_SIZE 512 #define SECTOR_WORDS (SECTOR_SIZE / 4) /* number of 32bit words per sector */ @@ -256,16 +233,14 @@ typedef struct hw_regs_s { int irq; /* our irq number */ int dma; /* our dma entry */ ide_ack_intr_t *ack_intr; /* acknowledge interrupt */ - void *priv; /* interface specific data */ hwif_chipset_t chipset; - unsigned long sata_scr[SATA_NR_PORTS]; - unsigned long sata_misc[SATA_NR_PORTS]; } hw_regs_t; /* * Register new hardware with ide */ int ide_register_hw(hw_regs_t *hw, struct hwif_s **hwifp); +int ide_register_hw_with_fixup(hw_regs_t *, struct hwif_s **, void (*)(struct hwif_s *)); /* * Set up hw_regs_t structure before calling ide_register_hw (optional) @@ -1453,6 +1428,7 @@ typedef struct ide_pci_device_s { void (*init_iops)(ide_hwif_t *); void (*init_hwif)(ide_hwif_t *); void (*init_dma)(ide_hwif_t *, unsigned long); + void (*fixup)(ide_hwif_t *); u8 channels; u8 autodma; ide_pci_enablebit_t enablebits[2]; @@ -1513,6 +1489,9 @@ extern int ide_hwif_request_regions(ide_hwif_t *hwif); extern void ide_hwif_release_regions(ide_hwif_t* hwif); extern void ide_unregister (unsigned int index); +void ide_undecoded_slave(ide_hwif_t *); + +int probe_hwif_init_with_fixup(ide_hwif_t *, void (*)(ide_hwif_t *)); extern int probe_hwif_init(ide_hwif_t *); static inline void *ide_get_hwifdata (ide_hwif_t * hwif) diff --git a/include/linux/jbd.h b/include/linux/jbd.h index dfdd307872bb..3d9451b62e5a 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h @@ -352,27 +352,6 @@ static inline void jbd_unlock_bh_journal_head(struct buffer_head *bh) bit_spin_unlock(BH_JournalHead, &bh->b_state); } -#define HAVE_JOURNAL_CALLBACK_STATUS -/** - * struct journal_callback - Base structure for callback information. - * @jcb_list: list information for other callbacks attached to the same handle. - * @jcb_func: Function to call with this callback structure. - * - * This struct is a 'seed' structure for a using with your own callback - * structs. If you are using callbacks you must allocate one of these - * or another struct of your own definition which has this struct - * as it's first element and pass it to journal_callback_set(). - * - * This is used internally by jbd to maintain callback information. - * - * See journal_callback_set for more information. - **/ -struct journal_callback { - struct list_head jcb_list; /* t_jcb_lock */ - void (*jcb_func)(struct journal_callback *jcb, int error); - /* user data goes here */ -}; - struct jbd_revoke_table_s; /** @@ -381,7 +360,6 @@ struct jbd_revoke_table_s; * @h_transaction: Which compound transaction is this update a part of? * @h_buffer_credits: Number of remaining buffers we are allowed to dirty. * @h_ref: Reference count on this handle - * @h_jcb: List of application registered callbacks for this handle. * @h_err: Field for caller's use to track errors through large fs operations * @h_sync: flag for sync-on-close * @h_jdata: flag to force data journaling @@ -407,13 +385,6 @@ struct handle_s /* operations */ int h_err; - /* - * List of application registered callbacks for this handle. The - * function(s) will be called after the transaction that this handle is - * part of has been committed to disk. [t_jcb_lock] - */ - struct list_head h_jcb; - /* Flags [no locking] */ unsigned int h_sync: 1; /* sync-on-close */ unsigned int h_jdata: 1; /* force data journaling */ @@ -455,8 +426,6 @@ struct handle_s * j_state_lock * ->j_list_lock (journal_unmap_buffer) * - * t_handle_lock - * ->t_jcb_lock */ struct transaction_s @@ -580,15 +549,6 @@ struct transaction_s */ int t_handle_count; - /* - * Protects the callback list - */ - spinlock_t t_jcb_lock; - /* - * List of registered callback functions for this transaction. - * Called when the transaction is committed. [t_jcb_lock] - */ - struct list_head t_jcb; }; /** @@ -921,10 +881,6 @@ extern int journal_invalidatepage(journal_t *, extern int journal_try_to_free_buffers(journal_t *, struct page *, int); extern int journal_stop(handle_t *); extern int journal_flush (journal_t *); -extern void journal_callback_set(handle_t *handle, - void (*fn)(struct journal_callback *,int), - struct journal_callback *jcb); - extern void journal_lock_updates (journal_t *); extern void journal_unlock_updates (journal_t *); diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index 1a5dce8f9346..9bbd04092365 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h @@ -47,6 +47,16 @@ __attribute__((format(printf,1,2))); static inline void __check_printsym_format(const char *fmt, ...) { } +/* ia64 and ppc64 use function descriptors, which contain the real address */ +#if defined(CONFIG_IA64) || defined(CONFIG_PPC64) +#define print_fn_descriptor_symbol(fmt, addr) \ +do { \ + unsigned long *__faddr = (unsigned long*) addr; \ + print_symbol(fmt, __faddr[0]); \ +} while (0) +#else +#define print_fn_descriptor_symbol(fmt, addr) print_symbol(fmt, addr) +#endif #define print_symbol(fmt, addr) \ do { \ diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 172b7f421f72..3177a7ffe573 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -64,7 +64,7 @@ struct kprobe { kprobe_opcode_t opcode; /* copy of the original instruction */ - kprobe_opcode_t insn[MAX_INSN_SIZE]; + struct arch_specific_insn ainsn; }; /* @@ -94,7 +94,8 @@ static inline int kprobe_running(void) return kprobe_cpu == smp_processor_id(); } -extern void arch_prepare_kprobe(struct kprobe *p); +extern int arch_prepare_kprobe(struct kprobe *p); +extern void arch_remove_kprobe(struct kprobe *p); extern void show_registers(struct pt_regs *regs); /* Get the kprobe at this addr (if any). Must have called lock_kprobes */ diff --git a/include/linux/meye.h b/include/linux/meye.h index dc2c12d64f7f..11ec45e9a132 100644 --- a/include/linux/meye.h +++ b/include/linux/meye.h @@ -1,4 +1,4 @@ -/* +/* * Motion Eye video4linux driver for Sony Vaio PictureBook * * Copyright (C) 2001-2003 Stelian Pop <stelian@popies.net> @@ -8,20 +8,20 @@ * Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com> * * Earlier work by Werner Almesberger, Paul `Rusty' Russell and Paul Mackerras. - * + * * Some parts borrowed from various video4linux drivers, especially * bttv-driver.c and zoran.c, see original files for credits. - * + * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -56,4 +56,11 @@ struct meye_params { /* get a jpeg compressed snapshot */ #define MEYEIOC_STILLJCAPT _IOR ('v', BASE_VIDIOCPRIVATE+5, int) +/* V4L2 private controls */ +#define V4L2_CID_AGC V4L2_CID_PRIVATE_BASE +#define V4L2_CID_SHARPNESS (V4L2_CID_PRIVATE_BASE + 1) +#define V4L2_CID_PICTURE (V4L2_CID_PRIVATE_BASE + 2) +#define V4L2_CID_JPEGQUAL (V4L2_CID_PRIVATE_BASE + 3) +#define V4L2_CID_FRAMERATE (V4L2_CID_PRIVATE_BASE + 4) + #endif diff --git a/include/linux/parport_pc.h b/include/linux/parport_pc.h index 2b5ad1bf19a2..0682cb927170 100644 --- a/include/linux/parport_pc.h +++ b/include/linux/parport_pc.h @@ -43,6 +43,23 @@ struct parport_pc_private { struct parport *port; }; +struct parport_pc_via_data +{ + /* ISA PnP IRQ routing register 1 */ + u8 via_pci_parport_irq_reg; + /* ISA PnP DMA request routing register */ + u8 via_pci_parport_dma_reg; + /* Register and value to enable SuperIO configuration access */ + u8 via_pci_superio_config_reg; + u8 via_pci_superio_config_data; + /* SuperIO function register number */ + u8 viacfg_function; + /* parallel port control register number */ + u8 viacfg_parport_control; + /* Parallel port base address register */ + u8 viacfg_parport_base; +}; + static __inline__ void parport_pc_write_data(struct parport *p, unsigned char d) { #ifdef DEBUG_PARPORT diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index ba4c3255ccf7..14b0b41e5ecc 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -227,7 +227,7 @@ extern struct proc_dir_entry proc_root; #endif /* CONFIG_PROC_FS */ -#if !defined(CONFIG_PROC_FS) +#if !defined(CONFIG_PROC_KCORE) static inline void kclist_add(struct kcore_list *new, void *addr, size_t size) { } diff --git a/include/linux/random.h b/include/linux/random.h index 068875bf9601..4aaffb57349d 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -44,8 +44,6 @@ struct rand_pool_info { extern void rand_initialize_irq(int irq); -extern void batch_entropy_store(u32 a, u32 b, int num); - extern void add_keyboard_randomness(unsigned char scancode); extern void add_mouse_randomness(__u32 mouse_data); extern void add_interrupt_randomness(int irq); diff --git a/include/linux/sched.h b/include/linux/sched.h index 5d4ebb202ea6..0c8262c6d6b8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1105,6 +1105,12 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm) extern long sched_setaffinity(pid_t pid, cpumask_t new_mask); extern long sched_getaffinity(pid_t pid, cpumask_t *mask); +#ifdef CONFIG_MAGIC_SYSRQ + +extern void normalize_rt_tasks(void); + +#endif + #endif /* __KERNEL__ */ #endif diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index a01972bb5c52..bba805dd7a39 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -91,6 +91,9 @@ /* MPC52xx type numbers */ #define PORT_MPC52xx 59 +/*IBM icom*/ +#define PORT_ICOM 60 + #ifdef __KERNEL__ #include <linux/config.h> diff --git a/include/linux/smb_fs.h b/include/linux/smb_fs.h index c776bcd95b7a..c4153120ade6 100644 --- a/include/linux/smb_fs.h +++ b/include/linux/smb_fs.h @@ -12,7 +12,6 @@ #include <linux/smb.h> #include <linux/smb_fs_i.h> #include <linux/smb_fs_sb.h> -#include <linux/fs.h> /* * ioctl commands @@ -26,6 +25,7 @@ #ifdef __KERNEL__ +#include <linux/fs.h> #include <linux/pagemap.h> #include <linux/vmalloc.h> #include <linux/smb_mount.h> diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h index 7fe8012f79f9..94cbe97bd8e6 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h @@ -31,49 +31,8 @@ struct sysrq_key_op { void handle_sysrq(int, struct pt_regs *, struct tty_struct *); void __handle_sysrq(int, struct pt_regs *, struct tty_struct *); - -/* - * Sysrq registration manipulation functions - */ - -void __sysrq_lock_table (void); -void __sysrq_unlock_table (void); -struct sysrq_key_op *__sysrq_get_key_op (int key); -void __sysrq_put_key_op (int key, struct sysrq_key_op *op_p); - -extern __inline__ int -__sysrq_swap_key_ops_nolock(int key, struct sysrq_key_op *insert_op_p, - struct sysrq_key_op *remove_op_p) -{ - int retval; - if (__sysrq_get_key_op(key) == remove_op_p) { - __sysrq_put_key_op(key, insert_op_p); - retval = 0; - } else { - retval = -1; - } - return retval; -} - -extern __inline__ int -__sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p, - struct sysrq_key_op *remove_op_p) { - int retval; - __sysrq_lock_table(); - retval = __sysrq_swap_key_ops_nolock(key, insert_op_p, remove_op_p); - __sysrq_unlock_table(); - return retval; -} - -static inline int register_sysrq_key(int key, struct sysrq_key_op *op_p) -{ - return __sysrq_swap_key_ops(key, op_p, NULL); -} - -static inline int unregister_sysrq_key(int key, struct sysrq_key_op *op_p) -{ - return __sysrq_swap_key_ops(key, NULL, op_p); -} +int register_sysrq_key(int, struct sysrq_key_op *); +int unregister_sysrq_key(int, struct sysrq_key_op *); #else diff --git a/include/linux/via.h b/include/linux/via.h new file mode 100644 index 000000000000..86ae3bcdb2ba --- /dev/null +++ b/include/linux/via.h @@ -0,0 +1,22 @@ +/* Miscellaneous definitions for VIA chipsets + Currently used only by drivers/parport/parport_pc.c */ + +/* Values for SuperIO function select configuration register */ +#define VIA_FUNCTION_PARPORT_SPP 0x00 +#define VIA_FUNCTION_PARPORT_ECP 0x01 +#define VIA_FUNCTION_PARPORT_EPP 0x02 +#define VIA_FUNCTION_PARPORT_DISABLE 0x03 +#define VIA_FUNCTION_PROBE 0xFF /* Special magic value to be used in code, not to be written into chip */ + +/* Bits for parallel port mode configuration register */ +#define VIA_PARPORT_ECPEPP 0X20 +#define VIA_PARPORT_BIDIR 0x80 + +/* VIA configuration registers */ +#define VIA_CONFIG_INDEX 0x3F0 +#define VIA_CONFIG_DATA 0x3F1 + +/* Mask for parallel port IRQ bits (in ISA PnP IRQ routing register 1) */ +#define VIA_IRQCONTROL_PARALLEL 0xF0 +/* Mask for parallel port DMA bits (in ISA PnP DMA routing register) */ +#define VIA_DMACONTROL_PARALLEL 0x0C diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index fda602c77144..819e211f60be 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -16,6 +16,7 @@ #ifdef __KERNEL__ #include <linux/time.h> /* need struct timeval */ #endif +#include <linux/compiler.h> /* need __user */ /* * M I S C E L L A N E O U S diff --git a/include/net/act_api.h b/include/net/act_api.h index fa7f529ba804..ea9c442c1a55 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -99,7 +99,6 @@ extern int tcf_act_police(struct sk_buff **skb, struct tc_action *a); #endif /* CONFIG_NET_CLS_ACT */ extern int tcf_police(struct sk_buff *skb, struct tcf_police *p); -extern int qdisc_copy_stats(struct sk_buff *skb, struct tc_stats *st, spinlock_t *lock); extern void tcf_police_destroy(struct tcf_police *p); extern struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est); extern int tcf_police_dump(struct sk_buff *skb, struct tcf_police *p); diff --git a/include/net/dn_nsp.h b/include/net/dn_nsp.h index 646dea8a7dea..6bbeafa73e8b 100644 --- a/include/net/dn_nsp.h +++ b/include/net/dn_nsp.h @@ -37,7 +37,7 @@ extern int dn_nsp_rx(struct sk_buff *); extern int dn_nsp_backlog_rcv(struct sock *sk, struct sk_buff *skb); extern struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri); -extern struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int noblock, int *err); +extern struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int noblock, long timeo, int *err); #define NSP_REASON_OK 0 /* No error */ #define NSP_REASON_NR 1 /* No resources */ diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 1fdba82386b5..2ad20e79a4a3 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -222,9 +222,6 @@ extern void qdisc_reset(struct Qdisc *qdisc); extern void qdisc_destroy(struct Qdisc *qdisc); extern struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops); -extern int qdisc_new_estimator(struct tc_stats *stats, spinlock_t *stats_lock, - struct rtattr *opt); -extern void qdisc_kill_estimator(struct tc_stats *stats); extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *tab); extern void qdisc_put_rtab(struct qdisc_rate_table *tab); diff --git a/init/main.c b/init/main.c index 4b20c9303bd4..ecc39fafe51c 100644 --- a/init/main.c +++ b/init/main.c @@ -604,7 +604,7 @@ static void __init do_initcalls(void) if (initcall_debug) { printk(KERN_DEBUG "Calling initcall 0x%p", *call); - print_symbol(": %s()", (unsigned long) *call); + print_fn_descriptor_symbol(": %s()", (unsigned long) *call); printk("\n"); } diff --git a/kernel/kprobes.c b/kernel/kprobes.c index ca4e28b4c6a7..d3d1321b0e5c 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -84,10 +84,13 @@ int register_kprobe(struct kprobe *p) ret = -EEXIST; goto out; } + + if ((ret = arch_prepare_kprobe(p)) != 0) { + goto out; + } hlist_add_head(&p->hlist, &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); - arch_prepare_kprobe(p); p->opcode = *p->addr; *p->addr = BREAKPOINT_INSTRUCTION; flush_icache_range((unsigned long) p->addr, @@ -101,6 +104,7 @@ void unregister_kprobe(struct kprobe *p) { unsigned long flags; spin_lock_irqsave(&kprobe_lock, flags); + arch_remove_kprobe(p); *p->addr = p->opcode; hlist_del(&p->hlist); flush_icache_range((unsigned long) p->addr, diff --git a/kernel/module.c b/kernel/module.c index 07cb91d8f761..0798443ce002 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -576,6 +576,8 @@ sys_delete_module(const char __user *name_user, unsigned int flags) /* Stop the machine so refcounts can't move and disable module. */ ret = try_stop_module(mod, flags, &forced); + if (ret != 0) + goto out; /* Never wait if forced. */ if (!forced && module_refcount(mod) != 0) diff --git a/kernel/panic.c b/kernel/panic.c index 97918d4ff44f..3f93784a4207 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -42,7 +42,7 @@ static long no_blink(long time) } /* Returns how long it waited in ms */ -long (*panic_blink)(long time) = no_blink; +long (*panic_blink)(long time); EXPORT_SYMBOL(panic_blink); /** @@ -75,7 +75,10 @@ NORET_TYPE void panic(const char * fmt, ...) smp_send_stop(); #endif - notifier_call_chain(&panic_notifier_list, 0, buf); + notifier_call_chain(&panic_notifier_list, 0, buf); + + if (!panic_blink) + panic_blink = no_blink; if (panic_timeout > 0) { diff --git a/kernel/sched.c b/kernel/sched.c index 76d8d418eae3..595348452a06 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4607,3 +4607,35 @@ void __might_sleep(char *file, int line) } EXPORT_SYMBOL(__might_sleep); #endif + +#ifdef CONFIG_MAGIC_SYSRQ +void normalize_rt_tasks(void) +{ + struct task_struct *p; + prio_array_t *array; + unsigned long flags; + runqueue_t *rq; + + read_lock_irq(&tasklist_lock); + for_each_process (p) { + if (!rt_task(p)) + continue; + + rq = task_rq_lock(p, &flags); + + array = p->array; + if (array) + deactivate_task(p, task_rq(p)); + __setscheduler(p, SCHED_NORMAL, 0); + if (array) { + __activate_task(p, task_rq(p)); + resched_task(rq->curr); + } + + task_rq_unlock(rq, &flags); + } + read_unlock_irq(&tasklist_lock); +} + +EXPORT_SYMBOL(normalize_rt_tasks); +#endif /* CONFIG_MAGIC_SYSRQ */ diff --git a/kernel/time.c b/kernel/time.c index 7909444c466a..b6d01cf709c4 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -487,8 +487,6 @@ int do_settimeofday (struct timespec *tv) return 0; } -EXPORT_SYMBOL(do_settimeofday); - void do_gettimeofday (struct timeval *tv) { unsigned long seq, nsec, usec, sec, offset; diff --git a/mm/bootmem.c b/mm/bootmem.c index 092d85176490..5e2dce496fb0 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -343,31 +343,29 @@ unsigned long __init free_all_bootmem_node (pg_data_t *pgdat) return(free_all_bootmem_core(pgdat)); } -#ifndef CONFIG_DISCONTIGMEM unsigned long __init init_bootmem (unsigned long start, unsigned long pages) { max_low_pfn = pages; min_low_pfn = start; - return(init_bootmem_core(&contig_page_data, start, 0, pages)); + return(init_bootmem_core(NODE_DATA(0), start, 0, pages)); } #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE void __init reserve_bootmem (unsigned long addr, unsigned long size) { - reserve_bootmem_core(contig_page_data.bdata, addr, size); + reserve_bootmem_core(NODE_DATA(0)->bdata, addr, size); } #endif /* !CONFIG_HAVE_ARCH_BOOTMEM_NODE */ void __init free_bootmem (unsigned long addr, unsigned long size) { - free_bootmem_core(contig_page_data.bdata, addr, size); + free_bootmem_core(NODE_DATA(0)->bdata, addr, size); } unsigned long __init free_all_bootmem (void) { - return(free_all_bootmem_core(&contig_page_data)); + return(free_all_bootmem_core(NODE_DATA(0))); } -#endif /* !CONFIG_DISCONTIGMEM */ void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal) { diff --git a/mm/filemap.c b/mm/filemap.c index ab211415faa1..3f169349c10f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -408,9 +408,7 @@ void fastcall unlock_page(struct page *page) smp_mb__after_clear_bit(); wake_up_page(page, PG_locked); } - EXPORT_SYMBOL(unlock_page); -EXPORT_SYMBOL(lock_page); /* * End writeback against a page. @@ -424,7 +422,6 @@ void end_page_writeback(struct page *page) smp_mb__after_clear_bit(); wake_up_page(page, PG_writeback); } - EXPORT_SYMBOL(end_page_writeback); /* diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 3d07ca3b170a..16c0787bb57a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1213,6 +1213,12 @@ static int __init find_next_best_node(int node, void *used_node_mask) if (test_bit(n, used_node_mask)) continue; + /* Use the local node if we haven't already */ + if (!test_bit(node, used_node_mask)) { + best_node = node; + break; + } + /* Use the distance array to find the distance */ val = node_distance(node, n); diff --git a/mm/prio_tree.c b/mm/prio_tree.c index 2a1d02f93320..3bd8d5a99dab 100644 --- a/mm/prio_tree.c +++ b/mm/prio_tree.c @@ -245,7 +245,7 @@ static struct prio_tree_node *prio_tree_insert(struct prio_tree_root *root, mask >>= 1; if (!mask) { - mask = 1UL << (root->index_bits - 1); + mask = 1UL << (BITS_PER_LONG - 1); size_flag = 1; } } @@ -334,7 +334,7 @@ static struct prio_tree_node *prio_tree_left(struct prio_tree_iter *iter, iter->mask = ULONG_MAX; } else { iter->size_level = 1; - iter->mask = 1UL << (iter->root->index_bits - 1); + iter->mask = 1UL << (BITS_PER_LONG - 1); } } return iter->cur; @@ -376,7 +376,7 @@ static struct prio_tree_node *prio_tree_right(struct prio_tree_iter *iter, iter->mask = ULONG_MAX; } else { iter->size_level = 1; - iter->mask = 1UL << (iter->root->index_bits - 1); + iter->mask = 1UL << (BITS_PER_LONG - 1); } } return iter->cur; diff --git a/mm/shmem.c b/mm/shmem.c index 5bebd17bd46d..142cb61c080b 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1986,6 +1986,8 @@ static int shmem_fill_super(struct super_block *sb, sbinfo->free_inodes = inodes; } sb->s_xattr = shmem_xattr_handlers; +#else + sb->s_flags |= MS_NOUSER; #endif sb->s_maxbytes = SHMEM_MAX_BYTES; diff --git a/net/core/neighbour.c b/net/core/neighbour.c index c722fa09459f..e46c304df3d9 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -59,7 +59,6 @@ static void neigh_app_notify(struct neighbour *n); static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev); void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev); -static int neigh_glbl_allocs; static struct neigh_table *neigh_tables; static struct file_operations neigh_stat_seq_fops; @@ -282,7 +281,6 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl) n->timer.data = (unsigned long)n; NEIGH_CACHE_STAT_INC(tbl, allocs); - neigh_glbl_allocs++; n->tbl = tbl; atomic_set(&n->refcnt, 1); n->dead = 1; @@ -612,7 +610,6 @@ void neigh_destroy(struct neighbour *neigh) NEIGH_PRINTK2("neigh %p is destroyed.\n", neigh); - neigh_glbl_allocs--; atomic_dec(&neigh->tbl->entries); kmem_cache_free(neigh->tbl->kmem_cachep, neigh); } diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index c08a80fd380d..2b615a719199 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -1723,7 +1723,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock, goto out; if (signal_pending(current)) { - rv = -ERESTARTSYS; + rv = sock_intr_errno(timeo); goto out; } @@ -1957,7 +1957,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock, goto out; if (signal_pending(current)) { - err = -ERESTARTSYS; + err = sock_intr_errno(timeo); goto out; } @@ -1992,7 +1992,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock, /* * Get a suitably sized skb. */ - skb = dn_alloc_send_skb(sk, &len, flags & MSG_DONTWAIT, &err); + skb = dn_alloc_send_skb(sk, &len, flags & MSG_DONTWAIT, timeo, &err); if (err) break; diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c index 0b4ef4940057..42abbf3f524f 100644 --- a/net/decnet/dn_nsp_out.c +++ b/net/decnet/dn_nsp_out.c @@ -141,7 +141,7 @@ struct sk_buff *dn_alloc_skb(struct sock *sk, int size, int pri) * whole size thats been asked for (plus 11 bytes of header). If this * fails, then we try for any size over 16 bytes for SOCK_STREAMS. */ -struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int noblock, int *err) +struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int noblock, long timeo, int *err) { int space; int len; @@ -151,7 +151,7 @@ struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int noblock, in while(skb == NULL) { if (signal_pending(current)) { - *err = ERESTARTSYS; + *err = sock_intr_errno(timeo); break; } diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 32e3cd4bc3b9..de85549feb7f 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -1676,7 +1676,7 @@ static struct dn_route *dn_rt_cache_get_first(struct seq_file *seq) rt = dn_rt_hash_table[s->bucket].chain; if (rt) break; - rcu_read_unlock(); + rcu_read_unlock_bh(); } return rt; } diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c index a54ef782f8b5..fc741925911a 100644 --- a/net/ipv4/netfilter/ip_conntrack_amanda.c +++ b/net/ipv4/netfilter/ip_conntrack_amanda.c @@ -49,7 +49,7 @@ static int help(struct sk_buff *skb, { struct ip_conntrack_expect *exp; struct ip_ct_amanda_expect *exp_amanda_info; - char *amp, *data, *data_limit, *tmp; + char *data, *data_limit, *tmp; unsigned int dataoff, i; u_int16_t port, len; @@ -70,11 +70,9 @@ static int help(struct sk_buff *skb, } LOCK_BH(&amanda_buffer_lock); - amp = skb_header_pointer(skb, dataoff, - skb->len - dataoff, amanda_buffer); - BUG_ON(amp == NULL); - data = amp; - data_limit = amp + skb->len - dataoff; + skb_copy_bits(skb, dataoff, amanda_buffer, skb->len - dataoff); + data = amanda_buffer; + data_limit = amanda_buffer + skb->len - dataoff; *data_limit = '\0'; /* Search for the CONNECT string */ @@ -110,7 +108,7 @@ static int help(struct sk_buff *skb, exp->mask.dst.u.tcp.port = 0xFFFF; exp_amanda_info = &exp->help.exp_amanda_info; - exp_amanda_info->offset = tmp - amp; + exp_amanda_info->offset = tmp - amanda_buffer; exp_amanda_info->port = port; exp_amanda_info->len = len; diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 51193e0f09a1..e5a54ae265cf 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1882,7 +1882,8 @@ int ip6_mc_add_src(struct inet6_dev *idev, struct in6_addr *pmca, int sfmode, if (err) { int j; - pmc->mca_sfcount[sfmode]--; + if (!delta) + pmc->mca_sfcount[sfmode]--; for (j=0; j<i; j++) (void) ip6_mc_del1_src(pmc, sfmode, &psfsrc[i]); } else if (isexclude != (pmc->mca_sfcount[MCAST_EXCLUDE] != 0)) { diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 76697614e3e9..194fe24e3236 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -424,10 +424,9 @@ retry: sk_for_each(osk, node, head) { if (nlk_sk(osk)->pid == pid) { /* Bind collision, search negative pid values. */ - if (pid > 0) - pid = rover; - else if (--pid > 0) - pid = -4097; + pid = rover--; + if (rover > -4097) + rover = -4097; netlink_table_ungrab(); goto retry; } diff --git a/net/sched/Makefile b/net/sched/Makefile index fad3a43a8939..0bd324914cfe 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -5,7 +5,6 @@ obj-y := sch_generic.o obj-$(CONFIG_NET_SCHED) += sch_api.o sch_fifo.o -obj-$(CONFIG_NET_ESTIMATOR) += estimator.o obj-$(CONFIG_NET_CLS) += cls_api.o obj-$(CONFIG_NET_CLS_ACT) += act_api.o obj-$(CONFIG_NET_ACT_POLICE) += police.o diff --git a/net/sched/gact.c b/net/sched/gact.c index 988f9b36a43c..20ee0ab0a162 100644 --- a/net/sched/gact.c +++ b/net/sched/gact.c @@ -203,9 +203,9 @@ tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) RTA_PUT(skb, TCA_GACT_PROB, sizeof (p_opt), &p_opt); } #endif - t.install = jiffies - p->tm.install; - t.lastuse = jiffies - p->tm.lastuse; - t.expires = p->tm.expires; + t.install = jiffies_to_clock_t(jiffies - p->tm.install); + t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse); + t.expires = jiffies_to_clock_t(p->tm.expires); RTA_PUT(skb, TCA_GACT_TM, sizeof (t), &t); return skb->len; diff --git a/net/sched/ipt.c b/net/sched/ipt.c index 7b3f9081feb5..860c7988e813 100644 --- a/net/sched/ipt.c +++ b/net/sched/ipt.c @@ -334,9 +334,9 @@ tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) RTA_PUT(skb, TCA_IPT_HOOK, 4, &p->hook); RTA_PUT(skb, TCA_IPT_CNT, sizeof(struct tc_cnt), &c); RTA_PUT(skb, TCA_IPT_TABLE, IFNAMSIZ, p->tname); - tm.install = jiffies - p->tm.install; - tm.lastuse = jiffies - p->tm.lastuse; - tm.expires = p->tm.expires; + tm.install = jiffies_to_clock_t(jiffies - p->tm.install); + tm.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse); + tm.expires = jiffies_to_clock_t(p->tm.expires); RTA_PUT(skb, TCA_IPT_TM, sizeof (tm), &tm); return skb->len; diff --git a/net/sched/mirred.c b/net/sched/mirred.c index d8ceefbb606d..6afd8199706e 100644 --- a/net/sched/mirred.c +++ b/net/sched/mirred.c @@ -138,8 +138,9 @@ tcf_mirred_init(struct rtattr *rta, struct rtattr *est, struct tc_action *a,int p->eaction = parm->eaction; if (parm->ifindex) { p->ifindex = parm->ifindex; + if (ovr) + dev_put(p->dev); p->dev = dev; - dev_hold(p->dev); } spin_unlock(&p->lock); } @@ -257,9 +258,9 @@ tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a,int bind, int ref) opt.ifindex = p->ifindex; DPRINTK(" tcf_mirred_dump index %d action %d eaction %d ifndex %d\n",p->index,p->action,p->eaction,p->ifindex); RTA_PUT(skb, TCA_MIRRED_PARMS, sizeof (opt), &opt); - t.install = jiffies - p->tm.install; - t.lastuse = jiffies - p->tm.lastuse; - t.expires = p->tm.expires; + t.install = jiffies_to_clock_t(jiffies - p->tm.install); + t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse); + t.expires = jiffies_to_clock_t(p->tm.expires); RTA_PUT(skb, TCA_MIRRED_TM, sizeof (t), &t); return skb->len; diff --git a/net/sched/pedit.c b/net/sched/pedit.c index bbe28664b1e9..805291378305 100644 --- a/net/sched/pedit.c +++ b/net/sched/pedit.c @@ -244,9 +244,9 @@ tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,int bind, int ref) #endif RTA_PUT(skb, TCA_PEDIT_PARMS, s, opt); - t.install = jiffies - p->tm.install; - t.lastuse = jiffies - p->tm.lastuse; - t.expires = p->tm.expires; + t.install = jiffies_to_clock_t(jiffies - p->tm.install); + t.lastuse = jiffies_to_clock_t(jiffies - p->tm.lastuse); + t.expires = jiffies_to_clock_t(p->tm.expires); RTA_PUT(skb, TCA_PEDIT_TM, sizeof (t), &t); return skb->len; diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index fee8da1a1c77..6059234b9bb6 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -451,11 +451,9 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) else sch->handle = handle; - /* enqueue is accessed locklessly - make sure it's visible - * before we set a netdevice's qdisc pointer to sch */ if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { qdisc_lock_tree(dev); - list_add_tail_rcu(&sch->list, &dev->qdisc_list); + list_add_tail(&sch->list, &dev->qdisc_list); qdisc_unlock_tree(dev); #ifdef CONFIG_NET_ESTIMATOR @@ -728,19 +726,6 @@ graft: return 0; } -int qdisc_copy_stats(struct sk_buff *skb, struct tc_stats *st, spinlock_t *lock) -{ - spin_lock_bh(lock); - RTA_PUT(skb, TCA_STATS, sizeof(struct tc_stats), st); - spin_unlock_bh(lock); - return 0; - -rtattr_failure: - spin_unlock_bh(lock); - return -1; -} - - static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, u32 pid, u32 seq, unsigned flags, int event) { @@ -1271,7 +1256,6 @@ static int __init pktsched_init(void) subsys_initcall(pktsched_init); -EXPORT_SYMBOL(qdisc_copy_stats); EXPORT_SYMBOL(qdisc_get_rtab); EXPORT_SYMBOL(qdisc_put_rtab); EXPORT_SYMBOL(register_qdisc); diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index c346f10a4f1a..fda8f7429c68 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -280,6 +280,7 @@ struct Qdisc noop_qdisc = { .dequeue = noop_dequeue, .flags = TCQ_F_BUILTIN, .ops = &noop_qdisc_ops, + .list = LIST_HEAD_INIT(noop_qdisc.list), }; struct Qdisc_ops noqueue_qdisc_ops = { @@ -298,6 +299,7 @@ struct Qdisc noqueue_qdisc = { .dequeue = noop_dequeue, .flags = TCQ_F_BUILTIN, .ops = &noqueue_qdisc_ops, + .list = LIST_HEAD_INIT(noqueue_qdisc.list), }; @@ -436,9 +438,6 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) dev_hold(dev); sch->stats_lock = &dev->queue_lock; atomic_set(&sch->refcnt, 1); - /* enqueue is accessed locklessly - make sure it's visible - * before we set a netdevice's qdisc pointer to sch */ - smp_wmb(); if (!ops->init || ops->init(sch, NULL) == 0) return sch; @@ -477,15 +476,15 @@ static void __qdisc_destroy(struct rcu_head *head) module_put(ops->owner); dev_put(qdisc->dev); - if (!(qdisc->flags&TCQ_F_BUILTIN)) - kfree((char *) qdisc - qdisc->padded); + kfree((char *) qdisc - qdisc->padded); } /* Under dev->queue_lock and BH! */ void qdisc_destroy(struct Qdisc *qdisc) { - if (!atomic_dec_and_test(&qdisc->refcnt)) + if (qdisc->flags & TCQ_F_BUILTIN || + !atomic_dec_and_test(&qdisc->refcnt)) return; list_del(&qdisc->list); call_rcu(&qdisc->q_rcu, __qdisc_destroy); @@ -519,7 +518,8 @@ void dev_activate(struct net_device *dev) } spin_lock_bh(&dev->queue_lock); - if ((dev->qdisc = dev->qdisc_sleeping) != &noqueue_qdisc) { + rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping); + if (dev->qdisc != &noqueue_qdisc) { dev->trans_start = jiffies; dev_watchdog_up(dev); } |
