diff --git a/[refs] b/[refs] index 66d95b89ed71..c75ecf4c1908 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 05814450070f13b671fc9dbf89477677aa0258cb +refs/heads/master: 0fec53a24a5e5f7ba68d891b68f568b6aeafaca6 diff --git a/trunk/CREDITS b/trunk/CREDITS index 8e577ce4abeb..521f00d1b549 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -3203,7 +3203,7 @@ N: Eugene Surovegin E: ebs@ebshome.net W: http://kernel.ebshome.net/ P: 1024D/AE5467F1 FF22 39F1 6728 89F6 6E6C 2365 7602 F33D AE54 67F1 -D: Embedded PowerPC 4xx: EMAC, I2C, PIC and random hacks/fixes +D: Embedded PowerPC 4xx: I2C, PIC and random hacks/fixes S: Sunnyvale, California 94085 S: USA diff --git a/trunk/Documentation/Changes b/trunk/Documentation/Changes index fe5ae0f55020..86b86399d61d 100644 --- a/trunk/Documentation/Changes +++ b/trunk/Documentation/Changes @@ -31,6 +31,8 @@ al espa Eine deutsche Version dieser Datei finden Sie unter . +Last updated: October 29th, 2002 + Chris Ricker (kaboom@gatech.edu or chris.ricker@genetics.utah.edu). Current Minimal Requirements @@ -46,7 +48,7 @@ necessary on all systems; obviously, if you don't have any ISDN hardware, for example, you probably needn't concern yourself with isdn4k-utils. -o Gnu C 3.2 # gcc --version +o Gnu C 2.95.3 # gcc --version o Gnu make 3.79.1 # make --version o binutils 2.12 # ld -v o util-linux 2.10o # fdformat --version @@ -72,7 +74,26 @@ GCC --- The gcc version requirements may vary depending on the type of CPU in your -computer. +computer. The next paragraph applies to users of x86 CPUs, but not +necessarily to users of other CPUs. Users of other CPUs should obtain +information about their gcc version requirements from another source. + +The recommended compiler for the kernel is gcc 2.95.x (x >= 3), and it +should be used when you need absolute stability. You may use gcc 3.0.x +instead if you wish, although it may cause problems. Later versions of gcc +have not received much testing for Linux kernel compilation, and there are +almost certainly bugs (mainly, but not exclusively, in the kernel) that +will need to be fixed in order to use these compilers. In any case, using +pgcc instead of plain gcc is just asking for trouble. + +The Red Hat gcc 2.96 compiler subtree can also be used to build this tree. +You should ensure you use gcc-2.96-74 or later. gcc-2.96-54 will not build +the kernel correctly. + +In addition, please pay attention to compiler optimization. Anything +greater than -O2 may not be wise. Similarly, if you choose to use gcc-2.95.x +or derivatives, be sure not to use -fstrict-aliasing (which, depending on +your version of gcc 2.95.x, may necessitate using -fno-strict-aliasing). Make ---- @@ -301,9 +322,9 @@ Getting updated software Kernel compilation ****************** -gcc ---- -o +gcc 2.95.3 +---------- +o Make ---- diff --git a/trunk/Documentation/CodingStyle b/trunk/Documentation/CodingStyle index ce780ef648f1..eb7db3c19227 100644 --- a/trunk/Documentation/CodingStyle +++ b/trunk/Documentation/CodingStyle @@ -344,7 +344,7 @@ Remember: if another thread can find your data structure, and you don't have a reference count on it, you almost certainly have a bug. - Chapter 11: Macros, Enums and RTL + Chapter 11: Macros, Enums, Inline functions and RTL Names of macros defining constants and labels in enums are capitalized. @@ -429,35 +429,7 @@ from void pointer to any other pointer type is guaranteed by the C programming language. - Chapter 14: The inline disease - -There appears to be a common misperception that gcc has a magic "make me -faster" speedup option called "inline". While the use of inlines can be -appropriate (for example as a means of replacing macros, see Chapter 11), it -very often is not. Abundant use of the inline keyword leads to a much bigger -kernel, which in turn slows the system as a whole down, due to a bigger -icache footprint for the CPU and simply because there is less memory -available for the pagecache. Just think about it; a pagecache miss causes a -disk seek, which easily takes 5 miliseconds. There are a LOT of cpu cycles -that can go into these 5 miliseconds. - -A reasonable rule of thumb is to not put inline at functions that have more -than 3 lines of code in them. An exception to this rule are the cases where -a parameter is known to be a compiletime constant, and as a result of this -constantness you *know* the compiler will be able to optimize most of your -function away at compile time. For a good example of this later case, see -the kmalloc() inline function. - -Often people argue that adding inline to functions that are static and used -only once is always a win since there is no space tradeoff. While this is -technically correct, gcc is capable of inlining these automatically without -help, and the maintenance issue of removing the inline when a second user -appears outweighs the potential value of the hint that tells gcc to do -something it would have done anyway. - - - - Chapter 15: References + Chapter 14: References The C Programming Language, Second Edition by Brian W. Kernighan and Dennis M. Ritchie. @@ -472,13 +444,10 @@ ISBN 0-201-61586-X. URL: http://cm.bell-labs.com/cm/cs/tpop/ GNU manuals - where in compliance with K&R and this text - for cpp, gcc, -gcc internals and indent, all available from http://www.gnu.org/manual/ +gcc internals and indent, all available from http://www.gnu.org WG14 is the international standardization working group for the programming -language C, URL: http://www.open-std.org/JTC1/SC22/WG14/ - -Kernel CodingStyle, by greg@kroah.com at OLS 2002: -http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ +language C, URL: http://std.dkuug.dk/JTC1/SC22/WG14/ -- -Last updated on 30 December 2005 by a community effort on LKML. +Last updated on 16 February 2004 by a community effort on LKML. diff --git a/trunk/Documentation/RCU/rcuref.txt b/trunk/Documentation/RCU/rcuref.txt index 3f60db41b2f0..a23fee66064d 100644 --- a/trunk/Documentation/RCU/rcuref.txt +++ b/trunk/Documentation/RCU/rcuref.txt @@ -1,67 +1,74 @@ -Refcounter design for elements of lists/arrays protected by RCU. +Refcounter framework for elements of lists/arrays protected by +RCU. Refcounting on elements of lists which are protected by traditional reader/writer spinlocks or semaphores are straight forward as in: -1. 2. -add() search_and_reference() -{ { - alloc_object read_lock(&list_lock); - ... search_for_element - atomic_set(&el->rc, 1); atomic_inc(&el->rc); - write_lock(&list_lock); ... - add_element read_unlock(&list_lock); - ... ... - write_unlock(&list_lock); } +1. 2. +add() search_and_reference() +{ { + alloc_object read_lock(&list_lock); + ... search_for_element + atomic_set(&el->rc, 1); atomic_inc(&el->rc); + write_lock(&list_lock); ... + add_element read_unlock(&list_lock); + ... ... + write_unlock(&list_lock); } } 3. 4. release_referenced() delete() { { - ... write_lock(&list_lock); - atomic_dec(&el->rc, relfunc) ... - ... delete_element -} write_unlock(&list_lock); - ... - if (atomic_dec_and_test(&el->rc)) - kfree(el); - ... + ... write_lock(&list_lock); + atomic_dec(&el->rc, relfunc) ... + ... delete_element +} write_unlock(&list_lock); + ... + if (atomic_dec_and_test(&el->rc)) + kfree(el); + ... } If this list/array is made lock free using rcu as in changing the write_lock in add() and delete() to spin_lock and changing read_lock -in search_and_reference to rcu_read_lock(), the atomic_get in +in search_and_reference to rcu_read_lock(), the rcuref_get in search_and_reference could potentially hold reference to an element which -has already been deleted from the list/array. atomic_inc_not_zero takes +has already been deleted from the list/array. rcuref_lf_get_rcu takes care of this scenario. search_and_reference should look as; 1. 2. add() search_and_reference() { { - alloc_object rcu_read_lock(); - ... search_for_element - atomic_set(&el->rc, 1); if (atomic_inc_not_zero(&el->rc)) { - write_lock(&list_lock); rcu_read_unlock(); - return FAIL; - add_element } - ... ... - write_unlock(&list_lock); rcu_read_unlock(); + alloc_object rcu_read_lock(); + ... search_for_element + atomic_set(&el->rc, 1); if (rcuref_inc_lf(&el->rc)) { + write_lock(&list_lock); rcu_read_unlock(); + return FAIL; + add_element } + ... ... + write_unlock(&list_lock); rcu_read_unlock(); } } 3. 4. release_referenced() delete() { { - ... write_lock(&list_lock); - atomic_dec(&el->rc, relfunc) ... - ... delete_element -} write_unlock(&list_lock); - ... - if (atomic_dec_and_test(&el->rc)) - call_rcu(&el->head, el_free); - ... + ... write_lock(&list_lock); + rcuref_dec(&el->rc, relfunc) ... + ... delete_element +} write_unlock(&list_lock); + ... + if (rcuref_dec_and_test(&el->rc)) + call_rcu(&el->head, el_free); + ... } Sometimes, reference to the element need to be obtained in the -update (write) stream. In such cases, atomic_inc_not_zero might be an -overkill since the spinlock serialising list updates are held. atomic_inc +update (write) stream. In such cases, rcuref_inc_lf might be an overkill +since the spinlock serialising list updates are held. rcuref_inc is to be used in such cases. - +For arches which do not have cmpxchg rcuref_inc_lf +api uses a hashed spinlock implementation and the same hashed spinlock +is acquired in all rcuref_xxx primitives to preserve atomicity. +Note: Use rcuref_inc api only if you need to use rcuref_inc_lf on the +refcounter atleast at one place. Mixing rcuref_inc and atomic_xxx api +might lead to races. rcuref_inc_lf() must be used in lockfree +RCU critical sections only. diff --git a/trunk/Documentation/SubmittingDrivers b/trunk/Documentation/SubmittingDrivers index dd311cff1cc3..c3cca924e94b 100644 --- a/trunk/Documentation/SubmittingDrivers +++ b/trunk/Documentation/SubmittingDrivers @@ -27,17 +27,18 @@ Who To Submit Drivers To ------------------------ Linux 2.0: - No new drivers are accepted for this kernel tree. + No new drivers are accepted for this kernel tree Linux 2.2: - No new drivers are accepted for this kernel tree. - -Linux 2.4: If the code area has a general maintainer then please submit it to the maintainer listed in MAINTAINERS in the kernel file. If the maintainer does not respond or you cannot find the appropriate - maintainer then please contact Marcelo Tosatti - . + maintainer then please contact the 2.2 kernel maintainer: + Marc-Christian Petersen . + +Linux 2.4: + The same rules apply as 2.2. The final contact point for Linux 2.4 + submissions is Marcelo Tosatti . Linux 2.6: The same rules apply as 2.4 except that you should follow linux-kernel @@ -52,7 +53,6 @@ Licensing: The code must be released to us under the of exclusive GPL licensing, and if you wish the driver to be useful to other communities such as BSD you may well wish to release under multiple licenses. - See accepted licenses at include/linux/module.h Copyright: The copyright owner must agree to use of GPL. It's best if the submitter and copyright owner @@ -143,13 +143,5 @@ KernelNewbies: http://kernelnewbies.org/ Linux USB project: - http://linux-usb.sourceforge.net/ - -How to NOT write kernel driver by arjanv@redhat.com - http://people.redhat.com/arjanv/olspaper.pdf - -Kernel Janitor: - http://janitor.kernelnewbies.org/ + http://sourceforge.net/projects/linux-usb/ --- -Last updated on 17 Nov 2005. diff --git a/trunk/Documentation/SubmittingPatches b/trunk/Documentation/SubmittingPatches index 6198e5ebcf65..1d47e6c09dc6 100644 --- a/trunk/Documentation/SubmittingPatches +++ b/trunk/Documentation/SubmittingPatches @@ -78,9 +78,7 @@ Randy Dunlap's patch scripts: http://www.xenotime.net/linux/scripts/patching-scripts-002.tar.gz Andrew Morton's patch scripts: -http://www.zip.com.au/~akpm/linux/patches/ -Instead of these scripts, quilt is the recommended patch management -tool (see above). +http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.20 @@ -99,7 +97,7 @@ need to split up your patch. See #3, next. 3) Separate your changes. -Separate _logical changes_ into a single patch file. +Separate each logical change into its own patch. For example, if your changes include both bug fixes and performance enhancements for a single driver, separate those changes into two @@ -114,10 +112,6 @@ If one patch depends on another patch in order for a change to be complete, that is OK. Simply note "this patch depends on patch X" in your patch description. -If you cannot condense your patch set into a smaller set of patches, -then only post say 15 or so at a time and wait for review and integration. - - 4) Select e-mail destination. @@ -130,10 +124,6 @@ your patch to the primary Linux kernel developer's mailing list, linux-kernel@vger.kernel.org. Most kernel developers monitor this e-mail list, and can comment on your changes. - -Do not send more than 15 patches at once to the vger mailing lists!!! - - Linus Torvalds is the final arbiter of all changes accepted into the Linux kernel. His e-mail address is . He gets a lot of e-mail, so typically you should do your best to -avoid- sending @@ -159,9 +149,6 @@ USB, framebuffer devices, the VFS, the SCSI subsystem, etc. See the MAINTAINERS file for a mailing list that relates specifically to your change. -Majordomo lists of VGER.KERNEL.ORG at: - - If changes affect userland-kernel interfaces, please send the MAN-PAGES maintainer (as listed in the MAINTAINERS file) a man-pages patch, or at least a notification of the change, @@ -386,14 +373,27 @@ a diffstat, to show what files have changed, and the number of inserted and deleted lines per file. A diffstat is especially useful on bigger patches. Other comments relevant only to the moment or the maintainer, not suitable for the permanent changelog, should also go here. -Use diffstat options "-p 1 -w 70" so that filenames are listed from the -top of the kernel source tree and don't use too much horizontal space -(easily fit in 80 columns, maybe with some indentation). See more details on the proper patch format in the following references. +13) More references for submitting patches + +Andrew Morton, "The perfect patch" (tpp). + + +Jeff Garzik, "Linux kernel patch submission format." + + +Greg KH, "How to piss off a kernel subsystem maintainer" + + +Kernel Documentation/CodingStyle + + +Linus Torvald's mail on the canonical patch format: + ----------------------------------- @@ -466,30 +466,3 @@ and 'extern __inline__'. Don't try to anticipate nebulous future cases which may or may not be useful: "Make it as simple as you can, and no simpler." - - ----------------------- -SECTION 3 - REFERENCES ----------------------- - -Andrew Morton, "The perfect patch" (tpp). - - -Jeff Garzik, "Linux kernel patch submission format." - - -Greg Kroah, "How to piss off a kernel subsystem maintainer". - - - - -NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people!. - - -Kernel Documentation/CodingStyle - - -Linus Torvald's mail on the canonical patch format: - --- -Last updated on 17 Nov 2005. diff --git a/trunk/Documentation/applying-patches.txt b/trunk/Documentation/applying-patches.txt index 05a08c2c1889..681e426e2482 100644 --- a/trunk/Documentation/applying-patches.txt +++ b/trunk/Documentation/applying-patches.txt @@ -2,8 +2,7 @@ Applying Patches To The Linux Kernel ------------------------------------ - Original by: Jesper Juhl, August 2005 - Last update: 2005-12-02 + (Written by Jesper Juhl, August 2005) @@ -119,7 +118,7 @@ wrong. When patch encounters a change that it can't fix up with fuzz it rejects it outright and leaves a file with a .rej extension (a reject file). You can -read this file to see exactly what change couldn't be applied, so you can +read this file to see exactely what change couldn't be applied, so you can go fix it up by hand if you wish. If you don't have any third party patches applied to your kernel source, but @@ -128,7 +127,7 @@ and have made no modifications yourself to the source files, then you should never see a fuzz or reject message from patch. If you do see such messages anyway, then there's a high risk that either your local source tree or the patch file is corrupted in some way. In that case you should probably try -re-downloading the patch and if things are still not OK then you'd be advised +redownloading the patch and if things are still not OK then you'd be advised to start with a fresh tree downloaded in full from kernel.org. Let's look a bit more at some of the messages patch can produce. @@ -181,11 +180,9 @@ wish to apply. Are there any alternatives to `patch'? --- - Yes there are alternatives. - - You can use the `interdiff' program (http://cyberelk.net/tim/patchutils/) to -generate a patch representing the differences between two patches and then -apply the result. + Yes there are alternatives. You can use the `interdiff' program +(http://cyberelk.net/tim/patchutils/) to generate a patch representing the +differences between two patches and then apply the result. This will let you move from something like 2.6.12.2 to 2.6.12.3 in a single step. The -z flag to interdiff will even let you feed it patches in gzip or bzip2 compressed form directly without the use of zcat or bzcat or manual @@ -200,7 +197,7 @@ do the additional steps since interdiff can get things wrong in some cases. Another alternative is `ketchup', which is a python script for automatic downloading and applying of patches (http://www.selenic.com/ketchup/). - Other nice tools are diffstat which shows a summary of changes made by a +Other nice tools are diffstat which shows a summary of changes made by a patch, lsdiff which displays a short listing of affected files in a patch file, along with (optionally) the line numbers of the start of each patch and grepdiff which displays a list of the files modified by a patch where @@ -261,7 +258,7 @@ $ patch -p1 -R < ../patch-2.6.11.1 # revert the 2.6.11.1 patch # source dir is now 2.6.11 $ patch -p1 < ../patch-2.6.12 # apply new 2.6.12 patch $ cd .. -$ mv linux-2.6.11.1 linux-2.6.12 # rename source dir +$ mv linux-2.6.11.1 inux-2.6.12 # rename source dir The 2.6.x.y kernels @@ -436,11 +433,7 @@ $ cd .. $ mv linux-2.6.12-mm1 linux-2.6.13-rc3-mm3 # rename the source dir -This concludes this list of explanations of the various kernel trees. -I hope you are now clear on how to apply the various patches and help testing -the kernel. - -Thank you's to Randy Dunlap, Rolf Eike Beer, Linus Torvalds, Bodo Eggert, -Johannes Stezenbach, Grant Coady, Pavel Machek and others that I may have -forgotten for their reviews and contributions to this document. +This concludes this list of explanations of the various kernel trees and I +hope you are now crystal clear on how to apply the various patches and help +testing the kernel. diff --git a/trunk/Documentation/block/stat.txt b/trunk/Documentation/block/stat.txt deleted file mode 100644 index 0dbc946de2ea..000000000000 --- a/trunk/Documentation/block/stat.txt +++ /dev/null @@ -1,82 +0,0 @@ -Block layer statistics in /sys/block//stat -=============================================== - -This file documents the contents of the /sys/block//stat file. - -The stat file provides several statistics about the state of block -device . - -Q. Why are there multiple statistics in a single file? Doesn't sysfs - normally contain a single value per file? -A. By having a single file, the kernel can guarantee that the statistics - represent a consistent snapshot of the state of the device. If the - statistics were exported as multiple files containing one statistic - each, it would be impossible to guarantee that a set of readings - represent a single point in time. - -The stat file consists of a single line of text containing 11 decimal -values separated by whitespace. The fields are summarized in the -following table, and described in more detail below. - -Name units description ----- ----- ----------- -read I/Os requests number of read I/Os processed -read merges requests number of read I/Os merged with in-queue I/O -read sectors sectors number of sectors read -read ticks milliseconds total wait time for read requests -write I/Os requests number of write I/Os processed -write merges requests number of write I/Os merged with in-queue I/O -write sectors sectors number of sectors written -write ticks milliseconds total wait time for write requests -in_flight requests number of I/Os currently in flight -io_ticks milliseconds total time this block device has been active -time_in_queue milliseconds total wait time for all requests - -read I/Os, write I/Os -===================== - -These values increment when an I/O request completes. - -read merges, write merges -========================= - -These values increment when an I/O request is merged with an -already-queued I/O request. - -read sectors, write sectors -=========================== - -These values count the number of sectors read from or written to this -block device. The "sectors" in question are the standard UNIX 512-byte -sectors, not any device- or filesystem-specific block size. The -counters are incremented when the I/O completes. - -read ticks, write ticks -======================= - -These values count the number of milliseconds that I/O requests have -waited on this block device. If there are multiple I/O requests waiting, -these values will increase at a rate greater than 1000/second; for -example, if 60 read requests wait for an average of 30 ms, the read_ticks -field will increase by 60*30 = 1800. - -in_flight -========= - -This value counts the number of I/O requests that have been issued to -the device driver but have not yet completed. It does not include I/O -requests that are in the queue but not yet issued to the device driver. - -io_ticks -======== - -This value counts the number of milliseconds during which the device has -had I/O requests queued. - -time_in_queue -============= - -This value counts the number of milliseconds that I/O requests have waited -on this block device. If there are multiple I/O requests waiting, this -value will increase as the product of the number of milliseconds times the -number of requests waiting (see "read ticks" above for an example). diff --git a/trunk/Documentation/cpu-hotplug.txt b/trunk/Documentation/cpu-hotplug.txt deleted file mode 100644 index 08c5d04f3086..000000000000 --- a/trunk/Documentation/cpu-hotplug.txt +++ /dev/null @@ -1,357 +0,0 @@ - CPU hotplug Support in Linux(tm) Kernel - - Maintainers: - CPU Hotplug Core: - Rusty Russell - Srivatsa Vaddagiri - i386: - Zwane Mwaikambo - ppc64: - Nathan Lynch - Joel Schopp - ia64/x86_64: - Ashok Raj - -Authors: Ashok Raj -Lots of feedback: Nathan Lynch , - Joel Schopp - -Introduction - -Modern advances in system architectures have introduced advanced error -reporting and correction capabilities in processors. CPU architectures permit -partitioning support, where compute resources of a single CPU could be made -available to virtual machine environments. There are couple OEMS that -support NUMA hardware which are hot pluggable as well, where physical -node insertion and removal require support for CPU hotplug. - -Such advances require CPUs available to a kernel to be removed either for -provisioning reasons, or for RAS purposes to keep an offending CPU off -system execution path. Hence the need for CPU hotplug support in the -Linux kernel. - -A more novel use of CPU-hotplug support is its use today in suspend -resume support for SMP. Dual-core and HT support makes even -a laptop run SMP kernels which didn't support these methods. SMP support -for suspend/resume is a work in progress. - -General Stuff about CPU Hotplug --------------------------------- - -Command Line Switches ---------------------- -maxcpus=n Restrict boot time cpus to n. Say if you have 4 cpus, using - maxcpus=2 will only boot 2. You can choose to bring the - other cpus later online, read FAQ's for more info. - -additional_cpus=n [x86_64 only] use this to limit hotpluggable cpus. - This option sets - cpu_possible_map = cpu_present_map + additional_cpus - -CPU maps and such ------------------ -[More on cpumaps and primitive to manipulate, please check -include/linux/cpumask.h that has more descriptive text.] - -cpu_possible_map: Bitmap of possible CPUs that can ever be available in the -system. This is used to allocate some boot time memory for per_cpu variables -that aren't designed to grow/shrink as CPUs are made available or removed. -Once set during boot time discovery phase, the map is static, i.e no bits -are added or removed anytime. Trimming it accurately for your system needs -upfront can save some boot time memory. See below for how we use heuristics -in x86_64 case to keep this under check. - -cpu_online_map: Bitmap of all CPUs currently online. Its set in __cpu_up() -after a cpu is available for kernel scheduling and ready to receive -interrupts from devices. Its cleared when a cpu is brought down using -__cpu_disable(), before which all OS services including interrupts are -migrated to another target CPU. - -cpu_present_map: Bitmap of CPUs currently present in the system. Not all -of them may be online. When physical hotplug is processed by the relevant -subsystem (e.g ACPI) can change and new bit either be added or removed -from the map depending on the event is hot-add/hot-remove. There are currently -no locking rules as of now. Typical usage is to init topology during boot, -at which time hotplug is disabled. - -You really dont need to manipulate any of the system cpu maps. They should -be read-only for most use. When setting up per-cpu resources almost always use -cpu_possible_map/for_each_cpu() to iterate. - -Never use anything other than cpumask_t to represent bitmap of CPUs. - -#include - -for_each_cpu - Iterate over cpu_possible_map -for_each_online_cpu - Iterate over cpu_online_map -for_each_present_cpu - Iterate over cpu_present_map -for_each_cpu_mask(x,mask) - Iterate over some random collection of cpu mask. - -#include -lock_cpu_hotplug() and unlock_cpu_hotplug(): - -The above calls are used to inhibit cpu hotplug operations. While holding the -cpucontrol mutex, cpu_online_map will not change. If you merely need to avoid -cpus going away, you could also use preempt_disable() and preempt_enable() -for those sections. Just remember the critical section cannot call any -function that can sleep or schedule this process away. The preempt_disable() -will work as long as stop_machine_run() is used to take a cpu down. - -CPU Hotplug - Frequently Asked Questions. - -Q: How to i enable my kernel to support CPU hotplug? -A: When doing make defconfig, Enable CPU hotplug support - - "Processor type and Features" -> Support for Hotpluggable CPUs - -Make sure that you have CONFIG_HOTPLUG, and CONFIG_SMP turned on as well. - -You would need to enable CONFIG_HOTPLUG_CPU for SMP suspend/resume support -as well. - -Q: What architectures support CPU hotplug? -A: As of 2.6.14, the following architectures support CPU hotplug. - -i386 (Intel), ppc, ppc64, parisc, s390, ia64 and x86_64 - -Q: How to test if hotplug is supported on the newly built kernel? -A: You should now notice an entry in sysfs. - -Check if sysfs is mounted, using the "mount" command. You should notice -an entry as shown below in the output. - -.... -none on /sys type sysfs (rw) -.... - -if this is not mounted, do the following. - -#mkdir /sysfs -#mount -t sysfs sys /sys - -now you should see entries for all present cpu, the following is an example -in a 8-way system. - -#pwd -#/sys/devices/system/cpu -#ls -l -total 0 -drwxr-xr-x 10 root root 0 Sep 19 07:44 . -drwxr-xr-x 13 root root 0 Sep 19 07:45 .. -drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu0 -drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu1 -drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu2 -drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu3 -drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu4 -drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu5 -drwxr-xr-x 3 root root 0 Sep 19 07:44 cpu6 -drwxr-xr-x 3 root root 0 Sep 19 07:48 cpu7 - -Under each directory you would find an "online" file which is the control -file to logically online/offline a processor. - -Q: Does hot-add/hot-remove refer to physical add/remove of cpus? -A: The usage of hot-add/remove may not be very consistently used in the code. -CONFIG_CPU_HOTPLUG enables logical online/offline capability in the kernel. -To support physical addition/removal, one would need some BIOS hooks and -the platform should have something like an attention button in PCI hotplug. -CONFIG_ACPI_HOTPLUG_CPU enables ACPI support for physical add/remove of CPUs. - -Q: How do i logically offline a CPU? -A: Do the following. - -#echo 0 > /sys/devices/system/cpu/cpuX/online - -once the logical offline is successful, check - -#cat /proc/interrupts - -you should now not see the CPU that you removed. Also online file will report -the state as 0 when a cpu if offline and 1 when its online. - -#To display the current cpu state. -#cat /sys/devices/system/cpu/cpuX/online - -Q: Why cant i remove CPU0 on some systems? -A: Some architectures may have some special dependency on a certain CPU. - -For e.g in IA64 platforms we have ability to sent platform interrupts to the -OS. a.k.a Corrected Platform Error Interrupts (CPEI). In current ACPI -specifications, we didn't have a way to change the target CPU. Hence if the -current ACPI version doesn't support such re-direction, we disable that CPU -by making it not-removable. - -In such cases you will also notice that the online file is missing under cpu0. - -Q: How do i find out if a particular CPU is not removable? -A: Depending on the implementation, some architectures may show this by the -absence of the "online" file. This is done if it can be determined ahead of -time that this CPU cannot be removed. - -In some situations, this can be a run time check, i.e if you try to remove the -last CPU, this will not be permitted. You can find such failures by -investigating the return value of the "echo" command. - -Q: What happens when a CPU is being logically offlined? -A: The following happen, listed in no particular order :-) - -- A notification is sent to in-kernel registered modules by sending an event - CPU_DOWN_PREPARE -- All process is migrated away from this outgoing CPU to a new CPU -- All interrupts targeted to this CPU is migrated to a new CPU -- timers/bottom half/task lets are also migrated to a new CPU -- Once all services are migrated, kernel calls an arch specific routine - __cpu_disable() to perform arch specific cleanup. -- Once this is successful, an event for successful cleanup is sent by an event - CPU_DEAD. - - "It is expected that each service cleans up when the CPU_DOWN_PREPARE - notifier is called, when CPU_DEAD is called its expected there is nothing - running on behalf of this CPU that was offlined" - -Q: If i have some kernel code that needs to be aware of CPU arrival and - departure, how to i arrange for proper notification? -A: This is what you would need in your kernel code to receive notifications. - - #include - static int __cpuinit foobar_cpu_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) - { - unsigned int cpu = (unsigned long)hcpu; - - switch (action) { - case CPU_ONLINE: - foobar_online_action(cpu); - break; - case CPU_DEAD: - foobar_dead_action(cpu); - break; - } - return NOTIFY_OK; - } - - static struct notifier_block foobar_cpu_notifer = - { - .notifier_call = foobar_cpu_callback, - }; - - -In your init function, - - register_cpu_notifier(&foobar_cpu_notifier); - -You can fail PREPARE notifiers if something doesn't work to prepare resources. -This will stop the activity and send a following CANCELED event back. - -CPU_DEAD should not be failed, its just a goodness indication, but bad -things will happen if a notifier in path sent a BAD notify code. - -Q: I don't see my action being called for all CPUs already up and running? -A: Yes, CPU notifiers are called only when new CPUs are on-lined or offlined. - If you need to perform some action for each cpu already in the system, then - - for_each_online_cpu(i) { - foobar_cpu_callback(&foobar_cpu_notifier, CPU_UP_PREPARE, i); - foobar_cpu_callback(&foobar-cpu_notifier, CPU_ONLINE, i); - } - -Q: If i would like to develop cpu hotplug support for a new architecture, - what do i need at a minimum? -A: The following are what is required for CPU hotplug infrastructure to work - correctly. - - - Make sure you have an entry in Kconfig to enable CONFIG_HOTPLUG_CPU - - __cpu_up() - Arch interface to bring up a CPU - - __cpu_disable() - Arch interface to shutdown a CPU, no more interrupts - can be handled by the kernel after the routine - returns. Including local APIC timers etc are - shutdown. - - __cpu_die() - This actually supposed to ensure death of the CPU. - Actually look at some example code in other arch - that implement CPU hotplug. The processor is taken - down from the idle() loop for that specific - architecture. __cpu_die() typically waits for some - per_cpu state to be set, to ensure the processor - dead routine is called to be sure positively. - -Q: I need to ensure that a particular cpu is not removed when there is some - work specific to this cpu is in progress. -A: First switch the current thread context to preferred cpu - - int my_func_on_cpu(int cpu) - { - cpumask_t saved_mask, new_mask = CPU_MASK_NONE; - int curr_cpu, err = 0; - - saved_mask = current->cpus_allowed; - cpu_set(cpu, new_mask); - err = set_cpus_allowed(current, new_mask); - - if (err) - return err; - - /* - * If we got scheduled out just after the return from - * set_cpus_allowed() before running the work, this ensures - * we stay locked. - */ - curr_cpu = get_cpu(); - - if (curr_cpu != cpu) { - err = -EAGAIN; - goto ret; - } else { - /* - * Do work : But cant sleep, since get_cpu() disables preempt - */ - } - ret: - put_cpu(); - set_cpus_allowed(current, saved_mask); - return err; - } - - -Q: How do we determine how many CPUs are available for hotplug. -A: There is no clear spec defined way from ACPI that can give us that - information today. Based on some input from Natalie of Unisys, - that the ACPI MADT (Multiple APIC Description Tables) marks those possible - CPUs in a system with disabled status. - - Andi implemented some simple heuristics that count the number of disabled - CPUs in MADT as hotpluggable CPUS. In the case there are no disabled CPUS - we assume 1/2 the number of CPUs currently present can be hotplugged. - - Caveat: Today's ACPI MADT can only provide 256 entries since the apicid field - in MADT is only 8 bits. - -User Space Notification - -Hotplug support for devices is common in Linux today. Its being used today to -support automatic configuration of network, usb and pci devices. A hotplug -event can be used to invoke an agent script to perform the configuration task. - -You can add /etc/hotplug/cpu.agent to handle hotplug notification user space -scripts. - - #!/bin/bash - # $Id: cpu.agent - # Kernel hotplug params include: - #ACTION=%s [online or offline] - #DEVPATH=%s - # - cd /etc/hotplug - . ./hotplug.functions - - case $ACTION in - online) - echo `date` ":cpu.agent" add cpu >> /tmp/hotplug.txt - ;; - offline) - echo `date` ":cpu.agent" remove cpu >>/tmp/hotplug.txt - ;; - *) - debug_mesg CPU $ACTION event not supported - exit 1 - ;; - esac diff --git a/trunk/Documentation/cpusets.txt b/trunk/Documentation/cpusets.txt index 9e49b1c35729..a09a8eb80665 100644 --- a/trunk/Documentation/cpusets.txt +++ b/trunk/Documentation/cpusets.txt @@ -14,10 +14,7 @@ CONTENTS: 1.1 What are cpusets ? 1.2 Why are cpusets needed ? 1.3 How are cpusets implemented ? - 1.4 What are exclusive cpusets ? - 1.5 What does notify_on_release do ? - 1.6 What is memory_pressure ? - 1.7 How do I use cpusets ? + 1.4 How do I use cpusets ? 2. Usage Examples and Syntax 2.1 Basic Usage 2.2 Adding/removing cpus @@ -52,6 +49,29 @@ its cpus_allowed vector, and the kernel page allocator will not allocate a page on a node that is not allowed in the requesting tasks mems_allowed vector. +If a cpuset is cpu or mem exclusive, no other cpuset, other than a direct +ancestor or descendent, may share any of the same CPUs or Memory Nodes. +A cpuset that is cpu exclusive has a sched domain associated with it. +The sched domain consists of all cpus in the current cpuset that are not +part of any exclusive child cpusets. +This ensures that the scheduler load balacing code only balances +against the cpus that are in the sched domain as defined above and not +all of the cpus in the system. This removes any overhead due to +load balancing code trying to pull tasks outside of the cpu exclusive +cpuset only to be prevented by the tasks' cpus_allowed mask. + +A cpuset that is mem_exclusive restricts kernel allocations for +page, buffer and other data commonly shared by the kernel across +multiple users. All cpusets, whether mem_exclusive or not, restrict +allocations of memory for user space. This enables configuring a +system so that several independent jobs can share common kernel +data, such as file system pages, while isolating each jobs user +allocation in its own cpuset. To do this, construct a large +mem_exclusive cpuset to hold all the jobs, and construct child, +non-mem_exclusive cpusets for each individual job. Only a small +amount of typical kernel memory, such as requests from interrupt +handlers, is allowed to be taken outside even a mem_exclusive cpuset. + User level code may create and destroy cpusets by name in the cpuset virtual file system, manage the attributes and permissions of these cpusets and which CPUs and Memory Nodes are assigned to each cpuset, @@ -172,15 +192,9 @@ containing the following files describing that cpuset: - cpus: list of CPUs in that cpuset - mems: list of Memory Nodes in that cpuset - - memory_migrate flag: if set, move pages to cpusets nodes - cpu_exclusive flag: is cpu placement exclusive? - mem_exclusive flag: is memory placement exclusive? - tasks: list of tasks (by pid) attached to that cpuset - - notify_on_release flag: run /sbin/cpuset_release_agent on exit? - - memory_pressure: measure of how much paging pressure in cpuset - -In addition, the root cpuset only has the following file: - - memory_pressure_enabled flag: compute memory_pressure? New cpusets are created using the mkdir system call or shell command. The properties of a cpuset, such as its flags, allowed @@ -214,108 +228,7 @@ exclusive cpuset. Also, the use of a Linux virtual file system (vfs) to represent the cpuset hierarchy provides for a familiar permission and name space for cpusets, with a minimum of additional kernel code. - -1.4 What are exclusive cpusets ? --------------------------------- - -If a cpuset is cpu or mem exclusive, no other cpuset, other than -a direct ancestor or descendent, may share any of the same CPUs or -Memory Nodes. - -A cpuset that is cpu_exclusive has a scheduler (sched) domain -associated with it. The sched domain consists of all CPUs in the -current cpuset that are not part of any exclusive child cpusets. -This ensures that the scheduler load balancing code only balances -against the CPUs that are in the sched domain as defined above and -not all of the CPUs in the system. This removes any overhead due to -load balancing code trying to pull tasks outside of the cpu_exclusive -cpuset only to be prevented by the tasks' cpus_allowed mask. - -A cpuset that is mem_exclusive restricts kernel allocations for -page, buffer and other data commonly shared by the kernel across -multiple users. All cpusets, whether mem_exclusive or not, restrict -allocations of memory for user space. This enables configuring a -system so that several independent jobs can share common kernel data, -such as file system pages, while isolating each jobs user allocation in -its own cpuset. To do this, construct a large mem_exclusive cpuset to -hold all the jobs, and construct child, non-mem_exclusive cpusets for -each individual job. Only a small amount of typical kernel memory, -such as requests from interrupt handlers, is allowed to be taken -outside even a mem_exclusive cpuset. - - -1.5 What does notify_on_release do ? ------------------------------------- - -If the notify_on_release flag is enabled (1) in a cpuset, then whenever -the last task in the cpuset leaves (exits or attaches to some other -cpuset) and the last child cpuset of that cpuset is removed, then -the kernel runs the command /sbin/cpuset_release_agent, supplying the -pathname (relative to the mount point of the cpuset file system) of the -abandoned cpuset. This enables automatic removal of abandoned cpusets. -The default value of notify_on_release in the root cpuset at system -boot is disabled (0). The default value of other cpusets at creation -is the current value of their parents notify_on_release setting. - - -1.6 What is memory_pressure ? ------------------------------ -The memory_pressure of a cpuset provides a simple per-cpuset metric -of the rate that the tasks in a cpuset are attempting to free up in -use memory on the nodes of the cpuset to satisfy additional memory -requests. - -This enables batch managers monitoring jobs running in dedicated -cpusets to efficiently detect what level of memory pressure that job -is causing. - -This is useful both on tightly managed systems running a wide mix of -submitted jobs, which may choose to terminate or re-prioritize jobs that -are trying to use more memory than allowed on the nodes assigned them, -and with tightly coupled, long running, massively parallel scientific -computing jobs that will dramatically fail to meet required performance -goals if they start to use more memory than allowed to them. - -This mechanism provides a very economical way for the batch manager -to monitor a cpuset for signs of memory pressure. It's up to the -batch manager or other user code to decide what to do about it and -take action. - -==> Unless this feature is enabled by writing "1" to the special file - /dev/cpuset/memory_pressure_enabled, the hook in the rebalance - code of __alloc_pages() for this metric reduces to simply noticing - that the cpuset_memory_pressure_enabled flag is zero. So only - systems that enable this feature will compute the metric. - -Why a per-cpuset, running average: - - Because this meter is per-cpuset, rather than per-task or mm, - the system load imposed by a batch scheduler monitoring this - metric is sharply reduced on large systems, because a scan of - the tasklist can be avoided on each set of queries. - - Because this meter is a running average, instead of an accumulating - counter, a batch scheduler can detect memory pressure with a - single read, instead of having to read and accumulate results - for a period of time. - - Because this meter is per-cpuset rather than per-task or mm, - the batch scheduler can obtain the key information, memory - pressure in a cpuset, with a single read, rather than having to - query and accumulate results over all the (dynamically changing) - set of tasks in the cpuset. - -A per-cpuset simple digital filter (requires a spinlock and 3 words -of data per-cpuset) is kept, and updated by any task attached to that -cpuset, if it enters the synchronous (direct) page reclaim code. - -A per-cpuset file provides an integer number representing the recent -(half-life of 10 seconds) rate of direct page reclaims caused by -the tasks in the cpuset, in units of reclaims attempted per second, -times 1000. - - -1.7 How do I use cpusets ? +1.4 How do I use cpusets ? -------------------------- In order to minimize the impact of cpusets on critical kernel @@ -364,30 +277,6 @@ rewritten to the 'tasks' file of its cpuset. This is done to avoid impacting the scheduler code in the kernel with a check for changes in a tasks processor placement. -Normally, once a page is allocated (given a physical page -of main memory) then that page stays on whatever node it -was allocated, so long as it remains allocated, even if the -cpusets memory placement policy 'mems' subsequently changes. -If the cpuset flag file 'memory_migrate' is set true, then when -tasks are attached to that cpuset, any pages that task had -allocated to it on nodes in its previous cpuset are migrated -to the tasks new cpuset. Depending on the implementation, -this migration may either be done by swapping the page out, -so that the next time the page is referenced, it will be paged -into the tasks new cpuset, usually on the node where it was -referenced, or this migration may be done by directly copying -the pages from the tasks previous cpuset to the new cpuset, -where possible to the same node, relative to the new cpuset, -as the node that held the page, relative to the old cpuset. -Also if 'memory_migrate' is set true, then if that cpusets -'mems' file is modified, pages allocated to tasks in that -cpuset, that were on nodes in the previous setting of 'mems', -will be moved to nodes in the new setting of 'mems.' Again, -depending on the implementation, this might be done by swapping, -or by direct copying. In either case, pages that were not in -the tasks prior cpuset, or in the cpusets prior 'mems' setting, -will not be moved. - There is an exception to the above. If hotplug functionality is used to remove all the CPUs that are currently assigned to a cpuset, then the kernel will automatically update the cpus_allowed of all diff --git a/trunk/Documentation/dvb/avermedia.txt b/trunk/Documentation/dvb/avermedia.txt index 068070ff13cd..2dc260b2b0a4 100644 --- a/trunk/Documentation/dvb/avermedia.txt +++ b/trunk/Documentation/dvb/avermedia.txt @@ -150,8 +150,7 @@ Getting the card going The frontend module sp887x.o, requires an external firmware. Please use the command "get_dvb_firmware sp887x" to download - it. Then copy it to /usr/lib/hotplug/firmware or /lib/firmware/ - (depending on configuration of firmware hotplug). + it. Then copy it to /usr/lib/hotplug/firmware. Receiving DVB-T in Australia diff --git a/trunk/Documentation/dvb/get_dvb_firmware b/trunk/Documentation/dvb/get_dvb_firmware index 75c28a174092..be6eb4c75991 100644 --- a/trunk/Documentation/dvb/get_dvb_firmware +++ b/trunk/Documentation/dvb/get_dvb_firmware @@ -23,7 +23,7 @@ use IO::Handle; @components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t", "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004", - "or51211", "or51132_qam", "or51132_vsb", "bluebird"); + "or51211", "or51132_qam", "or51132_vsb"); # Check args syntax() if (scalar(@ARGV) != 1); @@ -34,11 +34,7 @@ for ($i=0; $i < scalar(@components); $i++) { if ($cid eq $components[$i]) { $outfile = eval($cid); die $@ if $@; - print STDERR < "/tmp", CLEANUP => 1); checkstandard(); - + wgetfile($sourcefile, $url); unzip($sourcefile, $tmpdir); verify("$tmpdir/SkyNETU.sys", $hash); @@ -312,19 +308,6 @@ sub or51132_vsb { $fwfile; } -sub bluebird { - my $url = "http://www.linuxtv.org/download/dvb/firmware/dvb-usb-bluebird-01.fw"; - my $outfile = "dvb-usb-bluebird-01.fw"; - my $hash = "658397cb9eba9101af9031302671f49d"; - - checkstandard(); - - wgetfile($outfile, $url); - verify($outfile,$hash); - - $outfile; -} - # --------------------------------------------------------------- # Utilities diff --git a/trunk/Documentation/dvb/ttusb-dec.txt b/trunk/Documentation/dvb/ttusb-dec.txt index b2f271cd784b..5c1e984c26a7 100644 --- a/trunk/Documentation/dvb/ttusb-dec.txt +++ b/trunk/Documentation/dvb/ttusb-dec.txt @@ -41,5 +41,4 @@ Hotplug Firmware Loading for 2.6 kernels For 2.6 kernels the firmware is loaded at the point that the driver module is loaded. See linux/Documentation/dvb/firmware.txt for more information. -Copy the three files downloaded above into the /usr/lib/hotplug/firmware or -/lib/firmware directory (depending on configuration of firmware hotplug). +Copy the three files downloaded above into the /usr/lib/hotplug/firmware directory. diff --git a/trunk/Documentation/fb/cyblafb/bugs b/trunk/Documentation/fb/cyblafb/bugs index 9443a6d72cdd..f90cc66ea919 100644 --- a/trunk/Documentation/fb/cyblafb/bugs +++ b/trunk/Documentation/fb/cyblafb/bugs @@ -11,3 +11,4 @@ Untested features All LCD stuff is untested. If it worked in tridentfb, it should work in cyblafb. Please test and report the results to Knut_Petersen@t-online.de. + diff --git a/trunk/Documentation/fb/cyblafb/fb.modes b/trunk/Documentation/fb/cyblafb/fb.modes index fe0e5223ba86..cf4351fc32ff 100644 --- a/trunk/Documentation/fb/cyblafb/fb.modes +++ b/trunk/Documentation/fb/cyblafb/fb.modes @@ -14,141 +14,142 @@ # mode "640x480-50" - geometry 640 480 2048 4096 8 + geometry 640 480 640 3756 8 timings 47619 4294967256 24 17 0 216 3 endmode mode "640x480-60" - geometry 640 480 2048 4096 8 + geometry 640 480 640 3756 8 timings 39682 4294967256 24 17 0 216 3 endmode mode "640x480-70" - geometry 640 480 2048 4096 8 + geometry 640 480 640 3756 8 timings 34013 4294967256 24 17 0 216 3 endmode mode "640x480-72" - geometry 640 480 2048 4096 8 + geometry 640 480 640 3756 8 timings 33068 4294967256 24 17 0 216 3 endmode mode "640x480-75" - geometry 640 480 2048 4096 8 + geometry 640 480 640 3756 8 timings 31746 4294967256 24 17 0 216 3 endmode mode "640x480-80" - geometry 640 480 2048 4096 8 + geometry 640 480 640 3756 8 timings 29761 4294967256 24 17 0 216 3 endmode mode "640x480-85" - geometry 640 480 2048 4096 8 + geometry 640 480 640 3756 8 timings 28011 4294967256 24 17 0 216 3 endmode mode "800x600-50" - geometry 800 600 2048 4096 8 + geometry 800 600 800 3221 8 timings 30303 96 24 14 0 136 11 endmode mode "800x600-60" - geometry 800 600 2048 4096 8 + geometry 800 600 800 3221 8 timings 25252 96 24 14 0 136 11 endmode mode "800x600-70" - geometry 800 600 2048 4096 8 + geometry 800 600 800 3221 8 timings 21645 96 24 14 0 136 11 endmode mode "800x600-72" - geometry 800 600 2048 4096 8 + geometry 800 600 800 3221 8 timings 21043 96 24 14 0 136 11 endmode mode "800x600-75" - geometry 800 600 2048 4096 8 + geometry 800 600 800 3221 8 timings 20202 96 24 14 0 136 11 endmode mode "800x600-80" - geometry 800 600 2048 4096 8 + geometry 800 600 800 3221 8 timings 18939 96 24 14 0 136 11 endmode mode "800x600-85" - geometry 800 600 2048 4096 8 + geometry 800 600 800 3221 8 timings 17825 96 24 14 0 136 11 endmode mode "1024x768-50" - geometry 1024 768 2048 4096 8 + geometry 1024 768 1024 2815 8 timings 19054 144 24 29 0 120 3 endmode mode "1024x768-60" - geometry 1024 768 2048 4096 8 + geometry 1024 768 1024 2815 8 timings 15880 144 24 29 0 120 3 endmode mode "1024x768-70" - geometry 1024 768 2048 4096 8 + geometry 1024 768 1024 2815 8 timings 13610 144 24 29 0 120 3 endmode mode "1024x768-72" - geometry 1024 768 2048 4096 8 + geometry 1024 768 1024 2815 8 timings 13232 144 24 29 0 120 3 endmode mode "1024x768-75" - geometry 1024 768 2048 4096 8 + geometry 1024 768 1024 2815 8 timings 12703 144 24 29 0 120 3 endmode mode "1024x768-80" - geometry 1024 768 2048 4096 8 + geometry 1024 768 1024 2815 8 timings 11910 144 24 29 0 120 3 endmode mode "1024x768-85" - geometry 1024 768 2048 4096 8 + geometry 1024 768 1024 2815 8 timings 11209 144 24 29 0 120 3 endmode mode "1280x1024-50" - geometry 1280 1024 2048 4096 8 + geometry 1280 1024 1280 2662 8 timings 11114 232 16 39 0 160 3 endmode mode "1280x1024-60" - geometry 1280 1024 2048 4096 8 + geometry 1280 1024 1280 2662 8 timings 9262 232 16 39 0 160 3 endmode mode "1280x1024-70" - geometry 1280 1024 2048 4096 8 + geometry 1280 1024 1280 2662 8 timings 7939 232 16 39 0 160 3 endmode mode "1280x1024-72" - geometry 1280 1024 2048 4096 8 + geometry 1280 1024 1280 2662 8 timings 7719 232 16 39 0 160 3 endmode mode "1280x1024-75" - geometry 1280 1024 2048 4096 8 + geometry 1280 1024 1280 2662 8 timings 7410 232 16 39 0 160 3 endmode mode "1280x1024-80" - geometry 1280 1024 2048 4096 8 + geometry 1280 1024 1280 2662 8 timings 6946 232 16 39 0 160 3 endmode mode "1280x1024-85" - geometry 1280 1024 2048 4096 8 + geometry 1280 1024 1280 2662 8 timings 6538 232 16 39 0 160 3 endmode + diff --git a/trunk/Documentation/fb/cyblafb/performance b/trunk/Documentation/fb/cyblafb/performance index 8d15d5dfc6b3..eb4e47a9cea6 100644 --- a/trunk/Documentation/fb/cyblafb/performance +++ b/trunk/Documentation/fb/cyblafb/performance @@ -77,3 +77,4 @@ patch that speeds up kernel bitblitting a lot ( > 20%). | | | | | | | | | | +-----------+-----------------+-----------------+-----------------+ + diff --git a/trunk/Documentation/fb/cyblafb/todo b/trunk/Documentation/fb/cyblafb/todo index c5f6d0eae545..80fb2f89b6c1 100644 --- a/trunk/Documentation/fb/cyblafb/todo +++ b/trunk/Documentation/fb/cyblafb/todo @@ -22,10 +22,11 @@ accelerated color blitting Who needs it? The console driver does use color everything else is done using color expanding blitting of 1bpp character bitmaps. +xpanning Who needs it? + ioctls Who needs it? -TV-out Will be done later. Use "vga= " at boot time - to set a suitable video mode. +TV-out Will be done later ??? Feel free to contact me if you have any feature requests diff --git a/trunk/Documentation/fb/cyblafb/usage b/trunk/Documentation/fb/cyblafb/usage index a39bb3d402a2..e627c8f54211 100644 --- a/trunk/Documentation/fb/cyblafb/usage +++ b/trunk/Documentation/fb/cyblafb/usage @@ -40,16 +40,6 @@ Selecting Modes None of the modes possible to select as startup modes are affected by the problems described at the end of the next subsection. - For all startup modes cyblafb chooses a virtual x resolution of 2048, - the only exception is mode 1280x1024 in combination with 32 bpp. This - allows ywrap scrolling for all those modes if rotation is 0 or 2, and - also fast scrolling if rotation is 1 or 3. The default virtual y reso- - lution is 4096 for bpp == 8, 2048 for bpp==16 and 1024 for bpp == 32, - again with the only exception of 1280x1024 at 32 bpp. - - Please do set your video memory size to 8 Mb in the Bios setup. Other - values will work, but performace is decreased for a lot of modes. - Mode changes using fbset ======================== @@ -64,26 +54,20 @@ Selecting Modes - if a flat panel is found, cyblafb does not allow you to program a resolution higher than the physical resolution of the flat panel monitor + - cyblafb does not allow xres to differ from xres_virtual - cyblafb does not allow vclk to exceed 230 MHz. As 32 bpp and (currently) 24 bit modes use a doubled vclk internally, the dotclock limit as seen by fbset is 115 MHz for those modes and 230 MHz for 8 and 16 bpp modes. - - cyblafb will allow you to select very high resolutions as - long as the hardware can be programmed to these modes. The - documented limit 1600x1200 is not enforced, but don't expect - perfect signal quality. - Any request that violates the rules given above will be either changed - to something the hardware supports or an error value will be returned. + Any request that violates the rules given above will be ignored and + fbset will return an error. If you program a virtual y resolution higher than the hardware limit, cyblafb will silently decrease that value to the highest possible - value. The same is true for a virtual x resolution that is not - supported by the hardware. Cyblafb tries to adapt vyres first because - vxres decides if ywrap scrolling is possible or not. + value. - Attempts to disable acceleration are ignored, I believe that this is - safe. + Attempts to disable acceleration are ignored. Some video modes that should work do not work as expected. If you use the standard fb.modes, fbset 640x480-60 will program that mode, but @@ -145,6 +129,10 @@ mode 640x480 or 800x600 or 1024x768 or 1280x1024 verbosity 0 is the default, increase to at least 2 for every bug report! +vesafb allows cyblafb to be loaded after vesafb has been + loaded. See sections "Module unloading ...". + + Development hints ================= @@ -207,7 +195,7 @@ a graphics mode. After booting, load cyblafb without any mode and bpp parameter and assign cyblafb to individual ttys using con2fb, e.g.: - modprobe cyblafb + modprobe cyblafb vesafb=1 con2fb /dev/fb1 /dev/tty1 Unloading cyblafb works without problems after you assign vesafb to all @@ -215,3 +203,4 @@ ttys again, e.g.: con2fb /dev/fb0 /dev/tty1 rmmod cyblafb + diff --git a/trunk/Documentation/fb/cyblafb/whatsnew b/trunk/Documentation/fb/cyblafb/whatsnew deleted file mode 100644 index 76c07a26e044..000000000000 --- a/trunk/Documentation/fb/cyblafb/whatsnew +++ /dev/null @@ -1,29 +0,0 @@ -0.62 -==== - - - the vesafb parameter has been removed as I decided to allow the - feature without any special parameter. - - - Cyblafb does not use the vga style of panning any longer, now the - "right view" register in the graphics engine IO space is used. Without - that change it was impossible to use all available memory, and without - access to all available memory it is impossible to ywrap. - - - The imageblit function now uses hardware acceleration for all font - widths. Hardware blitting across pixel column 2048 is broken in the - cyberblade/i1 graphics core, but we work around that hardware bug. - - - modes with vxres != xres are supported now. - - - ywrap scrolling is supported now and the default. This is a big - performance gain. - - - default video modes use vyres > yres and vxres > xres to allow - almost optimal scrolling speed for normal and rotated screens - - - some features mainly usefull for debugging the upper layers of the - framebuffer system have been added, have a look at the code - - - fixed: Oops after unloading cyblafb when reading /proc/io* - - - we work around some bugs of the higher framebuffer layers. diff --git a/trunk/Documentation/filesystems/ext3.txt b/trunk/Documentation/filesystems/ext3.txt index 22e4040564d5..9840d5b8d5b9 100644 --- a/trunk/Documentation/filesystems/ext3.txt +++ b/trunk/Documentation/filesystems/ext3.txt @@ -22,11 +22,6 @@ journal=inum When a journal already exists, this option is the inode which will represent the ext3 file system's journal file. -journal_dev=devnum When the external journal device's major/minor numbers - have changed, this option allows to specify the new - journal location. The journal device is identified - through its new major/minor numbers encoded in devnum. - noload Don't load the journal on mounting. data=journal All data are committed into the journal prior diff --git a/trunk/Documentation/filesystems/proc.txt b/trunk/Documentation/filesystems/proc.txt index a4dcf42c2fd9..d4773565ea2f 100644 --- a/trunk/Documentation/filesystems/proc.txt +++ b/trunk/Documentation/filesystems/proc.txt @@ -1302,23 +1302,6 @@ VM has token based thrashing control mechanism and uses the token to prevent unnecessary page faults in thrashing situation. The unit of the value is second. The value would be useful to tune thrashing behavior. -drop_caches ------------ - -Writing to this will cause the kernel to drop clean caches, dentries and -inodes from memory, causing that memory to become free. - -To free pagecache: - echo 1 > /proc/sys/vm/drop_caches -To free dentries and inodes: - echo 2 > /proc/sys/vm/drop_caches -To free pagecache, dentries and inodes: - echo 3 > /proc/sys/vm/drop_caches - -As this is a non-destructive operation and dirty objects are not freeable, the -user should run `sync' first. - - 2.5 /proc/sys/dev - Device specific parameters ---------------------------------------------- diff --git a/trunk/Documentation/filesystems/ramfs-rootfs-initramfs.txt b/trunk/Documentation/filesystems/ramfs-rootfs-initramfs.txt index 60ab61e54e8a..b3404a032596 100644 --- a/trunk/Documentation/filesystems/ramfs-rootfs-initramfs.txt +++ b/trunk/Documentation/filesystems/ramfs-rootfs-initramfs.txt @@ -143,26 +143,12 @@ as the following example: dir /mnt 755 0 0 file /init initramfs/init.sh 755 0 0 -Run "usr/gen_init_cpio" (after the kernel build) to get a usage message -documenting the above file format. - One advantage of the text file is that root access is not required to set permissions or create device nodes in the new archive. (Note that those two example "file" entries expect to find files named "init.sh" and "busybox" in a directory called "initramfs", under the linux-2.6.* directory. See Documentation/early-userspace/README for more details.) -The kernel does not depend on external cpio tools, gen_init_cpio is created -from usr/gen_init_cpio.c which is entirely self-contained, and the kernel's -boot-time extractor is also (obviously) self-contained. However, if you _do_ -happen to have cpio installed, the following command line can extract the -generated cpio image back into its component files: - - cpio -i -d -H newc -F initramfs_data.cpio --no-absolute-filenames - -Contents of initramfs: ----------------------- - If you don't already understand what shared libraries, devices, and paths you need to get a minimal root filesystem up and running, here are some references: @@ -175,69 +161,13 @@ designed to be a tiny C library to statically link early userspace code against, along with some related utilities. It is BSD licensed. I use uClibc (http://www.uclibc.org) and busybox (http://www.busybox.net) -myself. These are LGPL and GPL, respectively. (A self-contained initramfs -package is planned for the busybox 1.2 release.) +myself. These are LGPL and GPL, respectively. In theory you could use glibc, but that's not well suited for small embedded uses like this. (A "hello world" program statically linked against glibc is over 400k. With uClibc it's 7k. Also note that glibc dlopens libnss to do name lookups, even when otherwise statically linked.) -Why cpio rather than tar? -------------------------- - -This decision was made back in December, 2001. The discussion started here: - - http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1538.html - -And spawned a second thread (specifically on tar vs cpio), starting here: - - http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1587.html - -The quick and dirty summary version (which is no substitute for reading -the above threads) is: - -1) cpio is a standard. It's decades old (from the AT&T days), and already - widely used on Linux (inside RPM, Red Hat's device driver disks). Here's - a Linux Journal article about it from 1996: - - http://www.linuxjournal.com/article/1213 - - It's not as popular as tar because the traditional cpio command line tools - require _truly_hideous_ command line arguments. But that says nothing - either way about the archive format, and there are alternative tools, - such as: - - http://freshmeat.net/projects/afio/ - -2) The cpio archive format chosen by the kernel is simpler and cleaner (and - thus easier to create and parse) than any of the (literally dozens of) - various tar archive formats. The complete initramfs archive format is - explained in buffer-format.txt, created in usr/gen_init_cpio.c, and - extracted in init/initramfs.c. All three together come to less than 26k - total of human-readable text. - -3) The GNU project standardizing on tar is approximately as relevant as - Windows standardizing on zip. Linux is not part of either, and is free - to make its own technical decisions. - -4) Since this is a kernel internal format, it could easily have been - something brand new. The kernel provides its own tools to create and - extract this format anyway. Using an existing standard was preferable, - but not essential. - -5) Al Viro made the decision (quote: "tar is ugly as hell and not going to be - supported on the kernel side"): - - http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1540.html - - explained his reasoning: - - http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1550.html - http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1638.html - - and, most importantly, designed and implemented the initramfs code. - Future directions: ------------------ diff --git a/trunk/Documentation/filesystems/relayfs.txt b/trunk/Documentation/filesystems/relayfs.txt index 5832377b7340..d803abed29f0 100644 --- a/trunk/Documentation/filesystems/relayfs.txt +++ b/trunk/Documentation/filesystems/relayfs.txt @@ -44,41 +44,30 @@ relayfs can operate in a mode where it will overwrite data not yet collected by userspace, and not wait for it to consume it. relayfs itself does not provide for communication of such data between -userspace and kernel, allowing the kernel side to remain simple and -not impose a single interface on userspace. It does provide a set of -examples and a separate helper though, described below. - -klog and relay-apps example code -================================ - -relayfs itself is ready to use, but to make things easier, a couple -simple utility functions and a set of examples are provided. - -The relay-apps example tarball, available on the relayfs sourceforge -site, contains a set of self-contained examples, each consisting of a -pair of .c files containing boilerplate code for each of the user and -kernel sides of a relayfs application; combined these two sets of -boilerplate code provide glue to easily stream data to disk, without -having to bother with mundane housekeeping chores. - -The 'klog debugging functions' patch (klog.patch in the relay-apps -tarball) provides a couple of high-level logging functions to the -kernel which allow writing formatted text or raw data to a channel, -regardless of whether a channel to write into exists or not, or -whether relayfs is compiled into the kernel or is configured as a -module. These functions allow you to put unconditional 'trace' -statements anywhere in the kernel or kernel modules; only when there -is a 'klog handler' registered will data actually be logged (see the -klog and kleak examples for details). - -It is of course possible to use relayfs from scratch i.e. without -using any of the relay-apps example code or klog, but you'll have to -implement communication between userspace and kernel, allowing both to -convey the state of buffers (full, empty, amount of padding). - -klog and the relay-apps examples can be found in the relay-apps -tarball on http://relayfs.sourceforge.net +userspace and kernel, allowing the kernel side to remain simple and not +impose a single interface on userspace. It does provide a separate +helper though, described below. +klog, relay-app & librelay +========================== + +relayfs itself is ready to use, but to make things easier, two +additional systems are provided. klog is a simple wrapper to make +writing formatted text or raw data to a channel simpler, regardless of +whether a channel to write into exists or not, or whether relayfs is +compiled into the kernel or is configured as a module. relay-app is +the kernel counterpart of userspace librelay.c, combined these two +files provide glue to easily stream data to disk, without having to +bother with housekeeping. klog and relay-app can be used together, +with klog providing high-level logging functions to the kernel and +relay-app taking care of kernel-user control and disk-logging chores. + +It is possible to use relayfs without relay-app & librelay, but you'll +have to implement communication between userspace and kernel, allowing +both to convey the state of buffers (full, empty, amount of padding). + +klog, relay-app and librelay can be found in the relay-apps tarball on +http://relayfs.sourceforge.net The relayfs user space API ========================== @@ -136,8 +125,6 @@ Here's a summary of the API relayfs provides to in-kernel clients: relay_reset(chan) relayfs_create_dir(name, parent) relayfs_remove_dir(dentry) - relayfs_create_file(name, parent, mode, fops, data) - relayfs_remove_file(dentry) channel management typically called on instigation of userspace: @@ -154,8 +141,6 @@ Here's a summary of the API relayfs provides to in-kernel clients: subbuf_start(buf, subbuf, prev_subbuf, prev_padding) buf_mapped(buf, filp) buf_unmapped(buf, filp) - create_buf_file(filename, parent, mode, buf, is_global) - remove_buf_file(dentry) helper functions: @@ -335,71 +320,6 @@ forces a sub-buffer switch on all the channel buffers, and can be used to finalize and process the last sub-buffers before the channel is closed. -Creating non-relay files ------------------------- - -relay_open() automatically creates files in the relayfs filesystem to -represent the per-cpu kernel buffers; it's often useful for -applications to be able to create their own files alongside the relay -files in the relayfs filesystem as well e.g. 'control' files much like -those created in /proc or debugfs for similar purposes, used to -communicate control information between the kernel and user sides of a -relayfs application. For this purpose the relayfs_create_file() and -relayfs_remove_file() API functions exist. For relayfs_create_file(), -the caller passes in a set of user-defined file operations to be used -for the file and an optional void * to a user-specified data item, -which will be accessible via inode->u.generic_ip (see the relay-apps -tarball for examples). The file_operations are a required parameter -to relayfs_create_file() and thus the semantics of these files are -completely defined by the caller. - -See the relay-apps tarball at http://relayfs.sourceforge.net for -examples of how these non-relay files are meant to be used. - -Creating relay files in other filesystems ------------------------------------------ - -By default of course, relay_open() creates relay files in the relayfs -filesystem. Because relay_file_operations is exported, however, it's -also possible to create and use relay files in other pseudo-filesytems -such as debugfs. - -For this purpose, two callback functions are provided, -create_buf_file() and remove_buf_file(). create_buf_file() is called -once for each per-cpu buffer from relay_open() to allow the client to -create a file to be used to represent the corresponding buffer; if -this callback is not defined, the default implementation will create -and return a file in the relayfs filesystem to represent the buffer. -The callback should return the dentry of the file created to represent -the relay buffer. Note that the parent directory passed to -relay_open() (and passed along to the callback), if specified, must -exist in the same filesystem the new relay file is created in. If -create_buf_file() is defined, remove_buf_file() must also be defined; -it's responsible for deleting the file(s) created in create_buf_file() -and is called during relay_close(). - -The create_buf_file() implementation can also be defined in such a way -as to allow the creation of a single 'global' buffer instead of the -default per-cpu set. This can be useful for applications interested -mainly in seeing the relative ordering of system-wide events without -the need to bother with saving explicit timestamps for the purpose of -merging/sorting per-cpu files in a postprocessing step. - -To have relay_open() create a global buffer, the create_buf_file() -implementation should set the value of the is_global outparam to a -non-zero value in addition to creating the file that will be used to -represent the single buffer. In the case of a global buffer, -create_buf_file() and remove_buf_file() will be called only once. The -normal channel-writing functions e.g. relay_write() can still be used -- writes from any cpu will transparently end up in the global buffer - -but since it is a global buffer, callers should make sure they use the -proper locking for such a buffer, either by wrapping writes in a -spinlock, or by copying a write function from relayfs_fs.h and -creating a local version that internally does the proper locking. - -See the 'exported-relayfile' examples in the relay-apps tarball for -examples of creating and using relay files in debugfs. - Misc ---- diff --git a/trunk/Documentation/filesystems/spufs.txt b/trunk/Documentation/filesystems/spufs.txt deleted file mode 100644 index 8edc3952eff4..000000000000 --- a/trunk/Documentation/filesystems/spufs.txt +++ /dev/null @@ -1,521 +0,0 @@ -SPUFS(2) Linux Programmer's Manual SPUFS(2) - - - -NAME - spufs - the SPU file system - - -DESCRIPTION - The SPU file system is used on PowerPC machines that implement the Cell - Broadband Engine Architecture in order to access Synergistic Processor - Units (SPUs). - - The file system provides a name space similar to posix shared memory or - message queues. Users that have write permissions on the file system - can use spu_create(2) to establish SPU contexts in the spufs root. - - Every SPU context is represented by a directory containing a predefined - set of files. These files can be used for manipulating the state of the - logical SPU. Users can change permissions on those files, but not actu- - ally add or remove files. - - -MOUNT OPTIONS - uid= - set the user owning the mount point, the default is 0 (root). - - gid= - set the group owning the mount point, the default is 0 (root). - - -FILES - The files in spufs mostly follow the standard behavior for regular sys- - tem calls like read(2) or write(2), but often support only a subset of - the operations supported on regular file systems. This list details the - supported operations and the deviations from the behaviour in the - respective man pages. - - All files that support the read(2) operation also support readv(2) and - all files that support the write(2) operation also support writev(2). - All files support the access(2) and stat(2) family of operations, but - only the st_mode, st_nlink, st_uid and st_gid fields of struct stat - contain reliable information. - - All files support the chmod(2)/fchmod(2) and chown(2)/fchown(2) opera- - tions, but will not be able to grant permissions that contradict the - possible operations, e.g. read access on the wbox file. - - The current set of files is: - - - /mem - the contents of the local storage memory of the SPU. This can be - accessed like a regular shared memory file and contains both code and - data in the address space of the SPU. The possible operations on an - open mem file are: - - read(2), pread(2), write(2), pwrite(2), lseek(2) - These operate as documented, with the exception that seek(2), - write(2) and pwrite(2) are not supported beyond the end of the - file. The file size is the size of the local storage of the SPU, - which normally is 256 kilobytes. - - mmap(2) - Mapping mem into the process address space gives access to the - SPU local storage within the process address space. Only - MAP_SHARED mappings are allowed. - - - /mbox - The first SPU to CPU communication mailbox. This file is read-only and - can be read in units of 32 bits. The file can only be used in non- - blocking mode and it even poll() will not block on it. The possible - operations on an open mbox file are: - - read(2) - If a count smaller than four is requested, read returns -1 and - sets errno to EINVAL. If there is no data available in the mail - box, the return value is set to -1 and errno becomes EAGAIN. - When data has been read successfully, four bytes are placed in - the data buffer and the value four is returned. - - - /ibox - The second SPU to CPU communication mailbox. This file is similar to - the first mailbox file, but can be read in blocking I/O mode, and the - poll familiy of system calls can be used to wait for it. The possible - operations on an open ibox file are: - - read(2) - If a count smaller than four is requested, read returns -1 and - sets errno to EINVAL. If there is no data available in the mail - box and the file descriptor has been opened with O_NONBLOCK, the - return value is set to -1 and errno becomes EAGAIN. - - If there is no data available in the mail box and the file - descriptor has been opened without O_NONBLOCK, the call will - block until the SPU writes to its interrupt mailbox channel. - When data has been read successfully, four bytes are placed in - the data buffer and the value four is returned. - - poll(2) - Poll on the ibox file returns (POLLIN | POLLRDNORM) whenever - data is available for reading. - - - /wbox - The CPU to SPU communation mailbox. It is write-only can can be written - in units of 32 bits. If the mailbox is full, write() will block and - poll can be used to wait for it becoming empty again. The possible - operations on an open wbox file are: write(2) If a count smaller than - four is requested, write returns -1 and sets errno to EINVAL. If there - is no space available in the mail box and the file descriptor has been - opened with O_NONBLOCK, the return value is set to -1 and errno becomes - EAGAIN. - - If there is no space available in the mail box and the file descriptor - has been opened without O_NONBLOCK, the call will block until the SPU - reads from its PPE mailbox channel. When data has been read success- - fully, four bytes are placed in the data buffer and the value four is - returned. - - poll(2) - Poll on the ibox file returns (POLLOUT | POLLWRNORM) whenever - space is available for writing. - - - /mbox_stat - /ibox_stat - /wbox_stat - Read-only files that contain the length of the current queue, i.e. how - many words can be read from mbox or ibox or how many words can be - written to wbox without blocking. The files can be read only in 4-byte - units and return a big-endian binary integer number. The possible - operations on an open *box_stat file are: - - read(2) - If a count smaller than four is requested, read returns -1 and - sets errno to EINVAL. Otherwise, a four byte value is placed in - the data buffer, containing the number of elements that can be - read from (for mbox_stat and ibox_stat) or written to (for - wbox_stat) the respective mail box without blocking or resulting - in EAGAIN. - - - /npc - /decr - /decr_status - /spu_tag_mask - /event_mask - /srr0 - Internal registers of the SPU. The representation is an ASCII string - with the numeric value of the next instruction to be executed. These - can be used in read/write mode for debugging, but normal operation of - programs should not rely on them because access to any of them except - npc requires an SPU context save and is therefore very inefficient. - - The contents of these files are: - - npc Next Program Counter - - decr SPU Decrementer - - decr_status Decrementer Status - - spu_tag_mask MFC tag mask for SPU DMA - - event_mask Event mask for SPU interrupts - - srr0 Interrupt Return address register - - - The possible operations on an open npc, decr, decr_status, - spu_tag_mask, event_mask or srr0 file are: - - read(2) - When the count supplied to the read call is shorter than the - required length for the pointer value plus a newline character, - subsequent reads from the same file descriptor will result in - completing the string, regardless of changes to the register by - a running SPU task. When a complete string has been read, all - subsequent read operations will return zero bytes and a new file - descriptor needs to be opened to read the value again. - - write(2) - A write operation on the file results in setting the register to - the value given in the string. The string is parsed from the - beginning to the first non-numeric character or the end of the - buffer. Subsequent writes to the same file descriptor overwrite - the previous setting. - - - /fpcr - This file gives access to the Floating Point Status and Control Regis- - ter as a four byte long file. The operations on the fpcr file are: - - read(2) - If a count smaller than four is requested, read returns -1 and - sets errno to EINVAL. Otherwise, a four byte value is placed in - the data buffer, containing the current value of the fpcr regis- - ter. - - write(2) - If a count smaller than four is requested, write returns -1 and - sets errno to EINVAL. Otherwise, a four byte value is copied - from the data buffer, updating the value of the fpcr register. - - - /signal1 - /signal2 - The two signal notification channels of an SPU. These are read-write - files that operate on a 32 bit word. Writing to one of these files - triggers an interrupt on the SPU. The value writting to the signal - files can be read from the SPU through a channel read or from host user - space through the file. After the value has been read by the SPU, it - is reset to zero. The possible operations on an open signal1 or sig- - nal2 file are: - - read(2) - If a count smaller than four is requested, read returns -1 and - sets errno to EINVAL. Otherwise, a four byte value is placed in - the data buffer, containing the current value of the specified - signal notification register. - - write(2) - If a count smaller than four is requested, write returns -1 and - sets errno to EINVAL. Otherwise, a four byte value is copied - from the data buffer, updating the value of the specified signal - notification register. The signal notification register will - either be replaced with the input data or will be updated to the - bitwise OR or the old value and the input data, depending on the - contents of the signal1_type, or signal2_type respectively, - file. - - - /signal1_type - /signal2_type - These two files change the behavior of the signal1 and signal2 notifi- - cation files. The contain a numerical ASCII string which is read as - either "1" or "0". In mode 0 (overwrite), the hardware replaces the - contents of the signal channel with the data that is written to it. in - mode 1 (logical OR), the hardware accumulates the bits that are subse- - quently written to it. The possible operations on an open signal1_type - or signal2_type file are: - - read(2) - When the count supplied to the read call is shorter than the - required length for the digit plus a newline character, subse- - quent reads from the same file descriptor will result in com- - pleting the string. When a complete string has been read, all - subsequent read operations will return zero bytes and a new file - descriptor needs to be opened to read the value again. - - write(2) - A write operation on the file results in setting the register to - the value given in the string. The string is parsed from the - beginning to the first non-numeric character or the end of the - buffer. Subsequent writes to the same file descriptor overwrite - the previous setting. - - -EXAMPLES - /etc/fstab entry - none /spu spufs gid=spu 0 0 - - -AUTHORS - Arnd Bergmann , Mark Nutter , - Ulrich Weigand - -SEE ALSO - capabilities(7), close(2), spu_create(2), spu_run(2), spufs(7) - - - -Linux 2005-09-28 SPUFS(2) - ------------------------------------------------------------------------------- - -SPU_RUN(2) Linux Programmer's Manual SPU_RUN(2) - - - -NAME - spu_run - execute an spu context - - -SYNOPSIS - #include - - int spu_run(int fd, unsigned int *npc, unsigned int *event); - -DESCRIPTION - The spu_run system call is used on PowerPC machines that implement the - Cell Broadband Engine Architecture in order to access Synergistic Pro- - cessor Units (SPUs). It uses the fd that was returned from spu_cre- - ate(2) to address a specific SPU context. When the context gets sched- - uled to a physical SPU, it starts execution at the instruction pointer - passed in npc. - - Execution of SPU code happens synchronously, meaning that spu_run does - not return while the SPU is still running. If there is a need to exe- - cute SPU code in parallel with other code on either the main CPU or - other SPUs, you need to create a new thread of execution first, e.g. - using the pthread_create(3) call. - - When spu_run returns, the current value of the SPU instruction pointer - is written back to npc, so you can call spu_run again without updating - the pointers. - - event can be a NULL pointer or point to an extended status code that - gets filled when spu_run returns. It can be one of the following con- - stants: - - SPE_EVENT_DMA_ALIGNMENT - A DMA alignment error - - SPE_EVENT_SPE_DATA_SEGMENT - A DMA segmentation error - - SPE_EVENT_SPE_DATA_STORAGE - A DMA storage error - - If NULL is passed as the event argument, these errors will result in a - signal delivered to the calling process. - -RETURN VALUE - spu_run returns the value of the spu_status register or -1 to indicate - an error and set errno to one of the error codes listed below. The - spu_status register value contains a bit mask of status codes and - optionally a 14 bit code returned from the stop-and-signal instruction - on the SPU. The bit masks for the status codes are: - - 0x02 SPU was stopped by stop-and-signal. - - 0x04 SPU was stopped by halt. - - 0x08 SPU is waiting for a channel. - - 0x10 SPU is in single-step mode. - - 0x20 SPU has tried to execute an invalid instruction. - - 0x40 SPU has tried to access an invalid channel. - - 0x3fff0000 - The bits masked with this value contain the code returned from - stop-and-signal. - - There are always one or more of the lower eight bits set or an error - code is returned from spu_run. - -ERRORS - EAGAIN or EWOULDBLOCK - fd is in non-blocking mode and spu_run would block. - - EBADF fd is not a valid file descriptor. - - EFAULT npc is not a valid pointer or status is neither NULL nor a valid - pointer. - - EINTR A signal occured while spu_run was in progress. The npc value - has been updated to the new program counter value if necessary. - - EINVAL fd is not a file descriptor returned from spu_create(2). - - ENOMEM Insufficient memory was available to handle a page fault result- - ing from an MFC direct memory access. - - ENOSYS the functionality is not provided by the current system, because - either the hardware does not provide SPUs or the spufs module is - not loaded. - - -NOTES - spu_run is meant to be used from libraries that implement a more - abstract interface to SPUs, not to be used from regular applications. - See http://www.bsc.es/projects/deepcomputing/linuxoncell/ for the rec- - ommended libraries. - - -CONFORMING TO - This call is Linux specific and only implemented by the ppc64 architec- - ture. Programs using this system call are not portable. - - -BUGS - The code does not yet fully implement all features lined out here. - - -AUTHOR - Arnd Bergmann - -SEE ALSO - capabilities(7), close(2), spu_create(2), spufs(7) - - - -Linux 2005-09-28 SPU_RUN(2) - ------------------------------------------------------------------------------- - -SPU_CREATE(2) Linux Programmer's Manual SPU_CREATE(2) - - - -NAME - spu_create - create a new spu context - - -SYNOPSIS - #include - #include - - int spu_create(const char *pathname, int flags, mode_t mode); - -DESCRIPTION - The spu_create system call is used on PowerPC machines that implement - the Cell Broadband Engine Architecture in order to access Synergistic - Processor Units (SPUs). It creates a new logical context for an SPU in - pathname and returns a handle to associated with it. pathname must - point to a non-existing directory in the mount point of the SPU file - system (spufs). When spu_create is successful, a directory gets cre- - ated on pathname and it is populated with files. - - The returned file handle can only be passed to spu_run(2) or closed, - other operations are not defined on it. When it is closed, all associ- - ated directory entries in spufs are removed. When the last file handle - pointing either inside of the context directory or to this file - descriptor is closed, the logical SPU context is destroyed. - - The parameter flags can be zero or any bitwise or'd combination of the - following constants: - - SPU_RAWIO - Allow mapping of some of the hardware registers of the SPU into - user space. This flag requires the CAP_SYS_RAWIO capability, see - capabilities(7). - - The mode parameter specifies the permissions used for creating the new - directory in spufs. mode is modified with the user's umask(2) value - and then used for both the directory and the files contained in it. The - file permissions mask out some more bits of mode because they typically - support only read or write access. See stat(2) for a full list of the - possible mode values. - - -RETURN VALUE - spu_create returns a new file descriptor. It may return -1 to indicate - an error condition and set errno to one of the error codes listed - below. - - -ERRORS - EACCESS - The current user does not have write access on the spufs mount - point. - - EEXIST An SPU context already exists at the given path name. - - EFAULT pathname is not a valid string pointer in the current address - space. - - EINVAL pathname is not a directory in the spufs mount point. - - ELOOP Too many symlinks were found while resolving pathname. - - EMFILE The process has reached its maximum open file limit. - - ENAMETOOLONG - pathname was too long. - - ENFILE The system has reached the global open file limit. - - ENOENT Part of pathname could not be resolved. - - ENOMEM The kernel could not allocate all resources required. - - ENOSPC There are not enough SPU resources available to create a new - context or the user specific limit for the number of SPU con- - texts has been reached. - - ENOSYS the functionality is not provided by the current system, because - either the hardware does not provide SPUs or the spufs module is - not loaded. - - ENOTDIR - A part of pathname is not a directory. - - - -NOTES - spu_create is meant to be used from libraries that implement a more - abstract interface to SPUs, not to be used from regular applications. - See http://www.bsc.es/projects/deepcomputing/linuxoncell/ for the rec- - ommended libraries. - - -FILES - pathname must point to a location beneath the mount point of spufs. By - convention, it gets mounted in /spu. - - -CONFORMING TO - This call is Linux specific and only implemented by the ppc64 architec- - ture. Programs using this system call are not portable. - - -BUGS - The code does not yet fully implement all features lined out here. - - -AUTHOR - Arnd Bergmann - -SEE ALSO - capabilities(7), close(2), spu_run(2), spufs(7) - - - -Linux 2005-09-28 SPU_CREATE(2) diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 0dc848bf0b56..acb010bb087b 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -998,8 +998,6 @@ running once the system is up. nowb [ARM] - nr_uarts= [SERIAL] maximum number of UARTs to be registered. - opl3= [HW,OSS] Format: diff --git a/trunk/Documentation/keys-request-key.txt b/trunk/Documentation/keys-request-key.txt index 22488d791168..5f2b9c5edbb5 100644 --- a/trunk/Documentation/keys-request-key.txt +++ b/trunk/Documentation/keys-request-key.txt @@ -56,12 +56,10 @@ A request proceeds in the following manner: (4) request_key() then forks and executes /sbin/request-key with a new session keyring that contains a link to auth key V. - (5) /sbin/request-key assumes the authority associated with key U. - - (6) /sbin/request-key execs an appropriate program to perform the actual + (5) /sbin/request-key execs an appropriate program to perform the actual instantiation. - (7) The program may want to access another key from A's context (say a + (6) The program may want to access another key from A's context (say a Kerberos TGT key). It just requests the appropriate key, and the keyring search notes that the session keyring has auth key V in its bottom level. @@ -69,19 +67,19 @@ A request proceeds in the following manner: UID, GID, groups and security info of process A as if it was process A, and come up with key W. - (8) The program then does what it must to get the data with which to + (7) The program then does what it must to get the data with which to instantiate key U, using key W as a reference (perhaps it contacts a Kerberos server using the TGT) and then instantiates key U. - (9) Upon instantiating key U, auth key V is automatically revoked so that it + (8) Upon instantiating key U, auth key V is automatically revoked so that it may not be used again. -(10) The program then exits 0 and request_key() deletes key V and returns key + (9) The program then exits 0 and request_key() deletes key V and returns key U to the caller. -This also extends further. If key W (step 7 above) didn't exist, key W would be -created uninstantiated, another auth key (X) would be created (as per step 3) -and another copy of /sbin/request-key spawned (as per step 4); but the context +This also extends further. If key W (step 5 above) didn't exist, key W would be +created uninstantiated, another auth key (X) would be created [as per step 3] +and another copy of /sbin/request-key spawned [as per step 4]; but the context specified by auth key X will still be process A, as it was in auth key V. This is because process A's keyrings can't simply be attached to @@ -140,8 +138,8 @@ until one succeeds: (3) The process's session keyring is searched. - (4) If the process has assumed the authority associated with a request_key() - authorisation key then: + (4) If the process has a request_key() authorisation key in its session + keyring then: (a) If extant, the calling process's thread keyring is searched. diff --git a/trunk/Documentation/keys.txt b/trunk/Documentation/keys.txt index aaa01b0e3ee9..6304db59bfe4 100644 --- a/trunk/Documentation/keys.txt +++ b/trunk/Documentation/keys.txt @@ -308,8 +308,6 @@ process making the call: KEY_SPEC_USER_KEYRING -4 UID-specific keyring KEY_SPEC_USER_SESSION_KEYRING -5 UID-session keyring KEY_SPEC_GROUP_KEYRING -6 GID-specific keyring - KEY_SPEC_REQKEY_AUTH_KEY -7 assumed request_key() - authorisation key The main syscalls are: @@ -500,11 +498,7 @@ The keyctl syscall functions are: keyring is full, error ENFILE will result. The link procedure checks the nesting of the keyrings, returning ELOOP if - it appears too deep or EDEADLK if the link would introduce a cycle. - - Any links within the keyring to keys that match the new key in terms of - type and description will be discarded from the keyring as the new one is - added. + it appears to deep or EDEADLK if the link would introduce a cycle. (*) Unlink a key or keyring from another keyring: @@ -634,41 +628,6 @@ The keyctl syscall functions are: there is one, otherwise the user default session keyring. - (*) Set the timeout on a key. - - long keyctl(KEYCTL_SET_TIMEOUT, key_serial_t key, unsigned timeout); - - This sets or clears the timeout on a key. The timeout can be 0 to clear - the timeout or a number of seconds to set the expiry time that far into - the future. - - The process must have attribute modification access on a key to set its - timeout. Timeouts may not be set with this function on negative, revoked - or expired keys. - - - (*) Assume the authority granted to instantiate a key - - long keyctl(KEYCTL_ASSUME_AUTHORITY, key_serial_t key); - - This assumes or divests the authority required to instantiate the - specified key. Authority can only be assumed if the thread has the - authorisation key associated with the specified key in its keyrings - somewhere. - - Once authority is assumed, searches for keys will also search the - requester's keyrings using the requester's security label, UID, GID and - groups. - - If the requested authority is unavailable, error EPERM will be returned, - likewise if the authority has been revoked because the target key is - already instantiated. - - If the specified key is 0, then any assumed authority will be divested. - - The assumed authorititive key is inherited across fork and exec. - - =============== KERNEL SERVICES =============== diff --git a/trunk/Documentation/kprobes.txt b/trunk/Documentation/kprobes.txt index 0ea5a0c6e827..0541fe1de704 100644 --- a/trunk/Documentation/kprobes.txt +++ b/trunk/Documentation/kprobes.txt @@ -411,8 +411,7 @@ int init_module(void) printk("Couldn't find %s to plant kprobe\n", "do_fork"); return -1; } - ret = register_kprobe(&kp); - if (ret < 0) { + if ((ret = register_kprobe(&kp) < 0)) { printk("register_kprobe failed, returned %d\n", ret); return -1; } diff --git a/trunk/Documentation/networking/bonding.txt b/trunk/Documentation/networking/bonding.txt index 8d8b4e5ea184..b0fe41da007b 100644 --- a/trunk/Documentation/networking/bonding.txt +++ b/trunk/Documentation/networking/bonding.txt @@ -945,6 +945,7 @@ bond0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 collisions:0 txqueuelen:0 eth0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 + inet addr:XXX.XXX.XXX.YYY Bcast:XXX.XXX.XXX.255 Mask:255.255.252.0 UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1 RX packets:3573025 errors:0 dropped:0 overruns:0 frame:0 TX packets:1643167 errors:1 dropped:0 overruns:1 carrier:0 @@ -952,6 +953,7 @@ eth0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 Interrupt:10 Base address:0x1080 eth1 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4 + inet addr:XXX.XXX.XXX.YYY Bcast:XXX.XXX.XXX.255 Mask:255.255.252.0 UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1 RX packets:3651769 errors:0 dropped:0 overruns:0 frame:0 TX packets:1643480 errors:0 dropped:0 overruns:0 carrier:0 diff --git a/trunk/Documentation/powerpc/00-INDEX b/trunk/Documentation/powerpc/00-INDEX index d6d65b9bcfe3..e7bea0a407b4 100644 --- a/trunk/Documentation/powerpc/00-INDEX +++ b/trunk/Documentation/powerpc/00-INDEX @@ -8,18 +8,12 @@ please mail me. cpu_features.txt - info on how we support a variety of CPUs with minimal compile-time options. -eeh-pci-error-recovery.txt - - info on PCI Bus EEH Error Recovery -hvcs.txt - - IBM "Hypervisor Virtual Console Server" Installation Guide -mpc52xx.txt - - Linux 2.6.x on MPC52xx family ppc_htab.txt - info about the Linux/PPC /proc/ppc_htab entry -SBC8260_memory_mapping.txt - - EST SBC8260 board info smp.txt - use and state info about Linux/PPC on MP machines +SBC8260_memory_mapping.txt + - EST SBC8260 board info sound.txt - info on sound support under Linux/PPC zImage_layout.txt diff --git a/trunk/Documentation/sysctl/vm.txt b/trunk/Documentation/sysctl/vm.txt index 6910c0136f8d..2f1aae32a5d9 100644 --- a/trunk/Documentation/sysctl/vm.txt +++ b/trunk/Documentation/sysctl/vm.txt @@ -26,13 +26,12 @@ Currently, these files are in /proc/sys/vm: - min_free_kbytes - laptop_mode - block_dump -- drop-caches ============================================================== dirty_ratio, dirty_background_ratio, dirty_expire_centisecs, dirty_writeback_centisecs, vfs_cache_pressure, laptop_mode, -block_dump, swap_token_timeout, drop-caches: +block_dump, swap_token_timeout: See Documentation/filesystems/proc.txt @@ -103,20 +102,3 @@ This is used to force the Linux VM to keep a minimum number of kilobytes free. The VM uses this number to compute a pages_min value for each lowmem zone in the system. Each lowmem zone gets a number of reserved free pages based proportionally on its size. - -============================================================== - -percpu_pagelist_fraction - -This is the fraction of pages at most (high mark pcp->high) in each zone that -are allocated for each per cpu page list. The min value for this is 8. It -means that we don't allow more than 1/8th of pages in each zone to be -allocated in any single per_cpu_pagelist. This entry only changes the value -of hot per cpu pagelists. User can specify a number like 100 to allocate -1/100th of each zone to each per cpu page list. - -The batch value of each per cpu pagelist is also updated as a result. It is -set to pcp->high/4. The upper limit of batch is (PAGE_SHIFT * 8) - -The initial value is zero. Kernel does not use this value at boot time to set -the high water marks for each per cpu page list. diff --git a/trunk/Documentation/video4linux/CARDLIST.bttv b/trunk/Documentation/video4linux/CARDLIST.bttv index 74fb085e178b..330246ac80f8 100644 --- a/trunk/Documentation/video4linux/CARDLIST.bttv +++ b/trunk/Documentation/video4linux/CARDLIST.bttv @@ -141,4 +141,3 @@ 140 -> Osprey 440 [0070:ff07] 141 -> Asound Skyeye PCTV 142 -> Sabrent TV-FM (bttv version) -143 -> Hauppauge ImpactVCB (bt878) [0070:13eb] diff --git a/trunk/Documentation/video4linux/CARDLIST.cx88 b/trunk/Documentation/video4linux/CARDLIST.cx88 index 34b6e59f2968..a1017d1a85d4 100644 --- a/trunk/Documentation/video4linux/CARDLIST.cx88 +++ b/trunk/Documentation/video4linux/CARDLIST.cx88 @@ -16,7 +16,7 @@ 15 -> DViCO FusionHDTV DVB-T1 [18ac:db00] 16 -> KWorld LTV883RF 17 -> DViCO FusionHDTV 3 Gold-Q [18ac:d810] - 18 -> Hauppauge Nova-T DVB-T [0070:9002,0070:9001] + 18 -> Hauppauge Nova-T DVB-T [0070:9002] 19 -> Conexant DVB-T reference design [14f1:0187] 20 -> Provideo PV259 [1540:2580] 21 -> DViCO FusionHDTV DVB-T Plus [18ac:db10] @@ -35,11 +35,3 @@ 34 -> ATI HDTV Wonder [1002:a101] 35 -> WinFast DTV1000-T [107d:665f] 36 -> AVerTV 303 (M126) [1461:000a] - 37 -> Hauppauge Nova-S-Plus DVB-S [0070:9201,0070:9202] - 38 -> Hauppauge Nova-SE2 DVB-S [0070:9200] - 39 -> KWorld DVB-S 100 [17de:08b2] - 40 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid [0070:9400,0070:9402] - 41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802] - 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025] - 43 -> KWorld/VStream XPert DVB-T with cx22702 [17de:08a1] - 44 -> DViCO FusionHDTV DVB-T Dual Digital [18ac:db50] diff --git a/trunk/Documentation/video4linux/CARDLIST.saa7134 b/trunk/Documentation/video4linux/CARDLIST.saa7134 index cb3a59bbeb17..efb708ec116a 100644 --- a/trunk/Documentation/video4linux/CARDLIST.saa7134 +++ b/trunk/Documentation/video4linux/CARDLIST.saa7134 @@ -56,7 +56,7 @@ 55 -> LifeView FlyDVB-T DUO [5168:0502,5168:0306] 56 -> Avermedia AVerTV 307 [1461:a70a] 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] - 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370] + 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0370,1421:1370] 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502] 61 -> Philips TOUGH DVB-T reference design [1131:2004] @@ -81,5 +81,4 @@ 80 -> ASUS Digimatrix TV [1043:0210] 81 -> Philips Tiger reference design [1131:2018] 82 -> MSI TV@Anywhere plus [1462:6231] - 83 -> Terratec Cinergy 250 PCI TV [153b:1160] - 84 -> LifeView FlyDVB Trio [5168:0319] + diff --git a/trunk/Documentation/video4linux/CARDLIST.tuner b/trunk/Documentation/video4linux/CARDLIST.tuner index 0bf3d5bf9ef8..9d6544ea9f41 100644 --- a/trunk/Documentation/video4linux/CARDLIST.tuner +++ b/trunk/Documentation/video4linux/CARDLIST.tuner @@ -40,7 +40,7 @@ tuner=38 - Philips PAL/SECAM multi (FM1216ME MK3) tuner=39 - LG NTSC (newer TAPC series) tuner=40 - HITACHI V7-J180AT tuner=41 - Philips PAL_MK (FI1216 MK) -tuner=42 - Philips 1236D ATSC/NTSC dual in +tuner=42 - Philips 1236D ATSC/NTSC daul in tuner=43 - Philips NTSC MK3 (FM1236MK3 or FM1236/F) tuner=44 - Philips 4 in 1 (ATI TV Wonder Pro/Conexant) tuner=45 - Microtune 4049 FM5 @@ -50,7 +50,7 @@ tuner=48 - Tenna TNF 8831 BGFF) tuner=49 - Microtune 4042 FI5 ATSC/NTSC dual in tuner=50 - TCL 2002N tuner=51 - Philips PAL/SECAM_D (FM 1256 I-H3) -tuner=52 - Thomson DTT 7610 (ATSC/NTSC) +tuner=52 - Thomson DDT 7610 (ATSC/NTSC) tuner=53 - Philips FQ1286 tuner=54 - tda8290+75 tuner=55 - TCL 2002MB @@ -58,7 +58,7 @@ tuner=56 - Philips PAL/SECAM multi (FQ1216AME MK4) tuner=57 - Philips FQ1236A MK4 tuner=58 - Ymec TVision TVF-8531MF/8831MF/8731MF tuner=59 - Ymec TVision TVF-5533MF -tuner=60 - Thomson DTT 761X (ATSC/NTSC) +tuner=60 - Thomson DDT 7611 (ATSC/NTSC) tuner=61 - Tena TNF9533-D/IF/TNF9533-B/DF tuner=62 - Philips TEA5767HN FM Radio tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 270e28c0506a..7e780906d34c 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -927,6 +927,7 @@ S: Maintained FARSYNC SYNCHRONOUS DRIVER P: Kevin Curtis M: kevin.curtis@farsite.co.uk +M: kevin.curtis@farsite.co.uk W: http://www.farsite.co.uk/ S: Supported @@ -1697,6 +1698,7 @@ S: Maintained MARVELL MV64340 ETHERNET DRIVER P: Manish Lachwani +M: Manish_Lachwani@pmc-sierra.com L: linux-mips@linux-mips.org L: netdev@vger.kernel.org S: Supported diff --git a/trunk/README b/trunk/README index cd5e2eb6213b..61c4f7429233 100644 --- a/trunk/README +++ b/trunk/README @@ -183,8 +183,11 @@ CONFIGURING the kernel: COMPILING the kernel: - - Make sure you have at least gcc 3.2 available. - For more information, refer to Documentation/Changes. + - Make sure you have gcc 2.95.3 available. + gcc 2.91.66 (egcs-1.1.2), and gcc 2.7.2.3 are known to miscompile + some parts of the kernel, and are *no longer supported*. + Also remember to upgrade your binutils package (for as/ld/nm and company) + if necessary. For more information, refer to Documentation/Changes. Please note that you can still run a.out user programs with this kernel. diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig index eedf41bf7057..153337ff1d7b 100644 --- a/trunk/arch/alpha/Kconfig +++ b/trunk/arch/alpha/Kconfig @@ -18,6 +18,9 @@ config MMU bool default y +config UID16 + bool + config RWSEM_GENERIC_SPINLOCK bool diff --git a/trunk/arch/alpha/kernel/process.c b/trunk/arch/alpha/kernel/process.c index abb739b88ed1..a8682612abc0 100644 --- a/trunk/arch/alpha/kernel/process.c +++ b/trunk/arch/alpha/kernel/process.c @@ -43,11 +43,6 @@ #include "proto.h" #include "pci_impl.h" -/* - * Power off function, if any - */ -void (*pm_power_off)(void) = machine_power_off; - void cpu_idle(void) { diff --git a/trunk/arch/alpha/kernel/ptrace.c b/trunk/arch/alpha/kernel/ptrace.c index 9969d212e94d..bbd37536d14e 100644 --- a/trunk/arch/alpha/kernel/ptrace.c +++ b/trunk/arch/alpha/kernel/ptrace.c @@ -265,16 +265,30 @@ do_sys_ptrace(long request, long pid, long addr, long data, lock_kernel(); DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n", request, pid, addr, data)); + ret = -EPERM; if (request == PTRACE_TRACEME) { - ret = ptrace_traceme(); + /* are we already being traced? */ + if (current->ptrace & PT_PTRACED) + goto out_notsk; + ret = security_ptrace(current->parent, current); + if (ret) + goto out_notsk; + /* set the ptrace bit in the process ptrace flags. */ + current->ptrace |= PT_PTRACED; + ret = 0; goto out_notsk; } + if (pid == 1) /* you may not mess with init */ + goto out_notsk; - child = ptrace_get_task_struct(pid); - if (IS_ERR(child)) { - ret = PTR_ERR(child); + ret = -ESRCH; + read_lock(&tasklist_lock); + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); + if (!child) goto out_notsk; - } if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 7a74e3e5f916..70f388d168db 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -46,6 +46,10 @@ config MCA (and especially the web page given there) before attempting to build an MCA bus kernel. +config UID16 + bool + default y + config RWSEM_GENERIC_SPINLOCK bool default y @@ -99,13 +103,6 @@ config ARCH_EBSA110 Ethernet interface, two PCMCIA sockets, two serial ports and a parallel port. -config ARCH_CAMELOT - bool "Epxa10db" - help - This enables support for Altera's Excalibur XA10 development board. - If you would like to build your kernel to run on one of these boards - then you must say 'Y' here. Otherwise say 'N' - config ARCH_FOOTBRIDGE bool "FootBridge" select FOOTBRIDGE @@ -217,8 +214,6 @@ endchoice source "arch/arm/mach-clps711x/Kconfig" -source "arch/arm/mach-epxa10db/Kconfig" - source "arch/arm/mach-footbridge/Kconfig" source "arch/arm/mach-integrator/Kconfig" diff --git a/trunk/arch/arm/Makefile b/trunk/arch/arm/Makefile index afaf3a1e903c..1c056d631153 100644 --- a/trunk/arch/arm/Makefile +++ b/trunk/arch/arm/Makefile @@ -84,7 +84,6 @@ endif machine-$(CONFIG_ARCH_PXA) := pxa machine-$(CONFIG_ARCH_L7200) := l7200 machine-$(CONFIG_ARCH_INTEGRATOR) := integrator - machine-$(CONFIG_ARCH_CAMELOT) := epxa10db textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 machine-$(CONFIG_ARCH_CLPS711X) := clps711x machine-$(CONFIG_ARCH_IOP3XX) := iop3xx diff --git a/trunk/arch/arm/boot/compressed/Makefile b/trunk/arch/arm/boot/compressed/Makefile index 6b505ce41a75..0009a80498cc 100644 --- a/trunk/arch/arm/boot/compressed/Makefile +++ b/trunk/arch/arm/boot/compressed/Makefile @@ -21,10 +21,6 @@ ifeq ($(CONFIG_ARCH_SHARK),y) OBJS += head-shark.o ofw-shark.o endif -ifeq ($(CONFIG_ARCH_CAMELOT),y) -OBJS += head-epxa10db.o -endif - ifeq ($(CONFIG_ARCH_L7200),y) OBJS += head-l7200.o endif diff --git a/trunk/arch/arm/boot/compressed/head-epxa10db.S b/trunk/arch/arm/boot/compressed/head-epxa10db.S deleted file mode 100644 index 757681f12a39..000000000000 --- a/trunk/arch/arm/boot/compressed/head-epxa10db.S +++ /dev/null @@ -1,5 +0,0 @@ -#include -#include - - .section ".start", "ax" - mov r7, #MACH_TYPE_CAMELOT diff --git a/trunk/arch/arm/common/scoop.c b/trunk/arch/arm/common/scoop.c index a2dfe0b0f1ec..b6de43e73699 100644 --- a/trunk/arch/arm/common/scoop.c +++ b/trunk/arch/arm/common/scoop.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/arm/configs/epxa10db_defconfig b/trunk/arch/arm/configs/epxa10db_defconfig deleted file mode 100644 index 9fb8b58c4954..000000000000 --- a/trunk/arch/arm/configs/epxa10db_defconfig +++ /dev/null @@ -1,644 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 22:46:51 2005 -# -CONFIG_ARM=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set - -# -# System Type -# -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -CONFIG_ARCH_CAMELOT=y -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_IOP3XX is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_H720X is not set - -# -# Epxa10db -# - -# -# PLD hotswap support -# -CONFIG_PLD=y -# CONFIG_PLD_HOTSWAP is not set - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_ARM922T=y -CONFIG_CPU_32v4=y -CONFIG_CPU_ABRT_EV4T=y -CONFIG_CPU_CACHE_V4WT=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_COPY_V4WB=y -CONFIG_CPU_TLB_V4WBI=y - -# -# Processor Features -# -# CONFIG_ARM_THUMB is not set -# CONFIG_CPU_ICACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_DISABLE is not set -# CONFIG_CPU_DCACHE_WRITETHROUGH is not set - -# -# Bus support -# - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# Kernel Features -# -# CONFIG_PREEMPT is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="mem=32M console=ttyUA0,115200 initrd=0x00200000,8M root=/dev/ram0 rw" -# CONFIG_XIP_KERNEL is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_NWFPE_XP is not set -# CONFIG_FPE_FASTFPE is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_AOUT is not set -# CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set - -# -# Power management options -# -# CONFIG_PM is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_ATA_OVER_ETH is not set - -# -# SCSI device support -# -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_PNP=y -# CONFIG_IP_PNP_DHCP is not set -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_IP_TCPDIAG is not set -# CONFIG_IP_TCPDIAG_IPV6 is not set -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# Ethernet (10 or 100Mbit) -# -# CONFIG_NET_ETHERNET is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -CONFIG_PPP=y -CONFIG_PPP_MULTILINK=y -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=y -CONFIG_PPP_SYNC_TTY=y -CONFIG_PPP_DEFLATE=y -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPPOE is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_UART00=y -CONFIG_SERIAL_UART00_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB is not set - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set - -# -# XFS support -# -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -CONFIG_SMB_FS=y -# CONFIG_SMB_NLS_DEFAULT is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_FRAME_POINTER=y -# CONFIG_DEBUG_USER is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_CRC_CCITT=y -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/trunk/arch/arm/kernel/asm-offsets.c b/trunk/arch/arm/kernel/asm-offsets.c index 0abbce8c70bc..04d3082a7b94 100644 --- a/trunk/arch/arm/kernel/asm-offsets.c +++ b/trunk/arch/arm/kernel/asm-offsets.c @@ -23,15 +23,20 @@ #error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32 #endif /* + * GCC 2.95.1, 2.95.2: ignores register clobber list in asm(). * GCC 3.0, 3.1: general bad code generation. * GCC 3.2.0: incorrect function argument offset calculation. * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c * (http://gcc.gnu.org/PR8896) and incorrect structure * initialisation in fs/jffs2/erase.c */ -#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3) +#if __GNUC__ < 2 || \ + (__GNUC__ == 2 && __GNUC_MINOR__ < 95) || \ + (__GNUC__ == 2 && __GNUC_MINOR__ == 95 && __GNUC_PATCHLEVEL__ != 0 && \ + __GNUC_PATCHLEVEL__ < 3) || \ + (__GNUC__ == 3 && __GNUC_MINOR__ < 3) #error Your compiler is too buggy; it is known to miscompile kernels. -#error Known good compilers: 3.3 +#error Known good compilers: 2.95.3, 2.95.4, 2.96, 3.3 #endif /* Use marker if you need to separate the values later */ diff --git a/trunk/arch/arm/kernel/irq.c b/trunk/arch/arm/kernel/irq.c index b5645c4462cf..869c466e6258 100644 --- a/trunk/arch/arm/kernel/irq.c +++ b/trunk/arch/arm/kernel/irq.c @@ -684,12 +684,8 @@ int setup_irq(unsigned int irq, struct irqaction *new) spin_lock_irqsave(&irq_controller_lock, flags); p = &desc->action; if ((old = *p) != NULL) { - /* - * Can't share interrupts unless both agree to and are - * the same type. - */ - if (!(old->flags & new->flags & SA_SHIRQ) || - (~old->flags & new->flags) & SA_TRIGGER_MASK) { + /* Can't share interrupts unless both agree to */ + if (!(old->flags & new->flags & SA_SHIRQ)) { spin_unlock_irqrestore(&irq_controller_lock, flags); return -EBUSY; } @@ -709,12 +705,6 @@ int setup_irq(unsigned int irq, struct irqaction *new) desc->running = 0; desc->pending = 0; desc->disable_depth = 1; - - if (new->flags & SA_TRIGGER_MASK) { - unsigned int type = new->flags & SA_TRIGGER_MASK; - desc->chip->set_type(irq, type); - } - if (!desc->noautoenable) { desc->disable_depth = 0; desc->chip->unmask(irq); diff --git a/trunk/arch/arm/mach-epxa10db/Kconfig b/trunk/arch/arm/mach-epxa10db/Kconfig deleted file mode 100644 index 55d896dd4950..000000000000 --- a/trunk/arch/arm/mach-epxa10db/Kconfig +++ /dev/null @@ -1,23 +0,0 @@ -if ARCH_CAMELOT - -menu "Epxa10db" - -comment "PLD hotswap support" - -config PLD - bool - default y - -config PLD_HOTSWAP - bool "Support for PLD device hotplugging (experimental)" - depends on EXPERIMENTAL - help - This enables support for the dynamic loading and configuration of - compatible drivers when the contents of the PLD are changed. This - is still experimental and requires configuration tools which are - not yet generally available. Say N here. You must enable the kernel - module loader for this feature to work. - -endmenu - -endif diff --git a/trunk/arch/arm/mach-epxa10db/Makefile b/trunk/arch/arm/mach-epxa10db/Makefile deleted file mode 100644 index 24fbd7d3a3c1..000000000000 --- a/trunk/arch/arm/mach-epxa10db/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# Makefile for the linux kernel. -# - -# Object file lists. - -obj-y := arch.o irq.o mm.o time.o -obj-m := -obj-n := -obj- := - diff --git a/trunk/arch/arm/mach-epxa10db/Makefile.boot b/trunk/arch/arm/mach-epxa10db/Makefile.boot deleted file mode 100644 index 28bec7d3fc88..000000000000 --- a/trunk/arch/arm/mach-epxa10db/Makefile.boot +++ /dev/null @@ -1,2 +0,0 @@ - zreladdr-y := 0x00008000 - diff --git a/trunk/arch/arm/mach-epxa10db/arch.c b/trunk/arch/arm/mach-epxa10db/arch.c deleted file mode 100644 index 44c56571d183..000000000000 --- a/trunk/arch/arm/mach-epxa10db/arch.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * linux/arch/arm/mach-epxa10db/arch.c - * - * Copyright (C) 2000 Deep Blue Solutions Ltd - * 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 - */ -#include -#include -#include - -#include -#include -#include - -#include - -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 = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = serial_platform_data, - }, -}; - -extern void epxa10db_map_io(void); -extern void epxa10db_init_irq(void); -extern struct sys_timer epxa10db_timer; - -MACHINE_START(CAMELOT, "Altera Epxa10db") - /* Maintainer: Altera Corporation */ - .phys_ram = 0x00000000, - .phys_io = 0x7fffc000, - .io_pg_offst = ((0xffffc000) >> 18) & 0xfffc, - .map_io = epxa10db_map_io, - .init_irq = epxa10db_init_irq, - .timer = &epxa10db_timer, -MACHINE_END - diff --git a/trunk/arch/arm/mach-epxa10db/irq.c b/trunk/arch/arm/mach-epxa10db/irq.c deleted file mode 100644 index 9bf927e13309..000000000000 --- a/trunk/arch/arm/mach-epxa10db/irq.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * linux/arch/arm/mach-epxa10db/irq.c - * - * 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 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static void epxa_mask_irq(unsigned int irq) -{ - writel(1 << irq, INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE))); -} - -static void epxa_unmask_irq(unsigned int irq) -{ - writel(1 << irq, INT_MS(IO_ADDRESS(EXC_INT_CTRL00_BASE))); -} - - -static struct irqchip epxa_irq_chip = { - .ack = epxa_mask_irq, - .mask = epxa_mask_irq, - .unmask = epxa_unmask_irq, -}; - -static struct resource irq_resource = { - .name = "irq_handler", - .start = IO_ADDRESS(EXC_INT_CTRL00_BASE), - .end = IO_ADDRESS(INT_PRIORITY_FC(EXC_INT_CTRL00_BASE))+4, -}; - -void __init epxa10db_init_irq(void) -{ - unsigned int i; - - request_resource(&iomem_resource, &irq_resource); - - /* - * This bit sets up the interrupt controller using - * the 6 PLD interrupts mode (the default) each - * irqs is assigned a priority which is the same - * as its interrupt number. This scheme is used because - * its easy, but you may want to change it depending - * on the contents of your PLD - */ - - writel(3,INT_MODE(IO_ADDRESS(EXC_INT_CTRL00_BASE))); - for (i = 0; i < NR_IRQS; i++){ - writel(i+1, INT_PRIORITY_P0(IO_ADDRESS(EXC_INT_CTRL00_BASE)) + (4*i)); - set_irq_chip(i,&epxa_irq_chip); - set_irq_handler(i,do_level_IRQ); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - } - - /* Disable all interrupts */ - writel(-1,INT_MC(IO_ADDRESS(EXC_INT_CTRL00_BASE))); - -} diff --git a/trunk/arch/arm/mach-epxa10db/mm.c b/trunk/arch/arm/mach-epxa10db/mm.c deleted file mode 100644 index cfd0d2182d44..000000000000 --- a/trunk/arch/arm/mach-epxa10db/mm.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * linux/arch/arm/mach-epxa10db/mm.c - * - * MM routines for Altera'a Epxa10db board - * - * 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 - */ -#include -#include - -#include -#include -#include -#include - -#include - -/* Page table mapping for I/O region */ - -static struct map_desc epxa10db_io_desc[] __initdata = { - { - .virtual = IO_ADDRESS(EXC_REGISTERS_BASE), - .pfn = __phys_to_pfn(EXC_REGISTERS_BASE), - .length = SZ_16K, - .type = MT_DEVICE - }, { - .virtual = IO_ADDRESS(EXC_PLD_BLOCK0_BASE), - .pfn = __phys_to_pfn(EXC_PLD_BLOCK0_BASE), - .length = SZ_16K, - .type = MT_DEVICE - }, { - .virtual = IO_ADDRESS(EXC_PLD_BLOCK1_BASE), - .pfn =__phys_to_pfn(EXC_PLD_BLOCK1_BASE), - .length = SZ_16K, - .type = MT_DEVICE - }, { - .virtual = IO_ADDRESS(EXC_PLD_BLOCK2_BASE), - .physical = __phys_to_pfn(EXC_PLD_BLOCK2_BASE), - .length = SZ_16K, - .type = MT_DEVICE - }, { - .virtual = IO_ADDRESS(EXC_PLD_BLOCK3_BASE), - .pfn = __phys_to_pfn(EXC_PLD_BLOCK3_BASE), - .length = SZ_16K, - .type = MT_DEVICE - }, { - .virtual = FLASH_VADDR(EXC_EBI_BLOCK0_BASE), - .pfn = __phys_to_pfn(EXC_EBI_BLOCK0_BASE), - .length = SZ_16M, - .type = MT_DEVICE - } -}; - -void __init epxa10db_map_io(void) -{ - iotable_init(epxa10db_io_desc, ARRAY_SIZE(epxa10db_io_desc)); -} diff --git a/trunk/arch/arm/mach-epxa10db/time.c b/trunk/arch/arm/mach-epxa10db/time.c deleted file mode 100644 index 4b1084dde8dd..000000000000 --- a/trunk/arch/arm/mach-epxa10db/time.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * linux/arch/arm/mach-epxa10db/time.c - * - * Copyright (C) 2000 Deep Blue Solutions - * 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 version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include - -#include -#include -#include - -#include - -#define TIMER00_TYPE (volatile unsigned int*) -#include - -static int epxa10db_set_rtc(void) -{ - return 1; -} - -static int epxa10db_rtc_init(void) -{ - set_rtc = epxa10db_set_rtc; - - return 0; -} - -__initcall(epxa10db_rtc_init); - - -/* - * IRQ handler for the timer - */ -static irqreturn_t -epxa10db_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) -{ - write_seqlock(&xtime_lock); - - // ...clear the interrupt - *TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))|=TIMER0_CR_CI_MSK; - - timer_tick(regs); - write_sequnlock(&xtime_lock); - - return IRQ_HANDLED; -} - -static struct irqaction epxa10db_timer_irq = { - .name = "Excalibur Timer Tick", - .flags = SA_INTERRUPT | SA_TIMER, - .handler = epxa10db_timer_interrupt, -}; - -/* - * Set up timer interrupt, and return the current time in seconds. - */ -static void __init epxa10db_timer_init(void) -{ - /* Start the timer */ - *TIMER0_LIMIT(IO_ADDRESS(EXC_TIMER00_BASE))=(unsigned int)(EXC_AHB2_CLK_FREQUENCY/200); - *TIMER0_PRESCALE(IO_ADDRESS(EXC_TIMER00_BASE))=1; - *TIMER0_CR(IO_ADDRESS(EXC_TIMER00_BASE))=TIMER0_CR_IE_MSK | TIMER0_CR_S_MSK; - - setup_irq(IRQ_TIMER0, &epxa10db_timer_irq); -} - -struct sys_timer epxa10db_timer = { - .init = epxa10db_timer_init, -}; diff --git a/trunk/arch/arm/mach-footbridge/netwinder-hw.c b/trunk/arch/arm/mach-footbridge/netwinder-hw.c index 9e563de465b5..775f85fc8513 100644 --- a/trunk/arch/arm/mach-footbridge/netwinder-hw.c +++ b/trunk/arch/arm/mach-footbridge/netwinder-hw.c @@ -601,7 +601,6 @@ EXPORT_SYMBOL(gpio_lock); EXPORT_SYMBOL(gpio_modify_op); EXPORT_SYMBOL(gpio_modify_io); EXPORT_SYMBOL(cpld_modify); -EXPORT_SYMBOL(gpio_read); /* * Initialise any other hardware after we've got the PCI bus diff --git a/trunk/arch/arm/mach-integrator/time.c b/trunk/arch/arm/mach-integrator/time.c index 3c22c16b38bf..9f46aaef8968 100644 --- a/trunk/arch/arm/mach-integrator/time.c +++ b/trunk/arch/arm/mach-integrator/time.c @@ -96,8 +96,7 @@ static struct rtc_ops rtc_ops = { .set_alarm = rtc_set_alarm, }; -static irqreturn_t arm_rtc_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { writel(0, rtc_base + RTC_EOI); return IRQ_HANDLED; @@ -125,7 +124,7 @@ static int rtc_probe(struct amba_device *dev, void *id) xtime.tv_sec = __raw_readl(rtc_base + RTC_DR); - ret = request_irq(dev->irq[0], arm_rtc_interrupt, SA_INTERRUPT, + ret = request_irq(dev->irq[0], rtc_interrupt, SA_INTERRUPT, "rtc-pl030", dev); if (ret) goto map_out; diff --git a/trunk/arch/arm/mach-omap1/serial.c b/trunk/arch/arm/mach-omap1/serial.c index 7a68f098a025..fcfb81d13cfe 100644 --- a/trunk/arch/arm/mach-omap1/serial.c +++ b/trunk/arch/arm/mach-omap1/serial.c @@ -252,8 +252,9 @@ static void __init omap_serial_set_port_wakeup(int gpio_nr) return; } omap_set_gpio_direction(gpio_nr, 1); + set_irq_type(OMAP_GPIO_IRQ(gpio_nr), IRQT_RISING); ret = request_irq(OMAP_GPIO_IRQ(gpio_nr), &omap_serial_wake_interrupt, - SA_TRIGGER_RISING, "serial wakeup", NULL); + 0, "serial wakeup", NULL); if (ret) { omap_free_gpio(gpio_nr); printk(KERN_ERR "No interrupt for UART wake GPIO: %i\n", diff --git a/trunk/arch/arm/mach-pxa/corgi.c b/trunk/arch/arm/mach-pxa/corgi.c index 5a7b873f29b3..100fb31b5156 100644 --- a/trunk/arch/arm/mach-pxa/corgi.c +++ b/trunk/arch/arm/mach-pxa/corgi.c @@ -213,14 +213,15 @@ static int corgi_mci_init(struct device *dev, irqreturn_t (*corgi_detect_int)(in corgi_mci_platform_data.detect_delay = msecs_to_jiffies(250); - err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int, - SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING, - "MMC card detect", data); + err = request_irq(CORGI_IRQ_GPIO_nSD_DETECT, corgi_detect_int, SA_INTERRUPT, + "MMC card detect", data); if (err) { printk(KERN_ERR "corgi_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); return -1; } + set_irq_type(CORGI_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE); + return 0; } diff --git a/trunk/arch/arm/mach-pxa/poodle.c b/trunk/arch/arm/mach-pxa/poodle.c index 663c95005985..eef3de26ad37 100644 --- a/trunk/arch/arm/mach-pxa/poodle.c +++ b/trunk/arch/arm/mach-pxa/poodle.c @@ -146,14 +146,15 @@ static int poodle_mci_init(struct device *dev, irqreturn_t (*poodle_detect_int)( poodle_mci_platform_data.detect_delay = msecs_to_jiffies(250); - err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int, - SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING, - "MMC card detect", data); + err = request_irq(POODLE_IRQ_GPIO_nSD_DETECT, poodle_detect_int, SA_INTERRUPT, + "MMC card detect", data); if (err) { printk(KERN_ERR "poodle_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); return -1; } + set_irq_type(POODLE_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE); + return 0; } diff --git a/trunk/arch/arm/mach-pxa/spitz.c b/trunk/arch/arm/mach-pxa/spitz.c index a9eacc06555f..f2007db0cda5 100644 --- a/trunk/arch/arm/mach-pxa/spitz.c +++ b/trunk/arch/arm/mach-pxa/spitz.c @@ -296,14 +296,15 @@ static int spitz_mci_init(struct device *dev, irqreturn_t (*spitz_detect_int)(in spitz_mci_platform_data.detect_delay = msecs_to_jiffies(250); - err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int, - SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING, - "MMC card detect", data); + err = request_irq(SPITZ_IRQ_GPIO_nSD_DETECT, spitz_detect_int, SA_INTERRUPT, + "MMC card detect", data); if (err) { printk(KERN_ERR "spitz_mci_init: MMC/SD: can't request MMC card detect IRQ\n"); return -1; } + set_irq_type(SPITZ_IRQ_GPIO_nSD_DETECT, IRQT_BOTHEDGE); + return 0; } diff --git a/trunk/arch/arm/mach-realview/localtimer.c b/trunk/arch/arm/mach-realview/localtimer.c index caf6b8bb6c95..c9d7c596b200 100644 --- a/trunk/arch/arm/mach-realview/localtimer.c +++ b/trunk/arch/arm/mach-realview/localtimer.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/arm/mach-s3c2410/usb-simtec.c b/trunk/arch/arm/mach-s3c2410/usb-simtec.c index 495f8c6ffcb6..5098b50158a3 100644 --- a/trunk/arch/arm/mach-s3c2410/usb-simtec.c +++ b/trunk/arch/arm/mach-s3c2410/usb-simtec.c @@ -84,13 +84,13 @@ static void usb_simtec_enableoc(struct s3c2410_hcd_info *info, int on) int ret; if (on) { - ret = request_irq(IRQ_USBOC, usb_simtec_ocirq, - SA_INTERRUPT | SA_TRIGGER_RISING | - SA_TRIGGER_FALLING, + ret = request_irq(IRQ_USBOC, usb_simtec_ocirq, SA_INTERRUPT, "USB Over-current", info); if (ret != 0) { printk(KERN_ERR "failed to request usb oc irq\n"); } + + set_irq_type(IRQ_USBOC, IRQT_BOTHEDGE); } else { free_irq(IRQ_USBOC, info); } diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index e84fdde6edf8..04cf0557e54b 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -83,8 +83,8 @@ config CPU_ARM920T # ARM922T config CPU_ARM922T bool "Support ARM922T processor" if ARCH_INTEGRATOR - depends on ARCH_CAMELOT || ARCH_LH7A40X || ARCH_INTEGRATOR - default y if ARCH_CAMELOT || ARCH_LH7A40X + depends on ARCH_LH7A40X || ARCH_INTEGRATOR + default y if ARCH_LH7A40X select CPU_32v4 select CPU_ABRT_EV4T select CPU_CACHE_V4WT diff --git a/trunk/arch/arm26/Kconfig b/trunk/arch/arm26/Kconfig index 274e07019b46..1f00b3d03a07 100644 --- a/trunk/arch/arm26/Kconfig +++ b/trunk/arch/arm26/Kconfig @@ -34,6 +34,10 @@ config FORCE_MAX_ZONEORDER int default 9 +config UID16 + bool + default y + config RWSEM_GENERIC_SPINLOCK bool default y diff --git a/trunk/arch/arm26/kernel/asm-offsets.c b/trunk/arch/arm26/kernel/asm-offsets.c index ac682d5fd039..4ccacaef94df 100644 --- a/trunk/arch/arm26/kernel/asm-offsets.c +++ b/trunk/arch/arm26/kernel/asm-offsets.c @@ -25,6 +25,13 @@ #if defined(__APCS_32__) && defined(CONFIG_CPU_26) #error Sorry, your compiler targets APCS-32 but this kernel requires APCS-26 #endif +#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95) +#error Sorry, your compiler is known to miscompile kernels. Only use gcc 2.95.3 and later. +#endif +#if __GNUC__ == 2 && __GNUC_MINOR__ == 95 +/* shame we can't detect the .1 or .2 releases */ +#warning GCC 2.95.2 and earlier miscompiles kernels. +#endif /* Use marker if you need to separate the values later */ diff --git a/trunk/arch/cris/Kconfig b/trunk/arch/cris/Kconfig index b83261949737..e5979d68e352 100644 --- a/trunk/arch/cris/Kconfig +++ b/trunk/arch/cris/Kconfig @@ -9,6 +9,10 @@ config MMU bool default y +config UID16 + bool + default y + config RWSEM_GENERIC_SPINLOCK bool default y diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index 61261b78ced7..ec85c0d6c6da 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -274,11 +274,6 @@ config GPREL_DATA_NONE endchoice -config FRV_ONCPU_SERIAL - bool "Use on-CPU serial ports" - select SERIAL_8250 - default y - config PCI bool "Use PCI" depends on MB93090_MB00 @@ -310,7 +305,23 @@ config RESERVE_DMA_COHERENT source "drivers/pci/Kconfig" -source "drivers/pcmcia/Kconfig" +config PCMCIA + tristate "Use PCMCIA" + help + Say Y here if you want to attach PCMCIA- or PC-cards to your FR-V + board. These are credit-card size devices such as network cards, + modems or hard drives often used with laptops computers. There are + actually two varieties of these cards: the older 16 bit PCMCIA cards + and the newer 32 bit CardBus cards. If you want to use CardBus + cards, you need to say Y here and also to "CardBus support" below. + + To use your PC-cards, you will need supporting software from David + Hinds pcmcia-cs package (see the file + for location). Please also read the PCMCIA-HOWTO, available from + . + + To compile this driver as modules, choose M here: the + modules will be called pcmcia_core and ds. #config MATH_EMULATION # bool "Math emulation support (EXPERIMENTAL)" diff --git a/trunk/arch/frv/Kconfig.debug b/trunk/arch/frv/Kconfig.debug index 211f01bc4caa..0034b654995d 100644 --- a/trunk/arch/frv/Kconfig.debug +++ b/trunk/arch/frv/Kconfig.debug @@ -2,10 +2,32 @@ menu "Kernel hacking" source "lib/Kconfig.debug" +config EARLY_PRINTK + bool "Early printk" + depends on EMBEDDED && DEBUG_KERNEL + default n + help + Write kernel log output directly into the VGA buffer or to a serial + port. + + This is useful for kernel debugging when your machine crashes very + early before the console code is initialized. For normal operation + it is not recommended because it looks ugly and doesn't cooperate + with klogd/syslogd or the X server. You should normally N here, + unless you want to debug such a crash. + config DEBUG_STACKOVERFLOW bool "Check for stack overflows" depends on DEBUG_KERNEL +config DEBUG_PAGEALLOC + bool "Page alloc debugging" + depends on DEBUG_KERNEL + help + Unmap pages from the kernel linear mapping after free_pages(). + This results in a large slowdown, but helps to find certain types + of memory corruptions. + config GDBSTUB bool "Remote GDB kernel debugging" depends on DEBUG_KERNEL diff --git a/trunk/arch/frv/Makefile b/trunk/arch/frv/Makefile index 90c0fb8d9dc3..54046d2386f5 100644 --- a/trunk/arch/frv/Makefile +++ b/trunk/arch/frv/Makefile @@ -109,10 +109,10 @@ bootstrap: $(Q)$(MAKEBOOT) bootstrap archmrproper: - $(Q)$(MAKE) $(build)=arch/frv/boot mrproper + $(Q)$(MAKE) -C arch/frv/boot mrproper archclean: - $(Q)$(MAKE) $(build)=arch/frv/boot clean + $(Q)$(MAKE) -C arch/frv/boot clean archdep: scripts/mkdep symlinks - $(Q)$(MAKE) $(build)=arch/frv/boot dep + $(Q)$(MAKE) -C arch/frv/boot dep diff --git a/trunk/arch/frv/kernel/Makefile b/trunk/arch/frv/kernel/Makefile index 5a827b349b5e..422f30ede575 100644 --- a/trunk/arch/frv/kernel/Makefile +++ b/trunk/arch/frv/kernel/Makefile @@ -21,4 +21,3 @@ obj-$(CONFIG_PM) += pm.o cmode.o obj-$(CONFIG_MB93093_PDK) += pm-mb93093.o obj-$(CONFIG_SYSCTL) += sysctl.o obj-$(CONFIG_FUTEX) += futex.o -obj-$(CONFIG_MODULES) += module.o diff --git a/trunk/arch/frv/kernel/frv_ksyms.c b/trunk/arch/frv/kernel/frv_ksyms.c index 5f118c89d091..1a76d5247190 100644 --- a/trunk/arch/frv/kernel/frv_ksyms.c +++ b/trunk/arch/frv/kernel/frv_ksyms.c @@ -16,11 +16,10 @@ #include #include #include -#include +#include extern void dump_thread(struct pt_regs *, struct user *); extern long __memcpy_user(void *dst, const void *src, size_t count); -extern long __memset_user(void *dst, const void *src, size_t count); /* platform dependent support */ @@ -51,11 +50,7 @@ EXPORT_SYMBOL(disable_irq); EXPORT_SYMBOL(__res_bus_clock_speed_HZ); EXPORT_SYMBOL(__page_offset); EXPORT_SYMBOL(__memcpy_user); -EXPORT_SYMBOL(__memset_user); -EXPORT_SYMBOL(frv_dcache_writeback); -EXPORT_SYMBOL(frv_cache_invalidate); -EXPORT_SYMBOL(frv_icache_invalidate); -EXPORT_SYMBOL(frv_cache_wback_inv); +EXPORT_SYMBOL(flush_dcache_page); #ifndef CONFIG_MMU EXPORT_SYMBOL(memory_start); @@ -77,9 +72,6 @@ EXPORT_SYMBOL(memcmp); EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(memmove); -EXPORT_SYMBOL(__outsl_ns); -EXPORT_SYMBOL(__insl_ns); - EXPORT_SYMBOL(get_wchan); #ifdef CONFIG_FRV_OUTOFLINE_ATOMIC_OPS @@ -88,13 +80,14 @@ EXPORT_SYMBOL(atomic_test_and_OR_mask); EXPORT_SYMBOL(atomic_test_and_XOR_mask); EXPORT_SYMBOL(atomic_add_return); EXPORT_SYMBOL(atomic_sub_return); +EXPORT_SYMBOL(__xchg_8); +EXPORT_SYMBOL(__xchg_16); EXPORT_SYMBOL(__xchg_32); +EXPORT_SYMBOL(__cmpxchg_8); +EXPORT_SYMBOL(__cmpxchg_16); EXPORT_SYMBOL(__cmpxchg_32); #endif -EXPORT_SYMBOL(__debug_bug_printk); -EXPORT_SYMBOL(__delay_loops_MHz); - /* * libgcc functions - functions that are used internally by the * compiler... (prototypes are not correct though, but that @@ -108,8 +101,6 @@ extern void __divdi3(void); extern void __lshrdi3(void); extern void __moddi3(void); extern void __muldi3(void); -extern void __mulll(void); -extern void __umulll(void); extern void __negdi2(void); extern void __ucmpdi2(void); extern void __udivdi3(void); @@ -125,10 +116,8 @@ EXPORT_SYMBOL(__ashrdi3); EXPORT_SYMBOL(__lshrdi3); //EXPORT_SYMBOL(__moddi3); EXPORT_SYMBOL(__muldi3); -EXPORT_SYMBOL(__mulll); -EXPORT_SYMBOL(__umulll); EXPORT_SYMBOL(__negdi2); -EXPORT_SYMBOL(__ucmpdi2); +//EXPORT_SYMBOL(__ucmpdi2); //EXPORT_SYMBOL(__udivdi3); //EXPORT_SYMBOL(__udivmoddi4); //EXPORT_SYMBOL(__umoddi3); diff --git a/trunk/arch/frv/kernel/irq.c b/trunk/arch/frv/kernel/irq.c index 59580c59c62c..8c524cdd2717 100644 --- a/trunk/arch/frv/kernel/irq.c +++ b/trunk/arch/frv/kernel/irq.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include @@ -179,8 +178,6 @@ void disable_irq_nosync(unsigned int irq) spin_unlock_irqrestore(&level->lock, flags); } -EXPORT_SYMBOL(disable_irq_nosync); - /** * disable_irq - disable an irq and wait for completion * @irq: Interrupt to disable @@ -207,8 +204,6 @@ void disable_irq(unsigned int irq) #endif } -EXPORT_SYMBOL(disable_irq); - /** * enable_irq - enable handling of an irq * @irq: Interrupt to enable @@ -273,8 +268,6 @@ void enable_irq(unsigned int irq) spin_unlock_irqrestore(&level->lock, flags); } -EXPORT_SYMBOL(enable_irq); - /*****************************************************************************/ /* * handles all normal device IRQ's @@ -432,8 +425,6 @@ int request_irq(unsigned int irq, return retval; } -EXPORT_SYMBOL(request_irq); - /** * free_irq - free an interrupt * @irq: Interrupt line to free @@ -505,8 +496,6 @@ void free_irq(unsigned int irq, void *dev_id) } } -EXPORT_SYMBOL(free_irq); - /* * IRQ autodetection code.. * @@ -530,8 +519,6 @@ unsigned long probe_irq_on(void) return 0; } -EXPORT_SYMBOL(probe_irq_on); - /* * Return a mask of triggered interrupts (this * can handle only legacy ISA interrupts). @@ -555,8 +542,6 @@ unsigned int probe_irq_mask(unsigned long xmask) return 0; } -EXPORT_SYMBOL(probe_irq_mask); - /* * Return the one interrupt that triggered (this can * handle any interrupt source). @@ -586,8 +571,6 @@ int probe_irq_off(unsigned long xmask) return -1; } -EXPORT_SYMBOL(probe_irq_off); - /* this was setup_x86_irq but it seems pretty generic */ int setup_irq(unsigned int irq, struct irqaction *new) { diff --git a/trunk/arch/frv/kernel/module.c b/trunk/arch/frv/kernel/module.c deleted file mode 100644 index 850d168f69fc..000000000000 --- a/trunk/arch/frv/kernel/module.c +++ /dev/null @@ -1,80 +0,0 @@ -/* module.c: FRV specific module loading bits - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - Derived from arch/i386/kernel/module.c, Copyright (C) 2001 Rusty Russell. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include -#include -#include -#include -#include -#include - -#if 0 -#define DEBUGP printk -#else -#define DEBUGP(fmt...) -#endif - -void *module_alloc(unsigned long size) -{ - if (size == 0) - return NULL; - - return vmalloc_exec(size); -} - - -/* Free memory returned from module_alloc */ -void module_free(struct module *mod, void *module_region) -{ - vfree(module_region); - /* FIXME: If module_region == mod->init_region, trim exception - table entries. */ -} - -/* We don't need anything special. */ -int module_frob_arch_sections(Elf_Ehdr *hdr, - Elf_Shdr *sechdrs, - char *secstrings, - struct module *mod) -{ - return 0; -} - -int apply_relocate(Elf32_Shdr *sechdrs, - const char *strtab, - unsigned int symindex, - unsigned int relsec, - struct module *me) -{ - printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", me->name); - return -ENOEXEC; -} - -int apply_relocate_add(Elf32_Shdr *sechdrs, - const char *strtab, - unsigned int symindex, - unsigned int relsec, - struct module *me) -{ - printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n", me->name); - return -ENOEXEC; -} - -int module_finalize(const Elf_Ehdr *hdr, - const Elf_Shdr *sechdrs, - struct module *me) -{ - return 0; -} - -void module_arch_cleanup(struct module *mod) -{ -} diff --git a/trunk/arch/frv/kernel/pm.c b/trunk/arch/frv/kernel/pm.c index f0b8fff3e733..712c3c24c954 100644 --- a/trunk/arch/frv/kernel/pm.c +++ b/trunk/arch/frv/kernel/pm.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -28,7 +27,6 @@ #include "local.h" void (*pm_power_off)(void); -EXPORT_SYMBOL(pm_power_off); extern void frv_change_cmode(int); diff --git a/trunk/arch/frv/kernel/setup.c b/trunk/arch/frv/kernel/setup.c index 5908deae9607..767ebb55bd83 100644 --- a/trunk/arch/frv/kernel/setup.c +++ b/trunk/arch/frv/kernel/setup.c @@ -787,7 +787,6 @@ void __init setup_arch(char **cmdline_p) #endif /* register those serial ports that are available */ -#ifdef CONFIG_FRV_ONCPU_SERIAL #ifndef CONFIG_GDBSTUB_UART0 __reg(UART0_BASE + UART_IER * 8) = 0; early_serial_setup(&__frv_uart0); @@ -796,7 +795,6 @@ void __init setup_arch(char **cmdline_p) __reg(UART1_BASE + UART_IER * 8) = 0; early_serial_setup(&__frv_uart1); #endif -#endif #if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) /* we need to initialize the Flashrom device here since we might diff --git a/trunk/arch/frv/kernel/time.c b/trunk/arch/frv/kernel/time.c index 24cf85f89e40..2e9741227b73 100644 --- a/trunk/arch/frv/kernel/time.c +++ b/trunk/arch/frv/kernel/time.c @@ -189,8 +189,6 @@ void do_gettimeofday(struct timeval *tv) tv->tv_usec = usec; } -EXPORT_SYMBOL(do_gettimeofday); - int do_settimeofday(struct timespec *tv) { time_t wtm_sec, sec = tv->tv_sec; @@ -220,7 +218,6 @@ int do_settimeofday(struct timespec *tv) clock_was_set(); return 0; } - EXPORT_SYMBOL(do_settimeofday); /* diff --git a/trunk/arch/frv/kernel/traps.c b/trunk/arch/frv/kernel/traps.c index 9eb84b2e6abc..89073cae4b5d 100644 --- a/trunk/arch/frv/kernel/traps.c +++ b/trunk/arch/frv/kernel/traps.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -251,8 +250,6 @@ void dump_stack(void) show_stack(NULL, NULL); } -EXPORT_SYMBOL(dump_stack); - void show_stack(struct task_struct *task, unsigned long *sp) { } diff --git a/trunk/arch/frv/kernel/uaccess.c b/trunk/arch/frv/kernel/uaccess.c index 9b751c0f0e84..f3fd58a5bc4a 100644 --- a/trunk/arch/frv/kernel/uaccess.c +++ b/trunk/arch/frv/kernel/uaccess.c @@ -10,7 +10,6 @@ */ #include -#include #include /*****************************************************************************/ @@ -59,11 +58,8 @@ long strncpy_from_user(char *dst, const char *src, long count) memset(p, 0, count); /* clear remainder of buffer [security] */ return err; - } /* end strncpy_from_user() */ -EXPORT_SYMBOL(strncpy_from_user); - /*****************************************************************************/ /* * Return the size of a string (including the ending 0) @@ -96,7 +92,4 @@ long strnlen_user(const char *src, long count) } return p - src + 1; /* return length including NUL */ - } /* end strnlen_user() */ - -EXPORT_SYMBOL(strnlen_user); diff --git a/trunk/arch/frv/kernel/vmlinux.lds.S b/trunk/arch/frv/kernel/vmlinux.lds.S index f474534ba78a..fceafd2cc202 100644 --- a/trunk/arch/frv/kernel/vmlinux.lds.S +++ b/trunk/arch/frv/kernel/vmlinux.lds.S @@ -112,7 +112,6 @@ SECTIONS #endif ) SCHED_TEXT - LOCK_TEXT *(.fixup) *(.gnu.warning) *(.exitcall.exit) diff --git a/trunk/arch/frv/lib/Makefile b/trunk/arch/frv/lib/Makefile index 08be305c9f44..19be2626d5e6 100644 --- a/trunk/arch/frv/lib/Makefile +++ b/trunk/arch/frv/lib/Makefile @@ -3,6 +3,6 @@ # lib-y := \ - __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o __ucmpdi2.o \ + __ashldi3.o __lshrdi3.o __muldi3.o __ashrdi3.o __negdi2.o \ checksum.o memcpy.o memset.o atomic-ops.o \ outsl_ns.o outsl_sw.o insl_ns.o insl_sw.o cache.o diff --git a/trunk/arch/frv/lib/__ucmpdi2.S b/trunk/arch/frv/lib/__ucmpdi2.S deleted file mode 100644 index d892f16ffaa9..000000000000 --- a/trunk/arch/frv/lib/__ucmpdi2.S +++ /dev/null @@ -1,45 +0,0 @@ -/* __ucmpdi2.S: 64-bit unsigned compare - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - - - .text - .p2align 4 - -############################################################################### -# -# int __ucmpdi2(unsigned long long a [GR8:GR9], -# unsigned long long b [GR10:GR11]) -# -# - returns 0, 1, or 2 as a <, =, > b respectively. -# -############################################################################### - .globl __ucmpdi2 - .type __ucmpdi2,@function -__ucmpdi2: - or.p gr8,gr0,gr4 - subcc gr8,gr10,gr0,icc0 - setlos.p #0,gr8 - bclr icc0,#2 ; a.msw < b.msw - - setlos.p #2,gr8 - bhilr icc0,#0 ; a.msw > b.msw - - subcc.p gr9,gr11,gr0,icc1 - setlos #0,gr8 - setlos.p #2,gr9 - setlos #1,gr7 - cknc icc1,cc6 - cor.p gr9,gr0,gr8, cc6,#1 - cckls icc1,cc4, cc6,#1 - andcr cc6,cc4,cc4 - cor gr7,gr0,gr8, cc4,#1 - bralr - .size __ucmpdi2, .-__ucmpdi2 diff --git a/trunk/arch/frv/lib/atomic-ops.S b/trunk/arch/frv/lib/atomic-ops.S index 545cd325ac57..b03d510a89e4 100644 --- a/trunk/arch/frv/lib/atomic-ops.S +++ b/trunk/arch/frv/lib/atomic-ops.S @@ -127,6 +127,48 @@ atomic_sub_return: .size atomic_sub_return, .-atomic_sub_return +############################################################################### +# +# uint8_t __xchg_8(uint8_t i, uint8_t *v) +# +############################################################################### + .globl __xchg_8 + .type __xchg_8,@function +__xchg_8: + or.p gr8,gr8,gr10 +0: + orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ + ckeq icc3,cc7 + ldub.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */ + orcr cc7,cc7,cc3 /* set CC3 to true */ + cstb.p gr10,@(gr9,gr0) ,cc3,#1 + corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ + beq icc3,#0,0b + bralr + + .size __xchg_8, .-__xchg_8 + +############################################################################### +# +# uint16_t __xchg_16(uint16_t i, uint16_t *v) +# +############################################################################### + .globl __xchg_16 + .type __xchg_16,@function +__xchg_16: + or.p gr8,gr8,gr10 +0: + orcc gr0,gr0,gr0,icc3 /* set ICC3.Z */ + ckeq icc3,cc7 + lduh.p @(gr9,gr0),gr8 /* LD.P/ORCR must be atomic */ + orcr cc7,cc7,cc3 /* set CC3 to true */ + csth.p gr10,@(gr9,gr0) ,cc3,#1 + corcc gr29,gr29,gr0 ,cc3,#1 /* clear ICC3.Z if store happens */ + beq icc3,#0,0b + bralr + + .size __xchg_16, .-__xchg_16 + ############################################################################### # # uint32_t __xchg_32(uint32_t i, uint32_t *v) @@ -148,6 +190,56 @@ __xchg_32: .size __xchg_32, .-__xchg_32 +############################################################################### +# +# uint8_t __cmpxchg_8(uint8_t *v, uint8_t test, uint8_t new) +# +############################################################################### + .globl __cmpxchg_8 + .type __cmpxchg_8,@function +__cmpxchg_8: + or.p gr8,gr8,gr11 +0: + orcc gr0,gr0,gr0,icc3 + ckeq icc3,cc7 + ldub.p @(gr11,gr0),gr8 + orcr cc7,cc7,cc3 + sub gr8,gr9,gr7 + sllicc gr7,#24,gr0,icc0 + bne icc0,#0,1f + cstb.p gr10,@(gr11,gr0) ,cc3,#1 + corcc gr29,gr29,gr0 ,cc3,#1 + beq icc3,#0,0b +1: + bralr + + .size __cmpxchg_8, .-__cmpxchg_8 + +############################################################################### +# +# uint16_t __cmpxchg_16(uint16_t *v, uint16_t test, uint16_t new) +# +############################################################################### + .globl __cmpxchg_16 + .type __cmpxchg_16,@function +__cmpxchg_16: + or.p gr8,gr8,gr11 +0: + orcc gr0,gr0,gr0,icc3 + ckeq icc3,cc7 + lduh.p @(gr11,gr0),gr8 + orcr cc7,cc7,cc3 + sub gr8,gr9,gr7 + sllicc gr7,#16,gr0,icc0 + bne icc0,#0,1f + csth.p gr10,@(gr11,gr0) ,cc3,#1 + corcc gr29,gr29,gr0 ,cc3,#1 + beq icc3,#0,0b +1: + bralr + + .size __cmpxchg_16, .-__cmpxchg_16 + ############################################################################### # # uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new) diff --git a/trunk/arch/frv/lib/checksum.c b/trunk/arch/frv/lib/checksum.c index 20e7dfc474ef..7bf5bd6cac8a 100644 --- a/trunk/arch/frv/lib/checksum.c +++ b/trunk/arch/frv/lib/checksum.c @@ -33,7 +33,6 @@ #include #include -#include static inline unsigned short from32to16(unsigned long x) { @@ -116,52 +115,34 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) return result; } -EXPORT_SYMBOL(csum_partial); - /* * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c */ unsigned short ip_compute_csum(const unsigned char * buff, int len) { - return ~do_csum(buff, len); + return ~do_csum(buff,len); } -EXPORT_SYMBOL(ip_compute_csum); - /* * copy from fs while checksumming, otherwise like csum_partial */ + unsigned int -csum_partial_copy_from_user(const char __user *src, char *dst, - int len, int sum, int *csum_err) +csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *csum_err) { - int rem; - - if (csum_err) - *csum_err = 0; - - rem = copy_from_user(dst, src, len); - if (rem != 0) { - if (csum_err) - *csum_err = -EFAULT; - memset(dst + len - rem, 0, rem); - len = rem; - } - + if (csum_err) *csum_err = 0; + memcpy(dst, src, len); return csum_partial(dst, len, sum); } -EXPORT_SYMBOL(csum_partial_copy_from_user); - /* * copy from ds while checksumming, otherwise like csum_partial */ + unsigned int csum_partial_copy(const char *src, char *dst, int len, int sum) { memcpy(dst, src, len); return csum_partial(dst, len, sum); } - -EXPORT_SYMBOL(csum_partial_copy); diff --git a/trunk/arch/frv/mb93090-mb00/Makefile b/trunk/arch/frv/mb93090-mb00/Makefile index 76595e870733..3faf0f8cf9b5 100644 --- a/trunk/arch/frv/mb93090-mb00/Makefile +++ b/trunk/arch/frv/mb93090-mb00/Makefile @@ -3,7 +3,7 @@ # ifeq "$(CONFIG_PCI)" "y" -obj-y := pci-frv.o pci-irq.o pci-vdk.o pci-iomap.o +obj-y := pci-frv.o pci-irq.o pci-vdk.o ifeq "$(CONFIG_MMU)" "y" obj-y += pci-dma.o diff --git a/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c b/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c index 4985466b1a7c..2082a9647f4f 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c +++ b/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c @@ -83,8 +83,6 @@ void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_hand return NULL; } -EXPORT_SYMBOL(dma_alloc_coherent); - void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) { struct dma_alloc_record *rec; @@ -104,8 +102,6 @@ void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_ BUG(); } -EXPORT_SYMBOL(dma_free_coherent); - /* * Map a single buffer of the indicated size for DMA in streaming mode. * The 32-bit bus address to use is returned. @@ -124,8 +120,6 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, return virt_to_bus(ptr); } -EXPORT_SYMBOL(dma_map_single); - /* * Map a set of buffers described by scatterlist in streaming * mode for DMA. This is the scather-gather version of the @@ -156,5 +150,3 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, return nents; } - -EXPORT_SYMBOL(dma_map_sg); diff --git a/trunk/arch/frv/mb93090-mb00/pci-dma.c b/trunk/arch/frv/mb93090-mb00/pci-dma.c index 671ce1e8434f..86fbdadc51b6 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-dma.c +++ b/trunk/arch/frv/mb93090-mb00/pci-dma.c @@ -28,15 +28,11 @@ void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_hand return ret; } -EXPORT_SYMBOL(dma_alloc_coherent); - void dma_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle) { consistent_free(vaddr); } -EXPORT_SYMBOL(dma_free_coherent); - /* * Map a single buffer of the indicated size for DMA in streaming mode. * The 32-bit bus address to use is returned. @@ -55,8 +51,6 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, return virt_to_bus(ptr); } -EXPORT_SYMBOL(dma_map_single); - /* * Map a set of buffers described by scatterlist in streaming * mode for DMA. This is the scather-gather version of the @@ -102,8 +96,6 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, return nents; } -EXPORT_SYMBOL(dma_map_sg); - dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset, size_t size, enum dma_data_direction direction) { @@ -111,5 +103,3 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long off flush_dcache_page(page); return (dma_addr_t) page_to_phys(page) + offset; } - -EXPORT_SYMBOL(dma_map_page); diff --git a/trunk/arch/frv/mb93090-mb00/pci-iomap.c b/trunk/arch/frv/mb93090-mb00/pci-iomap.c deleted file mode 100644 index 068fa04bd527..000000000000 --- a/trunk/arch/frv/mb93090-mb00/pci-iomap.c +++ /dev/null @@ -1,29 +0,0 @@ -/* pci-iomap.c: description - * - * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include -#include - -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - unsigned long start = pci_resource_start(dev, bar); - unsigned long len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len || !start) - return NULL; - - if ((flags & IORESOURCE_IO) || (flags & IORESOURCE_MEM)) - return (void __iomem *) start; - - return NULL; -} - -EXPORT_SYMBOL(pci_iomap); diff --git a/trunk/arch/frv/mm/cache-page.c b/trunk/arch/frv/mm/cache-page.c index 0261cbe153b5..683b5e344318 100644 --- a/trunk/arch/frv/mm/cache-page.c +++ b/trunk/arch/frv/mm/cache-page.c @@ -11,7 +11,6 @@ #include #include #include -#include #include /*****************************************************************************/ @@ -39,8 +38,6 @@ void flush_dcache_page(struct page *page) } /* end flush_dcache_page() */ -EXPORT_SYMBOL(flush_dcache_page); - /*****************************************************************************/ /* * ICI takes a virtual address and the page may not currently have one @@ -67,5 +64,3 @@ void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, } } /* end flush_icache_user_range() */ - -EXPORT_SYMBOL(flush_icache_user_range); diff --git a/trunk/arch/frv/mm/extable.c b/trunk/arch/frv/mm/extable.c index caacf030ac75..41be1128dc64 100644 --- a/trunk/arch/frv/mm/extable.c +++ b/trunk/arch/frv/mm/extable.c @@ -43,7 +43,7 @@ static inline unsigned long search_one_table(const struct exception_table_entry */ unsigned long search_exception_table(unsigned long pc) { - const struct exception_table_entry *extab; + unsigned long ret = 0; /* determine if the fault lay during a memcpy_user or a memset_user */ if (__frame->lr == (unsigned long) &__memset_user_error_lr && @@ -55,10 +55,9 @@ unsigned long search_exception_table(unsigned long pc) */ return (unsigned long) &__memset_user_error_handler; } - - if (__frame->lr == (unsigned long) &__memcpy_user_error_lr && - (unsigned long) &memcpy <= pc && pc < (unsigned long) &__memcpy_end - ) { + else if (__frame->lr == (unsigned long) &__memcpy_user_error_lr && + (unsigned long) &memcpy <= pc && pc < (unsigned long) &__memcpy_end + ) { /* the fault occurred in a protected memset * - we search for the return address (in LR) instead of the program counter * - it was probably during a copy_to/from_user() @@ -66,10 +65,27 @@ unsigned long search_exception_table(unsigned long pc) return (unsigned long) &__memcpy_user_error_handler; } - extab = search_exception_tables(pc); - if (extab) - return extab->fixup; +#ifndef CONFIG_MODULES + /* there is only the kernel to search. */ + ret = search_one_table(__start___ex_table, __stop___ex_table - 1, pc); + return ret; + +#else + /* the kernel is the last "module" -- no need to treat it special */ + unsigned long flags; + struct module *mp; - return 0; + spin_lock_irqsave(&modlist_lock, flags); + + for (mp = module_list; mp != NULL; mp = mp->next) { + if (mp->ex_table_start == NULL || !(mp->flags & (MOD_RUNNING | MOD_INITIALIZING))) + continue; + ret = search_one_table(mp->ex_table_start, mp->ex_table_end - 1, pc); + if (ret) + break; + } + spin_unlock_irqrestore(&modlist_lock, flags); + return ret; +#endif } /* end search_exception_table() */ diff --git a/trunk/arch/frv/mm/highmem.c b/trunk/arch/frv/mm/highmem.c index 7f77db7fabc7..7dc8fbf3af97 100644 --- a/trunk/arch/frv/mm/highmem.c +++ b/trunk/arch/frv/mm/highmem.c @@ -9,7 +9,6 @@ * 2 of the License, or (at your option) any later version. */ #include -#include void *kmap(struct page *page) { @@ -19,8 +18,6 @@ void *kmap(struct page *page) return kmap_high(page); } -EXPORT_SYMBOL(kmap); - void kunmap(struct page *page) { if (in_interrupt()) @@ -30,12 +27,7 @@ void kunmap(struct page *page) kunmap_high(page); } -EXPORT_SYMBOL(kunmap); - struct page *kmap_atomic_to_page(void *ptr) { return virt_to_page(ptr); } - - -EXPORT_SYMBOL(kmap_atomic_to_page); diff --git a/trunk/arch/h8300/Kconfig b/trunk/arch/h8300/Kconfig index 80940d712acf..26698a49f153 100644 --- a/trunk/arch/h8300/Kconfig +++ b/trunk/arch/h8300/Kconfig @@ -21,6 +21,10 @@ config FPU bool default n +config UID16 + bool + default y + config RWSEM_GENERIC_SPINLOCK bool default y diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index d849c6870e3a..968fabd8723f 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -29,6 +29,10 @@ config MMU config SBUS bool +config UID16 + bool + default y + config GENERIC_ISA_DMA bool default y @@ -626,6 +630,10 @@ config REGPARM and passes the first three arguments of a function call in registers. This will probably break binary only modules. + This feature is only enabled for gcc-3.0 and later - earlier compilers + generate incorrect output with certain kernel constructs when + -mregparm=3 is used. + config SECCOMP bool "Enable seccomp to safely compute untrusted bytecode" depends on PROC_FS @@ -695,7 +703,7 @@ depends on PM && !X86_VISWS config APM tristate "APM (Advanced Power Management) BIOS support" - depends on PM + depends on PM && PM_LEGACY ---help--- APM is a BIOS specification for saving power using several different techniques. This is mostly useful for battery powered laptops with diff --git a/trunk/arch/i386/Makefile b/trunk/arch/i386/Makefile index b84119f9cc63..d121ea18460f 100644 --- a/trunk/arch/i386/Makefile +++ b/trunk/arch/i386/Makefile @@ -37,7 +37,10 @@ CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) # CPU-specific tuning. Anything which can be shared with UML should go here. include $(srctree)/arch/i386/Makefile.cpu -cflags-$(CONFIG_REGPARM) += -mregparm=3 +# -mregparm=3 works ok on gcc-3.0 and later +# +GCC_VERSION := $(call cc-version) +cflags-$(CONFIG_REGPARM) += $(shell if [ $(GCC_VERSION) -ge 0300 ] ; then echo "-mregparm=3"; fi ;) # Disable unit-at-a-time mode, it makes gcc use a lot more stack # due to the lack of sharing of stacklots. diff --git a/trunk/arch/i386/Makefile.cpu b/trunk/arch/i386/Makefile.cpu index dcd936ef45db..8e51456df23d 100644 --- a/trunk/arch/i386/Makefile.cpu +++ b/trunk/arch/i386/Makefile.cpu @@ -1,7 +1,7 @@ # CPU tuning section - shared with UML. # Must change only cflags-y (or [yn]), not CFLAGS! That makes a difference for UML. -#-mtune exists since gcc 3.4 +#-mtune exists since gcc 3.4, and some -mcpu flavors didn't exist in gcc 2.95. HAS_MTUNE := $(call cc-option-yn, -mtune=i386) ifeq ($(HAS_MTUNE),y) tune = $(call cc-option,-mtune=$(1),) @@ -14,7 +14,7 @@ cflags-$(CONFIG_M386) += -march=i386 cflags-$(CONFIG_M486) += -march=i486 cflags-$(CONFIG_M586) += -march=i586 cflags-$(CONFIG_M586TSC) += -march=i586 -cflags-$(CONFIG_M586MMX) += -march=pentium-mmx +cflags-$(CONFIG_M586MMX) += $(call cc-option,-march=pentium-mmx,-march=i586) cflags-$(CONFIG_M686) += -march=i686 cflags-$(CONFIG_MPENTIUMII) += -march=i686 $(call tune,pentium2) cflags-$(CONFIG_MPENTIUMIII) += -march=i686 $(call tune,pentium3) @@ -23,8 +23,8 @@ cflags-$(CONFIG_MPENTIUM4) += -march=i686 $(call tune,pentium4) cflags-$(CONFIG_MK6) += -march=k6 # Please note, that patches that add -march=athlon-xp and friends are pointless. # They make zero difference whatsosever to performance at this time. -cflags-$(CONFIG_MK7) += -march=athlon -cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,-march=athlon) +cflags-$(CONFIG_MK7) += $(call cc-option,-march=athlon,-march=i686 $(align)-functions=4) +cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,$(call cc-option,-march=athlon,-march=i686 $(align)-functions=4)) cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0 cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586) @@ -37,5 +37,5 @@ cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) cflags-$(CONFIG_X86_ELAN) += -march=i486 # Geode GX1 support -cflags-$(CONFIG_MGEODEGX1) += -march=pentium-mmx +cflags-$(CONFIG_MGEODEGX1) += $(call cc-option,-march=pentium-mmx,-march=i486) diff --git a/trunk/arch/i386/boot/compressed/misc.c b/trunk/arch/i386/boot/compressed/misc.c index f19f3a7492a5..82a807f9f5e6 100644 --- a/trunk/arch/i386/boot/compressed/misc.c +++ b/trunk/arch/i386/boot/compressed/misc.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include diff --git a/trunk/arch/i386/kernel/Makefile b/trunk/arch/i386/kernel/Makefile index be1880bb75b4..f10de0f2c5e6 100644 --- a/trunk/arch/i386/kernel/Makefile +++ b/trunk/arch/i386/kernel/Makefile @@ -4,10 +4,10 @@ extra-y := head.o init_task.o vmlinux.lds -obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ +obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ - quirks.o i8237.o + doublefault.o quirks.o i8237.o obj-y += cpu/ obj-y += timers/ @@ -33,8 +33,6 @@ obj-y += sysenter.o vsyscall.o obj-$(CONFIG_ACPI_SRAT) += srat.o obj-$(CONFIG_HPET_TIMER) += time_hpet.o obj-$(CONFIG_EFI) += efi.o efi_stub.o -obj-$(CONFIG_DOUBLEFAULT) += doublefault.o -obj-$(CONFIG_VM86) += vm86.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o EXTRA_AFLAGS := -traditional diff --git a/trunk/arch/i386/kernel/apm.c b/trunk/arch/i386/kernel/apm.c index 9d8827156e54..2d793d4aef1a 100644 --- a/trunk/arch/i386/kernel/apm.c +++ b/trunk/arch/i386/kernel/apm.c @@ -2291,9 +2291,7 @@ static int __init apm_init(void) apm_info.disabled = 1; return -ENODEV; } -#ifdef CONFIG_PM_LEGACY pm_active = 1; -#endif /* * Set up a segment that references the real mode segment 0x40 @@ -2384,9 +2382,7 @@ static void __exit apm_exit(void) exit_kapmd = 1; while (kapmd_running) schedule(); -#ifdef CONFIG_PM_LEGACY pm_active = 0; -#endif } module_init(apm_init); diff --git a/trunk/arch/i386/kernel/cpu/common.c b/trunk/arch/i386/kernel/cpu/common.c index 170400879f44..cca655688ffc 100644 --- a/trunk/arch/i386/kernel/cpu/common.c +++ b/trunk/arch/i386/kernel/cpu/common.c @@ -609,10 +609,8 @@ void __devinit cpu_init(void) load_TR_desc(); load_LDT(&init_mm.context); -#ifdef CONFIG_DOUBLEFAULT /* Set up doublefault TSS pointer in the GDT */ __set_tss_desc(cpu, GDT_ENTRY_DOUBLEFAULT_TSS, &doublefault_tss); -#endif /* Clear %fs and %gs. */ asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs"); diff --git a/trunk/arch/i386/kernel/entry.S b/trunk/arch/i386/kernel/entry.S index 4d704724b2f5..607c06007508 100644 --- a/trunk/arch/i386/kernel/entry.S +++ b/trunk/arch/i386/kernel/entry.S @@ -323,7 +323,6 @@ work_notifysig: # deal with pending signals and ALIGN work_notifysig_v86: -#ifdef CONFIG_VM86 pushl %ecx # save ti_flags for do_notify_resume call save_v86_state # %eax contains pt_regs pointer popl %ecx @@ -331,7 +330,6 @@ work_notifysig_v86: xorl %edx, %edx call do_notify_resume jmp resume_userspace -#endif # perform syscall exit tracing ALIGN diff --git a/trunk/arch/i386/kernel/init_task.c b/trunk/arch/i386/kernel/init_task.c index cff95d10a4d8..9caa8e8db80c 100644 --- a/trunk/arch/i386/kernel/init_task.c +++ b/trunk/arch/i386/kernel/init_task.c @@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task); * per-CPU TSS segments. Threads are completely 'soft' on Linux, * no more per-task TSS's. */ -DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS; +DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_maxaligned_in_smp = INIT_TSS; diff --git a/trunk/arch/i386/kernel/irq.c b/trunk/arch/i386/kernel/irq.c index f3a9c78c4a24..1a201a932865 100644 --- a/trunk/arch/i386/kernel/irq.c +++ b/trunk/arch/i386/kernel/irq.c @@ -19,7 +19,7 @@ #include #include -DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_internodealigned_in_smp; +DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_maxaligned_in_smp; EXPORT_PER_CPU_SYMBOL(irq_stat); #ifndef CONFIG_X86_LOCAL_APIC diff --git a/trunk/arch/i386/kernel/process.c b/trunk/arch/i386/kernel/process.c index 035928f3f6c1..45e7f0ac4b04 100644 --- a/trunk/arch/i386/kernel/process.c +++ b/trunk/arch/i386/kernel/process.c @@ -48,7 +48,6 @@ #include #include #include -#include #ifdef CONFIG_MATH_EMULATION #include #endif diff --git a/trunk/arch/i386/kernel/syscall_table.S b/trunk/arch/i386/kernel/syscall_table.S index 6ff3e5243226..f7ba4acc20ec 100644 --- a/trunk/arch/i386/kernel/syscall_table.S +++ b/trunk/arch/i386/kernel/syscall_table.S @@ -293,4 +293,3 @@ ENTRY(sys_call_table) .long sys_inotify_init .long sys_inotify_add_watch .long sys_inotify_rm_watch - .long sys_migrate_pages diff --git a/trunk/arch/i386/kernel/time_hpet.c b/trunk/arch/i386/kernel/time_hpet.c index a529f0cdce17..9caeaa315cd7 100644 --- a/trunk/arch/i386/kernel/time_hpet.c +++ b/trunk/arch/i386/kernel/time_hpet.c @@ -259,6 +259,8 @@ __setup("hpet=", hpet_setup); #include #include +extern irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs); + #define DEFAULT_RTC_INT_FREQ 64 #define RTC_NUM_INTS 1 diff --git a/trunk/arch/ia64/Makefile b/trunk/arch/ia64/Makefile index 57b047c27e46..67932ad53082 100644 --- a/trunk/arch/ia64/Makefile +++ b/trunk/arch/ia64/Makefile @@ -37,6 +37,10 @@ $(error Sorry, you need a newer version of the assember, one that is built from ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz) endif +ifneq ($(shell if [ $(GCC_VERSION) -lt 0300 ] ; then echo "bad"; fi ;),) +$(error Sorry, your compiler is too old. GCC v2.96 is known to generate bad code.) +endif + ifeq ($(GCC_VERSION),0304) cflags-$(CONFIG_ITANIUM) += -mtune=merced cflags-$(CONFIG_MCKINLEY) += -mtune=mckinley diff --git a/trunk/arch/ia64/ia32/sys_ia32.c b/trunk/arch/ia64/ia32/sys_ia32.c index 9f8e8d558873..dc282710421a 100644 --- a/trunk/arch/ia64/ia32/sys_ia32.c +++ b/trunk/arch/ia64/ia32/sys_ia32.c @@ -1761,15 +1761,21 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data) lock_kernel(); if (request == PTRACE_TRACEME) { - ret = ptrace_traceme(); + ret = sys_ptrace(request, pid, addr, data); goto out; } - child = ptrace_get_task_struct(pid); - if (IS_ERR(child)) { - ret = PTR_ERR(child); + ret = -ESRCH; + read_lock(&tasklist_lock); + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); + if (!child) goto out; - } + ret = -EPERM; + if (pid == 1) /* no messing around with init! */ + goto out_tsk; if (request == PTRACE_ATTACH) { ret = sys_ptrace(request, pid, addr, data); diff --git a/trunk/arch/ia64/kernel/efi.c b/trunk/arch/ia64/kernel/efi.c index c485a3b32ba8..a3aa45cbcfa0 100644 --- a/trunk/arch/ia64/kernel/efi.c +++ b/trunk/arch/ia64/kernel/efi.c @@ -247,32 +247,6 @@ typedef struct kern_memdesc { static kern_memdesc_t *kern_memmap; -#define efi_md_size(md) (md->num_pages << EFI_PAGE_SHIFT) - -static inline u64 -kmd_end(kern_memdesc_t *kmd) -{ - return (kmd->start + (kmd->num_pages << EFI_PAGE_SHIFT)); -} - -static inline u64 -efi_md_end(efi_memory_desc_t *md) -{ - return (md->phys_addr + efi_md_size(md)); -} - -static inline int -efi_wb(efi_memory_desc_t *md) -{ - return (md->attribute & EFI_MEMORY_WB); -} - -static inline int -efi_uc(efi_memory_desc_t *md) -{ - return (md->attribute & EFI_MEMORY_UC); -} - static void walk (efi_freemem_callback_t callback, void *arg, u64 attr) { @@ -621,8 +595,8 @@ efi_get_iobase (void) return 0; } -static efi_memory_desc_t * -efi_memory_descriptor (unsigned long phys_addr) +u32 +efi_mem_type (unsigned long phys_addr) { void *efi_map_start, *efi_map_end, *p; efi_memory_desc_t *md; @@ -636,13 +610,13 @@ efi_memory_descriptor (unsigned long phys_addr) md = p; if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) - return md; + return md->type; } return 0; } -static int -efi_memmap_has_mmio (void) +u64 +efi_mem_attributes (unsigned long phys_addr) { void *efi_map_start, *efi_map_end, *p; efi_memory_desc_t *md; @@ -655,98 +629,36 @@ efi_memmap_has_mmio (void) for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { md = p; - if (md->type == EFI_MEMORY_MAPPED_IO) - return 1; + if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) + return md->attribute; } return 0; } - -u32 -efi_mem_type (unsigned long phys_addr) -{ - efi_memory_desc_t *md = efi_memory_descriptor(phys_addr); - - if (md) - return md->type; - return 0; -} - -u64 -efi_mem_attributes (unsigned long phys_addr) -{ - efi_memory_desc_t *md = efi_memory_descriptor(phys_addr); - - if (md) - return md->attribute; - return 0; -} EXPORT_SYMBOL(efi_mem_attributes); -/* - * Determines whether the memory at phys_addr supports the desired - * attribute (WB, UC, etc). If this returns 1, the caller can safely - * access *size bytes at phys_addr with the specified attribute. - */ -static int -efi_mem_attribute_range (unsigned long phys_addr, unsigned long *size, u64 attr) -{ - efi_memory_desc_t *md = efi_memory_descriptor(phys_addr); - unsigned long md_end; - - if (!md || (md->attribute & attr) != attr) - return 0; - - do { - md_end = efi_md_end(md); - if (phys_addr + *size <= md_end) - return 1; - - md = efi_memory_descriptor(md_end); - if (!md || (md->attribute & attr) != attr) { - *size = md_end - phys_addr; - return 1; - } - } while (md); - return 0; -} - -/* - * For /dev/mem, we only allow read & write system calls to access - * write-back memory, because read & write don't allow the user to - * control access size. - */ int valid_phys_addr_range (unsigned long phys_addr, unsigned long *size) { - return efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_WB); -} + void *efi_map_start, *efi_map_end, *p; + efi_memory_desc_t *md; + u64 efi_desc_size; -/* - * We allow mmap of anything in the EFI memory map that supports - * either write-back or uncacheable access. For uncacheable regions, - * the supported access sizes are system-dependent, and the user is - * responsible for using the correct size. - * - * Note that this doesn't currently allow access to hot-added memory, - * because that doesn't appear in the boot-time EFI memory map. - */ -int -valid_mmap_phys_addr_range (unsigned long phys_addr, unsigned long *size) -{ - if (efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_WB)) - return 1; + efi_map_start = __va(ia64_boot_param->efi_memmap); + efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; + efi_desc_size = ia64_boot_param->efi_memdesc_size; - if (efi_mem_attribute_range(phys_addr, size, EFI_MEMORY_UC)) - return 1; + for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { + md = p; - /* - * Some firmware doesn't report MMIO regions in the EFI memory map. - * The Intel BigSur (a.k.a. HP i2000) has this problem. In this - * case, we can't use the EFI memory map to validate mmap requests. - */ - if (!efi_memmap_has_mmio()) - return 1; + if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) { + if (!(md->attribute & EFI_MEMORY_WB)) + return 0; + if (*size > md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - phys_addr) + *size = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT) - phys_addr; + return 1; + } + } return 0; } @@ -795,6 +707,32 @@ efi_uart_console_only(void) return 0; } +#define efi_md_size(md) (md->num_pages << EFI_PAGE_SHIFT) + +static inline u64 +kmd_end(kern_memdesc_t *kmd) +{ + return (kmd->start + (kmd->num_pages << EFI_PAGE_SHIFT)); +} + +static inline u64 +efi_md_end(efi_memory_desc_t *md) +{ + return (md->phys_addr + efi_md_size(md)); +} + +static inline int +efi_wb(efi_memory_desc_t *md) +{ + return (md->attribute & EFI_MEMORY_WB); +} + +static inline int +efi_uc(efi_memory_desc_t *md) +{ + return (md->attribute & EFI_MEMORY_UC); +} + /* * Look for the first granule aligned memory descriptor memory * that is big enough to hold EFI memory map. Make sure this diff --git a/trunk/arch/ia64/kernel/entry.S b/trunk/arch/ia64/kernel/entry.S index 7a6ffd613789..0741b066b98f 100644 --- a/trunk/arch/ia64/kernel/entry.S +++ b/trunk/arch/ia64/kernel/entry.S @@ -1600,6 +1600,5 @@ sys_call_table: data8 sys_inotify_init data8 sys_inotify_add_watch data8 sys_inotify_rm_watch - data8 sys_migrate_pages // 1280 .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls diff --git a/trunk/arch/ia64/kernel/head.S b/trunk/arch/ia64/kernel/head.S index fbc7ea35dd57..bfe65b2e8621 100644 --- a/trunk/arch/ia64/kernel/head.S +++ b/trunk/arch/ia64/kernel/head.S @@ -1060,7 +1060,7 @@ SET_REG(b5); * the clobber lists for spin_lock() in include/asm-ia64/spinlock.h. */ -#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3) +#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) GLOBAL_ENTRY(ia64_spinlock_contention_pre3_4) .prologue diff --git a/trunk/arch/ia64/kernel/ia64_ksyms.c b/trunk/arch/ia64/kernel/ia64_ksyms.c index e72de580ebbf..5db9d3bcbbcb 100644 --- a/trunk/arch/ia64/kernel/ia64_ksyms.c +++ b/trunk/arch/ia64/kernel/ia64_ksyms.c @@ -103,7 +103,7 @@ EXPORT_SYMBOL(unw_init_running); #ifdef ASM_SUPPORTED # ifdef CONFIG_SMP -# if (__GNUC__ == 3 && __GNUC_MINOR__ < 3) +# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) /* * This is not a normal routine and we don't want a function descriptor for it, so we use * a fake declaration here. diff --git a/trunk/arch/ia64/kernel/ptrace.c b/trunk/arch/ia64/kernel/ptrace.c index 8d88eeea02d1..4b19d0410632 100644 --- a/trunk/arch/ia64/kernel/ptrace.c +++ b/trunk/arch/ia64/kernel/ptrace.c @@ -1422,7 +1422,14 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) lock_kernel(); ret = -EPERM; if (request == PTRACE_TRACEME) { - ret = ptrace_traceme(); + /* are we already being traced? */ + if (current->ptrace & PT_PTRACED) + goto out; + ret = security_ptrace(current->parent, current); + if (ret) + goto out; + current->ptrace |= PT_PTRACED; + ret = 0; goto out; } diff --git a/trunk/arch/ia64/oprofile/backtrace.c b/trunk/arch/ia64/oprofile/backtrace.c index adb01566bd57..b7dabbfb0d61 100644 --- a/trunk/arch/ia64/oprofile/backtrace.c +++ b/trunk/arch/ia64/oprofile/backtrace.c @@ -32,7 +32,7 @@ typedef struct u64 *prev_pfs_loc; /* state for WAR for old spinlock ool code */ } ia64_backtrace_t; -#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3) +#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) /* * Returns non-zero if the PC is in the spinlock contention out-of-line code * with non-standard calling sequence (on older compilers). diff --git a/trunk/arch/m32r/kernel/process.c b/trunk/arch/m32r/kernel/process.c index 3bf55d92933f..cc4b571e5db7 100644 --- a/trunk/arch/m32r/kernel/process.c +++ b/trunk/arch/m32r/kernel/process.c @@ -50,10 +50,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk) * Powermanagement idle function, if any.. */ void (*pm_idle)(void) = NULL; -EXPORT_SYMBOL(pm_idle); - -void (*pm_power_off)(void) = NULL; -EXPORT_SYMBOL(pm_power_off); void disable_hlt(void) { diff --git a/trunk/arch/m32r/kernel/ptrace.c b/trunk/arch/m32r/kernel/ptrace.c index 9b75caaf5cec..078d2a0e71c2 100644 --- a/trunk/arch/m32r/kernel/ptrace.c +++ b/trunk/arch/m32r/kernel/ptrace.c @@ -762,16 +762,28 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data) int ret; lock_kernel(); + ret = -EPERM; if (request == PTRACE_TRACEME) { - ret = ptrace_traceme(); + /* are we already being traced? */ + if (current->ptrace & PT_PTRACED) + goto out; + /* set the ptrace bit in the process flags. */ + current->ptrace |= PT_PTRACED; + ret = 0; goto out; } + ret = -ESRCH; + read_lock(&tasklist_lock); + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); + if (!child) + goto out; - child = ptrace_get_task_struct(pid); - if (IS_ERR(child)) { - ret = PTR_ERR(child); + ret = -EPERM; + if (pid == 1) /* you may not mess with init */ goto out; - } if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index 96b919828053..1dd5d18b2201 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -10,6 +10,10 @@ config MMU bool default y +config UID16 + bool + default y + config RWSEM_GENERIC_SPINLOCK bool default y diff --git a/trunk/arch/m68knommu/Kconfig b/trunk/arch/m68knommu/Kconfig index e2a6e8648960..b96498120fe9 100644 --- a/trunk/arch/m68knommu/Kconfig +++ b/trunk/arch/m68knommu/Kconfig @@ -17,6 +17,10 @@ config FPU bool default n +config UID16 + bool + default y + config RWSEM_GENERIC_SPINLOCK bool default y diff --git a/trunk/arch/mips/kernel/ptrace32.c b/trunk/arch/mips/kernel/ptrace32.c index 7e55457a491f..9a9b04972132 100644 --- a/trunk/arch/mips/kernel/ptrace32.c +++ b/trunk/arch/mips/kernel/ptrace32.c @@ -57,16 +57,30 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) (unsigned long) data); #endif lock_kernel(); + ret = -EPERM; if (request == PTRACE_TRACEME) { - ret = ptrace_traceme(); + /* are we already being traced? */ + if (current->ptrace & PT_PTRACED) + goto out; + if ((ret = security_ptrace(current->parent, current))) + goto out; + /* set the ptrace bit in the process flags. */ + current->ptrace |= PT_PTRACED; + ret = 0; goto out; } - - child = ptrace_get_task_struct(pid); - if (IS_ERR(child)) { - ret = PTR_ERR(child); + ret = -ESRCH; + read_lock(&tasklist_lock); + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); + if (!child) goto out; - } + + ret = -EPERM; + if (pid == 1) /* you may not mess with init */ + goto out_tsk; if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); diff --git a/trunk/arch/mips/kernel/vpe.c b/trunk/arch/mips/kernel/vpe.c index 9c89eebc356f..06be405be399 100644 --- a/trunk/arch/mips/kernel/vpe.c +++ b/trunk/arch/mips/kernel/vpe.c @@ -1171,8 +1171,7 @@ static int __init vpe_module_init(void) return -ENODEV; } - major = register_chrdev(0, module_name, &vpe_fops); - if (major < 0) { + if ((major = register_chrdev(0, module_name, &vpe_fops) < 0)) { printk("VPE loader: unable to register character device\n"); return major; } diff --git a/trunk/arch/mips/sgi-ip27/ip27-berr.c b/trunk/arch/mips/sgi-ip27/ip27-berr.c index ce907eda221b..07631a97670b 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-berr.c +++ b/trunk/arch/mips/sgi-ip27/ip27-berr.c @@ -11,7 +11,6 @@ #include #include #include /* for SIGBUS */ -#include /* schow_regs(), force_sig() */ #include #include diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index e77a06e9621e..874a283edb95 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -19,6 +19,9 @@ config MMU config STACK_GROWSUP def_bool y +config UID16 + bool + config RWSEM_GENERIC_SPINLOCK def_bool y diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 28004f002ec9..db93dbc0e21a 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -26,6 +26,9 @@ config MMU bool default y +config UID16 + bool + config GENERIC_HARDIRQS bool default y @@ -47,7 +50,7 @@ config PPC config EARLY_PRINTK bool - default y + default y if PPC64 config COMPAT bool @@ -297,7 +300,6 @@ config PPC_PMAC64 bool depends on PPC_PMAC && POWER4 select U3_DART - select MPIC_BROKEN_U3 select GENERIC_TBSYNC default y @@ -326,7 +328,9 @@ config PPC_CELL select MMIO_NVRAM config PPC_OF - def_bool y + bool + depends on PPC_MULTIPLATFORM # for now + default y config XICS depends on PPC_PSERIES @@ -375,28 +379,11 @@ config CELL_IIC bool default y -config CRASH_DUMP - bool "kernel crash dumps (EXPERIMENTAL)" - depends on PPC_MULTIPLATFORM - depends on EXPERIMENTAL - help - Build a kernel suitable for use as a kdump capture kernel. - The kernel will be linked at a different address than normal, and - so can only be used for Kdump. - - Don't change this unless you know what you are doing. - config IBMVIO depends on PPC_PSERIES || PPC_ISERIES bool default y -config IBMEBUS - depends on PPC_PSERIES - bool "Support for GX bus based adapters" - help - Bus device driver for GX bus based adapters. - config PPC_MPC106 bool default n @@ -488,7 +475,6 @@ source arch/powerpc/platforms/embedded6xx/Kconfig source arch/powerpc/platforms/4xx/Kconfig source arch/powerpc/platforms/85xx/Kconfig source arch/powerpc/platforms/8xx/Kconfig -source arch/powerpc/platforms/cell/Kconfig menu "Kernel options" @@ -592,12 +578,11 @@ config ARCH_SELECT_MEMORY_MODEL depends on PPC64 config ARCH_FLATMEM_ENABLE - def_bool y - depends on (PPC64 && !NUMA) || PPC32 + def_bool y + depends on PPC64 && !NUMA config ARCH_SPARSEMEM_ENABLE def_bool y - depends on PPC64 config ARCH_SPARSEMEM_DEFAULT def_bool y diff --git a/trunk/arch/powerpc/Makefile b/trunk/arch/powerpc/Makefile index 5f80e58e5cb3..a13eb575f834 100644 --- a/trunk/arch/powerpc/Makefile +++ b/trunk/arch/powerpc/Makefile @@ -151,7 +151,7 @@ CPPFLAGS_vmlinux.lds := -Upowerpc # All the instructions talk about "make bzImage". bzImage: zImage -BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm uImage +BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd vmlinux.sm .PHONY: $(BOOT_TARGETS) diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index 22726aefc8ea..9770f587af73 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -143,36 +143,6 @@ $(obj)/zImage.initrd: $(obj)/zImage.initrd.vmode $(obj)/addnote @cp -f $< $@ $(call if_changed,addnote) -#----------------------------------------------------------- -# build u-boot images -#----------------------------------------------------------- -quiet_cmd_mygzip = GZIP $@ -cmd_mygzip = gzip -f -9 < $< > $@.$$$$ && mv $@.$$$$ $@ - -quiet_cmd_objbin = OBJCOPY $@ - cmd_objbin = $(OBJCOPY) -O binary $< $@ - -quiet_cmd_uimage = UIMAGE $@ - cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \ - -C gzip -a 00000000 -e 00000000 -n 'Linux-$(KERNELRELEASE)' \ - -d $< $@ - -MKIMAGE := $(srctree)/scripts/mkuboot.sh -targets += uImage -extra-y += vmlinux.bin vmlinux.gz - -$(obj)/vmlinux.bin: vmlinux FORCE - $(call if_changed,objbin) - -$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE - $(call if_changed,mygzip) - -$(obj)/uImage: $(obj)/vmlinux.gz - $(Q)rm -f $@ - $(call cmd,uimage) - @echo -n ' Image: $@ ' - @if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi - install: $(CONFIGURE) $(BOOTIMAGE) sh -x $(srctree)/$(src)/install.sh "$(KERNELRELEASE)" vmlinux System.map "$(INSTALL_PATH)" "$(BOOTIMAGE)" diff --git a/trunk/arch/powerpc/configs/pmac32_defconfig b/trunk/arch/powerpc/configs/pmac32_defconfig deleted file mode 100644 index 398203bd98eb..000000000000 --- a/trunk/arch/powerpc/configs/pmac32_defconfig +++ /dev/null @@ -1,1729 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.15-rc5 -# Tue Dec 13 17:24:05 2005 -# -# CONFIG_PPC64 is not set -CONFIG_PPC32=y -CONFIG_PPC_MERGE=y -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_PPC=y -CONFIG_EARLY_PRINTK=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y - -# -# Processor support -# -CONFIG_6xx=y -# CONFIG_PPC_52xx is not set -# CONFIG_PPC_82xx is not set -# CONFIG_PPC_83xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_8xx is not set -# CONFIG_E200 is not set -# CONFIG_E500 is not set -CONFIG_PPC_FPU=y -CONFIG_ALTIVEC=y -CONFIG_PPC_STD_MMU=y -CONFIG_PPC_STD_MMU_32=y -# CONFIG_SMP is not set - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -CONFIG_HOTPLUG=y -CONFIG_KOBJECT_UEVENT=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# Block layer -# -CONFIG_LBD=y - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Platform support -# -CONFIG_PPC_MULTIPLATFORM=y -# CONFIG_PPC_ISERIES is not set -# CONFIG_EMBEDDED6xx is not set -# CONFIG_APUS is not set -# CONFIG_PPC_CHRP is not set -CONFIG_PPC_PMAC=y -CONFIG_PPC_OF=y -CONFIG_MPIC=y -# CONFIG_PPC_RTAS is not set -# CONFIG_MMIO_NVRAM is not set -# CONFIG_CRASH_DUMP is not set -CONFIG_PPC_MPC106=y -# CONFIG_GENERIC_TBSYNC is not set -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_TABLE=y -# CONFIG_CPU_FREQ_DEBUG is not set -CONFIG_CPU_FREQ_STAT=y -# CONFIG_CPU_FREQ_STAT_DETAILS is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -CONFIG_CPU_FREQ_PMAC=y -CONFIG_PPC601_SYNC_FIX=y -# CONFIG_TAU is not set -# CONFIG_WANT_EARLY_SERIAL is not set - -# -# Kernel options -# -# CONFIG_HIGHMEM is not set -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m -# CONFIG_KEXEC is not set -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_PROC_DEVICETREE=y -# CONFIG_CMDLINE_BOOL is not set -CONFIG_PM=y -# CONFIG_PM_LEGACY is not set -CONFIG_PM_DEBUG=y -CONFIG_SOFTWARE_SUSPEND=y -CONFIG_PM_STD_PARTITION="" -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_GENERIC_ISA_DMA=y -# CONFIG_PPC_I8259 is not set -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -CONFIG_PCI_LEGACY_PROC=y -# CONFIG_PCI_DEBUG is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -CONFIG_PCCARD=m -# CONFIG_PCMCIA_DEBUG is not set -CONFIG_PCMCIA=m -CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y -CONFIG_CARDBUS=y - -# -# PC-card bridges -# -CONFIG_YENTA=m -# CONFIG_PD6729 is not set -# CONFIG_I82092 is not set -CONFIG_PCCARD_NONSTATIC=m - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_BOOT_LOAD=0x00800000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set - -# -# Core Netfilter Configuration -# -# CONFIG_NETFILTER_NETLINK is not set - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -# CONFIG_IP_NF_CT_ACCT is not set -# CONFIG_IP_NF_CONNTRACK_MARK is not set -# CONFIG_IP_NF_CONNTRACK_EVENTS is not set -# CONFIG_IP_NF_CT_PROTO_SCTP is not set -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_IRC=m -CONFIG_IP_NF_NETBIOS_NS=m -CONFIG_IP_NF_TFTP=m -CONFIG_IP_NF_AMANDA=m -CONFIG_IP_NF_PPTP=m -# CONFIG_IP_NF_QUEUE is not set -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_LENGTH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_OWNER=m -# CONFIG_IP_NF_MATCH_ADDRTYPE is not set -# CONFIG_IP_NF_MATCH_REALM is not set -# CONFIG_IP_NF_MATCH_SCTP is not set -CONFIG_IP_NF_MATCH_DCCP=m -# CONFIG_IP_NF_MATCH_COMMENT is not set -# CONFIG_IP_NF_MATCH_HASHLIMIT is not set -CONFIG_IP_NF_MATCH_STRING=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -# CONFIG_IP_NF_TARGET_LOG is not set -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m -# CONFIG_IP_NF_TARGET_NFQUEUE is not set -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_TARGET_NETMAP=m -CONFIG_IP_NF_TARGET_SAME=m -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_NAT_TFTP=m -CONFIG_IP_NF_NAT_AMANDA=m -CONFIG_IP_NF_NAT_PPTP=m -# CONFIG_IP_NF_MANGLE is not set -CONFIG_IP_NF_RAW=m -CONFIG_IP_NF_TARGET_NOTRACK=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m - -# -# DCCP Configuration (EXPERIMENTAL) -# -CONFIG_IP_DCCP=m -CONFIG_INET_DCCP_DIAG=m - -# -# DCCP CCIDs Configuration (EXPERIMENTAL) -# -CONFIG_IP_DCCP_CCID3=m -CONFIG_IP_DCCP_TFRC_LIB=m - -# -# DCCP Kernel Hacking -# -# CONFIG_IP_DCCP_DEBUG is not set -# CONFIG_IP_DCCP_UNLOAD_HACK is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -CONFIG_IRDA=m - -# -# IrDA protocols -# -CONFIG_IRLAN=m -CONFIG_IRNET=m -CONFIG_IRCOMM=m -# CONFIG_IRDA_ULTRA is not set - -# -# IrDA options -# -CONFIG_IRDA_CACHE_LAST_LSAP=y -CONFIG_IRDA_FAST_RR=y -# CONFIG_IRDA_DEBUG is not set - -# -# Infrared-port device drivers -# - -# -# SIR device drivers -# -CONFIG_IRTTY_SIR=m - -# -# Dongle support -# -# CONFIG_DONGLE is not set - -# -# Old SIR device drivers -# -# CONFIG_IRPORT_SIR is not set - -# -# Old Serial dongle support -# - -# -# FIR device drivers -# -# CONFIG_USB_IRDA is not set -# CONFIG_SIGMATEL_FIR is not set -# CONFIG_NSC_FIR is not set -# CONFIG_WINBOND_FIR is not set -# CONFIG_TOSHIBA_FIR is not set -# CONFIG_SMC_IRCC_FIR is not set -# CONFIG_ALI_FIR is not set -# CONFIG_VLSI_FIR is not set -# CONFIG_VIA_FIR is not set -CONFIG_BT=m -CONFIG_BT_L2CAP=m -CONFIG_BT_SCO=m -CONFIG_BT_RFCOMM=m -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=m -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=m - -# -# Bluetooth device drivers -# -CONFIG_BT_HCIUSB=m -# CONFIG_BT_HCIUSB_SCO is not set -# CONFIG_BT_HCIUART is not set -CONFIG_BT_HCIBCM203X=m -# CONFIG_BT_HCIBPA10X is not set -CONFIG_BT_HCIBFUSB=m -# CONFIG_BT_HCIDTL1 is not set -# CONFIG_BT_HCIBT3C is not set -# CONFIG_BT_HCIBLUECARD is not set -# CONFIG_BT_HCIBTUART is not set -# CONFIG_BT_HCIVHCI is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -CONFIG_IEEE80211_CRYPT_CCMP=m -CONFIG_IEEE80211_CRYPT_TKIP=m - -# -# Device Drivers -# - -# -# Generic Driver Options -# -# CONFIG_STANDALONE is not set -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=m -# CONFIG_DEBUG_DRIVER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -CONFIG_CONNECTOR=y -CONFIG_PROC_EVENTS=y - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -CONFIG_MAC_FLOPPY=y -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_UB=m -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -CONFIG_BLK_DEV_IDECS=m -CONFIG_BLK_DEV_IDECD=y -# CONFIG_BLK_DEV_IDETAPE is not set -CONFIG_BLK_DEV_IDEFLOPPY=y -CONFIG_BLK_DEV_IDESCSI=y -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -# CONFIG_IDE_GENERIC is not set -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_SL82C105=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -CONFIG_BLK_DEV_PDC202XX_NEW=y -# CONFIG_PDC202XX_FORCE is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -CONFIG_BLK_DEV_IDE_PMAC=y -CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y -CONFIG_BLK_DEV_IDEDMA_PMAC=y -CONFIG_BLK_DEV_IDE_PMAC_BLINK=y -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=y -CONFIG_SCSI_PROC_FS=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_ST=y -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_CHR_DEV_SG=y -# CONFIG_CHR_DEV_SCH is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y -# CONFIG_SCSI_LOGGING is not set - -# -# SCSI Transport Attributes -# -CONFIG_SCSI_SPI_ATTRS=y -# CONFIG_SCSI_FC_ATTRS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set - -# -# SCSI low-level drivers -# -# CONFIG_ISCSI_TCP is not set -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AACRAID is not set -CONFIG_SCSI_AIC7XXX=m -CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -CONFIG_AIC7XXX_DEBUG_ENABLE=y -CONFIG_AIC7XXX_DEBUG_MASK=0 -CONFIG_AIC7XXX_REG_PRETTY_PRINT=y -CONFIG_SCSI_AIC7XXX_OLD=m -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -CONFIG_SCSI_SYM53C8XX_2=y -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLA2XXX=y -# CONFIG_SCSI_QLA21XX is not set -# CONFIG_SCSI_QLA22XX is not set -# CONFIG_SCSI_QLA2300 is not set -# CONFIG_SCSI_QLA2322 is not set -# CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA24XX is not set -# CONFIG_SCSI_LPFC is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_DEBUG is not set -CONFIG_SCSI_MESH=y -CONFIG_SCSI_MESH_SYNC_RATE=5 -CONFIG_SCSI_MESH_RESET_DELAY_MS=1000 -CONFIG_SCSI_MAC53C94=y - -# -# PCMCIA SCSI adapter support -# -# CONFIG_PCMCIA_AHA152X is not set -# CONFIG_PCMCIA_FDOMAIN is not set -# CONFIG_PCMCIA_NINJA_SCSI is not set -# CONFIG_PCMCIA_QLOGIC is not set -# CONFIG_PCMCIA_SYM53C500 is not set - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -# CONFIG_MD_RAID10 is not set -CONFIG_MD_RAID5=m -CONFIG_MD_RAID6=m -CONFIG_MD_MULTIPATH=m -CONFIG_MD_FAULTY=m -CONFIG_BLK_DEV_DM=m -CONFIG_DM_CRYPT=m -# CONFIG_DM_SNAPSHOT is not set -# CONFIG_DM_MIRROR is not set -# CONFIG_DM_ZERO is not set -# CONFIG_DM_MULTIPATH is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_SPI is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set - -# -# IEEE 1394 (FireWire) support -# -CONFIG_IEEE1394=m - -# -# Subsystem Options -# -# CONFIG_IEEE1394_VERBOSEDEBUG is not set -# CONFIG_IEEE1394_OUI_DB is not set -CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y -CONFIG_IEEE1394_CONFIG_ROM_IP1394=y -# CONFIG_IEEE1394_EXPORT_FULL_API is not set - -# -# Device Drivers -# -# CONFIG_IEEE1394_PCILYNX is not set -CONFIG_IEEE1394_OHCI1394=m - -# -# Protocol Drivers -# -CONFIG_IEEE1394_VIDEO1394=m -CONFIG_IEEE1394_SBP2=m -# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set -CONFIG_IEEE1394_ETH1394=m -CONFIG_IEEE1394_DV1394=m -CONFIG_IEEE1394_RAWIO=m -# CONFIG_IEEE1394_CMP is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Macintosh device drivers -# -CONFIG_ADB=y -CONFIG_ADB_CUDA=y -CONFIG_ADB_PMU=y -CONFIG_PMAC_APM_EMU=y -CONFIG_PMAC_MEDIABAY=y -CONFIG_PMAC_BACKLIGHT=y -CONFIG_INPUT_ADBHID=y -CONFIG_MAC_EMUMOUSEBTN=y -CONFIG_THERM_WINDTUNNEL=m -CONFIG_THERM_ADT746X=m -# CONFIG_WINDFARM is not set -# CONFIG_ANSLCD is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -CONFIG_MACE=y -# CONFIG_MACE_AAUI_PORT is not set -CONFIG_BMAC=y -# CONFIG_HAPPYMEAL is not set -CONFIG_SUNGEM=y -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NET_PCI=y -CONFIG_PCNET32=y -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -# CONFIG_MV643XX_ETH is not set - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y - -# -# Obsolete Wireless cards support (pre-802.11) -# -# CONFIG_STRIP is not set -# CONFIG_PCMCIA_WAVELAN is not set -# CONFIG_PCMCIA_NETWAVE is not set - -# -# Wireless 802.11 Frequency Hopping cards support -# -# CONFIG_PCMCIA_RAYCS is not set - -# -# Wireless 802.11b ISA/PCI cards support -# -# CONFIG_IPW2100 is not set -# CONFIG_IPW2200 is not set -# CONFIG_AIRO is not set -CONFIG_HERMES=m -CONFIG_APPLE_AIRPORT=m -# CONFIG_PLX_HERMES is not set -# CONFIG_TMD_HERMES is not set -# CONFIG_NORTEL_HERMES is not set -# CONFIG_PCI_HERMES is not set -# CONFIG_ATMEL is not set - -# -# Wireless 802.11b Pcmcia/Cardbus cards support -# -# CONFIG_PCMCIA_HERMES is not set -# CONFIG_PCMCIA_SPECTRUM is not set -# CONFIG_AIRO_CS is not set -# CONFIG_PCMCIA_WL3501 is not set - -# -# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support -# -CONFIG_PRISM54=m -# CONFIG_HOSTAP is not set -CONFIG_NET_WIRELESS=y - -# -# PCMCIA network device support -# -# CONFIG_NET_PCMCIA is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -CONFIG_PPP=y -CONFIG_PPP_MULTILINK=y -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=y -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=y -CONFIG_PPP_BSDCOMP=m -# CONFIG_PPP_MPPE is not set -# CONFIG_PPPOE is not set -# CONFIG_SLIP is not set -# CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -# CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -CONFIG_INPUT_MOUSE=y -# CONFIG_MOUSE_PS2 is not set -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=m -# CONFIG_SERIAL_8250_CS is not set -CONFIG_SERIAL_8250_NR_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=m -# CONFIG_SERIAL_PMACZILOG is not set -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -CONFIG_NVRAM=y -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -CONFIG_AGP=m -CONFIG_AGP_UNINORTH=m -CONFIG_DRM=m -# CONFIG_DRM_TDFX is not set -CONFIG_DRM_R128=m -CONFIG_DRM_RADEON=m -# CONFIG_DRM_MGA is not set -# CONFIG_DRM_SIS is not set -# CONFIG_DRM_VIA is not set -# CONFIG_DRM_SAVAGE is not set - -# -# PCMCIA character devices -# -# CONFIG_SYNCLINK_CS is not set -# CONFIG_CARDMAN_4000 is not set -# CONFIG_CARDMAN_4040 is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=m - -# -# I2C Algorithms -# -CONFIG_I2C_ALGOBIT=y -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -CONFIG_I2C_KEYWEST=m -# CONFIG_I2C_MPC is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_SENSORS_M41T00 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set - -# -# Misc devices -# - -# -# Multimedia Capabilities Port drivers -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FB=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_MACMODES=y -CONFIG_FB_MODE_HELPERS=y -CONFIG_FB_TILEBLITTING=y -# CONFIG_FB_CIRRUS is not set -# CONFIG_FB_PM2 is not set -# CONFIG_FB_CYBER2000 is not set -CONFIG_FB_OF=y -CONFIG_FB_CONTROL=y -CONFIG_FB_PLATINUM=y -CONFIG_FB_VALKYRIE=y -CONFIG_FB_CT65550=y -# CONFIG_FB_ASILIANT is not set -CONFIG_FB_IMSTT=y -# CONFIG_FB_VGA16 is not set -# CONFIG_FB_S1D13XXX is not set -CONFIG_FB_NVIDIA=y -CONFIG_FB_NVIDIA_I2C=y -# CONFIG_FB_RIVA is not set -CONFIG_FB_MATROX=y -CONFIG_FB_MATROX_MILLENIUM=y -CONFIG_FB_MATROX_MYSTIQUE=y -# CONFIG_FB_MATROX_G is not set -# CONFIG_FB_MATROX_I2C is not set -# CONFIG_FB_MATROX_MULTIHEAD is not set -# CONFIG_FB_RADEON_OLD is not set -CONFIG_FB_RADEON=y -CONFIG_FB_RADEON_I2C=y -# CONFIG_FB_RADEON_DEBUG is not set -CONFIG_FB_ATY128=y -CONFIG_FB_ATY=y -CONFIG_FB_ATY_CT=y -# CONFIG_FB_ATY_GENERIC_LCD is not set -# CONFIG_FB_ATY_XL_INIT is not set -CONFIG_FB_ATY_GX=y -# CONFIG_FB_SAVAGE is not set -# CONFIG_FB_SIS is not set -# CONFIG_FB_NEOMAGIC is not set -# CONFIG_FB_KYRO is not set -CONFIG_FB_3DFX=y -# CONFIG_FB_3DFX_ACCEL is not set -# CONFIG_FB_VOODOO1 is not set -# CONFIG_FB_CYBLA is not set -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -# CONFIG_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y - -# -# Logo configuration -# -CONFIG_LOGO=y -CONFIG_LOGO_LINUX_MONO=y -CONFIG_LOGO_LINUX_VGA16=y -CONFIG_LOGO_LINUX_CLUT224=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -CONFIG_SOUND=m -CONFIG_DMASOUND_PMAC=m -CONFIG_DMASOUND=m - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=m -CONFIG_SND_TIMER=m -CONFIG_SND_PCM=m -CONFIG_SND_HWDEP=m -CONFIG_SND_RAWMIDI=m -CONFIG_SND_SEQUENCER=m -CONFIG_SND_SEQ_DUMMY=m -CONFIG_SND_OSSEMUL=y -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set -CONFIG_SND_GENERIC_DRIVER=y - -# -# Generic devices -# -CONFIG_SND_DUMMY=m -# CONFIG_SND_VIRMIDI is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - -# -# PCI devices -# -# CONFIG_SND_ALI5451 is not set -# CONFIG_SND_ATIIXP is not set -# CONFIG_SND_ATIIXP_MODEM is not set -# CONFIG_SND_AU8810 is not set -# CONFIG_SND_AU8820 is not set -# CONFIG_SND_AU8830 is not set -# CONFIG_SND_AZT3328 is not set -# CONFIG_SND_BT87X is not set -# CONFIG_SND_CS46XX is not set -# CONFIG_SND_CS4281 is not set -# CONFIG_SND_EMU10K1 is not set -# CONFIG_SND_EMU10K1X is not set -# CONFIG_SND_CA0106 is not set -# CONFIG_SND_KORG1212 is not set -# CONFIG_SND_MIXART is not set -# CONFIG_SND_NM256 is not set -# CONFIG_SND_RME32 is not set -# CONFIG_SND_RME96 is not set -# CONFIG_SND_RME9652 is not set -# CONFIG_SND_HDSP is not set -# CONFIG_SND_HDSPM is not set -# CONFIG_SND_TRIDENT is not set -# CONFIG_SND_YMFPCI is not set -# CONFIG_SND_AD1889 is not set -# CONFIG_SND_ALS4000 is not set -# CONFIG_SND_CMIPCI is not set -# CONFIG_SND_ENS1370 is not set -# CONFIG_SND_ENS1371 is not set -# CONFIG_SND_ES1938 is not set -# CONFIG_SND_ES1968 is not set -# CONFIG_SND_MAESTRO3 is not set -# CONFIG_SND_FM801 is not set -# CONFIG_SND_ICE1712 is not set -# CONFIG_SND_ICE1724 is not set -# CONFIG_SND_INTEL8X0 is not set -# CONFIG_SND_INTEL8X0M is not set -# CONFIG_SND_SONICVIBES is not set -# CONFIG_SND_VIA82XX is not set -# CONFIG_SND_VIA82XX_MODEM is not set -# CONFIG_SND_VX222 is not set -# CONFIG_SND_HDA_INTEL is not set - -# -# ALSA PowerMac devices -# -CONFIG_SND_POWERMAC=m -# CONFIG_SND_POWERMAC_AUTO_DRC is not set - -# -# USB devices -# -CONFIG_SND_USB_AUDIO=m -# CONFIG_SND_USB_USX2Y is not set - -# -# PCMCIA devices -# - -# -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -CONFIG_USB_DYNAMIC_MINORS=y -# CONFIG_USB_SUSPEND is not set -# CONFIG_USB_OTG is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_EHCI_HCD is not set -# CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=y -# CONFIG_USB_OHCI_BIG_ENDIAN is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_UHCI_HCD is not set -# CONFIG_USB_SL811_HCD is not set - -# -# USB Device Class drivers -# -# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set -CONFIG_USB_ACM=m -CONFIG_USB_PRINTER=m - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# may also be needed; see USB_STORAGE Help for more information -# -# CONFIG_USB_STORAGE is not set - -# -# USB Input Devices -# -CONFIG_USB_HID=y -CONFIG_USB_HIDINPUT=y -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_MTOUCH is not set -# CONFIG_USB_ITMTOUCH is not set -# CONFIG_USB_EGALAX is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -CONFIG_USB_APPLETOUCH=y - -# -# USB Imaging devices -# -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set - -# -# USB Multimedia devices -# -# CONFIG_USB_DABUSB is not set - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network Adapters -# -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -CONFIG_USB_USBNET=m -CONFIG_USB_NET_AX8817X=m -CONFIG_USB_NET_CDCETHER=m -# CONFIG_USB_NET_GL620A is not set -CONFIG_USB_NET_NET1080=m -# CONFIG_USB_NET_PLUSB is not set -# CONFIG_USB_NET_RNDIS_HOST is not set -# CONFIG_USB_NET_CDC_SUBSET is not set -CONFIG_USB_NET_ZAURUS=m -# CONFIG_USB_ZD1201 is not set -CONFIG_USB_MON=y - -# -# USB port drivers -# - -# -# USB Serial Converter support -# -CONFIG_USB_SERIAL=m -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_AIRPRIME is not set -# CONFIG_USB_SERIAL_ANYDATA is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_CP2101 is not set -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -CONFIG_USB_SERIAL_VISOR=m -CONFIG_USB_SERIAL_IPAQ=m -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_GARMIN is not set -# CONFIG_USB_SERIAL_IPW is not set -CONFIG_USB_SERIAL_KEYSPAN_PDA=m -CONFIG_USB_SERIAL_KEYSPAN=m -CONFIG_USB_SERIAL_KEYSPAN_MPR=y -CONFIG_USB_SERIAL_KEYSPAN_USA28=y -CONFIG_USB_SERIAL_KEYSPAN_USA28X=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y -CONFIG_USB_SERIAL_KEYSPAN_USA19=y -CONFIG_USB_SERIAL_KEYSPAN_USA18X=y -CONFIG_USB_SERIAL_KEYSPAN_USA19W=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y -CONFIG_USB_SERIAL_KEYSPAN_USA49W=y -CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_HP4X is not set -# CONFIG_USB_SERIAL_SAFE is not set -# CONFIG_USB_SERIAL_TI is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OPTION is not set -# CONFIG_USB_SERIAL_OMNINET is not set -CONFIG_USB_EZUSB=y - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGETKIT is not set -# CONFIG_USB_PHIDGETSERVO is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TEST is not set - -# -# USB DSL modem support -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# SN Devices -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -CONFIG_FUSE_FS=m - -# -# CD-ROM/DVD Filesystems -# -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_ZISOFS_FS=y -CONFIG_UDF_FS=m -CONFIG_UDF_NLS=y - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -CONFIG_RELAYFS_FS=m - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -CONFIG_HFS_FS=m -CONFIG_HFSPLUS_FS=m -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -CONFIG_NFSD=y -# CONFIG_NFSD_V3 is not set -# CONFIG_NFSD_TCP is not set -CONFIG_LOCKD=y -CONFIG_EXPORTFS=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -CONFIG_NLS_ISO8859_1=m -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=m - -# -# Library routines -# -CONFIG_CRC_CCITT=y -CONFIG_CRC16=y -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_TEXTSEARCH=y -CONFIG_TEXTSEARCH_KMP=m -CONFIG_TEXTSEARCH_BM=m -CONFIG_TEXTSEARCH_FSM=m - -# -# Instrumentation Support -# -CONFIG_PROFILING=y -CONFIG_OPROFILE=y - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_DEBUG_KERNEL=y -# CONFIG_MAGIC_SYSRQ is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_VM is not set -# CONFIG_RCU_TORTURE_TEST is not set -CONFIG_DEBUGGER=y -CONFIG_XMON=y -CONFIG_XMON_DEFAULT=y -# CONFIG_BDI_SWITCH is not set -CONFIG_BOOTX_TEXT=y - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -CONFIG_CRYPTO=y -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set -CONFIG_CRYPTO_AES=m -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set -CONFIG_CRYPTO_ARC4=m -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_DEFLATE is not set -CONFIG_CRYPTO_MICHAEL_MIC=m -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Hardware crypto devices -# diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index 6e03b595b6c8..9ed551b6c172 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -17,11 +17,11 @@ obj-y += vdso32/ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ signal_64.o ptrace32.o systbl.o \ paca.o ioctl32.o cpu_setup_power4.o \ - firmware.o sysfs.o idle_64.o + firmware.o sysfs.o udbg.o idle_64.o obj-$(CONFIG_PPC64) += vdso64/ obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o -obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o +obj-$(CONFIG_PPC_OF) += of_device.o procfs-$(CONFIG_PPC64) := proc_ppc64.o obj-$(CONFIG_PROC_FS) += $(procfs-y) rtaspci-$(CONFIG_PPC64) := rtas_pci.o @@ -30,10 +30,12 @@ obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o obj-$(CONFIG_RTAS_PROC) += rtas-proc.o obj-$(CONFIG_LPARCFG) += lparcfg.o obj-$(CONFIG_IBMVIO) += vio.o -obj-$(CONFIG_IBMEBUS) += ibmebus.o obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o +obj-$(CONFIG_PPC_PSERIES) += udbg_16550.o +obj-$(CONFIG_PPC_MAPLE) += udbg_16550.o +udbgscc-$(CONFIG_PPC64) := udbg_scc.o +obj-$(CONFIG_PPC_PMAC) += $(udbgscc-y) obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o -obj-$(CONFIG_CRASH_DUMP) += crash_dump.o ifeq ($(CONFIG_PPC_MERGE),y) @@ -46,25 +48,25 @@ extra-$(CONFIG_8xx) := head_8xx.o extra-y += vmlinux.lds obj-y += process.o init_task.o time.o \ - prom.o traps.o setup-common.o udbg.o + prom.o traps.o setup-common.o obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o -obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o +obj-$(CONFIG_PPC_OF) += prom_init.o obj-$(CONFIG_MODULES) += ppc_ksyms.o obj-$(CONFIG_BOOTX_TEXT) += btext.o obj-$(CONFIG_6xx) += idle_6xx.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_KPROBES) += kprobes.o -obj-$(CONFIG_SERIAL_8250) += legacy_serial.o udbg_16550.o + module-$(CONFIG_PPC64) += module_64.o obj-$(CONFIG_MODULES) += $(module-y) pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \ pci_direct_iommu.o iomap.o obj-$(CONFIG_PCI) += $(pci64-y) -kexec-$(CONFIG_PPC64) := machine_kexec_64.o -kexec-$(CONFIG_PPC32) := machine_kexec_32.o -obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y) + +kexec64-$(CONFIG_PPC64) += machine_kexec_64.o +obj-$(CONFIG_KEXEC) += $(kexec64-y) ifeq ($(CONFIG_PPC_ISERIES),y) $(obj)/head_64.o: $(obj)/lparmap.s diff --git a/trunk/arch/powerpc/kernel/asm-offsets.c b/trunk/arch/powerpc/kernel/asm-offsets.c index 56399c5c931a..91538d2445bf 100644 --- a/trunk/arch/powerpc/kernel/asm-offsets.c +++ b/trunk/arch/powerpc/kernel/asm-offsets.c @@ -92,9 +92,9 @@ int main(void) DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); - DEFINE(TI_SIGFRAME, offsetof(struct thread_info, nvgprs_frame)); - DEFINE(TI_TASK, offsetof(struct thread_info, task)); + DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror)); #ifdef CONFIG_PPC32 + DEFINE(TI_TASK, offsetof(struct thread_info, task)); DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); #endif /* CONFIG_PPC32 */ @@ -131,9 +131,11 @@ int main(void) DEFINE(PACALOWHTLBAREAS, offsetof(struct paca_struct, context.low_htlb_areas)); DEFINE(PACAHIGHHTLBAREAS, offsetof(struct paca_struct, context.high_htlb_areas)); #endif /* CONFIG_HUGETLB_PAGE */ + DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr)); DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen)); DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc)); DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb)); + DEFINE(PACA_EXDSI, offsetof(struct paca_struct, exdsi)); DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp)); DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca)); DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); diff --git a/trunk/arch/powerpc/kernel/btext.c b/trunk/arch/powerpc/kernel/btext.c index 6223d39177cb..bdfba92b2b38 100644 --- a/trunk/arch/powerpc/kernel/btext.c +++ b/trunk/arch/powerpc/kernel/btext.c @@ -31,18 +31,15 @@ static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb); static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb); static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb); -#define __force_data __attribute__((__section__(".data"))) +static int g_loc_X; +static int g_loc_Y; +static int g_max_loc_X; +static int g_max_loc_Y; -static int g_loc_X __force_data; -static int g_loc_Y __force_data; -static int g_max_loc_X __force_data; -static int g_max_loc_Y __force_data; - -static int dispDeviceRowBytes __force_data; -static int dispDeviceDepth __force_data; -static int dispDeviceRect[4] __force_data; -static unsigned char *dispDeviceBase __force_data; -static unsigned char *logicalDisplayBase __force_data; +static int dispDeviceRowBytes; +static int dispDeviceDepth; +static int dispDeviceRect[4]; +static unsigned char *dispDeviceBase, *logicalDisplayBase; unsigned long disp_BAT[2] __initdata = {0, 0}; @@ -50,7 +47,7 @@ unsigned long disp_BAT[2] __initdata = {0, 0}; static unsigned char vga_font[cmapsz]; -int boot_text_mapped __force_data = 0; +int boot_text_mapped; int force_printk_to_btext = 0; #ifdef CONFIG_PPC32 @@ -60,7 +57,7 @@ int force_printk_to_btext = 0; * * The display is mapped to virtual address 0xD0000000, rather * than 1:1, because some some CHRP machines put the frame buffer - * in the region starting at 0xC0000000 (PAGE_OFFSET). + * in the region starting at 0xC0000000 (KERNELBASE). * This mapping is temporary and will disappear as soon as the * setup done by MMU_Init() is applied. * @@ -69,9 +66,10 @@ int force_printk_to_btext = 0; * is really badly aligned, but I didn't encounter this case * yet. */ -void __init btext_prepare_BAT(void) +void __init +btext_prepare_BAT(void) { - unsigned long vaddr = PAGE_OFFSET + 0x10000000; + unsigned long vaddr = KERNELBASE + 0x10000000; unsigned long addr; unsigned long lowbits; @@ -97,13 +95,12 @@ void __init btext_prepare_BAT(void) } #endif - -/* This function can be used to enable the early boot text when doing - * OF booting or within bootx init. It must be followed by a btext_unmap() - * call before the logical address becomes unuseable +/* This function will enable the early boot text when doing OF booting. This + * way, xmon output should work too */ -void __init btext_setup_display(int width, int height, int depth, int pitch, - unsigned long address) +void __init +btext_setup_display(int width, int height, int depth, int pitch, + unsigned long address) { g_loc_X = 0; g_loc_Y = 0; @@ -119,11 +116,6 @@ void __init btext_setup_display(int width, int height, int depth, int pitch, boot_text_mapped = 1; } -void __init btext_unmap(void) -{ - boot_text_mapped = 0; -} - /* Here's a small text engine to use during early boot * or for debugging purposes * @@ -135,7 +127,7 @@ void __init btext_unmap(void) * changes. */ -static void map_boot_text(void) +void map_boot_text(void) { unsigned long base, offset, size; unsigned char *vbase; @@ -183,9 +175,8 @@ int btext_initialize(struct device_node *np) if (prop) address = *prop; - /* FIXME: Add support for PCI reg properties. Right now, only - * reliable on macs - */ + /* FIXME: Add support for PCI reg properties */ + if (address == 0) return -EINVAL; @@ -193,6 +184,7 @@ int btext_initialize(struct device_node *np) g_loc_Y = 0; g_max_loc_X = width / 8; g_max_loc_Y = height / 16; + logicalDisplayBase = (unsigned char *)address; dispDeviceBase = (unsigned char *)address; dispDeviceRowBytes = pitch; dispDeviceDepth = depth; @@ -205,12 +197,14 @@ int btext_initialize(struct device_node *np) return 0; } -int __init btext_find_display(int allow_nonstdout) +void __init init_boot_display(void) { char *name; struct device_node *np = NULL; int rc = -ENODEV; + printk("trying to initialize btext ...\n"); + name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); if (name != NULL) { np = of_find_node_by_path(name); @@ -224,8 +218,8 @@ int __init btext_find_display(int allow_nonstdout) } if (np) rc = btext_initialize(np); - if (rc == 0 || !allow_nonstdout) - return rc; + if (rc == 0) + return; for (np = NULL; (np = of_find_node_by_type(np, "display"));) { if (get_property(np, "linux,opened", NULL)) { @@ -234,9 +228,8 @@ int __init btext_find_display(int allow_nonstdout) printk("result: %d\n", rc); } if (rc == 0) - break; + return; } - return rc; } /* Calc the base address of a given point (x,y) */ @@ -284,83 +277,44 @@ EXPORT_SYMBOL(btext_update_display); void btext_clearscreen(void) { - unsigned int *base = (unsigned int *)calc_base(0, 0); + unsigned long *base = (unsigned long *)calc_base(0, 0); unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * - (dispDeviceDepth >> 3)) >> 2; + (dispDeviceDepth >> 3)) >> 3; int i,j; for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++) { - unsigned int *ptr = base; + unsigned long *ptr = base; for(j=width; j; --j) *(ptr++) = 0; - base += (dispDeviceRowBytes >> 2); + base += (dispDeviceRowBytes >> 3); } } -void btext_flushscreen(void) -{ - unsigned int *base = (unsigned int *)calc_base(0, 0); - unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * - (dispDeviceDepth >> 3)) >> 2; - int i,j; - - for (i=0; i < (dispDeviceRect[3] - dispDeviceRect[1]); i++) - { - unsigned int *ptr = base; - for(j = width; j > 0; j -= 8) { - __asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr)); - ptr += 8; - } - base += (dispDeviceRowBytes >> 2); - } - __asm__ __volatile__ ("sync" ::: "memory"); -} - -void btext_flushline(void) -{ - unsigned int *base = (unsigned int *)calc_base(0, g_loc_Y << 4); - unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * - (dispDeviceDepth >> 3)) >> 2; - int i,j; - - for (i=0; i < 16; i++) - { - unsigned int *ptr = base; - for(j = width; j > 0; j -= 8) { - __asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr)); - ptr += 8; - } - base += (dispDeviceRowBytes >> 2); - } - __asm__ __volatile__ ("sync" ::: "memory"); -} - - #ifndef NO_SCROLL static void scrollscreen(void) { - unsigned int *src = (unsigned int *)calc_base(0,16); - unsigned int *dst = (unsigned int *)calc_base(0,0); + unsigned long *src = (unsigned long *)calc_base(0,16); + unsigned long *dst = (unsigned long *)calc_base(0,0); unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * - (dispDeviceDepth >> 3)) >> 2; + (dispDeviceDepth >> 3)) >> 3; int i,j; for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++) { - unsigned int *src_ptr = src; - unsigned int *dst_ptr = dst; + unsigned long *src_ptr = src; + unsigned long *dst_ptr = dst; for(j=width; j; --j) *(dst_ptr++) = *(src_ptr++); - src += (dispDeviceRowBytes >> 2); - dst += (dispDeviceRowBytes >> 2); + src += (dispDeviceRowBytes >> 3); + dst += (dispDeviceRowBytes >> 3); } for (i=0; i<16; i++) { - unsigned int *dst_ptr = dst; + unsigned long *dst_ptr = dst; for(j=width; j; --j) *(dst_ptr++) = 0; - dst += (dispDeviceRowBytes >> 2); + dst += (dispDeviceRowBytes >> 3); } } #endif /* ndef NO_SCROLL */ @@ -423,14 +377,6 @@ void btext_drawstring(const char *c) btext_drawchar(*c++); } -void btext_drawtext(const char *c, unsigned int len) -{ - if (!boot_text_mapped) - return; - while (len--) - btext_drawchar(*c++); -} - void btext_drawhex(unsigned long v) { char *hex_table = "0123456789abcdef"; diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c index 43c74a6b07b1..1d85cedbbb7b 100644 --- a/trunk/arch/powerpc/kernel/cputable.c +++ b/trunk/arch/powerpc/kernel/cputable.c @@ -78,8 +78,10 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_power3, +#ifdef CONFIG_OPROFILE .oprofile_cpu_type = "ppc64/power3", - .oprofile_type = RS64, + .oprofile_model = &op_model_rs64, +#endif }, { /* Power3+ */ .pvr_mask = 0xffff0000, @@ -91,8 +93,10 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_power3, +#ifdef CONFIG_OPROFILE .oprofile_cpu_type = "ppc64/power3", - .oprofile_type = RS64, + .oprofile_model = &op_model_rs64, +#endif }, { /* Northstar */ .pvr_mask = 0xffff0000, @@ -104,8 +108,10 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_power3, +#ifdef CONFIG_OPROFILE .oprofile_cpu_type = "ppc64/rs64", - .oprofile_type = RS64, + .oprofile_model = &op_model_rs64, +#endif }, { /* Pulsar */ .pvr_mask = 0xffff0000, @@ -117,8 +123,10 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_power3, +#ifdef CONFIG_OPROFILE .oprofile_cpu_type = "ppc64/rs64", - .oprofile_type = RS64, + .oprofile_model = &op_model_rs64, +#endif }, { /* I-star */ .pvr_mask = 0xffff0000, @@ -130,8 +138,10 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_power3, +#ifdef CONFIG_OPROFILE .oprofile_cpu_type = "ppc64/rs64", - .oprofile_type = RS64, + .oprofile_model = &op_model_rs64, +#endif }, { /* S-star */ .pvr_mask = 0xffff0000, @@ -143,8 +153,10 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_power3, +#ifdef CONFIG_OPROFILE .oprofile_cpu_type = "ppc64/rs64", - .oprofile_type = RS64, + .oprofile_model = &op_model_rs64, +#endif }, { /* Power4 */ .pvr_mask = 0xffff0000, @@ -156,8 +168,10 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_power4, +#ifdef CONFIG_OPROFILE .oprofile_cpu_type = "ppc64/power4", - .oprofile_type = POWER4, + .oprofile_model = &op_model_rs64, +#endif }, { /* Power4+ */ .pvr_mask = 0xffff0000, @@ -169,8 +183,10 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_power4, +#ifdef CONFIG_OPROFILE .oprofile_cpu_type = "ppc64/power4", - .oprofile_type = POWER4, + .oprofile_model = &op_model_power4, +#endif }, { /* PPC970 */ .pvr_mask = 0xffff0000, @@ -183,8 +199,10 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, +#ifdef CONFIG_OPROFILE .oprofile_cpu_type = "ppc64/970", - .oprofile_type = POWER4, + .oprofile_model = &op_model_power4, +#endif }, #endif /* CONFIG_PPC64 */ #if defined(CONFIG_PPC64) || defined(CONFIG_POWER4) @@ -203,8 +221,10 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 8, .cpu_setup = __setup_cpu_ppc970, +#ifdef CONFIG_OPROFILE .oprofile_cpu_type = "ppc64/970", - .oprofile_type = POWER4, + .oprofile_model = &op_model_power4, +#endif }, #endif /* defined(CONFIG_PPC64) || defined(CONFIG_POWER4) */ #ifdef CONFIG_PPC64 @@ -218,8 +238,10 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 128, .dcache_bsize = 128, .cpu_setup = __setup_cpu_ppc970, +#ifdef CONFIG_OPROFILE .oprofile_cpu_type = "ppc64/970", - .oprofile_type = POWER4, + .oprofile_model = &op_model_power4, +#endif }, { /* Power5 GR */ .pvr_mask = 0xffff0000, @@ -231,23 +253,27 @@ struct cpu_spec cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 6, .cpu_setup = __setup_cpu_power4, +#ifdef CONFIG_OPROFILE .oprofile_cpu_type = "ppc64/power5", - .oprofile_type = POWER4, + .oprofile_model = &op_model_power4, +#endif }, { /* Power5 GS */ .pvr_mask = 0xffff0000, .pvr_value = 0x003b0000, - .cpu_name = "POWER5+ (gs)", + .cpu_name = "POWER5 (gs)", .cpu_features = CPU_FTRS_POWER5, .cpu_user_features = COMMON_USER_POWER5_PLUS, .icache_bsize = 128, .dcache_bsize = 128, .num_pmcs = 6, .cpu_setup = __setup_cpu_power4, - .oprofile_cpu_type = "ppc64/power5+", - .oprofile_type = POWER4, +#ifdef CONFIG_OPROFILE + .oprofile_cpu_type = "ppc64/power5", + .oprofile_model = &op_model_power4, +#endif }, - { /* Cell Broadband Engine */ + { /* BE DD1.x */ .pvr_mask = 0xffff0000, .pvr_value = 0x00700000, .cpu_name = "Cell Broadband Engine", @@ -519,9 +545,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = G4, + .cpu_setup = __setup_cpu_745x }, { /* 7450 2.1 */ .pvr_mask = 0xffffffff, @@ -532,9 +556,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = G4, + .cpu_setup = __setup_cpu_745x }, { /* 7450 2.3 and newer */ .pvr_mask = 0xffff0000, @@ -545,9 +567,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = G4, + .cpu_setup = __setup_cpu_745x }, { /* 7455 rev 1.x */ .pvr_mask = 0xffffff00, @@ -558,9 +578,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = G4, + .cpu_setup = __setup_cpu_745x }, { /* 7455 rev 2.0 */ .pvr_mask = 0xffffffff, @@ -571,9 +589,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = G4, + .cpu_setup = __setup_cpu_745x }, { /* 7455 others */ .pvr_mask = 0xffff0000, @@ -584,9 +600,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = G4, + .cpu_setup = __setup_cpu_745x }, { /* 7447/7457 Rev 1.0 */ .pvr_mask = 0xffffffff, @@ -597,9 +611,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = G4, + .cpu_setup = __setup_cpu_745x }, { /* 7447/7457 Rev 1.1 */ .pvr_mask = 0xffffffff, @@ -610,9 +622,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = G4, + .cpu_setup = __setup_cpu_745x }, { /* 7447/7457 Rev 1.2 and later */ .pvr_mask = 0xffff0000, @@ -623,9 +633,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = G4, + .cpu_setup = __setup_cpu_745x }, { /* 7447A */ .pvr_mask = 0xffff0000, @@ -636,9 +644,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = G4, + .cpu_setup = __setup_cpu_745x }, { /* 7448 */ .pvr_mask = 0xffff0000, @@ -649,9 +655,7 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = G4, + .cpu_setup = __setup_cpu_745x }, { /* 82xx (8240, 8245, 8260 are all 603e cores) */ .pvr_mask = 0x7fff0000, @@ -975,8 +979,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .oprofile_cpu_type = "ppc/e500", - .oprofile_type = BOOKE, }, { /* e500v2 */ .pvr_mask = 0xffff0000, @@ -990,8 +992,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, .num_pmcs = 4, - .oprofile_cpu_type = "ppc/e500", - .oprofile_type = BOOKE, }, #endif #if !CLASSIC_PPC diff --git a/trunk/arch/powerpc/kernel/crash.c b/trunk/arch/powerpc/kernel/crash.c deleted file mode 100644 index 4681155121ef..000000000000 --- a/trunk/arch/powerpc/kernel/crash.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Architecture specific (PPC64) functions for kexec based crash dumps. - * - * Copyright (C) 2005, IBM Corp. - * - * Created by: Haren Myneni - * - * This source code is licensed under the GNU General Public License, - * Version 2. See the file COPYING for more details. - * - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef DEBUG -#include -#define DBG(fmt...) udbg_printf(fmt) -#else -#define DBG(fmt...) -#endif - -/* This keeps a track of which one is crashing cpu. */ -int crashing_cpu = -1; - -static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, - size_t data_len) -{ - struct elf_note note; - - note.n_namesz = strlen(name) + 1; - note.n_descsz = data_len; - note.n_type = type; - memcpy(buf, ¬e, sizeof(note)); - buf += (sizeof(note) +3)/4; - memcpy(buf, name, note.n_namesz); - buf += (note.n_namesz + 3)/4; - memcpy(buf, data, note.n_descsz); - buf += (note.n_descsz + 3)/4; - - return buf; -} - -static void final_note(u32 *buf) -{ - struct elf_note note; - - note.n_namesz = 0; - note.n_descsz = 0; - note.n_type = 0; - memcpy(buf, ¬e, sizeof(note)); -} - -static void crash_save_this_cpu(struct pt_regs *regs, int cpu) -{ - struct elf_prstatus prstatus; - u32 *buf; - - if ((cpu < 0) || (cpu >= NR_CPUS)) - return; - - /* Using ELF notes here is opportunistic. - * I need a well defined structure format - * for the data I pass, and I need tags - * on the data to indicate what information I have - * squirrelled away. ELF notes happen to provide - * all of that that no need to invent something new. - */ - buf = &crash_notes[cpu][0]; - memset(&prstatus, 0, sizeof(prstatus)); - prstatus.pr_pid = current->pid; - elf_core_copy_regs(&prstatus.pr_reg, regs); - buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus, - sizeof(prstatus)); - final_note(buf); -} - -/* FIXME Merge this with xmon_save_regs ?? */ -static inline void crash_get_current_regs(struct pt_regs *regs) -{ - unsigned long tmp1, tmp2; - - __asm__ __volatile__ ( - "std 0,0(%2)\n" - "std 1,8(%2)\n" - "std 2,16(%2)\n" - "std 3,24(%2)\n" - "std 4,32(%2)\n" - "std 5,40(%2)\n" - "std 6,48(%2)\n" - "std 7,56(%2)\n" - "std 8,64(%2)\n" - "std 9,72(%2)\n" - "std 10,80(%2)\n" - "std 11,88(%2)\n" - "std 12,96(%2)\n" - "std 13,104(%2)\n" - "std 14,112(%2)\n" - "std 15,120(%2)\n" - "std 16,128(%2)\n" - "std 17,136(%2)\n" - "std 18,144(%2)\n" - "std 19,152(%2)\n" - "std 20,160(%2)\n" - "std 21,168(%2)\n" - "std 22,176(%2)\n" - "std 23,184(%2)\n" - "std 24,192(%2)\n" - "std 25,200(%2)\n" - "std 26,208(%2)\n" - "std 27,216(%2)\n" - "std 28,224(%2)\n" - "std 29,232(%2)\n" - "std 30,240(%2)\n" - "std 31,248(%2)\n" - "mfmsr %0\n" - "std %0, 264(%2)\n" - "mfctr %0\n" - "std %0, 280(%2)\n" - "mflr %0\n" - "std %0, 288(%2)\n" - "bl 1f\n" - "1: mflr %1\n" - "std %1, 256(%2)\n" - "mtlr %0\n" - "mfxer %0\n" - "std %0, 296(%2)\n" - : "=&r" (tmp1), "=&r" (tmp2) - : "b" (regs)); -} - -/* We may have saved_regs from where the error came from - * or it is NULL if via a direct panic(). - */ -static void crash_save_self(struct pt_regs *saved_regs) -{ - struct pt_regs regs; - int cpu; - - cpu = smp_processor_id(); - if (saved_regs) - memcpy(®s, saved_regs, sizeof(regs)); - else - crash_get_current_regs(®s); - crash_save_this_cpu(®s, cpu); -} - -#ifdef CONFIG_SMP -static atomic_t waiting_for_crash_ipi; - -void crash_ipi_callback(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - - if (cpu == crashing_cpu) - return; - - if (!cpu_online(cpu)) - return; - - if (ppc_md.kexec_cpu_down) - ppc_md.kexec_cpu_down(1, 1); - - local_irq_disable(); - - crash_save_this_cpu(regs, cpu); - atomic_dec(&waiting_for_crash_ipi); - kexec_smp_wait(); - /* NOTREACHED */ -} - -static void crash_kexec_prepare_cpus(void) -{ - unsigned int msecs; - - atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); - - crash_send_ipi(crash_ipi_callback); - smp_wmb(); - - /* - * FIXME: Until we will have the way to stop other CPUSs reliabally, - * the crash CPU will send an IPI and wait for other CPUs to - * respond. If not, proceed the kexec boot even though we failed to - * capture other CPU states. - */ - msecs = 1000000; - while ((atomic_read(&waiting_for_crash_ipi) > 0) && (--msecs > 0)) { - barrier(); - mdelay(1); - } - - /* Would it be better to replace the trap vector here? */ - - /* - * FIXME: In case if we do not get all CPUs, one possibility: ask the - * user to do soft reset such that we get all. - * IPI handler is already set by the panic cpu initially. Therefore, - * all cpus could invoke this handler from die() and the panic CPU - * will call machine_kexec() directly from this handler to do - * kexec boot. - */ - if (atomic_read(&waiting_for_crash_ipi)) - printk(KERN_ALERT "done waiting: %d cpus not responding\n", - atomic_read(&waiting_for_crash_ipi)); - /* Leave the IPI callback set */ -} -#else -static void crash_kexec_prepare_cpus(void) -{ - /* - * move the secondarys to us so that we can copy - * the new kernel 0-0x100 safely - * - * do this if kexec in setup.c ? - */ - smp_release_cpus(); -} - -#endif - -void default_machine_crash_shutdown(struct pt_regs *regs) -{ - /* - * This function is only called after the system - * has paniced or is otherwise in a critical state. - * The minimum amount of code to allow a kexec'd kernel - * to run successfully needs to happen here. - * - * In practice this means stopping other cpus in - * an SMP system. - * The kernel is broken so disable interrupts. - */ - local_irq_disable(); - - if (ppc_md.kexec_cpu_down) - ppc_md.kexec_cpu_down(1, 0); - - /* - * Make a note of crashing cpu. Will be used in machine_kexec - * such that another IPI will not be sent. - */ - crashing_cpu = smp_processor_id(); - crash_kexec_prepare_cpus(); - crash_save_self(regs); -} diff --git a/trunk/arch/powerpc/kernel/crash_dump.c b/trunk/arch/powerpc/kernel/crash_dump.c deleted file mode 100644 index 87effa3f21a7..000000000000 --- a/trunk/arch/powerpc/kernel/crash_dump.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Routines for doing kexec-based kdump. - * - * Copyright (C) 2005, IBM Corp. - * - * Created by: Michael Ellerman - * - * This source code is licensed under the GNU General Public License, - * Version 2. See the file COPYING for more details. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include - -#ifdef DEBUG -#include -#define DBG(fmt...) udbg_printf(fmt) -#else -#define DBG(fmt...) -#endif - -static void __init create_trampoline(unsigned long addr) -{ - /* The maximum range of a single instruction branch, is the current - * instruction's address + (32 MB - 4) bytes. For the trampoline we - * need to branch to current address + 32 MB. So we insert a nop at - * the trampoline address, then the next instruction (+ 4 bytes) - * does a branch to (32 MB - 4). The net effect is that when we - * branch to "addr" we jump to ("addr" + 32 MB). Although it requires - * two instructions it doesn't require any registers. - */ - create_instruction(addr, 0x60000000); /* nop */ - create_branch(addr + 4, addr + PHYSICAL_START, 0); -} - -void __init kdump_setup(void) -{ - unsigned long i; - - DBG(" -> kdump_setup()\n"); - - for (i = KDUMP_TRAMPOLINE_START; i < KDUMP_TRAMPOLINE_END; i += 8) { - create_trampoline(i); - } - - create_trampoline(__pa(system_reset_fwnmi) - PHYSICAL_START); - create_trampoline(__pa(machine_check_fwnmi) - PHYSICAL_START); - - DBG(" <- kdump_setup()\n"); -} - -static int __init parse_elfcorehdr(char *p) -{ - if (p) - elfcorehdr_addr = memparse(p, &p); - - return 0; -} -__setup("elfcorehdr=", parse_elfcorehdr); - -static int __init parse_savemaxmem(char *p) -{ - if (p) - saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1; - - return 0; -} -__setup("savemaxmem=", parse_savemaxmem); - -/* - * copy_oldmem_page - copy one page from "oldmem" - * @pfn: page frame number to be copied - * @buf: target memory address for the copy; this can be in kernel address - * space or user address space (see @userbuf) - * @csize: number of bytes to copy - * @offset: offset in bytes into the page (based on pfn) to begin the copy - * @userbuf: if set, @buf is in user address space, use copy_to_user(), - * otherwise @buf is in kernel address space, use memcpy(). - * - * Copy a page from "oldmem". For this page, there is no pte mapped - * in the current kernel. We stitch up a pte, similar to kmap_atomic. - */ -ssize_t copy_oldmem_page(unsigned long pfn, char *buf, - size_t csize, unsigned long offset, int userbuf) -{ - void *vaddr; - - if (!csize) - return 0; - - vaddr = __ioremap(pfn << PAGE_SHIFT, PAGE_SIZE, 0); - - if (userbuf) { - if (copy_to_user((char __user *)buf, (vaddr + offset), csize)) { - iounmap(vaddr); - return -EFAULT; - } - } else - memcpy(buf, (vaddr + offset), csize); - - iounmap(vaddr); - return csize; -} diff --git a/trunk/arch/powerpc/kernel/dma_64.c b/trunk/arch/powerpc/kernel/dma_64.c index 36aaa7663f02..7c3419656ccc 100644 --- a/trunk/arch/powerpc/kernel/dma_64.c +++ b/trunk/arch/powerpc/kernel/dma_64.c @@ -10,7 +10,6 @@ /* Include the busses we support */ #include #include -#include #include #include @@ -23,10 +22,6 @@ static struct dma_mapping_ops *get_dma_ops(struct device *dev) #ifdef CONFIG_IBMVIO if (dev->bus == &vio_bus_type) return &vio_dma_ops; -#endif -#ifdef CONFIG_IBMEBUS - if (dev->bus == &ibmebus_bus_type) - return &ibmebus_dma_ops; #endif return NULL; } @@ -52,10 +47,6 @@ int dma_set_mask(struct device *dev, u64 dma_mask) if (dev->bus == &vio_bus_type) return -EIO; #endif /* CONFIG_IBMVIO */ -#ifdef CONFIG_IBMEBUS - if (dev->bus == &ibmebus_bus_type) - return -EIO; -#endif BUG(); return 0; } diff --git a/trunk/arch/powerpc/kernel/entry_32.S b/trunk/arch/powerpc/kernel/entry_32.S index 036b71d2adfc..2e99ae41723c 100644 --- a/trunk/arch/powerpc/kernel/entry_32.S +++ b/trunk/arch/powerpc/kernel/entry_32.S @@ -200,6 +200,8 @@ _GLOBAL(DoSyscall) bl do_show_syscall #endif /* SHOW_SYSCALLS */ rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ + li r11,0 + stb r11,TI_SC_NOERR(r10) lwz r11,TI_FLAGS(r10) andi. r11,r11,_TIF_SYSCALL_T_OR_A bne- syscall_dotrace @@ -220,21 +222,25 @@ ret_from_syscall: bl do_show_syscall_exit #endif mr r6,r3 + li r11,-_LAST_ERRNO + cmplw 0,r3,r11 rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ + blt+ 30f + lbz r11,TI_SC_NOERR(r12) + cmpwi r11,0 + bne 30f + neg r3,r3 + lwz r10,_CCR(r1) /* Set SO bit in CR */ + oris r10,r10,0x1000 + stw r10,_CCR(r1) + /* disable interrupts so current_thread_info()->flags can't change */ - LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ +30: LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ SYNC MTMSRD(r10) lwz r9,TI_FLAGS(r12) - li r8,-_LAST_ERRNO - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL) + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) bne- syscall_exit_work - cmplw 0,r3,r8 - blt+ syscall_exit_cont - lwz r11,_CCR(r1) /* Load CR */ - neg r3,r3 - oris r11,r11,0x1000 /* Set SO bit in CR */ - stw r11,_CCR(r1) syscall_exit_cont: #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) /* If the process has its own DBCR0 value, load it up. The single @@ -286,113 +292,46 @@ syscall_dotrace: b syscall_dotrace_cont syscall_exit_work: - andi. r0,r9,_TIF_RESTOREALL - bne- 2f - cmplw 0,r3,r8 - blt+ 1f - andi. r0,r9,_TIF_NOERROR - bne- 1f - lwz r11,_CCR(r1) /* Load CR */ - neg r3,r3 - oris r11,r11,0x1000 /* Set SO bit in CR */ - stw r11,_CCR(r1) - -1: stw r6,RESULT(r1) /* Save result */ + stw r6,RESULT(r1) /* Save result */ stw r3,GPR3(r1) /* Update return value */ -2: andi. r0,r9,(_TIF_PERSYSCALL_MASK) - beq 4f - - /* Clear per-syscall TIF flags if any are set, but _leave_ - _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that - yet. */ - - li r11,_TIF_PERSYSCALL_MASK - addi r12,r12,TI_FLAGS -3: lwarx r8,0,r12 - andc r8,r8,r11 -#ifdef CONFIG_IBM405_ERR77 - dcbt 0,r12 -#endif - stwcx. r8,0,r12 - bne- 3b - subi r12,r12,TI_FLAGS - -4: /* Anything which requires enabling interrupts? */ - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS) - beq 7f - - /* Save NVGPRS if they're not saved already */ + andi. r0,r9,_TIF_SYSCALL_T_OR_A + beq 5f + ori r10,r10,MSR_EE + SYNC + MTMSRD(r10) /* re-enable interrupts */ lwz r4,_TRAP(r1) andi. r4,r4,1 - beq 5f + beq 4f SAVE_NVGPRS(r1) li r4,0xc00 stw r4,_TRAP(r1) - - /* Re-enable interrupts */ -5: ori r10,r10,MSR_EE - SYNC - MTMSRD(r10) - - andi. r0,r9,_TIF_SAVE_NVGPRS - bne save_user_nvgprs - -save_user_nvgprs_cont: - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) - beq 7f - +4: addi r3,r1,STACK_FRAME_OVERHEAD bl do_syscall_trace_leave REST_NVGPRS(r1) - -6: lwz r3,GPR3(r1) +2: + lwz r3,GPR3(r1) LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ SYNC MTMSRD(r10) /* disable interrupts again */ rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ lwz r9,TI_FLAGS(r12) -7: +5: andi. r0,r9,_TIF_NEED_RESCHED - bne 8f + bne 1f lwz r5,_MSR(r1) andi. r5,r5,MSR_PR - beq ret_from_except + beq syscall_exit_cont andi. r0,r9,_TIF_SIGPENDING - beq ret_from_except + beq syscall_exit_cont b do_user_signal -8: +1: ori r10,r10,MSR_EE SYNC MTMSRD(r10) /* re-enable interrupts */ bl schedule - b 6b - -save_user_nvgprs: - lwz r8,TI_SIGFRAME(r12) - -.macro savewords start, end - 1: stw \start,4*(\start)(r8) - .section __ex_table,"a" - .align 2 - .long 1b,save_user_nvgprs_fault - .previous - .if \end - \start - savewords "(\start+1)",\end - .endif -.endm - savewords 14,31 - b save_user_nvgprs_cont - - -save_user_nvgprs_fault: - li r3,11 /* SIGSEGV */ - lwz r4,TI_TASK(r12) - bl force_sigsegv + b 2b - rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ - lwz r9,TI_FLAGS(r12) - b save_user_nvgprs_cont - #ifdef SHOW_SYSCALLS do_show_syscall: #ifdef SHOW_SYSCALLS_TASK @@ -462,10 +401,28 @@ show_syscalls_task: #endif /* SHOW_SYSCALLS */ /* - * The fork/clone functions need to copy the full register set into - * the child process. Therefore we need to save all the nonvolatile - * registers (r13 - r31) before calling the C code. + * The sigsuspend and rt_sigsuspend system calls can call do_signal + * and thus put the process into the stopped state where we might + * want to examine its user state with ptrace. Therefore we need + * to save all the nonvolatile registers (r13 - r31) before calling + * the C code. */ + .globl ppc_sigsuspend +ppc_sigsuspend: + SAVE_NVGPRS(r1) + lwz r0,_TRAP(r1) + rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ + stw r0,_TRAP(r1) /* register set saved */ + b sys_sigsuspend + + .globl ppc_rt_sigsuspend +ppc_rt_sigsuspend: + SAVE_NVGPRS(r1) + lwz r0,_TRAP(r1) + rlwinm r0,r0,0,0,30 + stw r0,_TRAP(r1) + b sys_rt_sigsuspend + .globl ppc_fork ppc_fork: SAVE_NVGPRS(r1) @@ -490,6 +447,14 @@ ppc_clone: stw r0,_TRAP(r1) /* register set saved */ b sys_clone + .globl ppc_swapcontext +ppc_swapcontext: + SAVE_NVGPRS(r1) + lwz r0,_TRAP(r1) + rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ + stw r0,_TRAP(r1) /* register set saved */ + b sys_swapcontext + /* * Top-level page fault handling. * This is in assembler because if do_page_fault tells us that @@ -661,6 +626,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_601) .long ret_from_except #endif + .globl sigreturn_exit +sigreturn_exit: + subi r1,r3,STACK_FRAME_OVERHEAD + rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ + lwz r9,TI_FLAGS(r12) + andi. r0,r9,_TIF_SYSCALL_T_OR_A + beq+ ret_from_except_full + bl do_syscall_trace_leave + /* fall through */ + .globl ret_from_except_full ret_from_except_full: REST_NVGPRS(r1) @@ -683,7 +658,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */ /* Check current_thread_info()->flags */ rlwinm r9,r1,0,0,(31-THREAD_SHIFT) lwz r9,TI_FLAGS(r9) - andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL) + andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED) bne do_work restore_user: diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index aacebb33e98a..bce33a38399f 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -113,7 +113,9 @@ system_call_common: addi r9,r1,STACK_FRAME_OVERHEAD #endif clrrdi r11,r1,THREAD_SHIFT + li r12,0 ld r10,TI_FLAGS(r11) + stb r12,TI_SC_NOERR(r11) andi. r11,r10,_TIF_SYSCALL_T_OR_A bne- syscall_dotrace syscall_dotrace_cont: @@ -142,12 +144,24 @@ system_call: /* label this so stack traces look sane */ bctrl /* Call handler */ syscall_exit: - std r3,RESULT(r1) #ifdef SHOW_SYSCALLS + std r3,GPR3(r1) bl .do_show_syscall_exit - ld r3,RESULT(r1) + ld r3,GPR3(r1) #endif + std r3,RESULT(r1) + ld r5,_CCR(r1) + li r10,-_LAST_ERRNO + cmpld r3,r10 clrrdi r12,r1,THREAD_SHIFT + bge- syscall_error +syscall_error_cont: + + /* check for syscall tracing or audit */ + ld r9,TI_FLAGS(r12) + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) + bne- syscall_exit_trace +syscall_exit_trace_cont: /* disable interrupts so current_thread_info()->flags can't change, and so that we don't get interrupted after loading SRR0/1. */ @@ -159,13 +173,8 @@ syscall_exit: rotldi r10,r10,16 mtmsrd r10,1 ld r9,TI_FLAGS(r12) - li r11,-_LAST_ERRNO - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL|_TIF_SAVE_NVGPRS|_TIF_NOERROR) + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) bne- syscall_exit_work - cmpld r3,r11 - ld r5,_CCR(r1) - bge- syscall_error -syscall_error_cont: ld r7,_NIP(r1) stdcx. r0,0,r1 /* to clear the reservation */ andi. r6,r8,MSR_PR @@ -184,12 +193,21 @@ syscall_error_cont: rfid b . /* prevent speculative execution */ -syscall_error: - oris r5,r5,0x1000 /* Set SO bit in CR */ +syscall_enosys: + li r3,-ENOSYS + std r3,RESULT(r1) + clrrdi r12,r1,THREAD_SHIFT + ld r5,_CCR(r1) + +syscall_error: + lbz r11,TI_SC_NOERR(r12) + cmpwi 0,r11,0 + bne- syscall_error_cont neg r3,r3 + oris r5,r5,0x1000 /* Set SO bit in CR */ std r5,_CCR(r1) b syscall_error_cont - + /* Traced system call support */ syscall_dotrace: bl .save_nvgprs @@ -207,69 +225,21 @@ syscall_dotrace: ld r10,TI_FLAGS(r10) b syscall_dotrace_cont -syscall_enosys: - li r3,-ENOSYS - b syscall_exit - -syscall_exit_work: - /* If TIF_RESTOREALL is set, don't scribble on either r3 or ccr. - If TIF_NOERROR is set, just save r3 as it is. */ - - andi. r0,r9,_TIF_RESTOREALL - bne- 2f - cmpld r3,r11 /* r10 is -LAST_ERRNO */ - blt+ 1f - andi. r0,r9,_TIF_NOERROR - bne- 1f - ld r5,_CCR(r1) - neg r3,r3 - oris r5,r5,0x1000 /* Set SO bit in CR */ - std r5,_CCR(r1) -1: std r3,GPR3(r1) -2: andi. r0,r9,(_TIF_PERSYSCALL_MASK) - beq 4f - - /* Clear per-syscall TIF flags if any are set, but _leave_ - _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that - yet. */ - - li r11,_TIF_PERSYSCALL_MASK - addi r12,r12,TI_FLAGS -3: ldarx r10,0,r12 - andc r10,r10,r11 - stdcx. r10,0,r12 - bne- 3b - subi r12,r12,TI_FLAGS - -4: bl .save_nvgprs - /* Anything else left to do? */ - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS) - beq .ret_from_except_lite - - /* Re-enable interrupts */ - mfmsr r10 - ori r10,r10,MSR_EE - mtmsrd r10,1 - - andi. r0,r9,_TIF_SAVE_NVGPRS - bne save_user_nvgprs - - /* If tracing, re-enable interrupts and do it */ -save_user_nvgprs_cont: - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) - beq 5f - +syscall_exit_trace: + std r3,GPR3(r1) + bl .save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD bl .do_syscall_trace_leave REST_NVGPRS(r1) + ld r3,GPR3(r1) + ld r5,_CCR(r1) clrrdi r12,r1,THREAD_SHIFT + b syscall_exit_trace_cont - /* Disable interrupts again and handle other work if any */ -5: mfmsr r10 - rldicl r10,r10,48,1 - rotldi r10,r10,16 - mtmsrd r10,1 - +/* Stuff to do on exit from a system call. */ +syscall_exit_work: + std r3,GPR3(r1) + std r5,_CCR(r1) b .ret_from_except_lite /* Save non-volatile GPRs, if not already saved. */ @@ -282,52 +252,6 @@ _GLOBAL(save_nvgprs) std r0,_TRAP(r1) blr - -save_user_nvgprs: - ld r10,TI_SIGFRAME(r12) - andi. r0,r9,_TIF_32BIT - beq- save_user_nvgprs_64 - - /* 32-bit save to userspace */ - -.macro savewords start, end - 1: stw \start,4*(\start)(r10) - .section __ex_table,"a" - .align 3 - .llong 1b,save_user_nvgprs_fault - .previous - .if \end - \start - savewords "(\start+1)",\end - .endif -.endm - savewords 14,31 - b save_user_nvgprs_cont - -save_user_nvgprs_64: - /* 64-bit save to userspace */ - -.macro savelongs start, end - 1: std \start,8*(\start)(r10) - .section __ex_table,"a" - .align 3 - .llong 1b,save_user_nvgprs_fault - .previous - .if \end - \start - savelongs "(\start+1)",\end - .endif -.endm - savelongs 14,31 - b save_user_nvgprs_cont - -save_user_nvgprs_fault: - li r3,11 /* SIGSEGV */ - ld r4,TI_TASK(r12) - bl .force_sigsegv - - clrrdi r12,r1,THREAD_SHIFT - ld r9,TI_FLAGS(r12) - b save_user_nvgprs_cont - /* * The sigsuspend and rt_sigsuspend system calls can call do_signal * and thus put the process into the stopped state where we might @@ -336,6 +260,35 @@ save_user_nvgprs_fault: * the C code. Similarly, fork, vfork and clone need the full * register state on the stack so that it can be copied to the child. */ +_GLOBAL(ppc32_sigsuspend) + bl .save_nvgprs + bl .compat_sys_sigsuspend + b 70f + +_GLOBAL(ppc64_rt_sigsuspend) + bl .save_nvgprs + bl .sys_rt_sigsuspend + b 70f + +_GLOBAL(ppc32_rt_sigsuspend) + bl .save_nvgprs + bl .compat_sys_rt_sigsuspend +70: cmpdi 0,r3,0 + /* If it returned an error, we need to return via syscall_exit to set + the SO bit in cr0 and potentially stop for ptrace. */ + bne syscall_exit + /* If sigsuspend() returns zero, we are going into a signal handler. We + may need to call audit_syscall_exit() to mark the exit from sigsuspend() */ +#ifdef CONFIG_AUDITSYSCALL + ld r3,PACACURRENT(r13) + ld r4,AUDITCONTEXT(r3) + cmpdi 0,r4,0 + beq .ret_from_except /* No audit_context: Leave immediately. */ + li r4, 2 /* AUDITSC_FAILURE */ + li r5,-4 /* It's always -EINTR */ + bl .audit_syscall_exit +#endif + b .ret_from_except _GLOBAL(ppc_fork) bl .save_nvgprs @@ -352,6 +305,37 @@ _GLOBAL(ppc_clone) bl .sys_clone b syscall_exit +_GLOBAL(ppc32_swapcontext) + bl .save_nvgprs + bl .compat_sys_swapcontext + b 80f + +_GLOBAL(ppc64_swapcontext) + bl .save_nvgprs + bl .sys_swapcontext + b 80f + +_GLOBAL(ppc32_sigreturn) + bl .compat_sys_sigreturn + b 80f + +_GLOBAL(ppc32_rt_sigreturn) + bl .compat_sys_rt_sigreturn + b 80f + +_GLOBAL(ppc64_rt_sigreturn) + bl .sys_rt_sigreturn + +80: cmpdi 0,r3,0 + blt syscall_exit + clrrdi r4,r1,THREAD_SHIFT + ld r4,TI_FLAGS(r4) + andi. r4,r4,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) + beq+ 81f + addi r3,r1,STACK_FRAME_OVERHEAD + bl .do_syscall_trace_leave +81: b .ret_from_except + _GLOBAL(ret_from_fork) bl .schedule_tail REST_NVGPRS(r1) @@ -690,7 +674,7 @@ _GLOBAL(enter_rtas) /* Setup our real return addr */ SET_REG_TO_LABEL(r4,.rtas_return_loc) - SET_REG_TO_CONST(r9,PAGE_OFFSET) + SET_REG_TO_CONST(r9,KERNELBASE) sub r4,r4,r9 mtlr r4 @@ -718,7 +702,7 @@ _GLOBAL(enter_rtas) _STATIC(rtas_return_loc) /* relocation is off at this point */ mfspr r4,SPRN_SPRG3 /* Get PACA */ - SET_REG_TO_CONST(r5, PAGE_OFFSET) + SET_REG_TO_CONST(r5, KERNELBASE) sub r4,r4,r5 /* RELOC the PACA base pointer */ mfmsr r6 diff --git a/trunk/arch/powerpc/kernel/head_32.S b/trunk/arch/powerpc/kernel/head_32.S index 03b25f9359f8..ccdf94731e30 100644 --- a/trunk/arch/powerpc/kernel/head_32.S +++ b/trunk/arch/powerpc/kernel/head_32.S @@ -120,25 +120,10 @@ __start: * because OF may have I/O devices mapped into that area * (particularly on CHRP). */ -#ifdef CONFIG_PPC_MULTIPLATFORM cmpwi 0,r5,0 beq 1f bl prom_init trap -#endif - -/* - * Check for BootX signature when supporting PowerMac and branch to - * appropriate trampoline if it's present - */ -#ifdef CONFIG_PPC_PMAC -1: lis r31,0x426f - ori r31,r31,0x6f58 - cmpw 0,r3,r31 - bne 1f - bl bootx_init - trap -#endif /* CONFIG_PPC_PMAC */ 1: mr r31,r3 /* save parameters */ mr r30,r4 @@ -168,9 +153,6 @@ __after_mmu_off: bl flush_tlbs bl initial_bats -#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) - bl setup_disp_bat -#endif /* * Call setup_cpu for CPU 0 and initialize 6xx Idle @@ -468,11 +450,16 @@ SystemCall: * by executing an altivec instruction. */ . = 0xf00 - b PerformanceMonitor + b Trap_0f . = 0xf20 b AltiVecUnavailable +Trap_0f: + EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE(0xf00, unknown_exception) + /* * Handle TLB miss for instruction on 603/603e. * Note: we get an alternate set of r0 - r3 to use automatically. @@ -716,11 +703,6 @@ AltiVecUnavailable: #endif /* CONFIG_ALTIVEC */ EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception) -PerformanceMonitor: - EXCEPTION_PROLOG - addi r3,r1,STACK_FRAME_OVERHEAD - EXC_XFER_STD(0xf00, performance_monitor_exception) - #ifdef CONFIG_ALTIVEC /* Note that the AltiVec support is closely modeled after the FP * support. Changes to one are likely to be applicable to the @@ -1324,32 +1306,6 @@ initial_bats: blr -#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) -setup_disp_bat: - /* - * setup the display bat prepared for us in prom.c - */ - mflr r8 - bl reloc_offset - mtlr r8 - addis r8,r3,disp_BAT@ha - addi r8,r8,disp_BAT@l - cmpwi cr0,r8,0 - beqlr - lwz r11,0(r8) - lwz r8,4(r8) - mfspr r9,SPRN_PVR - rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ - cmpwi 0,r9,1 - beq 1f - mtspr SPRN_DBAT3L,r8 - mtspr SPRN_DBAT3U,r11 - blr -1: mtspr SPRN_IBAT3L,r8 - mtspr SPRN_IBAT3U,r11 - blr -#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */ - #ifdef CONFIG_8260 /* Jump into the system reset for the rom. * We first disable the MMU, and then jump to the ROM reset address. diff --git a/trunk/arch/powerpc/kernel/head_64.S b/trunk/arch/powerpc/kernel/head_64.S index 1c066d125375..8a8bf79ef044 100644 --- a/trunk/arch/powerpc/kernel/head_64.S +++ b/trunk/arch/powerpc/kernel/head_64.S @@ -154,15 +154,11 @@ _GLOBAL(__secondary_hold) bne 100b #ifdef CONFIG_HMT - LOADADDR(r4, .hmt_init) - mtctr r4 - bctr + b .hmt_init #else #ifdef CONFIG_SMP - LOADADDR(r4, .pSeries_secondary_smp_init) - mtctr r4 mr r3,r24 - bctr + b .pSeries_secondary_smp_init #else BUG_OPCODE #endif @@ -204,20 +200,6 @@ exception_marker: #define EX_R3 64 #define EX_LR 72 -/* - * We're short on space and time in the exception prolog, so we can't use - * the normal LOADADDR macro. Normally we just need the low halfword of the - * address, but for Kdump we need the whole low word. - */ -#ifdef CONFIG_CRASH_DUMP -#define LOAD_HANDLER(reg, label) \ - oris reg,reg,(label)@h; /* virt addr of handler ... */ \ - ori reg,reg,(label)@l; /* .. and the rest */ -#else -#define LOAD_HANDLER(reg, label) \ - ori reg,reg,(label)@l; /* virt addr of handler ... */ -#endif - #define EXCEPTION_PROLOG_PSERIES(area, label) \ mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ std r9,area+EX_R9(r13); /* save r9 - r12 */ \ @@ -230,7 +212,7 @@ exception_marker: clrrdi r12,r13,32; /* get high part of &label */ \ mfmsr r10; \ mfspr r11,SPRN_SRR0; /* save SRR0 */ \ - LOAD_HANDLER(r12,label) \ + ori r12,r12,(label)@l; /* virt addr of handler */ \ ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \ mtspr SPRN_SRR0,r12; \ mfspr r12,SPRN_SRR1; /* and SRR1 */ \ @@ -571,7 +553,6 @@ slb_miss_user_pseries: * Vectors for the FWNMI option. Share common code. */ .globl system_reset_fwnmi - .align 7 system_reset_fwnmi: HMT_MEDIUM mtspr SPRN_SPRG1,r13 /* save r13 */ @@ -579,7 +560,6 @@ system_reset_fwnmi: EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) .globl machine_check_fwnmi - .align 7 machine_check_fwnmi: HMT_MEDIUM mtspr SPRN_SPRG1,r13 /* save r13 */ @@ -746,8 +726,7 @@ iSeries_secondary_smp_loop: decrementer_iSeries_masked: li r11,1 stb r11,PACALPPACA+LPPACADECRINT(r13) - LOADBASE(r12,tb_ticks_per_jiffy) - lwz r12,OFF(tb_ticks_per_jiffy)(r12) + lwz r12,PACADEFAULTDECR(r13) mtspr SPRN_DEC,r12 /* fall through */ @@ -1366,7 +1345,7 @@ _GLOBAL(do_stab_bolted) * fixed address (the linker can't compute (u64)&initial_stab >> * PAGE_SHIFT). */ - . = STAB0_OFFSET /* 0x6000 */ + . = STAB0_PHYS_ADDR /* 0x6000 */ .globl initial_stab initial_stab: .space 4096 @@ -1506,13 +1485,11 @@ _STATIC(__mmu_off) * */ _GLOBAL(__start_initialization_multiplatform) -#ifdef CONFIG_PPC_MULTIPLATFORM /* * Are we booted from a PROM Of-type client-interface ? */ cmpldi cr0,r5,0 bne .__boot_from_prom /* yes -> prom */ -#endif /* Save parameters */ mr r31,r3 @@ -1533,7 +1510,6 @@ _GLOBAL(__start_initialization_multiplatform) bl .__mmu_off b .__after_prom_start -#ifdef CONFIG_PPC_MULTIPLATFORM _STATIC(__boot_from_prom) /* Save parameters */ mr r31,r3 @@ -1566,7 +1542,6 @@ _STATIC(__boot_from_prom) bl .prom_init /* We never return */ trap -#endif /* * At this point, r3 contains the physical address we are running at, @@ -1575,7 +1550,7 @@ _STATIC(__boot_from_prom) _STATIC(__after_prom_start) /* - * We need to run with __start at physical address PHYSICAL_START. + * We need to run with __start at physical address 0. * This will leave some code in the first 256B of * real memory, which are reserved for software use. * The remainder of the first page is loaded with the fixed @@ -1590,7 +1565,7 @@ _STATIC(__after_prom_start) mr r26,r3 SET_REG_TO_CONST(r27,KERNELBASE) - LOADADDR(r3, PHYSICAL_START) /* target addr */ + li r3,0 /* target addr */ // XXX FIXME: Use phys returned by OF (r30) add r4,r27,r26 /* source addr */ @@ -1871,7 +1846,7 @@ _STATIC(start_here_multiplatform) mulli r13,r27,PACA_SIZE /* Calculate vaddr of right paca */ add r13,r13,r24 /* for this processor. */ add r13,r13,r26 /* convert to physical addr */ - mtspr SPRN_SPRG3,r13 + mtspr SPRN_SPRG3,r13 /* PPPBBB: Temp... -Peter */ /* Do very early kernel initializations, including initial hash table, * stab and slb setup before we turn on relocation. */ diff --git a/trunk/arch/powerpc/kernel/ibmebus.c b/trunk/arch/powerpc/kernel/ibmebus.c deleted file mode 100644 index e47d40ac6f39..000000000000 --- a/trunk/arch/powerpc/kernel/ibmebus.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * IBM PowerPC IBM eBus Infrastructure Support. - * - * Copyright (c) 2005 IBM Corporation - * Heiko J Schick - * - * All rights reserved. - * - * This source code is distributed under a dual license of GPL v2.0 and OpenIB - * BSD. - * - * OpenIB BSD License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include - -static struct ibmebus_dev ibmebus_bus_device = { /* fake "parent" device */ - .name = ibmebus_bus_device.ofdev.dev.bus_id, - .ofdev.dev.bus_id = "ibmebus", - .ofdev.dev.bus = &ibmebus_bus_type, -}; - -static void *ibmebus_alloc_coherent(struct device *dev, - size_t size, - dma_addr_t *dma_handle, - gfp_t flag) -{ - void *mem; - - mem = kmalloc(size, flag); - *dma_handle = (dma_addr_t)mem; - - return mem; -} - -static void ibmebus_free_coherent(struct device *dev, - size_t size, void *vaddr, - dma_addr_t dma_handle) -{ - kfree(vaddr); -} - -static dma_addr_t ibmebus_map_single(struct device *dev, - void *ptr, - size_t size, - enum dma_data_direction direction) -{ - return (dma_addr_t)(ptr); -} - -static void ibmebus_unmap_single(struct device *dev, - dma_addr_t dma_addr, - size_t size, - enum dma_data_direction direction) -{ - return; -} - -static int ibmebus_map_sg(struct device *dev, - struct scatterlist *sg, - int nents, enum dma_data_direction direction) -{ - int i; - - for (i = 0; i < nents; i++) { - sg[i].dma_address = (dma_addr_t)page_address(sg[i].page) - + sg[i].offset; - sg[i].dma_length = sg[i].length; - } - - return nents; -} - -static void ibmebus_unmap_sg(struct device *dev, - struct scatterlist *sg, - int nents, enum dma_data_direction direction) -{ - return; -} - -static int ibmebus_dma_supported(struct device *dev, u64 mask) -{ - return 1; -} - -struct dma_mapping_ops ibmebus_dma_ops = { - .alloc_coherent = ibmebus_alloc_coherent, - .free_coherent = ibmebus_free_coherent, - .map_single = ibmebus_map_single, - .unmap_single = ibmebus_unmap_single, - .map_sg = ibmebus_map_sg, - .unmap_sg = ibmebus_unmap_sg, - .dma_supported = ibmebus_dma_supported, -}; - -static int ibmebus_bus_probe(struct device *dev) -{ - struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev); - struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver); - const struct of_device_id *id; - int error = -ENODEV; - - if (!ibmebusdrv->probe) - return error; - - id = of_match_device(ibmebusdrv->id_table, &ibmebusdev->ofdev); - if (id) { - error = ibmebusdrv->probe(ibmebusdev, id); - } - - return error; -} - -static int ibmebus_bus_remove(struct device *dev) -{ - struct ibmebus_dev *ibmebusdev = to_ibmebus_dev(dev); - struct ibmebus_driver *ibmebusdrv = to_ibmebus_driver(dev->driver); - - if (ibmebusdrv->remove) { - return ibmebusdrv->remove(ibmebusdev); - } - - return 0; -} - -static void __devinit ibmebus_dev_release(struct device *dev) -{ - of_node_put(to_ibmebus_dev(dev)->ofdev.node); - kfree(to_ibmebus_dev(dev)); -} - -static ssize_t ibmebusdev_show_name(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%s\n", to_ibmebus_dev(dev)->name); -} -static DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, ibmebusdev_show_name, - NULL); - -static struct ibmebus_dev* __devinit ibmebus_register_device_common( - struct ibmebus_dev *dev, char *name) -{ - int err = 0; - - dev->name = name; - dev->ofdev.dev.parent = &ibmebus_bus_device.ofdev.dev; - dev->ofdev.dev.bus = &ibmebus_bus_type; - dev->ofdev.dev.release = ibmebus_dev_release; - - /* An ibmebusdev is based on a of_device. We have to change the - * bus type to use our own DMA mapping operations. - */ - if ((err = of_device_register(&dev->ofdev)) != 0) { - printk(KERN_ERR "%s: failed to register device (%d).\n", - __FUNCTION__, err); - return NULL; - } - - device_create_file(&dev->ofdev.dev, &dev_attr_name); - - return dev; -} - -static struct ibmebus_dev* __devinit ibmebus_register_device_node( - struct device_node *dn) -{ - struct ibmebus_dev *dev; - char *loc_code; - int length; - - loc_code = (char *)get_property(dn, "ibm,loc-code", NULL); - if (!loc_code) { - printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n", - __FUNCTION__, dn->name ? dn->name : ""); - return NULL; - } - - if (strlen(loc_code) == 0) { - printk(KERN_WARNING "%s: 'ibm,loc-code' is invalid\n", - __FUNCTION__); - return NULL; - } - - dev = kmalloc(sizeof(struct ibmebus_dev), GFP_KERNEL); - if (!dev) { - return NULL; - } - memset(dev, 0, sizeof(struct ibmebus_dev)); - - dev->ofdev.node = of_node_get(dn); - - length = strlen(loc_code); - memcpy(dev->ofdev.dev.bus_id, loc_code - + (length - min(length, BUS_ID_SIZE - 1)), - min(length, BUS_ID_SIZE - 1)); - - /* Register with generic device framework. */ - if (ibmebus_register_device_common(dev, dn->name) == NULL) { - kfree(dev); - return NULL; - } - - return dev; -} - -static void ibmebus_probe_of_nodes(char* name) -{ - struct device_node *dn = NULL; - - while ((dn = of_find_node_by_name(dn, name))) { - if (ibmebus_register_device_node(dn) == NULL) { - of_node_put(dn); - - return; - } - } - - of_node_put(dn); - - return; -} - -static void ibmebus_add_devices_by_id(struct of_device_id *idt) -{ - while (strlen(idt->name) > 0) { - ibmebus_probe_of_nodes(idt->name); - idt++; - } - - return; -} - -static int ibmebus_match_helper(struct device *dev, void *data) -{ - if (strcmp((char*)data, to_ibmebus_dev(dev)->name) == 0) - return 1; - - return 0; -} - -static int ibmebus_unregister_device(struct device *dev) -{ - device_remove_file(dev, &dev_attr_name); - of_device_unregister(to_of_device(dev)); - - return 0; -} - -static void ibmebus_remove_devices_by_id(struct of_device_id *idt) -{ - struct device *dev; - - while (strlen(idt->name) > 0) { - while ((dev = bus_find_device(&ibmebus_bus_type, NULL, - (void*)idt->name, - ibmebus_match_helper))) { - ibmebus_unregister_device(dev); - } - idt++; - - } - - return; -} - -int ibmebus_register_driver(struct ibmebus_driver *drv) -{ - int err = 0; - - drv->driver.name = drv->name; - drv->driver.bus = &ibmebus_bus_type; - drv->driver.probe = ibmebus_bus_probe; - drv->driver.remove = ibmebus_bus_remove; - - if ((err = driver_register(&drv->driver) != 0)) - return err; - - ibmebus_add_devices_by_id(drv->id_table); - - return 0; -} -EXPORT_SYMBOL(ibmebus_register_driver); - -void ibmebus_unregister_driver(struct ibmebus_driver *drv) -{ - driver_unregister(&drv->driver); - ibmebus_remove_devices_by_id(drv->id_table); -} -EXPORT_SYMBOL(ibmebus_unregister_driver); - -int ibmebus_request_irq(struct ibmebus_dev *dev, - u32 ist, - irqreturn_t (*handler)(int, void*, struct pt_regs *), - unsigned long irq_flags, const char * devname, - void *dev_id) -{ - unsigned int irq = virt_irq_create_mapping(ist); - - if (irq == NO_IRQ) - return -EINVAL; - - irq = irq_offset_up(irq); - - return request_irq(irq, handler, - irq_flags, devname, dev_id); -} -EXPORT_SYMBOL(ibmebus_request_irq); - -void ibmebus_free_irq(struct ibmebus_dev *dev, u32 ist, void *dev_id) -{ - unsigned int irq = virt_irq_create_mapping(ist); - - irq = irq_offset_up(irq); - free_irq(irq, dev_id); - - return; -} -EXPORT_SYMBOL(ibmebus_free_irq); - -static int ibmebus_bus_match(struct device *dev, struct device_driver *drv) -{ - const struct ibmebus_dev *ebus_dev = to_ibmebus_dev(dev); - struct ibmebus_driver *ebus_drv = to_ibmebus_driver(drv); - const struct of_device_id *ids = ebus_drv->id_table; - const struct of_device_id *found_id; - - if (!ids) - return 0; - - found_id = of_match_device(ids, &ebus_dev->ofdev); - if (found_id) - return 1; - - return 0; -} - -struct bus_type ibmebus_bus_type = { - .name = "ibmebus", - .match = ibmebus_bus_match, -}; -EXPORT_SYMBOL(ibmebus_bus_type); - -static int __init ibmebus_bus_init(void) -{ - int err; - - printk(KERN_INFO "IBM eBus Device Driver\n"); - - err = bus_register(&ibmebus_bus_type); - if (err) { - printk(KERN_ERR ":%s: failed to register IBM eBus.\n", - __FUNCTION__); - return err; - } - - err = device_register(&ibmebus_bus_device.ofdev.dev); - if (err) { - printk(KERN_WARNING "%s: device_register returned %i\n", - __FUNCTION__, err); - bus_unregister(&ibmebus_bus_type); - - return err; - } - - return 0; -} -__initcall(ibmebus_bus_init); diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 5651032d8706..5a71ed9612fe 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -31,6 +31,7 @@ * to reduce code space and undefined function references. */ +#include #include #include #include @@ -43,12 +44,18 @@ #include #include #include +#include #include #include +#include +#include #include #include #include #include +#ifdef CONFIG_PPC64 +#include +#endif #include #include @@ -59,7 +66,8 @@ #include #include #include -#ifdef CONFIG_PPC_ISERIES +#ifdef CONFIG_PPC64 +#include #include #endif @@ -70,6 +78,10 @@ EXPORT_SYMBOL(__irq_offset_value); static int ppc_spurious_interrupts; +#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_SMP) +extern void iSeries_smp_message_recv(struct pt_regs *); +#endif + #ifdef CONFIG_PPC32 #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) @@ -183,6 +195,49 @@ void fixup_irqs(cpumask_t map) } #endif +#ifdef CONFIG_PPC_ISERIES +void do_IRQ(struct pt_regs *regs) +{ + struct paca_struct *lpaca; + + irq_enter(); + +#ifdef CONFIG_DEBUG_STACKOVERFLOW + /* Debugging check for stack overflow: is there less than 2KB free? */ + { + long sp; + + sp = __get_SP() & (THREAD_SIZE-1); + + if (unlikely(sp < (sizeof(struct thread_info) + 2048))) { + printk("do_IRQ: stack overflow: %ld\n", + sp - sizeof(struct thread_info)); + dump_stack(); + } + } +#endif + + lpaca = get_paca(); +#ifdef CONFIG_SMP + if (lpaca->lppaca.int_dword.fields.ipi_cnt) { + lpaca->lppaca.int_dword.fields.ipi_cnt = 0; + iSeries_smp_message_recv(regs); + } +#endif /* CONFIG_SMP */ + if (hvlpevent_is_pending()) + process_hvlpevents(regs); + + irq_exit(); + + if (lpaca->lppaca.int_dword.fields.decr_int) { + lpaca->lppaca.int_dword.fields.decr_int = 0; + /* Signal a fake decrementer interrupt */ + timer_interrupt(regs); + } +} + +#else /* CONFIG_PPC_ISERIES */ + void do_IRQ(struct pt_regs *regs) { int irq; @@ -231,25 +286,17 @@ void do_IRQ(struct pt_regs *regs) } else #endif __do_IRQ(irq, regs); - } else if (irq != -2) - /* That's not SMP safe ... but who cares ? */ - ppc_spurious_interrupts++; - - irq_exit(); - -#ifdef CONFIG_PPC_ISERIES - { - struct paca_struct *lpaca = get_paca(); - - if (lpaca->lppaca.int_dword.fields.decr_int) { - lpaca->lppaca.int_dword.fields.decr_int = 0; - /* Signal a fake decrementer interrupt */ - timer_interrupt(regs); - } - } + } else +#ifdef CONFIG_PPC32 + if (irq != -2) #endif + /* That's not SMP safe ... but who cares ? */ + ppc_spurious_interrupts++; + irq_exit(); } +#endif /* CONFIG_PPC_ISERIES */ + void __init init_IRQ(void) { #ifdef CONFIG_PPC64 diff --git a/trunk/arch/powerpc/kernel/legacy_serial.c b/trunk/arch/powerpc/kernel/legacy_serial.c deleted file mode 100644 index f970ace208d3..000000000000 --- a/trunk/arch/powerpc/kernel/legacy_serial.c +++ /dev/null @@ -1,557 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef DEBUG - -#ifdef DEBUG -#define DBG(fmt...) do { printk(fmt); } while(0) -#else -#define DBG(fmt...) do { } while(0) -#endif - -#define MAX_LEGACY_SERIAL_PORTS 8 - -static struct plat_serial8250_port -legacy_serial_ports[MAX_LEGACY_SERIAL_PORTS+1]; -static struct legacy_serial_info { - struct device_node *np; - unsigned int speed; - unsigned int clock; - phys_addr_t taddr; -} legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS]; -static unsigned int legacy_serial_count; -static int legacy_serial_console = -1; - -static int __init add_legacy_port(struct device_node *np, int want_index, - int iotype, phys_addr_t base, - phys_addr_t taddr, unsigned long irq, - unsigned int flags) -{ - u32 *clk, *spd, clock = BASE_BAUD * 16; - int index; - - /* get clock freq. if present */ - clk = (u32 *)get_property(np, "clock-frequency", NULL); - if (clk && *clk) - clock = *clk; - - /* get default speed if present */ - spd = (u32 *)get_property(np, "current-speed", NULL); - - /* If we have a location index, then try to use it */ - if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS) - index = want_index; - else - index = legacy_serial_count; - - /* if our index is still out of range, that mean that - * array is full, we could scan for a free slot but that - * make little sense to bother, just skip the port - */ - if (index >= MAX_LEGACY_SERIAL_PORTS) - return -1; - if (index >= legacy_serial_count) - legacy_serial_count = index + 1; - - /* Check if there is a port who already claimed our slot */ - if (legacy_serial_infos[index].np != 0) { - /* if we still have some room, move it, else override */ - if (legacy_serial_count < MAX_LEGACY_SERIAL_PORTS) { - printk(KERN_INFO "Moved legacy port %d -> %d\n", - index, legacy_serial_count); - legacy_serial_ports[legacy_serial_count] = - legacy_serial_ports[index]; - legacy_serial_infos[legacy_serial_count] = - legacy_serial_infos[index]; - legacy_serial_count++; - } else { - printk(KERN_INFO "Replacing legacy port %d\n", index); - } - } - - /* Now fill the entry */ - memset(&legacy_serial_ports[index], 0, - sizeof(struct plat_serial8250_port)); - if (iotype == UPIO_PORT) - legacy_serial_ports[index].iobase = base; - else - legacy_serial_ports[index].mapbase = base; - legacy_serial_ports[index].iotype = iotype; - legacy_serial_ports[index].uartclk = clock; - legacy_serial_ports[index].irq = irq; - legacy_serial_ports[index].flags = flags; - legacy_serial_infos[index].taddr = taddr; - legacy_serial_infos[index].np = of_node_get(np); - legacy_serial_infos[index].clock = clock; - legacy_serial_infos[index].speed = spd ? *spd : 0; - - printk(KERN_INFO "Found legacy serial port %d for %s\n", - index, np->full_name); - printk(KERN_INFO " %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n", - (iotype == UPIO_PORT) ? "port" : "mem", - (unsigned long long)base, (unsigned long long)taddr, irq, - legacy_serial_ports[index].uartclk, - legacy_serial_infos[index].speed); - - return index; -} - -static int __init add_legacy_soc_port(struct device_node *np, - struct device_node *soc_dev) -{ - phys_addr_t addr; - u32 *addrp; - unsigned int flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; - - /* We only support ports that have a clock frequency properly - * encoded in the device-tree. - */ - if (get_property(np, "clock-frequency", NULL) == NULL) - return -1; - - /* Get the address */ - addrp = of_get_address(soc_dev, 0, NULL, NULL); - if (addrp == NULL) - return -1; - - addr = of_translate_address(soc_dev, addrp); - - /* Add port, irq will be dealt with later. We passed a translated - * IO port value. It will be fixed up later along with the irq - */ - return add_legacy_port(np, -1, UPIO_MEM, addr, addr, NO_IRQ, flags); -} - -#ifdef CONFIG_ISA -static int __init add_legacy_isa_port(struct device_node *np, - struct device_node *isa_brg) -{ - u32 *reg; - char *typep; - int index = -1; - phys_addr_t taddr; - - /* Get the ISA port number */ - reg = (u32 *)get_property(np, "reg", NULL); - if (reg == NULL) - return -1; - - /* Verify it's an IO port, we don't support anything else */ - if (!(reg[0] & 0x00000001)) - return -1; - - /* Now look for an "ibm,aix-loc" property that gives us ordering - * if any... - */ - typep = (char *)get_property(np, "ibm,aix-loc", NULL); - - /* If we have a location index, then use it */ - if (typep && *typep == 'S') - index = simple_strtol(typep+1, NULL, 0) - 1; - - /* Translate ISA address */ - taddr = of_translate_address(np, reg); - - /* Add port, irq will be dealt with later */ - return add_legacy_port(np, index, UPIO_PORT, reg[1], taddr, NO_IRQ, UPF_BOOT_AUTOCONF); - -} -#endif - -#ifdef CONFIG_PCI -static int __init add_legacy_pci_port(struct device_node *np, - struct device_node *pci_dev) -{ - phys_addr_t addr, base; - u32 *addrp; - unsigned int flags; - int iotype, index = -1, lindex = 0; - - /* We only support ports that have a clock frequency properly - * encoded in the device-tree (that is have an fcode). Anything - * else can't be used that early and will be normally probed by - * the generic 8250_pci driver later on. The reason is that 8250 - * compatible UARTs on PCI need all sort of quirks (port offsets - * etc...) that this code doesn't know about - */ - if (get_property(np, "clock-frequency", NULL) == NULL) - return -1; - - /* Get the PCI address. Assume BAR 0 */ - addrp = of_get_pci_address(pci_dev, 0, NULL, &flags); - if (addrp == NULL) - return -1; - - /* We only support BAR 0 for now */ - iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT; - addr = of_translate_address(pci_dev, addrp); - - /* Set the IO base to the same as the translated address for MMIO, - * or to the domain local IO base for PIO (it will be fixed up later) - */ - if (iotype == UPIO_MEM) - base = addr; - else - base = addrp[2]; - - /* Try to guess an index... If we have subdevices of the pci dev, - * we get to their "reg" property - */ - if (np != pci_dev) { - u32 *reg = (u32 *)get_property(np, "reg", NULL); - if (reg && (*reg < 4)) - index = lindex = *reg; - } - - /* Local index means it's the Nth port in the PCI chip. Unfortunately - * the offset to add here is device specific. We know about those - * EXAR ports and we default to the most common case. If your UART - * doesn't work for these settings, you'll have to add your own special - * cases here - */ - if (device_is_compatible(pci_dev, "pci13a8,152") || - device_is_compatible(pci_dev, "pci13a8,154") || - device_is_compatible(pci_dev, "pci13a8,158")) { - addr += 0x200 * lindex; - base += 0x200 * lindex; - } else { - addr += 8 * lindex; - base += 8 * lindex; - } - - /* Add port, irq will be dealt with later. We passed a translated - * IO port value. It will be fixed up later along with the irq - */ - return add_legacy_port(np, index, iotype, base, addr, NO_IRQ, UPF_BOOT_AUTOCONF); -} -#endif - -/* - * This is called very early, as part of setup_system() or eventually - * setup_arch(), basically before anything else in this file. This function - * will try to build a list of all the available 8250-compatible serial ports - * in the machine using the Open Firmware device-tree. It currently only deals - * with ISA and PCI busses but could be extended. It allows a very early boot - * console to be initialized, that list is also used later to provide 8250 with - * the machine non-PCI ports and to properly pick the default console port - */ -void __init find_legacy_serial_ports(void) -{ - struct device_node *np, *stdout = NULL; - char *path; - int index; - - DBG(" -> find_legacy_serial_port()\n"); - - /* Now find out if one of these is out firmware console */ - path = (char *)get_property(of_chosen, "linux,stdout-path", NULL); - if (path != NULL) { - stdout = of_find_node_by_path(path); - if (stdout) - DBG("stdout is %s\n", stdout->full_name); - } else { - DBG(" no linux,stdout-path !\n"); - } - - /* First fill our array with SOC ports */ - for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { - struct device_node *soc = of_get_parent(np); - if (soc && !strcmp(soc->type, "soc")) { - index = add_legacy_soc_port(np, np); - if (index >= 0 && np == stdout) - legacy_serial_console = index; - } - of_node_put(soc); - } - -#ifdef CONFIG_ISA - /* First fill our array with ISA ports */ - for (np = NULL; (np = of_find_node_by_type(np, "serial"));) { - struct device_node *isa = of_get_parent(np); - if (isa && !strcmp(isa->name, "isa")) { - index = add_legacy_isa_port(np, isa); - if (index >= 0 && np == stdout) - legacy_serial_console = index; - } - of_node_put(isa); - } -#endif - -#ifdef CONFIG_PCI - /* Next, try to locate PCI ports */ - for (np = NULL; (np = of_find_all_nodes(np));) { - struct device_node *pci, *parent = of_get_parent(np); - if (parent && !strcmp(parent->name, "isa")) { - of_node_put(parent); - continue; - } - if (strcmp(np->name, "serial") && strcmp(np->type, "serial")) { - of_node_put(parent); - continue; - } - /* Check for known pciclass, and also check wether we have - * a device with child nodes for ports or not - */ - if (device_is_compatible(np, "pciclass,0700") || - device_is_compatible(np, "pciclass,070002")) - pci = np; - else if (device_is_compatible(parent, "pciclass,0700") || - device_is_compatible(parent, "pciclass,070002")) - pci = parent; - else { - of_node_put(parent); - continue; - } - index = add_legacy_pci_port(np, pci); - if (index >= 0 && np == stdout) - legacy_serial_console = index; - of_node_put(parent); - } -#endif - - DBG("legacy_serial_console = %d\n", legacy_serial_console); - - /* udbg is 64 bits only for now, that will change soon though ... */ - while (legacy_serial_console >= 0) { - struct legacy_serial_info *info = - &legacy_serial_infos[legacy_serial_console]; - void __iomem *addr; - - if (info->taddr == 0) - break; - addr = ioremap(info->taddr, 0x1000); - if (addr == NULL) - break; - if (info->speed == 0) - info->speed = udbg_probe_uart_speed(addr, info->clock); - DBG("default console speed = %d\n", info->speed); - udbg_init_uart(addr, info->speed, info->clock); - break; - } - - DBG(" <- find_legacy_serial_port()\n"); -} - -static struct platform_device serial_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = legacy_serial_ports, - }, -}; - -static void __init fixup_port_irq(int index, - struct device_node *np, - struct plat_serial8250_port *port) -{ - DBG("fixup_port_irq(%d)\n", index); - - /* Check for interrupts in that node */ - if (np->n_intrs > 0) { - port->irq = np->intrs[0].line; - DBG(" port %d (%s), irq=%d\n", - index, np->full_name, port->irq); - return; - } - - /* Check for interrupts in the parent */ - np = of_get_parent(np); - if (np == NULL) - return; - - if (np->n_intrs > 0) { - port->irq = np->intrs[0].line; - DBG(" port %d (%s), irq=%d\n", - index, np->full_name, port->irq); - } - of_node_put(np); -} - -static void __init fixup_port_pio(int index, - struct device_node *np, - struct plat_serial8250_port *port) -{ -#ifdef CONFIG_PCI - struct pci_controller *hose; - - DBG("fixup_port_pio(%d)\n", index); - - hose = pci_find_hose_for_OF_device(np); - if (hose) { - unsigned long offset = (unsigned long)hose->io_base_virt - -#ifdef CONFIG_PPC64 - pci_io_base; -#else - isa_io_base; -#endif - DBG("port %d, IO %lx -> %lx\n", - index, port->iobase, port->iobase + offset); - port->iobase += offset; - } -#endif -} - -static void __init fixup_port_mmio(int index, - struct device_node *np, - struct plat_serial8250_port *port) -{ - DBG("fixup_port_mmio(%d)\n", index); - - port->membase = ioremap(port->mapbase, 0x100); -} - -/* - * This is called as an arch initcall, hopefully before the PCI bus is - * probed and/or the 8250 driver loaded since we need to register our - * platform devices before 8250 PCI ones are detected as some of them - * must properly "override" the platform ones. - * - * This function fixes up the interrupt value for platform ports as it - * couldn't be done earlier before interrupt maps have been parsed. It - * also "corrects" the IO address for PIO ports for the same reason, - * since earlier, the PHBs virtual IO space wasn't assigned yet. It then - * registers all those platform ports for use by the 8250 driver when it - * finally loads. - */ -static int __init serial_dev_init(void) -{ - int i; - - if (legacy_serial_count == 0) - return -ENODEV; - - /* - * Before we register the platfrom serial devices, we need - * to fixup their interrutps and their IO ports. - */ - DBG("Fixing serial ports interrupts and IO ports ...\n"); - - for (i = 0; i < legacy_serial_count; i++) { - struct plat_serial8250_port *port = &legacy_serial_ports[i]; - struct device_node *np = legacy_serial_infos[i].np; - - if (port->irq == NO_IRQ) - fixup_port_irq(i, np, port); - if (port->iotype == UPIO_PORT) - fixup_port_pio(i, np, port); - if (port->iotype == UPIO_MEM) - fixup_port_mmio(i, np, port); - } - - DBG("Registering platform serial ports\n"); - - return platform_device_register(&serial_device); -} -arch_initcall(serial_dev_init); - - -/* - * This is called very early, as part of console_init() (typically just after - * time_init()). This function is respondible for trying to find a good - * default console on serial ports. It tries to match the open firmware - * default output with one of the available serial console drivers, either - * one of the platform serial ports that have been probed earlier by - * find_legacy_serial_ports() or some more platform specific ones. - */ -static int __init check_legacy_serial_console(void) -{ - struct device_node *prom_stdout = NULL; - int speed = 0, offset = 0; - char *name; - u32 *spd; - - DBG(" -> check_legacy_serial_console()\n"); - - /* The user has requested a console so this is already set up. */ - if (strstr(saved_command_line, "console=")) { - DBG(" console was specified !\n"); - return -EBUSY; - } - - if (!of_chosen) { - DBG(" of_chosen is NULL !\n"); - return -ENODEV; - } - - if (legacy_serial_console < 0) { - DBG(" legacy_serial_console not found !\n"); - return -ENODEV; - } - /* We are getting a weird phandle from OF ... */ - /* ... So use the full path instead */ - name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); - if (name == NULL) { - DBG(" no linux,stdout-path !\n"); - return -ENODEV; - } - prom_stdout = of_find_node_by_path(name); - if (!prom_stdout) { - DBG(" can't find stdout package %s !\n", name); - return -ENODEV; - } - DBG("stdout is %s\n", prom_stdout->full_name); - - name = (char *)get_property(prom_stdout, "name", NULL); - if (!name) { - DBG(" stdout package has no name !\n"); - goto not_found; - } - spd = (u32 *)get_property(prom_stdout, "current-speed", NULL); - if (spd) - speed = *spd; - - if (0) - ; -#ifdef CONFIG_SERIAL_8250_CONSOLE - else if (strcmp(name, "serial") == 0) { - int i; - /* Look for it in probed array */ - for (i = 0; i < legacy_serial_count; i++) { - if (prom_stdout != legacy_serial_infos[i].np) - continue; - offset = i; - speed = legacy_serial_infos[i].speed; - break; - } - if (i >= legacy_serial_count) - goto not_found; - } -#endif /* CONFIG_SERIAL_8250_CONSOLE */ -#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE - else if (strcmp(name, "ch-a") == 0) - offset = 0; - else if (strcmp(name, "ch-b") == 0) - offset = 1; -#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */ - else - goto not_found; - of_node_put(prom_stdout); - - DBG("Found serial console at ttyS%d\n", offset); - - if (speed) { - static char __initdata opt[16]; - sprintf(opt, "%d", speed); - return add_preferred_console("ttyS", offset, opt); - } else - return add_preferred_console("ttyS", offset, NULL); - - not_found: - DBG("No preferred console found !\n"); - of_node_put(prom_stdout); - return -ENODEV; -} -console_initcall(check_legacy_serial_console); - diff --git a/trunk/arch/powerpc/kernel/lparmap.c b/trunk/arch/powerpc/kernel/lparmap.c index 584d1e3c013d..5a05a797485f 100644 --- a/trunk/arch/powerpc/kernel/lparmap.c +++ b/trunk/arch/powerpc/kernel/lparmap.c @@ -7,7 +7,7 @@ * 2 of the License, or (at your option) any later version. */ #include -#include +#include #include const struct LparMap __attribute__((__section__(".text"))) xLparMap = { @@ -16,16 +16,16 @@ const struct LparMap __attribute__((__section__(".text"))) xLparMap = { .xSegmentTableOffs = STAB0_PAGE, .xEsids = { - { .xKernelEsid = GET_ESID(PAGE_OFFSET), - .xKernelVsid = KERNEL_VSID(PAGE_OFFSET), }, - { .xKernelEsid = GET_ESID(VMALLOC_START), - .xKernelVsid = KERNEL_VSID(VMALLOC_START), }, + { .xKernelEsid = GET_ESID(KERNELBASE), + .xKernelVsid = KERNEL_VSID(KERNELBASE), }, + { .xKernelEsid = GET_ESID(VMALLOCBASE), + .xKernelVsid = KERNEL_VSID(VMALLOCBASE), }, }, .xRanges = { { .xPages = HvPagesToMap, .xOffset = 0, - .xVPN = KERNEL_VSID(PAGE_OFFSET) << (SID_SHIFT - HW_PAGE_SHIFT), + .xVPN = KERNEL_VSID(KERNELBASE) << (SID_SHIFT - HW_PAGE_SHIFT), }, }, }; diff --git a/trunk/arch/powerpc/kernel/machine_kexec.c b/trunk/arch/powerpc/kernel/machine_kexec.c deleted file mode 100644 index a91e40c9ae45..000000000000 --- a/trunk/arch/powerpc/kernel/machine_kexec.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Code to handle transition of Linux booting another kernel. - * - * Copyright (C) 2002-2003 Eric Biederman - * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz - * Copyright (C) 2005 IBM Corporation. - * - * This source code is licensed under the GNU General Public License, - * Version 2. See the file COPYING for more details. - */ - -#include -#include -#include -#include - -/* - * Provide a dummy crash_notes definition until crash dump is implemented. - * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. - */ -note_buf_t crash_notes[NR_CPUS]; - -void machine_crash_shutdown(struct pt_regs *regs) -{ - if (ppc_md.machine_crash_shutdown) - ppc_md.machine_crash_shutdown(regs); -} - -/* - * Do what every setup is needed on image and the - * reboot code buffer to allow us to avoid allocations - * later. - */ -int machine_kexec_prepare(struct kimage *image) -{ - if (ppc_md.machine_kexec_prepare) - return ppc_md.machine_kexec_prepare(image); - /* - * Fail if platform doesn't provide its own machine_kexec_prepare - * implementation. - */ - return -ENOSYS; -} - -void machine_kexec_cleanup(struct kimage *image) -{ - if (ppc_md.machine_kexec_cleanup) - ppc_md.machine_kexec_cleanup(image); -} - -/* - * Do not allocate memory (or fail in any way) in machine_kexec(). - * We are past the point of no return, committed to rebooting now. - */ -NORET_TYPE void machine_kexec(struct kimage *image) -{ - if (ppc_md.machine_kexec) - ppc_md.machine_kexec(image); - else { - /* - * Fall back to normal restart if platform doesn't provide - * its own kexec function, and user insist to kexec... - */ - machine_restart(NULL); - } - for(;;); -} diff --git a/trunk/arch/powerpc/kernel/machine_kexec_32.c b/trunk/arch/powerpc/kernel/machine_kexec_32.c deleted file mode 100644 index 443606134dff..000000000000 --- a/trunk/arch/powerpc/kernel/machine_kexec_32.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * PPC32 code to handle Linux booting another kernel. - * - * Copyright (C) 2002-2003 Eric Biederman - * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz - * Copyright (C) 2005 IBM Corporation. - * - * This source code is licensed under the GNU General Public License, - * Version 2. See the file COPYING for more details. - */ - -#include -#include -#include -#include -#include -#include - -typedef NORET_TYPE void (*relocate_new_kernel_t)( - unsigned long indirection_page, - unsigned long reboot_code_buffer, - unsigned long start_address) ATTRIB_NORET; - -/* - * This is a generic machine_kexec function suitable at least for - * non-OpenFirmware embedded platforms. - * It merely copies the image relocation code to the control page and - * jumps to it. - * A platform specific function may just call this one. - */ -void default_machine_kexec(struct kimage *image) -{ - const extern unsigned char relocate_new_kernel[]; - const extern unsigned int relocate_new_kernel_size; - unsigned long page_list; - unsigned long reboot_code_buffer, reboot_code_buffer_phys; - relocate_new_kernel_t rnk; - - /* Interrupts aren't acceptable while we reboot */ - local_irq_disable(); - - page_list = image->head; - - /* we need both effective and real address here */ - reboot_code_buffer = - (unsigned long)page_address(image->control_code_page); - reboot_code_buffer_phys = virt_to_phys((void *)reboot_code_buffer); - - /* copy our kernel relocation code to the control code page */ - memcpy((void *)reboot_code_buffer, relocate_new_kernel, - relocate_new_kernel_size); - - flush_icache_range(reboot_code_buffer, - reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE); - printk(KERN_INFO "Bye!\n"); - - /* now call it */ - rnk = (relocate_new_kernel_t) reboot_code_buffer; - (*rnk)(page_list, reboot_code_buffer_phys, image->start); -} - -int default_machine_kexec_prepare(struct kimage *image) -{ - return 0; -} diff --git a/trunk/arch/powerpc/kernel/machine_kexec_64.c b/trunk/arch/powerpc/kernel/machine_kexec_64.c index d6431440c54f..97c51e452be7 100644 --- a/trunk/arch/powerpc/kernel/machine_kexec_64.c +++ b/trunk/arch/powerpc/kernel/machine_kexec_64.c @@ -1,5 +1,5 @@ /* - * PPC64 code to handle Linux booting another kernel. + * machine_kexec.c - handle transition of Linux booting another kernel * * Copyright (C) 2004-2005, IBM Corp. * @@ -28,7 +28,21 @@ #define HASH_GROUP_SIZE 0x80 /* size of each hash group, asm/mmu.h */ -int default_machine_kexec_prepare(struct kimage *image) +/* Have this around till we move it into crash specific file */ +note_buf_t crash_notes[NR_CPUS]; + +/* Dummy for now. Not sure if we need to have a crash shutdown in here + * and if what it will achieve. Letting it be now to compile the code + * in generic kexec environment + */ +void machine_crash_shutdown(struct pt_regs *regs) +{ + /* do nothing right now */ + /* smp_relase_cpus() if we want smp on panic kernel */ + /* cpu_irq_down to isolate us until we are ready */ +} + +int machine_kexec_prepare(struct kimage *image) { int i; unsigned long begin, end; /* limits of segment */ @@ -97,6 +111,11 @@ int default_machine_kexec_prepare(struct kimage *image) return 0; } +void machine_kexec_cleanup(struct kimage *image) +{ + /* we do nothing in prepare that needs to be undone */ +} + #define IND_FLAGS (IND_DESTINATION | IND_INDIRECTION | IND_DONE | IND_SOURCE) static void copy_segments(unsigned long ind) @@ -153,8 +172,9 @@ void kexec_copy_flush(struct kimage *image) * including ones that were in place on the original copy */ for (i = 0; i < nr_segments; i++) - flush_icache_range((unsigned long)__va(ranges[i].mem), - (unsigned long)__va(ranges[i].mem + ranges[i].memsz)); + flush_icache_range(ranges[i].mem + KERNELBASE, + ranges[i].mem + KERNELBASE + + ranges[i].memsz); } #ifdef CONFIG_SMP @@ -263,20 +283,13 @@ extern NORET_TYPE void kexec_sequence(void *newstack, unsigned long start, void (*clear_all)(void)) ATTRIB_NORET; /* too late to fail here */ -void default_machine_kexec(struct kimage *image) +void machine_kexec(struct kimage *image) { + /* prepare control code if any */ - /* - * If the kexec boot is the normal one, need to shutdown other cpus - * into our wait loop and quiesce interrupts. - * Otherwise, in the case of crashed mode (crashing_cpu >= 0), - * stopping other CPUs and collecting their pt_regs is done before - * using debugger IPI. - */ - - if (crashing_cpu == -1) - kexec_prepare_cpus(); + /* shutdown other cpus into our wait loop and quiesce interrupts */ + kexec_prepare_cpus(); /* switch to a staticly allocated stack. Based on irq stack code. * XXX: the task struct will likely be invalid once we do the copy! diff --git a/trunk/arch/powerpc/kernel/misc_32.S b/trunk/arch/powerpc/kernel/misc_32.S index 01d0d97a16e1..624a983a9676 100644 --- a/trunk/arch/powerpc/kernel/misc_32.S +++ b/trunk/arch/powerpc/kernel/misc_32.S @@ -5,10 +5,6 @@ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) * and Paul Mackerras. * - * kexec bits: - * Copyright (C) 2002-2003 Eric Biederman - * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz - * * 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 @@ -28,8 +24,6 @@ #include #include #include -#include -#include .text @@ -1012,110 +1006,3 @@ _GLOBAL(execve) */ _GLOBAL(__main) blr - -#ifdef CONFIG_KEXEC - /* - * Must be relocatable PIC code callable as a C function. - */ - .globl relocate_new_kernel -relocate_new_kernel: - /* r3 = page_list */ - /* r4 = reboot_code_buffer */ - /* r5 = start_address */ - - li r0, 0 - - /* - * Set Machine Status Register to a known status, - * switch the MMU off and jump to 1: in a single step. - */ - - mr r8, r0 - ori r8, r8, MSR_RI|MSR_ME - mtspr SPRN_SRR1, r8 - addi r8, r4, 1f - relocate_new_kernel - mtspr SPRN_SRR0, r8 - sync - rfi - -1: - /* from this point address translation is turned off */ - /* and interrupts are disabled */ - - /* set a new stack at the bottom of our page... */ - /* (not really needed now) */ - addi r1, r4, KEXEC_CONTROL_CODE_SIZE - 8 /* for LR Save+Back Chain */ - stw r0, 0(r1) - - /* Do the copies */ - li r6, 0 /* checksum */ - mr r0, r3 - b 1f - -0: /* top, read another word for the indirection page */ - lwzu r0, 4(r3) - -1: - /* is it a destination page? (r8) */ - rlwinm. r7, r0, 0, 31, 31 /* IND_DESTINATION (1<<0) */ - beq 2f - - rlwinm r8, r0, 0, 0, 19 /* clear kexec flags, page align */ - b 0b - -2: /* is it an indirection page? (r3) */ - rlwinm. r7, r0, 0, 30, 30 /* IND_INDIRECTION (1<<1) */ - beq 2f - - rlwinm r3, r0, 0, 0, 19 /* clear kexec flags, page align */ - subi r3, r3, 4 - b 0b - -2: /* are we done? */ - rlwinm. r7, r0, 0, 29, 29 /* IND_DONE (1<<2) */ - beq 2f - b 3f - -2: /* is it a source page? (r9) */ - rlwinm. r7, r0, 0, 28, 28 /* IND_SOURCE (1<<3) */ - beq 0b - - rlwinm r9, r0, 0, 0, 19 /* clear kexec flags, page align */ - - li r7, PAGE_SIZE / 4 - mtctr r7 - subi r9, r9, 4 - subi r8, r8, 4 -9: - lwzu r0, 4(r9) /* do the copy */ - xor r6, r6, r0 - stwu r0, 4(r8) - dcbst 0, r8 - sync - icbi 0, r8 - bdnz 9b - - addi r9, r9, 4 - addi r8, r8, 4 - b 0b - -3: - - /* To be certain of avoiding problems with self-modifying code - * execute a serializing instruction here. - */ - isync - sync - - /* jump to the entry point, usually the setup routine */ - mtlr r5 - blrl - -1: b 1b - -relocate_new_kernel_end: - - .globl relocate_new_kernel_size -relocate_new_kernel_size: - .long relocate_new_kernel_end - relocate_new_kernel -#endif diff --git a/trunk/arch/powerpc/kernel/nvram_64.c b/trunk/arch/powerpc/kernel/nvram_64.c index fd7db8d542db..c0fcd29918ce 100644 --- a/trunk/arch/powerpc/kernel/nvram_64.c +++ b/trunk/arch/powerpc/kernel/nvram_64.c @@ -80,74 +80,80 @@ static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin) static ssize_t dev_nvram_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - ssize_t ret; - char *tmp = NULL; - ssize_t size; - - ret = -ENODEV; - if (!ppc_md.nvram_size) - goto out; + ssize_t len; + char *tmp_buffer; + int size; - ret = 0; + if (ppc_md.nvram_size == NULL) + return -ENODEV; size = ppc_md.nvram_size(); - if (*ppos >= size || size < 0) - goto out; - count = min_t(size_t, count, size - *ppos); - count = min(count, PAGE_SIZE); + if (!access_ok(VERIFY_WRITE, buf, count)) + return -EFAULT; + if (*ppos >= size) + return 0; + if (count > size) + count = size; - ret = -ENOMEM; - tmp = kmalloc(count, GFP_KERNEL); - if (!tmp) - goto out; + tmp_buffer = (char *) kmalloc(count, GFP_KERNEL); + if (!tmp_buffer) { + printk(KERN_ERR "dev_read_nvram: kmalloc failed\n"); + return -ENOMEM; + } - ret = ppc_md.nvram_read(tmp, count, ppos); - if (ret <= 0) - goto out; + len = ppc_md.nvram_read(tmp_buffer, count, ppos); + if ((long)len <= 0) { + kfree(tmp_buffer); + return len; + } - if (copy_to_user(buf, tmp, ret)) - ret = -EFAULT; + if (copy_to_user(buf, tmp_buffer, len)) { + kfree(tmp_buffer); + return -EFAULT; + } -out: - kfree(tmp); - return ret; + kfree(tmp_buffer); + return len; } static ssize_t dev_nvram_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) + size_t count, loff_t *ppos) { - ssize_t ret; - char *tmp = NULL; - ssize_t size; - - ret = -ENODEV; - if (!ppc_md.nvram_size) - goto out; + ssize_t len; + char * tmp_buffer; + int size; - ret = 0; + if (ppc_md.nvram_size == NULL) + return -ENODEV; size = ppc_md.nvram_size(); - if (*ppos >= size || size < 0) - goto out; - count = min_t(size_t, count, size - *ppos); - count = min(count, PAGE_SIZE); - - ret = -ENOMEM; - tmp = kmalloc(count, GFP_KERNEL); - if (!tmp) - goto out; - - ret = -EFAULT; - if (copy_from_user(tmp, buf, count)) - goto out; + if (!access_ok(VERIFY_READ, buf, count)) + return -EFAULT; + if (*ppos >= size) + return 0; + if (count > size) + count = size; - ret = ppc_md.nvram_write(tmp, count, ppos); + tmp_buffer = (char *) kmalloc(count, GFP_KERNEL); + if (!tmp_buffer) { + printk(KERN_ERR "dev_nvram_write: kmalloc failed\n"); + return -ENOMEM; + } + + if (copy_from_user(tmp_buffer, buf, count)) { + kfree(tmp_buffer); + return -EFAULT; + } -out: - kfree(tmp); - return ret; + len = ppc_md.nvram_write(tmp_buffer, count, ppos); + if ((long)len <= 0) { + kfree(tmp_buffer); + return len; + } + kfree(tmp_buffer); + return len; } static int dev_nvram_ioctl(struct inode *inode, struct file *file, diff --git a/trunk/arch/powerpc/kernel/paca.c b/trunk/arch/powerpc/kernel/paca.c index 999bdd816769..a7b68f911eb1 100644 --- a/trunk/arch/powerpc/kernel/paca.c +++ b/trunk/arch/powerpc/kernel/paca.c @@ -17,7 +17,6 @@ #include #include #include -#include #include @@ -27,7 +26,8 @@ extern unsigned long __toc_start; /* The Paca is an array with one entry per processor. Each contains an * lppaca, which contains the information shared between the - * hypervisor and Linux. + * hypervisor and Linux. Each also contains an ItLpRegSave area which + * is used by the hypervisor to save registers. * On systems with hardware multi-threading, there are two threads * per processor. The Paca array must contain an entry for each thread. * The VPD Areas will give a max logical processors = 2 * max physical @@ -37,6 +37,7 @@ extern unsigned long __toc_start; #define PACA_INIT_COMMON(number, start, asrr, asrv) \ .lock_token = 0x8000, \ .paca_index = (number), /* Paca Index */ \ + .default_decr = 0x00ff0000, /* Initial Decr */ \ .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ .stab_real = (asrr), /* Real pointer to segment table */ \ .stab_addr = (asrv), /* Virt pointer to segment table */ \ @@ -56,7 +57,11 @@ extern unsigned long __toc_start; #ifdef CONFIG_PPC_ISERIES #define PACA_INIT_ISERIES(number) \ .lppaca_ptr = &paca[number].lppaca, \ - .reg_save_ptr = &iseries_reg_save[number], + .reg_save_ptr = &paca[number].reg_save, \ + .reg_save = { \ + .xDesc = 0xd397d9e2, /* "LpRS" */ \ + .xSize = sizeof(struct ItLpRegSave) \ + } #define PACA_INIT(number) \ { \ diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index fc60a773af7d..8b6008ab217d 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -34,7 +34,7 @@ #ifdef DEBUG #include -#define DBG(fmt...) printk(fmt) +#define DBG(fmt...) udbg_printf(fmt) #else #define DBG(fmt...) #endif @@ -251,7 +251,7 @@ void pcibios_free_controller(struct pci_controller *phb) kfree(phb); } -void __devinit pcibios_claim_one_bus(struct pci_bus *b) +static void __init pcibios_claim_one_bus(struct pci_bus *b) { struct pci_dev *dev; struct pci_bus *child_bus; @@ -323,7 +323,6 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) addrs = (u32 *) get_property(node, "assigned-addresses", &proplen); if (!addrs) return; - DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs); for (; proplen >= 20; proplen -= 20, addrs += 5) { flags = pci_parse_of_flags(addrs[0]); if (!flags) @@ -333,9 +332,6 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev) if (!size) continue; i = addrs[0] & 0xff; - DBG(" base: %llx, size: %llx, i: %x\n", - (unsigned long long)base, (unsigned long long)size, i); - if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; } else if (i == dev->rom_base_reg) { @@ -366,8 +362,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, if (type == NULL) type = ""; - DBG(" create device, devfn: %x, type: %s\n", devfn, type); - memset(dev, 0, sizeof(struct pci_dev)); dev->bus = bus; dev->sysdata = node; @@ -387,8 +381,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); dev->class = get_int_prop(node, "class-code", 0); - DBG(" class: 0x%x\n", dev->class); - dev->current_state = 4; /* unknown power state */ if (!strcmp(type, "pci")) { @@ -410,8 +402,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, pci_parse_of_addrs(node, dev); - DBG(" adding to system ...\n"); - pci_device_add(dev, bus); /* XXX pci_scan_msi_device(dev); */ @@ -428,21 +418,15 @@ void __devinit of_scan_bus(struct device_node *node, int reglen, devfn; struct pci_dev *dev; - DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number); - while ((child = of_get_next_child(node, child)) != NULL) { - DBG(" * %s\n", child->full_name); reg = (u32 *) get_property(child, "reg", ®len); if (reg == NULL || reglen < 20) continue; devfn = (reg[0] >> 8) & 0xff; - /* create a new pci_dev for this device */ dev = of_create_pci_dev(child, bus, devfn); if (!dev) continue; - DBG("dev header type: %x\n", dev->hdr_type); - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) of_scan_pci_bridge(child, dev); @@ -462,18 +446,16 @@ void __devinit of_scan_pci_bridge(struct device_node *node, unsigned int flags; u64 size; - DBG("of_scan_pci_bridge(%s)\n", node->full_name); - /* parse bus-range property */ busrange = (u32 *) get_property(node, "bus-range", &len); if (busrange == NULL || len != 8) { - printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n", + printk(KERN_ERR "Can't get bus-range for PCI-PCI bridge %s\n", node->full_name); return; } ranges = (u32 *) get_property(node, "ranges", &len); if (ranges == NULL) { - printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", + printk(KERN_ERR "Can't get ranges for PCI-PCI bridge %s\n", node->full_name); return; } @@ -527,13 +509,10 @@ void __devinit of_scan_pci_bridge(struct device_node *node, } sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), bus->number); - DBG(" bus name: %s\n", bus->name); mode = PCI_PROBE_NORMAL; if (ppc_md.pci_probe_mode) mode = ppc_md.pci_probe_mode(bus); - DBG(" probe mode: %d\n", mode); - if (mode == PCI_PROBE_DEVTREE) of_scan_bus(node, bus); else if (mode == PCI_PROBE_NORMAL) @@ -549,8 +528,6 @@ void __devinit scan_phb(struct pci_controller *hose) int i, mode; struct resource *res; - DBG("Scanning PHB %s\n", node ? node->full_name : ""); - bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node); if (bus == NULL) { printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", @@ -575,9 +552,8 @@ void __devinit scan_phb(struct pci_controller *hose) mode = PCI_PROBE_NORMAL; #ifdef CONFIG_PPC_MULTIPLATFORM - if (node && ppc_md.pci_probe_mode) + if (ppc_md.pci_probe_mode) mode = ppc_md.pci_probe_mode(bus); - DBG(" probe mode: %d\n", mode); if (mode == PCI_PROBE_DEVTREE) { bus->subordinate = hose->last_busno; of_scan_bus(node, bus); @@ -866,7 +842,8 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, * Returns a negative error code on failure, zero on success. */ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine) + enum pci_mmap_state mmap_state, + int write_combine) { unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; struct resource *rp; @@ -919,25 +896,6 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node, unsigned long phb_io_base_phys, void __iomem * phb_io_base_virt) { - /* Remove these asap */ - - struct pci_address { - u32 a_hi; - u32 a_mid; - u32 a_lo; - }; - - struct isa_address { - u32 a_hi; - u32 a_lo; - }; - - struct isa_range { - struct isa_address isa_addr; - struct pci_address pci_addr; - unsigned int size; - }; - struct isa_range *range; unsigned long pci_addr; unsigned int isa_addr; @@ -1265,7 +1223,6 @@ void __devinit pcibios_fixup_device_resources(struct pci_dev *dev, } EXPORT_SYMBOL(pcibios_fixup_device_resources); - static void __devinit do_bus_setup(struct pci_bus *bus) { struct pci_dev *dev; @@ -1349,38 +1306,8 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, *end = rsrc->end + offset; } -struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) -{ - if (!have_of) - return NULL; - while(node) { - struct pci_controller *hose, *tmp; - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) - if (hose->arch_data == node) - return hose; - node = node->parent; - } - return NULL; -} - #endif /* CONFIG_PPC_MULTIPLATFORM */ -unsigned long pci_address_to_pio(phys_addr_t address) -{ - struct pci_controller *hose, *tmp; - - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { - if (address >= hose->io_base_phys && - address < (hose->io_base_phys + hose->pci_io_size)) { - unsigned long base = - (unsigned long)hose->io_base_virt - pci_io_base; - return base + (address - hose->io_base_phys); - } - } - return (unsigned int)-1; -} -EXPORT_SYMBOL_GPL(pci_address_to_pio); - #define IOBASE_BRIDGE_NUMBER 0 #define IOBASE_MEMORY 1 diff --git a/trunk/arch/powerpc/kernel/pmc.c b/trunk/arch/powerpc/kernel/pmc.c index e6fb194fe537..2d333cc84082 100644 --- a/trunk/arch/powerpc/kernel/pmc.c +++ b/trunk/arch/powerpc/kernel/pmc.c @@ -43,13 +43,8 @@ static void dummy_perf(struct pt_regs *regs) mtspr(SPRN_MMCR0, mmcr0); } #else -/* Ensure exceptions are disabled */ static void dummy_perf(struct pt_regs *regs) { - unsigned int mmcr0 = mfspr(SPRN_MMCR0); - - mmcr0 &= ~(MMCR0_PMXE); - mtspr(SPRN_MMCR0, mmcr0); } #endif diff --git a/trunk/arch/powerpc/kernel/ppc_ksyms.c b/trunk/arch/powerpc/kernel/ppc_ksyms.c index b2758148a0de..94db25708456 100644 --- a/trunk/arch/powerpc/kernel/ppc_ksyms.c +++ b/trunk/arch/powerpc/kernel/ppc_ksyms.c @@ -76,6 +76,11 @@ EXPORT_SYMBOL(single_step_exception); EXPORT_SYMBOL(sys_sigreturn); #endif +#if defined(CONFIG_PPC_PREP) +EXPORT_SYMBOL(_prep_type); +EXPORT_SYMBOL(ucSystemType); +#endif + EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strncpy); EXPORT_SYMBOL(strcat); diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index 977ee3adaf2d..3bf968e74095 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -38,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -57,6 +55,21 @@ #define DBG(fmt...) #endif +struct pci_reg_property { + struct pci_address addr; + u32 size_hi; + u32 size_lo; +}; + +struct isa_reg_property { + u32 space; + u32 address; + u32 size; +}; + + +typedef int interpret_func(struct device_node *, unsigned long *, + int, int, int); static int __initdata dt_root_addr_cells; static int __initdata dt_root_size_cells; @@ -298,16 +311,6 @@ static int __devinit finish_node_interrupts(struct device_node *np, int i, j, n, sense; unsigned int *irq, virq; struct device_node *ic; - int trace = 0; - - //#define TRACE(fmt...) do { if (trace) { printk(fmt); mdelay(1000); } } while(0) -#define TRACE(fmt...) - - if (!strcmp(np->name, "smu-doorbell")) - trace = 1; - - TRACE("Finishing SMU doorbell ! num_interrupt_controllers = %d\n", - num_interrupt_controllers); if (num_interrupt_controllers == 0) { /* @@ -342,12 +345,11 @@ static int __devinit finish_node_interrupts(struct device_node *np, } ints = (unsigned int *) get_property(np, "interrupts", &intlen); - TRACE("ints=%p, intlen=%d\n", ints, intlen); if (ints == NULL) return 0; intrcells = prom_n_intr_cells(np); intlen /= intrcells * sizeof(unsigned int); - TRACE("intrcells=%d, new intlen=%d\n", intrcells, intlen); + np->intrs = prom_alloc(intlen * sizeof(*(np->intrs)), mem_start); if (!np->intrs) return -ENOMEM; @@ -358,7 +360,6 @@ static int __devinit finish_node_interrupts(struct device_node *np, intrcount = 0; for (i = 0; i < intlen; ++i, ints += intrcells) { n = map_interrupt(&irq, &ic, np, ints, intrcells); - TRACE("map, irq=%d, ic=%p, n=%d\n", irq, ic, n); if (n <= 0) continue; @@ -369,7 +370,6 @@ static int __devinit finish_node_interrupts(struct device_node *np, np->intrs[intrcount].sense = map_isa_senses[sense]; } else { virq = virt_irq_create_mapping(irq[0]); - TRACE("virq=%d\n", virq); #ifdef CONFIG_PPC64 if (virq == NO_IRQ) { printk(KERN_CRIT "Could not allocate interrupt" @@ -379,12 +379,6 @@ static int __devinit finish_node_interrupts(struct device_node *np, #endif np->intrs[intrcount].line = irq_offset_up(virq); sense = (n > 1)? (irq[1] & 3): 1; - - /* Apple uses bits in there in a different way, let's - * only keep the real sense bit on macs - */ - if (_machine == PLATFORM_POWERMAC) - sense &= 0x1; np->intrs[intrcount].sense = map_mpic_senses[sense]; } @@ -394,13 +388,12 @@ static int __devinit finish_node_interrupts(struct device_node *np, char *name = get_property(ic->parent, "name", NULL); if (name && !strcmp(name, "u3")) np->intrs[intrcount].line += 128; - else if (!(name && (!strcmp(name, "mac-io") || - !strcmp(name, "u4")))) + else if (!(name && !strcmp(name, "mac-io"))) /* ignore other cascaded controllers, such as the k2-sata-root */ break; } -#endif /* CONFIG_PPC64 */ +#endif if (n > 2) { printk("hmmm, got %d intr cells for %s:", n, np->full_name); @@ -415,19 +408,234 @@ static int __devinit finish_node_interrupts(struct device_node *np, return 0; } +static int __devinit interpret_pci_props(struct device_node *np, + unsigned long *mem_start, + int naddrc, int nsizec, + int measure_only) +{ + struct address_range *adr; + struct pci_reg_property *pci_addrs; + int i, l, n_addrs; + + pci_addrs = (struct pci_reg_property *) + get_property(np, "assigned-addresses", &l); + if (!pci_addrs) + return 0; + + n_addrs = l / sizeof(*pci_addrs); + + adr = prom_alloc(n_addrs * sizeof(*adr), mem_start); + if (!adr) + return -ENOMEM; + + if (measure_only) + return 0; + + np->addrs = adr; + np->n_addrs = n_addrs; + + for (i = 0; i < n_addrs; i++) { + adr[i].space = pci_addrs[i].addr.a_hi; + adr[i].address = pci_addrs[i].addr.a_lo | + ((u64)pci_addrs[i].addr.a_mid << 32); + adr[i].size = pci_addrs[i].size_lo; + } + + return 0; +} + +static int __init interpret_dbdma_props(struct device_node *np, + unsigned long *mem_start, + int naddrc, int nsizec, + int measure_only) +{ + struct reg_property32 *rp; + struct address_range *adr; + unsigned long base_address; + int i, l; + struct device_node *db; + + base_address = 0; + if (!measure_only) { + for (db = np->parent; db != NULL; db = db->parent) { + if (!strcmp(db->type, "dbdma") && db->n_addrs != 0) { + base_address = db->addrs[0].address; + break; + } + } + } + + rp = (struct reg_property32 *) get_property(np, "reg", &l); + if (rp != 0 && l >= sizeof(struct reg_property32)) { + i = 0; + adr = (struct address_range *) (*mem_start); + while ((l -= sizeof(struct reg_property32)) >= 0) { + if (!measure_only) { + adr[i].space = 2; + adr[i].address = rp[i].address + base_address; + adr[i].size = rp[i].size; + } + ++i; + } + np->addrs = adr; + np->n_addrs = i; + (*mem_start) += i * sizeof(struct address_range); + } + + return 0; +} + +static int __init interpret_macio_props(struct device_node *np, + unsigned long *mem_start, + int naddrc, int nsizec, + int measure_only) +{ + struct reg_property32 *rp; + struct address_range *adr; + unsigned long base_address; + int i, l; + struct device_node *db; + + base_address = 0; + if (!measure_only) { + for (db = np->parent; db != NULL; db = db->parent) { + if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) { + base_address = db->addrs[0].address; + break; + } + } + } + + rp = (struct reg_property32 *) get_property(np, "reg", &l); + if (rp != 0 && l >= sizeof(struct reg_property32)) { + i = 0; + adr = (struct address_range *) (*mem_start); + while ((l -= sizeof(struct reg_property32)) >= 0) { + if (!measure_only) { + adr[i].space = 2; + adr[i].address = rp[i].address + base_address; + adr[i].size = rp[i].size; + } + ++i; + } + np->addrs = adr; + np->n_addrs = i; + (*mem_start) += i * sizeof(struct address_range); + } + + return 0; +} + +static int __init interpret_isa_props(struct device_node *np, + unsigned long *mem_start, + int naddrc, int nsizec, + int measure_only) +{ + struct isa_reg_property *rp; + struct address_range *adr; + int i, l; + + rp = (struct isa_reg_property *) get_property(np, "reg", &l); + if (rp != 0 && l >= sizeof(struct isa_reg_property)) { + i = 0; + adr = (struct address_range *) (*mem_start); + while ((l -= sizeof(struct isa_reg_property)) >= 0) { + if (!measure_only) { + adr[i].space = rp[i].space; + adr[i].address = rp[i].address; + adr[i].size = rp[i].size; + } + ++i; + } + np->addrs = adr; + np->n_addrs = i; + (*mem_start) += i * sizeof(struct address_range); + } + + return 0; +} + +static int __init interpret_root_props(struct device_node *np, + unsigned long *mem_start, + int naddrc, int nsizec, + int measure_only) +{ + struct address_range *adr; + int i, l; + unsigned int *rp; + int rpsize = (naddrc + nsizec) * sizeof(unsigned int); + + rp = (unsigned int *) get_property(np, "reg", &l); + if (rp != 0 && l >= rpsize) { + i = 0; + adr = (struct address_range *) (*mem_start); + while ((l -= rpsize) >= 0) { + if (!measure_only) { + adr[i].space = 0; + adr[i].address = rp[naddrc - 1]; + adr[i].size = rp[naddrc + nsizec - 1]; + } + ++i; + rp += naddrc + nsizec; + } + np->addrs = adr; + np->n_addrs = i; + (*mem_start) += i * sizeof(struct address_range); + } + + return 0; +} + static int __devinit finish_node(struct device_node *np, unsigned long *mem_start, + interpret_func *ifunc, + int naddrc, int nsizec, int measure_only) { struct device_node *child; - int rc = 0; + int *ip, rc = 0; + + /* get the device addresses and interrupts */ + if (ifunc != NULL) + rc = ifunc(np, mem_start, naddrc, nsizec, measure_only); + if (rc) + goto out; rc = finish_node_interrupts(np, mem_start, measure_only); if (rc) goto out; + /* Look for #address-cells and #size-cells properties. */ + ip = (int *) get_property(np, "#address-cells", NULL); + if (ip != NULL) + naddrc = *ip; + ip = (int *) get_property(np, "#size-cells", NULL); + if (ip != NULL) + nsizec = *ip; + + if (!strcmp(np->name, "device-tree") || np->parent == NULL) + ifunc = interpret_root_props; + else if (np->type == 0) + ifunc = NULL; + else if (!strcmp(np->type, "pci") || !strcmp(np->type, "vci")) + ifunc = interpret_pci_props; + else if (!strcmp(np->type, "dbdma")) + ifunc = interpret_dbdma_props; + else if (!strcmp(np->type, "mac-io") || ifunc == interpret_macio_props) + ifunc = interpret_macio_props; + else if (!strcmp(np->type, "isa")) + ifunc = interpret_isa_props; + else if (!strcmp(np->name, "uni-n") || !strcmp(np->name, "u3")) + ifunc = interpret_root_props; + else if (!((ifunc == interpret_dbdma_props + || ifunc == interpret_macio_props) + && (!strcmp(np->type, "escc") + || !strcmp(np->type, "media-bay")))) + ifunc = NULL; + for (child = np->child; child != NULL; child = child->sibling) { - rc = finish_node(child, mem_start, measure_only); + rc = finish_node(child, mem_start, ifunc, + naddrc, nsizec, measure_only); if (rc) goto out; } @@ -489,10 +697,10 @@ void __init finish_device_tree(void) * reason and then remove those additional 16 bytes */ size = 16; - finish_node(allnodes, &size, 1); + finish_node(allnodes, &size, NULL, 0, 0, 1); size -= 16; end = start = (unsigned long) __va(lmb_alloc(size, 128)); - finish_node(allnodes, &end, 0); + finish_node(allnodes, &end, NULL, 0, 0, 0); BUG_ON(end != start + size); DBG(" <- finish_device_tree\n"); @@ -989,16 +1197,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node, } #endif /* CONFIG_PPC_RTAS */ -#ifdef CONFIG_KEXEC - lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL); - if (lprop) - crashk_res.start = *lprop; - - lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-size", NULL); - if (lprop) - crashk_res.end = crashk_res.start + *lprop - 1; -#endif - /* break now */ return 1; } @@ -1065,9 +1263,7 @@ static int __init early_init_dt_scan_memory(unsigned long node, } else if (strcmp(type, "memory") != 0) return 0; - reg = (cell_t *)of_get_flat_dt_prop(node, "linux,usable-memory", &l); - if (reg == NULL) - reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l); + reg = (cell_t *)of_get_flat_dt_prop(node, "reg", &l); if (reg == NULL) return 0; @@ -1139,14 +1335,11 @@ void __init early_init_devtree(void *params) of_scan_flat_dt(early_init_dt_scan_memory, NULL); lmb_enforce_memory_limit(memory_limit); lmb_analyze(); + lmb_reserve(0, __pa(klimit)); DBG("Phys. mem: %lx\n", lmb_phys_mem_size()); /* Reserve LMB regions used by kernel, initrd, dt, etc... */ - lmb_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START); -#ifdef CONFIG_CRASH_DUMP - lmb_reserve(0, KDUMP_RESERVE_LIMIT); -#endif early_reserve_mem(); DBG("Scanning CPUs ...\n"); @@ -1609,6 +1802,7 @@ static void of_node_release(struct kref *kref) prop = next; } kfree(node->intrs); + kfree(node->addrs); kfree(node->full_name); kfree(node->data); kfree(node); @@ -1690,7 +1884,9 @@ void of_detach_node(const struct device_node *np) * This should probably be split up into smaller chunks. */ -static int of_finish_dynamic_node(struct device_node *node) +static int of_finish_dynamic_node(struct device_node *node, + unsigned long *unused1, int unused2, + int unused3, int unused4) { struct device_node *parent = of_get_parent(node); int err = 0; @@ -1711,8 +1907,7 @@ static int of_finish_dynamic_node(struct device_node *node) return -ENODEV; /* fix up new node's linux_phandle field */ - if ((ibm_phandle = (unsigned int *)get_property(node, - "ibm,phandle", NULL))) + if ((ibm_phandle = (unsigned int *)get_property(node, "ibm,phandle", NULL))) node->linux_phandle = *ibm_phandle; out: @@ -1727,9 +1922,7 @@ static int prom_reconfig_notifier(struct notifier_block *nb, switch (action) { case PSERIES_RECONFIG_ADD: - err = of_finish_dynamic_node(node); - if (!err) - finish_node(node, NULL, 0); + err = finish_node(node, NULL, of_finish_dynamic_node, 0, 0, 0); if (err < 0) { printk(KERN_ERR "finish_node returned %d\n", err); err = NOTIFY_BAD; @@ -1803,4 +1996,175 @@ int prom_add_property(struct device_node* np, struct property* prop) return 0; } +/* I quickly hacked that one, check against spec ! */ +static inline unsigned long +bus_space_to_resource_flags(unsigned int bus_space) +{ + u8 space = (bus_space >> 24) & 0xf; + if (space == 0) + space = 0x02; + if (space == 0x02) + return IORESOURCE_MEM; + else if (space == 0x01) + return IORESOURCE_IO; + else { + printk(KERN_WARNING "prom.c: bus_space_to_resource_flags(), space: %x\n", + bus_space); + return 0; + } +} + +#ifdef CONFIG_PCI +static struct resource *find_parent_pci_resource(struct pci_dev* pdev, + struct address_range *range) +{ + unsigned long mask; + int i; + + /* Check this one */ + mask = bus_space_to_resource_flags(range->space); + for (i=0; iresource[i].flags & mask) == mask && + pdev->resource[i].start <= range->address && + pdev->resource[i].end > range->address) { + if ((range->address + range->size - 1) > pdev->resource[i].end) { + /* Add better message */ + printk(KERN_WARNING "PCI/OF resource overlap !\n"); + return NULL; + } + break; + } + } + if (i == DEVICE_COUNT_RESOURCE) + return NULL; + return &pdev->resource[i]; +} + +/* + * Request an OF device resource. Currently handles child of PCI devices, + * or other nodes attached to the root node. Ultimately, put some + * link to resources in the OF node. + */ +struct resource *request_OF_resource(struct device_node* node, int index, + const char* name_postfix) +{ + struct pci_dev* pcidev; + u8 pci_bus, pci_devfn; + unsigned long iomask; + struct device_node* nd; + struct resource* parent; + struct resource *res = NULL; + int nlen, plen; + + if (index >= node->n_addrs) + goto fail; + + /* Sanity check on bus space */ + iomask = bus_space_to_resource_flags(node->addrs[index].space); + if (iomask & IORESOURCE_MEM) + parent = &iomem_resource; + else if (iomask & IORESOURCE_IO) + parent = &ioport_resource; + else + goto fail; + + /* Find a PCI parent if any */ + nd = node; + pcidev = NULL; + while (nd) { + if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) + pcidev = pci_find_slot(pci_bus, pci_devfn); + if (pcidev) break; + nd = nd->parent; + } + if (pcidev) + parent = find_parent_pci_resource(pcidev, &node->addrs[index]); + if (!parent) { + printk(KERN_WARNING "request_OF_resource(%s), parent not found\n", + node->name); + goto fail; + } + res = __request_region(parent, node->addrs[index].address, + node->addrs[index].size, NULL); + if (!res) + goto fail; + nlen = strlen(node->name); + plen = name_postfix ? strlen(name_postfix) : 0; + res->name = (const char *)kmalloc(nlen+plen+1, GFP_KERNEL); + if (res->name) { + strcpy((char *)res->name, node->name); + if (plen) + strcpy((char *)res->name+nlen, name_postfix); + } + return res; +fail: + return NULL; +} +EXPORT_SYMBOL(request_OF_resource); + +int release_OF_resource(struct device_node *node, int index) +{ + struct pci_dev* pcidev; + u8 pci_bus, pci_devfn; + unsigned long iomask, start, end; + struct device_node* nd; + struct resource* parent; + struct resource *res = NULL; + + if (index >= node->n_addrs) + return -EINVAL; + + /* Sanity check on bus space */ + iomask = bus_space_to_resource_flags(node->addrs[index].space); + if (iomask & IORESOURCE_MEM) + parent = &iomem_resource; + else if (iomask & IORESOURCE_IO) + parent = &ioport_resource; + else + return -EINVAL; + + /* Find a PCI parent if any */ + nd = node; + pcidev = NULL; + while(nd) { + if (!pci_device_from_OF_node(nd, &pci_bus, &pci_devfn)) + pcidev = pci_find_slot(pci_bus, pci_devfn); + if (pcidev) break; + nd = nd->parent; + } + if (pcidev) + parent = find_parent_pci_resource(pcidev, &node->addrs[index]); + if (!parent) { + printk(KERN_WARNING "release_OF_resource(%s), parent not found\n", + node->name); + return -ENODEV; + } + + /* Find us in the parent and its childs */ + res = parent->child; + start = node->addrs[index].address; + end = start + node->addrs[index].size - 1; + while (res) { + if (res->start == start && res->end == end && + (res->flags & IORESOURCE_BUSY)) + break; + if (res->start <= start && res->end >= end) + res = res->child; + else + res = res->sibling; + } + if (!res) + return -ENODEV; + + if (res->name) { + kfree(res->name); + res->name = NULL; + } + release_resource(res); + kfree(res); + + return 0; +} +EXPORT_SYMBOL(release_OF_resource); +#endif /* CONFIG_PCI */ diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index e381f2fc121c..bcdc209dca85 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -192,11 +192,6 @@ static unsigned long __initdata alloc_bottom; static unsigned long __initdata rmo_top; static unsigned long __initdata ram_top; -#ifdef CONFIG_KEXEC -static unsigned long __initdata prom_crashk_base; -static unsigned long __initdata prom_crashk_size; -#endif - static struct mem_map_entry __initdata mem_reserve_map[MEM_RESERVE_MAP_SIZE]; static int __initdata mem_reserve_cnt; @@ -558,8 +553,7 @@ unsigned long prom_memparse(const char *ptr, const char **retptr) static void __init early_cmdline_parse(void) { struct prom_t *_prom = &RELOC(prom); - const char *opt; - char *p; + char *opt, *p; int l = 0; RELOC(prom_cmd_line[0]) = 0; @@ -596,34 +590,6 @@ static void __init early_cmdline_parse(void) RELOC(prom_memory_limit) = ALIGN(RELOC(prom_memory_limit), 0x1000000); #endif } - -#ifdef CONFIG_KEXEC - /* - * crashkernel=size@addr specifies the location to reserve for - * crash kernel. - */ - opt = strstr(RELOC(prom_cmd_line), RELOC("crashkernel=")); - if (opt) { - opt += 12; - RELOC(prom_crashk_size) = prom_memparse(opt, &opt); - - if (ALIGN(RELOC(prom_crashk_size), 0x1000000) != - RELOC(prom_crashk_size)) { - prom_printf("Warning: crashkernel size is not " - "aligned to 16MB\n"); - } - - /* - * At present, the crash kernel always run at 32MB. - * Just ignore whatever user passed. - */ - RELOC(prom_crashk_base) = 0x2000000; - if (*opt == '@') { - prom_printf("Warning: PPC64 kdump kernel always runs " - "at 32 MB\n"); - } - } -#endif } #ifdef CONFIG_PPC_PSERIES @@ -1045,12 +1011,6 @@ static void __init prom_init_mem(void) prom_printf(" alloc_top_hi : %x\n", RELOC(alloc_top_high)); prom_printf(" rmo_top : %x\n", RELOC(rmo_top)); prom_printf(" ram_top : %x\n", RELOC(ram_top)); -#ifdef CONFIG_KEXEC - if (RELOC(prom_crashk_base)) { - prom_printf(" crashk_base : %x\n", RELOC(prom_crashk_base)); - prom_printf(" crashk_size : %x\n", RELOC(prom_crashk_size)); - } -#endif } @@ -1540,8 +1500,6 @@ static int __init prom_find_machine_type(void) #ifdef CONFIG_PPC64 if (strstr(p, RELOC("Momentum,Maple"))) return PLATFORM_MAPLE; - if (strstr(p, RELOC("IBM,CPB"))) - return PLATFORM_CELL; #endif i += sl + 1; } @@ -2036,7 +1994,7 @@ static void __init prom_check_initrd(unsigned long r3, unsigned long r4) if (r3 && r4 && r4 != 0xdeadbeef) { unsigned long val; - RELOC(prom_initrd_start) = is_kernel_addr(r3) ? __pa(r3) : r3; + RELOC(prom_initrd_start) = (r3 >= KERNELBASE) ? __pa(r3) : r3; RELOC(prom_initrd_end) = RELOC(prom_initrd_start) + r4; val = RELOC(prom_initrd_start); @@ -2136,10 +2094,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, */ prom_init_mem(); -#ifdef CONFIG_KEXEC - if (RELOC(prom_crashk_base)) - reserve_mem(RELOC(prom_crashk_base), RELOC(prom_crashk_size)); -#endif /* * Determine which cpu is actually running right _now_ */ @@ -2196,16 +2150,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, } #endif -#ifdef CONFIG_KEXEC - if (RELOC(prom_crashk_base)) { - prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-base", - PTRRELOC(&prom_crashk_base), - sizeof(RELOC(prom_crashk_base))); - prom_setprop(_prom->chosen, "/chosen", "linux,crashkernel-size", - PTRRELOC(&prom_crashk_size), - sizeof(RELOC(prom_crashk_size))); - } -#endif /* * Fixup any known bugs in the device-tree */ diff --git a/trunk/arch/powerpc/kernel/prom_parse.c b/trunk/arch/powerpc/kernel/prom_parse.c deleted file mode 100644 index 309ae1d5fa77..000000000000 --- a/trunk/arch/powerpc/kernel/prom_parse.c +++ /dev/null @@ -1,547 +0,0 @@ -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include - -#ifdef DEBUG -#define DBG(fmt...) do { printk(fmt); } while(0) -#else -#define DBG(fmt...) do { } while(0) -#endif - -#ifdef CONFIG_PPC64 -#define PRu64 "%lx" -#else -#define PRu64 "%llx" -#endif - -/* Max address size we deal with */ -#define OF_MAX_ADDR_CELLS 4 -#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ - (ns) > 0) - -/* Debug utility */ -#ifdef DEBUG -static void of_dump_addr(const char *s, u32 *addr, int na) -{ - printk("%s", s); - while(na--) - printk(" %08x", *(addr++)); - printk("\n"); -} -#else -static void of_dump_addr(const char *s, u32 *addr, int na) { } -#endif - -/* Read a big address */ -static inline u64 of_read_addr(u32 *cell, int size) -{ - u64 r = 0; - while (size--) - r = (r << 32) | *(cell++); - return r; -} - -/* Callbacks for bus specific translators */ -struct of_bus { - const char *name; - const char *addresses; - int (*match)(struct device_node *parent); - void (*count_cells)(struct device_node *child, - int *addrc, int *sizec); - u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna); - int (*translate)(u32 *addr, u64 offset, int na); - unsigned int (*get_flags)(u32 *addr); -}; - - -/* - * Default translator (generic bus) - */ - -static void of_bus_default_count_cells(struct device_node *dev, - int *addrc, int *sizec) -{ - if (addrc) - *addrc = prom_n_addr_cells(dev); - if (sizec) - *sizec = prom_n_size_cells(dev); -} - -static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna) -{ - u64 cp, s, da; - - cp = of_read_addr(range, na); - s = of_read_addr(range + na + pna, ns); - da = of_read_addr(addr, na); - - DBG("OF: default map, cp="PRu64", s="PRu64", da="PRu64"\n", - cp, s, da); - - if (da < cp || da >= (cp + s)) - return OF_BAD_ADDR; - return da - cp; -} - -static int of_bus_default_translate(u32 *addr, u64 offset, int na) -{ - u64 a = of_read_addr(addr, na); - memset(addr, 0, na * 4); - a += offset; - if (na > 1) - addr[na - 2] = a >> 32; - addr[na - 1] = a & 0xffffffffu; - - return 0; -} - -static unsigned int of_bus_default_get_flags(u32 *addr) -{ - return IORESOURCE_MEM; -} - - -/* - * PCI bus specific translator - */ - -static int of_bus_pci_match(struct device_node *np) -{ - return !strcmp(np->type, "pci"); -} - -static void of_bus_pci_count_cells(struct device_node *np, - int *addrc, int *sizec) -{ - if (addrc) - *addrc = 3; - if (sizec) - *sizec = 2; -} - -static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna) -{ - u64 cp, s, da; - - /* Check address type match */ - if ((addr[0] ^ range[0]) & 0x03000000) - return OF_BAD_ADDR; - - /* Read address values, skipping high cell */ - cp = of_read_addr(range + 1, na - 1); - s = of_read_addr(range + na + pna, ns); - da = of_read_addr(addr + 1, na - 1); - - DBG("OF: PCI map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); - - if (da < cp || da >= (cp + s)) - return OF_BAD_ADDR; - return da - cp; -} - -static int of_bus_pci_translate(u32 *addr, u64 offset, int na) -{ - return of_bus_default_translate(addr + 1, offset, na - 1); -} - -static unsigned int of_bus_pci_get_flags(u32 *addr) -{ - unsigned int flags = 0; - u32 w = addr[0]; - - switch((w >> 24) & 0x03) { - case 0x01: - flags |= IORESOURCE_IO; - case 0x02: /* 32 bits */ - case 0x03: /* 64 bits */ - flags |= IORESOURCE_MEM; - } - if (w & 0x40000000) - flags |= IORESOURCE_PREFETCH; - return flags; -} - -/* - * ISA bus specific translator - */ - -static int of_bus_isa_match(struct device_node *np) -{ - return !strcmp(np->name, "isa"); -} - -static void of_bus_isa_count_cells(struct device_node *child, - int *addrc, int *sizec) -{ - if (addrc) - *addrc = 2; - if (sizec) - *sizec = 1; -} - -static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna) -{ - u64 cp, s, da; - - /* Check address type match */ - if ((addr[0] ^ range[0]) & 0x00000001) - return OF_BAD_ADDR; - - /* Read address values, skipping high cell */ - cp = of_read_addr(range + 1, na - 1); - s = of_read_addr(range + na + pna, ns); - da = of_read_addr(addr + 1, na - 1); - - DBG("OF: ISA map, cp="PRu64", s="PRu64", da="PRu64"\n", cp, s, da); - - if (da < cp || da >= (cp + s)) - return OF_BAD_ADDR; - return da - cp; -} - -static int of_bus_isa_translate(u32 *addr, u64 offset, int na) -{ - return of_bus_default_translate(addr + 1, offset, na - 1); -} - -static unsigned int of_bus_isa_get_flags(u32 *addr) -{ - unsigned int flags = 0; - u32 w = addr[0]; - - if (w & 1) - flags |= IORESOURCE_IO; - else - flags |= IORESOURCE_MEM; - return flags; -} - - -/* - * Array of bus specific translators - */ - -static struct of_bus of_busses[] = { - /* PCI */ - { - .name = "pci", - .addresses = "assigned-addresses", - .match = of_bus_pci_match, - .count_cells = of_bus_pci_count_cells, - .map = of_bus_pci_map, - .translate = of_bus_pci_translate, - .get_flags = of_bus_pci_get_flags, - }, - /* ISA */ - { - .name = "isa", - .addresses = "reg", - .match = of_bus_isa_match, - .count_cells = of_bus_isa_count_cells, - .map = of_bus_isa_map, - .translate = of_bus_isa_translate, - .get_flags = of_bus_isa_get_flags, - }, - /* Default */ - { - .name = "default", - .addresses = "reg", - .match = NULL, - .count_cells = of_bus_default_count_cells, - .map = of_bus_default_map, - .translate = of_bus_default_translate, - .get_flags = of_bus_default_get_flags, - }, -}; - -static struct of_bus *of_match_bus(struct device_node *np) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(of_busses); i ++) - if (!of_busses[i].match || of_busses[i].match(np)) - return &of_busses[i]; - BUG(); - return NULL; -} - -static int of_translate_one(struct device_node *parent, struct of_bus *bus, - struct of_bus *pbus, u32 *addr, - int na, int ns, int pna) -{ - u32 *ranges; - unsigned int rlen; - int rone; - u64 offset = OF_BAD_ADDR; - - /* Normally, an absence of a "ranges" property means we are - * crossing a non-translatable boundary, and thus the addresses - * below the current not cannot be converted to CPU physical ones. - * Unfortunately, while this is very clear in the spec, it's not - * what Apple understood, and they do have things like /uni-n or - * /ht nodes with no "ranges" property and a lot of perfectly - * useable mapped devices below them. Thus we treat the absence of - * "ranges" as equivalent to an empty "ranges" property which means - * a 1:1 translation at that level. It's up to the caller not to try - * to translate addresses that aren't supposed to be translated in - * the first place. --BenH. - */ - ranges = (u32 *)get_property(parent, "ranges", &rlen); - if (ranges == NULL || rlen == 0) { - offset = of_read_addr(addr, na); - memset(addr, 0, pna * 4); - DBG("OF: no ranges, 1:1 translation\n"); - goto finish; - } - - DBG("OF: walking ranges...\n"); - - /* Now walk through the ranges */ - rlen /= 4; - rone = na + pna + ns; - for (; rlen >= rone; rlen -= rone, ranges += rone) { - offset = bus->map(addr, ranges, na, ns, pna); - if (offset != OF_BAD_ADDR) - break; - } - if (offset == OF_BAD_ADDR) { - DBG("OF: not found !\n"); - return 1; - } - memcpy(addr, ranges + na, 4 * pna); - - finish: - of_dump_addr("OF: parent translation for:", addr, pna); - DBG("OF: with offset: "PRu64"\n", offset); - - /* Translate it into parent bus space */ - return pbus->translate(addr, offset, pna); -} - - -/* - * Translate an address from the device-tree into a CPU physical address, - * this walks up the tree and applies the various bus mappings on the - * way. - * - * Note: We consider that crossing any level with #size-cells == 0 to mean - * that translation is impossible (that is we are not dealing with a value - * that can be mapped to a cpu physical address). This is not really specified - * that way, but this is traditionally the way IBM at least do things - */ -u64 of_translate_address(struct device_node *dev, u32 *in_addr) -{ - struct device_node *parent = NULL; - struct of_bus *bus, *pbus; - u32 addr[OF_MAX_ADDR_CELLS]; - int na, ns, pna, pns; - u64 result = OF_BAD_ADDR; - - DBG("OF: ** translation for device %s **\n", dev->full_name); - - /* Increase refcount at current level */ - of_node_get(dev); - - /* Get parent & match bus type */ - parent = of_get_parent(dev); - if (parent == NULL) - goto bail; - bus = of_match_bus(parent); - - /* Cound address cells & copy address locally */ - bus->count_cells(dev, &na, &ns); - if (!OF_CHECK_COUNTS(na, ns)) { - printk(KERN_ERR "prom_parse: Bad cell count for %s\n", - dev->full_name); - goto bail; - } - memcpy(addr, in_addr, na * 4); - - DBG("OF: bus is %s (na=%d, ns=%d) on %s\n", - bus->name, na, ns, parent->full_name); - of_dump_addr("OF: translating address:", addr, na); - - /* Translate */ - for (;;) { - /* Switch to parent bus */ - of_node_put(dev); - dev = parent; - parent = of_get_parent(dev); - - /* If root, we have finished */ - if (parent == NULL) { - DBG("OF: reached root node\n"); - result = of_read_addr(addr, na); - break; - } - - /* Get new parent bus and counts */ - pbus = of_match_bus(parent); - pbus->count_cells(dev, &pna, &pns); - if (!OF_CHECK_COUNTS(pna, pns)) { - printk(KERN_ERR "prom_parse: Bad cell count for %s\n", - dev->full_name); - break; - } - - DBG("OF: parent bus is %s (na=%d, ns=%d) on %s\n", - pbus->name, pna, pns, parent->full_name); - - /* Apply bus translation */ - if (of_translate_one(dev, bus, pbus, addr, na, ns, pna)) - break; - - /* Complete the move up one level */ - na = pna; - ns = pns; - bus = pbus; - - of_dump_addr("OF: one level translation:", addr, na); - } - bail: - of_node_put(parent); - of_node_put(dev); - - return result; -} -EXPORT_SYMBOL(of_translate_address); - -u32 *of_get_address(struct device_node *dev, int index, u64 *size, - unsigned int *flags) -{ - u32 *prop; - unsigned int psize; - struct device_node *parent; - struct of_bus *bus; - int onesize, i, na, ns; - - /* Get parent & match bus type */ - parent = of_get_parent(dev); - if (parent == NULL) - return NULL; - bus = of_match_bus(parent); - bus->count_cells(dev, &na, &ns); - of_node_put(parent); - if (!OF_CHECK_COUNTS(na, ns)) - return NULL; - - /* Get "reg" or "assigned-addresses" property */ - prop = (u32 *)get_property(dev, bus->addresses, &psize); - if (prop == NULL) - return NULL; - psize /= 4; - - onesize = na + ns; - for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) - if (i == index) { - if (size) - *size = of_read_addr(prop + na, ns); - if (flags) - *flags = bus->get_flags(prop); - return prop; - } - return NULL; -} -EXPORT_SYMBOL(of_get_address); - -u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, - unsigned int *flags) -{ - u32 *prop; - unsigned int psize; - struct device_node *parent; - struct of_bus *bus; - int onesize, i, na, ns; - - /* Get parent & match bus type */ - parent = of_get_parent(dev); - if (parent == NULL) - return NULL; - bus = of_match_bus(parent); - if (strcmp(bus->name, "pci")) - return NULL; - bus->count_cells(dev, &na, &ns); - of_node_put(parent); - if (!OF_CHECK_COUNTS(na, ns)) - return NULL; - - /* Get "reg" or "assigned-addresses" property */ - prop = (u32 *)get_property(dev, bus->addresses, &psize); - if (prop == NULL) - return NULL; - psize /= 4; - - onesize = na + ns; - for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++) - if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) { - if (size) - *size = of_read_addr(prop + na, ns); - if (flags) - *flags = bus->get_flags(prop); - return prop; - } - return NULL; -} -EXPORT_SYMBOL(of_get_pci_address); - -static int __of_address_to_resource(struct device_node *dev, u32 *addrp, - u64 size, unsigned int flags, - struct resource *r) -{ - u64 taddr; - - if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0) - return -EINVAL; - taddr = of_translate_address(dev, addrp); - if (taddr == OF_BAD_ADDR) - return -EINVAL; - memset(r, 0, sizeof(struct resource)); - if (flags & IORESOURCE_IO) { - unsigned long port; - port = pci_address_to_pio(taddr); - if (port == (unsigned long)-1) - return -EINVAL; - r->start = port; - r->end = port + size - 1; - } else { - r->start = taddr; - r->end = taddr + size - 1; - } - r->flags = flags; - r->name = dev->name; - return 0; -} - -int of_address_to_resource(struct device_node *dev, int index, - struct resource *r) -{ - u32 *addrp; - u64 size; - unsigned int flags; - - addrp = of_get_address(dev, index, &size, &flags); - if (addrp == NULL) - return -EINVAL; - return __of_address_to_resource(dev, addrp, size, flags, r); -} -EXPORT_SYMBOL_GPL(of_address_to_resource); - -int of_pci_address_to_resource(struct device_node *dev, int bar, - struct resource *r) -{ - u32 *addrp; - u64 size; - unsigned int flags; - - addrp = of_get_pci_address(dev, bar, &size, &flags); - if (addrp == NULL) - return -EINVAL; - return __of_address_to_resource(dev, addrp, size, flags, r); -} -EXPORT_SYMBOL_GPL(of_pci_address_to_resource); diff --git a/trunk/arch/powerpc/kernel/ptrace32.c b/trunk/arch/powerpc/kernel/ptrace32.c index 826ee3d056de..61762640b877 100644 --- a/trunk/arch/powerpc/kernel/ptrace32.c +++ b/trunk/arch/powerpc/kernel/ptrace32.c @@ -45,19 +45,33 @@ long compat_sys_ptrace(int request, int pid, unsigned long addr, unsigned long data) { struct task_struct *child; - int ret; + int ret = -EPERM; lock_kernel(); if (request == PTRACE_TRACEME) { - ret = ptrace_traceme(); + /* are we already being traced? */ + if (current->ptrace & PT_PTRACED) + goto out; + ret = security_ptrace(current->parent, current); + if (ret) + goto out; + /* set the ptrace bit in the process flags. */ + current->ptrace |= PT_PTRACED; + ret = 0; goto out; } - - child = ptrace_get_task_struct(pid); - if (IS_ERR(child)) { - ret = PTR_ERR(child); + ret = -ESRCH; + read_lock(&tasklist_lock); + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); + if (!child) goto out; - } + + ret = -EPERM; + if (pid == 1) /* you may not mess with init */ + goto out_tsk; if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); diff --git a/trunk/arch/powerpc/kernel/rtas_pci.c b/trunk/arch/powerpc/kernel/rtas_pci.c index 45b8109951fe..60dec2401c26 100644 --- a/trunk/arch/powerpc/kernel/rtas_pci.c +++ b/trunk/arch/powerpc/kernel/rtas_pci.c @@ -188,19 +188,39 @@ int is_python(struct device_node *dev) return 0; } -static void python_countermeasures(struct device_node *dev) +static int get_phb_reg_prop(struct device_node *dev, + unsigned int addr_size_words, + struct reg_property64 *reg) { - struct resource registers; + unsigned int *ui_ptr = NULL, len; + + /* Found a PHB, now figure out where his registers are mapped. */ + ui_ptr = (unsigned int *)get_property(dev, "reg", &len); + if (ui_ptr == NULL) + return 1; + + if (addr_size_words == 1) { + reg->address = ((struct reg_property32 *)ui_ptr)->address; + reg->size = ((struct reg_property32 *)ui_ptr)->size; + } else { + *reg = *((struct reg_property64 *)ui_ptr); + } + + return 0; +} + +static void python_countermeasures(struct device_node *dev, + unsigned int addr_size_words) +{ + struct reg_property64 reg_struct; void __iomem *chip_regs; volatile u32 val; - if (of_address_to_resource(dev, 0, ®isters)) { - printk(KERN_ERR "Can't get address for Python workarounds !\n"); + if (get_phb_reg_prop(dev, addr_size_words, ®_struct)) return; - } /* Python's register file is 1 MB in size. */ - chip_regs = ioremap(registers.start & ~(0xfffffUL), 0x100000); + chip_regs = ioremap(reg_struct.address & ~(0xfffffUL), 0x100000); /* * Firmware doesn't always clear this bit which is critical @@ -281,10 +301,11 @@ static int phb_set_bus_ranges(struct device_node *dev, } static int __devinit setup_phb(struct device_node *dev, - struct pci_controller *phb) + struct pci_controller *phb, + unsigned int addr_size_words) { if (is_python(dev)) - python_countermeasures(dev); + python_countermeasures(dev, addr_size_words); if (phb_set_bus_ranges(dev, phb)) return 1; @@ -299,8 +320,8 @@ unsigned long __init find_and_init_phbs(void) { struct device_node *node; struct pci_controller *phb; - unsigned int index; unsigned int root_size_cells = 0; + unsigned int index; unsigned int *opprop = NULL; struct device_node *root = of_find_node_by_path("/"); @@ -322,11 +343,10 @@ unsigned long __init find_and_init_phbs(void) phb = pcibios_alloc_controller(node); if (!phb) continue; - setup_phb(node, phb); + setup_phb(node, phb, root_size_cells); pci_process_bridge_OF_ranges(phb, node, 0); pci_setup_phb_io(phb, index == 0); #ifdef CONFIG_PPC_PSERIES - /* XXX This code need serious fixing ... --BenH */ if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) { int addr = root_size_cells * (index + 2) - 1; mpic_assign_isu(pSeries_mpic, index, opprop[addr]); @@ -361,17 +381,22 @@ unsigned long __init find_and_init_phbs(void) struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) { + struct device_node *root = of_find_node_by_path("/"); + unsigned int root_size_cells = 0; struct pci_controller *phb; int primary; + root_size_cells = prom_n_size_cells(root); + primary = list_empty(&hose_list); phb = pcibios_alloc_controller(dn); if (!phb) return NULL; - setup_phb(dn, phb); + setup_phb(dn, phb, root_size_cells); pci_process_bridge_OF_ranges(phb, dn, primary); pci_setup_phb_io_dynamic(phb, primary); + of_node_put(root); pci_devs_phb_init_dynamic(phb); scan_phb(phb); diff --git a/trunk/arch/powerpc/kernel/setup-common.c b/trunk/arch/powerpc/kernel/setup-common.c index d5c52fae023a..bd3eb4292b53 100644 --- a/trunk/arch/powerpc/kernel/setup-common.c +++ b/trunk/arch/powerpc/kernel/setup-common.c @@ -93,8 +93,8 @@ EXPORT_SYMBOL(ppc_do_canonicalize_irqs); /* also used by kexec */ void machine_shutdown(void) { - if (ppc_md.machine_shutdown) - ppc_md.machine_shutdown(); + if (ppc_md.nvram_sync) + ppc_md.nvram_sync(); } void machine_restart(char *cmd) @@ -294,6 +294,129 @@ struct seq_operations cpuinfo_op = { .show = show_cpuinfo, }; +#ifdef CONFIG_PPC_MULTIPLATFORM +static int __init set_preferred_console(void) +{ + struct device_node *prom_stdout = NULL; + char *name; + u32 *spd; + int offset = 0; + + DBG(" -> set_preferred_console()\n"); + + /* The user has requested a console so this is already set up. */ + if (strstr(saved_command_line, "console=")) { + DBG(" console was specified !\n"); + return -EBUSY; + } + + if (!of_chosen) { + DBG(" of_chosen is NULL !\n"); + return -ENODEV; + } + /* We are getting a weird phandle from OF ... */ + /* ... So use the full path instead */ + name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); + if (name == NULL) { + DBG(" no linux,stdout-path !\n"); + return -ENODEV; + } + prom_stdout = of_find_node_by_path(name); + if (!prom_stdout) { + DBG(" can't find stdout package %s !\n", name); + return -ENODEV; + } + DBG("stdout is %s\n", prom_stdout->full_name); + + name = (char *)get_property(prom_stdout, "name", NULL); + if (!name) { + DBG(" stdout package has no name !\n"); + goto not_found; + } + spd = (u32 *)get_property(prom_stdout, "current-speed", NULL); + + if (0) + ; +#ifdef CONFIG_SERIAL_8250_CONSOLE + else if (strcmp(name, "serial") == 0) { + int i; + u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); + if (i > 8) { + switch (reg[1]) { + case 0x3f8: + offset = 0; + break; + case 0x2f8: + offset = 1; + break; + case 0x898: + offset = 2; + break; + case 0x890: + offset = 3; + break; + default: + /* We dont recognise the serial port */ + goto not_found; + } + } + } +#endif /* CONFIG_SERIAL_8250_CONSOLE */ +#ifdef CONFIG_PPC_PSERIES + else if (strcmp(name, "vty") == 0) { + u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL); + char *compat = (char *)get_property(prom_stdout, "compatible", NULL); + + if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) { + /* Host Virtual Serial Interface */ + switch (reg[0]) { + case 0x30000000: + offset = 0; + break; + case 0x30000001: + offset = 1; + break; + default: + goto not_found; + } + of_node_put(prom_stdout); + DBG("Found hvsi console at offset %d\n", offset); + return add_preferred_console("hvsi", offset, NULL); + } else { + /* pSeries LPAR virtual console */ + of_node_put(prom_stdout); + DBG("Found hvc console\n"); + return add_preferred_console("hvc", 0, NULL); + } + } +#endif /* CONFIG_PPC_PSERIES */ +#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE + else if (strcmp(name, "ch-a") == 0) + offset = 0; + else if (strcmp(name, "ch-b") == 0) + offset = 1; +#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */ + else + goto not_found; + of_node_put(prom_stdout); + + DBG("Found serial console at ttyS%d\n", offset); + + if (spd) { + static char __initdata opt[16]; + sprintf(opt, "%d", *spd); + return add_preferred_console("ttyS", offset, opt); + } else + return add_preferred_console("ttyS", offset, NULL); + + not_found: + DBG("No preferred console found !\n"); + of_node_put(prom_stdout); + return -ENODEV; +} +console_initcall(set_preferred_console); +#endif /* CONFIG_PPC_MULTIPLATFORM */ + void __init check_for_initrd(void) { #ifdef CONFIG_BLK_DEV_INITRD @@ -319,7 +442,7 @@ void __init check_for_initrd(void) /* If we were passed an initrd, set the ROOT_DEV properly if the values * look sensible. If not, clear initrd reference. */ - if (is_kernel_addr(initrd_start) && is_kernel_addr(initrd_end) && + if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE && initrd_end > initrd_start) ROOT_DEV = Root_RAM0; else diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index e5d285adb496..e5694335bf10 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -39,8 +39,6 @@ #include #include #include -#include -#include #include "setup.h" @@ -174,23 +172,12 @@ void __init platform_init(void) */ void __init machine_init(unsigned long dt_ptr, unsigned long phys) { - /* If btext is enabled, we might have a BAT setup for early display, - * thus we do enable some very basic udbg output - */ -#ifdef CONFIG_BOOTX_TEXT - udbg_putc = btext_drawchar; -#endif - - /* Do some early initialization based on the flat device tree */ early_init_devtree(__va(dt_ptr)); - /* Check default command line */ #ifdef CONFIG_CMDLINE - if (cmd_line[0] == 0) - strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); + strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); #endif /* CONFIG_CMDLINE */ - /* Base init based on machine type */ platform_init(); #ifdef CONFIG_6xx @@ -295,22 +282,25 @@ void __init setup_arch(char **cmdline_p) unflatten_device_tree(); check_for_initrd(); + finish_device_tree(); - if (ppc_md.init_early) - ppc_md.init_early(); + smp_setup_cpu_maps(); -#ifdef CONFIG_SERIAL_8250 - find_legacy_serial_ports(); +#ifdef CONFIG_BOOTX_TEXT + init_boot_display(); #endif - finish_device_tree(); - smp_setup_cpu_maps(); +#ifdef CONFIG_PPC_PMAC + /* This could be called "early setup arch", it must be done + * now because xmon need it + */ + if (_machine == _MACH_Pmac) + pmac_feature_init(); /* New cool way */ +#endif #ifdef CONFIG_XMON_DEFAULT xmon_init(1); #endif - /* Register early console */ - register_early_udbg_console(); #if defined(CONFIG_KGDB) if (ppc_md.kgdb_map_scc) diff --git a/trunk/arch/powerpc/kernel/setup_64.c b/trunk/arch/powerpc/kernel/setup_64.c index 98e9f0595dd8..e3fb78397dc6 100644 --- a/trunk/arch/powerpc/kernel/setup_64.c +++ b/trunk/arch/powerpc/kernel/setup_64.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -269,10 +268,6 @@ void __init early_setup(unsigned long dt_ptr) } ppc_md = **mach; -#ifdef CONFIG_CRASH_DUMP - kdump_setup(); -#endif - DBG("Found, Initializing memory management...\n"); /* @@ -322,7 +317,6 @@ void early_setup_secondary(void) void smp_release_cpus(void) { extern unsigned long __secondary_hold_spinloop; - unsigned long *ptr; DBG(" -> smp_release_cpus()\n"); @@ -333,9 +327,7 @@ void smp_release_cpus(void) * This is useless but harmless on iSeries, secondaries are already * waiting on their paca spinloops. */ - ptr = (unsigned long *)((unsigned long)&__secondary_hold_spinloop - - PHYSICAL_START); - *ptr = 1; + __secondary_hold_spinloop = 1; mb(); DBG(" <- smp_release_cpus()\n"); @@ -467,21 +459,16 @@ void __init setup_system(void) */ ppc_md.init_early(); - /* - * We can discover serial ports now since the above did setup the - * hash table management for us, thus ioremap works. We do that early - * so that further code can be debugged - */ -#ifdef CONFIG_SERIAL_8250 - find_legacy_serial_ports(); -#endif - /* * "Finish" the device-tree, that is do the actual parsing of * some of the properties like the interrupt map */ finish_device_tree(); +#ifdef CONFIG_BOOTX_TEXT + init_boot_display(); +#endif + /* * Initialize xmon */ @@ -520,9 +507,6 @@ void __init setup_system(void) ppc64_caches.iline_size); printk("htab_address = 0x%p\n", htab_address); printk("htab_hash_mask = 0x%lx\n", htab_hash_mask); -#if PHYSICAL_START > 0 - printk("physical_start = 0x%x\n", PHYSICAL_START); -#endif printk("-----------------------------------------------------\n"); mm_init_ppc64(); @@ -673,6 +657,187 @@ void ppc64_terminate_msg(unsigned int src, const char *msg) printk("[terminate]%04x %s\n", src, msg); } +#ifndef CONFIG_PPC_ISERIES +/* + * This function can be used by platforms to "find" legacy serial ports. + * It works for "serial" nodes under an "isa" node, and will try to + * respect the "ibm,aix-loc" property if any. It works with up to 8 + * ports. + */ + +#define MAX_LEGACY_SERIAL_PORTS 8 +static struct plat_serial8250_port serial_ports[MAX_LEGACY_SERIAL_PORTS+1]; +static unsigned int old_serial_count; + +void __init generic_find_legacy_serial_ports(u64 *physport, + unsigned int *default_speed) +{ + struct device_node *np; + u32 *sizeprop; + + struct isa_reg_property { + u32 space; + u32 address; + u32 size; + }; + struct pci_reg_property { + struct pci_address addr; + u32 size_hi; + u32 size_lo; + }; + + DBG(" -> generic_find_legacy_serial_port()\n"); + + *physport = 0; + if (default_speed) + *default_speed = 0; + + np = of_find_node_by_path("/"); + if (!np) + return; + + /* First fill our array */ + for (np = NULL; (np = of_find_node_by_type(np, "serial"));) { + struct device_node *isa, *pci; + struct isa_reg_property *reg; + unsigned long phys_size, addr_size, io_base; + u32 *rangesp; + u32 *interrupts, *clk, *spd; + char *typep; + int index, rlen, rentsize; + + /* Ok, first check if it's under an "isa" parent */ + isa = of_get_parent(np); + if (!isa || strcmp(isa->name, "isa")) { + DBG("%s: no isa parent found\n", np->full_name); + continue; + } + + /* Now look for an "ibm,aix-loc" property that gives us ordering + * if any... + */ + typep = (char *)get_property(np, "ibm,aix-loc", NULL); + + /* Get the ISA port number */ + reg = (struct isa_reg_property *)get_property(np, "reg", NULL); + if (reg == NULL) + goto next_port; + /* We assume the interrupt number isn't translated ... */ + interrupts = (u32 *)get_property(np, "interrupts", NULL); + /* get clock freq. if present */ + clk = (u32 *)get_property(np, "clock-frequency", NULL); + /* get default speed if present */ + spd = (u32 *)get_property(np, "current-speed", NULL); + /* Default to locate at end of array */ + index = old_serial_count; /* end of the array by default */ + + /* If we have a location index, then use it */ + if (typep && *typep == 'S') { + index = simple_strtol(typep+1, NULL, 0) - 1; + /* if index is out of range, use end of array instead */ + if (index >= MAX_LEGACY_SERIAL_PORTS) + index = old_serial_count; + /* if our index is still out of range, that mean that + * array is full, we could scan for a free slot but that + * make little sense to bother, just skip the port + */ + if (index >= MAX_LEGACY_SERIAL_PORTS) + goto next_port; + if (index >= old_serial_count) + old_serial_count = index + 1; + /* Check if there is a port who already claimed our slot */ + if (serial_ports[index].iobase != 0) { + /* if we still have some room, move it, else override */ + if (old_serial_count < MAX_LEGACY_SERIAL_PORTS) { + DBG("Moved legacy port %d -> %d\n", index, + old_serial_count); + serial_ports[old_serial_count++] = + serial_ports[index]; + } else { + DBG("Replacing legacy port %d\n", index); + } + } + } + if (index >= MAX_LEGACY_SERIAL_PORTS) + goto next_port; + if (index >= old_serial_count) + old_serial_count = index + 1; + + /* Now fill the entry */ + memset(&serial_ports[index], 0, sizeof(struct plat_serial8250_port)); + serial_ports[index].uartclk = clk ? *clk : BASE_BAUD * 16; + serial_ports[index].iobase = reg->address; + serial_ports[index].irq = interrupts ? interrupts[0] : 0; + serial_ports[index].flags = ASYNC_BOOT_AUTOCONF; + + DBG("Added legacy port, index: %d, port: %x, irq: %d, clk: %d\n", + index, + serial_ports[index].iobase, + serial_ports[index].irq, + serial_ports[index].uartclk); + + /* Get phys address of IO reg for port 1 */ + if (index != 0) + goto next_port; + + pci = of_get_parent(isa); + if (!pci) { + DBG("%s: no pci parent found\n", np->full_name); + goto next_port; + } + + rangesp = (u32 *)get_property(pci, "ranges", &rlen); + if (rangesp == NULL) { + of_node_put(pci); + goto next_port; + } + rlen /= 4; + + /* we need the #size-cells of the PCI bridge node itself */ + phys_size = 1; + sizeprop = (u32 *)get_property(pci, "#size-cells", NULL); + if (sizeprop != NULL) + phys_size = *sizeprop; + /* we need the parent #addr-cells */ + addr_size = prom_n_addr_cells(pci); + rentsize = 3 + addr_size + phys_size; + io_base = 0; + for (;rlen >= rentsize; rlen -= rentsize,rangesp += rentsize) { + if (((rangesp[0] >> 24) & 0x3) != 1) + continue; /* not IO space */ + io_base = rangesp[3]; + if (addr_size == 2) + io_base = (io_base << 32) | rangesp[4]; + } + if (io_base != 0) { + *physport = io_base + reg->address; + if (default_speed && spd) + *default_speed = *spd; + } + of_node_put(pci); + next_port: + of_node_put(isa); + } + + DBG(" <- generic_find_legacy_serial_port()\n"); +} + +static struct platform_device serial_device = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev = { + .platform_data = serial_ports, + }, +}; + +static int __init serial_dev_init(void) +{ + return platform_device_register(&serial_device); +} +arch_initcall(serial_dev_init); + +#endif /* CONFIG_PPC_ISERIES */ + int check_legacy_ioport(unsigned long base_port) { if (ppc_md.check_legacy_ioport == NULL) diff --git a/trunk/arch/powerpc/kernel/signal_32.c b/trunk/arch/powerpc/kernel/signal_32.c index d3f0b6d452fb..5a2eba60dd39 100644 --- a/trunk/arch/powerpc/kernel/signal_32.c +++ b/trunk/arch/powerpc/kernel/signal_32.c @@ -76,6 +76,7 @@ * registers from *regs. This is what we need * to do when a signal has been delivered. */ +#define sigreturn_exit(regs) return 0 #define GP_REGS_SIZE min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32)) #undef __SIGNAL_FRAMESIZE @@ -155,17 +156,9 @@ static inline int save_general_regs(struct pt_regs *regs, elf_greg_t64 *gregs = (elf_greg_t64 *)regs; int i; - if (!FULL_REGS(regs)) { - set_thread_flag(TIF_SAVE_NVGPRS); - current_thread_info()->nvgprs_frame = frame->mc_gregs; - } - - for (i = 0; i <= PT_RESULT; i ++) { - if (i == 14 && !FULL_REGS(regs)) - i = 32; + for (i = 0; i <= PT_RESULT; i ++) if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i])) return -EFAULT; - } return 0; } @@ -186,6 +179,8 @@ static inline int restore_general_regs(struct pt_regs *regs, #else /* CONFIG_PPC64 */ +extern void sigreturn_exit(struct pt_regs *); + #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) @@ -219,15 +214,6 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka, static inline int save_general_regs(struct pt_regs *regs, struct mcontext __user *frame) { - if (!FULL_REGS(regs)) { - /* Zero out the unsaved GPRs to avoid information - leak, and set TIF_SAVE_NVGPRS to ensure that the - registers do actually get saved later. */ - memset(®s->gpr[14], 0, 18 * sizeof(unsigned long)); - current_thread_info()->nvgprs_frame = &frame->mc_gregs; - set_thread_flag(TIF_SAVE_NVGPRS); - } - return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE); } @@ -270,10 +256,8 @@ long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7, while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(&saveset, regs)) { - set_thread_flag(TIF_RESTOREALL); - return 0; - } + if (do_signal(&saveset, regs)) + sigreturn_exit(regs); } } @@ -308,10 +292,8 @@ long sys_rt_sigsuspend( while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(&saveset, regs)) { - set_thread_flag(TIF_RESTOREALL); - return 0; - } + if (do_signal(&saveset, regs)) + sigreturn_exit(regs); } } @@ -409,6 +391,9 @@ struct rt_sigframe { static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, int sigret) { +#ifdef CONFIG_PPC32 + CHECK_FULL_REGS(regs); +#endif /* Make sure floating point registers are stored in regs */ flush_fp_to_thread(current); @@ -843,6 +828,12 @@ static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka, regs->gpr[6] = (unsigned long) rt_sf; regs->nip = (unsigned long) ka->sa.sa_handler; regs->trap = 0; +#ifdef CONFIG_PPC64 + regs->result = 0; + + if (test_thread_flag(TIF_SINGLESTEP)) + ptrace_notify(SIGTRAP); +#endif return 1; badframe: @@ -920,8 +911,8 @@ long sys_swapcontext(struct ucontext __user *old_ctx, */ if (do_setcontext(new_ctx, regs, 0)) do_exit(SIGSEGV); - - set_thread_flag(TIF_RESTOREALL); + sigreturn_exit(regs); + /* doesn't actually return back to here */ return 0; } @@ -954,11 +945,12 @@ long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, * nobody does any... */ compat_sys_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs); + return (int)regs->result; #else do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]); -#endif - set_thread_flag(TIF_RESTOREALL); + sigreturn_exit(regs); /* doesn't return here */ return 0; +#endif bad: force_sig(SIGSEGV, current); @@ -1049,7 +1041,9 @@ int sys_debug_setcontext(struct ucontext __user *ctx, */ do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]); - set_thread_flag(TIF_RESTOREALL); + sigreturn_exit(regs); + /* doesn't actually return back to here */ + out: return 0; } @@ -1113,6 +1107,12 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka, regs->gpr[4] = (unsigned long) sc; regs->nip = (unsigned long) ka->sa.sa_handler; regs->trap = 0; +#ifdef CONFIG_PPC64 + regs->result = 0; + + if (test_thread_flag(TIF_SINGLESTEP)) + ptrace_notify(SIGTRAP); +#endif return 1; @@ -1160,8 +1160,12 @@ long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, || restore_user_regs(regs, sr, 1)) goto badframe; - set_thread_flag(TIF_RESTOREALL); +#ifdef CONFIG_PPC64 + return (int)regs->result; +#else + sigreturn_exit(regs); /* doesn't return */ return 0; +#endif badframe: force_sig(SIGSEGV, current); diff --git a/trunk/arch/powerpc/kernel/signal_64.c b/trunk/arch/powerpc/kernel/signal_64.c index 5462bef898f6..1decf2785530 100644 --- a/trunk/arch/powerpc/kernel/signal_64.c +++ b/trunk/arch/powerpc/kernel/signal_64.c @@ -96,10 +96,8 @@ long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int while (1) { current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(&saveset, regs)) { - set_thread_flag(TIF_RESTOREALL); + if (do_signal(&saveset, regs)) return 0; - } } } @@ -154,14 +152,6 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, err |= __put_user(0, &sc->v_regs); #endif /* CONFIG_ALTIVEC */ err |= __put_user(&sc->gp_regs, &sc->regs); - if (!FULL_REGS(regs)) { - /* Zero out the unsaved GPRs to avoid information - leak, and set TIF_SAVE_NVGPRS to ensure that the - registers do actually get saved later. */ - memset(®s->gpr[14], 0, 18 * sizeof(unsigned long)); - set_thread_flag(TIF_SAVE_NVGPRS); - current_thread_info()->nvgprs_frame = &sc->gp_regs; - } err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE); err |= __copy_to_user(&sc->fp_regs, ¤t->thread.fpr, FP_REGS_SIZE); err |= __put_user(signr, &sc->signal); @@ -350,7 +340,6 @@ int sys_swapcontext(struct ucontext __user *old_ctx, do_exit(SIGSEGV); /* This returns like rt_sigreturn */ - set_thread_flag(TIF_RESTOREALL); return 0; } @@ -383,8 +372,7 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5, */ do_sigaltstack(&uc->uc_stack, NULL, regs->gpr[1]); - set_thread_flag(TIF_RESTOREALL); - return 0; + return regs->result; badframe: #if DEBUG_SIG @@ -466,6 +454,9 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, if (err) goto badframe; + if (test_thread_flag(TIF_SINGLESTEP)) + ptrace_notify(SIGTRAP); + return 1; badframe: @@ -511,8 +502,6 @@ static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) * we only get here if there is a handler, we dont restart. */ regs->result = -EINTR; - regs->gpr[3] = EINTR; - regs->ccr |= 0x10000000; break; case -ERESTARTSYS: /* ERESTARTSYS means to restart the syscall if there is no @@ -520,8 +509,6 @@ static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka) */ if (!(ka->sa.sa_flags & SA_RESTART)) { regs->result = -EINTR; - regs->gpr[3] = EINTR; - regs->ccr |= 0x10000000; break; } /* fallthrough */ diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index d381ec90b759..30374d2f88e5 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -76,8 +75,6 @@ void smp_call_function_interrupt(void); int smt_enabled_at_boot = 1; -static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL; - #ifdef CONFIG_MPIC int __init smp_mpic_probe(void) { @@ -126,16 +123,11 @@ void smp_message_recv(int msg, struct pt_regs *regs) /* XXX Do we have to do this? */ set_need_resched(); break; - case PPC_MSG_DEBUGGER_BREAK: - if (crash_ipi_function_ptr) { - crash_ipi_function_ptr(regs); - break; - } #ifdef CONFIG_DEBUGGER + case PPC_MSG_DEBUGGER_BREAK: debugger_ipi(regs); break; -#endif /* CONFIG_DEBUGGER */ - /* FALLTHROUGH */ +#endif default: printk("SMP %d: smp_message_recv(): unknown msg %d\n", smp_processor_id(), msg); @@ -155,17 +147,6 @@ void smp_send_debugger_break(int cpu) } #endif -#ifdef CONFIG_KEXEC -void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)) -{ - crash_ipi_function_ptr = crash_ipi_callback; - if (crash_ipi_callback) { - mb(); - smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK); - } -} -#endif - static void stop_this_cpu(void *dummy) { local_irq_disable(); @@ -471,6 +452,10 @@ int __devinit __cpu_up(unsigned int cpu) if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) return -EINVAL; +#ifdef CONFIG_PPC64 + paca[cpu].default_decr = tb_ticks_per_jiffy; +#endif + /* Make sure callin-map entry is 0 (can be leftover a CPU * hotplug */ @@ -569,8 +554,6 @@ void __init smp_cpus_done(unsigned int max_cpus) smp_ops->setup_cpu(boot_cpuid); set_cpus_allowed(current, old_mask); - - dump_numa_cpu_topology(); } #ifdef CONFIG_HOTPLUG_CPU diff --git a/trunk/arch/powerpc/kernel/syscalls.c b/trunk/arch/powerpc/kernel/syscalls.c index ad895c99813b..91b93d917b64 100644 --- a/trunk/arch/powerpc/kernel/syscalls.c +++ b/trunk/arch/powerpc/kernel/syscalls.c @@ -43,6 +43,9 @@ #include #include +extern unsigned long wall_jiffies; + + /* * sys_ipc() is the de-multiplexer for the SysV IPC calls.. * @@ -308,6 +311,31 @@ int sys_olduname(struct oldold_utsname __user *name) return error? -EFAULT: 0; } +#ifdef CONFIG_PPC64 +time_t sys64_time(time_t __user * tloc) +{ + time_t secs; + time_t usecs; + + long tb_delta = tb_ticks_since(tb_last_stamp); + tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy; + + secs = xtime.tv_sec; + usecs = (xtime.tv_nsec/1000) + tb_delta / tb_ticks_per_usec; + while (usecs >= USEC_PER_SEC) { + ++secs; + usecs -= USEC_PER_SEC; + } + + if (tloc) { + if (put_user(secs,tloc)) + secs = -EFAULT; + } + + return secs; +} +#endif + long ppc_fadvise64_64(int fd, int advice, u32 offset_high, u32 offset_low, u32 len_high, u32 len_low) { diff --git a/trunk/arch/powerpc/kernel/systbl.S b/trunk/arch/powerpc/kernel/systbl.S index 65463a1076e8..65eaea91b499 100644 --- a/trunk/arch/powerpc/kernel/systbl.S +++ b/trunk/arch/powerpc/kernel/systbl.S @@ -54,7 +54,7 @@ SYSCALL(link) SYSCALL(unlink) COMPAT_SYS(execve) SYSCALL(chdir) -COMPAT_SYS(time) +SYSX(sys64_time,compat_sys_time,sys_time) SYSCALL(mknod) SYSCALL(chmod) SYSCALL(lchown) @@ -113,7 +113,7 @@ SYSCALL(sgetmask) COMPAT_SYS(ssetmask) SYSCALL(setreuid) SYSCALL(setregid) -SYS32ONLY(sigsuspend) +SYSX(sys_ni_syscall,ppc32_sigsuspend,ppc_sigsuspend) COMPAT_SYS(sigpending) COMPAT_SYS(sethostname) COMPAT_SYS(setrlimit) @@ -160,7 +160,7 @@ SYSCALL(swapoff) COMPAT_SYS(sysinfo) COMPAT_SYS(ipc) SYSCALL(fsync) -SYS32ONLY(sigreturn) +SYSX(sys_ni_syscall,ppc32_sigreturn,sys_sigreturn) PPC_SYS(clone) COMPAT_SYS(setdomainname) PPC_SYS(newuname) @@ -213,13 +213,13 @@ COMPAT_SYS(nfsservctl) SYSCALL(setresgid) SYSCALL(getresgid) COMPAT_SYS(prctl) -COMPAT_SYS(rt_sigreturn) +SYSX(ppc64_rt_sigreturn,ppc32_rt_sigreturn,sys_rt_sigreturn) COMPAT_SYS(rt_sigaction) COMPAT_SYS(rt_sigprocmask) COMPAT_SYS(rt_sigpending) COMPAT_SYS(rt_sigtimedwait) COMPAT_SYS(rt_sigqueueinfo) -COMPAT_SYS(rt_sigsuspend) +SYSX(ppc64_rt_sigsuspend,ppc32_rt_sigsuspend,ppc_rt_sigsuspend) COMPAT_SYS(pread64) COMPAT_SYS(pwrite64) SYSCALL(chown) @@ -290,7 +290,7 @@ COMPAT_SYS(clock_settime) COMPAT_SYS(clock_gettime) COMPAT_SYS(clock_getres) COMPAT_SYS(clock_nanosleep) -COMPAT_SYS(swapcontext) +SYSX(ppc64_swapcontext,ppc32_swapcontext,ppc_swapcontext) COMPAT_SYS(tgkill) COMPAT_SYS(utimes) COMPAT_SYS(statfs64) @@ -319,5 +319,3 @@ COMPAT_SYS(ioprio_get) SYSCALL(inotify_init) SYSCALL(inotify_add_watch) SYSCALL(inotify_rm_watch) -SYSCALL(spu_run) -SYSCALL(spu_create) diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index 56f50e91bddb..de8479769bb7 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -699,6 +699,10 @@ void __init time_init(void) div128_by_32(1024*1024, 0, tb_ticks_per_sec, &res); tb_to_xs = res.result_low; +#ifdef CONFIG_PPC64 + get_paca()->default_decr = tb_ticks_per_jiffy; +#endif + /* * Compute scale factor for sched_clock. * The calibrate_decr() function has set tb_ticks_per_sec, diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index 7509aa6474f2..1511454c4690 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -96,7 +95,7 @@ static DEFINE_SPINLOCK(die_lock); int die(const char *str, struct pt_regs *regs, long err) { - static int die_counter, crash_dump_start = 0; + static int die_counter; int nl = 0; if (debugger(regs)) @@ -157,21 +156,7 @@ int die(const char *str, struct pt_regs *regs, long err) print_modules(); show_regs(regs); bust_spinlocks(0); - - if (!crash_dump_start && kexec_should_crash(current)) { - crash_dump_start = 1; - spin_unlock_irq(&die_lock); - crash_kexec(regs); - /* NOTREACHED */ - } spin_unlock_irq(&die_lock); - if (crash_dump_start) - /* - * Only for soft-reset: Other CPUs will be responded to an IPI - * sent by first kexec CPU. - */ - for(;;) - ; if (in_interrupt()) panic("Fatal exception in interrupt"); @@ -230,10 +215,8 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) void system_reset_exception(struct pt_regs *regs) { /* See if any machine dependent calls */ - if (ppc_md.system_reset_exception) { - if (ppc_md.system_reset_exception(regs)) - return; - } + if (ppc_md.system_reset_exception) + ppc_md.system_reset_exception(regs); die("System Reset", regs, SIGABRT); @@ -903,10 +886,12 @@ void altivec_unavailable_exception(struct pt_regs *regs) die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); } +#if defined(CONFIG_PPC64) || defined(CONFIG_E500) void performance_monitor_exception(struct pt_regs *regs) { perf_irq(regs); } +#endif #ifdef CONFIG_8xx void SoftwareEmulation(struct pt_regs *regs) diff --git a/trunk/arch/powerpc/kernel/udbg.c b/trunk/arch/powerpc/kernel/udbg.c index 558c1ceb2b93..0d878e72fc44 100644 --- a/trunk/arch/powerpc/kernel/udbg.c +++ b/trunk/arch/powerpc/kernel/udbg.c @@ -16,8 +16,8 @@ #include #include -void (*udbg_putc)(char c); -int (*udbg_getc)(void); +void (*udbg_putc)(unsigned char c); +unsigned char (*udbg_getc)(void); int (*udbg_getc_poll)(void); /* udbg library, used by xmon et al */ @@ -57,8 +57,8 @@ int udbg_write(const char *s, int n) int udbg_read(char *buf, int buflen) { - char *p = buf; - int i, c; + char c, *p = buf; + int i; if (!udbg_getc) return 0; @@ -66,11 +66,8 @@ int udbg_read(char *buf, int buflen) for (i = 0; i < buflen; ++i) { do { c = udbg_getc(); - if (c == -1 && i == 0) - return -1; - } while (c == 0x11 || c == 0x13); - if (c == 0 || c == -1) + if (c == 0) break; *p++ = c; } @@ -81,7 +78,7 @@ int udbg_read(char *buf, int buflen) #define UDBG_BUFSIZE 256 void udbg_printf(const char *fmt, ...) { - char buf[UDBG_BUFSIZE]; + unsigned char buf[UDBG_BUFSIZE]; va_list args; va_start(args, fmt); @@ -90,12 +87,6 @@ void udbg_printf(const char *fmt, ...) va_end(args); } -void __init udbg_progress(char *s, unsigned short hex) -{ - udbg_puts(s); - udbg_puts("\n"); -} - /* * Early boot console based on udbg */ @@ -108,7 +99,7 @@ static void udbg_console_write(struct console *con, const char *s, static struct console udbg_console = { .name = "udbg", .write = udbg_console_write, - .flags = CON_PRINTBUFFER | CON_ENABLED, + .flags = CON_PRINTBUFFER, .index = -1, }; @@ -116,19 +107,15 @@ static int early_console_initialized; void __init disable_early_printk(void) { -#if 1 if (!early_console_initialized) return; unregister_console(&udbg_console); early_console_initialized = 0; -#endif } /* called by setup_system */ void register_early_udbg_console(void) { - if (early_console_initialized) - return; early_console_initialized = 1; register_console(&udbg_console); } diff --git a/trunk/arch/powerpc/kernel/udbg_16550.c b/trunk/arch/powerpc/kernel/udbg_16550.c index 7541bf44d2da..9313574ab935 100644 --- a/trunk/arch/powerpc/kernel/udbg_16550.c +++ b/trunk/arch/powerpc/kernel/udbg_16550.c @@ -43,11 +43,9 @@ struct NS16550 { #define LSR_TEMT 0x40 /* Xmitter empty */ #define LSR_ERR 0x80 /* Error */ -#define LCR_DLAB 0x80 - static volatile struct NS16550 __iomem *udbg_comport; -static void udbg_550_putc(char c) +static void udbg_550_putc(unsigned char c) { if (udbg_comport) { while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0) @@ -69,80 +67,39 @@ static int udbg_550_getc_poll(void) return -1; } -static int udbg_550_getc(void) +static unsigned char udbg_550_getc(void) { if (udbg_comport) { while ((in_8(&udbg_comport->lsr) & LSR_DR) == 0) /* wait for char */; return in_8(&udbg_comport->rbr); } - return -1; + return 0; } -void udbg_init_uart(void __iomem *comport, unsigned int speed, - unsigned int clock) +void udbg_init_uart(void __iomem *comport, unsigned int speed) { - unsigned int dll, base_bauds = clock / 16; - - if (speed == 0) - speed = 9600; - dll = base_bauds / speed; + u16 dll = speed ? (115200 / speed) : 12; if (comport) { udbg_comport = (struct NS16550 __iomem *)comport; out_8(&udbg_comport->lcr, 0x00); out_8(&udbg_comport->ier, 0xff); out_8(&udbg_comport->ier, 0x00); - out_8(&udbg_comport->lcr, LCR_DLAB); - out_8(&udbg_comport->dll, dll & 0xff); - out_8(&udbg_comport->dlm, dll >> 8); - /* 8 data, 1 stop, no parity */ - out_8(&udbg_comport->lcr, 0x03); - /* RTS/DTR */ - out_8(&udbg_comport->mcr, 0x03); - /* Clear & enable FIFOs */ - out_8(&udbg_comport->fcr ,0x07); + out_8(&udbg_comport->lcr, 0x80); /* Access baud rate */ + out_8(&udbg_comport->dll, dll & 0xff); /* 1 = 115200, 2 = 57600, + 3 = 38400, 12 = 9600 baud */ + out_8(&udbg_comport->dlm, dll >> 8); /* dll >> 8 which should be zero + for fast rates; */ + out_8(&udbg_comport->lcr, 0x03); /* 8 data, 1 stop, no parity */ + out_8(&udbg_comport->mcr, 0x03); /* RTS/DTR */ + out_8(&udbg_comport->fcr ,0x07); /* Clear & enable FIFOs */ udbg_putc = udbg_550_putc; udbg_getc = udbg_550_getc; udbg_getc_poll = udbg_550_getc_poll; } } -unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock) -{ - unsigned int dll, dlm, divisor, prescaler, speed; - u8 old_lcr; - volatile struct NS16550 __iomem *port = comport; - - old_lcr = in_8(&port->lcr); - - /* select divisor latch registers. */ - out_8(&port->lcr, LCR_DLAB); - - /* now, read the divisor */ - dll = in_8(&port->dll); - dlm = in_8(&port->dlm); - divisor = dlm << 8 | dll; - - /* check prescaling */ - if (in_8(&port->mcr) & 0x80) - prescaler = 4; - else - prescaler = 1; - - /* restore the LCR */ - out_8(&port->lcr, old_lcr); - - /* calculate speed */ - speed = (clock / prescaler) / (divisor * 16); - - /* sanity check */ - if (speed < 0 || speed > (clock / 16)) - speed = 9600; - - return speed; -} - #ifdef CONFIG_PPC_MAPLE void udbg_maple_real_putc(unsigned char c) { diff --git a/trunk/arch/powerpc/platforms/powermac/udbg_scc.c b/trunk/arch/powerpc/kernel/udbg_scc.c similarity index 66% rename from trunk/arch/powerpc/platforms/powermac/udbg_scc.c rename to trunk/arch/powerpc/kernel/udbg_scc.c index e87d53acfb61..820c53551507 100644 --- a/trunk/arch/powerpc/platforms/powermac/udbg_scc.c +++ b/trunk/arch/powerpc/kernel/udbg_scc.c @@ -25,7 +25,7 @@ extern void real_writeb(u8 data, volatile u8 __iomem *addr); static volatile u8 __iomem *sccc; static volatile u8 __iomem *sccd; -static void udbg_scc_putc(char c) +static void udbg_scc_putc(unsigned char c) { if (sccc) { while ((in_8(sccc) & SCC_TXRDY) == 0) @@ -47,14 +47,14 @@ static int udbg_scc_getc_poll(void) return -1; } -static int udbg_scc_getc(void) +static unsigned char udbg_scc_getc(void) { if (sccc) { while ((in_8(sccc) & SCC_RXRDY) == 0) ; return in_8(sccd); } - return -1; + return 0; } static unsigned char scc_inittab[] = { @@ -67,59 +67,38 @@ static unsigned char scc_inittab[] = { 3, 0xc1, /* rx enable, 8 bits */ }; -void udbg_scc_init(int force_scc) +void udbg_init_scc(struct device_node *np) { u32 *reg; unsigned long addr; - struct device_node *stdout = NULL, *escc = NULL, *macio = NULL; - struct device_node *ch, *ch_def = NULL, *ch_a = NULL; - char *path; int i, x; - escc = of_find_node_by_name(NULL, "escc"); - if (escc == NULL) - goto bail; - macio = of_get_parent(escc); - if (macio == NULL) - goto bail; - path = (char *)get_property(of_chosen, "linux,stdout-path", NULL); - if (path != NULL) - stdout = of_find_node_by_path(path); - for (ch = NULL; (ch = of_get_next_child(escc, ch)) != NULL;) { - if (ch == stdout) - ch_def = of_node_get(ch); - if (strcmp(ch->name, "ch-a") == 0) - ch_a = of_node_get(ch); - } - if (ch_def == NULL && !force_scc) - goto bail; - - ch = ch_def ? ch_def : ch_a; + if (np == NULL) + np = of_find_node_by_name(NULL, "escc"); + if (np == NULL || np->parent == NULL) + return; + udbg_printf("found SCC...\n"); /* Get address within mac-io ASIC */ - reg = (u32 *)get_property(escc, "reg", NULL); + reg = (u32 *)get_property(np, "reg", NULL); if (reg == NULL) - goto bail; + return; addr = reg[0]; - + udbg_printf("local addr: %lx\n", addr); /* Get address of mac-io PCI itself */ - reg = (u32 *)get_property(macio, "assigned-addresses", NULL); + reg = (u32 *)get_property(np->parent, "assigned-addresses", NULL); if (reg == NULL) - goto bail; + return; addr += reg[2]; - - /* Lock the serial port */ - pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch, - PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1); - + udbg_printf("final addr: %lx\n", addr); /* Setup for 57600 8N1 */ - if (ch == ch_a) - addr += 0x20; + addr += 0x20; sccc = (volatile u8 * __iomem) ioremap(addr & PAGE_MASK, PAGE_SIZE) ; sccc += addr & ~PAGE_MASK; sccd = sccc + 0x10; + udbg_printf("ioremap result sccc: %p\n", sccc); mb(); for (i = 20000; i != 0; --i) @@ -134,17 +113,9 @@ void udbg_scc_init(int force_scc) udbg_getc_poll = udbg_scc_getc_poll; udbg_puts("Hello World !\n"); - - bail: - of_node_put(macio); - of_node_put(escc); - of_node_put(stdout); - of_node_put(ch_def); - of_node_put(ch_a); } -#ifdef CONFIG_PPC64 -static void udbg_real_scc_putc(char c) +static void udbg_real_scc_putc(unsigned char c) { while ((real_readb(sccc) & SCC_TXRDY) == 0) ; @@ -162,4 +133,3 @@ void udbg_init_pmac_realmode(void) udbg_getc = NULL; udbg_getc_poll = NULL; } -#endif /* CONFIG_PPC64 */ diff --git a/trunk/arch/powerpc/mm/fault.c b/trunk/arch/powerpc/mm/fault.c index a4815d316722..93d4fbfdb724 100644 --- a/trunk/arch/powerpc/mm/fault.c +++ b/trunk/arch/powerpc/mm/fault.c @@ -81,8 +81,7 @@ static int store_updates_sp(struct pt_regs *regs) } #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) -static void do_dabr(struct pt_regs *regs, unsigned long address, - unsigned long error_code) +static void do_dabr(struct pt_regs *regs, unsigned long error_code) { siginfo_t info; @@ -100,7 +99,7 @@ static void do_dabr(struct pt_regs *regs, unsigned long address, info.si_signo = SIGTRAP; info.si_errno = 0; info.si_code = TRAP_HWBKPT; - info.si_addr = (void __user *)address; + info.si_addr = (void __user *)regs->nip; force_sig_info(SIGTRAP, &info, current); } #endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/ @@ -160,7 +159,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) if (error_code & DSISR_DABRMATCH) { /* DABR match */ - do_dabr(regs, address, error_code); + do_dabr(regs, error_code); return 0; } #endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/ diff --git a/trunk/arch/powerpc/mm/hash_utils_64.c b/trunk/arch/powerpc/mm/hash_utils_64.c index 5bb433cbe41b..a606504678bd 100644 --- a/trunk/arch/powerpc/mm/hash_utils_64.c +++ b/trunk/arch/powerpc/mm/hash_utils_64.c @@ -456,7 +456,7 @@ void __init htab_initialize(void) /* create bolted the linear mapping in the hash table */ for (i=0; i < lmb.memory.cnt; i++) { - base = (unsigned long)__va(lmb.memory.region[i].base); + base = lmb.memory.region[i].base + KERNELBASE; size = lmb.memory.region[i].size; DBG("creating mapping for region: %lx : %lx\n", base, size); @@ -498,8 +498,8 @@ void __init htab_initialize(void) * for either 4K or 16MB pages. */ if (tce_alloc_start) { - tce_alloc_start = (unsigned long)__va(tce_alloc_start); - tce_alloc_end = (unsigned long)__va(tce_alloc_end); + tce_alloc_start += KERNELBASE; + tce_alloc_end += KERNELBASE; if (base + size >= tce_alloc_start) tce_alloc_start = base + size + 1; @@ -644,7 +644,6 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) DBG_LOW(" -> rc=%d\n", rc); return rc; } -EXPORT_SYMBOL_GPL(hash_page); void hash_preload(struct mm_struct *mm, unsigned long ea, unsigned long access, unsigned long trap) diff --git a/trunk/arch/powerpc/mm/hugetlbpage.c b/trunk/arch/powerpc/mm/hugetlbpage.c index b51bb28c054b..54131b877da3 100644 --- a/trunk/arch/powerpc/mm/hugetlbpage.c +++ b/trunk/arch/powerpc/mm/hugetlbpage.c @@ -549,17 +549,6 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, return addr; } -static int htlb_check_hinted_area(unsigned long addr, unsigned long len) -{ - struct vm_area_struct *vma; - - vma = find_vma(current->mm, addr); - if (!vma || ((addr + len) <= vma->vm_start)) - return 0; - - return -ENOMEM; -} - static unsigned long htlb_get_low_area(unsigned long len, u16 segmask) { unsigned long addr = 0; @@ -629,28 +618,15 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, if (!cpu_has_feature(CPU_FTR_16M_PAGE)) return -EINVAL; - /* Paranoia, caller should have dealt with this */ - BUG_ON((addr + len) < addr); - if (test_thread_flag(TIF_32BIT)) { - /* Paranoia, caller should have dealt with this */ - BUG_ON((addr + len) > 0x100000000UL); - curareas = current->mm->context.low_htlb_areas; - /* First see if we can use the hint address */ - if (addr && (htlb_check_hinted_area(addr, len) == 0)) { - areamask = LOW_ESID_MASK(addr, len); - if (open_low_hpage_areas(current->mm, areamask) == 0) - return addr; - } - - /* Next see if we can map in the existing low areas */ + /* First see if we can do the mapping in the existing + * low areas */ addr = htlb_get_low_area(len, curareas); if (addr != -ENOMEM) return addr; - /* Finally go looking for areas to open */ lastshift = 0; for (areamask = LOW_ESID_MASK(0x100000000UL-len, len); ! lastshift; areamask >>=1) { @@ -665,22 +641,12 @@ unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr, } else { curareas = current->mm->context.high_htlb_areas; - /* First see if we can use the hint address */ - /* We discourage 64-bit processes from doing hugepage - * mappings below 4GB (must use MAP_FIXED) */ - if ((addr >= 0x100000000UL) - && (htlb_check_hinted_area(addr, len) == 0)) { - areamask = HTLB_AREA_MASK(addr, len); - if (open_high_hpage_areas(current->mm, areamask) == 0) - return addr; - } - - /* Next see if we can map in the existing high areas */ + /* First see if we can do the mapping in the existing + * high areas */ addr = htlb_get_high_area(len, curareas); if (addr != -ENOMEM) return addr; - /* Finally go looking for areas to open */ lastshift = 0; for (areamask = HTLB_AREA_MASK(TASK_SIZE_USER64-len, len); ! lastshift; areamask >>=1) { diff --git a/trunk/arch/powerpc/mm/imalloc.c b/trunk/arch/powerpc/mm/imalloc.c index 8b0c132bc163..f9587bcc6a48 100644 --- a/trunk/arch/powerpc/mm/imalloc.c +++ b/trunk/arch/powerpc/mm/imalloc.c @@ -107,7 +107,6 @@ static int im_region_status(unsigned long v_addr, unsigned long size, if (v_addr < (unsigned long) tmp->addr + tmp->size) break; - *vm = NULL; if (tmp) { if (im_region_overlaps(v_addr, size, tmp)) return IM_REGION_OVERLAP; @@ -128,6 +127,7 @@ static int im_region_status(unsigned long v_addr, unsigned long size, } } + *vm = NULL; return IM_REGION_UNUSED; } diff --git a/trunk/arch/powerpc/mm/init_32.c b/trunk/arch/powerpc/mm/init_32.c index 7d0d75c11848..7d4b8b5f0606 100644 --- a/trunk/arch/powerpc/mm/init_32.c +++ b/trunk/arch/powerpc/mm/init_32.c @@ -188,11 +188,6 @@ void __init MMU_init(void) if (ppc_md.progress) ppc_md.progress("MMU:exit", 0x211); - - /* From now on, btext is no longer BAT mapped if it was at all */ -#ifdef CONFIG_BOOTX_TEXT - btext_unmap(); -#endif } /* This is only called until mem_init is done. */ diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 15aac0d78dfa..ed6ed2e30dac 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -114,18 +114,19 @@ void online_page(struct page *page) num_physpages++; } +/* + * This works only for the non-NUMA case. Later, we'll need a lookup + * to convert from real physical addresses to nid, that doesn't use + * pfn_to_nid(). + */ int __devinit add_memory(u64 start, u64 size) { - struct pglist_data *pgdata; + struct pglist_data *pgdata = NODE_DATA(0); struct zone *zone; - int nid; unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; - nid = hot_add_scn_to_nid(start); - pgdata = NODE_DATA(nid); - - start = __va(start); + start += KERNELBASE; create_section_mapping(start, start + size); /* this should work for most non-highmem platforms */ diff --git a/trunk/arch/powerpc/mm/numa.c b/trunk/arch/powerpc/mm/numa.c index 2863a912bcd0..ba7a3055a9fc 100644 --- a/trunk/arch/powerpc/mm/numa.c +++ b/trunk/arch/powerpc/mm/numa.c @@ -37,7 +37,6 @@ EXPORT_SYMBOL(node_data); static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES]; static int min_common_depth; -static int n_mem_addr_cells, n_mem_size_cells; /* * We need somewhere to store start/end/node for each region until we have @@ -255,20 +254,32 @@ static int __init find_min_common_depth(void) return depth; } -static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells) +static int __init get_mem_addr_cells(void) { struct device_node *memory = NULL; + int rc; memory = of_find_node_by_type(memory, "memory"); if (!memory) - panic("numa.c: No memory nodes found!"); + return 0; /* it won't matter */ - *n_addr_cells = prom_n_addr_cells(memory); - *n_size_cells = prom_n_size_cells(memory); - of_node_put(memory); + rc = prom_n_addr_cells(memory); + return rc; } -static unsigned long __devinit read_n_cells(int n, unsigned int **buf) +static int __init get_mem_size_cells(void) +{ + struct device_node *memory = NULL; + int rc; + + memory = of_find_node_by_type(memory, "memory"); + if (!memory) + return 0; /* it won't matter */ + rc = prom_n_size_cells(memory); + return rc; +} + +static unsigned long __init read_n_cells(int n, unsigned int **buf) { unsigned long result = 0; @@ -375,6 +386,7 @@ static int __init parse_numa_properties(void) { struct device_node *cpu = NULL; struct device_node *memory = NULL; + int addr_cells, size_cells; int max_domain; unsigned long i; @@ -413,7 +425,8 @@ static int __init parse_numa_properties(void) } } - get_n_mem_cells(&n_mem_addr_cells, &n_mem_size_cells); + addr_cells = get_mem_addr_cells(); + size_cells = get_mem_size_cells(); memory = NULL; while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { unsigned long start; @@ -423,21 +436,15 @@ static int __init parse_numa_properties(void) unsigned int *memcell_buf; unsigned int len; - memcell_buf = (unsigned int *)get_property(memory, - "linux,usable-memory", &len); - if (!memcell_buf || len <= 0) - memcell_buf = - (unsigned int *)get_property(memory, "reg", - &len); + memcell_buf = (unsigned int *)get_property(memory, "reg", &len); if (!memcell_buf || len <= 0) continue; - /* ranges in cell */ - ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells); + ranges = memory->n_addrs; new_range: /* these are order-sensitive, and modify the buffer pointer */ - start = read_n_cells(n_mem_addr_cells, &memcell_buf); - size = read_n_cells(n_mem_size_cells, &memcell_buf); + start = read_n_cells(addr_cells, &memcell_buf); + size = read_n_cells(size_cells, &memcell_buf); numa_domain = of_node_numa_domain(memory); @@ -490,41 +497,7 @@ static void __init setup_nonnuma(void) node_set_online(0); } -void __init dump_numa_cpu_topology(void) -{ - unsigned int node; - unsigned int cpu, count; - - if (min_common_depth == -1 || !numa_enabled) - return; - - for_each_online_node(node) { - printk(KERN_INFO "Node %d CPUs:", node); - - count = 0; - /* - * If we used a CPU iterator here we would miss printing - * the holes in the cpumap. - */ - for (cpu = 0; cpu < NR_CPUS; cpu++) { - if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) { - if (count == 0) - printk(" %u", cpu); - ++count; - } else { - if (count > 1) - printk("-%u", cpu - 1); - count = 0; - } - } - - if (count > 1) - printk("-%u", NR_CPUS - 1); - printk("\n"); - } -} - -static void __init dump_numa_memory_topology(void) +static void __init dump_numa_topology(void) { unsigned int node; unsigned int count; @@ -556,6 +529,7 @@ static void __init dump_numa_memory_topology(void) printk("-0x%lx", i); printk("\n"); } + return; } /* @@ -617,7 +591,7 @@ void __init do_init_bootmem(void) if (parse_numa_properties()) setup_nonnuma(); else - dump_numa_memory_topology(); + dump_numa_topology(); register_cpu_notifier(&ppc64_numa_nb); @@ -756,60 +730,3 @@ static int __init early_numa(char *p) return 0; } early_param("numa", early_numa); - -#ifdef CONFIG_MEMORY_HOTPLUG -/* - * Find the node associated with a hot added memory section. Section - * corresponds to a SPARSEMEM section, not an LMB. It is assumed that - * sections are fully contained within a single LMB. - */ -int hot_add_scn_to_nid(unsigned long scn_addr) -{ - struct device_node *memory = NULL; - nodemask_t nodes; - int numa_domain = 0; - - if (!numa_enabled || (min_common_depth < 0)) - return numa_domain; - - while ((memory = of_find_node_by_type(memory, "memory")) != NULL) { - unsigned long start, size; - int ranges; - unsigned int *memcell_buf; - unsigned int len; - - memcell_buf = (unsigned int *)get_property(memory, "reg", &len); - if (!memcell_buf || len <= 0) - continue; - - /* ranges in cell */ - ranges = (len >> 2) / (n_mem_addr_cells + n_mem_size_cells); -ha_new_range: - start = read_n_cells(n_mem_addr_cells, &memcell_buf); - size = read_n_cells(n_mem_size_cells, &memcell_buf); - numa_domain = of_node_numa_domain(memory); - - /* Domains not present at boot default to 0 */ - if (!node_online(numa_domain)) - numa_domain = any_online_node(NODE_MASK_ALL); - - if ((scn_addr >= start) && (scn_addr < (start + size))) { - of_node_put(memory); - goto got_numa_domain; - } - - if (--ranges) /* process all ranges in cell */ - goto ha_new_range; - } - BUG(); /* section address should be found above */ - - /* Temporary code to ensure that returned node is not empty */ -got_numa_domain: - nodes_setall(nodes); - while (NODE_DATA(numa_domain)->node_spanned_pages == 0) { - node_clear(numa_domain, nodes); - numa_domain = any_online_node(nodes); - } - return numa_domain; -} -#endif /* CONFIG_MEMORY_HOTPLUG */ diff --git a/trunk/arch/powerpc/mm/slb.c b/trunk/arch/powerpc/mm/slb.c index ffc8ed4de62d..60e852f2f8e5 100644 --- a/trunk/arch/powerpc/mm/slb.c +++ b/trunk/arch/powerpc/mm/slb.c @@ -75,7 +75,7 @@ static void slb_flush_and_rebolt(void) vflags = SLB_VSID_KERNEL | virtual_llp; ksp_esid_data = mk_esid_data(get_paca()->kstack, 2); - if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET) + if ((ksp_esid_data & ESID_MASK) == KERNELBASE) ksp_esid_data &= ~SLB_ESID_V; /* We need to do this all in asm, so we're sure we don't touch @@ -87,8 +87,8 @@ static void slb_flush_and_rebolt(void) /* Slot 2 - kernel stack */ "slbmte %2,%3\n" "isync" - :: "r"(mk_vsid_data(VMALLOC_START, vflags)), - "r"(mk_esid_data(VMALLOC_START, 1)), + :: "r"(mk_vsid_data(VMALLOCBASE, vflags)), + "r"(mk_esid_data(VMALLOCBASE, 1)), "r"(mk_vsid_data(ksp_esid_data, lflags)), "r"(ksp_esid_data) : "memory"); @@ -134,14 +134,14 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm) else unmapped_base = TASK_UNMAPPED_BASE_USER64; - if (is_kernel_addr(pc)) + if (pc >= KERNELBASE) return; slb_allocate(pc); if (GET_ESID(pc) == GET_ESID(stack)) return; - if (is_kernel_addr(stack)) + if (stack >= KERNELBASE) return; slb_allocate(stack); @@ -149,7 +149,7 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm) || (GET_ESID(stack) == GET_ESID(unmapped_base))) return; - if (is_kernel_addr(unmapped_base)) + if (unmapped_base >= KERNELBASE) return; slb_allocate(unmapped_base); } @@ -213,10 +213,10 @@ void slb_initialize(void) asm volatile("isync":::"memory"); asm volatile("slbmte %0,%0"::"r" (0) : "memory"); asm volatile("isync; slbia; isync":::"memory"); - create_slbe(PAGE_OFFSET, lflags, 0); + create_slbe(KERNELBASE, lflags, 0); /* VMALLOC space has 4K pages always for now */ - create_slbe(VMALLOC_START, vflags, 1); + create_slbe(VMALLOCBASE, vflags, 1); /* We don't bolt the stack for the time being - we're in boot, * so the stack is in the bolted segment. By the time it goes diff --git a/trunk/arch/powerpc/mm/slb_low.S b/trunk/arch/powerpc/mm/slb_low.S index d1acee38f163..950ffc5848c7 100644 --- a/trunk/arch/powerpc/mm/slb_low.S +++ b/trunk/arch/powerpc/mm/slb_low.S @@ -37,9 +37,9 @@ _GLOBAL(slb_allocate_realmode) srdi r9,r3,60 /* get region */ srdi r10,r3,28 /* get esid */ - cmpldi cr7,r9,0xc /* cmp PAGE_OFFSET for later use */ + cmpldi cr7,r9,0xc /* cmp KERNELBASE for later use */ - /* r3 = address, r10 = esid, cr7 = <> PAGE_OFFSET */ + /* r3 = address, r10 = esid, cr7 = <>KERNELBASE */ blt cr7,0f /* user or kernel? */ /* kernel address: proto-VSID = ESID */ @@ -166,7 +166,7 @@ _GLOBAL(slb_allocate_user) /* * Finish loading of an SLB entry and return * - * r3 = EA, r10 = proto-VSID, r11 = flags, clobbers r9, cr7 = <> PAGE_OFFSET + * r3 = EA, r10 = proto-VSID, r11 = flags, clobbers r9, cr7 = <>KERNELBASE */ slb_finish_load: ASM_VSID_SCRAMBLE(r10,r9) diff --git a/trunk/arch/powerpc/mm/stab.c b/trunk/arch/powerpc/mm/stab.c index 82e4951826bc..51e7951414e5 100644 --- a/trunk/arch/powerpc/mm/stab.c +++ b/trunk/arch/powerpc/mm/stab.c @@ -40,7 +40,7 @@ static int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid) unsigned long entry, group, old_esid, castout_entry, i; unsigned int global_entry; struct stab_entry *ste, *castout_ste; - unsigned long kernel_segment = (esid << SID_SHIFT) >= PAGE_OFFSET; + unsigned long kernel_segment = (esid << SID_SHIFT) >= KERNELBASE; vsid_data = vsid << STE_VSID_SHIFT; esid_data = esid << SID_SHIFT | STE_ESID_KP | STE_ESID_V; @@ -83,7 +83,7 @@ static int make_ste(unsigned long stab, unsigned long esid, unsigned long vsid) } /* Dont cast out the first kernel segment */ - if ((castout_ste->esid_data & ESID_MASK) != PAGE_OFFSET) + if ((castout_ste->esid_data & ESID_MASK) != KERNELBASE) break; castout_entry = (castout_entry + 1) & 0xf; @@ -122,7 +122,7 @@ static int __ste_allocate(unsigned long ea, struct mm_struct *mm) unsigned long offset; /* Kernel or user address? */ - if (is_kernel_addr(ea)) { + if (ea >= KERNELBASE) { vsid = get_kernel_vsid(ea); } else { if ((ea >= TASK_SIZE_USER64) || (! mm)) @@ -133,7 +133,7 @@ static int __ste_allocate(unsigned long ea, struct mm_struct *mm) stab_entry = make_ste(get_paca()->stab_addr, GET_ESID(ea), vsid); - if (!is_kernel_addr(ea)) { + if (ea < KERNELBASE) { offset = __get_cpu_var(stab_cache_ptr); if (offset < NR_STAB_CACHE_ENTRIES) __get_cpu_var(stab_cache[offset++]) = stab_entry; @@ -190,7 +190,7 @@ void switch_stab(struct task_struct *tsk, struct mm_struct *mm) entry++, ste++) { unsigned long ea; ea = ste->esid_data & ESID_MASK; - if (!is_kernel_addr(ea)) { + if (ea < KERNELBASE) { ste->esid_data = 0; } } @@ -251,7 +251,7 @@ void stabs_alloc(void) panic("Unable to allocate segment table for CPU %d.\n", cpu); - newstab = (unsigned long)__va(newstab); + newstab += KERNELBASE; memset((void *)newstab, 0, HW_PAGE_SIZE); @@ -270,11 +270,11 @@ void stabs_alloc(void) */ void stab_initialize(unsigned long stab) { - unsigned long vsid = get_kernel_vsid(PAGE_OFFSET); + unsigned long vsid = get_kernel_vsid(KERNELBASE); unsigned long stabreal; asm volatile("isync; slbia; isync":::"memory"); - make_ste(stab, GET_ESID(PAGE_OFFSET), vsid); + make_ste(stab, GET_ESID(KERNELBASE), vsid); /* Order update */ asm volatile("sync":::"memory"); diff --git a/trunk/arch/powerpc/mm/tlb_64.c b/trunk/arch/powerpc/mm/tlb_64.c index bb3afb6e6317..859d29a0cac5 100644 --- a/trunk/arch/powerpc/mm/tlb_64.c +++ b/trunk/arch/powerpc/mm/tlb_64.c @@ -168,7 +168,7 @@ void hpte_update(struct mm_struct *mm, unsigned long addr, batch->mm = mm; batch->psize = psize; } - if (!is_kernel_addr(addr)) { + if (addr < KERNELBASE) { vsid = get_vsid(mm->context.id, addr); WARN_ON(vsid == 0); } else diff --git a/trunk/arch/powerpc/oprofile/Makefile b/trunk/arch/powerpc/oprofile/Makefile index 554cd7c75321..0782d0cca89c 100644 --- a/trunk/arch/powerpc/oprofile/Makefile +++ b/trunk/arch/powerpc/oprofile/Makefile @@ -9,4 +9,3 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ oprofile-y := $(DRIVER_OBJS) common.o oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o -oprofile-$(CONFIG_PPC32) += op_model_7450.o diff --git a/trunk/arch/powerpc/oprofile/common.c b/trunk/arch/powerpc/oprofile/common.c index 71615eb70b2b..af2c05d20ba5 100644 --- a/trunk/arch/powerpc/oprofile/common.c +++ b/trunk/arch/powerpc/oprofile/common.c @@ -14,6 +14,9 @@ */ #include +#ifndef __powerpc64__ +#include +#endif /* ! __powerpc64__ */ #include #include #include @@ -28,6 +31,10 @@ static struct op_powerpc_model *model; static struct op_counter_config ctr[OP_MAX_COUNTER]; static struct op_system_config sys; +#ifndef __powerpc64__ +static char *cpu_type; +#endif /* ! __powerpc64__ */ + static void op_handle_interrupt(struct pt_regs *regs) { model->handle_interrupt(regs, ctr); @@ -46,7 +53,14 @@ static int op_powerpc_setup(void) model->reg_setup(ctr, &sys, model->num_counters); /* Configure the registers on all cpus. */ +#ifdef __powerpc64__ on_each_cpu(model->cpu_setup, NULL, 0, 1); +#else /* __powerpc64__ */ +#if 0 + /* FIXME: Make multi-cpu work */ + on_each_cpu(model->reg_setup, NULL, 0, 1); +#endif +#endif /* __powerpc64__ */ return 0; } @@ -81,7 +95,7 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) { int i; -#ifdef CONFIG_PPC64 +#ifdef __powerpc64__ /* * There is one mmcr0, mmcr1 and mmcra for setting the events for * all of the counters. @@ -89,7 +103,7 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0); oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1); oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra); -#endif +#endif /* __powerpc64__ */ for (i = 0; i < model->num_counters; ++i) { struct dentry *dir; @@ -101,68 +115,65 @@ static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); - +#ifdef __powerpc64__ /* - * Classic PowerPC doesn't support per-counter - * control like this, but the options are - * expected, so they remain. For Freescale - * Book-E style performance monitors, we do - * support them. + * We dont support per counter user/kernel selection, but + * we leave the entries because userspace expects them */ +#endif /* __powerpc64__ */ oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); +#ifndef __powerpc64__ + /* FIXME: Not sure if this is used */ +#endif /* ! __powerpc64__ */ oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask); } oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel); oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user); -#ifdef CONFIG_PPC64 +#ifdef __powerpc64__ oprofilefs_create_ulong(sb, root, "backtrace_spinlocks", &sys.backtrace_spinlocks); -#endif +#endif /* __powerpc64__ */ /* Default to tracing both kernel and user */ sys.enable_kernel = 1; sys.enable_user = 1; -#ifdef CONFIG_PPC64 +#ifdef __powerpc64__ /* Turn on backtracing through spinlocks by default */ sys.backtrace_spinlocks = 1; -#endif +#endif /* __powerpc64__ */ return 0; } int __init oprofile_arch_init(struct oprofile_operations *ops) { - if (!cur_cpu_spec->oprofile_cpu_type) - return -ENODEV; - - switch (cur_cpu_spec->oprofile_type) { -#ifdef CONFIG_PPC64 - case RS64: - model = &op_model_rs64; - break; - case POWER4: - model = &op_model_power4; - break; -#else - case G4: - model = &op_model_7450; - break; -#endif +#ifndef __powerpc64__ #ifdef CONFIG_FSL_BOOKE - case BOOKE: - model = &op_model_fsl_booke; - break; + model = &op_model_fsl_booke; +#else + return -ENODEV; #endif - default: - return -ENODEV; - } + cpu_type = kmalloc(32, GFP_KERNEL); + if (NULL == cpu_type) + return -ENOMEM; + + sprintf(cpu_type, "ppc/%s", cur_cpu_spec->cpu_name); + + model->num_counters = cur_cpu_spec->num_pmcs; + + ops->cpu_type = cpu_type; +#else /* __powerpc64__ */ + if (!cur_cpu_spec->oprofile_model || !cur_cpu_spec->oprofile_cpu_type) + return -ENODEV; + model = cur_cpu_spec->oprofile_model; model->num_counters = cur_cpu_spec->num_pmcs; ops->cpu_type = cur_cpu_spec->oprofile_cpu_type; +#endif /* __powerpc64__ */ ops->create_files = op_powerpc_create_files; ops->setup = op_powerpc_setup; ops->shutdown = op_powerpc_shutdown; @@ -177,4 +188,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) void oprofile_arch_exit(void) { +#ifndef __powerpc64__ + kfree(cpu_type); + cpu_type = NULL; +#endif /* ! __powerpc64__ */ } diff --git a/trunk/arch/powerpc/oprofile/op_model_7450.c b/trunk/arch/powerpc/oprofile/op_model_7450.c deleted file mode 100644 index 32abfdbb0eb1..000000000000 --- a/trunk/arch/powerpc/oprofile/op_model_7450.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * oprofile/op_model_7450.c - * - * Freescale 745x/744x oprofile support, based on fsl_booke support - * Copyright (C) 2004 Anton Blanchard , IBM - * - * Copyright (c) 2004 Freescale Semiconductor, Inc - * - * Author: Andy Fleming - * Maintainer: Kumar Gala - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static unsigned long reset_value[OP_MAX_COUNTER]; - -static int oprofile_running; -static u32 mmcr0_val, mmcr1_val, mmcr2_val; - -#define MMCR0_PMC1_SHIFT 6 -#define MMCR0_PMC2_SHIFT 0 -#define MMCR1_PMC3_SHIFT 27 -#define MMCR1_PMC4_SHIFT 22 -#define MMCR1_PMC5_SHIFT 17 -#define MMCR1_PMC6_SHIFT 11 - -#define mmcr0_event1(event) \ - ((event << MMCR0_PMC1_SHIFT) & MMCR0_PMC1SEL) -#define mmcr0_event2(event) \ - ((event << MMCR0_PMC2_SHIFT) & MMCR0_PMC2SEL) - -#define mmcr1_event3(event) \ - ((event << MMCR1_PMC3_SHIFT) & MMCR1_PMC3SEL) -#define mmcr1_event4(event) \ - ((event << MMCR1_PMC4_SHIFT) & MMCR1_PMC4SEL) -#define mmcr1_event5(event) \ - ((event << MMCR1_PMC5_SHIFT) & MMCR1_PMC5SEL) -#define mmcr1_event6(event) \ - ((event << MMCR1_PMC6_SHIFT) & MMCR1_PMC6SEL) - -#define MMCR0_INIT (MMCR0_FC | MMCR0_FCS | MMCR0_FCP | MMCR0_FCM1 | MMCR0_FCM0) - -/* Unfreezes the counters on this CPU, enables the interrupt, - * enables the counters to trigger the interrupt, and sets the - * counters to only count when the mark bit is not set. - */ -static void pmc_start_ctrs(void) -{ - u32 mmcr0 = mfspr(SPRN_MMCR0); - - mmcr0 &= ~(MMCR0_FC | MMCR0_FCM0); - mmcr0 |= (MMCR0_FCECE | MMCR0_PMC1CE | MMCR0_PMCnCE | MMCR0_PMXE); - - mtspr(SPRN_MMCR0, mmcr0); -} - -/* Disables the counters on this CPU, and freezes them */ -static void pmc_stop_ctrs(void) -{ - u32 mmcr0 = mfspr(SPRN_MMCR0); - - mmcr0 |= MMCR0_FC; - mmcr0 &= ~(MMCR0_FCECE | MMCR0_PMC1CE | MMCR0_PMCnCE | MMCR0_PMXE); - - mtspr(SPRN_MMCR0, mmcr0); -} - -/* Configures the counters on this CPU based on the global - * settings */ -static void fsl7450_cpu_setup(void *unused) -{ - /* freeze all counters */ - pmc_stop_ctrs(); - - mtspr(SPRN_MMCR0, mmcr0_val); - mtspr(SPRN_MMCR1, mmcr1_val); - mtspr(SPRN_MMCR2, mmcr2_val); -} - -#define NUM_CTRS 6 - -/* Configures the global settings for the countes on all CPUs. */ -static void fsl7450_reg_setup(struct op_counter_config *ctr, - struct op_system_config *sys, - int num_ctrs) -{ - int i; - - /* Our counters count up, and "count" refers to - * how much before the next interrupt, and we interrupt - * on overflow. So we calculate the starting value - * which will give us "count" until overflow. - * Then we set the events on the enabled counters */ - for (i = 0; i < NUM_CTRS; ++i) - reset_value[i] = 0x80000000UL - ctr[i].count; - - /* Set events for Counters 1 & 2 */ - mmcr0_val = MMCR0_INIT | mmcr0_event1(ctr[0].event) - | mmcr0_event2(ctr[1].event); - - /* Setup user/kernel bits */ - if (sys->enable_kernel) - mmcr0_val &= ~(MMCR0_FCS); - - if (sys->enable_user) - mmcr0_val &= ~(MMCR0_FCP); - - /* Set events for Counters 3-6 */ - mmcr1_val = mmcr1_event3(ctr[2].event) - | mmcr1_event4(ctr[3].event) - | mmcr1_event5(ctr[4].event) - | mmcr1_event6(ctr[5].event); - - mmcr2_val = 0; -} - -/* Sets the counters on this CPU to the chosen values, and starts them */ -static void fsl7450_start(struct op_counter_config *ctr) -{ - int i; - - mtmsr(mfmsr() | MSR_PMM); - - for (i = 0; i < NUM_CTRS; ++i) { - if (ctr[i].enabled) - ctr_write(i, reset_value[i]); - else - ctr_write(i, 0); - } - - /* Clear the freeze bit, and enable the interrupt. - * The counters won't actually start until the rfi clears - * the PMM bit */ - pmc_start_ctrs(); - - oprofile_running = 1; -} - -/* Stop the counters on this CPU */ -static void fsl7450_stop(void) -{ - /* freeze counters */ - pmc_stop_ctrs(); - - oprofile_running = 0; - - mb(); -} - - -/* Handle the interrupt on this CPU, and log a sample for each - * event that triggered the interrupt */ -static void fsl7450_handle_interrupt(struct pt_regs *regs, - struct op_counter_config *ctr) -{ - unsigned long pc; - int is_kernel; - int val; - int i; - - /* set the PMM bit (see comment below) */ - mtmsr(mfmsr() | MSR_PMM); - - pc = mfspr(SPRN_SIAR); - is_kernel = (pc >= KERNELBASE); - - for (i = 0; i < NUM_CTRS; ++i) { - val = ctr_read(i); - if (val < 0) { - if (oprofile_running && ctr[i].enabled) { - oprofile_add_pc(pc, is_kernel, i); - ctr_write(i, reset_value[i]); - } else { - ctr_write(i, 0); - } - } - } - - /* The freeze bit was set by the interrupt. */ - /* Clear the freeze bit, and reenable the interrupt. - * The counters won't actually start until the rfi clears - * the PMM bit */ - pmc_start_ctrs(); -} - -struct op_powerpc_model op_model_7450= { - .reg_setup = fsl7450_reg_setup, - .cpu_setup = fsl7450_cpu_setup, - .start = fsl7450_start, - .stop = fsl7450_stop, - .handle_interrupt = fsl7450_handle_interrupt, -}; diff --git a/trunk/arch/powerpc/oprofile/op_model_power4.c b/trunk/arch/powerpc/oprofile/op_model_power4.c index 659a021da0c7..a3401b46f3ba 100644 --- a/trunk/arch/powerpc/oprofile/op_model_power4.c +++ b/trunk/arch/powerpc/oprofile/op_model_power4.c @@ -252,7 +252,7 @@ static unsigned long get_pc(struct pt_regs *regs) return (unsigned long)__va(pc); /* Not sure where we were */ - if (!is_kernel_addr(pc)) + if (pc < KERNELBASE) /* function descriptor madness */ return *((unsigned long *)kernel_unknown_bucket); @@ -264,7 +264,7 @@ static int get_kernel(unsigned long pc) int is_kernel; if (!mmcra_has_sihv) { - is_kernel = is_kernel_addr(pc); + is_kernel = (pc >= KERNELBASE); } else { unsigned long mmcra = mfspr(SPRN_MMCRA); is_kernel = ((mmcra & MMCRA_SIPR) == 0); diff --git a/trunk/arch/powerpc/oprofile/op_model_rs64.c b/trunk/arch/powerpc/oprofile/op_model_rs64.c index 5c909ee609fe..e010b85996e8 100644 --- a/trunk/arch/powerpc/oprofile/op_model_rs64.c +++ b/trunk/arch/powerpc/oprofile/op_model_rs64.c @@ -178,6 +178,7 @@ static void rs64_handle_interrupt(struct pt_regs *regs, int val; int i; unsigned long pc = mfspr(SPRN_SIAR); + int is_kernel = (pc >= KERNELBASE); /* set the PMM bit (see comment below) */ mtmsrd(mfmsr() | MSR_PMM); @@ -186,7 +187,7 @@ static void rs64_handle_interrupt(struct pt_regs *regs, val = ctr_read(i); if (val < 0) { if (ctr[i].enabled) { - oprofile_add_pc(pc, is_kernel_addr(pc), i); + oprofile_add_pc(pc, is_kernel, i); ctr_write(i, reset_value[i]); } else { ctr_write(i, 0); diff --git a/trunk/arch/powerpc/platforms/cell/Kconfig b/trunk/arch/powerpc/platforms/cell/Kconfig deleted file mode 100644 index 3157071e241c..000000000000 --- a/trunk/arch/powerpc/platforms/cell/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -menu "Cell Broadband Engine options" - depends on PPC_CELL - -config SPU_FS - tristate "SPU file system" - default m - depends on PPC_CELL - help - The SPU file system is used to access Synergistic Processing - Units on machines implementing the Broadband Processor - Architecture. - -endmenu diff --git a/trunk/arch/powerpc/platforms/cell/Makefile b/trunk/arch/powerpc/platforms/cell/Makefile index 16031b565be4..55e094b96bc0 100644 --- a/trunk/arch/powerpc/platforms/cell/Makefile +++ b/trunk/arch/powerpc/platforms/cell/Makefile @@ -1,10 +1,2 @@ obj-y += interrupt.o iommu.o setup.o spider-pic.o -obj-y += pervasive.o - obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_SPU_FS) += spufs/ spu-base.o - -spu-base-y += spu_base.o spu_priv1.o - -builtin-spufs-$(CONFIG_SPU_FS) += spu_syscalls.o -obj-y += $(builtin-spufs-m) diff --git a/trunk/arch/powerpc/platforms/cell/interrupt.c b/trunk/arch/powerpc/platforms/cell/interrupt.c index 63aa52acf441..7fbe78a9327d 100644 --- a/trunk/arch/powerpc/platforms/cell/interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/interrupt.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -56,7 +55,6 @@ struct iic_regs { struct iic { struct iic_regs __iomem *regs; - u8 target_id; }; static DEFINE_PER_CPU(struct iic, iic); @@ -174,11 +172,12 @@ int iic_get_irq(struct pt_regs *regs) return irq; } -static int setup_iic(int cpu, struct iic *iic) +static struct iic_regs __iomem *find_iic(int cpu) { struct device_node *np; int nodeid = cpu / 2; unsigned long regs; + struct iic_regs __iomem *iic_regs; for (np = of_find_node_by_type(NULL, "cpu"); np; @@ -189,23 +188,20 @@ static int setup_iic(int cpu, struct iic *iic) if (!np) { printk(KERN_WARNING "IIC: CPU %d not found\n", cpu); - iic->regs = NULL; - iic->target_id = 0xff; - return -ENODEV; + iic_regs = NULL; + } else { + regs = *(long *)get_property(np, "iic", NULL); + + /* hack until we have decided on the devtree info */ + regs += 0x400; + if (cpu & 1) + regs += 0x20; + + printk(KERN_DEBUG "IIC for CPU %d at %lx\n", cpu, regs); + iic_regs = __ioremap(regs, sizeof(struct iic_regs), + _PAGE_NO_CACHE); } - - regs = *(long *)get_property(np, "iic", NULL); - - /* hack until we have decided on the devtree info */ - regs += 0x400; - if (cpu & 1) - regs += 0x20; - - printk(KERN_DEBUG "IIC for CPU %d at %lx\n", cpu, regs); - iic->regs = __ioremap(regs, sizeof(struct iic_regs), - _PAGE_NO_CACHE); - iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe); - return 0; + return iic_regs; } #ifdef CONFIG_SMP @@ -231,12 +227,6 @@ void iic_cause_IPI(int cpu, int mesg) out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4); } -u8 iic_get_target_id(int cpu) -{ - return per_cpu(iic, cpu).target_id; -} -EXPORT_SYMBOL_GPL(iic_get_target_id); - static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs) { smp_message_recv(iic_irq_to_ipi(irq), regs); @@ -286,7 +276,7 @@ void iic_init_IRQ(void) irq_offset = 0; for_each_cpu(cpu) { iic = &per_cpu(iic, cpu); - setup_iic(cpu, iic); + iic->regs = find_iic(cpu); if (iic->regs) out_be64(&iic->regs->prio, 0xff); } diff --git a/trunk/arch/powerpc/platforms/cell/interrupt.h b/trunk/arch/powerpc/platforms/cell/interrupt.h index a14bd38791c0..37d58e6fd0c6 100644 --- a/trunk/arch/powerpc/platforms/cell/interrupt.h +++ b/trunk/arch/powerpc/platforms/cell/interrupt.h @@ -54,7 +54,6 @@ extern void iic_setup_cpu(void); extern void iic_local_enable(void); extern void iic_local_disable(void); -extern u8 iic_get_target_id(int cpu); extern void spider_init_IRQ(void); extern int spider_get_irq(unsigned long int_pending); diff --git a/trunk/arch/powerpc/platforms/cell/iommu.c b/trunk/arch/powerpc/platforms/cell/iommu.c index 46e7cb9c3e64..74f999b4ac9e 100644 --- a/trunk/arch/powerpc/platforms/cell/iommu.c +++ b/trunk/arch/powerpc/platforms/cell/iommu.c @@ -29,8 +29,6 @@ #include #include #include -#include -#include #include #include @@ -42,7 +40,6 @@ #include #include #include -#include #include "iommu.h" @@ -223,6 +220,8 @@ set_iopt_cache(void __iomem *base, unsigned long index, { unsigned long __iomem *tags = base + IOC_PT_CACHE_DIR; unsigned long __iomem *p = base + IOC_PT_CACHE_REG; + pr_debug("iopt %02lx was v%016lx/t%016lx, store v%016lx/t%016lx\n", + index, get_iopt_cache(base, index, &oldtag), oldtag, val, tag); out_be64(p, val); out_be64(&tags[index], tag); @@ -249,176 +248,67 @@ set_iocmd_config(void __iomem *base) out_be64(p, conf | IOCMD_CONF_TE); } -static void enable_mapping(void __iomem *base, void __iomem *mmio_base) +/* FIXME: get these from the device tree */ +#define ioc_base 0x20000511000ull +#define ioc_mmio_base 0x20000510000ull +#define ioid 0x48a +#define iopt_phys_offset (- 0x20000000) /* We have a 512MB offset from the SB */ +#define io_page_size 0x1000000 + +static unsigned long map_iopt_entry(unsigned long address) { - set_iocmd_config(base); - set_iost_origin(mmio_base); + switch (address >> 20) { + case 0x600: + address = 0x24020000000ull; /* spider i/o */ + break; + default: + address += iopt_phys_offset; + break; + } + + return get_iopt_entry(address, ioid, IOPT_PROT_RW); } -static void iommu_dev_setup_null(struct pci_dev *d) { } static void iommu_bus_setup_null(struct pci_bus *b) { } - -struct cell_iommu { - unsigned long base; - unsigned long mmio_base; - void __iomem *mapped_base; - void __iomem *mapped_mmio_base; -}; - -static struct cell_iommu cell_iommus[NR_CPUS]; +static void iommu_dev_setup_null(struct pci_dev *d) { } /* initialize the iommu to support a simple linear mapping * for each DMA window used by any device. For now, we * happen to know that there is only one DMA window in use, * starting at iopt_phys_offset. */ -static void cell_do_map_iommu(struct cell_iommu *iommu, - unsigned int ioid, - unsigned long map_start, - unsigned long map_size) +static void cell_map_iommu(void) { - unsigned long io_address, real_address; - void __iomem *ioc_base, *ioc_mmio_base; + unsigned long address; + void __iomem *base; ioste ioste; unsigned long index; - /* we pretend the io page table was at a very high address */ - const unsigned long fake_iopt = 0x10000000000ul; - const unsigned long io_page_size = 0x1000000; /* use 16M pages */ - const unsigned long io_segment_size = 0x10000000; /* 256M */ - - ioc_base = iommu->mapped_base; - ioc_mmio_base = iommu->mapped_mmio_base; - - for (real_address = 0, io_address = 0; - io_address <= map_start + map_size; - real_address += io_page_size, io_address += io_page_size) { - ioste = get_iost_entry(fake_iopt, io_address, io_page_size); - if ((real_address % io_segment_size) == 0) /* segment start */ - set_iost_cache(ioc_mmio_base, - io_address >> 28, ioste); - index = get_ioc_hash_1way(ioste, io_address); - pr_debug("addr %08lx, index %02lx, ioste %016lx\n", - io_address, index, ioste.val); - set_iopt_cache(ioc_mmio_base, - get_ioc_hash_1way(ioste, io_address), - get_ioc_tag(ioste, io_address), - get_iopt_entry(real_address-map_start, ioid, IOPT_PROT_RW)); - } -} - -static void iommu_devnode_setup(struct device_node *d) -{ - unsigned int *ioid; - unsigned long *dma_window, map_start, map_size, token; - struct cell_iommu *iommu; - - ioid = (unsigned int *)get_property(d, "ioid", NULL); - if (!ioid) - pr_debug("No ioid entry found !\n"); - - dma_window = (unsigned long *)get_property(d, "ibm,dma-window", NULL); - if (!dma_window) - pr_debug("No ibm,dma-window entry found !\n"); - - map_start = dma_window[1]; - map_size = dma_window[2]; - token = dma_window[0] >> 32; - - iommu = &cell_iommus[token]; - - cell_do_map_iommu(iommu, *ioid, map_start, map_size); -} - -static void iommu_bus_setup(struct pci_bus *b) -{ - struct device_node *d = (struct device_node *)b->sysdata; - iommu_devnode_setup(d); -} - - -static int cell_map_iommu_hardcoded(int num_nodes) -{ - struct cell_iommu *iommu = NULL; - - pr_debug("%s(%d): Using hardcoded defaults\n", __FUNCTION__, __LINE__); - - /* node 0 */ - iommu = &cell_iommus[0]; - iommu->mapped_base = __ioremap(0x20000511000, 0x1000, _PAGE_NO_CACHE); - iommu->mapped_mmio_base = __ioremap(0x20000510000, 0x1000, _PAGE_NO_CACHE); - - enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); - - cell_do_map_iommu(iommu, 0x048a, - 0x20000000ul,0x20000000ul); - - if (num_nodes < 2) - return 0; - - /* node 1 */ - iommu = &cell_iommus[1]; - iommu->mapped_base = __ioremap(0x30000511000, 0x1000, _PAGE_NO_CACHE); - iommu->mapped_mmio_base = __ioremap(0x30000510000, 0x1000, _PAGE_NO_CACHE); - - enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); - - cell_do_map_iommu(iommu, 0x048a, - 0x20000000,0x20000000ul); - - return 0; -} - - -static int cell_map_iommu(void) -{ - unsigned int num_nodes = 0, *node_id; - unsigned long *base, *mmio_base; - struct device_node *dn; - struct cell_iommu *iommu = NULL; - - /* determine number of nodes (=iommus) */ - pr_debug("%s(%d): determining number of nodes...", __FUNCTION__, __LINE__); - for(dn = of_find_node_by_type(NULL, "cpu"); - dn; - dn = of_find_node_by_type(dn, "cpu")) { - node_id = (unsigned int *)get_property(dn, "node-id", NULL); - - if (num_nodes < *node_id) - num_nodes = *node_id; - } - - num_nodes++; - pr_debug("%i found.\n", num_nodes); - - /* map the iommu registers for each node */ - pr_debug("%s(%d): Looping through nodes\n", __FUNCTION__, __LINE__); - for(dn = of_find_node_by_type(NULL, "cpu"); - dn; - dn = of_find_node_by_type(dn, "cpu")) { - - node_id = (unsigned int *)get_property(dn, "node-id", NULL); - base = (unsigned long *)get_property(dn, "ioc-cache", NULL); - mmio_base = (unsigned long *)get_property(dn, "ioc-translation", NULL); - - if (!base || !mmio_base || !node_id) - return cell_map_iommu_hardcoded(num_nodes); - - iommu = &cell_iommus[*node_id]; - iommu->base = *base; - iommu->mmio_base = *mmio_base; + base = __ioremap(ioc_base, 0x1000, _PAGE_NO_CACHE); + pr_debug("%lx mapped to %p\n", ioc_base, base); + set_iocmd_config(base); + iounmap(base); - iommu->mapped_base = __ioremap(*base, 0x1000, _PAGE_NO_CACHE); - iommu->mapped_mmio_base = __ioremap(*mmio_base, 0x1000, _PAGE_NO_CACHE); + base = __ioremap(ioc_mmio_base, 0x1000, _PAGE_NO_CACHE); + pr_debug("%lx mapped to %p\n", ioc_mmio_base, base); - enable_mapping(iommu->mapped_base, - iommu->mapped_mmio_base); + set_iost_origin(base); - /* everything else will be done in iommu_bus_setup */ + for (address = 0; address < 0x100000000ul; address += io_page_size) { + ioste = get_iost_entry(0x10000000000ul, address, io_page_size); + if ((address & 0xfffffff) == 0) /* segment start */ + set_iost_cache(base, address >> 28, ioste); + index = get_ioc_hash_1way(ioste, address); + pr_debug("addr %08lx, index %02lx, ioste %016lx\n", + address, index, ioste.val); + set_iopt_cache(base, + get_ioc_hash_1way(ioste, address), + get_ioc_tag(ioste, address), + map_iopt_entry(address)); } - - return 1; + iounmap(base); } + static void *cell_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { @@ -475,28 +365,11 @@ static int cell_dma_supported(struct device *dev, u64 mask) void cell_init_iommu(void) { - int setup_bus = 0; - - if (of_find_node_by_path("/mambo")) { - pr_info("Not using iommu on systemsim\n"); - } else { - - if (!(of_chosen && - get_property(of_chosen, "linux,iommu-off", NULL))) - setup_bus = cell_map_iommu(); - - if (setup_bus) { - pr_debug("%s: IOMMU mapping activated\n", __FUNCTION__); - ppc_md.iommu_dev_setup = iommu_dev_setup_null; - ppc_md.iommu_bus_setup = iommu_bus_setup; - } else { - pr_debug("%s: IOMMU mapping activated, " - "no device action necessary\n", __FUNCTION__); - /* Direct I/O, IOMMU off */ - ppc_md.iommu_dev_setup = iommu_dev_setup_null; - ppc_md.iommu_bus_setup = iommu_bus_setup_null; - } - } + cell_map_iommu(); + + /* Direct I/O, IOMMU off */ + ppc_md.iommu_dev_setup = iommu_dev_setup_null; + ppc_md.iommu_bus_setup = iommu_bus_setup_null; pci_dma_ops.alloc_coherent = cell_alloc_coherent; pci_dma_ops.free_coherent = cell_free_coherent; diff --git a/trunk/arch/powerpc/platforms/cell/pervasive.c b/trunk/arch/powerpc/platforms/cell/pervasive.c deleted file mode 100644 index 85152544c153..000000000000 --- a/trunk/arch/powerpc/platforms/cell/pervasive.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * CBE Pervasive Monitor and Debug - * - * (C) Copyright IBM Corporation 2005 - * - * Authors: Maximino Aguilar (maguilar@us.ibm.com) - * Michael N. Day (mnday@us.ibm.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, 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. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "pervasive.h" - -static DEFINE_SPINLOCK(cbe_pervasive_lock); -struct cbe_pervasive { - struct pmd_regs __iomem *regs; - unsigned int thread; -}; - -/* can't use per_cpu from setup_arch */ -static struct cbe_pervasive cbe_pervasive[NR_CPUS]; - -static void __init cbe_enable_pause_zero(void) -{ - unsigned long thread_switch_control; - unsigned long temp_register; - struct cbe_pervasive *p; - int thread; - - spin_lock_irq(&cbe_pervasive_lock); - p = &cbe_pervasive[smp_processor_id()]; - - if (!cbe_pervasive->regs) - goto out; - - pr_debug("Power Management: CPU %d\n", smp_processor_id()); - - /* Enable Pause(0) control bit */ - temp_register = in_be64(&p->regs->pm_control); - - out_be64(&p->regs->pm_control, - temp_register|PMD_PAUSE_ZERO_CONTROL); - - /* Enable DEC and EE interrupt request */ - thread_switch_control = mfspr(SPRN_TSC_CELL); - thread_switch_control |= TSC_CELL_EE_ENABLE | TSC_CELL_EE_BOOST; - - switch ((mfspr(SPRN_CTRLF) & CTRL_CT)) { - case CTRL_CT0: - thread_switch_control |= TSC_CELL_DEC_ENABLE_0; - thread = 0; - break; - case CTRL_CT1: - thread_switch_control |= TSC_CELL_DEC_ENABLE_1; - thread = 1; - break; - default: - printk(KERN_WARNING "%s: unknown configuration\n", - __FUNCTION__); - thread = -1; - break; - } - - if (p->thread != thread) - printk(KERN_WARNING "%s: device tree inconsistant, " - "cpu %i: %d/%d\n", __FUNCTION__, - smp_processor_id(), - p->thread, thread); - - mtspr(SPRN_TSC_CELL, thread_switch_control); - -out: - spin_unlock_irq(&cbe_pervasive_lock); -} - -static void cbe_idle(void) -{ - unsigned long ctrl; - - cbe_enable_pause_zero(); - - while (1) { - if (!need_resched()) { - local_irq_disable(); - while (!need_resched()) { - /* go into low thread priority */ - HMT_low(); - - /* - * atomically disable thread execution - * and runlatch. - * External and Decrementer exceptions - * are still handled when the thread - * is disabled but now enter in - * cbe_system_reset_exception() - */ - ctrl = mfspr(SPRN_CTRLF); - ctrl &= ~(CTRL_RUNLATCH | CTRL_TE); - mtspr(SPRN_CTRLT, ctrl); - } - /* restore thread prio */ - HMT_medium(); - local_irq_enable(); - } - - /* - * turn runlatch on again before scheduling the - * process we just woke up - */ - ppc64_runlatch_on(); - - preempt_enable_no_resched(); - schedule(); - preempt_disable(); - } -} - -int cbe_system_reset_exception(struct pt_regs *regs) -{ - switch (regs->msr & SRR1_WAKEMASK) { - case SRR1_WAKEEE: - do_IRQ(regs); - break; - case SRR1_WAKEDEC: - timer_interrupt(regs); - break; - case SRR1_WAKEMT: - /* no action required */ - break; - default: - /* do system reset */ - return 0; - } - /* everything handled */ - return 1; -} - -static int __init cbe_find_pmd_mmio(int cpu, struct cbe_pervasive *p) -{ - struct device_node *node; - unsigned int *int_servers; - char *addr; - unsigned long real_address; - unsigned int size; - - struct pmd_regs __iomem *pmd_mmio_area; - int hardid, thread; - int proplen; - - pmd_mmio_area = NULL; - hardid = get_hard_smp_processor_id(cpu); - for (node = NULL; (node = of_find_node_by_type(node, "cpu"));) { - int_servers = (void *) get_property(node, - "ibm,ppc-interrupt-server#s", &proplen); - if (!int_servers) { - printk(KERN_WARNING "%s misses " - "ibm,ppc-interrupt-server#s property", - node->full_name); - continue; - } - for (thread = 0; thread < proplen / sizeof (int); thread++) { - if (hardid == int_servers[thread]) { - addr = get_property(node, "pervasive", NULL); - goto found; - } - } - } - - printk(KERN_WARNING "%s: CPU %d not found\n", __FUNCTION__, cpu); - return -EINVAL; - -found: - real_address = *(unsigned long*) addr; - addr += sizeof (unsigned long); - size = *(unsigned int*) addr; - - pr_debug("pervasive area for CPU %d at %lx, size %x\n", - cpu, real_address, size); - p->regs = __ioremap(real_address, size, _PAGE_NO_CACHE); - p->thread = thread; - return 0; -} - -void __init cell_pervasive_init(void) -{ - struct cbe_pervasive *p; - int cpu; - int ret; - - if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) - return; - - for_each_cpu(cpu) { - p = &cbe_pervasive[cpu]; - ret = cbe_find_pmd_mmio(cpu, p); - if (ret) - return; - } - - ppc_md.idle_loop = cbe_idle; - ppc_md.system_reset_exception = cbe_system_reset_exception; -} diff --git a/trunk/arch/powerpc/platforms/cell/pervasive.h b/trunk/arch/powerpc/platforms/cell/pervasive.h deleted file mode 100644 index da1fb85ca3e8..000000000000 --- a/trunk/arch/powerpc/platforms/cell/pervasive.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Cell Pervasive Monitor and Debug interface and HW structures - * - * (C) Copyright IBM Corporation 2005 - * - * Authors: Maximino Aguilar (maguilar@us.ibm.com) - * David J. Erb (djerb@us.ibm.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, 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. - */ - - -#ifndef PERVASIVE_H -#define PERVASIVE_H - -struct pmd_regs { - u8 pad_0x0000_0x0800[0x0800 - 0x0000]; /* 0x0000 */ - - /* Thermal Sensor Registers */ - u64 ts_ctsr1; /* 0x0800 */ - u64 ts_ctsr2; /* 0x0808 */ - u64 ts_mtsr1; /* 0x0810 */ - u64 ts_mtsr2; /* 0x0818 */ - u64 ts_itr1; /* 0x0820 */ - u64 ts_itr2; /* 0x0828 */ - u64 ts_gitr; /* 0x0830 */ - u64 ts_isr; /* 0x0838 */ - u64 ts_imr; /* 0x0840 */ - u64 tm_cr1; /* 0x0848 */ - u64 tm_cr2; /* 0x0850 */ - u64 tm_simr; /* 0x0858 */ - u64 tm_tpr; /* 0x0860 */ - u64 tm_str1; /* 0x0868 */ - u64 tm_str2; /* 0x0870 */ - u64 tm_tsr; /* 0x0878 */ - - /* Power Management */ - u64 pm_control; /* 0x0880 */ -#define PMD_PAUSE_ZERO_CONTROL 0x10000 - u64 pm_status; /* 0x0888 */ - - /* Time Base Register */ - u64 tbr; /* 0x0890 */ - - u8 pad_0x0898_0x1000 [0x1000 - 0x0898]; /* 0x0898 */ -}; - -void __init cell_pervasive_init(void); - -#endif diff --git a/trunk/arch/powerpc/platforms/cell/setup.c b/trunk/arch/powerpc/platforms/cell/setup.c index 18e25e65c04b..9a495634d0c2 100644 --- a/trunk/arch/powerpc/platforms/cell/setup.c +++ b/trunk/arch/powerpc/platforms/cell/setup.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -49,7 +48,6 @@ #include "interrupt.h" #include "iommu.h" -#include "pervasive.h" #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) @@ -69,77 +67,6 @@ void cell_show_cpuinfo(struct seq_file *m) of_node_put(root); } -#ifdef CONFIG_SPARSEMEM -static int __init find_spu_node_id(struct device_node *spe) -{ - unsigned int *id; -#ifdef CONFIG_NUMA - struct device_node *cpu; - cpu = spe->parent->parent; - id = (unsigned int *)get_property(cpu, "node-id", NULL); -#else - id = NULL; -#endif - return id ? *id : 0; -} - -static void __init cell_spuprop_present(struct device_node *spe, - const char *prop, int early) -{ - struct address_prop { - unsigned long address; - unsigned int len; - } __attribute__((packed)) *p; - int proplen; - - unsigned long start_pfn, end_pfn, pfn; - int node_id; - - p = (void*)get_property(spe, prop, &proplen); - WARN_ON(proplen != sizeof (*p)); - - node_id = find_spu_node_id(spe); - - start_pfn = p->address >> PAGE_SHIFT; - end_pfn = (p->address + p->len + PAGE_SIZE - 1) >> PAGE_SHIFT; - - /* We need to call memory_present *before* the call to sparse_init, - but we can initialize the page structs only *after* that call. - Thus, we're being called twice. */ - if (early) - memory_present(node_id, start_pfn, end_pfn); - else { - /* As the pages backing SPU LS and I/O are outside the range - of regular memory, their page structs were not initialized - by free_area_init. Do it here instead. */ - for (pfn = start_pfn; pfn < end_pfn; pfn++) { - struct page *page = pfn_to_page(pfn); - set_page_links(page, ZONE_DMA, node_id, pfn); - set_page_count(page, 1); - reset_page_mapcount(page); - SetPageReserved(page); - INIT_LIST_HEAD(&page->lru); - } - } -} - -static void __init cell_spumem_init(int early) -{ - struct device_node *node; - for (node = of_find_node_by_type(NULL, "spe"); - node; node = of_find_node_by_type(node, "spe")) { - cell_spuprop_present(node, "local-store", early); - cell_spuprop_present(node, "problem", early); - cell_spuprop_present(node, "priv1", early); - cell_spuprop_present(node, "priv2", early); - } -} -#else -static void __init cell_spumem_init(int early) -{ -} -#endif - static void cell_progress(char *s, unsigned short hex) { printk("*** %04x : %s\n", hex, s ? s : ""); @@ -166,14 +93,11 @@ static void __init cell_setup_arch(void) init_pci_config_tokens(); find_and_init_phbs(); spider_init_IRQ(); - cell_pervasive_init(); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; #endif mmio_nvram_init(); - - cell_spumem_init(0); } /* @@ -189,8 +113,6 @@ static void __init cell_init_early(void) ppc64_interrupt_controller = IC_CELL_PIC; - cell_spumem_init(1); - DBG(" <- cell_init_early()\n"); } @@ -203,15 +125,6 @@ static int __init cell_probe(int platform) return 1; } -/* - * Cell has no legacy IO; anything calling this function has to - * fail or bad things will happen - */ -static int cell_check_legacy_ioport(unsigned int baseport) -{ - return -ENODEV; -} - struct machdep_calls __initdata cell_md = { .probe = cell_probe, .setup_arch = cell_setup_arch, @@ -224,11 +137,5 @@ struct machdep_calls __initdata cell_md = { .get_rtc_time = rtas_get_rtc_time, .set_rtc_time = rtas_set_rtc_time, .calibrate_decr = generic_calibrate_decr, - .check_legacy_ioport = cell_check_legacy_ioport, .progress = cell_progress, -#ifdef CONFIG_KEXEC - .machine_kexec = default_machine_kexec, - .machine_kexec_prepare = default_machine_kexec_prepare, - .machine_crash_shutdown = default_machine_crash_shutdown, -#endif }; diff --git a/trunk/arch/powerpc/platforms/cell/spu_base.c b/trunk/arch/powerpc/platforms/cell/spu_base.c deleted file mode 100644 index d75ae03df686..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spu_base.c +++ /dev/null @@ -1,711 +0,0 @@ -/* - * Low-level SPU handling - * - * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 - * - * Author: Arnd Bergmann - * - * 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, 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. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "interrupt.h" - -static int __spu_trap_invalid_dma(struct spu *spu) -{ - pr_debug("%s\n", __FUNCTION__); - force_sig(SIGBUS, /* info, */ current); - return 0; -} - -static int __spu_trap_dma_align(struct spu *spu) -{ - pr_debug("%s\n", __FUNCTION__); - force_sig(SIGBUS, /* info, */ current); - return 0; -} - -static int __spu_trap_error(struct spu *spu) -{ - pr_debug("%s\n", __FUNCTION__); - force_sig(SIGILL, /* info, */ current); - return 0; -} - -static void spu_restart_dma(struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags)) - out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); -} - -static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - struct mm_struct *mm = spu->mm; - u64 esid, vsid; - - pr_debug("%s\n", __FUNCTION__); - - if (test_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags)) { - /* SLBs are pre-loaded for context switch, so - * we should never get here! - */ - printk("%s: invalid access during switch!\n", __func__); - return 1; - } - if (!mm || (REGION_ID(ea) != USER_REGION_ID)) { - /* Future: support kernel segments so that drivers - * can use SPUs. - */ - pr_debug("invalid region access at %016lx\n", ea); - return 1; - } - - esid = (ea & ESID_MASK) | SLB_ESID_V; - vsid = (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT) | SLB_VSID_USER; - if (in_hugepage_area(mm->context, ea)) - vsid |= SLB_VSID_L; - - out_be64(&priv2->slb_index_W, spu->slb_replace); - out_be64(&priv2->slb_vsid_RW, vsid); - out_be64(&priv2->slb_esid_RW, esid); - - spu->slb_replace++; - if (spu->slb_replace >= 8) - spu->slb_replace = 0; - - spu_restart_dma(spu); - - return 0; -} - -extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX -static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) -{ - pr_debug("%s\n", __FUNCTION__); - - /* Handle kernel space hash faults immediately. - User hash faults need to be deferred to process context. */ - if ((dsisr & MFC_DSISR_PTE_NOT_FOUND) - && REGION_ID(ea) != USER_REGION_ID - && hash_page(ea, _PAGE_PRESENT, 0x300) == 0) { - spu_restart_dma(spu); - return 0; - } - - if (test_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags)) { - printk("%s: invalid access during switch!\n", __func__); - return 1; - } - - spu->dar = ea; - spu->dsisr = dsisr; - mb(); - if (spu->stop_callback) - spu->stop_callback(spu); - return 0; -} - -static int __spu_trap_mailbox(struct spu *spu) -{ - if (spu->ibox_callback) - spu->ibox_callback(spu); - - /* atomically disable SPU mailbox interrupts */ - spin_lock(&spu->register_lock); - spu_int_mask_and(spu, 2, ~0x1); - spin_unlock(&spu->register_lock); - return 0; -} - -static int __spu_trap_stop(struct spu *spu) -{ - pr_debug("%s\n", __FUNCTION__); - spu->stop_code = in_be32(&spu->problem->spu_status_R); - if (spu->stop_callback) - spu->stop_callback(spu); - return 0; -} - -static int __spu_trap_halt(struct spu *spu) -{ - pr_debug("%s\n", __FUNCTION__); - spu->stop_code = in_be32(&spu->problem->spu_status_R); - if (spu->stop_callback) - spu->stop_callback(spu); - return 0; -} - -static int __spu_trap_tag_group(struct spu *spu) -{ - pr_debug("%s\n", __FUNCTION__); - /* wake_up(&spu->dma_wq); */ - return 0; -} - -static int __spu_trap_spubox(struct spu *spu) -{ - if (spu->wbox_callback) - spu->wbox_callback(spu); - - /* atomically disable SPU mailbox interrupts */ - spin_lock(&spu->register_lock); - spu_int_mask_and(spu, 2, ~0x10); - spin_unlock(&spu->register_lock); - return 0; -} - -static irqreturn_t -spu_irq_class_0(int irq, void *data, struct pt_regs *regs) -{ - struct spu *spu; - - spu = data; - spu->class_0_pending = 1; - if (spu->stop_callback) - spu->stop_callback(spu); - - return IRQ_HANDLED; -} - -int -spu_irq_class_0_bottom(struct spu *spu) -{ - unsigned long stat, mask; - - spu->class_0_pending = 0; - - mask = spu_int_mask_get(spu, 0); - stat = spu_int_stat_get(spu, 0); - - stat &= mask; - - if (stat & 1) /* invalid MFC DMA */ - __spu_trap_invalid_dma(spu); - - if (stat & 2) /* invalid DMA alignment */ - __spu_trap_dma_align(spu); - - if (stat & 4) /* error on SPU */ - __spu_trap_error(spu); - - spu_int_stat_clear(spu, 0, stat); - - return (stat & 0x7) ? -EIO : 0; -} -EXPORT_SYMBOL_GPL(spu_irq_class_0_bottom); - -static irqreturn_t -spu_irq_class_1(int irq, void *data, struct pt_regs *regs) -{ - struct spu *spu; - unsigned long stat, mask, dar, dsisr; - - spu = data; - - /* atomically read & clear class1 status. */ - spin_lock(&spu->register_lock); - mask = spu_int_mask_get(spu, 1); - stat = spu_int_stat_get(spu, 1) & mask; - dar = spu_mfc_dar_get(spu); - dsisr = spu_mfc_dsisr_get(spu); - if (stat & 2) /* mapping fault */ - spu_mfc_dsisr_set(spu, 0ul); - spu_int_stat_clear(spu, 1, stat); - spin_unlock(&spu->register_lock); - - if (stat & 1) /* segment fault */ - __spu_trap_data_seg(spu, dar); - - if (stat & 2) { /* mapping fault */ - __spu_trap_data_map(spu, dar, dsisr); - } - - if (stat & 4) /* ls compare & suspend on get */ - ; - - if (stat & 8) /* ls compare & suspend on put */ - ; - - return stat ? IRQ_HANDLED : IRQ_NONE; -} -EXPORT_SYMBOL_GPL(spu_irq_class_1_bottom); - -static irqreturn_t -spu_irq_class_2(int irq, void *data, struct pt_regs *regs) -{ - struct spu *spu; - unsigned long stat; - unsigned long mask; - - spu = data; - stat = spu_int_stat_get(spu, 2); - mask = spu_int_mask_get(spu, 2); - - pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask); - - stat &= mask; - - if (stat & 1) /* PPC core mailbox */ - __spu_trap_mailbox(spu); - - if (stat & 2) /* SPU stop-and-signal */ - __spu_trap_stop(spu); - - if (stat & 4) /* SPU halted */ - __spu_trap_halt(spu); - - if (stat & 8) /* DMA tag group complete */ - __spu_trap_tag_group(spu); - - if (stat & 0x10) /* SPU mailbox threshold */ - __spu_trap_spubox(spu); - - spu_int_stat_clear(spu, 2, stat); - return stat ? IRQ_HANDLED : IRQ_NONE; -} - -static int -spu_request_irqs(struct spu *spu) -{ - int ret; - int irq_base; - - irq_base = IIC_NODE_STRIDE * spu->node + IIC_SPE_OFFSET; - - snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", spu->number); - ret = request_irq(irq_base + spu->isrc, - spu_irq_class_0, 0, spu->irq_c0, spu); - if (ret) - goto out; - - snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", spu->number); - ret = request_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, - spu_irq_class_1, 0, spu->irq_c1, spu); - if (ret) - goto out1; - - snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", spu->number); - ret = request_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc, - spu_irq_class_2, 0, spu->irq_c2, spu); - if (ret) - goto out2; - goto out; - -out2: - free_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, spu); -out1: - free_irq(irq_base + spu->isrc, spu); -out: - return ret; -} - -static void -spu_free_irqs(struct spu *spu) -{ - int irq_base; - - irq_base = IIC_NODE_STRIDE * spu->node + IIC_SPE_OFFSET; - - free_irq(irq_base + spu->isrc, spu); - free_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, spu); - free_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc, spu); -} - -static LIST_HEAD(spu_list); -static DECLARE_MUTEX(spu_mutex); - -static void spu_init_channels(struct spu *spu) -{ - static const struct { - unsigned channel; - unsigned count; - } zero_list[] = { - { 0x00, 1, }, { 0x01, 1, }, { 0x03, 1, }, { 0x04, 1, }, - { 0x18, 1, }, { 0x19, 1, }, { 0x1b, 1, }, { 0x1d, 1, }, - }, count_list[] = { - { 0x00, 0, }, { 0x03, 0, }, { 0x04, 0, }, { 0x15, 16, }, - { 0x17, 1, }, { 0x18, 0, }, { 0x19, 0, }, { 0x1b, 0, }, - { 0x1c, 1, }, { 0x1d, 0, }, { 0x1e, 1, }, - }; - struct spu_priv2 __iomem *priv2; - int i; - - priv2 = spu->priv2; - - /* initialize all channel data to zero */ - for (i = 0; i < ARRAY_SIZE(zero_list); i++) { - int count; - - out_be64(&priv2->spu_chnlcntptr_RW, zero_list[i].channel); - for (count = 0; count < zero_list[i].count; count++) - out_be64(&priv2->spu_chnldata_RW, 0); - } - - /* initialize channel counts to meaningful values */ - for (i = 0; i < ARRAY_SIZE(count_list); i++) { - out_be64(&priv2->spu_chnlcntptr_RW, count_list[i].channel); - out_be64(&priv2->spu_chnlcnt_RW, count_list[i].count); - } -} - -struct spu *spu_alloc(void) -{ - struct spu *spu; - - down(&spu_mutex); - if (!list_empty(&spu_list)) { - spu = list_entry(spu_list.next, struct spu, list); - list_del_init(&spu->list); - pr_debug("Got SPU %x %d\n", spu->isrc, spu->number); - } else { - pr_debug("No SPU left\n"); - spu = NULL; - } - up(&spu_mutex); - - if (spu) - spu_init_channels(spu); - - return spu; -} -EXPORT_SYMBOL_GPL(spu_alloc); - -void spu_free(struct spu *spu) -{ - down(&spu_mutex); - list_add_tail(&spu->list, &spu_list); - up(&spu_mutex); -} -EXPORT_SYMBOL_GPL(spu_free); - -static int spu_handle_mm_fault(struct spu *spu) -{ - struct mm_struct *mm = spu->mm; - struct vm_area_struct *vma; - u64 ea, dsisr, is_write; - int ret; - - ea = spu->dar; - dsisr = spu->dsisr; -#if 0 - if (!IS_VALID_EA(ea)) { - return -EFAULT; - } -#endif /* XXX */ - if (mm == NULL) { - return -EFAULT; - } - if (mm->pgd == NULL) { - return -EFAULT; - } - - down_read(&mm->mmap_sem); - vma = find_vma(mm, ea); - if (!vma) - goto bad_area; - if (vma->vm_start <= ea) - goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; -#if 0 - if (expand_stack(vma, ea)) - goto bad_area; -#endif /* XXX */ -good_area: - is_write = dsisr & MFC_DSISR_ACCESS_PUT; - if (is_write) { - if (!(vma->vm_flags & VM_WRITE)) - goto bad_area; - } else { - if (dsisr & MFC_DSISR_ACCESS_DENIED) - goto bad_area; - if (!(vma->vm_flags & (VM_READ | VM_EXEC))) - goto bad_area; - } - ret = 0; - switch (handle_mm_fault(mm, vma, ea, is_write)) { - case VM_FAULT_MINOR: - current->min_flt++; - break; - case VM_FAULT_MAJOR: - current->maj_flt++; - break; - case VM_FAULT_SIGBUS: - ret = -EFAULT; - goto bad_area; - case VM_FAULT_OOM: - ret = -ENOMEM; - goto bad_area; - default: - BUG(); - } - up_read(&mm->mmap_sem); - return ret; - -bad_area: - up_read(&mm->mmap_sem); - return -EFAULT; -} - -int spu_irq_class_1_bottom(struct spu *spu) -{ - u64 ea, dsisr, access, error = 0UL; - int ret = 0; - - ea = spu->dar; - dsisr = spu->dsisr; - if (dsisr & MFC_DSISR_PTE_NOT_FOUND) { - access = (_PAGE_PRESENT | _PAGE_USER); - access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL; - if (hash_page(ea, access, 0x300) != 0) - error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; - } - if ((error & CLASS1_ENABLE_STORAGE_FAULT_INTR) || - (dsisr & MFC_DSISR_ACCESS_DENIED)) { - if ((ret = spu_handle_mm_fault(spu)) != 0) - error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; - else - error &= ~CLASS1_ENABLE_STORAGE_FAULT_INTR; - } - spu->dar = 0UL; - spu->dsisr = 0UL; - if (!error) { - spu_restart_dma(spu); - } else { - __spu_trap_invalid_dma(spu); - } - return ret; -} - -void spu_irq_setaffinity(struct spu *spu, int cpu) -{ - u64 target = iic_get_target_id(cpu); - u64 route = target << 48 | target << 32 | target << 16; - spu_int_route_set(spu, route); -} -EXPORT_SYMBOL_GPL(spu_irq_setaffinity); - -static void __iomem * __init map_spe_prop(struct device_node *n, - const char *name) -{ - struct address_prop { - unsigned long address; - unsigned int len; - } __attribute__((packed)) *prop; - - void *p; - int proplen; - - p = get_property(n, name, &proplen); - if (proplen != sizeof (struct address_prop)) - return NULL; - - prop = p; - - return ioremap(prop->address, prop->len); -} - -static void spu_unmap(struct spu *spu) -{ - iounmap(spu->priv2); - iounmap(spu->priv1); - iounmap(spu->problem); - iounmap((u8 __iomem *)spu->local_store); -} - -static int __init spu_map_device(struct spu *spu, struct device_node *spe) -{ - char *prop; - int ret; - - ret = -ENODEV; - prop = get_property(spe, "isrc", NULL); - if (!prop) - goto out; - spu->isrc = *(unsigned int *)prop; - - spu->name = get_property(spe, "name", NULL); - if (!spu->name) - goto out; - - prop = get_property(spe, "local-store", NULL); - if (!prop) - goto out; - spu->local_store_phys = *(unsigned long *)prop; - - /* we use local store as ram, not io memory */ - spu->local_store = (void __force *)map_spe_prop(spe, "local-store"); - if (!spu->local_store) - goto out; - - spu->problem= map_spe_prop(spe, "problem"); - if (!spu->problem) - goto out_unmap; - - spu->priv1= map_spe_prop(spe, "priv1"); - /* priv1 is not available on a hypervisor */ - - spu->priv2= map_spe_prop(spe, "priv2"); - if (!spu->priv2) - goto out_unmap; - ret = 0; - goto out; - -out_unmap: - spu_unmap(spu); -out: - return ret; -} - -static int __init find_spu_node_id(struct device_node *spe) -{ - unsigned int *id; - struct device_node *cpu; - - cpu = spe->parent->parent; - id = (unsigned int *)get_property(cpu, "node-id", NULL); - - return id ? *id : 0; -} - -static int __init create_spu(struct device_node *spe) -{ - struct spu *spu; - int ret; - static int number; - - ret = -ENOMEM; - spu = kmalloc(sizeof (*spu), GFP_KERNEL); - if (!spu) - goto out; - - ret = spu_map_device(spu, spe); - if (ret) - goto out_free; - - spu->node = find_spu_node_id(spe); - spu->stop_code = 0; - spu->slb_replace = 0; - spu->mm = NULL; - spu->ctx = NULL; - spu->rq = NULL; - spu->pid = 0; - spu->class_0_pending = 0; - spu->flags = 0UL; - spu->dar = 0UL; - spu->dsisr = 0UL; - spin_lock_init(&spu->register_lock); - - spu_mfc_sdr_set(spu, mfspr(SPRN_SDR1)); - spu_mfc_sr1_set(spu, 0x33); - - spu->ibox_callback = NULL; - spu->wbox_callback = NULL; - spu->stop_callback = NULL; - - down(&spu_mutex); - spu->number = number++; - ret = spu_request_irqs(spu); - if (ret) - goto out_unmap; - - list_add(&spu->list, &spu_list); - up(&spu_mutex); - - pr_debug(KERN_DEBUG "Using SPE %s %02x %p %p %p %p %d\n", - spu->name, spu->isrc, spu->local_store, - spu->problem, spu->priv1, spu->priv2, spu->number); - goto out; - -out_unmap: - up(&spu_mutex); - spu_unmap(spu); -out_free: - kfree(spu); -out: - return ret; -} - -static void destroy_spu(struct spu *spu) -{ - list_del_init(&spu->list); - - spu_free_irqs(spu); - spu_unmap(spu); - kfree(spu); -} - -static void cleanup_spu_base(void) -{ - struct spu *spu, *tmp; - down(&spu_mutex); - list_for_each_entry_safe(spu, tmp, &spu_list, list) - destroy_spu(spu); - up(&spu_mutex); -} -module_exit(cleanup_spu_base); - -static int __init init_spu_base(void) -{ - struct device_node *node; - int ret; - - ret = -ENODEV; - for (node = of_find_node_by_type(NULL, "spe"); - node; node = of_find_node_by_type(node, "spe")) { - ret = create_spu(node); - if (ret) { - printk(KERN_WARNING "%s: Error initializing %s\n", - __FUNCTION__, node->name); - cleanup_spu_base(); - break; - } - } - /* in some old firmware versions, the spe is called 'spc', so we - look for that as well */ - for (node = of_find_node_by_type(NULL, "spc"); - node; node = of_find_node_by_type(node, "spc")) { - ret = create_spu(node); - if (ret) { - printk(KERN_WARNING "%s: Error initializing %s\n", - __FUNCTION__, node->name); - cleanup_spu_base(); - break; - } - } - return ret; -} -module_init(init_spu_base); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Arnd Bergmann "); diff --git a/trunk/arch/powerpc/platforms/cell/spu_priv1.c b/trunk/arch/powerpc/platforms/cell/spu_priv1.c deleted file mode 100644 index b2656421c7b5..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spu_priv1.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * access to SPU privileged registers - */ -#include - -#include -#include - -void spu_int_mask_and(struct spu *spu, int class, u64 mask) -{ - u64 old_mask; - - old_mask = in_be64(&spu->priv1->int_mask_RW[class]); - out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask); -} -EXPORT_SYMBOL_GPL(spu_int_mask_and); - -void spu_int_mask_or(struct spu *spu, int class, u64 mask) -{ - u64 old_mask; - - old_mask = in_be64(&spu->priv1->int_mask_RW[class]); - out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask); -} -EXPORT_SYMBOL_GPL(spu_int_mask_or); - -void spu_int_mask_set(struct spu *spu, int class, u64 mask) -{ - out_be64(&spu->priv1->int_mask_RW[class], mask); -} -EXPORT_SYMBOL_GPL(spu_int_mask_set); - -u64 spu_int_mask_get(struct spu *spu, int class) -{ - return in_be64(&spu->priv1->int_mask_RW[class]); -} -EXPORT_SYMBOL_GPL(spu_int_mask_get); - -void spu_int_stat_clear(struct spu *spu, int class, u64 stat) -{ - out_be64(&spu->priv1->int_stat_RW[class], stat); -} -EXPORT_SYMBOL_GPL(spu_int_stat_clear); - -u64 spu_int_stat_get(struct spu *spu, int class) -{ - return in_be64(&spu->priv1->int_stat_RW[class]); -} -EXPORT_SYMBOL_GPL(spu_int_stat_get); - -void spu_int_route_set(struct spu *spu, u64 route) -{ - out_be64(&spu->priv1->int_route_RW, route); -} -EXPORT_SYMBOL_GPL(spu_int_route_set); - -u64 spu_mfc_dar_get(struct spu *spu) -{ - return in_be64(&spu->priv1->mfc_dar_RW); -} -EXPORT_SYMBOL_GPL(spu_mfc_dar_get); - -u64 spu_mfc_dsisr_get(struct spu *spu) -{ - return in_be64(&spu->priv1->mfc_dsisr_RW); -} -EXPORT_SYMBOL_GPL(spu_mfc_dsisr_get); - -void spu_mfc_dsisr_set(struct spu *spu, u64 dsisr) -{ - out_be64(&spu->priv1->mfc_dsisr_RW, dsisr); -} -EXPORT_SYMBOL_GPL(spu_mfc_dsisr_set); - -void spu_mfc_sdr_set(struct spu *spu, u64 sdr) -{ - out_be64(&spu->priv1->mfc_sdr_RW, sdr); -} -EXPORT_SYMBOL_GPL(spu_mfc_sdr_set); - -void spu_mfc_sr1_set(struct spu *spu, u64 sr1) -{ - out_be64(&spu->priv1->mfc_sr1_RW, sr1); -} -EXPORT_SYMBOL_GPL(spu_mfc_sr1_set); - -u64 spu_mfc_sr1_get(struct spu *spu) -{ - return in_be64(&spu->priv1->mfc_sr1_RW); -} -EXPORT_SYMBOL_GPL(spu_mfc_sr1_get); - -void spu_mfc_tclass_id_set(struct spu *spu, u64 tclass_id) -{ - out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id); -} -EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_set); - -u64 spu_mfc_tclass_id_get(struct spu *spu) -{ - return in_be64(&spu->priv1->mfc_tclass_id_RW); -} -EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_get); - -void spu_tlb_invalidate(struct spu *spu) -{ - out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul); -} -EXPORT_SYMBOL_GPL(spu_tlb_invalidate); - -void spu_resource_allocation_groupID_set(struct spu *spu, u64 id) -{ - out_be64(&spu->priv1->resource_allocation_groupID_RW, id); -} -EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_set); - -u64 spu_resource_allocation_groupID_get(struct spu *spu) -{ - return in_be64(&spu->priv1->resource_allocation_groupID_RW); -} -EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_get); - -void spu_resource_allocation_enable_set(struct spu *spu, u64 enable) -{ - out_be64(&spu->priv1->resource_allocation_enable_RW, enable); -} -EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_set); - -u64 spu_resource_allocation_enable_get(struct spu *spu) -{ - return in_be64(&spu->priv1->resource_allocation_enable_RW); -} -EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_get); diff --git a/trunk/arch/powerpc/platforms/cell/spu_syscalls.c b/trunk/arch/powerpc/platforms/cell/spu_syscalls.c deleted file mode 100644 index 261b507a901a..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spu_syscalls.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * SPU file system -- system call stubs - * - * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 - * - * Author: Arnd Bergmann - * - * 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, 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. - */ -#include -#include -#include - -#include - -struct spufs_calls spufs_calls = { - .owner = NULL, -}; - -/* These stub syscalls are needed to have the actual implementation - * within a loadable module. When spufs is built into the kernel, - * this file is not used and the syscalls directly enter the fs code */ - -asmlinkage long sys_spu_create(const char __user *name, - unsigned int flags, mode_t mode) -{ - long ret; - struct module *owner = spufs_calls.owner; - - ret = -ENOSYS; - if (owner && try_module_get(owner)) { - ret = spufs_calls.create_thread(name, flags, mode); - module_put(owner); - } - return ret; -} - -asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus) -{ - long ret; - struct file *filp; - int fput_needed; - struct module *owner = spufs_calls.owner; - - ret = -ENOSYS; - if (owner && try_module_get(owner)) { - ret = -EBADF; - filp = fget_light(fd, &fput_needed); - if (filp) { - ret = spufs_calls.spu_run(filp, unpc, ustatus); - fput_light(filp, fput_needed); - } - module_put(owner); - } - return ret; -} - -int register_spu_syscalls(struct spufs_calls *calls) -{ - if (spufs_calls.owner) - return -EBUSY; - - spufs_calls.create_thread = calls->create_thread; - spufs_calls.spu_run = calls->spu_run; - smp_mb(); - spufs_calls.owner = calls->owner; - return 0; -} -EXPORT_SYMBOL_GPL(register_spu_syscalls); - -void unregister_spu_syscalls(struct spufs_calls *calls) -{ - BUG_ON(spufs_calls.owner != calls->owner); - spufs_calls.owner = NULL; -} -EXPORT_SYMBOL_GPL(unregister_spu_syscalls); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/Makefile b/trunk/arch/powerpc/platforms/cell/spufs/Makefile deleted file mode 100644 index a7cddf40e3d9..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -obj-$(CONFIG_SPU_FS) += spufs.o -spufs-y += inode.o file.o context.o switch.o syscalls.o -spufs-y += sched.o backing_ops.o hw_ops.o run.o - -# Rules to build switch.o with the help of SPU tool chain -SPU_CROSS := spu- -SPU_CC := $(SPU_CROSS)gcc -SPU_AS := $(SPU_CROSS)gcc -SPU_LD := $(SPU_CROSS)ld -SPU_OBJCOPY := $(SPU_CROSS)objcopy -SPU_CFLAGS := -O2 -Wall -I$(srctree)/include -I$(objtree)/include2 -SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include -I$(objtree)/include2 -SPU_LDFLAGS := -N -Ttext=0x0 - -$(obj)/switch.o: $(obj)/spu_save_dump.h $(obj)/spu_restore_dump.h - -# Compile SPU files - cmd_spu_cc = $(SPU_CC) $(SPU_CFLAGS) -c -o $@ $< -quiet_cmd_spu_cc = SPU_CC $@ -$(obj)/spu_%.o: $(src)/spu_%.c - $(call if_changed,spu_cc) - -# Assemble SPU files - cmd_spu_as = $(SPU_AS) $(SPU_AFLAGS) -o $@ $< -quiet_cmd_spu_as = SPU_AS $@ -$(obj)/spu_%.o: $(src)/spu_%.S - $(call if_changed,spu_as) - -# Link SPU Executables - cmd_spu_ld = $(SPU_LD) $(SPU_LDFLAGS) -o $@ $^ -quiet_cmd_spu_ld = SPU_LD $@ -$(obj)/spu_%: $(obj)/spu_%_crt0.o $(obj)/spu_%.o - $(call if_changed,spu_ld) - -# Copy into binary format - cmd_spu_objcopy = $(SPU_OBJCOPY) -O binary $< $@ -quiet_cmd_spu_objcopy = OBJCOPY $@ -$(obj)/spu_%.bin: $(src)/spu_% - $(call if_changed,spu_objcopy) - -# create C code from ELF executable -cmd_hexdump = ( \ - echo "/*" ; \ - echo " * $*_dump.h: Copyright (C) 2005 IBM." ; \ - echo " * Hex-dump auto generated from $*.c." ; \ - echo " * Do not edit!" ; \ - echo " */" ; \ - echo "static unsigned int $*_code[] __page_aligned = {" ; \ - hexdump -v -e '"0x" 4/1 "%02x" "," "\n"' $< ; \ - echo "};" ; \ - ) > $@ -quiet_cmd_hexdump = HEXDUMP $@ -$(obj)/%_dump.h: $(obj)/%.bin - $(call if_changed,hexdump) diff --git a/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c b/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c deleted file mode 100644 index a5c489a53c61..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/backing_ops.c +++ /dev/null @@ -1,308 +0,0 @@ -/* backing_ops.c - query/set operations on saved SPU context. - * - * Copyright (C) IBM 2005 - * Author: Mark Nutter - * - * These register operations allow SPUFS to operate on saved - * SPU contexts rather than hardware. - * - * 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, 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "spufs.h" - -/* - * Reads/writes to various problem and priv2 registers require - * state changes, i.e. generate SPU events, modify channel - * counts, etc. - */ - -static void gen_spu_event(struct spu_context *ctx, u32 event) -{ - u64 ch0_cnt; - u64 ch0_data; - u64 ch1_data; - - ch0_cnt = ctx->csa.spu_chnlcnt_RW[0]; - ch0_data = ctx->csa.spu_chnldata_RW[0]; - ch1_data = ctx->csa.spu_chnldata_RW[1]; - ctx->csa.spu_chnldata_RW[0] |= event; - if ((ch0_cnt == 0) && !(ch0_data & event) && (ch1_data & event)) { - ctx->csa.spu_chnlcnt_RW[0] = 1; - } -} - -static int spu_backing_mbox_read(struct spu_context *ctx, u32 * data) -{ - u32 mbox_stat; - int ret = 0; - - spin_lock(&ctx->csa.register_lock); - mbox_stat = ctx->csa.prob.mb_stat_R; - if (mbox_stat & 0x0000ff) { - /* Read the first available word. - * Implementation note: the depth - * of pu_mb_R is currently 1. - */ - *data = ctx->csa.prob.pu_mb_R; - ctx->csa.prob.mb_stat_R &= ~(0x0000ff); - ctx->csa.spu_chnlcnt_RW[28] = 1; - gen_spu_event(ctx, MFC_PU_MAILBOX_AVAILABLE_EVENT); - ret = 4; - } - spin_unlock(&ctx->csa.register_lock); - return ret; -} - -static u32 spu_backing_mbox_stat_read(struct spu_context *ctx) -{ - return ctx->csa.prob.mb_stat_R; -} - -static unsigned int spu_backing_mbox_stat_poll(struct spu_context *ctx, - unsigned int events) -{ - int ret; - u32 stat; - - ret = 0; - spin_lock_irq(&ctx->csa.register_lock); - stat = ctx->csa.prob.mb_stat_R; - - /* if the requested event is there, return the poll - mask, otherwise enable the interrupt to get notified, - but first mark any pending interrupts as done so - we don't get woken up unnecessarily */ - - if (events & (POLLIN | POLLRDNORM)) { - if (stat & 0xff0000) - ret |= POLLIN | POLLRDNORM; - else { - ctx->csa.priv1.int_stat_class0_RW &= ~0x1; - ctx->csa.priv1.int_mask_class2_RW |= 0x1; - } - } - if (events & (POLLOUT | POLLWRNORM)) { - if (stat & 0x00ff00) - ret = POLLOUT | POLLWRNORM; - else { - ctx->csa.priv1.int_stat_class0_RW &= ~0x10; - ctx->csa.priv1.int_mask_class2_RW |= 0x10; - } - } - spin_unlock_irq(&ctx->csa.register_lock); - return ret; -} - -static int spu_backing_ibox_read(struct spu_context *ctx, u32 * data) -{ - int ret; - - spin_lock(&ctx->csa.register_lock); - if (ctx->csa.prob.mb_stat_R & 0xff0000) { - /* Read the first available word. - * Implementation note: the depth - * of puint_mb_R is currently 1. - */ - *data = ctx->csa.priv2.puint_mb_R; - ctx->csa.prob.mb_stat_R &= ~(0xff0000); - ctx->csa.spu_chnlcnt_RW[30] = 1; - gen_spu_event(ctx, MFC_PU_INT_MAILBOX_AVAILABLE_EVENT); - ret = 4; - } else { - /* make sure we get woken up by the interrupt */ - ctx->csa.priv1.int_mask_class2_RW |= 0x1UL; - ret = 0; - } - spin_unlock(&ctx->csa.register_lock); - return ret; -} - -static int spu_backing_wbox_write(struct spu_context *ctx, u32 data) -{ - int ret; - - spin_lock(&ctx->csa.register_lock); - if ((ctx->csa.prob.mb_stat_R) & 0x00ff00) { - int slot = ctx->csa.spu_chnlcnt_RW[29]; - int avail = (ctx->csa.prob.mb_stat_R & 0x00ff00) >> 8; - - /* We have space to write wbox_data. - * Implementation note: the depth - * of spu_mb_W is currently 4. - */ - BUG_ON(avail != (4 - slot)); - ctx->csa.spu_mailbox_data[slot] = data; - ctx->csa.spu_chnlcnt_RW[29] = ++slot; - ctx->csa.prob.mb_stat_R = (((4 - slot) & 0xff) << 8); - gen_spu_event(ctx, MFC_SPU_MAILBOX_WRITTEN_EVENT); - ret = 4; - } else { - /* make sure we get woken up by the interrupt when space - becomes available */ - ctx->csa.priv1.int_mask_class2_RW |= 0x10; - ret = 0; - } - spin_unlock(&ctx->csa.register_lock); - return ret; -} - -static u32 spu_backing_signal1_read(struct spu_context *ctx) -{ - return ctx->csa.spu_chnldata_RW[3]; -} - -static void spu_backing_signal1_write(struct spu_context *ctx, u32 data) -{ - spin_lock(&ctx->csa.register_lock); - if (ctx->csa.priv2.spu_cfg_RW & 0x1) - ctx->csa.spu_chnldata_RW[3] |= data; - else - ctx->csa.spu_chnldata_RW[3] = data; - ctx->csa.spu_chnlcnt_RW[3] = 1; - gen_spu_event(ctx, MFC_SIGNAL_1_EVENT); - spin_unlock(&ctx->csa.register_lock); -} - -static u32 spu_backing_signal2_read(struct spu_context *ctx) -{ - return ctx->csa.spu_chnldata_RW[4]; -} - -static void spu_backing_signal2_write(struct spu_context *ctx, u32 data) -{ - spin_lock(&ctx->csa.register_lock); - if (ctx->csa.priv2.spu_cfg_RW & 0x2) - ctx->csa.spu_chnldata_RW[4] |= data; - else - ctx->csa.spu_chnldata_RW[4] = data; - ctx->csa.spu_chnlcnt_RW[4] = 1; - gen_spu_event(ctx, MFC_SIGNAL_2_EVENT); - spin_unlock(&ctx->csa.register_lock); -} - -static void spu_backing_signal1_type_set(struct spu_context *ctx, u64 val) -{ - u64 tmp; - - spin_lock(&ctx->csa.register_lock); - tmp = ctx->csa.priv2.spu_cfg_RW; - if (val) - tmp |= 1; - else - tmp &= ~1; - ctx->csa.priv2.spu_cfg_RW = tmp; - spin_unlock(&ctx->csa.register_lock); -} - -static u64 spu_backing_signal1_type_get(struct spu_context *ctx) -{ - return ((ctx->csa.priv2.spu_cfg_RW & 1) != 0); -} - -static void spu_backing_signal2_type_set(struct spu_context *ctx, u64 val) -{ - u64 tmp; - - spin_lock(&ctx->csa.register_lock); - tmp = ctx->csa.priv2.spu_cfg_RW; - if (val) - tmp |= 2; - else - tmp &= ~2; - ctx->csa.priv2.spu_cfg_RW = tmp; - spin_unlock(&ctx->csa.register_lock); -} - -static u64 spu_backing_signal2_type_get(struct spu_context *ctx) -{ - return ((ctx->csa.priv2.spu_cfg_RW & 2) != 0); -} - -static u32 spu_backing_npc_read(struct spu_context *ctx) -{ - return ctx->csa.prob.spu_npc_RW; -} - -static void spu_backing_npc_write(struct spu_context *ctx, u32 val) -{ - ctx->csa.prob.spu_npc_RW = val; -} - -static u32 spu_backing_status_read(struct spu_context *ctx) -{ - return ctx->csa.prob.spu_status_R; -} - -static char *spu_backing_get_ls(struct spu_context *ctx) -{ - return ctx->csa.lscsa->ls; -} - -static void spu_backing_runcntl_write(struct spu_context *ctx, u32 val) -{ - spin_lock(&ctx->csa.register_lock); - ctx->csa.prob.spu_runcntl_RW = val; - if (val & SPU_RUNCNTL_RUNNABLE) { - ctx->csa.prob.spu_status_R |= SPU_STATUS_RUNNING; - } else { - ctx->csa.prob.spu_status_R &= ~SPU_STATUS_RUNNING; - } - spin_unlock(&ctx->csa.register_lock); -} - -static void spu_backing_runcntl_stop(struct spu_context *ctx) -{ - spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP); -} - -struct spu_context_ops spu_backing_ops = { - .mbox_read = spu_backing_mbox_read, - .mbox_stat_read = spu_backing_mbox_stat_read, - .mbox_stat_poll = spu_backing_mbox_stat_poll, - .ibox_read = spu_backing_ibox_read, - .wbox_write = spu_backing_wbox_write, - .signal1_read = spu_backing_signal1_read, - .signal1_write = spu_backing_signal1_write, - .signal2_read = spu_backing_signal2_read, - .signal2_write = spu_backing_signal2_write, - .signal1_type_set = spu_backing_signal1_type_set, - .signal1_type_get = spu_backing_signal1_type_get, - .signal2_type_set = spu_backing_signal2_type_set, - .signal2_type_get = spu_backing_signal2_type_get, - .npc_read = spu_backing_npc_read, - .npc_write = spu_backing_npc_write, - .status_read = spu_backing_status_read, - .get_ls = spu_backing_get_ls, - .runcntl_write = spu_backing_runcntl_write, - .runcntl_stop = spu_backing_runcntl_stop, -}; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/context.c b/trunk/arch/powerpc/platforms/cell/spufs/context.c deleted file mode 100644 index 336f238102fd..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/context.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * SPU file system -- SPU context management - * - * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 - * - * Author: Arnd Bergmann - * - * 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, 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. - */ - -#include -#include -#include -#include -#include -#include "spufs.h" - -struct spu_context *alloc_spu_context(struct address_space *local_store) -{ - struct spu_context *ctx; - ctx = kmalloc(sizeof *ctx, GFP_KERNEL); - if (!ctx) - goto out; - /* Binding to physical processor deferred - * until spu_activate(). - */ - spu_init_csa(&ctx->csa); - if (!ctx->csa.lscsa) { - goto out_free; - } - spin_lock_init(&ctx->mmio_lock); - kref_init(&ctx->kref); - init_rwsem(&ctx->state_sema); - init_MUTEX(&ctx->run_sema); - init_waitqueue_head(&ctx->ibox_wq); - init_waitqueue_head(&ctx->wbox_wq); - init_waitqueue_head(&ctx->stop_wq); - ctx->ibox_fasync = NULL; - ctx->wbox_fasync = NULL; - ctx->state = SPU_STATE_SAVED; - ctx->local_store = local_store; - ctx->spu = NULL; - ctx->ops = &spu_backing_ops; - ctx->owner = get_task_mm(current); - goto out; -out_free: - kfree(ctx); - ctx = NULL; -out: - return ctx; -} - -void destroy_spu_context(struct kref *kref) -{ - struct spu_context *ctx; - ctx = container_of(kref, struct spu_context, kref); - down_write(&ctx->state_sema); - spu_deactivate(ctx); - ctx->ibox_fasync = NULL; - ctx->wbox_fasync = NULL; - up_write(&ctx->state_sema); - spu_fini_csa(&ctx->csa); - kfree(ctx); -} - -struct spu_context * get_spu_context(struct spu_context *ctx) -{ - kref_get(&ctx->kref); - return ctx; -} - -int put_spu_context(struct spu_context *ctx) -{ - return kref_put(&ctx->kref, &destroy_spu_context); -} - -/* give up the mm reference when the context is about to be destroyed */ -void spu_forget(struct spu_context *ctx) -{ - struct mm_struct *mm; - spu_acquire_saved(ctx); - mm = ctx->owner; - ctx->owner = NULL; - mmput(mm); - spu_release(ctx); -} - -void spu_acquire(struct spu_context *ctx) -{ - down_read(&ctx->state_sema); -} - -void spu_release(struct spu_context *ctx) -{ - up_read(&ctx->state_sema); -} - -void spu_unmap_mappings(struct spu_context *ctx) -{ - unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); -} - -int spu_acquire_runnable(struct spu_context *ctx) -{ - int ret = 0; - - down_read(&ctx->state_sema); - if (ctx->state == SPU_STATE_RUNNABLE) { - ctx->spu->prio = current->prio; - return 0; - } - up_read(&ctx->state_sema); - - down_write(&ctx->state_sema); - /* ctx is about to be freed, can't acquire any more */ - if (!ctx->owner) { - ret = -EINVAL; - goto out; - } - - if (ctx->state == SPU_STATE_SAVED) { - ret = spu_activate(ctx, 0); - if (ret) - goto out; - ctx->state = SPU_STATE_RUNNABLE; - } - - downgrade_write(&ctx->state_sema); - /* On success, we return holding the lock */ - - return ret; -out: - /* Release here, to simplify calling code. */ - up_write(&ctx->state_sema); - - return ret; -} - -void spu_acquire_saved(struct spu_context *ctx) -{ - down_read(&ctx->state_sema); - - if (ctx->state == SPU_STATE_SAVED) - return; - - up_read(&ctx->state_sema); - down_write(&ctx->state_sema); - - if (ctx->state == SPU_STATE_RUNNABLE) { - spu_deactivate(ctx); - ctx->state = SPU_STATE_SAVED; - } - - downgrade_write(&ctx->state_sema); -} diff --git a/trunk/arch/powerpc/platforms/cell/spufs/file.c b/trunk/arch/powerpc/platforms/cell/spufs/file.c deleted file mode 100644 index dfa649c9b956..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/file.c +++ /dev/null @@ -1,794 +0,0 @@ -/* - * SPU file system -- file contents - * - * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 - * - * Author: Arnd Bergmann - * - * 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, 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. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "spufs.h" - - -static int -spufs_mem_open(struct inode *inode, struct file *file) -{ - struct spufs_inode_info *i = SPUFS_I(inode); - file->private_data = i->i_ctx; - file->f_mapping = i->i_ctx->local_store; - return 0; -} - -static ssize_t -spufs_mem_read(struct file *file, char __user *buffer, - size_t size, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - char *local_store; - int ret; - - spu_acquire(ctx); - - local_store = ctx->ops->get_ls(ctx); - ret = simple_read_from_buffer(buffer, size, pos, local_store, LS_SIZE); - - spu_release(ctx); - return ret; -} - -static ssize_t -spufs_mem_write(struct file *file, const char __user *buffer, - size_t size, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - char *local_store; - int ret; - - size = min_t(ssize_t, LS_SIZE - *pos, size); - if (size <= 0) - return -EFBIG; - *pos += size; - - spu_acquire(ctx); - - local_store = ctx->ops->get_ls(ctx); - ret = copy_from_user(local_store + *pos - size, - buffer, size) ? -EFAULT : size; - - spu_release(ctx); - return ret; -} - -#ifdef CONFIG_SPARSEMEM -static struct page * -spufs_mem_mmap_nopage(struct vm_area_struct *vma, - unsigned long address, int *type) -{ - struct page *page = NOPAGE_SIGBUS; - - struct spu_context *ctx = vma->vm_file->private_data; - unsigned long offset = address - vma->vm_start; - offset += vma->vm_pgoff << PAGE_SHIFT; - - spu_acquire(ctx); - - if (ctx->state == SPU_STATE_SAVED) - page = vmalloc_to_page(ctx->csa.lscsa->ls + offset); - else - page = pfn_to_page((ctx->spu->local_store_phys + offset) - >> PAGE_SHIFT); - - spu_release(ctx); - - if (type) - *type = VM_FAULT_MINOR; - - page_cache_get(page); - return page; -} - -static struct vm_operations_struct spufs_mem_mmap_vmops = { - .nopage = spufs_mem_mmap_nopage, -}; - -static int -spufs_mem_mmap(struct file *file, struct vm_area_struct *vma) -{ - if (!(vma->vm_flags & VM_SHARED)) - return -EINVAL; - - /* FIXME: */ - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); - - vma->vm_ops = &spufs_mem_mmap_vmops; - return 0; -} -#endif - -static struct file_operations spufs_mem_fops = { - .open = spufs_mem_open, - .read = spufs_mem_read, - .write = spufs_mem_write, - .llseek = generic_file_llseek, -#ifdef CONFIG_SPARSEMEM - .mmap = spufs_mem_mmap, -#endif -}; - -static int -spufs_regs_open(struct inode *inode, struct file *file) -{ - struct spufs_inode_info *i = SPUFS_I(inode); - file->private_data = i->i_ctx; - return 0; -} - -static ssize_t -spufs_regs_read(struct file *file, char __user *buffer, - size_t size, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - int ret; - - spu_acquire_saved(ctx); - - ret = simple_read_from_buffer(buffer, size, pos, - lscsa->gprs, sizeof lscsa->gprs); - - spu_release(ctx); - return ret; -} - -static ssize_t -spufs_regs_write(struct file *file, const char __user *buffer, - size_t size, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - int ret; - - size = min_t(ssize_t, sizeof lscsa->gprs - *pos, size); - if (size <= 0) - return -EFBIG; - *pos += size; - - spu_acquire_saved(ctx); - - ret = copy_from_user(lscsa->gprs + *pos - size, - buffer, size) ? -EFAULT : size; - - spu_release(ctx); - return ret; -} - -static struct file_operations spufs_regs_fops = { - .open = spufs_regs_open, - .read = spufs_regs_read, - .write = spufs_regs_write, - .llseek = generic_file_llseek, -}; - -static ssize_t -spufs_fpcr_read(struct file *file, char __user * buffer, - size_t size, loff_t * pos) -{ - struct spu_context *ctx = file->private_data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - int ret; - - spu_acquire_saved(ctx); - - ret = simple_read_from_buffer(buffer, size, pos, - &lscsa->fpcr, sizeof(lscsa->fpcr)); - - spu_release(ctx); - return ret; -} - -static ssize_t -spufs_fpcr_write(struct file *file, const char __user * buffer, - size_t size, loff_t * pos) -{ - struct spu_context *ctx = file->private_data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - int ret; - - size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size); - if (size <= 0) - return -EFBIG; - *pos += size; - - spu_acquire_saved(ctx); - - ret = copy_from_user((char *)&lscsa->fpcr + *pos - size, - buffer, size) ? -EFAULT : size; - - spu_release(ctx); - return ret; -} - -static struct file_operations spufs_fpcr_fops = { - .open = spufs_regs_open, - .read = spufs_fpcr_read, - .write = spufs_fpcr_write, - .llseek = generic_file_llseek, -}; - -/* generic open function for all pipe-like files */ -static int spufs_pipe_open(struct inode *inode, struct file *file) -{ - struct spufs_inode_info *i = SPUFS_I(inode); - file->private_data = i->i_ctx; - - return nonseekable_open(inode, file); -} - -static ssize_t spufs_mbox_read(struct file *file, char __user *buf, - size_t len, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - u32 mbox_data; - int ret; - - if (len < 4) - return -EINVAL; - - spu_acquire(ctx); - ret = ctx->ops->mbox_read(ctx, &mbox_data); - spu_release(ctx); - - if (!ret) - return -EAGAIN; - - if (copy_to_user(buf, &mbox_data, sizeof mbox_data)) - return -EFAULT; - - return 4; -} - -static struct file_operations spufs_mbox_fops = { - .open = spufs_pipe_open, - .read = spufs_mbox_read, -}; - -static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf, - size_t len, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - u32 mbox_stat; - - if (len < 4) - return -EINVAL; - - spu_acquire(ctx); - - mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff; - - spu_release(ctx); - - if (copy_to_user(buf, &mbox_stat, sizeof mbox_stat)) - return -EFAULT; - - return 4; -} - -static struct file_operations spufs_mbox_stat_fops = { - .open = spufs_pipe_open, - .read = spufs_mbox_stat_read, -}; - -/* low-level ibox access function */ -size_t spu_ibox_read(struct spu_context *ctx, u32 *data) -{ - return ctx->ops->ibox_read(ctx, data); -} - -static int spufs_ibox_fasync(int fd, struct file *file, int on) -{ - struct spu_context *ctx = file->private_data; - - return fasync_helper(fd, file, on, &ctx->ibox_fasync); -} - -/* interrupt-level ibox callback function. */ -void spufs_ibox_callback(struct spu *spu) -{ - struct spu_context *ctx = spu->ctx; - - wake_up_all(&ctx->ibox_wq); - kill_fasync(&ctx->ibox_fasync, SIGIO, POLLIN); -} - -static ssize_t spufs_ibox_read(struct file *file, char __user *buf, - size_t len, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - u32 ibox_data; - ssize_t ret; - - if (len < 4) - return -EINVAL; - - spu_acquire(ctx); - - ret = 0; - if (file->f_flags & O_NONBLOCK) { - if (!spu_ibox_read(ctx, &ibox_data)) - ret = -EAGAIN; - } else { - ret = spufs_wait(ctx->ibox_wq, spu_ibox_read(ctx, &ibox_data)); - } - - spu_release(ctx); - - if (ret) - return ret; - - ret = 4; - if (copy_to_user(buf, &ibox_data, sizeof ibox_data)) - ret = -EFAULT; - - return ret; -} - -static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait) -{ - struct spu_context *ctx = file->private_data; - unsigned int mask; - - poll_wait(file, &ctx->ibox_wq, wait); - - spu_acquire(ctx); - mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM); - spu_release(ctx); - - return mask; -} - -static struct file_operations spufs_ibox_fops = { - .open = spufs_pipe_open, - .read = spufs_ibox_read, - .poll = spufs_ibox_poll, - .fasync = spufs_ibox_fasync, -}; - -static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf, - size_t len, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - u32 ibox_stat; - - if (len < 4) - return -EINVAL; - - spu_acquire(ctx); - ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff; - spu_release(ctx); - - if (copy_to_user(buf, &ibox_stat, sizeof ibox_stat)) - return -EFAULT; - - return 4; -} - -static struct file_operations spufs_ibox_stat_fops = { - .open = spufs_pipe_open, - .read = spufs_ibox_stat_read, -}; - -/* low-level mailbox write */ -size_t spu_wbox_write(struct spu_context *ctx, u32 data) -{ - return ctx->ops->wbox_write(ctx, data); -} - -static int spufs_wbox_fasync(int fd, struct file *file, int on) -{ - struct spu_context *ctx = file->private_data; - int ret; - - ret = fasync_helper(fd, file, on, &ctx->wbox_fasync); - - return ret; -} - -/* interrupt-level wbox callback function. */ -void spufs_wbox_callback(struct spu *spu) -{ - struct spu_context *ctx = spu->ctx; - - wake_up_all(&ctx->wbox_wq); - kill_fasync(&ctx->wbox_fasync, SIGIO, POLLOUT); -} - -static ssize_t spufs_wbox_write(struct file *file, const char __user *buf, - size_t len, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - u32 wbox_data; - int ret; - - if (len < 4) - return -EINVAL; - - if (copy_from_user(&wbox_data, buf, sizeof wbox_data)) - return -EFAULT; - - spu_acquire(ctx); - - ret = 0; - if (file->f_flags & O_NONBLOCK) { - if (!spu_wbox_write(ctx, wbox_data)) - ret = -EAGAIN; - } else { - ret = spufs_wait(ctx->wbox_wq, spu_wbox_write(ctx, wbox_data)); - } - - spu_release(ctx); - - return ret ? ret : sizeof wbox_data; -} - -static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait) -{ - struct spu_context *ctx = file->private_data; - unsigned int mask; - - poll_wait(file, &ctx->wbox_wq, wait); - - spu_acquire(ctx); - mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM); - spu_release(ctx); - - return mask; -} - -static struct file_operations spufs_wbox_fops = { - .open = spufs_pipe_open, - .write = spufs_wbox_write, - .poll = spufs_wbox_poll, - .fasync = spufs_wbox_fasync, -}; - -static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf, - size_t len, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - u32 wbox_stat; - - if (len < 4) - return -EINVAL; - - spu_acquire(ctx); - wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff; - spu_release(ctx); - - if (copy_to_user(buf, &wbox_stat, sizeof wbox_stat)) - return -EFAULT; - - return 4; -} - -static struct file_operations spufs_wbox_stat_fops = { - .open = spufs_pipe_open, - .read = spufs_wbox_stat_read, -}; - -static ssize_t spufs_signal1_read(struct file *file, char __user *buf, - size_t len, loff_t *pos) -{ - struct spu_context *ctx = file->private_data; - u32 data; - - if (len < 4) - return -EINVAL; - - spu_acquire(ctx); - data = ctx->ops->signal1_read(ctx); - spu_release(ctx); - - if (copy_to_user(buf, &data, 4)) - return -EFAULT; - - return 4; -} - -static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, - size_t len, loff_t *pos) -{ - struct spu_context *ctx; - u32 data; - - ctx = file->private_data; - - if (len < 4) - return -EINVAL; - - if (copy_from_user(&data, buf, 4)) - return -EFAULT; - - spu_acquire(ctx); - ctx->ops->signal1_write(ctx, data); - spu_release(ctx); - - return 4; -} - -static struct file_operations spufs_signal1_fops = { - .open = spufs_pipe_open, - .read = spufs_signal1_read, - .write = spufs_signal1_write, -}; - -static ssize_t spufs_signal2_read(struct file *file, char __user *buf, - size_t len, loff_t *pos) -{ - struct spu_context *ctx; - u32 data; - - ctx = file->private_data; - - if (len < 4) - return -EINVAL; - - spu_acquire(ctx); - data = ctx->ops->signal2_read(ctx); - spu_release(ctx); - - if (copy_to_user(buf, &data, 4)) - return -EFAULT; - - return 4; -} - -static ssize_t spufs_signal2_write(struct file *file, const char __user *buf, - size_t len, loff_t *pos) -{ - struct spu_context *ctx; - u32 data; - - ctx = file->private_data; - - if (len < 4) - return -EINVAL; - - if (copy_from_user(&data, buf, 4)) - return -EFAULT; - - spu_acquire(ctx); - ctx->ops->signal2_write(ctx, data); - spu_release(ctx); - - return 4; -} - -static struct file_operations spufs_signal2_fops = { - .open = spufs_pipe_open, - .read = spufs_signal2_read, - .write = spufs_signal2_write, -}; - -static void spufs_signal1_type_set(void *data, u64 val) -{ - struct spu_context *ctx = data; - - spu_acquire(ctx); - ctx->ops->signal1_type_set(ctx, val); - spu_release(ctx); -} - -static u64 spufs_signal1_type_get(void *data) -{ - struct spu_context *ctx = data; - u64 ret; - - spu_acquire(ctx); - ret = ctx->ops->signal1_type_get(ctx); - spu_release(ctx); - - return ret; -} -DEFINE_SIMPLE_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get, - spufs_signal1_type_set, "%llu"); - -static void spufs_signal2_type_set(void *data, u64 val) -{ - struct spu_context *ctx = data; - - spu_acquire(ctx); - ctx->ops->signal2_type_set(ctx, val); - spu_release(ctx); -} - -static u64 spufs_signal2_type_get(void *data) -{ - struct spu_context *ctx = data; - u64 ret; - - spu_acquire(ctx); - ret = ctx->ops->signal2_type_get(ctx); - spu_release(ctx); - - return ret; -} -DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, - spufs_signal2_type_set, "%llu"); - -static void spufs_npc_set(void *data, u64 val) -{ - struct spu_context *ctx = data; - spu_acquire(ctx); - ctx->ops->npc_write(ctx, val); - spu_release(ctx); -} - -static u64 spufs_npc_get(void *data) -{ - struct spu_context *ctx = data; - u64 ret; - spu_acquire(ctx); - ret = ctx->ops->npc_read(ctx); - spu_release(ctx); - return ret; -} -DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set, "%llx\n") - -static void spufs_decr_set(void *data, u64 val) -{ - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - spu_acquire_saved(ctx); - lscsa->decr.slot[0] = (u32) val; - spu_release(ctx); -} - -static u64 spufs_decr_get(void *data) -{ - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - u64 ret; - spu_acquire_saved(ctx); - ret = lscsa->decr.slot[0]; - spu_release(ctx); - return ret; -} -DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set, - "%llx\n") - -static void spufs_decr_status_set(void *data, u64 val) -{ - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - spu_acquire_saved(ctx); - lscsa->decr_status.slot[0] = (u32) val; - spu_release(ctx); -} - -static u64 spufs_decr_status_get(void *data) -{ - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - u64 ret; - spu_acquire_saved(ctx); - ret = lscsa->decr_status.slot[0]; - spu_release(ctx); - return ret; -} -DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get, - spufs_decr_status_set, "%llx\n") - -static void spufs_spu_tag_mask_set(void *data, u64 val) -{ - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - spu_acquire_saved(ctx); - lscsa->tag_mask.slot[0] = (u32) val; - spu_release(ctx); -} - -static u64 spufs_spu_tag_mask_get(void *data) -{ - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - u64 ret; - spu_acquire_saved(ctx); - ret = lscsa->tag_mask.slot[0]; - spu_release(ctx); - return ret; -} -DEFINE_SIMPLE_ATTRIBUTE(spufs_spu_tag_mask_ops, spufs_spu_tag_mask_get, - spufs_spu_tag_mask_set, "%llx\n") - -static void spufs_event_mask_set(void *data, u64 val) -{ - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - spu_acquire_saved(ctx); - lscsa->event_mask.slot[0] = (u32) val; - spu_release(ctx); -} - -static u64 spufs_event_mask_get(void *data) -{ - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - u64 ret; - spu_acquire_saved(ctx); - ret = lscsa->event_mask.slot[0]; - spu_release(ctx); - return ret; -} -DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get, - spufs_event_mask_set, "%llx\n") - -static void spufs_srr0_set(void *data, u64 val) -{ - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - spu_acquire_saved(ctx); - lscsa->srr0.slot[0] = (u32) val; - spu_release(ctx); -} - -static u64 spufs_srr0_get(void *data) -{ - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; - u64 ret; - spu_acquire_saved(ctx); - ret = lscsa->srr0.slot[0]; - spu_release(ctx); - return ret; -} -DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set, - "%llx\n") - -struct tree_descr spufs_dir_contents[] = { - { "mem", &spufs_mem_fops, 0666, }, - { "regs", &spufs_regs_fops, 0666, }, - { "mbox", &spufs_mbox_fops, 0444, }, - { "ibox", &spufs_ibox_fops, 0444, }, - { "wbox", &spufs_wbox_fops, 0222, }, - { "mbox_stat", &spufs_mbox_stat_fops, 0444, }, - { "ibox_stat", &spufs_ibox_stat_fops, 0444, }, - { "wbox_stat", &spufs_wbox_stat_fops, 0444, }, - { "signal1", &spufs_signal1_fops, 0666, }, - { "signal2", &spufs_signal2_fops, 0666, }, - { "signal1_type", &spufs_signal1_type, 0666, }, - { "signal2_type", &spufs_signal2_type, 0666, }, - { "npc", &spufs_npc_ops, 0666, }, - { "fpcr", &spufs_fpcr_fops, 0666, }, - { "decr", &spufs_decr_ops, 0666, }, - { "decr_status", &spufs_decr_status_ops, 0666, }, - { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, - { "event_mask", &spufs_event_mask_ops, 0666, }, - { "srr0", &spufs_srr0_ops, 0666, }, - {}, -}; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c b/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c deleted file mode 100644 index 5445719bff79..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ /dev/null @@ -1,255 +0,0 @@ -/* hw_ops.c - query/set operations on active SPU context. - * - * Copyright (C) IBM 2005 - * Author: Mark Nutter - * - * 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, 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "spufs.h" - -static int spu_hw_mbox_read(struct spu_context *ctx, u32 * data) -{ - struct spu *spu = ctx->spu; - struct spu_problem __iomem *prob = spu->problem; - u32 mbox_stat; - int ret = 0; - - spin_lock_irq(&spu->register_lock); - mbox_stat = in_be32(&prob->mb_stat_R); - if (mbox_stat & 0x0000ff) { - *data = in_be32(&prob->pu_mb_R); - ret = 4; - } - spin_unlock_irq(&spu->register_lock); - return ret; -} - -static u32 spu_hw_mbox_stat_read(struct spu_context *ctx) -{ - return in_be32(&ctx->spu->problem->mb_stat_R); -} - -static unsigned int spu_hw_mbox_stat_poll(struct spu_context *ctx, - unsigned int events) -{ - struct spu *spu = ctx->spu; - int ret = 0; - u32 stat; - - spin_lock_irq(&spu->register_lock); - stat = in_be32(&spu->problem->mb_stat_R); - - /* if the requested event is there, return the poll - mask, otherwise enable the interrupt to get notified, - but first mark any pending interrupts as done so - we don't get woken up unnecessarily */ - - if (events & (POLLIN | POLLRDNORM)) { - if (stat & 0xff0000) - ret |= POLLIN | POLLRDNORM; - else { - spu_int_stat_clear(spu, 2, 0x1); - spu_int_mask_or(spu, 2, 0x1); - } - } - if (events & (POLLOUT | POLLWRNORM)) { - if (stat & 0x00ff00) - ret = POLLOUT | POLLWRNORM; - else { - spu_int_stat_clear(spu, 2, 0x10); - spu_int_mask_or(spu, 2, 0x10); - } - } - spin_unlock_irq(&spu->register_lock); - return ret; -} - -static int spu_hw_ibox_read(struct spu_context *ctx, u32 * data) -{ - struct spu *spu = ctx->spu; - struct spu_problem __iomem *prob = spu->problem; - struct spu_priv2 __iomem *priv2 = spu->priv2; - int ret; - - spin_lock_irq(&spu->register_lock); - if (in_be32(&prob->mb_stat_R) & 0xff0000) { - /* read the first available word */ - *data = in_be64(&priv2->puint_mb_R); - ret = 4; - } else { - /* make sure we get woken up by the interrupt */ - spu_int_mask_or(spu, 2, 0x1); - ret = 0; - } - spin_unlock_irq(&spu->register_lock); - return ret; -} - -static int spu_hw_wbox_write(struct spu_context *ctx, u32 data) -{ - struct spu *spu = ctx->spu; - struct spu_problem __iomem *prob = spu->problem; - int ret; - - spin_lock_irq(&spu->register_lock); - if (in_be32(&prob->mb_stat_R) & 0x00ff00) { - /* we have space to write wbox_data to */ - out_be32(&prob->spu_mb_W, data); - ret = 4; - } else { - /* make sure we get woken up by the interrupt when space - becomes available */ - spu_int_mask_or(spu, 2, 0x10); - ret = 0; - } - spin_unlock_irq(&spu->register_lock); - return ret; -} - -static u32 spu_hw_signal1_read(struct spu_context *ctx) -{ - return in_be32(&ctx->spu->problem->signal_notify1); -} - -static void spu_hw_signal1_write(struct spu_context *ctx, u32 data) -{ - out_be32(&ctx->spu->problem->signal_notify1, data); -} - -static u32 spu_hw_signal2_read(struct spu_context *ctx) -{ - return in_be32(&ctx->spu->problem->signal_notify1); -} - -static void spu_hw_signal2_write(struct spu_context *ctx, u32 data) -{ - out_be32(&ctx->spu->problem->signal_notify2, data); -} - -static void spu_hw_signal1_type_set(struct spu_context *ctx, u64 val) -{ - struct spu *spu = ctx->spu; - struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 tmp; - - spin_lock_irq(&spu->register_lock); - tmp = in_be64(&priv2->spu_cfg_RW); - if (val) - tmp |= 1; - else - tmp &= ~1; - out_be64(&priv2->spu_cfg_RW, tmp); - spin_unlock_irq(&spu->register_lock); -} - -static u64 spu_hw_signal1_type_get(struct spu_context *ctx) -{ - return ((in_be64(&ctx->spu->priv2->spu_cfg_RW) & 1) != 0); -} - -static void spu_hw_signal2_type_set(struct spu_context *ctx, u64 val) -{ - struct spu *spu = ctx->spu; - struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 tmp; - - spin_lock_irq(&spu->register_lock); - tmp = in_be64(&priv2->spu_cfg_RW); - if (val) - tmp |= 2; - else - tmp &= ~2; - out_be64(&priv2->spu_cfg_RW, tmp); - spin_unlock_irq(&spu->register_lock); -} - -static u64 spu_hw_signal2_type_get(struct spu_context *ctx) -{ - return ((in_be64(&ctx->spu->priv2->spu_cfg_RW) & 2) != 0); -} - -static u32 spu_hw_npc_read(struct spu_context *ctx) -{ - return in_be32(&ctx->spu->problem->spu_npc_RW); -} - -static void spu_hw_npc_write(struct spu_context *ctx, u32 val) -{ - out_be32(&ctx->spu->problem->spu_npc_RW, val); -} - -static u32 spu_hw_status_read(struct spu_context *ctx) -{ - return in_be32(&ctx->spu->problem->spu_status_R); -} - -static char *spu_hw_get_ls(struct spu_context *ctx) -{ - return ctx->spu->local_store; -} - -static void spu_hw_runcntl_write(struct spu_context *ctx, u32 val) -{ - eieio(); - out_be32(&ctx->spu->problem->spu_runcntl_RW, val); -} - -static void spu_hw_runcntl_stop(struct spu_context *ctx) -{ - spin_lock_irq(&ctx->spu->register_lock); - out_be32(&ctx->spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP); - while (in_be32(&ctx->spu->problem->spu_status_R) & SPU_STATUS_RUNNING) - cpu_relax(); - spin_unlock_irq(&ctx->spu->register_lock); -} - -struct spu_context_ops spu_hw_ops = { - .mbox_read = spu_hw_mbox_read, - .mbox_stat_read = spu_hw_mbox_stat_read, - .mbox_stat_poll = spu_hw_mbox_stat_poll, - .ibox_read = spu_hw_ibox_read, - .wbox_write = spu_hw_wbox_write, - .signal1_read = spu_hw_signal1_read, - .signal1_write = spu_hw_signal1_write, - .signal2_read = spu_hw_signal2_read, - .signal2_write = spu_hw_signal2_write, - .signal1_type_set = spu_hw_signal1_type_set, - .signal1_type_get = spu_hw_signal1_type_get, - .signal2_type_set = spu_hw_signal2_type_set, - .signal2_type_get = spu_hw_signal2_type_get, - .npc_read = spu_hw_npc_read, - .npc_write = spu_hw_npc_write, - .status_read = spu_hw_status_read, - .get_ls = spu_hw_get_ls, - .runcntl_write = spu_hw_runcntl_write, - .runcntl_stop = spu_hw_runcntl_stop, -}; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/inode.c b/trunk/arch/powerpc/platforms/cell/spufs/inode.c deleted file mode 100644 index 1f3507c75e90..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/inode.c +++ /dev/null @@ -1,486 +0,0 @@ -/* - * SPU file system - * - * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 - * - * Author: Arnd Bergmann - * - * 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, 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "spufs.h" - -static kmem_cache_t *spufs_inode_cache; - -static struct inode * -spufs_alloc_inode(struct super_block *sb) -{ - struct spufs_inode_info *ei; - - ei = kmem_cache_alloc(spufs_inode_cache, SLAB_KERNEL); - if (!ei) - return NULL; - return &ei->vfs_inode; -} - -static void -spufs_destroy_inode(struct inode *inode) -{ - kmem_cache_free(spufs_inode_cache, SPUFS_I(inode)); -} - -static void -spufs_init_once(void *p, kmem_cache_t * cachep, unsigned long flags) -{ - struct spufs_inode_info *ei = p; - - if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == - SLAB_CTOR_CONSTRUCTOR) { - inode_init_once(&ei->vfs_inode); - } -} - -static struct inode * -spufs_new_inode(struct super_block *sb, int mode) -{ - struct inode *inode; - - inode = new_inode(sb); - if (!inode) - goto out; - - inode->i_mode = mode; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; - inode->i_blksize = PAGE_CACHE_SIZE; - inode->i_blocks = 0; - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; -out: - return inode; -} - -static int -spufs_setattr(struct dentry *dentry, struct iattr *attr) -{ - struct inode *inode = dentry->d_inode; - - if ((attr->ia_valid & ATTR_SIZE) && - (attr->ia_size != inode->i_size)) - return -EINVAL; - return inode_setattr(inode, attr); -} - - -static int -spufs_new_file(struct super_block *sb, struct dentry *dentry, - struct file_operations *fops, int mode, - struct spu_context *ctx) -{ - static struct inode_operations spufs_file_iops = { - .setattr = spufs_setattr, - }; - struct inode *inode; - int ret; - - ret = -ENOSPC; - inode = spufs_new_inode(sb, S_IFREG | mode); - if (!inode) - goto out; - - ret = 0; - inode->i_op = &spufs_file_iops; - inode->i_fop = fops; - inode->u.generic_ip = SPUFS_I(inode)->i_ctx = get_spu_context(ctx); - d_add(dentry, inode); -out: - return ret; -} - -static void -spufs_delete_inode(struct inode *inode) -{ - if (SPUFS_I(inode)->i_ctx) - put_spu_context(SPUFS_I(inode)->i_ctx); - clear_inode(inode); -} - -static void spufs_prune_dir(struct dentry *dir) -{ - struct dentry *dentry, *tmp; - down(&dir->d_inode->i_sem); - list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) { - spin_lock(&dcache_lock); - spin_lock(&dentry->d_lock); - if (!(d_unhashed(dentry)) && dentry->d_inode) { - dget_locked(dentry); - __d_drop(dentry); - spin_unlock(&dentry->d_lock); - simple_unlink(dir->d_inode, dentry); - spin_unlock(&dcache_lock); - dput(dentry); - } else { - spin_unlock(&dentry->d_lock); - spin_unlock(&dcache_lock); - } - } - shrink_dcache_parent(dir); - up(&dir->d_inode->i_sem); -} - -static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) -{ - struct spu_context *ctx; - - /* remove all entries */ - down(&root->i_sem); - spufs_prune_dir(dir_dentry); - up(&root->i_sem); - - /* We have to give up the mm_struct */ - ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx; - spu_forget(ctx); - - /* XXX Do we need to hold i_sem here ? */ - return simple_rmdir(root, dir_dentry); -} - -static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, - int mode, struct spu_context *ctx) -{ - struct dentry *dentry; - int ret; - - while (files->name && files->name[0]) { - ret = -ENOMEM; - dentry = d_alloc_name(dir, files->name); - if (!dentry) - goto out; - ret = spufs_new_file(dir->d_sb, dentry, files->ops, - files->mode & mode, ctx); - if (ret) - goto out; - files++; - } - return 0; -out: - spufs_prune_dir(dir); - return ret; -} - -static int spufs_dir_close(struct inode *inode, struct file *file) -{ - struct inode *dir; - struct dentry *dentry; - int ret; - - dentry = file->f_dentry; - dir = dentry->d_parent->d_inode; - - ret = spufs_rmdir(dir, dentry); - WARN_ON(ret); - - return dcache_dir_close(inode, file); -} - -struct inode_operations spufs_dir_inode_operations = { - .lookup = simple_lookup, -}; - -struct file_operations spufs_context_fops = { - .open = dcache_dir_open, - .release = spufs_dir_close, - .llseek = dcache_dir_lseek, - .read = generic_read_dir, - .readdir = dcache_readdir, - .fsync = simple_sync_file, -}; - -static int -spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode) -{ - int ret; - struct inode *inode; - struct spu_context *ctx; - - ret = -ENOSPC; - inode = spufs_new_inode(dir->i_sb, mode | S_IFDIR); - if (!inode) - goto out; - - if (dir->i_mode & S_ISGID) { - inode->i_gid = dir->i_gid; - inode->i_mode &= S_ISGID; - } - ctx = alloc_spu_context(inode->i_mapping); - SPUFS_I(inode)->i_ctx = ctx; - if (!ctx) - goto out_iput; - - inode->i_op = &spufs_dir_inode_operations; - inode->i_fop = &simple_dir_operations; - ret = spufs_fill_dir(dentry, spufs_dir_contents, mode, ctx); - if (ret) - goto out_free_ctx; - - d_instantiate(dentry, inode); - dget(dentry); - dir->i_nlink++; - dentry->d_inode->i_nlink++; - goto out; - -out_free_ctx: - put_spu_context(ctx); -out_iput: - iput(inode); -out: - return ret; -} - -static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt) -{ - int ret; - struct file *filp; - - ret = get_unused_fd(); - if (ret < 0) { - dput(dentry); - mntput(mnt); - goto out; - } - - filp = dentry_open(dentry, mnt, O_RDONLY); - if (IS_ERR(filp)) { - put_unused_fd(ret); - ret = PTR_ERR(filp); - goto out; - } - - filp->f_op = &spufs_context_fops; - fd_install(ret, filp); -out: - return ret; -} - -static struct file_system_type spufs_type; - -long spufs_create_thread(struct nameidata *nd, - unsigned int flags, mode_t mode) -{ - struct dentry *dentry; - int ret; - - /* need to be at the root of spufs */ - ret = -EINVAL; - if (nd->dentry->d_sb->s_type != &spufs_type || - nd->dentry != nd->dentry->d_sb->s_root) - goto out; - - dentry = lookup_create(nd, 1); - ret = PTR_ERR(dentry); - if (IS_ERR(dentry)) - goto out_dir; - - ret = -EEXIST; - if (dentry->d_inode) - goto out_dput; - - mode &= ~current->fs->umask; - ret = spufs_mkdir(nd->dentry->d_inode, dentry, mode & S_IRWXUGO); - if (ret) - goto out_dput; - - /* - * get references for dget and mntget, will be released - * in error path of *_open(). - */ - ret = spufs_context_open(dget(dentry), mntget(nd->mnt)); - if (ret < 0) - spufs_rmdir(nd->dentry->d_inode, dentry); - -out_dput: - dput(dentry); -out_dir: - up(&nd->dentry->d_inode->i_sem); -out: - return ret; -} - -/* File system initialization */ -enum { - Opt_uid, Opt_gid, Opt_err, -}; - -static match_table_t spufs_tokens = { - { Opt_uid, "uid=%d" }, - { Opt_gid, "gid=%d" }, - { Opt_err, NULL }, -}; - -static int -spufs_parse_options(char *options, struct inode *root) -{ - char *p; - substring_t args[MAX_OPT_ARGS]; - - while ((p = strsep(&options, ",")) != NULL) { - int token, option; - - if (!*p) - continue; - - token = match_token(p, spufs_tokens, args); - switch (token) { - case Opt_uid: - if (match_int(&args[0], &option)) - return 0; - root->i_uid = option; - break; - case Opt_gid: - if (match_int(&args[0], &option)) - return 0; - root->i_gid = option; - break; - default: - return 0; - } - } - return 1; -} - -static int -spufs_create_root(struct super_block *sb, void *data) -{ - struct inode *inode; - int ret; - - ret = -ENOMEM; - inode = spufs_new_inode(sb, S_IFDIR | 0775); - if (!inode) - goto out; - - inode->i_op = &spufs_dir_inode_operations; - inode->i_fop = &simple_dir_operations; - SPUFS_I(inode)->i_ctx = NULL; - - ret = -EINVAL; - if (!spufs_parse_options(data, inode)) - goto out_iput; - - ret = -ENOMEM; - sb->s_root = d_alloc_root(inode); - if (!sb->s_root) - goto out_iput; - - return 0; -out_iput: - iput(inode); -out: - return ret; -} - -static int -spufs_fill_super(struct super_block *sb, void *data, int silent) -{ - static struct super_operations s_ops = { - .alloc_inode = spufs_alloc_inode, - .destroy_inode = spufs_destroy_inode, - .statfs = simple_statfs, - .delete_inode = spufs_delete_inode, - .drop_inode = generic_delete_inode, - }; - - sb->s_maxbytes = MAX_LFS_FILESIZE; - sb->s_blocksize = PAGE_CACHE_SIZE; - sb->s_blocksize_bits = PAGE_CACHE_SHIFT; - sb->s_magic = SPUFS_MAGIC; - sb->s_op = &s_ops; - - return spufs_create_root(sb, data); -} - -static struct super_block * -spufs_get_sb(struct file_system_type *fstype, int flags, - const char *name, void *data) -{ - return get_sb_single(fstype, flags, data, spufs_fill_super); -} - -static struct file_system_type spufs_type = { - .owner = THIS_MODULE, - .name = "spufs", - .get_sb = spufs_get_sb, - .kill_sb = kill_litter_super, -}; - -static int spufs_init(void) -{ - int ret; - ret = -ENOMEM; - spufs_inode_cache = kmem_cache_create("spufs_inode_cache", - sizeof(struct spufs_inode_info), 0, - SLAB_HWCACHE_ALIGN, spufs_init_once, NULL); - - if (!spufs_inode_cache) - goto out; - if (spu_sched_init() != 0) { - kmem_cache_destroy(spufs_inode_cache); - goto out; - } - ret = register_filesystem(&spufs_type); - if (ret) - goto out_cache; - ret = register_spu_syscalls(&spufs_calls); - if (ret) - goto out_fs; - return 0; -out_fs: - unregister_filesystem(&spufs_type); -out_cache: - kmem_cache_destroy(spufs_inode_cache); -out: - return ret; -} -module_init(spufs_init); - -static void spufs_exit(void) -{ - spu_sched_exit(); - unregister_spu_syscalls(&spufs_calls); - unregister_filesystem(&spufs_type); - kmem_cache_destroy(spufs_inode_cache); -} -module_exit(spufs_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Arnd Bergmann "); - diff --git a/trunk/arch/powerpc/platforms/cell/spufs/run.c b/trunk/arch/powerpc/platforms/cell/spufs/run.c deleted file mode 100644 index 18ea8866c61a..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/run.c +++ /dev/null @@ -1,131 +0,0 @@ -#include -#include - -#include - -#include "spufs.h" - -/* interrupt-level stop callback function. */ -void spufs_stop_callback(struct spu *spu) -{ - struct spu_context *ctx = spu->ctx; - - wake_up_all(&ctx->stop_wq); -} - -static inline int spu_stopped(struct spu_context *ctx, u32 * stat) -{ - struct spu *spu; - u64 pte_fault; - - *stat = ctx->ops->status_read(ctx); - if (ctx->state != SPU_STATE_RUNNABLE) - return 1; - spu = ctx->spu; - pte_fault = spu->dsisr & - (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED); - return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0; -} - -static inline int spu_run_init(struct spu_context *ctx, u32 * npc, - u32 * status) -{ - int ret; - - if ((ret = spu_acquire_runnable(ctx)) != 0) - return ret; - ctx->ops->npc_write(ctx, *npc); - ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); - return 0; -} - -static inline int spu_run_fini(struct spu_context *ctx, u32 * npc, - u32 * status) -{ - int ret = 0; - - *status = ctx->ops->status_read(ctx); - *npc = ctx->ops->npc_read(ctx); - spu_release(ctx); - - if (signal_pending(current)) - ret = -ERESTARTSYS; - if (unlikely(current->ptrace & PT_PTRACED)) { - if ((*status & SPU_STATUS_STOPPED_BY_STOP) - && (*status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) { - force_sig(SIGTRAP, current); - ret = -ERESTARTSYS; - } - } - return ret; -} - -static inline int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc, - u32 *status) -{ - int ret; - - if ((ret = spu_run_fini(ctx, npc, status)) != 0) - return ret; - if (*status & (SPU_STATUS_STOPPED_BY_STOP | - SPU_STATUS_STOPPED_BY_HALT)) { - return *status; - } - if ((ret = spu_run_init(ctx, npc, status)) != 0) - return ret; - return 0; -} - -static inline int spu_process_events(struct spu_context *ctx) -{ - struct spu *spu = ctx->spu; - u64 pte_fault = MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED; - int ret = 0; - - if (spu->dsisr & pte_fault) - ret = spu_irq_class_1_bottom(spu); - if (spu->class_0_pending) - ret = spu_irq_class_0_bottom(spu); - if (!ret && signal_pending(current)) - ret = -ERESTARTSYS; - return ret; -} - -long spufs_run_spu(struct file *file, struct spu_context *ctx, - u32 * npc, u32 * status) -{ - int ret; - - if (down_interruptible(&ctx->run_sema)) - return -ERESTARTSYS; - - ret = spu_run_init(ctx, npc, status); - if (ret) - goto out; - - do { - ret = spufs_wait(ctx->stop_wq, spu_stopped(ctx, status)); - if (unlikely(ret)) - break; - if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { - ret = spu_reacquire_runnable(ctx, npc, status); - if (ret) - goto out; - continue; - } - ret = spu_process_events(ctx); - - } while (!ret && !(*status & (SPU_STATUS_STOPPED_BY_STOP | - SPU_STATUS_STOPPED_BY_HALT))); - - ctx->ops->runcntl_stop(ctx); - ret = spu_run_fini(ctx, npc, status); - if (!ret) - ret = *status; - spu_yield(ctx); - -out: - up(&ctx->run_sema); - return ret; -} - diff --git a/trunk/arch/powerpc/platforms/cell/spufs/sched.c b/trunk/arch/powerpc/platforms/cell/spufs/sched.c deleted file mode 100644 index 963182fbd1aa..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/sched.c +++ /dev/null @@ -1,461 +0,0 @@ -/* sched.c - SPU scheduler. - * - * Copyright (C) IBM 2005 - * Author: Mark Nutter - * - * SPU scheduler, based on Linux thread priority. For now use - * a simple "cooperative" yield model with no preemption. SPU - * scheduling will eventually be preemptive: When a thread with - * a higher static priority gets ready to run, then an active SPU - * context will be preempted and returned to the waitq. - * - * 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, 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. - */ - -#undef DEBUG - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "spufs.h" - -#define SPU_MIN_TIMESLICE (100 * HZ / 1000) - -#define SPU_BITMAP_SIZE (((MAX_PRIO+BITS_PER_LONG)/BITS_PER_LONG)+1) -struct spu_prio_array { - atomic_t nr_blocked; - unsigned long bitmap[SPU_BITMAP_SIZE]; - wait_queue_head_t waitq[MAX_PRIO]; -}; - -/* spu_runqueue - This is the main runqueue data structure for SPUs. */ -struct spu_runqueue { - struct semaphore sem; - unsigned long nr_active; - unsigned long nr_idle; - unsigned long nr_switches; - struct list_head active_list; - struct list_head idle_list; - struct spu_prio_array prio; -}; - -static struct spu_runqueue *spu_runqueues = NULL; - -static inline struct spu_runqueue *spu_rq(void) -{ - /* Future: make this a per-NODE array, - * and use cpu_to_node(smp_processor_id()) - */ - return spu_runqueues; -} - -static inline struct spu *del_idle(struct spu_runqueue *rq) -{ - struct spu *spu; - - BUG_ON(rq->nr_idle <= 0); - BUG_ON(list_empty(&rq->idle_list)); - /* Future: Move SPU out of low-power SRI state. */ - spu = list_entry(rq->idle_list.next, struct spu, sched_list); - list_del_init(&spu->sched_list); - rq->nr_idle--; - return spu; -} - -static inline void del_active(struct spu_runqueue *rq, struct spu *spu) -{ - BUG_ON(rq->nr_active <= 0); - BUG_ON(list_empty(&rq->active_list)); - list_del_init(&spu->sched_list); - rq->nr_active--; -} - -static inline void add_idle(struct spu_runqueue *rq, struct spu *spu) -{ - /* Future: Put SPU into low-power SRI state. */ - list_add_tail(&spu->sched_list, &rq->idle_list); - rq->nr_idle++; -} - -static inline void add_active(struct spu_runqueue *rq, struct spu *spu) -{ - rq->nr_active++; - rq->nr_switches++; - list_add_tail(&spu->sched_list, &rq->active_list); -} - -static void prio_wakeup(struct spu_runqueue *rq) -{ - if (atomic_read(&rq->prio.nr_blocked) && rq->nr_idle) { - int best = sched_find_first_bit(rq->prio.bitmap); - if (best < MAX_PRIO) { - wait_queue_head_t *wq = &rq->prio.waitq[best]; - wake_up_interruptible_nr(wq, 1); - } - } -} - -static void prio_wait(struct spu_runqueue *rq, struct spu_context *ctx, - u64 flags) -{ - int prio = current->prio; - wait_queue_head_t *wq = &rq->prio.waitq[prio]; - DEFINE_WAIT(wait); - - __set_bit(prio, rq->prio.bitmap); - atomic_inc(&rq->prio.nr_blocked); - prepare_to_wait_exclusive(wq, &wait, TASK_INTERRUPTIBLE); - if (!signal_pending(current)) { - up(&rq->sem); - up_write(&ctx->state_sema); - pr_debug("%s: pid=%d prio=%d\n", __FUNCTION__, - current->pid, current->prio); - schedule(); - down_write(&ctx->state_sema); - down(&rq->sem); - } - finish_wait(wq, &wait); - atomic_dec(&rq->prio.nr_blocked); - if (!waitqueue_active(wq)) - __clear_bit(prio, rq->prio.bitmap); -} - -static inline int is_best_prio(struct spu_runqueue *rq) -{ - int best_prio; - - best_prio = sched_find_first_bit(rq->prio.bitmap); - return (current->prio < best_prio) ? 1 : 0; -} - -static inline void mm_needs_global_tlbie(struct mm_struct *mm) -{ - /* Global TLBIE broadcast required with SPEs. */ -#if (NR_CPUS > 1) - __cpus_setall(&mm->cpu_vm_mask, NR_CPUS); -#else - __cpus_setall(&mm->cpu_vm_mask, NR_CPUS+1); /* is this ok? */ -#endif -} - -static inline void bind_context(struct spu *spu, struct spu_context *ctx) -{ - pr_debug("%s: pid=%d SPU=%d\n", __FUNCTION__, current->pid, - spu->number); - spu->ctx = ctx; - spu->flags = 0; - ctx->flags = 0; - ctx->spu = spu; - ctx->ops = &spu_hw_ops; - spu->pid = current->pid; - spu->prio = current->prio; - spu->mm = ctx->owner; - mm_needs_global_tlbie(spu->mm); - spu->ibox_callback = spufs_ibox_callback; - spu->wbox_callback = spufs_wbox_callback; - spu->stop_callback = spufs_stop_callback; - mb(); - spu_unmap_mappings(ctx); - spu_restore(&ctx->csa, spu); - spu->timestamp = jiffies; -} - -static inline void unbind_context(struct spu *spu, struct spu_context *ctx) -{ - pr_debug("%s: unbind pid=%d SPU=%d\n", __FUNCTION__, - spu->pid, spu->number); - spu_unmap_mappings(ctx); - spu_save(&ctx->csa, spu); - spu->timestamp = jiffies; - ctx->state = SPU_STATE_SAVED; - spu->ibox_callback = NULL; - spu->wbox_callback = NULL; - spu->stop_callback = NULL; - spu->mm = NULL; - spu->pid = 0; - spu->prio = MAX_PRIO; - ctx->ops = &spu_backing_ops; - ctx->spu = NULL; - ctx->flags = 0; - spu->flags = 0; - spu->ctx = NULL; -} - -static void spu_reaper(void *data) -{ - struct spu_context *ctx = data; - struct spu *spu; - - down_write(&ctx->state_sema); - spu = ctx->spu; - if (spu && test_bit(SPU_CONTEXT_PREEMPT, &ctx->flags)) { - if (atomic_read(&spu->rq->prio.nr_blocked)) { - pr_debug("%s: spu=%d\n", __func__, spu->number); - ctx->ops->runcntl_stop(ctx); - spu_deactivate(ctx); - wake_up_all(&ctx->stop_wq); - } else { - clear_bit(SPU_CONTEXT_PREEMPT, &ctx->flags); - } - } - up_write(&ctx->state_sema); - put_spu_context(ctx); -} - -static void schedule_spu_reaper(struct spu_runqueue *rq, struct spu *spu) -{ - struct spu_context *ctx = get_spu_context(spu->ctx); - unsigned long now = jiffies; - unsigned long expire = spu->timestamp + SPU_MIN_TIMESLICE; - - set_bit(SPU_CONTEXT_PREEMPT, &ctx->flags); - INIT_WORK(&ctx->reap_work, spu_reaper, ctx); - if (time_after(now, expire)) - schedule_work(&ctx->reap_work); - else - schedule_delayed_work(&ctx->reap_work, expire - now); -} - -static void check_preempt_active(struct spu_runqueue *rq) -{ - struct list_head *p; - struct spu *worst = NULL; - - list_for_each(p, &rq->active_list) { - struct spu *spu = list_entry(p, struct spu, sched_list); - struct spu_context *ctx = spu->ctx; - if (!test_bit(SPU_CONTEXT_PREEMPT, &ctx->flags)) { - if (!worst || (spu->prio > worst->prio)) { - worst = spu; - } - } - } - if (worst && (current->prio < worst->prio)) - schedule_spu_reaper(rq, worst); -} - -static struct spu *get_idle_spu(struct spu_context *ctx, u64 flags) -{ - struct spu_runqueue *rq; - struct spu *spu = NULL; - - rq = spu_rq(); - down(&rq->sem); - for (;;) { - if (rq->nr_idle > 0) { - if (is_best_prio(rq)) { - /* Fall through. */ - spu = del_idle(rq); - break; - } else { - prio_wakeup(rq); - up(&rq->sem); - yield(); - if (signal_pending(current)) { - return NULL; - } - rq = spu_rq(); - down(&rq->sem); - continue; - } - } else { - check_preempt_active(rq); - prio_wait(rq, ctx, flags); - if (signal_pending(current)) { - prio_wakeup(rq); - spu = NULL; - break; - } - continue; - } - } - up(&rq->sem); - return spu; -} - -static void put_idle_spu(struct spu *spu) -{ - struct spu_runqueue *rq = spu->rq; - - down(&rq->sem); - add_idle(rq, spu); - prio_wakeup(rq); - up(&rq->sem); -} - -static int get_active_spu(struct spu *spu) -{ - struct spu_runqueue *rq = spu->rq; - struct list_head *p; - struct spu *tmp; - int rc = 0; - - down(&rq->sem); - list_for_each(p, &rq->active_list) { - tmp = list_entry(p, struct spu, sched_list); - if (tmp == spu) { - del_active(rq, spu); - rc = 1; - break; - } - } - up(&rq->sem); - return rc; -} - -static void put_active_spu(struct spu *spu) -{ - struct spu_runqueue *rq = spu->rq; - - down(&rq->sem); - add_active(rq, spu); - up(&rq->sem); -} - -/* Lock order: - * spu_activate() & spu_deactivate() require the - * caller to have down_write(&ctx->state_sema). - * - * The rq->sem is breifly held (inside or outside a - * given ctx lock) for list management, but is never - * held during save/restore. - */ - -int spu_activate(struct spu_context *ctx, u64 flags) -{ - struct spu *spu; - - if (ctx->spu) - return 0; - spu = get_idle_spu(ctx, flags); - if (!spu) - return (signal_pending(current)) ? -ERESTARTSYS : -EAGAIN; - bind_context(spu, ctx); - /* - * We're likely to wait for interrupts on the same - * CPU that we are now on, so send them here. - */ - spu_irq_setaffinity(spu, raw_smp_processor_id()); - put_active_spu(spu); - return 0; -} - -void spu_deactivate(struct spu_context *ctx) -{ - struct spu *spu; - int needs_idle; - - spu = ctx->spu; - if (!spu) - return; - needs_idle = get_active_spu(spu); - unbind_context(spu, ctx); - if (needs_idle) - put_idle_spu(spu); -} - -void spu_yield(struct spu_context *ctx) -{ - struct spu *spu; - int need_yield = 0; - - down_write(&ctx->state_sema); - spu = ctx->spu; - if (spu && (sched_find_first_bit(spu->rq->prio.bitmap) < MAX_PRIO)) { - pr_debug("%s: yielding SPU %d\n", __FUNCTION__, spu->number); - spu_deactivate(ctx); - ctx->state = SPU_STATE_SAVED; - need_yield = 1; - } else if (spu) { - spu->prio = MAX_PRIO; - } - up_write(&ctx->state_sema); - if (unlikely(need_yield)) - yield(); -} - -int __init spu_sched_init(void) -{ - struct spu_runqueue *rq; - struct spu *spu; - int i; - - rq = spu_runqueues = kmalloc(sizeof(struct spu_runqueue), GFP_KERNEL); - if (!rq) { - printk(KERN_WARNING "%s: Unable to allocate runqueues.\n", - __FUNCTION__); - return 1; - } - memset(rq, 0, sizeof(struct spu_runqueue)); - init_MUTEX(&rq->sem); - INIT_LIST_HEAD(&rq->active_list); - INIT_LIST_HEAD(&rq->idle_list); - rq->nr_active = 0; - rq->nr_idle = 0; - rq->nr_switches = 0; - atomic_set(&rq->prio.nr_blocked, 0); - for (i = 0; i < MAX_PRIO; i++) { - init_waitqueue_head(&rq->prio.waitq[i]); - __clear_bit(i, rq->prio.bitmap); - } - __set_bit(MAX_PRIO, rq->prio.bitmap); - for (;;) { - spu = spu_alloc(); - if (!spu) - break; - pr_debug("%s: adding SPU[%d]\n", __FUNCTION__, spu->number); - add_idle(rq, spu); - spu->rq = rq; - spu->timestamp = jiffies; - } - if (!rq->nr_idle) { - printk(KERN_WARNING "%s: No available SPUs.\n", __FUNCTION__); - kfree(rq); - return 1; - } - return 0; -} - -void __exit spu_sched_exit(void) -{ - struct spu_runqueue *rq = spu_rq(); - struct spu *spu; - - if (!rq) { - printk(KERN_WARNING "%s: no runqueues!\n", __FUNCTION__); - return; - } - while (rq->nr_idle > 0) { - spu = del_idle(rq); - if (!spu) - break; - spu_free(spu); - } - kfree(rq); -} diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spu_restore.c b/trunk/arch/powerpc/platforms/cell/spufs/spu_restore.c deleted file mode 100644 index 0bf723dcd677..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/spu_restore.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * spu_restore.c - * - * (C) Copyright IBM Corp. 2005 - * - * SPU-side context restore sequence outlined in - * Synergistic Processor Element Book IV - * - * Author: Mark Nutter - * - * 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, 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. - * - */ - - -#ifndef LS_SIZE -#define LS_SIZE 0x40000 /* 256K (in bytes) */ -#endif - -typedef unsigned int u32; -typedef unsigned long long u64; - -#include -#include -#include "spu_utils.h" - -#define BR_INSTR 0x327fff80 /* br -4 */ -#define NOP_INSTR 0x40200000 /* nop */ -#define HEQ_INSTR 0x7b000000 /* heq $0, $0 */ -#define STOP_INSTR 0x00000000 /* stop 0x0 */ -#define ILLEGAL_INSTR 0x00800000 /* illegal instr */ -#define RESTORE_COMPLETE 0x00003ffc /* stop 0x3ffc */ - -static inline void fetch_regs_from_mem(addr64 lscsa_ea) -{ - unsigned int ls = (unsigned int)®s_spill[0]; - unsigned int size = sizeof(regs_spill); - unsigned int tag_id = 0; - unsigned int cmd = 0x40; /* GET */ - - spu_writech(MFC_LSA, ls); - spu_writech(MFC_EAH, lscsa_ea.ui[0]); - spu_writech(MFC_EAL, lscsa_ea.ui[1]); - spu_writech(MFC_Size, size); - spu_writech(MFC_TagID, tag_id); - spu_writech(MFC_Cmd, cmd); -} - -static inline void restore_upper_240kb(addr64 lscsa_ea) -{ - unsigned int ls = 16384; - unsigned int list = (unsigned int)&dma_list[0]; - unsigned int size = sizeof(dma_list); - unsigned int tag_id = 0; - unsigned int cmd = 0x44; /* GETL */ - - /* Restore, Step 4: - * Enqueue the GETL command (tag 0) to the MFC SPU command - * queue to transfer the upper 240 kb of LS from CSA. - */ - spu_writech(MFC_LSA, ls); - spu_writech(MFC_EAH, lscsa_ea.ui[0]); - spu_writech(MFC_EAL, list); - spu_writech(MFC_Size, size); - spu_writech(MFC_TagID, tag_id); - spu_writech(MFC_Cmd, cmd); -} - -static inline void restore_decr(void) -{ - unsigned int offset; - unsigned int decr_running; - unsigned int decr; - - /* Restore, Step 6: - * If the LSCSA "decrementer running" flag is set - * then write the SPU_WrDec channel with the - * decrementer value from LSCSA. - */ - offset = LSCSA_QW_OFFSET(decr_status); - decr_running = regs_spill[offset].slot[0]; - if (decr_running) { - offset = LSCSA_QW_OFFSET(decr); - decr = regs_spill[offset].slot[0]; - spu_writech(SPU_WrDec, decr); - } -} - -static inline void write_ppu_mb(void) -{ - unsigned int offset; - unsigned int data; - - /* Restore, Step 11: - * Write the MFC_WrOut_MB channel with the PPU_MB - * data from LSCSA. - */ - offset = LSCSA_QW_OFFSET(ppu_mb); - data = regs_spill[offset].slot[0]; - spu_writech(SPU_WrOutMbox, data); -} - -static inline void write_ppuint_mb(void) -{ - unsigned int offset; - unsigned int data; - - /* Restore, Step 12: - * Write the MFC_WrInt_MB channel with the PPUINT_MB - * data from LSCSA. - */ - offset = LSCSA_QW_OFFSET(ppuint_mb); - data = regs_spill[offset].slot[0]; - spu_writech(SPU_WrOutIntrMbox, data); -} - -static inline void restore_fpcr(void) -{ - unsigned int offset; - vector unsigned int fpcr; - - /* Restore, Step 13: - * Restore the floating-point status and control - * register from the LSCSA. - */ - offset = LSCSA_QW_OFFSET(fpcr); - fpcr = regs_spill[offset].v; - spu_mtfpscr(fpcr); -} - -static inline void restore_srr0(void) -{ - unsigned int offset; - unsigned int srr0; - - /* Restore, Step 14: - * Restore the SPU SRR0 data from the LSCSA. - */ - offset = LSCSA_QW_OFFSET(srr0); - srr0 = regs_spill[offset].slot[0]; - spu_writech(SPU_WrSRR0, srr0); -} - -static inline void restore_event_mask(void) -{ - unsigned int offset; - unsigned int event_mask; - - /* Restore, Step 15: - * Restore the SPU_RdEventMsk data from the LSCSA. - */ - offset = LSCSA_QW_OFFSET(event_mask); - event_mask = regs_spill[offset].slot[0]; - spu_writech(SPU_WrEventMask, event_mask); -} - -static inline void restore_tag_mask(void) -{ - unsigned int offset; - unsigned int tag_mask; - - /* Restore, Step 16: - * Restore the SPU_RdTagMsk data from the LSCSA. - */ - offset = LSCSA_QW_OFFSET(tag_mask); - tag_mask = regs_spill[offset].slot[0]; - spu_writech(MFC_WrTagMask, tag_mask); -} - -static inline void restore_complete(void) -{ - extern void exit_fini(void); - unsigned int *exit_instrs = (unsigned int *)exit_fini; - unsigned int offset; - unsigned int stopped_status; - unsigned int stopped_code; - - /* Restore, Step 18: - * Issue a stop-and-signal instruction with - * "good context restore" signal value. - * - * Restore, Step 19: - * There may be additional instructions placed - * here by the PPE Sequence for SPU Context - * Restore in order to restore the correct - * "stopped state". - * - * This step is handled here by analyzing the - * LSCSA.stopped_status and then modifying the - * exit() function to behave appropriately. - */ - - offset = LSCSA_QW_OFFSET(stopped_status); - stopped_status = regs_spill[offset].slot[0]; - stopped_code = regs_spill[offset].slot[1]; - - switch (stopped_status) { - case SPU_STOPPED_STATUS_P_I: - /* SPU_Status[P,I]=1. Add illegal instruction - * followed by stop-and-signal instruction after - * end of restore code. - */ - exit_instrs[0] = RESTORE_COMPLETE; - exit_instrs[1] = ILLEGAL_INSTR; - exit_instrs[2] = STOP_INSTR | stopped_code; - break; - case SPU_STOPPED_STATUS_P_H: - /* SPU_Status[P,H]=1. Add 'heq $0, $0' followed - * by stop-and-signal instruction after end of - * restore code. - */ - exit_instrs[0] = RESTORE_COMPLETE; - exit_instrs[1] = HEQ_INSTR; - exit_instrs[2] = STOP_INSTR | stopped_code; - break; - case SPU_STOPPED_STATUS_S_P: - /* SPU_Status[S,P]=1. Add nop instruction - * followed by 'br -4' after end of restore - * code. - */ - exit_instrs[0] = RESTORE_COMPLETE; - exit_instrs[1] = STOP_INSTR | stopped_code; - exit_instrs[2] = NOP_INSTR; - exit_instrs[3] = BR_INSTR; - break; - case SPU_STOPPED_STATUS_S_I: - /* SPU_Status[S,I]=1. Add illegal instruction - * followed by 'br -4' after end of restore code. - */ - exit_instrs[0] = RESTORE_COMPLETE; - exit_instrs[1] = ILLEGAL_INSTR; - exit_instrs[2] = NOP_INSTR; - exit_instrs[3] = BR_INSTR; - break; - case SPU_STOPPED_STATUS_I: - /* SPU_Status[I]=1. Add illegal instruction followed - * by infinite loop after end of restore sequence. - */ - exit_instrs[0] = RESTORE_COMPLETE; - exit_instrs[1] = ILLEGAL_INSTR; - exit_instrs[2] = NOP_INSTR; - exit_instrs[3] = BR_INSTR; - break; - case SPU_STOPPED_STATUS_S: - /* SPU_Status[S]=1. Add two 'nop' instructions. */ - exit_instrs[0] = RESTORE_COMPLETE; - exit_instrs[1] = NOP_INSTR; - exit_instrs[2] = NOP_INSTR; - exit_instrs[3] = BR_INSTR; - break; - case SPU_STOPPED_STATUS_H: - /* SPU_Status[H]=1. Add 'heq $0, $0' instruction - * after end of restore code. - */ - exit_instrs[0] = RESTORE_COMPLETE; - exit_instrs[1] = HEQ_INSTR; - exit_instrs[2] = NOP_INSTR; - exit_instrs[3] = BR_INSTR; - break; - case SPU_STOPPED_STATUS_P: - /* SPU_Status[P]=1. Add stop-and-signal instruction - * after end of restore code. - */ - exit_instrs[0] = RESTORE_COMPLETE; - exit_instrs[1] = STOP_INSTR | stopped_code; - break; - case SPU_STOPPED_STATUS_R: - /* SPU_Status[I,S,H,P,R]=0. Add infinite loop. */ - exit_instrs[0] = RESTORE_COMPLETE; - exit_instrs[1] = NOP_INSTR; - exit_instrs[2] = NOP_INSTR; - exit_instrs[3] = BR_INSTR; - break; - default: - /* SPU_Status[R]=1. No additonal instructions. */ - break; - } - spu_sync(); -} - -/** - * main - entry point for SPU-side context restore. - * - * This code deviates from the documented sequence in the - * following aspects: - * - * 1. The EA for LSCSA is passed from PPE in the - * signal notification channels. - * 2. The register spill area is pulled by SPU - * into LS, rather than pushed by PPE. - * 3. All 128 registers are restored by exit(). - * 4. The exit() function is modified at run - * time in order to properly restore the - * SPU_Status register. - */ -int main() -{ - addr64 lscsa_ea; - - lscsa_ea.ui[0] = spu_readch(SPU_RdSigNotify1); - lscsa_ea.ui[1] = spu_readch(SPU_RdSigNotify2); - fetch_regs_from_mem(lscsa_ea); - - set_event_mask(); /* Step 1. */ - set_tag_mask(); /* Step 2. */ - build_dma_list(lscsa_ea); /* Step 3. */ - restore_upper_240kb(lscsa_ea); /* Step 4. */ - /* Step 5: done by 'exit'. */ - restore_decr(); /* Step 6. */ - enqueue_putllc(lscsa_ea); /* Step 7. */ - set_tag_update(); /* Step 8. */ - read_tag_status(); /* Step 9. */ - read_llar_status(); /* Step 10. */ - write_ppu_mb(); /* Step 11. */ - write_ppuint_mb(); /* Step 12. */ - restore_fpcr(); /* Step 13. */ - restore_srr0(); /* Step 14. */ - restore_event_mask(); /* Step 15. */ - restore_tag_mask(); /* Step 16. */ - /* Step 17. done by 'exit'. */ - restore_complete(); /* Step 18. */ - - return 0; -} diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_crt0.S b/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_crt0.S deleted file mode 100644 index 2905949debe1..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_crt0.S +++ /dev/null @@ -1,116 +0,0 @@ -/* - * crt0_r.S: Entry function for SPU-side context restore. - * - * Copyright (C) 2005 IBM - * - * Entry and exit function for SPU-side of the context restore - * sequence. Sets up an initial stack frame, then branches to - * 'main'. On return, restores all 128 registers from the LSCSA - * and exits. - * - * - * 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, 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. - */ - -#include - -.data -.align 7 -.globl regs_spill -regs_spill: -.space SIZEOF_SPU_SPILL_REGS, 0x0 - -.text -.global _start -_start: - /* Initialize the stack pointer to point to 16368 - * (16kb-16). The back chain pointer is initialized - * to NULL. - */ - il $0, 0 - il $SP, 16368 - stqd $0, 0($SP) - - /* Allocate a minimum stack frame for the called main. - * This is needed so that main has a place to save the - * link register when it calls another function. - */ - stqd $SP, -160($SP) - ai $SP, $SP, -160 - - /* Call the program's main function. */ - brsl $0, main - -.global exit -.global _exit -exit: -_exit: - /* SPU Context Restore, Step 5: Restore the remaining 112 GPRs. */ - ila $3, regs_spill + 256 -restore_regs: - lqr $4, restore_reg_insts -restore_reg_loop: - ai $4, $4, 4 - .balignl 16, 0x40200000 -restore_reg_insts: /* must be quad-word aligned. */ - lqd $16, 0($3) - lqd $17, 16($3) - lqd $18, 32($3) - lqd $19, 48($3) - andi $5, $4, 0x7F - stqr $4, restore_reg_insts - ai $3, $3, 64 - brnz $5, restore_reg_loop - - /* SPU Context Restore Step 17: Restore the first 16 GPRs. */ - lqa $0, regs_spill + 0 - lqa $1, regs_spill + 16 - lqa $2, regs_spill + 32 - lqa $3, regs_spill + 48 - lqa $4, regs_spill + 64 - lqa $5, regs_spill + 80 - lqa $6, regs_spill + 96 - lqa $7, regs_spill + 112 - lqa $8, regs_spill + 128 - lqa $9, regs_spill + 144 - lqa $10, regs_spill + 160 - lqa $11, regs_spill + 176 - lqa $12, regs_spill + 192 - lqa $13, regs_spill + 208 - lqa $14, regs_spill + 224 - lqa $15, regs_spill + 240 - - /* Under normal circumstances, the 'exit' function - * terminates with 'stop SPU_RESTORE_COMPLETE', - * indicating that the SPU-side restore code has - * completed. - * - * However it is possible that instructions immediately - * following the 'stop 0x3ffc' have been modified at run - * time so as to recreate the exact SPU_Status settings - * from the application, e.g. illegal instruciton, halt, - * etc. - */ -.global exit_fini -.global _exit_fini -exit_fini: -_exit_fini: - stop SPU_RESTORE_COMPLETE - stop 0 - stop 0 - stop 0 - - /* Pad the size of this crt0.o to be multiple of 16 bytes. */ -.balignl 16, 0x0 diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped b/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped deleted file mode 100644 index 1b2355ff7036..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped +++ /dev/null @@ -1,231 +0,0 @@ -/* - * spu_restore_dump.h: Copyright (C) 2005 IBM. - * Hex-dump auto generated from spu_restore.c. - * Do not edit! - */ -static unsigned int spu_restore_code[] __page_aligned = { -0x40800000, 0x409ff801, 0x24000080, 0x24fd8081, -0x1cd80081, 0x33001180, 0x42030003, 0x33800284, -0x1c010204, 0x40200000, 0x40200000, 0x40200000, -0x34000190, 0x34004191, 0x34008192, 0x3400c193, -0x141fc205, 0x23fffd84, 0x1c100183, 0x217ffa85, -0x3080a000, 0x3080a201, 0x3080a402, 0x3080a603, -0x3080a804, 0x3080aa05, 0x3080ac06, 0x3080ae07, -0x3080b008, 0x3080b209, 0x3080b40a, 0x3080b60b, -0x3080b80c, 0x3080ba0d, 0x3080bc0e, 0x3080be0f, -0x00003ffc, 0x00000000, 0x00000000, 0x00000000, -0x01a00182, 0x3ec00083, 0xb0a14103, 0x01a00204, -0x3ec10082, 0x4202800e, 0x04000703, 0xb0a14202, -0x21a00803, 0x3fbf028d, 0x3f20068d, 0x3fbe0682, -0x3fe30102, 0x21a00882, 0x3f82028f, 0x3fe3078f, -0x3fbf0784, 0x3f200204, 0x3fbe0204, 0x3fe30204, -0x04000203, 0x21a00903, 0x40848002, 0x21a00982, -0x40800003, 0x21a00a03, 0x40802002, 0x21a00a82, -0x21a00083, 0x40800082, 0x21a00b02, 0x10002818, -0x40a80002, 0x32800007, 0x4207000c, 0x18008208, -0x40a0000b, 0x4080020a, 0x40800709, 0x00200000, -0x42070002, 0x3ac30384, 0x1cffc489, 0x00200000, -0x18008383, 0x38830382, 0x4cffc486, 0x3ac28185, -0xb0408584, 0x28830382, 0x1c020387, 0x38828182, -0xb0408405, 0x1802c408, 0x28828182, 0x217ff886, -0x04000583, 0x21a00803, 0x3fbe0682, 0x3fe30102, -0x04000106, 0x21a00886, 0x04000603, 0x21a00903, -0x40803c02, 0x21a00982, 0x40800003, 0x04000184, -0x21a00a04, 0x40802202, 0x21a00a82, 0x42028005, -0x34208702, 0x21002282, 0x21a00804, 0x21a00886, -0x3fbf0782, 0x3f200102, 0x3fbe0102, 0x3fe30102, -0x21a00902, 0x40804003, 0x21a00983, 0x21a00a04, -0x40805a02, 0x21a00a82, 0x40800083, 0x21a00b83, -0x01a00c02, 0x01a00d83, 0x3420c282, 0x21a00e02, -0x34210283, 0x21a00f03, 0x34200284, 0x77400200, -0x3421c282, 0x21a00702, 0x34218283, 0x21a00083, -0x34214282, 0x21a00b02, 0x4200480c, 0x00200000, -0x1c010286, 0x34220284, 0x34220302, 0x0f608203, -0x5c024204, 0x3b81810b, 0x42013c02, 0x00200000, -0x18008185, 0x38808183, 0x3b814182, 0x21004e84, -0x4020007f, 0x35000100, 0x000004e0, 0x000002a0, -0x000002e8, 0x00000428, 0x00000360, 0x000002e8, -0x000004a0, 0x00000468, 0x000003c8, 0x00000360, -0x409ffe02, 0x30801203, 0x40800204, 0x3ec40085, -0x10009c09, 0x3ac10606, 0xb060c105, 0x4020007f, -0x4020007f, 0x20801203, 0x38810602, 0xb0408586, -0x28810602, 0x32004180, 0x34204702, 0x21a00382, -0x4020007f, 0x327fdc80, 0x409ffe02, 0x30801203, -0x40800204, 0x3ec40087, 0x40800405, 0x00200000, -0x40800606, 0x3ac10608, 0x3ac14609, 0x3ac1860a, -0xb060c107, 0x20801203, 0x41004003, 0x38810602, -0x4020007f, 0xb0408188, 0x4020007f, 0x28810602, -0x41201002, 0x38814603, 0x10009c09, 0xb060c109, -0x4020007f, 0x28814603, 0x41193f83, 0x38818602, -0x60ffc003, 0xb040818a, 0x28818602, 0x32003080, -0x409ffe02, 0x30801203, 0x40800204, 0x3ec40087, -0x41201008, 0x10009c14, 0x40800405, 0x3ac10609, -0x40800606, 0x3ac1460a, 0xb060c107, 0x3ac1860b, -0x20801203, 0x38810602, 0xb0408409, 0x28810602, -0x38814603, 0xb060c40a, 0x4020007f, 0x28814603, -0x41193f83, 0x38818602, 0x60ffc003, 0xb040818b, -0x28818602, 0x32002380, 0x409ffe02, 0x30801204, -0x40800205, 0x3ec40083, 0x40800406, 0x3ac14607, -0x3ac18608, 0xb0810103, 0x41004002, 0x20801204, -0x4020007f, 0x38814603, 0x10009c0b, 0xb060c107, -0x4020007f, 0x4020007f, 0x28814603, 0x38818602, -0x4020007f, 0x4020007f, 0xb0408588, 0x28818602, -0x4020007f, 0x32001780, 0x409ffe02, 0x1000640e, -0x40800204, 0x30801203, 0x40800405, 0x3ec40087, -0x40800606, 0x3ac10608, 0x3ac14609, 0x3ac1860a, -0xb060c107, 0x20801203, 0x413d8003, 0x38810602, -0x4020007f, 0x327fd780, 0x409ffe02, 0x10007f0c, -0x40800205, 0x30801204, 0x40800406, 0x3ec40083, -0x3ac14607, 0x3ac18608, 0xb0810103, 0x413d8002, -0x20801204, 0x38814603, 0x4020007f, 0x327feb80, -0x409ffe02, 0x30801203, 0x40800204, 0x3ec40087, -0x40800405, 0x1000650a, 0x40800606, 0x3ac10608, -0x3ac14609, 0x3ac1860a, 0xb060c107, 0x20801203, -0x38810602, 0xb0408588, 0x4020007f, 0x327fc980, -0x00400000, 0x40800003, 0x4020007f, 0x35000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -}; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spu_save.c b/trunk/arch/powerpc/platforms/cell/spufs/spu_save.c deleted file mode 100644 index 196033b8a579..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/spu_save.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * spu_save.c - * - * (C) Copyright IBM Corp. 2005 - * - * SPU-side context save sequence outlined in - * Synergistic Processor Element Book IV - * - * Author: Mark Nutter - * - * 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, 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. - * - */ - - -#ifndef LS_SIZE -#define LS_SIZE 0x40000 /* 256K (in bytes) */ -#endif - -typedef unsigned int u32; -typedef unsigned long long u64; - -#include -#include -#include "spu_utils.h" - -static inline void save_event_mask(void) -{ - unsigned int offset; - - /* Save, Step 2: - * Read the SPU_RdEventMsk channel and save to the LSCSA. - */ - offset = LSCSA_QW_OFFSET(event_mask); - regs_spill[offset].slot[0] = spu_readch(SPU_RdEventStatMask); -} - -static inline void save_tag_mask(void) -{ - unsigned int offset; - - /* Save, Step 3: - * Read the SPU_RdTagMsk channel and save to the LSCSA. - */ - offset = LSCSA_QW_OFFSET(tag_mask); - regs_spill[offset].slot[0] = spu_readch(MFC_RdTagMask); -} - -static inline void save_upper_240kb(addr64 lscsa_ea) -{ - unsigned int ls = 16384; - unsigned int list = (unsigned int)&dma_list[0]; - unsigned int size = sizeof(dma_list); - unsigned int tag_id = 0; - unsigned int cmd = 0x24; /* PUTL */ - - /* Save, Step 7: - * Enqueue the PUTL command (tag 0) to the MFC SPU command - * queue to transfer the remaining 240 kb of LS to CSA. - */ - spu_writech(MFC_LSA, ls); - spu_writech(MFC_EAH, lscsa_ea.ui[0]); - spu_writech(MFC_EAL, list); - spu_writech(MFC_Size, size); - spu_writech(MFC_TagID, tag_id); - spu_writech(MFC_Cmd, cmd); -} - -static inline void save_fpcr(void) -{ - // vector unsigned int fpcr; - unsigned int offset; - - /* Save, Step 9: - * Issue the floating-point status and control register - * read instruction, and save to the LSCSA. - */ - offset = LSCSA_QW_OFFSET(fpcr); - regs_spill[offset].v = spu_mffpscr(); -} - -static inline void save_decr(void) -{ - unsigned int offset; - - /* Save, Step 10: - * Read and save the SPU_RdDec channel data to - * the LSCSA. - */ - offset = LSCSA_QW_OFFSET(decr); - regs_spill[offset].slot[0] = spu_readch(SPU_RdDec); -} - -static inline void save_srr0(void) -{ - unsigned int offset; - - /* Save, Step 11: - * Read and save the SPU_WSRR0 channel data to - * the LSCSA. - */ - offset = LSCSA_QW_OFFSET(srr0); - regs_spill[offset].slot[0] = spu_readch(SPU_RdSRR0); -} - -static inline void spill_regs_to_mem(addr64 lscsa_ea) -{ - unsigned int ls = (unsigned int)®s_spill[0]; - unsigned int size = sizeof(regs_spill); - unsigned int tag_id = 0; - unsigned int cmd = 0x20; /* PUT */ - - /* Save, Step 13: - * Enqueue a PUT command (tag 0) to send the LSCSA - * to the CSA. - */ - spu_writech(MFC_LSA, ls); - spu_writech(MFC_EAH, lscsa_ea.ui[0]); - spu_writech(MFC_EAL, lscsa_ea.ui[1]); - spu_writech(MFC_Size, size); - spu_writech(MFC_TagID, tag_id); - spu_writech(MFC_Cmd, cmd); -} - -static inline void enqueue_sync(addr64 lscsa_ea) -{ - unsigned int tag_id = 0; - unsigned int cmd = 0xCC; - - /* Save, Step 14: - * Enqueue an MFC_SYNC command (tag 0). - */ - spu_writech(MFC_TagID, tag_id); - spu_writech(MFC_Cmd, cmd); -} - -static inline void save_complete(void) -{ - /* Save, Step 18: - * Issue a stop-and-signal instruction indicating - * "save complete". Note: This function will not - * return!! - */ - spu_stop(SPU_SAVE_COMPLETE); -} - -/** - * main - entry point for SPU-side context save. - * - * This code deviates from the documented sequence as follows: - * - * 1. The EA for LSCSA is passed from PPE in the - * signal notification channels. - * 2. All 128 registers are saved by crt0.o. - */ -int main() -{ - addr64 lscsa_ea; - - lscsa_ea.ui[0] = spu_readch(SPU_RdSigNotify1); - lscsa_ea.ui[1] = spu_readch(SPU_RdSigNotify2); - - /* Step 1: done by exit(). */ - save_event_mask(); /* Step 2. */ - save_tag_mask(); /* Step 3. */ - set_event_mask(); /* Step 4. */ - set_tag_mask(); /* Step 5. */ - build_dma_list(lscsa_ea); /* Step 6. */ - save_upper_240kb(lscsa_ea); /* Step 7. */ - /* Step 8: done by exit(). */ - save_fpcr(); /* Step 9. */ - save_decr(); /* Step 10. */ - save_srr0(); /* Step 11. */ - enqueue_putllc(lscsa_ea); /* Step 12. */ - spill_regs_to_mem(lscsa_ea); /* Step 13. */ - enqueue_sync(lscsa_ea); /* Step 14. */ - set_tag_update(); /* Step 15. */ - read_tag_status(); /* Step 16. */ - read_llar_status(); /* Step 17. */ - save_complete(); /* Step 18. */ - - return 0; -} diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spu_save_crt0.S b/trunk/arch/powerpc/platforms/cell/spufs/spu_save_crt0.S deleted file mode 100644 index 6659d6a66faa..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/spu_save_crt0.S +++ /dev/null @@ -1,102 +0,0 @@ -/* - * crt0_s.S: Entry function for SPU-side context save. - * - * Copyright (C) 2005 IBM - * - * Entry function for SPU-side of the context save sequence. - * Saves all 128 GPRs, sets up an initial stack frame, then - * branches to 'main'. - * - * - * 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, 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. - */ - -#include - -.data -.align 7 -.globl regs_spill -regs_spill: -.space SIZEOF_SPU_SPILL_REGS, 0x0 - -.text -.global _start -_start: - /* SPU Context Save Step 1: Save the first 16 GPRs. */ - stqa $0, regs_spill + 0 - stqa $1, regs_spill + 16 - stqa $2, regs_spill + 32 - stqa $3, regs_spill + 48 - stqa $4, regs_spill + 64 - stqa $5, regs_spill + 80 - stqa $6, regs_spill + 96 - stqa $7, regs_spill + 112 - stqa $8, regs_spill + 128 - stqa $9, regs_spill + 144 - stqa $10, regs_spill + 160 - stqa $11, regs_spill + 176 - stqa $12, regs_spill + 192 - stqa $13, regs_spill + 208 - stqa $14, regs_spill + 224 - stqa $15, regs_spill + 240 - - /* SPU Context Save, Step 8: Save the remaining 112 GPRs. */ - ila $3, regs_spill + 256 -save_regs: - lqr $4, save_reg_insts -save_reg_loop: - ai $4, $4, 4 - .balignl 16, 0x40200000 -save_reg_insts: /* must be quad-word aligned. */ - stqd $16, 0($3) - stqd $17, 16($3) - stqd $18, 32($3) - stqd $19, 48($3) - andi $5, $4, 0x7F - stqr $4, save_reg_insts - ai $3, $3, 64 - brnz $5, save_reg_loop - - /* Initialize the stack pointer to point to 16368 - * (16kb-16). The back chain pointer is initialized - * to NULL. - */ - il $0, 0 - il $SP, 16368 - stqd $0, 0($SP) - - /* Allocate a minimum stack frame for the called main. - * This is needed so that main has a place to save the - * link register when it calls another function. - */ - stqd $SP, -160($SP) - ai $SP, $SP, -160 - - /* Call the program's main function. */ - brsl $0, main - - /* In this case main should not return; if it does - * there has been an error in the sequence. Execute - * stop-and-signal with code=0. - */ -.global exit -.global _exit -exit: -_exit: - stop 0x0 - - /* Pad the size of this crt0.o to be multiple of 16 bytes. */ -.balignl 16, 0x0 - diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped b/trunk/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped deleted file mode 100644 index 39e54003f1df..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped +++ /dev/null @@ -1,191 +0,0 @@ -/* - * spu_save_dump.h: Copyright (C) 2005 IBM. - * Hex-dump auto generated from spu_save.c. - * Do not edit! - */ -static unsigned int spu_save_code[] __page_aligned = { -0x20805000, 0x20805201, 0x20805402, 0x20805603, -0x20805804, 0x20805a05, 0x20805c06, 0x20805e07, -0x20806008, 0x20806209, 0x2080640a, 0x2080660b, -0x2080680c, 0x20806a0d, 0x20806c0e, 0x20806e0f, -0x4201c003, 0x33800184, 0x1c010204, 0x40200000, -0x24000190, 0x24004191, 0x24008192, 0x2400c193, -0x141fc205, 0x23fffd84, 0x1c100183, 0x217ffb85, -0x40800000, 0x409ff801, 0x24000080, 0x24fd8081, -0x1cd80081, 0x33000180, 0x00000000, 0x00000000, -0x01a00182, 0x3ec00083, 0xb1c38103, 0x01a00204, -0x3ec10082, 0x4201400d, 0xb1c38202, 0x01a00583, -0x34218682, 0x3ed80684, 0xb0408184, 0x24218682, -0x01a00603, 0x00200000, 0x34214682, 0x3ed40684, -0xb0408184, 0x40800003, 0x24214682, 0x21a00083, -0x40800082, 0x21a00b02, 0x4020007f, 0x1000251e, -0x40a80002, 0x32800008, 0x4205c00c, 0x00200000, -0x40a0000b, 0x3f82070f, 0x4080020a, 0x40800709, -0x3fe3078f, 0x3fbf0783, 0x3f200183, 0x3fbe0183, -0x3fe30187, 0x18008387, 0x4205c002, 0x3ac30404, -0x1cffc489, 0x00200000, 0x18008403, 0x38830402, -0x4cffc486, 0x3ac28185, 0xb0408584, 0x28830402, -0x1c020408, 0x38828182, 0xb0408385, 0x1802c387, -0x28828182, 0x217ff886, 0x04000582, 0x32800007, -0x21a00802, 0x3fbf0705, 0x3f200285, 0x3fbe0285, -0x3fe30285, 0x21a00885, 0x04000603, 0x21a00903, -0x40803c02, 0x21a00982, 0x04000386, 0x21a00a06, -0x40801202, 0x21a00a82, 0x73000003, 0x24200683, -0x01a00404, 0x00200000, 0x34204682, 0x3ec40683, -0xb0408203, 0x24204682, 0x01a00783, 0x00200000, -0x3421c682, 0x3edc0684, 0xb0408184, 0x2421c682, -0x21a00806, 0x21a00885, 0x3fbf0784, 0x3f200204, -0x3fbe0204, 0x3fe30204, 0x21a00904, 0x40804002, -0x21a00982, 0x21a00a06, 0x40805a02, 0x21a00a82, -0x04000683, 0x21a00803, 0x21a00885, 0x21a00904, -0x40848002, 0x21a00982, 0x21a00a06, 0x40801002, -0x21a00a82, 0x21a00a06, 0x40806602, 0x00200000, -0x35800009, 0x21a00a82, 0x40800083, 0x21a00b83, -0x01a00c02, 0x01a00d83, 0x00003ffb, 0x40800003, -0x4020007f, 0x35000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -}; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spu_utils.h b/trunk/arch/powerpc/platforms/cell/spufs/spu_utils.h deleted file mode 100644 index 58359feb6c95..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/spu_utils.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * utils.h: Utilities for SPU-side of the context switch operation. - * - * (C) Copyright IBM 2005 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, 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. - */ - -#ifndef _SPU_CONTEXT_UTILS_H_ -#define _SPU_CONTEXT_UTILS_H_ - -/* - * 64-bit safe EA. - */ -typedef union { - unsigned long long ull; - unsigned int ui[2]; -} addr64; - -/* - * 128-bit register template. - */ -typedef union { - unsigned int slot[4]; - vector unsigned int v; -} spu_reg128v; - -/* - * DMA list structure. - */ -struct dma_list_elem { - unsigned int size; - unsigned int ea_low; -}; - -/* - * Declare storage for 8-byte aligned DMA list. - */ -struct dma_list_elem dma_list[15] __attribute__ ((aligned(8))); - -/* - * External definition for storage - * declared in crt0. - */ -extern spu_reg128v regs_spill[NR_SPU_SPILL_REGS]; - -/* - * Compute LSCSA byte offset for a given field. - */ -static struct spu_lscsa *dummy = (struct spu_lscsa *)0; -#define LSCSA_BYTE_OFFSET(_field) \ - ((char *)(&(dummy->_field)) - (char *)(&(dummy->gprs[0].slot[0]))) -#define LSCSA_QW_OFFSET(_field) (LSCSA_BYTE_OFFSET(_field) >> 4) - -static inline void set_event_mask(void) -{ - unsigned int event_mask = 0; - - /* Save, Step 4: - * Restore, Step 1: - * Set the SPU_RdEventMsk channel to zero to mask - * all events. - */ - spu_writech(SPU_WrEventMask, event_mask); -} - -static inline void set_tag_mask(void) -{ - unsigned int tag_mask = 1; - - /* Save, Step 5: - * Restore, Step 2: - * Set the SPU_WrTagMsk channel to '01' to unmask - * only tag group 0. - */ - spu_writech(MFC_WrTagMask, tag_mask); -} - -static inline void build_dma_list(addr64 lscsa_ea) -{ - unsigned int ea_low; - int i; - - /* Save, Step 6: - * Restore, Step 3: - * Update the effective address for the CSA in the - * pre-canned DMA-list in local storage. - */ - ea_low = lscsa_ea.ui[1]; - ea_low += LSCSA_BYTE_OFFSET(ls[16384]); - - for (i = 0; i < 15; i++, ea_low += 16384) { - dma_list[i].size = 16384; - dma_list[i].ea_low = ea_low; - } -} - -static inline void enqueue_putllc(addr64 lscsa_ea) -{ - unsigned int ls = 0; - unsigned int size = 128; - unsigned int tag_id = 0; - unsigned int cmd = 0xB4; /* PUTLLC */ - - /* Save, Step 12: - * Restore, Step 7: - * Send a PUTLLC (tag 0) command to the MFC using - * an effective address in the CSA in order to - * remove any possible lock-line reservation. - */ - spu_writech(MFC_LSA, ls); - spu_writech(MFC_EAH, lscsa_ea.ui[0]); - spu_writech(MFC_EAL, lscsa_ea.ui[1]); - spu_writech(MFC_Size, size); - spu_writech(MFC_TagID, tag_id); - spu_writech(MFC_Cmd, cmd); -} - -static inline void set_tag_update(void) -{ - unsigned int update_any = 1; - - /* Save, Step 15: - * Restore, Step 8: - * Write the MFC_TagUpdate channel with '01'. - */ - spu_writech(MFC_WrTagUpdate, update_any); -} - -static inline void read_tag_status(void) -{ - /* Save, Step 16: - * Restore, Step 9: - * Read the MFC_TagStat channel data. - */ - spu_readch(MFC_RdTagStat); -} - -static inline void read_llar_status(void) -{ - /* Save, Step 17: - * Restore, Step 10: - * Read the MFC_AtomicStat channel data. - */ - spu_readch(MFC_RdAtomicStat); -} - -#endif /* _SPU_CONTEXT_UTILS_H_ */ diff --git a/trunk/arch/powerpc/platforms/cell/spufs/spufs.h b/trunk/arch/powerpc/platforms/cell/spufs/spufs.h deleted file mode 100644 index db2601f0abd5..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/spufs.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * SPU file system - * - * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 - * - * Author: Arnd Bergmann - * - * 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, 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. - */ -#ifndef SPUFS_H -#define SPUFS_H - -#include -#include -#include -#include - -#include -#include - -/* The magic number for our file system */ -enum { - SPUFS_MAGIC = 0x23c9b64e, -}; - -struct spu_context_ops; - -#define SPU_CONTEXT_PREEMPT 0UL - -struct spu_context { - struct spu *spu; /* pointer to a physical SPU */ - struct spu_state csa; /* SPU context save area. */ - spinlock_t mmio_lock; /* protects mmio access */ - struct address_space *local_store;/* local store backing store */ - - enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; - struct rw_semaphore state_sema; - struct semaphore run_sema; - - struct mm_struct *owner; - - struct kref kref; - wait_queue_head_t ibox_wq; - wait_queue_head_t wbox_wq; - wait_queue_head_t stop_wq; - struct fasync_struct *ibox_fasync; - struct fasync_struct *wbox_fasync; - struct spu_context_ops *ops; - struct work_struct reap_work; - u64 flags; -}; - -/* SPU context query/set operations. */ -struct spu_context_ops { - int (*mbox_read) (struct spu_context * ctx, u32 * data); - u32(*mbox_stat_read) (struct spu_context * ctx); - unsigned int (*mbox_stat_poll)(struct spu_context *ctx, - unsigned int events); - int (*ibox_read) (struct spu_context * ctx, u32 * data); - int (*wbox_write) (struct spu_context * ctx, u32 data); - u32(*signal1_read) (struct spu_context * ctx); - void (*signal1_write) (struct spu_context * ctx, u32 data); - u32(*signal2_read) (struct spu_context * ctx); - void (*signal2_write) (struct spu_context * ctx, u32 data); - void (*signal1_type_set) (struct spu_context * ctx, u64 val); - u64(*signal1_type_get) (struct spu_context * ctx); - void (*signal2_type_set) (struct spu_context * ctx, u64 val); - u64(*signal2_type_get) (struct spu_context * ctx); - u32(*npc_read) (struct spu_context * ctx); - void (*npc_write) (struct spu_context * ctx, u32 data); - u32(*status_read) (struct spu_context * ctx); - char*(*get_ls) (struct spu_context * ctx); - void (*runcntl_write) (struct spu_context * ctx, u32 data); - void (*runcntl_stop) (struct spu_context * ctx); -}; - -extern struct spu_context_ops spu_hw_ops; -extern struct spu_context_ops spu_backing_ops; - -struct spufs_inode_info { - struct spu_context *i_ctx; - struct inode vfs_inode; -}; -#define SPUFS_I(inode) \ - container_of(inode, struct spufs_inode_info, vfs_inode) - -extern struct tree_descr spufs_dir_contents[]; - -/* system call implementation */ -long spufs_run_spu(struct file *file, - struct spu_context *ctx, u32 *npc, u32 *status); -long spufs_create_thread(struct nameidata *nd, - unsigned int flags, mode_t mode); -extern struct file_operations spufs_context_fops; - -/* context management */ -struct spu_context * alloc_spu_context(struct address_space *local_store); -void destroy_spu_context(struct kref *kref); -struct spu_context * get_spu_context(struct spu_context *ctx); -int put_spu_context(struct spu_context *ctx); -void spu_unmap_mappings(struct spu_context *ctx); - -void spu_forget(struct spu_context *ctx); -void spu_acquire(struct spu_context *ctx); -void spu_release(struct spu_context *ctx); -int spu_acquire_runnable(struct spu_context *ctx); -void spu_acquire_saved(struct spu_context *ctx); - -int spu_activate(struct spu_context *ctx, u64 flags); -void spu_deactivate(struct spu_context *ctx); -void spu_yield(struct spu_context *ctx); -int __init spu_sched_init(void); -void __exit spu_sched_exit(void); - -/* - * spufs_wait - * Same as wait_event_interruptible(), except that here - * we need to call spu_release(ctx) before sleeping, and - * then spu_acquire(ctx) when awoken. - */ - -#define spufs_wait(wq, condition) \ -({ \ - int __ret = 0; \ - DEFINE_WAIT(__wait); \ - for (;;) { \ - prepare_to_wait(&(wq), &__wait, TASK_INTERRUPTIBLE); \ - if (condition) \ - break; \ - if (!signal_pending(current)) { \ - spu_release(ctx); \ - schedule(); \ - spu_acquire(ctx); \ - continue; \ - } \ - __ret = -ERESTARTSYS; \ - break; \ - } \ - finish_wait(&(wq), &__wait); \ - __ret; \ -}) - -size_t spu_wbox_write(struct spu_context *ctx, u32 data); -size_t spu_ibox_read(struct spu_context *ctx, u32 *data); - -/* irq callback funcs. */ -void spufs_ibox_callback(struct spu *spu); -void spufs_wbox_callback(struct spu *spu); -void spufs_stop_callback(struct spu *spu); - -#endif diff --git a/trunk/arch/powerpc/platforms/cell/spufs/switch.c b/trunk/arch/powerpc/platforms/cell/spufs/switch.c deleted file mode 100644 index 1061c12b2edb..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/switch.c +++ /dev/null @@ -1,2180 +0,0 @@ -/* - * spu_switch.c - * - * (C) Copyright IBM Corp. 2005 - * - * Author: Mark Nutter - * - * Host-side part of SPU context switch sequence outlined in - * Synergistic Processor Element, Book IV. - * - * A fully premptive switch of an SPE is very expensive in terms - * of time and system resources. SPE Book IV indicates that SPE - * allocation should follow a "serially reusable device" model, - * in which the SPE is assigned a task until it completes. When - * this is not possible, this sequence may be used to premptively - * save, and then later (optionally) restore the context of a - * program executing on an SPE. - * - * - * 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, 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "spu_save_dump.h" -#include "spu_restore_dump.h" - -#if 0 -#define POLL_WHILE_TRUE(_c) { \ - do { \ - } while (_c); \ - } -#else -#define RELAX_SPIN_COUNT 1000 -#define POLL_WHILE_TRUE(_c) { \ - do { \ - int _i; \ - for (_i=0; _iproblem; - u32 isolate_state; - - /* Save, Step 2: - * Save, Step 6: - * If SPU_Status[E,L,IS] any field is '1', this - * SPU is in isolate state and cannot be context - * saved at this time. - */ - isolate_state = SPU_STATUS_ISOLATED_STATE | - SPU_STATUS_ISOLATED_LOAD_STAUTUS | SPU_STATUS_ISOLATED_EXIT_STAUTUS; - return (in_be32(&prob->spu_status_R) & isolate_state) ? 1 : 0; -} - -static inline void disable_interrupts(struct spu_state *csa, struct spu *spu) -{ - /* Save, Step 3: - * Restore, Step 2: - * Save INT_Mask_class0 in CSA. - * Write INT_MASK_class0 with value of 0. - * Save INT_Mask_class1 in CSA. - * Write INT_MASK_class1 with value of 0. - * Save INT_Mask_class2 in CSA. - * Write INT_MASK_class2 with value of 0. - */ - spin_lock_irq(&spu->register_lock); - if (csa) { - csa->priv1.int_mask_class0_RW = spu_int_mask_get(spu, 0); - csa->priv1.int_mask_class1_RW = spu_int_mask_get(spu, 1); - csa->priv1.int_mask_class2_RW = spu_int_mask_get(spu, 2); - } - spu_int_mask_set(spu, 0, 0ul); - spu_int_mask_set(spu, 1, 0ul); - spu_int_mask_set(spu, 2, 0ul); - eieio(); - spin_unlock_irq(&spu->register_lock); -} - -static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu) -{ - /* Save, Step 4: - * Restore, Step 25. - * Set a software watchdog timer, which specifies the - * maximum allowable time for a context save sequence. - * - * For present, this implementation will not set a global - * watchdog timer, as virtualization & variable system load - * may cause unpredictable execution times. - */ -} - -static inline void inhibit_user_access(struct spu_state *csa, struct spu *spu) -{ - /* Save, Step 5: - * Restore, Step 3: - * Inhibit user-space access (if provided) to this - * SPU by unmapping the virtual pages assigned to - * the SPU memory-mapped I/O (MMIO) for problem - * state. TBD. - */ -} - -static inline void set_switch_pending(struct spu_state *csa, struct spu *spu) -{ - /* Save, Step 7: - * Restore, Step 5: - * Set a software context switch pending flag. - */ - set_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags); - mb(); -} - -static inline void save_mfc_cntl(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 8: - * Read and save MFC_CNTL[Ss]. - */ - if (csa) { - csa->priv2.mfc_control_RW = in_be64(&priv2->mfc_control_RW) & - MFC_CNTL_SUSPEND_DMA_STATUS_MASK; - } -} - -static inline void save_spu_runcntl(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Save, Step 9: - * Save SPU_Runcntl in the CSA. This value contains - * the "Application Desired State". - */ - csa->prob.spu_runcntl_RW = in_be32(&prob->spu_runcntl_RW); -} - -static inline void save_mfc_sr1(struct spu_state *csa, struct spu *spu) -{ - /* Save, Step 10: - * Save MFC_SR1 in the CSA. - */ - csa->priv1.mfc_sr1_RW = spu_mfc_sr1_get(spu); -} - -static inline void save_spu_status(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Save, Step 11: - * Read SPU_Status[R], and save to CSA. - */ - if ((in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING) == 0) { - csa->prob.spu_status_R = in_be32(&prob->spu_status_R); - } else { - u32 stopped; - - out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP); - eieio(); - POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & - SPU_STATUS_RUNNING); - stopped = - SPU_STATUS_INVALID_INSTR | SPU_STATUS_SINGLE_STEP | - SPU_STATUS_STOPPED_BY_HALT | SPU_STATUS_STOPPED_BY_STOP; - if ((in_be32(&prob->spu_status_R) & stopped) == 0) - csa->prob.spu_status_R = SPU_STATUS_RUNNING; - else - csa->prob.spu_status_R = in_be32(&prob->spu_status_R); - } -} - -static inline void save_mfc_decr(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 12: - * Read MFC_CNTL[Ds]. Update saved copy of - * CSA.MFC_CNTL[Ds]. - */ - if (in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DECREMENTER_RUNNING) { - csa->priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING; - csa->suspend_time = get_cycles(); - out_be64(&priv2->spu_chnlcntptr_RW, 7ULL); - eieio(); - csa->spu_chnldata_RW[7] = in_be64(&priv2->spu_chnldata_RW); - eieio(); - } -} - -static inline void halt_mfc_decr(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 13: - * Write MFC_CNTL[Dh] set to a '1' to halt - * the decrementer. - */ - out_be64(&priv2->mfc_control_RW, MFC_CNTL_DECREMENTER_HALTED); - eieio(); -} - -static inline void save_timebase(struct spu_state *csa, struct spu *spu) -{ - /* Save, Step 14: - * Read PPE Timebase High and Timebase low registers - * and save in CSA. TBD. - */ - csa->suspend_time = get_cycles(); -} - -static inline void remove_other_spu_access(struct spu_state *csa, - struct spu *spu) -{ - /* Save, Step 15: - * Remove other SPU access to this SPU by unmapping - * this SPU's pages from their address space. TBD. - */ -} - -static inline void do_mfc_mssync(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Save, Step 16: - * Restore, Step 11. - * Write SPU_MSSync register. Poll SPU_MSSync[P] - * for a value of 0. - */ - out_be64(&prob->spc_mssync_RW, 1UL); - POLL_WHILE_TRUE(in_be64(&prob->spc_mssync_RW) & MS_SYNC_PENDING); -} - -static inline void issue_mfc_tlbie(struct spu_state *csa, struct spu *spu) -{ - /* Save, Step 17: - * Restore, Step 12. - * Restore, Step 48. - * Write TLB_Invalidate_Entry[IS,VPN,L,Lp]=0 register. - * Then issue a PPE sync instruction. - */ - spu_tlb_invalidate(spu); - mb(); -} - -static inline void handle_pending_interrupts(struct spu_state *csa, - struct spu *spu) -{ - /* Save, Step 18: - * Handle any pending interrupts from this SPU - * here. This is OS or hypervisor specific. One - * option is to re-enable interrupts to handle any - * pending interrupts, with the interrupt handlers - * recognizing the software Context Switch Pending - * flag, to ensure the SPU execution or MFC command - * queue is not restarted. TBD. - */ -} - -static inline void save_mfc_queues(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - int i; - - /* Save, Step 19: - * If MFC_Cntl[Se]=0 then save - * MFC command queues. - */ - if ((in_be64(&priv2->mfc_control_RW) & MFC_CNTL_DMA_QUEUES_EMPTY) == 0) { - for (i = 0; i < 8; i++) { - csa->priv2.puq[i].mfc_cq_data0_RW = - in_be64(&priv2->puq[i].mfc_cq_data0_RW); - csa->priv2.puq[i].mfc_cq_data1_RW = - in_be64(&priv2->puq[i].mfc_cq_data1_RW); - csa->priv2.puq[i].mfc_cq_data2_RW = - in_be64(&priv2->puq[i].mfc_cq_data2_RW); - csa->priv2.puq[i].mfc_cq_data3_RW = - in_be64(&priv2->puq[i].mfc_cq_data3_RW); - } - for (i = 0; i < 16; i++) { - csa->priv2.spuq[i].mfc_cq_data0_RW = - in_be64(&priv2->spuq[i].mfc_cq_data0_RW); - csa->priv2.spuq[i].mfc_cq_data1_RW = - in_be64(&priv2->spuq[i].mfc_cq_data1_RW); - csa->priv2.spuq[i].mfc_cq_data2_RW = - in_be64(&priv2->spuq[i].mfc_cq_data2_RW); - csa->priv2.spuq[i].mfc_cq_data3_RW = - in_be64(&priv2->spuq[i].mfc_cq_data3_RW); - } - } -} - -static inline void save_ppu_querymask(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Save, Step 20: - * Save the PPU_QueryMask register - * in the CSA. - */ - csa->prob.dma_querymask_RW = in_be32(&prob->dma_querymask_RW); -} - -static inline void save_ppu_querytype(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Save, Step 21: - * Save the PPU_QueryType register - * in the CSA. - */ - csa->prob.dma_querytype_RW = in_be32(&prob->dma_querytype_RW); -} - -static inline void save_mfc_csr_tsq(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 22: - * Save the MFC_CSR_TSQ register - * in the LSCSA. - */ - csa->priv2.spu_tag_status_query_RW = - in_be64(&priv2->spu_tag_status_query_RW); -} - -static inline void save_mfc_csr_cmd(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 23: - * Save the MFC_CSR_CMD1 and MFC_CSR_CMD2 - * registers in the CSA. - */ - csa->priv2.spu_cmd_buf1_RW = in_be64(&priv2->spu_cmd_buf1_RW); - csa->priv2.spu_cmd_buf2_RW = in_be64(&priv2->spu_cmd_buf2_RW); -} - -static inline void save_mfc_csr_ato(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 24: - * Save the MFC_CSR_ATO register in - * the CSA. - */ - csa->priv2.spu_atomic_status_RW = in_be64(&priv2->spu_atomic_status_RW); -} - -static inline void save_mfc_tclass_id(struct spu_state *csa, struct spu *spu) -{ - /* Save, Step 25: - * Save the MFC_TCLASS_ID register in - * the CSA. - */ - csa->priv1.mfc_tclass_id_RW = spu_mfc_tclass_id_get(spu); -} - -static inline void set_mfc_tclass_id(struct spu_state *csa, struct spu *spu) -{ - /* Save, Step 26: - * Restore, Step 23. - * Write the MFC_TCLASS_ID register with - * the value 0x10000000. - */ - spu_mfc_tclass_id_set(spu, 0x10000000); - eieio(); -} - -static inline void purge_mfc_queue(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 27: - * Restore, Step 14. - * Write MFC_CNTL[Pc]=1 (purge queue). - */ - out_be64(&priv2->mfc_control_RW, MFC_CNTL_PURGE_DMA_REQUEST); - eieio(); -} - -static inline void wait_purge_complete(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 28: - * Poll MFC_CNTL[Ps] until value '11' is read - * (purge complete). - */ - POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & - MFC_CNTL_PURGE_DMA_COMPLETE); -} - -static inline void save_mfc_slbs(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - int i; - - /* Save, Step 29: - * If MFC_SR1[R]='1', save SLBs in CSA. - */ - if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) { - csa->priv2.slb_index_W = in_be64(&priv2->slb_index_W); - for (i = 0; i < 8; i++) { - out_be64(&priv2->slb_index_W, i); - eieio(); - csa->slb_esid_RW[i] = in_be64(&priv2->slb_esid_RW); - csa->slb_vsid_RW[i] = in_be64(&priv2->slb_vsid_RW); - eieio(); - } - } -} - -static inline void setup_mfc_sr1(struct spu_state *csa, struct spu *spu) -{ - /* Save, Step 30: - * Restore, Step 18: - * Write MFC_SR1 with MFC_SR1[D=0,S=1] and - * MFC_SR1[TL,R,Pr,T] set correctly for the - * OS specific environment. - * - * Implementation note: The SPU-side code - * for save/restore is privileged, so the - * MFC_SR1[Pr] bit is not set. - * - */ - spu_mfc_sr1_set(spu, (MFC_STATE1_MASTER_RUN_CONTROL_MASK | - MFC_STATE1_RELOCATE_MASK | - MFC_STATE1_BUS_TLBIE_MASK)); -} - -static inline void save_spu_npc(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Save, Step 31: - * Save SPU_NPC in the CSA. - */ - csa->prob.spu_npc_RW = in_be32(&prob->spu_npc_RW); -} - -static inline void save_spu_privcntl(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 32: - * Save SPU_PrivCntl in the CSA. - */ - csa->priv2.spu_privcntl_RW = in_be64(&priv2->spu_privcntl_RW); -} - -static inline void reset_spu_privcntl(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 33: - * Restore, Step 16: - * Write SPU_PrivCntl[S,Le,A] fields reset to 0. - */ - out_be64(&priv2->spu_privcntl_RW, 0UL); - eieio(); -} - -static inline void save_spu_lslr(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 34: - * Save SPU_LSLR in the CSA. - */ - csa->priv2.spu_lslr_RW = in_be64(&priv2->spu_lslr_RW); -} - -static inline void reset_spu_lslr(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 35: - * Restore, Step 17. - * Reset SPU_LSLR. - */ - out_be64(&priv2->spu_lslr_RW, LS_ADDR_MASK); - eieio(); -} - -static inline void save_spu_cfg(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 36: - * Save SPU_Cfg in the CSA. - */ - csa->priv2.spu_cfg_RW = in_be64(&priv2->spu_cfg_RW); -} - -static inline void save_pm_trace(struct spu_state *csa, struct spu *spu) -{ - /* Save, Step 37: - * Save PM_Trace_Tag_Wait_Mask in the CSA. - * Not performed by this implementation. - */ -} - -static inline void save_mfc_rag(struct spu_state *csa, struct spu *spu) -{ - /* Save, Step 38: - * Save RA_GROUP_ID register and the - * RA_ENABLE reigster in the CSA. - */ - csa->priv1.resource_allocation_groupID_RW = - spu_resource_allocation_groupID_get(spu); - csa->priv1.resource_allocation_enable_RW = - spu_resource_allocation_enable_get(spu); -} - -static inline void save_ppu_mb_stat(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Save, Step 39: - * Save MB_Stat register in the CSA. - */ - csa->prob.mb_stat_R = in_be32(&prob->mb_stat_R); -} - -static inline void save_ppu_mb(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Save, Step 40: - * Save the PPU_MB register in the CSA. - */ - csa->prob.pu_mb_R = in_be32(&prob->pu_mb_R); -} - -static inline void save_ppuint_mb(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 41: - * Save the PPUINT_MB register in the CSA. - */ - csa->priv2.puint_mb_R = in_be64(&priv2->puint_mb_R); -} - -static inline void save_ch_part1(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 idx, ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL }; - int i; - - /* Save, Step 42: - * Save the following CH: [0,1,3,4,24,25,27] - */ - for (i = 0; i < 7; i++) { - idx = ch_indices[i]; - out_be64(&priv2->spu_chnlcntptr_RW, idx); - eieio(); - csa->spu_chnldata_RW[idx] = in_be64(&priv2->spu_chnldata_RW); - csa->spu_chnlcnt_RW[idx] = in_be64(&priv2->spu_chnlcnt_RW); - out_be64(&priv2->spu_chnldata_RW, 0UL); - out_be64(&priv2->spu_chnlcnt_RW, 0UL); - eieio(); - } -} - -static inline void save_spu_mb(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - int i; - - /* Save, Step 43: - * Save SPU Read Mailbox Channel. - */ - out_be64(&priv2->spu_chnlcntptr_RW, 29UL); - eieio(); - csa->spu_chnlcnt_RW[29] = in_be64(&priv2->spu_chnlcnt_RW); - for (i = 0; i < 4; i++) { - csa->spu_mailbox_data[i] = in_be64(&priv2->spu_chnldata_RW); - } - out_be64(&priv2->spu_chnlcnt_RW, 0UL); - eieio(); -} - -static inline void save_mfc_cmd(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 44: - * Save MFC_CMD Channel. - */ - out_be64(&priv2->spu_chnlcntptr_RW, 21UL); - eieio(); - csa->spu_chnlcnt_RW[21] = in_be64(&priv2->spu_chnlcnt_RW); - eieio(); -} - -static inline void reset_ch(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 ch_indices[4] = { 21UL, 23UL, 28UL, 30UL }; - u64 ch_counts[4] = { 16UL, 1UL, 1UL, 1UL }; - u64 idx; - int i; - - /* Save, Step 45: - * Reset the following CH: [21, 23, 28, 30] - */ - for (i = 0; i < 4; i++) { - idx = ch_indices[i]; - out_be64(&priv2->spu_chnlcntptr_RW, idx); - eieio(); - out_be64(&priv2->spu_chnlcnt_RW, ch_counts[i]); - eieio(); - } -} - -static inline void resume_mfc_queue(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 46: - * Restore, Step 25. - * Write MFC_CNTL[Sc]=0 (resume queue processing). - */ - out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESUME_DMA_QUEUE); -} - -static inline void invalidate_slbs(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 45: - * Restore, Step 19: - * If MFC_SR1[R]=1, write 0 to SLB_Invalidate_All. - */ - if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) { - out_be64(&priv2->slb_invalidate_all_W, 0UL); - eieio(); - } -} - -static inline void get_kernel_slb(u64 ea, u64 slb[2]) -{ - slb[0] = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | SLB_VSID_KERNEL; - slb[1] = (ea & ESID_MASK) | SLB_ESID_V; - - /* Large pages are used for kernel text/data, but not vmalloc. */ - if (cpu_has_feature(CPU_FTR_16M_PAGE) - && REGION_ID(ea) == KERNEL_REGION_ID) - slb[0] |= SLB_VSID_L; -} - -static inline void load_mfc_slb(struct spu *spu, u64 slb[2], int slbe) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - out_be64(&priv2->slb_index_W, slbe); - eieio(); - out_be64(&priv2->slb_vsid_RW, slb[0]); - out_be64(&priv2->slb_esid_RW, slb[1]); - eieio(); -} - -static inline void setup_mfc_slbs(struct spu_state *csa, struct spu *spu) -{ - u64 code_slb[2]; - u64 lscsa_slb[2]; - - /* Save, Step 47: - * Restore, Step 30. - * If MFC_SR1[R]=1, write 0 to SLB_Invalidate_All - * register, then initialize SLB_VSID and SLB_ESID - * to provide access to SPU context save code and - * LSCSA. - * - * This implementation places both the context - * switch code and LSCSA in kernel address space. - * - * Further this implementation assumes that the - * MFC_SR1[R]=1 (in other words, assume that - * translation is desired by OS environment). - */ - invalidate_slbs(csa, spu); - get_kernel_slb((unsigned long)&spu_save_code[0], code_slb); - get_kernel_slb((unsigned long)csa->lscsa, lscsa_slb); - load_mfc_slb(spu, code_slb, 0); - if ((lscsa_slb[0] != code_slb[0]) || (lscsa_slb[1] != code_slb[1])) - load_mfc_slb(spu, lscsa_slb, 1); -} - -static inline void set_switch_active(struct spu_state *csa, struct spu *spu) -{ - /* Save, Step 48: - * Restore, Step 23. - * Change the software context switch pending flag - * to context switch active. - */ - set_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags); - clear_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags); - mb(); -} - -static inline void enable_interrupts(struct spu_state *csa, struct spu *spu) -{ - unsigned long class1_mask = CLASS1_ENABLE_SEGMENT_FAULT_INTR | - CLASS1_ENABLE_STORAGE_FAULT_INTR; - - /* Save, Step 49: - * Restore, Step 22: - * Reset and then enable interrupts, as - * needed by OS. - * - * This implementation enables only class1 - * (translation) interrupts. - */ - spin_lock_irq(&spu->register_lock); - spu_int_stat_clear(spu, 0, ~0ul); - spu_int_stat_clear(spu, 1, ~0ul); - spu_int_stat_clear(spu, 2, ~0ul); - spu_int_mask_set(spu, 0, 0ul); - spu_int_mask_set(spu, 1, class1_mask); - spu_int_mask_set(spu, 2, 0ul); - spin_unlock_irq(&spu->register_lock); -} - -static inline int send_mfc_dma(struct spu *spu, unsigned long ea, - unsigned int ls_offset, unsigned int size, - unsigned int tag, unsigned int rclass, - unsigned int cmd) -{ - struct spu_problem __iomem *prob = spu->problem; - union mfc_tag_size_class_cmd command; - unsigned int transfer_size; - volatile unsigned int status = 0x0; - - while (size > 0) { - transfer_size = - (size > MFC_MAX_DMA_SIZE) ? MFC_MAX_DMA_SIZE : size; - command.u.mfc_size = transfer_size; - command.u.mfc_tag = tag; - command.u.mfc_rclassid = rclass; - command.u.mfc_cmd = cmd; - do { - out_be32(&prob->mfc_lsa_W, ls_offset); - out_be64(&prob->mfc_ea_W, ea); - out_be64(&prob->mfc_union_W.all64, command.all64); - status = - in_be32(&prob->mfc_union_W.by32.mfc_class_cmd32); - if (unlikely(status & 0x2)) { - cpu_relax(); - } - } while (status & 0x3); - size -= transfer_size; - ea += transfer_size; - ls_offset += transfer_size; - } - return 0; -} - -static inline void save_ls_16kb(struct spu_state *csa, struct spu *spu) -{ - unsigned long addr = (unsigned long)&csa->lscsa->ls[0]; - unsigned int ls_offset = 0x0; - unsigned int size = 16384; - unsigned int tag = 0; - unsigned int rclass = 0; - unsigned int cmd = MFC_PUT_CMD; - - /* Save, Step 50: - * Issue a DMA command to copy the first 16K bytes - * of local storage to the CSA. - */ - send_mfc_dma(spu, addr, ls_offset, size, tag, rclass, cmd); -} - -static inline void set_spu_npc(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Save, Step 51: - * Restore, Step 31. - * Write SPU_NPC[IE]=0 and SPU_NPC[LSA] to entry - * point address of context save code in local - * storage. - * - * This implementation uses SPU-side save/restore - * programs with entry points at LSA of 0. - */ - out_be32(&prob->spu_npc_RW, 0); - eieio(); -} - -static inline void set_signot1(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - union { - u64 ull; - u32 ui[2]; - } addr64; - - /* Save, Step 52: - * Restore, Step 32: - * Write SPU_Sig_Notify_1 register with upper 32-bits - * of the CSA.LSCSA effective address. - */ - addr64.ull = (u64) csa->lscsa; - out_be32(&prob->signal_notify1, addr64.ui[0]); - eieio(); -} - -static inline void set_signot2(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - union { - u64 ull; - u32 ui[2]; - } addr64; - - /* Save, Step 53: - * Restore, Step 33: - * Write SPU_Sig_Notify_2 register with lower 32-bits - * of the CSA.LSCSA effective address. - */ - addr64.ull = (u64) csa->lscsa; - out_be32(&prob->signal_notify2, addr64.ui[1]); - eieio(); -} - -static inline void send_save_code(struct spu_state *csa, struct spu *spu) -{ - unsigned long addr = (unsigned long)&spu_save_code[0]; - unsigned int ls_offset = 0x0; - unsigned int size = sizeof(spu_save_code); - unsigned int tag = 0; - unsigned int rclass = 0; - unsigned int cmd = MFC_GETFS_CMD; - - /* Save, Step 54: - * Issue a DMA command to copy context save code - * to local storage and start SPU. - */ - send_mfc_dma(spu, addr, ls_offset, size, tag, rclass, cmd); -} - -static inline void set_ppu_querymask(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Save, Step 55: - * Restore, Step 38. - * Write PPU_QueryMask=1 (enable Tag Group 0) - * and issue eieio instruction. - */ - out_be32(&prob->dma_querymask_RW, MFC_TAGID_TO_TAGMASK(0)); - eieio(); -} - -static inline void wait_tag_complete(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - u32 mask = MFC_TAGID_TO_TAGMASK(0); - unsigned long flags; - - /* Save, Step 56: - * Restore, Step 39. - * Restore, Step 39. - * Restore, Step 46. - * Poll PPU_TagStatus[gn] until 01 (Tag group 0 complete) - * or write PPU_QueryType[TS]=01 and wait for Tag Group - * Complete Interrupt. Write INT_Stat_Class0 or - * INT_Stat_Class2 with value of 'handled'. - */ - POLL_WHILE_FALSE(in_be32(&prob->dma_tagstatus_R) & mask); - - local_irq_save(flags); - spu_int_stat_clear(spu, 0, ~(0ul)); - spu_int_stat_clear(spu, 2, ~(0ul)); - local_irq_restore(flags); -} - -static inline void wait_spu_stopped(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - unsigned long flags; - - /* Save, Step 57: - * Restore, Step 40. - * Poll until SPU_Status[R]=0 or wait for SPU Class 0 - * or SPU Class 2 interrupt. Write INT_Stat_class0 - * or INT_Stat_class2 with value of handled. - */ - POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING); - - local_irq_save(flags); - spu_int_stat_clear(spu, 0, ~(0ul)); - spu_int_stat_clear(spu, 2, ~(0ul)); - local_irq_restore(flags); -} - -static inline int check_save_status(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - u32 complete; - - /* Save, Step 54: - * If SPU_Status[P]=1 and SPU_Status[SC] = "success", - * context save succeeded, otherwise context save - * failed. - */ - complete = ((SPU_SAVE_COMPLETE << SPU_STOP_STATUS_SHIFT) | - SPU_STATUS_STOPPED_BY_STOP); - return (in_be32(&prob->spu_status_R) != complete) ? 1 : 0; -} - -static inline void terminate_spu_app(struct spu_state *csa, struct spu *spu) -{ - /* Restore, Step 4: - * If required, notify the "using application" that - * the SPU task has been terminated. TBD. - */ -} - -static inline void suspend_mfc(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Restore, Step 7: - * Restore, Step 47. - * Write MFC_Cntl[Dh,Sc]='1','1' to suspend - * the queue and halt the decrementer. - */ - out_be64(&priv2->mfc_control_RW, MFC_CNTL_SUSPEND_DMA_QUEUE | - MFC_CNTL_DECREMENTER_HALTED); - eieio(); -} - -static inline void wait_suspend_mfc_complete(struct spu_state *csa, - struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Restore, Step 8: - * Restore, Step 47. - * Poll MFC_CNTL[Ss] until 11 is returned. - */ - POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & - MFC_CNTL_SUSPEND_COMPLETE); -} - -static inline int suspend_spe(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Restore, Step 9: - * If SPU_Status[R]=1, stop SPU execution - * and wait for stop to complete. - * - * Returns 1 if SPU_Status[R]=1 on entry. - * 0 otherwise - */ - if (in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING) { - if (in_be32(&prob->spu_status_R) & - SPU_STATUS_ISOLATED_EXIT_STAUTUS) { - POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & - SPU_STATUS_RUNNING); - } - if ((in_be32(&prob->spu_status_R) & - SPU_STATUS_ISOLATED_LOAD_STAUTUS) - || (in_be32(&prob->spu_status_R) & - SPU_STATUS_ISOLATED_STATE)) { - out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP); - eieio(); - POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & - SPU_STATUS_RUNNING); - out_be32(&prob->spu_runcntl_RW, 0x2); - eieio(); - POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & - SPU_STATUS_RUNNING); - } - if (in_be32(&prob->spu_status_R) & - SPU_STATUS_WAITING_FOR_CHANNEL) { - out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP); - eieio(); - POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & - SPU_STATUS_RUNNING); - } - return 1; - } - return 0; -} - -static inline void clear_spu_status(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Restore, Step 10: - * If SPU_Status[R]=0 and SPU_Status[E,L,IS]=1, - * release SPU from isolate state. - */ - if (!(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING)) { - if (in_be32(&prob->spu_status_R) & - SPU_STATUS_ISOLATED_EXIT_STAUTUS) { - spu_mfc_sr1_set(spu, - MFC_STATE1_MASTER_RUN_CONTROL_MASK); - eieio(); - out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_RUNNABLE); - eieio(); - POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & - SPU_STATUS_RUNNING); - } - if ((in_be32(&prob->spu_status_R) & - SPU_STATUS_ISOLATED_LOAD_STAUTUS) - || (in_be32(&prob->spu_status_R) & - SPU_STATUS_ISOLATED_STATE)) { - spu_mfc_sr1_set(spu, - MFC_STATE1_MASTER_RUN_CONTROL_MASK); - eieio(); - out_be32(&prob->spu_runcntl_RW, 0x2); - eieio(); - POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & - SPU_STATUS_RUNNING); - } - } -} - -static inline void reset_ch_part1(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL }; - u64 idx; - int i; - - /* Restore, Step 20: - * Reset the following CH: [0,1,3,4,24,25,27] - */ - for (i = 0; i < 7; i++) { - idx = ch_indices[i]; - out_be64(&priv2->spu_chnlcntptr_RW, idx); - eieio(); - out_be64(&priv2->spu_chnldata_RW, 0UL); - out_be64(&priv2->spu_chnlcnt_RW, 0UL); - eieio(); - } -} - -static inline void reset_ch_part2(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 ch_indices[5] = { 21UL, 23UL, 28UL, 29UL, 30UL }; - u64 ch_counts[5] = { 16UL, 1UL, 1UL, 0UL, 1UL }; - u64 idx; - int i; - - /* Restore, Step 21: - * Reset the following CH: [21, 23, 28, 29, 30] - */ - for (i = 0; i < 5; i++) { - idx = ch_indices[i]; - out_be64(&priv2->spu_chnlcntptr_RW, idx); - eieio(); - out_be64(&priv2->spu_chnlcnt_RW, ch_counts[i]); - eieio(); - } -} - -static inline void setup_spu_status_part1(struct spu_state *csa, - struct spu *spu) -{ - u32 status_P = SPU_STATUS_STOPPED_BY_STOP; - u32 status_I = SPU_STATUS_INVALID_INSTR; - u32 status_H = SPU_STATUS_STOPPED_BY_HALT; - u32 status_S = SPU_STATUS_SINGLE_STEP; - u32 status_S_I = SPU_STATUS_SINGLE_STEP | SPU_STATUS_INVALID_INSTR; - u32 status_S_P = SPU_STATUS_SINGLE_STEP | SPU_STATUS_STOPPED_BY_STOP; - u32 status_P_H = SPU_STATUS_STOPPED_BY_HALT |SPU_STATUS_STOPPED_BY_STOP; - u32 status_P_I = SPU_STATUS_STOPPED_BY_STOP |SPU_STATUS_INVALID_INSTR; - u32 status_code; - - /* Restore, Step 27: - * If the CSA.SPU_Status[I,S,H,P]=1 then add the correct - * instruction sequence to the end of the SPU based restore - * code (after the "context restored" stop and signal) to - * restore the correct SPU status. - * - * NOTE: Rather than modifying the SPU executable, we - * instead add a new 'stopped_status' field to the - * LSCSA. The SPU-side restore reads this field and - * takes the appropriate action when exiting. - */ - - status_code = - (csa->prob.spu_status_R >> SPU_STOP_STATUS_SHIFT) & 0xFFFF; - if ((csa->prob.spu_status_R & status_P_I) == status_P_I) { - - /* SPU_Status[P,I]=1 - Illegal Instruction followed - * by Stop and Signal instruction, followed by 'br -4'. - * - */ - csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_P_I; - csa->lscsa->stopped_status.slot[1] = status_code; - - } else if ((csa->prob.spu_status_R & status_P_H) == status_P_H) { - - /* SPU_Status[P,H]=1 - Halt Conditional, followed - * by Stop and Signal instruction, followed by - * 'br -4'. - */ - csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_P_H; - csa->lscsa->stopped_status.slot[1] = status_code; - - } else if ((csa->prob.spu_status_R & status_S_P) == status_S_P) { - - /* SPU_Status[S,P]=1 - Stop and Signal instruction - * followed by 'br -4'. - */ - csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_S_P; - csa->lscsa->stopped_status.slot[1] = status_code; - - } else if ((csa->prob.spu_status_R & status_S_I) == status_S_I) { - - /* SPU_Status[S,I]=1 - Illegal instruction followed - * by 'br -4'. - */ - csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_S_I; - csa->lscsa->stopped_status.slot[1] = status_code; - - } else if ((csa->prob.spu_status_R & status_P) == status_P) { - - /* SPU_Status[P]=1 - Stop and Signal instruction - * followed by 'br -4'. - */ - csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_P; - csa->lscsa->stopped_status.slot[1] = status_code; - - } else if ((csa->prob.spu_status_R & status_H) == status_H) { - - /* SPU_Status[H]=1 - Halt Conditional, followed - * by 'br -4'. - */ - csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_H; - - } else if ((csa->prob.spu_status_R & status_S) == status_S) { - - /* SPU_Status[S]=1 - Two nop instructions. - */ - csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_S; - - } else if ((csa->prob.spu_status_R & status_I) == status_I) { - - /* SPU_Status[I]=1 - Illegal instruction followed - * by 'br -4'. - */ - csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_I; - - } -} - -static inline void setup_spu_status_part2(struct spu_state *csa, - struct spu *spu) -{ - u32 mask; - - /* Restore, Step 28: - * If the CSA.SPU_Status[I,S,H,P,R]=0 then - * add a 'br *' instruction to the end of - * the SPU based restore code. - * - * NOTE: Rather than modifying the SPU executable, we - * instead add a new 'stopped_status' field to the - * LSCSA. The SPU-side restore reads this field and - * takes the appropriate action when exiting. - */ - mask = SPU_STATUS_INVALID_INSTR | - SPU_STATUS_SINGLE_STEP | - SPU_STATUS_STOPPED_BY_HALT | - SPU_STATUS_STOPPED_BY_STOP | SPU_STATUS_RUNNING; - if (!(csa->prob.spu_status_R & mask)) { - csa->lscsa->stopped_status.slot[0] = SPU_STOPPED_STATUS_R; - } -} - -static inline void restore_mfc_rag(struct spu_state *csa, struct spu *spu) -{ - /* Restore, Step 29: - * Restore RA_GROUP_ID register and the - * RA_ENABLE reigster from the CSA. - */ - spu_resource_allocation_groupID_set(spu, - csa->priv1.resource_allocation_groupID_RW); - spu_resource_allocation_enable_set(spu, - csa->priv1.resource_allocation_enable_RW); -} - -static inline void send_restore_code(struct spu_state *csa, struct spu *spu) -{ - unsigned long addr = (unsigned long)&spu_restore_code[0]; - unsigned int ls_offset = 0x0; - unsigned int size = sizeof(spu_restore_code); - unsigned int tag = 0; - unsigned int rclass = 0; - unsigned int cmd = MFC_GETFS_CMD; - - /* Restore, Step 37: - * Issue MFC DMA command to copy context - * restore code to local storage. - */ - send_mfc_dma(spu, addr, ls_offset, size, tag, rclass, cmd); -} - -static inline void setup_decr(struct spu_state *csa, struct spu *spu) -{ - /* Restore, Step 34: - * If CSA.MFC_CNTL[Ds]=1 (decrementer was - * running) then adjust decrementer, set - * decrementer running status in LSCSA, - * and set decrementer "wrapped" status - * in LSCSA. - */ - if (csa->priv2.mfc_control_RW & MFC_CNTL_DECREMENTER_RUNNING) { - cycles_t resume_time = get_cycles(); - cycles_t delta_time = resume_time - csa->suspend_time; - - csa->lscsa->decr.slot[0] = delta_time; - } -} - -static inline void setup_ppu_mb(struct spu_state *csa, struct spu *spu) -{ - /* Restore, Step 35: - * Copy the CSA.PU_MB data into the LSCSA. - */ - csa->lscsa->ppu_mb.slot[0] = csa->prob.pu_mb_R; -} - -static inline void setup_ppuint_mb(struct spu_state *csa, struct spu *spu) -{ - /* Restore, Step 36: - * Copy the CSA.PUINT_MB data into the LSCSA. - */ - csa->lscsa->ppuint_mb.slot[0] = csa->priv2.puint_mb_R; -} - -static inline int check_restore_status(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - u32 complete; - - /* Restore, Step 40: - * If SPU_Status[P]=1 and SPU_Status[SC] = "success", - * context restore succeeded, otherwise context restore - * failed. - */ - complete = ((SPU_RESTORE_COMPLETE << SPU_STOP_STATUS_SHIFT) | - SPU_STATUS_STOPPED_BY_STOP); - return (in_be32(&prob->spu_status_R) != complete) ? 1 : 0; -} - -static inline void restore_spu_privcntl(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Restore, Step 41: - * Restore SPU_PrivCntl from the CSA. - */ - out_be64(&priv2->spu_privcntl_RW, csa->priv2.spu_privcntl_RW); - eieio(); -} - -static inline void restore_status_part1(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - u32 mask; - - /* Restore, Step 42: - * If any CSA.SPU_Status[I,S,H,P]=1, then - * restore the error or single step state. - */ - mask = SPU_STATUS_INVALID_INSTR | - SPU_STATUS_SINGLE_STEP | - SPU_STATUS_STOPPED_BY_HALT | SPU_STATUS_STOPPED_BY_STOP; - if (csa->prob.spu_status_R & mask) { - out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_RUNNABLE); - eieio(); - POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & - SPU_STATUS_RUNNING); - } -} - -static inline void restore_status_part2(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - u32 mask; - - /* Restore, Step 43: - * If all CSA.SPU_Status[I,S,H,P,R]=0 then write - * SPU_RunCntl[R0R1]='01', wait for SPU_Status[R]=1, - * then write '00' to SPU_RunCntl[R0R1] and wait - * for SPU_Status[R]=0. - */ - mask = SPU_STATUS_INVALID_INSTR | - SPU_STATUS_SINGLE_STEP | - SPU_STATUS_STOPPED_BY_HALT | - SPU_STATUS_STOPPED_BY_STOP | SPU_STATUS_RUNNING; - if (!(csa->prob.spu_status_R & mask)) { - out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_RUNNABLE); - eieio(); - POLL_WHILE_FALSE(in_be32(&prob->spu_status_R) & - SPU_STATUS_RUNNING); - out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP); - eieio(); - POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & - SPU_STATUS_RUNNING); - } -} - -static inline void restore_ls_16kb(struct spu_state *csa, struct spu *spu) -{ - unsigned long addr = (unsigned long)&csa->lscsa->ls[0]; - unsigned int ls_offset = 0x0; - unsigned int size = 16384; - unsigned int tag = 0; - unsigned int rclass = 0; - unsigned int cmd = MFC_GET_CMD; - - /* Restore, Step 44: - * Issue a DMA command to restore the first - * 16kb of local storage from CSA. - */ - send_mfc_dma(spu, addr, ls_offset, size, tag, rclass, cmd); -} - -static inline void clear_interrupts(struct spu_state *csa, struct spu *spu) -{ - /* Restore, Step 49: - * Write INT_MASK_class0 with value of 0. - * Write INT_MASK_class1 with value of 0. - * Write INT_MASK_class2 with value of 0. - * Write INT_STAT_class0 with value of -1. - * Write INT_STAT_class1 with value of -1. - * Write INT_STAT_class2 with value of -1. - */ - spin_lock_irq(&spu->register_lock); - spu_int_mask_set(spu, 0, 0ul); - spu_int_mask_set(spu, 1, 0ul); - spu_int_mask_set(spu, 2, 0ul); - spu_int_stat_clear(spu, 0, ~0ul); - spu_int_stat_clear(spu, 1, ~0ul); - spu_int_stat_clear(spu, 2, ~0ul); - spin_unlock_irq(&spu->register_lock); -} - -static inline void restore_mfc_queues(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - int i; - - /* Restore, Step 50: - * If MFC_Cntl[Se]!=0 then restore - * MFC command queues. - */ - if ((csa->priv2.mfc_control_RW & MFC_CNTL_DMA_QUEUES_EMPTY_MASK) == 0) { - for (i = 0; i < 8; i++) { - out_be64(&priv2->puq[i].mfc_cq_data0_RW, - csa->priv2.puq[i].mfc_cq_data0_RW); - out_be64(&priv2->puq[i].mfc_cq_data1_RW, - csa->priv2.puq[i].mfc_cq_data1_RW); - out_be64(&priv2->puq[i].mfc_cq_data2_RW, - csa->priv2.puq[i].mfc_cq_data2_RW); - out_be64(&priv2->puq[i].mfc_cq_data3_RW, - csa->priv2.puq[i].mfc_cq_data3_RW); - } - for (i = 0; i < 16; i++) { - out_be64(&priv2->spuq[i].mfc_cq_data0_RW, - csa->priv2.spuq[i].mfc_cq_data0_RW); - out_be64(&priv2->spuq[i].mfc_cq_data1_RW, - csa->priv2.spuq[i].mfc_cq_data1_RW); - out_be64(&priv2->spuq[i].mfc_cq_data2_RW, - csa->priv2.spuq[i].mfc_cq_data2_RW); - out_be64(&priv2->spuq[i].mfc_cq_data3_RW, - csa->priv2.spuq[i].mfc_cq_data3_RW); - } - } - eieio(); -} - -static inline void restore_ppu_querymask(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Restore, Step 51: - * Restore the PPU_QueryMask register from CSA. - */ - out_be32(&prob->dma_querymask_RW, csa->prob.dma_querymask_RW); - eieio(); -} - -static inline void restore_ppu_querytype(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Restore, Step 52: - * Restore the PPU_QueryType register from CSA. - */ - out_be32(&prob->dma_querytype_RW, csa->prob.dma_querytype_RW); - eieio(); -} - -static inline void restore_mfc_csr_tsq(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Restore, Step 53: - * Restore the MFC_CSR_TSQ register from CSA. - */ - out_be64(&priv2->spu_tag_status_query_RW, - csa->priv2.spu_tag_status_query_RW); - eieio(); -} - -static inline void restore_mfc_csr_cmd(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Restore, Step 54: - * Restore the MFC_CSR_CMD1 and MFC_CSR_CMD2 - * registers from CSA. - */ - out_be64(&priv2->spu_cmd_buf1_RW, csa->priv2.spu_cmd_buf1_RW); - out_be64(&priv2->spu_cmd_buf2_RW, csa->priv2.spu_cmd_buf2_RW); - eieio(); -} - -static inline void restore_mfc_csr_ato(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Restore, Step 55: - * Restore the MFC_CSR_ATO register from CSA. - */ - out_be64(&priv2->spu_atomic_status_RW, csa->priv2.spu_atomic_status_RW); -} - -static inline void restore_mfc_tclass_id(struct spu_state *csa, struct spu *spu) -{ - /* Restore, Step 56: - * Restore the MFC_TCLASS_ID register from CSA. - */ - spu_mfc_tclass_id_set(spu, csa->priv1.mfc_tclass_id_RW); - eieio(); -} - -static inline void set_llr_event(struct spu_state *csa, struct spu *spu) -{ - u64 ch0_cnt, ch0_data; - u64 ch1_data; - - /* Restore, Step 57: - * Set the Lock Line Reservation Lost Event by: - * 1. OR CSA.SPU_Event_Status with bit 21 (Lr) set to 1. - * 2. If CSA.SPU_Channel_0_Count=0 and - * CSA.SPU_Wr_Event_Mask[Lr]=1 and - * CSA.SPU_Event_Status[Lr]=0 then set - * CSA.SPU_Event_Status_Count=1. - */ - ch0_cnt = csa->spu_chnlcnt_RW[0]; - ch0_data = csa->spu_chnldata_RW[0]; - ch1_data = csa->spu_chnldata_RW[1]; - csa->spu_chnldata_RW[0] |= MFC_LLR_LOST_EVENT; - if ((ch0_cnt == 0) && !(ch0_data & MFC_LLR_LOST_EVENT) && - (ch1_data & MFC_LLR_LOST_EVENT)) { - csa->spu_chnlcnt_RW[0] = 1; - } -} - -static inline void restore_decr_wrapped(struct spu_state *csa, struct spu *spu) -{ - /* Restore, Step 58: - * If the status of the CSA software decrementer - * "wrapped" flag is set, OR in a '1' to - * CSA.SPU_Event_Status[Tm]. - */ - if (csa->lscsa->decr_status.slot[0] == 1) { - csa->spu_chnldata_RW[0] |= 0x20; - } - if ((csa->lscsa->decr_status.slot[0] == 1) && - (csa->spu_chnlcnt_RW[0] == 0 && - ((csa->spu_chnldata_RW[2] & 0x20) == 0x0) && - ((csa->spu_chnldata_RW[0] & 0x20) != 0x1))) { - csa->spu_chnlcnt_RW[0] = 1; - } -} - -static inline void restore_ch_part1(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 idx, ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL }; - int i; - - /* Restore, Step 59: - * Restore the following CH: [0,1,3,4,24,25,27] - */ - for (i = 0; i < 7; i++) { - idx = ch_indices[i]; - out_be64(&priv2->spu_chnlcntptr_RW, idx); - eieio(); - out_be64(&priv2->spu_chnldata_RW, csa->spu_chnldata_RW[idx]); - out_be64(&priv2->spu_chnlcnt_RW, csa->spu_chnlcnt_RW[idx]); - eieio(); - } -} - -static inline void restore_ch_part2(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 ch_indices[3] = { 9UL, 21UL, 23UL }; - u64 ch_counts[3] = { 1UL, 16UL, 1UL }; - u64 idx; - int i; - - /* Restore, Step 60: - * Restore the following CH: [9,21,23]. - */ - ch_counts[0] = 1UL; - ch_counts[1] = csa->spu_chnlcnt_RW[21]; - ch_counts[2] = 1UL; - for (i = 0; i < 3; i++) { - idx = ch_indices[i]; - out_be64(&priv2->spu_chnlcntptr_RW, idx); - eieio(); - out_be64(&priv2->spu_chnlcnt_RW, ch_counts[i]); - eieio(); - } -} - -static inline void restore_spu_lslr(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Restore, Step 61: - * Restore the SPU_LSLR register from CSA. - */ - out_be64(&priv2->spu_lslr_RW, csa->priv2.spu_lslr_RW); - eieio(); -} - -static inline void restore_spu_cfg(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Restore, Step 62: - * Restore the SPU_Cfg register from CSA. - */ - out_be64(&priv2->spu_cfg_RW, csa->priv2.spu_cfg_RW); - eieio(); -} - -static inline void restore_pm_trace(struct spu_state *csa, struct spu *spu) -{ - /* Restore, Step 63: - * Restore PM_Trace_Tag_Wait_Mask from CSA. - * Not performed by this implementation. - */ -} - -static inline void restore_spu_npc(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Restore, Step 64: - * Restore SPU_NPC from CSA. - */ - out_be32(&prob->spu_npc_RW, csa->prob.spu_npc_RW); - eieio(); -} - -static inline void restore_spu_mb(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - int i; - - /* Restore, Step 65: - * Restore MFC_RdSPU_MB from CSA. - */ - out_be64(&priv2->spu_chnlcntptr_RW, 29UL); - eieio(); - out_be64(&priv2->spu_chnlcnt_RW, csa->spu_chnlcnt_RW[29]); - for (i = 0; i < 4; i++) { - out_be64(&priv2->spu_chnldata_RW, csa->spu_mailbox_data[i]); - } - eieio(); -} - -static inline void check_ppu_mb_stat(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - u32 dummy = 0; - - /* Restore, Step 66: - * If CSA.MB_Stat[P]=0 (mailbox empty) then - * read from the PPU_MB register. - */ - if ((csa->prob.mb_stat_R & 0xFF) == 0) { - dummy = in_be32(&prob->pu_mb_R); - eieio(); - } -} - -static inline void check_ppuint_mb_stat(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - u64 dummy = 0UL; - - /* Restore, Step 66: - * If CSA.MB_Stat[I]=0 (mailbox empty) then - * read from the PPUINT_MB register. - */ - if ((csa->prob.mb_stat_R & 0xFF0000) == 0) { - dummy = in_be64(&priv2->puint_mb_R); - eieio(); - spu_int_stat_clear(spu, 2, CLASS2_ENABLE_MAILBOX_INTR); - eieio(); - } -} - -static inline void restore_mfc_slbs(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - int i; - - /* Restore, Step 68: - * If MFC_SR1[R]='1', restore SLBs from CSA. - */ - if (csa->priv1.mfc_sr1_RW & MFC_STATE1_RELOCATE_MASK) { - for (i = 0; i < 8; i++) { - out_be64(&priv2->slb_index_W, i); - eieio(); - out_be64(&priv2->slb_esid_RW, csa->slb_esid_RW[i]); - out_be64(&priv2->slb_vsid_RW, csa->slb_vsid_RW[i]); - eieio(); - } - out_be64(&priv2->slb_index_W, csa->priv2.slb_index_W); - eieio(); - } -} - -static inline void restore_mfc_sr1(struct spu_state *csa, struct spu *spu) -{ - /* Restore, Step 69: - * Restore the MFC_SR1 register from CSA. - */ - spu_mfc_sr1_set(spu, csa->priv1.mfc_sr1_RW); - eieio(); -} - -static inline void restore_other_spu_access(struct spu_state *csa, - struct spu *spu) -{ - /* Restore, Step 70: - * Restore other SPU mappings to this SPU. TBD. - */ -} - -static inline void restore_spu_runcntl(struct spu_state *csa, struct spu *spu) -{ - struct spu_problem __iomem *prob = spu->problem; - - /* Restore, Step 71: - * If CSA.SPU_Status[R]=1 then write - * SPU_RunCntl[R0R1]='01'. - */ - if (csa->prob.spu_status_R & SPU_STATUS_RUNNING) { - out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_RUNNABLE); - eieio(); - } -} - -static inline void restore_mfc_cntl(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Restore, Step 72: - * Restore the MFC_CNTL register for the CSA. - */ - out_be64(&priv2->mfc_control_RW, csa->priv2.mfc_control_RW); - eieio(); -} - -static inline void enable_user_access(struct spu_state *csa, struct spu *spu) -{ - /* Restore, Step 73: - * Enable user-space access (if provided) to this - * SPU by mapping the virtual pages assigned to - * the SPU memory-mapped I/O (MMIO) for problem - * state. TBD. - */ -} - -static inline void reset_switch_active(struct spu_state *csa, struct spu *spu) -{ - /* Restore, Step 74: - * Reset the "context switch active" flag. - */ - clear_bit(SPU_CONTEXT_SWITCH_ACTIVE, &spu->flags); - mb(); -} - -static inline void reenable_interrupts(struct spu_state *csa, struct spu *spu) -{ - /* Restore, Step 75: - * Re-enable SPU interrupts. - */ - spin_lock_irq(&spu->register_lock); - spu_int_mask_set(spu, 0, csa->priv1.int_mask_class0_RW); - spu_int_mask_set(spu, 1, csa->priv1.int_mask_class1_RW); - spu_int_mask_set(spu, 2, csa->priv1.int_mask_class2_RW); - spin_unlock_irq(&spu->register_lock); -} - -static int quiece_spu(struct spu_state *prev, struct spu *spu) -{ - /* - * Combined steps 2-18 of SPU context save sequence, which - * quiesce the SPU state (disable SPU execution, MFC command - * queues, decrementer, SPU interrupts, etc.). - * - * Returns 0 on success. - * 2 if failed step 2. - * 6 if failed step 6. - */ - - if (check_spu_isolate(prev, spu)) { /* Step 2. */ - return 2; - } - disable_interrupts(prev, spu); /* Step 3. */ - set_watchdog_timer(prev, spu); /* Step 4. */ - inhibit_user_access(prev, spu); /* Step 5. */ - if (check_spu_isolate(prev, spu)) { /* Step 6. */ - return 6; - } - set_switch_pending(prev, spu); /* Step 7. */ - save_mfc_cntl(prev, spu); /* Step 8. */ - save_spu_runcntl(prev, spu); /* Step 9. */ - save_mfc_sr1(prev, spu); /* Step 10. */ - save_spu_status(prev, spu); /* Step 11. */ - save_mfc_decr(prev, spu); /* Step 12. */ - halt_mfc_decr(prev, spu); /* Step 13. */ - save_timebase(prev, spu); /* Step 14. */ - remove_other_spu_access(prev, spu); /* Step 15. */ - do_mfc_mssync(prev, spu); /* Step 16. */ - issue_mfc_tlbie(prev, spu); /* Step 17. */ - handle_pending_interrupts(prev, spu); /* Step 18. */ - - return 0; -} - -static void save_csa(struct spu_state *prev, struct spu *spu) -{ - /* - * Combine steps 19-44 of SPU context save sequence, which - * save regions of the privileged & problem state areas. - */ - - save_mfc_queues(prev, spu); /* Step 19. */ - save_ppu_querymask(prev, spu); /* Step 20. */ - save_ppu_querytype(prev, spu); /* Step 21. */ - save_mfc_csr_tsq(prev, spu); /* Step 22. */ - save_mfc_csr_cmd(prev, spu); /* Step 23. */ - save_mfc_csr_ato(prev, spu); /* Step 24. */ - save_mfc_tclass_id(prev, spu); /* Step 25. */ - set_mfc_tclass_id(prev, spu); /* Step 26. */ - purge_mfc_queue(prev, spu); /* Step 27. */ - wait_purge_complete(prev, spu); /* Step 28. */ - save_mfc_slbs(prev, spu); /* Step 29. */ - setup_mfc_sr1(prev, spu); /* Step 30. */ - save_spu_npc(prev, spu); /* Step 31. */ - save_spu_privcntl(prev, spu); /* Step 32. */ - reset_spu_privcntl(prev, spu); /* Step 33. */ - save_spu_lslr(prev, spu); /* Step 34. */ - reset_spu_lslr(prev, spu); /* Step 35. */ - save_spu_cfg(prev, spu); /* Step 36. */ - save_pm_trace(prev, spu); /* Step 37. */ - save_mfc_rag(prev, spu); /* Step 38. */ - save_ppu_mb_stat(prev, spu); /* Step 39. */ - save_ppu_mb(prev, spu); /* Step 40. */ - save_ppuint_mb(prev, spu); /* Step 41. */ - save_ch_part1(prev, spu); /* Step 42. */ - save_spu_mb(prev, spu); /* Step 43. */ - save_mfc_cmd(prev, spu); /* Step 44. */ - reset_ch(prev, spu); /* Step 45. */ -} - -static void save_lscsa(struct spu_state *prev, struct spu *spu) -{ - /* - * Perform steps 46-57 of SPU context save sequence, - * which save regions of the local store and register - * file. - */ - - resume_mfc_queue(prev, spu); /* Step 46. */ - setup_mfc_slbs(prev, spu); /* Step 47. */ - set_switch_active(prev, spu); /* Step 48. */ - enable_interrupts(prev, spu); /* Step 49. */ - save_ls_16kb(prev, spu); /* Step 50. */ - set_spu_npc(prev, spu); /* Step 51. */ - set_signot1(prev, spu); /* Step 52. */ - set_signot2(prev, spu); /* Step 53. */ - send_save_code(prev, spu); /* Step 54. */ - set_ppu_querymask(prev, spu); /* Step 55. */ - wait_tag_complete(prev, spu); /* Step 56. */ - wait_spu_stopped(prev, spu); /* Step 57. */ -} - -static void harvest(struct spu_state *prev, struct spu *spu) -{ - /* - * Perform steps 2-25 of SPU context restore sequence, - * which resets an SPU either after a failed save, or - * when using SPU for first time. - */ - - disable_interrupts(prev, spu); /* Step 2. */ - inhibit_user_access(prev, spu); /* Step 3. */ - terminate_spu_app(prev, spu); /* Step 4. */ - set_switch_pending(prev, spu); /* Step 5. */ - remove_other_spu_access(prev, spu); /* Step 6. */ - suspend_mfc(prev, spu); /* Step 7. */ - wait_suspend_mfc_complete(prev, spu); /* Step 8. */ - if (!suspend_spe(prev, spu)) /* Step 9. */ - clear_spu_status(prev, spu); /* Step 10. */ - do_mfc_mssync(prev, spu); /* Step 11. */ - issue_mfc_tlbie(prev, spu); /* Step 12. */ - handle_pending_interrupts(prev, spu); /* Step 13. */ - purge_mfc_queue(prev, spu); /* Step 14. */ - wait_purge_complete(prev, spu); /* Step 15. */ - reset_spu_privcntl(prev, spu); /* Step 16. */ - reset_spu_lslr(prev, spu); /* Step 17. */ - setup_mfc_sr1(prev, spu); /* Step 18. */ - invalidate_slbs(prev, spu); /* Step 19. */ - reset_ch_part1(prev, spu); /* Step 20. */ - reset_ch_part2(prev, spu); /* Step 21. */ - enable_interrupts(prev, spu); /* Step 22. */ - set_switch_active(prev, spu); /* Step 23. */ - set_mfc_tclass_id(prev, spu); /* Step 24. */ - resume_mfc_queue(prev, spu); /* Step 25. */ -} - -static void restore_lscsa(struct spu_state *next, struct spu *spu) -{ - /* - * Perform steps 26-40 of SPU context restore sequence, - * which restores regions of the local store and register - * file. - */ - - set_watchdog_timer(next, spu); /* Step 26. */ - setup_spu_status_part1(next, spu); /* Step 27. */ - setup_spu_status_part2(next, spu); /* Step 28. */ - restore_mfc_rag(next, spu); /* Step 29. */ - setup_mfc_slbs(next, spu); /* Step 30. */ - set_spu_npc(next, spu); /* Step 31. */ - set_signot1(next, spu); /* Step 32. */ - set_signot2(next, spu); /* Step 33. */ - setup_decr(next, spu); /* Step 34. */ - setup_ppu_mb(next, spu); /* Step 35. */ - setup_ppuint_mb(next, spu); /* Step 36. */ - send_restore_code(next, spu); /* Step 37. */ - set_ppu_querymask(next, spu); /* Step 38. */ - wait_tag_complete(next, spu); /* Step 39. */ - wait_spu_stopped(next, spu); /* Step 40. */ -} - -static void restore_csa(struct spu_state *next, struct spu *spu) -{ - /* - * Combine steps 41-76 of SPU context restore sequence, which - * restore regions of the privileged & problem state areas. - */ - - restore_spu_privcntl(next, spu); /* Step 41. */ - restore_status_part1(next, spu); /* Step 42. */ - restore_status_part2(next, spu); /* Step 43. */ - restore_ls_16kb(next, spu); /* Step 44. */ - wait_tag_complete(next, spu); /* Step 45. */ - suspend_mfc(next, spu); /* Step 46. */ - wait_suspend_mfc_complete(next, spu); /* Step 47. */ - issue_mfc_tlbie(next, spu); /* Step 48. */ - clear_interrupts(next, spu); /* Step 49. */ - restore_mfc_queues(next, spu); /* Step 50. */ - restore_ppu_querymask(next, spu); /* Step 51. */ - restore_ppu_querytype(next, spu); /* Step 52. */ - restore_mfc_csr_tsq(next, spu); /* Step 53. */ - restore_mfc_csr_cmd(next, spu); /* Step 54. */ - restore_mfc_csr_ato(next, spu); /* Step 55. */ - restore_mfc_tclass_id(next, spu); /* Step 56. */ - set_llr_event(next, spu); /* Step 57. */ - restore_decr_wrapped(next, spu); /* Step 58. */ - restore_ch_part1(next, spu); /* Step 59. */ - restore_ch_part2(next, spu); /* Step 60. */ - restore_spu_lslr(next, spu); /* Step 61. */ - restore_spu_cfg(next, spu); /* Step 62. */ - restore_pm_trace(next, spu); /* Step 63. */ - restore_spu_npc(next, spu); /* Step 64. */ - restore_spu_mb(next, spu); /* Step 65. */ - check_ppu_mb_stat(next, spu); /* Step 66. */ - check_ppuint_mb_stat(next, spu); /* Step 67. */ - restore_mfc_slbs(next, spu); /* Step 68. */ - restore_mfc_sr1(next, spu); /* Step 69. */ - restore_other_spu_access(next, spu); /* Step 70. */ - restore_spu_runcntl(next, spu); /* Step 71. */ - restore_mfc_cntl(next, spu); /* Step 72. */ - enable_user_access(next, spu); /* Step 73. */ - reset_switch_active(next, spu); /* Step 74. */ - reenable_interrupts(next, spu); /* Step 75. */ -} - -static int __do_spu_save(struct spu_state *prev, struct spu *spu) -{ - int rc; - - /* - * SPU context save can be broken into three phases: - * - * (a) quiesce [steps 2-16]. - * (b) save of CSA, performed by PPE [steps 17-42] - * (c) save of LSCSA, mostly performed by SPU [steps 43-52]. - * - * Returns 0 on success. - * 2,6 if failed to quiece SPU - * 53 if SPU-side of save failed. - */ - - rc = quiece_spu(prev, spu); /* Steps 2-16. */ - switch (rc) { - default: - case 2: - case 6: - harvest(prev, spu); - return rc; - break; - case 0: - break; - } - save_csa(prev, spu); /* Steps 17-43. */ - save_lscsa(prev, spu); /* Steps 44-53. */ - return check_save_status(prev, spu); /* Step 54. */ -} - -static int __do_spu_restore(struct spu_state *next, struct spu *spu) -{ - int rc; - - /* - * SPU context restore can be broken into three phases: - * - * (a) harvest (or reset) SPU [steps 2-24]. - * (b) restore LSCSA [steps 25-40], mostly performed by SPU. - * (c) restore CSA [steps 41-76], performed by PPE. - * - * The 'harvest' step is not performed here, but rather - * as needed below. - */ - - restore_lscsa(next, spu); /* Steps 24-39. */ - rc = check_restore_status(next, spu); /* Step 40. */ - switch (rc) { - default: - /* Failed. Return now. */ - return rc; - break; - case 0: - /* Fall through to next step. */ - break; - } - restore_csa(next, spu); - - return 0; -} - -/** - * spu_save - SPU context save, with locking. - * @prev: pointer to SPU context save area, to be saved. - * @spu: pointer to SPU iomem structure. - * - * Acquire locks, perform the save operation then return. - */ -int spu_save(struct spu_state *prev, struct spu *spu) -{ - int rc; - - acquire_spu_lock(spu); /* Step 1. */ - rc = __do_spu_save(prev, spu); /* Steps 2-53. */ - release_spu_lock(spu); - if (rc) { - panic("%s failed on SPU[%d], rc=%d.\n", - __func__, spu->number, rc); - } - return rc; -} - -/** - * spu_restore - SPU context restore, with harvest and locking. - * @new: pointer to SPU context save area, to be restored. - * @spu: pointer to SPU iomem structure. - * - * Perform harvest + restore, as we may not be coming - * from a previous succesful save operation, and the - * hardware state is unknown. - */ -int spu_restore(struct spu_state *new, struct spu *spu) -{ - int rc; - - acquire_spu_lock(spu); - harvest(NULL, spu); - spu->stop_code = 0; - spu->dar = 0; - spu->dsisr = 0; - spu->slb_replace = 0; - spu->class_0_pending = 0; - rc = __do_spu_restore(new, spu); - release_spu_lock(spu); - if (rc) { - panic("%s failed on SPU[%d] rc=%d.\n", - __func__, spu->number, rc); - } - return rc; -} - -/** - * spu_harvest - SPU harvest (reset) operation - * @spu: pointer to SPU iomem structure. - * - * Perform SPU harvest (reset) operation. - */ -void spu_harvest(struct spu *spu) -{ - acquire_spu_lock(spu); - harvest(NULL, spu); - release_spu_lock(spu); -} - -static void init_prob(struct spu_state *csa) -{ - csa->spu_chnlcnt_RW[9] = 1; - csa->spu_chnlcnt_RW[21] = 16; - csa->spu_chnlcnt_RW[23] = 1; - csa->spu_chnlcnt_RW[28] = 1; - csa->spu_chnlcnt_RW[30] = 1; - csa->prob.spu_runcntl_RW = SPU_RUNCNTL_STOP; -} - -static void init_priv1(struct spu_state *csa) -{ - /* Enable decode, relocate, tlbie response, master runcntl. */ - csa->priv1.mfc_sr1_RW = MFC_STATE1_LOCAL_STORAGE_DECODE_MASK | - MFC_STATE1_MASTER_RUN_CONTROL_MASK | - MFC_STATE1_PROBLEM_STATE_MASK | - MFC_STATE1_RELOCATE_MASK | MFC_STATE1_BUS_TLBIE_MASK; - - /* Set storage description. */ - csa->priv1.mfc_sdr_RW = mfspr(SPRN_SDR1); - - /* Enable OS-specific set of interrupts. */ - csa->priv1.int_mask_class0_RW = CLASS0_ENABLE_DMA_ALIGNMENT_INTR | - CLASS0_ENABLE_INVALID_DMA_COMMAND_INTR | - CLASS0_ENABLE_SPU_ERROR_INTR; - csa->priv1.int_mask_class1_RW = CLASS1_ENABLE_SEGMENT_FAULT_INTR | - CLASS1_ENABLE_STORAGE_FAULT_INTR; - csa->priv1.int_mask_class2_RW = CLASS2_ENABLE_SPU_STOP_INTR | - CLASS2_ENABLE_SPU_HALT_INTR; -} - -static void init_priv2(struct spu_state *csa) -{ - csa->priv2.spu_lslr_RW = LS_ADDR_MASK; - csa->priv2.mfc_control_RW = MFC_CNTL_RESUME_DMA_QUEUE | - MFC_CNTL_NORMAL_DMA_QUEUE_OPERATION | - MFC_CNTL_DMA_QUEUES_EMPTY_MASK; -} - -/** - * spu_alloc_csa - allocate and initialize an SPU context save area. - * - * Allocate and initialize the contents of an SPU context save area. - * This includes enabling address translation, interrupt masks, etc., - * as appropriate for the given OS environment. - * - * Note that storage for the 'lscsa' is allocated separately, - * as it is by far the largest of the context save regions, - * and may need to be pinned or otherwise specially aligned. - */ -void spu_init_csa(struct spu_state *csa) -{ - struct spu_lscsa *lscsa; - unsigned char *p; - - if (!csa) - return; - memset(csa, 0, sizeof(struct spu_state)); - - lscsa = vmalloc(sizeof(struct spu_lscsa)); - if (!lscsa) - return; - - memset(lscsa, 0, sizeof(struct spu_lscsa)); - csa->lscsa = lscsa; - csa->register_lock = SPIN_LOCK_UNLOCKED; - - /* Set LS pages reserved to allow for user-space mapping. */ - for (p = lscsa->ls; p < lscsa->ls + LS_SIZE; p += PAGE_SIZE) - SetPageReserved(vmalloc_to_page(p)); - - init_prob(csa); - init_priv1(csa); - init_priv2(csa); -} - -void spu_fini_csa(struct spu_state *csa) -{ - /* Clear reserved bit before vfree. */ - unsigned char *p; - for (p = csa->lscsa->ls; p < csa->lscsa->ls + LS_SIZE; p += PAGE_SIZE) - ClearPageReserved(vmalloc_to_page(p)); - - vfree(csa->lscsa); -} diff --git a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c b/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c deleted file mode 100644 index d549aa7ebea6..000000000000 --- a/trunk/arch/powerpc/platforms/cell/spufs/syscalls.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include "spufs.h" - -/** - * sys_spu_run - run code loaded into an SPU - * - * @unpc: next program counter for the SPU - * @ustatus: status of the SPU - * - * This system call transfers the control of execution of a - * user space thread to an SPU. It will return when the - * SPU has finished executing or when it hits an error - * condition and it will be interrupted if a signal needs - * to be delivered to a handler in user space. - * - * The next program counter is set to the passed value - * before the SPU starts fetching code and the user space - * pointer gets updated with the new value when returning - * from kernel space. - * - * The status value returned from spu_run reflects the - * value of the spu_status register after the SPU has stopped. - * - */ -long do_spu_run(struct file *filp, __u32 __user *unpc, __u32 __user *ustatus) -{ - long ret; - struct spufs_inode_info *i; - u32 npc, status; - - ret = -EFAULT; - if (get_user(npc, unpc) || get_user(status, ustatus)) - goto out; - - /* check if this file was created by spu_create */ - ret = -EINVAL; - if (filp->f_op != &spufs_context_fops) - goto out; - - i = SPUFS_I(filp->f_dentry->d_inode); - ret = spufs_run_spu(filp, i->i_ctx, &npc, &status); - - if (put_user(npc, unpc) || put_user(status, ustatus)) - ret = -EFAULT; -out: - return ret; -} - -#ifndef MODULE -asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus) -{ - int fput_needed; - struct file *filp; - long ret; - - ret = -EBADF; - filp = fget_light(fd, &fput_needed); - if (filp) { - ret = do_spu_run(filp, unpc, ustatus); - fput_light(filp, fput_needed); - } - - return ret; -} -#endif - -asmlinkage long sys_spu_create(const char __user *pathname, - unsigned int flags, mode_t mode) -{ - char *tmp; - int ret; - - tmp = getname(pathname); - ret = PTR_ERR(tmp); - if (!IS_ERR(tmp)) { - struct nameidata nd; - - ret = path_lookup(tmp, LOOKUP_PARENT| - LOOKUP_OPEN|LOOKUP_CREATE, &nd); - if (!ret) { - ret = spufs_create_thread(&nd, flags, mode); - path_release(&nd); - } - putname(tmp); - } - - return ret; -} - -struct spufs_calls spufs_calls = { - .create_thread = sys_spu_create, - .spu_run = do_spu_run, - .owner = THIS_MODULE, -}; diff --git a/trunk/arch/powerpc/platforms/chrp/setup.c b/trunk/arch/powerpc/platforms/chrp/setup.c index 4ec8ba737e7d..dda5f2c72c25 100644 --- a/trunk/arch/powerpc/platforms/chrp/setup.c +++ b/trunk/arch/powerpc/platforms/chrp/setup.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,7 @@ #include "chrp.h" void rtas_indicator_progress(char *, unsigned short); +void btext_progress(char *, unsigned short); int _chrp_type; EXPORT_SYMBOL(_chrp_type); @@ -262,6 +264,11 @@ void __init chrp_setup_arch(void) ppc_md.set_rtc_time = rtas_set_rtc_time; } +#ifdef CONFIG_BOOTX_TEXT + if (ppc_md.progress == NULL && boot_text_mapped) + ppc_md.progress = btext_progress; +#endif + #ifdef CONFIG_BLK_DEV_INITRD /* this is fine for chrp */ initrd_below_start_ok = 1; @@ -515,3 +522,12 @@ void __init chrp_init(void) smp_ops = &chrp_smp_ops; #endif /* CONFIG_SMP */ } + +#ifdef CONFIG_BOOTX_TEXT +void +btext_progress(char *s, unsigned short hex) +{ + btext_drawstring(s); + btext_drawstring("\n"); +} +#endif /* CONFIG_BOOTX_TEXT */ diff --git a/trunk/arch/powerpc/platforms/iseries/irq.c b/trunk/arch/powerpc/platforms/iseries/irq.c index 42e978e4897a..a58daa153686 100644 --- a/trunk/arch/powerpc/platforms/iseries/irq.c +++ b/trunk/arch/powerpc/platforms/iseries/irq.c @@ -35,138 +35,161 @@ #include #include -#include #include #include #include -#include #include "irq.h" #include "call_pci.h" -#if defined(CONFIG_SMP) -extern void iSeries_smp_message_recv(struct pt_regs *); -#endif +static long Pci_Interrupt_Count; +static long Pci_Event_Count; + +enum XmPciLpEvent_Subtype { + XmPciLpEvent_BusCreated = 0, // PHB has been created + XmPciLpEvent_BusError = 1, // PHB has failed + XmPciLpEvent_BusFailed = 2, // Msg to Secondary, Primary failed bus + XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed + XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered + XmPciLpEvent_BusRecovered = 12, // PHB has been recovered + XmPciLpEvent_UnQuiesceBus = 18, // Secondary bus unqiescing + XmPciLpEvent_BridgeError = 21, // Bridge Error + XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt +}; + +struct XmPciLpEvent_BusInterrupt { + HvBusNumber busNumber; + HvSubBusNumber subBusNumber; +}; -enum pci_event_type { - pe_bus_created = 0, /* PHB has been created */ - pe_bus_error = 1, /* PHB has failed */ - pe_bus_failed = 2, /* Msg to Secondary, Primary failed bus */ - pe_node_failed = 4, /* Multi-adapter bridge has failed */ - pe_node_recovered = 5, /* Multi-adapter bridge has recovered */ - pe_bus_recovered = 12, /* PHB has been recovered */ - pe_unquiese_bus = 18, /* Secondary bus unqiescing */ - pe_bridge_error = 21, /* Bridge Error */ - pe_slot_interrupt = 22 /* Slot interrupt */ +struct XmPciLpEvent_NodeInterrupt { + HvBusNumber busNumber; + HvSubBusNumber subBusNumber; + HvAgentId deviceId; }; -struct pci_event { - struct HvLpEvent event; +struct XmPciLpEvent { + struct HvLpEvent hvLpEvent; + union { - u64 __align; /* Align on an 8-byte boundary */ + u64 alignData; // Align on an 8-byte boundary + struct { u32 fisr; - HvBusNumber bus_number; - HvSubBusNumber sub_bus_number; - HvAgentId dev_id; - } slot; - struct { - HvBusNumber bus_number; - HvSubBusNumber sub_bus_number; - } bus; - struct { - HvBusNumber bus_number; - HvSubBusNumber sub_bus_number; - HvAgentId dev_id; - } node; - } data; -}; + HvBusNumber busNumber; + HvSubBusNumber subBusNumber; + HvAgentId deviceId; + } slotInterrupt; + + struct XmPciLpEvent_BusInterrupt busFailed; + struct XmPciLpEvent_BusInterrupt busRecovered; + struct XmPciLpEvent_BusInterrupt busCreated; + + struct XmPciLpEvent_NodeInterrupt nodeFailed; + struct XmPciLpEvent_NodeInterrupt nodeRecovered; + + } eventData; -static DEFINE_SPINLOCK(pending_irqs_lock); -static int num_pending_irqs; -static int pending_irqs[NR_IRQS]; +}; -static void int_received(struct pci_event *event, struct pt_regs *regs) +static void intReceived(struct XmPciLpEvent *eventParm, + struct pt_regs *regsParm) { int irq; +#ifdef CONFIG_IRQSTACKS + struct thread_info *curtp, *irqtp; +#endif - switch (event->event.xSubtype) { - case pe_slot_interrupt: - irq = event->event.xCorrelationToken; - if (irq < NR_IRQS) { - spin_lock(&pending_irqs_lock); - pending_irqs[irq]++; - num_pending_irqs++; - spin_unlock(&pending_irqs_lock); - } else { - printk(KERN_WARNING "int_received: bad irq number %d\n", - irq); - HvCallPci_eoi(event->data.slot.bus_number, - event->data.slot.sub_bus_number, - event->data.slot.dev_id); - } + ++Pci_Interrupt_Count; + + switch (eventParm->hvLpEvent.xSubtype) { + case XmPciLpEvent_SlotInterrupt: + irq = eventParm->hvLpEvent.xCorrelationToken; + /* Dispatch the interrupt handlers for this irq */ +#ifdef CONFIG_IRQSTACKS + /* Switch to the irq stack to handle this */ + curtp = current_thread_info(); + irqtp = hardirq_ctx[smp_processor_id()]; + if (curtp != irqtp) { + irqtp->task = curtp->task; + irqtp->flags = 0; + call___do_IRQ(irq, regsParm, irqtp); + irqtp->task = NULL; + if (irqtp->flags) + set_bits(irqtp->flags, &curtp->flags); + } else +#endif + __do_IRQ(irq, regsParm); + HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber, + eventParm->eventData.slotInterrupt.subBusNumber, + eventParm->eventData.slotInterrupt.deviceId); break; /* Ignore error recovery events for now */ - case pe_bus_created: - printk(KERN_INFO "int_received: system bus %d created\n", - event->data.bus.bus_number); + case XmPciLpEvent_BusCreated: + printk(KERN_INFO "intReceived: system bus %d created\n", + eventParm->eventData.busCreated.busNumber); break; - case pe_bus_error: - case pe_bus_failed: - printk(KERN_INFO "int_received: system bus %d failed\n", - event->data.bus.bus_number); + case XmPciLpEvent_BusError: + case XmPciLpEvent_BusFailed: + printk(KERN_INFO "intReceived: system bus %d failed\n", + eventParm->eventData.busFailed.busNumber); break; - case pe_bus_recovered: - case pe_unquiese_bus: - printk(KERN_INFO "int_received: system bus %d recovered\n", - event->data.bus.bus_number); + case XmPciLpEvent_BusRecovered: + case XmPciLpEvent_UnQuiesceBus: + printk(KERN_INFO "intReceived: system bus %d recovered\n", + eventParm->eventData.busRecovered.busNumber); break; - case pe_node_failed: - case pe_bridge_error: + case XmPciLpEvent_NodeFailed: + case XmPciLpEvent_BridgeError: printk(KERN_INFO - "int_received: multi-adapter bridge %d/%d/%d failed\n", - event->data.node.bus_number, - event->data.node.sub_bus_number, - event->data.node.dev_id); + "intReceived: multi-adapter bridge %d/%d/%d failed\n", + eventParm->eventData.nodeFailed.busNumber, + eventParm->eventData.nodeFailed.subBusNumber, + eventParm->eventData.nodeFailed.deviceId); break; - case pe_node_recovered: + case XmPciLpEvent_NodeRecovered: printk(KERN_INFO - "int_received: multi-adapter bridge %d/%d/%d recovered\n", - event->data.node.bus_number, - event->data.node.sub_bus_number, - event->data.node.dev_id); + "intReceived: multi-adapter bridge %d/%d/%d recovered\n", + eventParm->eventData.nodeRecovered.busNumber, + eventParm->eventData.nodeRecovered.subBusNumber, + eventParm->eventData.nodeRecovered.deviceId); break; default: printk(KERN_ERR - "int_received: unrecognized event subtype 0x%x\n", - event->event.xSubtype); + "intReceived: unrecognized event subtype 0x%x\n", + eventParm->hvLpEvent.xSubtype); break; } } -static void pci_event_handler(struct HvLpEvent *event, struct pt_regs *regs) +static void XmPciLpEvent_handler(struct HvLpEvent *eventParm, + struct pt_regs *regsParm) { - if (event && (event->xType == HvLpEvent_Type_PciIo)) { - switch (event->xFlags.xFunction) { +#ifdef CONFIG_PCI + ++Pci_Event_Count; + + if (eventParm && (eventParm->xType == HvLpEvent_Type_PciIo)) { + switch (eventParm->xFlags.xFunction) { case HvLpEvent_Function_Int: - int_received((struct pci_event *)event, regs); + intReceived((struct XmPciLpEvent *)eventParm, regsParm); break; case HvLpEvent_Function_Ack: printk(KERN_ERR - "pci_event_handler: unexpected ack received\n"); + "XmPciLpEvent_handler: unexpected ack received\n"); break; default: printk(KERN_ERR - "pci_event_handler: unexpected event function %d\n", - (int)event->xFlags.xFunction); + "XmPciLpEvent_handler: unexpected event function %d\n", + (int)eventParm->xFlags.xFunction); break; } - } else if (event) + } else if (eventParm) printk(KERN_ERR - "pci_event_handler: Unrecognized PCI event type 0x%x\n", - (int)event->xType); + "XmPciLpEvent_handler: Unrecognized PCI event type 0x%x\n", + (int)eventParm->xType); else - printk(KERN_ERR "pci_event_handler: NULL event received\n"); + printk(KERN_ERR "XmPciLpEvent_handler: NULL event received\n"); +#endif } /* @@ -176,21 +199,20 @@ static void pci_event_handler(struct HvLpEvent *event, struct pt_regs *regs) void __init iSeries_init_IRQ(void) { /* Register PCI event handler and open an event path */ - int ret; - - ret = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, - &pci_event_handler); - if (ret == 0) { - ret = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0); - if (ret != 0) - printk(KERN_ERR "iseries_init_IRQ: open event path " - "failed with rc 0x%x\n", ret); + int xRc; + + xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, + &XmPciLpEvent_handler); + if (xRc == 0) { + xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0); + if (xRc != 0) + printk(KERN_ERR "iSeries_init_IRQ: open event path " + "failed with rc 0x%x\n", xRc); } else - printk(KERN_ERR "iseries_init_IRQ: register handler " - "failed with rc 0x%x\n", ret); + printk(KERN_ERR "iSeries_init_IRQ: register handler " + "failed with rc 0x%x\n", xRc); } -#define REAL_IRQ_TO_SUBBUS(irq) (((irq) >> 14) & 0xff) #define REAL_IRQ_TO_BUS(irq) ((((irq) >> 6) & 0xff) + 1) #define REAL_IRQ_TO_IDSEL(irq) ((((irq) >> 3) & 7) + 1) #define REAL_IRQ_TO_FUNC(irq) ((irq) & 7) @@ -199,40 +221,40 @@ void __init iSeries_init_IRQ(void) * This will be called by device drivers (via enable_IRQ) * to enable INTA in the bridge interrupt status register. */ -static void iseries_enable_IRQ(unsigned int irq) +static void iSeries_enable_IRQ(unsigned int irq) { - u32 bus, dev_id, function, mask; - const u32 sub_bus = 0; + u32 bus, deviceId, function, mask; + const u32 subBus = 0; unsigned int rirq = virt_irq_to_real_map[irq]; /* The IRQ has already been locked by the caller */ bus = REAL_IRQ_TO_BUS(rirq); function = REAL_IRQ_TO_FUNC(rirq); - dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; + deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; /* Unmask secondary INTA */ mask = 0x80000000; - HvCallPci_unmaskInterrupts(bus, sub_bus, dev_id, mask); + HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask); } -/* This is called by iseries_activate_IRQs */ -static unsigned int iseries_startup_IRQ(unsigned int irq) +/* This is called by iSeries_activate_IRQs */ +static unsigned int iSeries_startup_IRQ(unsigned int irq) { - u32 bus, dev_id, function, mask; - const u32 sub_bus = 0; + u32 bus, deviceId, function, mask; + const u32 subBus = 0; unsigned int rirq = virt_irq_to_real_map[irq]; bus = REAL_IRQ_TO_BUS(rirq); function = REAL_IRQ_TO_FUNC(rirq); - dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; + deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; /* Link the IRQ number to the bridge */ - HvCallXm_connectBusUnit(bus, sub_bus, dev_id, irq); + HvCallXm_connectBusUnit(bus, subBus, deviceId, irq); /* Unmask bridge interrupts in the FISR */ mask = 0x01010000 << function; - HvCallPci_unmaskFisr(bus, sub_bus, dev_id, mask); - iseries_enable_IRQ(irq); + HvCallPci_unmaskFisr(bus, subBus, deviceId, mask); + iSeries_enable_IRQ(irq); return 0; } @@ -257,115 +279,78 @@ void __init iSeries_activate_IRQs() } /* this is not called anywhere currently */ -static void iseries_shutdown_IRQ(unsigned int irq) +static void iSeries_shutdown_IRQ(unsigned int irq) { - u32 bus, dev_id, function, mask; - const u32 sub_bus = 0; + u32 bus, deviceId, function, mask; + const u32 subBus = 0; unsigned int rirq = virt_irq_to_real_map[irq]; /* irq should be locked by the caller */ bus = REAL_IRQ_TO_BUS(rirq); function = REAL_IRQ_TO_FUNC(rirq); - dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; + deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; /* Invalidate the IRQ number in the bridge */ - HvCallXm_connectBusUnit(bus, sub_bus, dev_id, 0); + HvCallXm_connectBusUnit(bus, subBus, deviceId, 0); /* Mask bridge interrupts in the FISR */ mask = 0x01010000 << function; - HvCallPci_maskFisr(bus, sub_bus, dev_id, mask); + HvCallPci_maskFisr(bus, subBus, deviceId, mask); } /* * This will be called by device drivers (via disable_IRQ) * to disable INTA in the bridge interrupt status register. */ -static void iseries_disable_IRQ(unsigned int irq) +static void iSeries_disable_IRQ(unsigned int irq) { - u32 bus, dev_id, function, mask; - const u32 sub_bus = 0; + u32 bus, deviceId, function, mask; + const u32 subBus = 0; unsigned int rirq = virt_irq_to_real_map[irq]; /* The IRQ has already been locked by the caller */ bus = REAL_IRQ_TO_BUS(rirq); function = REAL_IRQ_TO_FUNC(rirq); - dev_id = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; + deviceId = (REAL_IRQ_TO_IDSEL(rirq) << 4) + function; /* Mask secondary INTA */ mask = 0x80000000; - HvCallPci_maskInterrupts(bus, sub_bus, dev_id, mask); + HvCallPci_maskInterrupts(bus, subBus, deviceId, mask); } -static void iseries_end_IRQ(unsigned int irq) +/* + * This does nothing because there is not enough information + * provided to do the EOI HvCall. This is done by XmPciLpEvent.c + */ +static void iSeries_end_IRQ(unsigned int irq) { - unsigned int rirq = virt_irq_to_real_map[irq]; - - HvCallPci_eoi(REAL_IRQ_TO_BUS(rirq), REAL_IRQ_TO_SUBBUS(rirq), - (REAL_IRQ_TO_IDSEL(rirq) << 4) + REAL_IRQ_TO_FUNC(rirq)); } static hw_irq_controller iSeries_IRQ_handler = { .typename = "iSeries irq controller", - .startup = iseries_startup_IRQ, - .shutdown = iseries_shutdown_IRQ, - .enable = iseries_enable_IRQ, - .disable = iseries_disable_IRQ, - .end = iseries_end_IRQ + .startup = iSeries_startup_IRQ, + .shutdown = iSeries_shutdown_IRQ, + .enable = iSeries_enable_IRQ, + .disable = iSeries_disable_IRQ, + .end = iSeries_end_IRQ }; /* * This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot * It calculates the irq value for the slot. - * Note that sub_bus is always 0 (at the moment at least). + * Note that subBusNumber is always 0 (at the moment at least). */ -int __init iSeries_allocate_IRQ(HvBusNumber bus, - HvSubBusNumber sub_bus, HvAgentId dev_id) +int __init iSeries_allocate_IRQ(HvBusNumber busNumber, + HvSubBusNumber subBusNumber, HvAgentId deviceId) { int virtirq; unsigned int realirq; - u8 idsel = (dev_id >> 4); - u8 function = dev_id & 7; + u8 idsel = (deviceId >> 4); + u8 function = deviceId & 7; - realirq = (((((sub_bus << 8) + (bus - 1)) << 3) + (idsel - 1)) << 3) - + function; + realirq = ((busNumber - 1) << 6) + ((idsel - 1) << 3) + function; virtirq = virt_irq_create_mapping(realirq); irq_desc[virtirq].handler = &iSeries_IRQ_handler; return virtirq; } - -/* - * Get the next pending IRQ. - */ -int iSeries_get_irq(struct pt_regs *regs) -{ - struct paca_struct *lpaca; - /* -2 means ignore this interrupt */ - int irq = -2; - - lpaca = get_paca(); -#ifdef CONFIG_SMP - if (lpaca->lppaca.int_dword.fields.ipi_cnt) { - lpaca->lppaca.int_dword.fields.ipi_cnt = 0; - iSeries_smp_message_recv(regs); - } -#endif /* CONFIG_SMP */ - if (hvlpevent_is_pending()) - process_hvlpevents(regs); - - if (num_pending_irqs) { - spin_lock(&pending_irqs_lock); - for (irq = 0; irq < NR_IRQS; irq++) { - if (pending_irqs[irq]) { - pending_irqs[irq]--; - num_pending_irqs--; - break; - } - } - spin_unlock(&pending_irqs_lock); - if (irq >= NR_IRQS) - irq = -2; - } - - return irq; -} diff --git a/trunk/arch/powerpc/platforms/iseries/irq.h b/trunk/arch/powerpc/platforms/iseries/irq.h index b9c801ba5a47..5f643f16ecc0 100644 --- a/trunk/arch/powerpc/platforms/iseries/irq.h +++ b/trunk/arch/powerpc/platforms/iseries/irq.h @@ -4,6 +4,5 @@ extern void iSeries_init_IRQ(void); extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId); extern void iSeries_activate_IRQs(void); -extern int iSeries_get_irq(struct pt_regs *); #endif /* _ISERIES_IRQ_H */ diff --git a/trunk/arch/powerpc/platforms/iseries/lpardata.c b/trunk/arch/powerpc/platforms/iseries/lpardata.c index ea72385aaf0a..bb8c91537f35 100644 --- a/trunk/arch/powerpc/platforms/iseries/lpardata.c +++ b/trunk/arch/powerpc/platforms/iseries/lpardata.c @@ -225,10 +225,3 @@ struct ItVpdAreas itVpdAreas = { 0,0 } }; - -struct ItLpRegSave iseries_reg_save[] = { - [0 ... (NR_CPUS-1)] = { - .xDesc = 0xd397d9e2, /* "LpRS" */ - .xSize = sizeof(struct ItLpRegSave), - }, -}; diff --git a/trunk/arch/powerpc/platforms/iseries/setup.c b/trunk/arch/powerpc/platforms/iseries/setup.c index ad5ef80500ce..da26639190db 100644 --- a/trunk/arch/powerpc/platforms/iseries/setup.c +++ b/trunk/arch/powerpc/platforms/iseries/setup.c @@ -569,6 +569,16 @@ static void iSeries_show_cpuinfo(struct seq_file *m) seq_printf(m, "machine\t\t: 64-bit iSeries Logical Partition\n"); } +/* + * Document me. + * and Implement me. + */ +static int iSeries_get_irq(struct pt_regs *regs) +{ + /* -2 means ignore this interrupt */ + return -2; +} + /* * Document me. */ diff --git a/trunk/arch/powerpc/platforms/maple/setup.c b/trunk/arch/powerpc/platforms/maple/setup.c index dd73e38bfb7d..7ece8983a105 100644 --- a/trunk/arch/powerpc/platforms/maple/setup.c +++ b/trunk/arch/powerpc/platforms/maple/setup.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -192,10 +191,24 @@ static void __init maple_init_early(void) */ hpte_init_native(); + /* Find the serial port */ + generic_find_legacy_serial_ports(&physport, &default_speed); + + DBG("phys port addr: %lx\n", (long)physport); + + if (physport) { + void *comport; + /* Map the uart for udbg. */ + comport = (void *)ioremap(physport, 16); + udbg_init_uart(comport, default_speed); + + DBG("Hello World !\n"); + } + /* Setup interrupt mapping options */ ppc64_interrupt_controller = IC_OPEN_PIC; - iommu_init_early_dart(); + iommu_init_early_u3(); DBG(" <- maple_init_early\n"); } @@ -257,7 +270,7 @@ static int __init maple_probe(int platform) * occupies having to be broken up so the DART itself is not * part of the cacheable linar mapping */ - alloc_dart_table(); + alloc_u3_dart_table(); return 1; } @@ -279,9 +292,4 @@ struct machdep_calls __initdata maple_md = { .calibrate_decr = generic_calibrate_decr, .progress = maple_progress, .idle_loop = native_idle, -#ifdef CONFIG_KEXEC - .machine_kexec = default_machine_kexec, - .machine_kexec_prepare = default_machine_kexec_prepare, - .machine_crash_shutdown = default_machine_crash_shutdown, -#endif }; diff --git a/trunk/arch/powerpc/platforms/powermac/Makefile b/trunk/arch/powerpc/platforms/powermac/Makefile index 78093d7f97af..c9df44fcf571 100644 --- a/trunk/arch/powerpc/platforms/powermac/Makefile +++ b/trunk/arch/powerpc/platforms/powermac/Makefile @@ -1,14 +1,9 @@ -CFLAGS_bootx_init.o += -fPIC - obj-y += pic.o setup.o time.o feature.o pci.o \ - sleep.o low_i2c.o cache.o pfunc_core.o \ - pfunc_base.o + sleep.o low_i2c.o cache.o obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o obj-$(CONFIG_NVRAM) += nvram.o # ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff obj-$(CONFIG_PPC64) += nvram.o -obj-$(CONFIG_PPC32) += bootx_init.o obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_PPC_MERGE) += udbg_scc.o udbg_adb.o diff --git a/trunk/arch/powerpc/platforms/powermac/bootx_init.c b/trunk/arch/powerpc/platforms/powermac/bootx_init.c deleted file mode 100644 index fa8b4d7b5ded..000000000000 --- a/trunk/arch/powerpc/platforms/powermac/bootx_init.c +++ /dev/null @@ -1,547 +0,0 @@ -/* - * Early boot support code for BootX bootloader - * - * Copyright (C) 2005 Ben. Herrenschmidt (benh@kernel.crashing.org) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef DEBUG -#define SET_BOOT_BAT - -#ifdef DEBUG -#define DBG(fmt...) do { bootx_printf(fmt); } while(0) -#else -#define DBG(fmt...) do { } while(0) -#endif - -extern void __start(unsigned long r3, unsigned long r4, unsigned long r5); - -static unsigned long __initdata bootx_dt_strbase; -static unsigned long __initdata bootx_dt_strend; -static unsigned long __initdata bootx_node_chosen; -static boot_infos_t * __initdata bootx_info; -static char __initdata bootx_disp_path[256]; - -/* Is boot-info compatible ? */ -#define BOOT_INFO_IS_COMPATIBLE(bi) \ - ((bi)->compatible_version <= BOOT_INFO_VERSION) -#define BOOT_INFO_IS_V2_COMPATIBLE(bi) ((bi)->version >= 2) -#define BOOT_INFO_IS_V4_COMPATIBLE(bi) ((bi)->version >= 4) - -#ifdef CONFIG_BOOTX_TEXT -static void __init bootx_printf(const char *format, ...) -{ - const char *p, *q, *s; - va_list args; - unsigned long v; - - va_start(args, format); - for (p = format; *p != 0; p = q) { - for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q) - ; - if (q > p) - btext_drawtext(p, q - p); - if (*q == 0) - break; - if (*q == '\n') { - ++q; - btext_flushline(); - btext_drawstring("\r\n"); - btext_flushline(); - continue; - } - ++q; - if (*q == 0) - break; - switch (*q) { - case 's': - ++q; - s = va_arg(args, const char *); - if (s == NULL) - s = ""; - btext_drawstring(s); - break; - case 'x': - ++q; - v = va_arg(args, unsigned long); - btext_drawhex(v); - break; - } - } -} -#else /* CONFIG_BOOTX_TEXT */ -static void __init bootx_printf(const char *format, ...) {} -#endif /* CONFIG_BOOTX_TEXT */ - -static void * __init bootx_early_getprop(unsigned long base, - unsigned long node, - char *prop) -{ - struct bootx_dt_node *np = (struct bootx_dt_node *)(base + node); - u32 *ppp = &np->properties; - - while(*ppp) { - struct bootx_dt_prop *pp = - (struct bootx_dt_prop *)(base + *ppp); - - if (strcmp((char *)((unsigned long)pp->name + base), - prop) == 0) { - return (void *)((unsigned long)pp->value + base); - } - ppp = &pp->next; - } - return NULL; -} - -#define dt_push_token(token, mem) \ - do { \ - *(mem) = _ALIGN_UP(*(mem),4); \ - *((u32 *)*(mem)) = token; \ - *(mem) += 4; \ - } while(0) - -static unsigned long __init bootx_dt_find_string(char *str) -{ - char *s, *os; - - s = os = (char *)bootx_dt_strbase; - s += 4; - while (s < (char *)bootx_dt_strend) { - if (strcmp(s, str) == 0) - return s - os; - s += strlen(s) + 1; - } - return 0; -} - -static void __init bootx_dt_add_prop(char *name, void *data, int size, - unsigned long *mem_end) -{ - unsigned long soff = bootx_dt_find_string(name); - if (data == NULL) - size = 0; - if (soff == 0) { - bootx_printf("WARNING: Can't find string index for <%s>\n", - name); - return; - } - if (size > 0x20000) { - bootx_printf("WARNING: ignoring large property "); - bootx_printf("%s length 0x%x\n", name, size); - return; - } - dt_push_token(OF_DT_PROP, mem_end); - dt_push_token(size, mem_end); - dt_push_token(soff, mem_end); - - /* push property content */ - if (size && data) { - memcpy((void *)*mem_end, data, size); - *mem_end = _ALIGN_UP(*mem_end + size, 4); - } -} - -static void __init bootx_add_chosen_props(unsigned long base, - unsigned long *mem_end) -{ - u32 val = _MACH_Pmac; - - bootx_dt_add_prop("linux,platform", &val, 4, mem_end); - - if (bootx_info->kernelParamsOffset) { - char *args = (char *)((unsigned long)bootx_info) + - bootx_info->kernelParamsOffset; - bootx_dt_add_prop("bootargs", args, strlen(args) + 1, mem_end); - } - if (bootx_info->ramDisk) { - val = ((unsigned long)bootx_info) + bootx_info->ramDisk; - bootx_dt_add_prop("linux,initrd-start", &val, 4, mem_end); - val += bootx_info->ramDiskSize; - bootx_dt_add_prop("linux,initrd-end", &val, 4, mem_end); - } - if (strlen(bootx_disp_path)) - bootx_dt_add_prop("linux,stdout-path", bootx_disp_path, - strlen(bootx_disp_path) + 1, mem_end); -} - -static void __init bootx_add_display_props(unsigned long base, - unsigned long *mem_end) -{ - bootx_dt_add_prop("linux,boot-display", NULL, 0, mem_end); - bootx_dt_add_prop("linux,opened", NULL, 0, mem_end); -} - -static void __init bootx_dt_add_string(char *s, unsigned long *mem_end) -{ - unsigned int l = strlen(s) + 1; - memcpy((void *)*mem_end, s, l); - bootx_dt_strend = *mem_end = *mem_end + l; -} - -static void __init bootx_scan_dt_build_strings(unsigned long base, - unsigned long node, - unsigned long *mem_end) -{ - struct bootx_dt_node *np = (struct bootx_dt_node *)(base + node); - u32 *cpp, *ppp = &np->properties; - unsigned long soff; - char *namep; - - /* Keep refs to known nodes */ - namep = np->full_name ? (char *)(base + np->full_name) : NULL; - if (namep == NULL) { - bootx_printf("Node without a full name !\n"); - namep = ""; - } - DBG("* strings: %s\n", namep); - - if (!strcmp(namep, "/chosen")) { - DBG(" detected /chosen ! adding properties names !\n"); - bootx_dt_add_string("linux,platform", mem_end); - bootx_dt_add_string("linux,stdout-path", mem_end); - bootx_dt_add_string("linux,initrd-start", mem_end); - bootx_dt_add_string("linux,initrd-end", mem_end); - bootx_dt_add_string("bootargs", mem_end); - bootx_node_chosen = node; - } - if (node == bootx_info->dispDeviceRegEntryOffset) { - DBG(" detected display ! adding properties names !\n"); - bootx_dt_add_string("linux,boot-display", mem_end); - bootx_dt_add_string("linux,opened", mem_end); - strncpy(bootx_disp_path, namep, 255); - } - - /* get and store all property names */ - while (*ppp) { - struct bootx_dt_prop *pp = - (struct bootx_dt_prop *)(base + *ppp); - - namep = pp->name ? (char *)(base + pp->name) : NULL; - if (namep == NULL || strcmp(namep, "name") == 0) - goto next; - /* get/create string entry */ - soff = bootx_dt_find_string(namep); - if (soff == 0) - bootx_dt_add_string(namep, mem_end); - next: - ppp = &pp->next; - } - - /* do all our children */ - cpp = &np->child; - while(*cpp) { - np = (struct bootx_dt_node *)(base + *cpp); - bootx_scan_dt_build_strings(base, *cpp, mem_end); - cpp = &np->sibling; - } -} - -static void __init bootx_scan_dt_build_struct(unsigned long base, - unsigned long node, - unsigned long *mem_end) -{ - struct bootx_dt_node *np = (struct bootx_dt_node *)(base + node); - u32 *cpp, *ppp = &np->properties; - char *namep, *p, *ep, *lp; - int l; - - dt_push_token(OF_DT_BEGIN_NODE, mem_end); - - /* get the node's full name */ - namep = np->full_name ? (char *)(base + np->full_name) : NULL; - if (namep == NULL) - namep = ""; - l = strlen(namep); - - DBG("* struct: %s\n", namep); - - /* Fixup an Apple bug where they have bogus \0 chars in the - * middle of the path in some properties, and extract - * the unit name (everything after the last '/'). - */ - memcpy((void *)*mem_end, namep, l + 1); - namep = (char *)*mem_end; - for (lp = p = namep, ep = namep + l; p < ep; p++) { - if (*p == '/') - lp = namep; - else if (*p != 0) - *lp++ = *p; - } - *lp = 0; - *mem_end = _ALIGN_UP((unsigned long)lp + 1, 4); - - /* get and store all properties */ - while (*ppp) { - struct bootx_dt_prop *pp = - (struct bootx_dt_prop *)(base + *ppp); - - namep = pp->name ? (char *)(base + pp->name) : NULL; - /* Skip "name" */ - if (namep == NULL || !strcmp(namep, "name")) - goto next; - /* Skip "bootargs" in /chosen too as we replace it */ - if (node == bootx_node_chosen && !strcmp(namep, "bootargs")) - goto next; - - /* push property head */ - bootx_dt_add_prop(namep, - pp->value ? (void *)(base + pp->value): NULL, - pp->length, mem_end); - next: - ppp = &pp->next; - } - - if (node == bootx_node_chosen) - bootx_add_chosen_props(base, mem_end); - if (node == bootx_info->dispDeviceRegEntryOffset) - bootx_add_display_props(base, mem_end); - - /* do all our children */ - cpp = &np->child; - while(*cpp) { - np = (struct bootx_dt_node *)(base + *cpp); - bootx_scan_dt_build_struct(base, *cpp, mem_end); - cpp = &np->sibling; - } - - dt_push_token(OF_DT_END_NODE, mem_end); -} - -static unsigned long __init bootx_flatten_dt(unsigned long start) -{ - boot_infos_t *bi = bootx_info; - unsigned long mem_start, mem_end; - struct boot_param_header *hdr; - unsigned long base; - u64 *rsvmap; - - /* Start using memory after the big blob passed by BootX, get - * some space for the header - */ - mem_start = mem_end = _ALIGN_UP(((unsigned long)bi) + start, 4); - DBG("Boot params header at: %x\n", mem_start); - hdr = (struct boot_param_header *)mem_start; - mem_end += sizeof(struct boot_param_header); - rsvmap = (u64 *)(_ALIGN_UP(mem_end, 8)); - hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - mem_start; - mem_end = ((unsigned long)rsvmap) + 8 * sizeof(u64); - - /* Get base of tree */ - base = ((unsigned long)bi) + bi->deviceTreeOffset; - - /* Build string array */ - DBG("Building string array at: %x\n", mem_end); - DBG("Device Tree Base=%x\n", base); - bootx_dt_strbase = mem_end; - mem_end += 4; - bootx_dt_strend = mem_end; - bootx_scan_dt_build_strings(base, 4, &mem_end); - hdr->off_dt_strings = bootx_dt_strbase - mem_start; - hdr->dt_strings_size = bootx_dt_strend - bootx_dt_strbase; - - /* Build structure */ - mem_end = _ALIGN(mem_end, 16); - DBG("Building device tree structure at: %x\n", mem_end); - hdr->off_dt_struct = mem_end - mem_start; - bootx_scan_dt_build_struct(base, 4, &mem_end); - dt_push_token(OF_DT_END, &mem_end); - - /* Finish header */ - hdr->boot_cpuid_phys = 0; - hdr->magic = OF_DT_HEADER; - hdr->totalsize = mem_end - mem_start; - hdr->version = OF_DT_VERSION; - /* Version 16 is not backward compatible */ - hdr->last_comp_version = 0x10; - - /* Reserve the whole thing and copy the reserve map in, we - * also bump mem_reserve_cnt to cause further reservations to - * fail since it's too late. - */ - mem_end = _ALIGN(mem_end, PAGE_SIZE); - DBG("End of boot params: %x\n", mem_end); - rsvmap[0] = mem_start; - rsvmap[1] = mem_end; - rsvmap[2] = 0; - rsvmap[3] = 0; - - return (unsigned long)hdr; -} - - -#ifdef CONFIG_BOOTX_TEXT -static void __init btext_welcome(boot_infos_t *bi) -{ - unsigned long flags; - unsigned long pvr; - - bootx_printf("Welcome to Linux, kernel " UTS_RELEASE "\n"); - bootx_printf("\nlinked at : 0x%x", KERNELBASE); - bootx_printf("\nframe buffer at : 0x%x", bi->dispDeviceBase); - bootx_printf(" (phys), 0x%x", bi->logicalDisplayBase); - bootx_printf(" (log)"); - bootx_printf("\nklimit : 0x%x",(unsigned long)klimit); - bootx_printf("\nboot_info at : 0x%x", bi); - __asm__ __volatile__ ("mfmsr %0" : "=r" (flags)); - bootx_printf("\nMSR : 0x%x", flags); - __asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr)); - bootx_printf("\nPVR : 0x%x", pvr); - pvr >>= 16; - if (pvr > 1) { - __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags)); - bootx_printf("\nHID0 : 0x%x", flags); - } - if (pvr == 8 || pvr == 12 || pvr == 0x800c) { - __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags)); - bootx_printf("\nICTC : 0x%x", flags); - } -#ifdef DEBUG - bootx_printf("\n\n"); - bootx_printf("bi->deviceTreeOffset : 0x%x\n", - bi->deviceTreeOffset); - bootx_printf("bi->deviceTreeSize : 0x%x\n", - bi->deviceTreeSize); -#endif - bootx_printf("\n\n"); -} -#endif /* CONFIG_BOOTX_TEXT */ - -void __init bootx_init(unsigned long r3, unsigned long r4) -{ - boot_infos_t *bi = (boot_infos_t *) r4; - unsigned long hdr; - unsigned long space; - unsigned long ptr, x; - char *model; - unsigned long offset = reloc_offset(); - - reloc_got2(offset); - - bootx_info = bi; - - /* We haven't cleared any bss at this point, make sure - * what we need is initialized - */ - bootx_dt_strbase = bootx_dt_strend = 0; - bootx_node_chosen = 0; - bootx_disp_path[0] = 0; - - if (!BOOT_INFO_IS_V2_COMPATIBLE(bi)) - bi->logicalDisplayBase = bi->dispDeviceBase; - -#ifdef CONFIG_BOOTX_TEXT - btext_setup_display(bi->dispDeviceRect[2] - bi->dispDeviceRect[0], - bi->dispDeviceRect[3] - bi->dispDeviceRect[1], - bi->dispDeviceDepth, bi->dispDeviceRowBytes, - (unsigned long)bi->logicalDisplayBase); - btext_clearscreen(); - btext_flushscreen(); -#endif /* CONFIG_BOOTX_TEXT */ - - /* - * Test if boot-info is compatible. Done only in config - * CONFIG_BOOTX_TEXT since there is nothing much we can do - * with an incompatible version, except display a message - * and eventually hang the processor... - * - * I'll try to keep enough of boot-info compatible in the - * future to always allow display of this message; - */ - if (!BOOT_INFO_IS_COMPATIBLE(bi)) { - bootx_printf(" !!! WARNING - Incompatible version" - " of BootX !!!\n\n\n"); - for (;;) - ; - } - if (bi->architecture != BOOT_ARCH_PCI) { - bootx_printf(" !!! WARNING - Usupported machine" - " architecture !\n"); - for (;;) - ; - } - -#ifdef CONFIG_BOOTX_TEXT - btext_welcome(bi); -#endif - /* New BootX enters kernel with MMU off, i/os are not allowed - * here. This hack will have been done by the boostrap anyway. - */ - if (bi->version < 4) { - /* - * XXX If this is an iMac, turn off the USB controller. - */ - model = (char *) bootx_early_getprop(r4 + bi->deviceTreeOffset, - 4, "model"); - if (model - && (strcmp(model, "iMac,1") == 0 - || strcmp(model, "PowerMac1,1") == 0)) { - bootx_printf("iMac,1 detected, shutting down USB \n"); - out_le32((unsigned *)0x80880008, 1); /* XXX */ - } - } - - /* Get a pointer that points above the device tree, args, ramdisk, - * etc... to use for generating the flattened tree - */ - if (bi->version < 5) { - space = bi->deviceTreeOffset + bi->deviceTreeSize; - if (bi->ramDisk) - space = bi->ramDisk + bi->ramDiskSize; - } else - space = bi->totalParamsSize; - - bootx_printf("Total space used by parameters & ramdisk: %x \n", space); - - /* New BootX will have flushed all TLBs and enters kernel with - * MMU switched OFF, so this should not be useful anymore. - */ - if (bi->version < 4) { - bootx_printf("Touching pages...\n"); - - /* - * Touch each page to make sure the PTEs for them - * are in the hash table - the aim is to try to avoid - * getting DSI exceptions while copying the kernel image. - */ - for (ptr = ((unsigned long) &_stext) & PAGE_MASK; - ptr < (unsigned long)bi + space; ptr += PAGE_SIZE) - x = *(volatile unsigned long *)ptr; - } - - /* Ok, now we need to generate a flattened device-tree to pass - * to the kernel - */ - bootx_printf("Preparing boot params...\n"); - - hdr = bootx_flatten_dt(space); - -#ifdef CONFIG_BOOTX_TEXT -#ifdef SET_BOOT_BAT - bootx_printf("Preparing BAT...\n"); - btext_prepare_BAT(); -#else - btext_unmap(); -#endif -#endif - - reloc_got2(-offset); - - __start(hdr, KERNELBASE + offset, 0); -} diff --git a/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c b/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c index a4b50c4109c2..39150342c6f1 100644 --- a/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c +++ b/trunk/arch/powerpc/platforms/powermac/cpufreq_64.c @@ -28,7 +28,6 @@ #include #include #include -#include #undef DEBUG @@ -86,10 +85,6 @@ static u32 *g5_pmode_data; static int g5_pmode_max; static int g5_pmode_cur; -static void (*g5_switch_volt)(int speed_mode); -static int (*g5_switch_freq)(int speed_mode); -static int (*g5_query_freq)(void); - static DECLARE_MUTEX(g5_switch_mutex); @@ -97,11 +92,9 @@ static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */ static int g5_fvt_count; /* number of op. points */ static int g5_fvt_cur; /* current op. point */ -/* - * SMU based voltage switching for Neo2 platforms - */ +/* ----------------- real hardware interface */ -static void g5_smu_switch_volt(int speed_mode) +static void g5_switch_volt(int speed_mode) { struct smu_simple_cmd cmd; @@ -112,57 +105,26 @@ static void g5_smu_switch_volt(int speed_mode) wait_for_completion(&comp); } -/* - * Platform function based voltage/vdnap switching for Neo2 - */ - -static struct pmf_function *pfunc_set_vdnap0; -static struct pmf_function *pfunc_vdnap0_complete; - -static void g5_vdnap_switch_volt(int speed_mode) +static int g5_switch_freq(int speed_mode) { - struct pmf_args args; - u32 slew, done = 0; - unsigned long timeout; - - slew = (speed_mode == CPUFREQ_LOW) ? 1 : 0; - args.count = 1; - args.u[0].p = &slew; + struct cpufreq_freqs freqs; + int to; - pmf_call_one(pfunc_set_vdnap0, &args); + if (g5_pmode_cur == speed_mode) + return 0; - /* It's an irq GPIO so we should be able to just block here, - * I'll do that later after I've properly tested the IRQ code for - * platform functions - */ - timeout = jiffies + HZ/10; - while(!time_after(jiffies, timeout)) { - args.count = 1; - args.u[0].p = &done; - pmf_call_one(pfunc_vdnap0_complete, &args); - if (done) - break; - msleep(1); - } - if (done == 0) - printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n"); -} + down(&g5_switch_mutex); + freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency; + freqs.new = g5_cpu_freqs[speed_mode].frequency; + freqs.cpu = 0; -/* - * SCOM based frequency switching for 970FX rev3 - */ -static int g5_scom_switch_freq(int speed_mode) -{ - unsigned long flags; - int to; + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); /* If frequency is going up, first ramp up the voltage */ if (speed_mode < g5_pmode_cur) g5_switch_volt(speed_mode); - local_irq_save(flags); - /* Clear PCR high */ scom970_write(SCOM_PCR, 0); /* Clear PCR low */ @@ -185,8 +147,6 @@ static int g5_scom_switch_freq(int speed_mode) udelay(100); } - local_irq_restore(flags); - /* If frequency is going down, last ramp the voltage */ if (speed_mode > g5_pmode_cur) g5_switch_volt(speed_mode); @@ -194,10 +154,14 @@ static int g5_scom_switch_freq(int speed_mode) g5_pmode_cur = speed_mode; ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul; + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + up(&g5_switch_mutex); + return 0; } -static int g5_scom_query_freq(void) +static int g5_query_freq(void) { unsigned long psr = scom970_read(SCOM_PSR); int i; @@ -209,104 +173,7 @@ static int g5_scom_query_freq(void) return i; } -/* - * Platform function based voltage switching for PowerMac7,2 & 7,3 - */ - -static struct pmf_function *pfunc_cpu0_volt_high; -static struct pmf_function *pfunc_cpu0_volt_low; -static struct pmf_function *pfunc_cpu1_volt_high; -static struct pmf_function *pfunc_cpu1_volt_low; - -static void g5_pfunc_switch_volt(int speed_mode) -{ - if (speed_mode == CPUFREQ_HIGH) { - if (pfunc_cpu0_volt_high) - pmf_call_one(pfunc_cpu0_volt_high, NULL); - if (pfunc_cpu1_volt_high) - pmf_call_one(pfunc_cpu1_volt_high, NULL); - } else { - if (pfunc_cpu0_volt_low) - pmf_call_one(pfunc_cpu0_volt_low, NULL); - if (pfunc_cpu1_volt_low) - pmf_call_one(pfunc_cpu1_volt_low, NULL); - } - msleep(10); /* should be faster , to fix */ -} - -/* - * Platform function based frequency switching for PowerMac7,2 & 7,3 - */ - -static struct pmf_function *pfunc_cpu_setfreq_high; -static struct pmf_function *pfunc_cpu_setfreq_low; -static struct pmf_function *pfunc_cpu_getfreq; -static struct pmf_function *pfunc_slewing_done;; - -static int g5_pfunc_switch_freq(int speed_mode) -{ - struct pmf_args args; - u32 done = 0; - unsigned long timeout; - - /* If frequency is going up, first ramp up the voltage */ - if (speed_mode < g5_pmode_cur) - g5_switch_volt(speed_mode); - - /* Do it */ - if (speed_mode == CPUFREQ_HIGH) - pmf_call_one(pfunc_cpu_setfreq_high, NULL); - else - pmf_call_one(pfunc_cpu_setfreq_low, NULL); - - /* It's an irq GPIO so we should be able to just block here, - * I'll do that later after I've properly tested the IRQ code for - * platform functions - */ - timeout = jiffies + HZ/10; - while(!time_after(jiffies, timeout)) { - args.count = 1; - args.u[0].p = &done; - pmf_call_one(pfunc_slewing_done, &args); - if (done) - break; - msleep(1); - } - if (done == 0) - printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n"); - - /* If frequency is going down, last ramp the voltage */ - if (speed_mode > g5_pmode_cur) - g5_switch_volt(speed_mode); - - g5_pmode_cur = speed_mode; - ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul; - - return 0; -} - -static int g5_pfunc_query_freq(void) -{ - struct pmf_args args; - u32 val = 0; - - args.count = 1; - args.u[0].p = &val; - pmf_call_one(pfunc_cpu_getfreq, &args); - return val ? CPUFREQ_HIGH : CPUFREQ_LOW; -} - -/* - * Fake voltage switching for platforms with missing support - */ - -static void g5_dummy_switch_volt(int speed_mode) -{ -} - -/* - * Common interface to the cpufreq core - */ +/* ----------------- cpufreq bookkeeping */ static int g5_cpufreq_verify(struct cpufreq_policy *policy) { @@ -316,30 +183,13 @@ static int g5_cpufreq_verify(struct cpufreq_policy *policy) static int g5_cpufreq_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { - unsigned int newstate = 0; - struct cpufreq_freqs freqs; - int rc; + unsigned int newstate = 0; if (cpufreq_frequency_table_target(policy, g5_cpu_freqs, target_freq, relation, &newstate)) return -EINVAL; - if (g5_pmode_cur == newstate) - return 0; - - down(&g5_switch_mutex); - - freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency; - freqs.new = g5_cpu_freqs[newstate].frequency; - freqs.cpu = 0; - - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - rc = g5_switch_freq(newstate); - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - up(&g5_switch_mutex); - - return rc; + return g5_switch_freq(newstate); } static unsigned int g5_cpufreq_get_speed(unsigned int cpu) @@ -355,7 +205,6 @@ static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->governor = CPUFREQ_DEFAULT_GOVERNOR; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cur = g5_cpu_freqs[g5_query_freq()].frequency; - policy->cpus = cpu_possible_map; cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu); return cpufreq_frequency_table_cpuinfo(policy, @@ -375,39 +224,19 @@ static struct cpufreq_driver g5_cpufreq_driver = { }; -static int __init g5_neo2_cpufreq_init(struct device_node *cpus) +static int __init g5_cpufreq_init(void) { struct device_node *cpunode; unsigned int psize, ssize; + struct smu_sdbp_header *shdr; unsigned long max_freq; - char *freq_method, *volt_method; - u32 *valp, pvr_hi; - int use_volts_vdnap = 0; - int use_volts_smu = 0; + u32 *valp; int rc = -ENODEV; - /* Check supported platforms */ - if (machine_is_compatible("PowerMac8,1") || - machine_is_compatible("PowerMac8,2") || - machine_is_compatible("PowerMac9,1")) - use_volts_smu = 1; - else if (machine_is_compatible("PowerMac11,2")) - use_volts_vdnap = 1; - else - return -ENODEV; - - /* Get first CPU node */ - for (cpunode = NULL; - (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { - u32 *reg = - (u32 *)get_property(cpunode, "reg", NULL); - if (reg == NULL || (*reg) != 0) - continue; - if (!strcmp(cpunode->type, "cpu")) - break; - } - if (cpunode == NULL) { - printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n"); + /* Look for CPU and SMU nodes */ + cpunode = of_find_node_by_type(NULL, "cpu"); + if (!cpunode) { + DBG("No CPU node !\n"); return -ENODEV; } @@ -417,9 +246,8 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) DBG("No cpu-version property !\n"); goto bail_noprops; } - pvr_hi = (*valp) >> 16; - if (pvr_hi != 0x3c && pvr_hi != 0x44) { - printk(KERN_ERR "cpufreq: Unsupported CPU version\n"); + if (((*valp) >> 16) != 0x3c) { + DBG("Wrong CPU version: %08x\n", *valp); goto bail_noprops; } @@ -431,50 +259,18 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) } g5_pmode_max = psize / sizeof(u32) - 1; - if (use_volts_smu) { - struct smu_sdbp_header *shdr; - - /* Look for the FVT table */ - shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL); - if (!shdr) - goto bail_noprops; - g5_fvt_table = (struct smu_sdbp_fvt *)&shdr[1]; - ssize = (shdr->len * sizeof(u32)) - - sizeof(struct smu_sdbp_header); - g5_fvt_count = ssize / sizeof(struct smu_sdbp_fvt); - g5_fvt_cur = 0; - - /* Sanity checking */ - if (g5_fvt_count < 1 || g5_pmode_max < 1) - goto bail_noprops; - - g5_switch_volt = g5_smu_switch_volt; - volt_method = "SMU"; - } else if (use_volts_vdnap) { - struct device_node *root; - - root = of_find_node_by_path("/"); - if (root == NULL) { - printk(KERN_ERR "cpufreq: Can't find root of " - "device tree\n"); - goto bail_noprops; - } - pfunc_set_vdnap0 = pmf_find_function(root, "set-vdnap0"); - pfunc_vdnap0_complete = - pmf_find_function(root, "slewing-done"); - if (pfunc_set_vdnap0 == NULL || - pfunc_vdnap0_complete == NULL) { - printk(KERN_ERR "cpufreq: Can't find required " - "platform function\n"); - goto bail_noprops; - } - - g5_switch_volt = g5_vdnap_switch_volt; - volt_method = "GPIO"; - } else { - g5_switch_volt = g5_dummy_switch_volt; - volt_method = "none"; - } + /* Look for the FVT table */ + shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL); + if (!shdr) + goto bail_noprops; + g5_fvt_table = (struct smu_sdbp_fvt *)&shdr[1]; + ssize = (shdr->len * sizeof(u32)) - sizeof(struct smu_sdbp_header); + g5_fvt_count = ssize / sizeof(struct smu_sdbp_fvt); + g5_fvt_cur = 0; + + /* Sanity checking */ + if (g5_fvt_count < 1 || g5_pmode_max < 1) + goto bail_noprops; /* * From what I see, clock-frequency is always the maximal frequency. @@ -490,23 +286,19 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) g5_cpu_freqs[0].frequency = max_freq; g5_cpu_freqs[1].frequency = max_freq/2; - /* Set callbacks */ - g5_switch_freq = g5_scom_switch_freq; - g5_query_freq = g5_scom_query_freq; - freq_method = "SCOM"; + /* Check current frequency */ + g5_pmode_cur = g5_query_freq(); + if (g5_pmode_cur > 1) + /* We don't support anything but 1:1 and 1:2, fixup ... */ + g5_pmode_cur = 1; /* Force apply current frequency to make sure everything is in * sync (voltage is right for example). Firmware may leave us with * a strange setting ... */ - g5_switch_volt(CPUFREQ_HIGH); - msleep(10); - g5_pmode_cur = -1; - g5_switch_freq(g5_query_freq()); + g5_switch_freq(g5_pmode_cur); printk(KERN_INFO "Registering G5 CPU frequency driver\n"); - printk(KERN_INFO "Frequency method: %s, Voltage method: %s\n", - freq_method, volt_method); printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n", g5_cpu_freqs[1].frequency/1000, g5_cpu_freqs[0].frequency/1000, @@ -525,200 +317,6 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) return rc; } -static int __init g5_pm72_cpufreq_init(struct device_node *cpus) -{ - struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL; - u8 *eeprom = NULL; - u32 *valp; - u64 max_freq, min_freq, ih, il; - int has_volt = 1, rc = 0; - - /* Get first CPU node */ - for (cpunode = NULL; - (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) { - if (!strcmp(cpunode->type, "cpu")) - break; - } - if (cpunode == NULL) { - printk(KERN_ERR "cpufreq: Can't find any CPU node\n"); - return -ENODEV; - } - - /* Lookup the cpuid eeprom node */ - cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0"); - if (cpuid != NULL) - eeprom = (u8 *)get_property(cpuid, "cpuid", NULL); - if (eeprom == NULL) { - printk(KERN_ERR "cpufreq: Can't find cpuid EEPROM !\n"); - rc = -ENODEV; - goto bail; - } - - /* Lookup the i2c hwclock */ - for (hwclock = NULL; - (hwclock = of_find_node_by_name(hwclock, "i2c-hwclock")) != NULL;){ - char *loc = get_property(hwclock, "hwctrl-location", NULL); - if (loc == NULL) - continue; - if (strcmp(loc, "CPU CLOCK")) - continue; - if (!get_property(hwclock, "platform-get-frequency", NULL)) - continue; - break; - } - if (hwclock == NULL) { - printk(KERN_ERR "cpufreq: Can't find i2c clock chip !\n"); - rc = -ENODEV; - goto bail; - } - - DBG("cpufreq: i2c clock chip found: %s\n", hwclock->full_name); - - /* Now get all the platform functions */ - pfunc_cpu_getfreq = - pmf_find_function(hwclock, "get-frequency"); - pfunc_cpu_setfreq_high = - pmf_find_function(hwclock, "set-frequency-high"); - pfunc_cpu_setfreq_low = - pmf_find_function(hwclock, "set-frequency-low"); - pfunc_slewing_done = - pmf_find_function(hwclock, "slewing-done"); - pfunc_cpu0_volt_high = - pmf_find_function(hwclock, "set-voltage-high-0"); - pfunc_cpu0_volt_low = - pmf_find_function(hwclock, "set-voltage-low-0"); - pfunc_cpu1_volt_high = - pmf_find_function(hwclock, "set-voltage-high-1"); - pfunc_cpu1_volt_low = - pmf_find_function(hwclock, "set-voltage-low-1"); - - /* Check we have minimum requirements */ - if (pfunc_cpu_getfreq == NULL || pfunc_cpu_setfreq_high == NULL || - pfunc_cpu_setfreq_low == NULL || pfunc_slewing_done == NULL) { - printk(KERN_ERR "cpufreq: Can't find platform functions !\n"); - rc = -ENODEV; - goto bail; - } - - /* Check that we have complete sets */ - if (pfunc_cpu0_volt_high == NULL || pfunc_cpu0_volt_low == NULL) { - pmf_put_function(pfunc_cpu0_volt_high); - pmf_put_function(pfunc_cpu0_volt_low); - pfunc_cpu0_volt_high = pfunc_cpu0_volt_low = NULL; - has_volt = 0; - } - if (!has_volt || - pfunc_cpu1_volt_high == NULL || pfunc_cpu1_volt_low == NULL) { - pmf_put_function(pfunc_cpu1_volt_high); - pmf_put_function(pfunc_cpu1_volt_low); - pfunc_cpu1_volt_high = pfunc_cpu1_volt_low = NULL; - } - - /* Note: The device tree also contains a "platform-set-values" - * function for which I haven't quite figured out the usage. It - * might have to be called on init and/or wakeup, I'm not too sure - * but things seem to work fine without it so far ... - */ - - /* Get max frequency from device-tree */ - valp = (u32 *)get_property(cpunode, "clock-frequency", NULL); - if (!valp) { - printk(KERN_ERR "cpufreq: Can't find CPU frequency !\n"); - rc = -ENODEV; - goto bail; - } - - max_freq = (*valp)/1000; - - /* Now calculate reduced frequency by using the cpuid input freq - * ratio. This requires 64 bits math unless we are willing to lose - * some precision - */ - ih = *((u32 *)(eeprom + 0x10)); - il = *((u32 *)(eeprom + 0x20)); - min_freq = 0; - if (ih != 0 && il != 0) - min_freq = (max_freq * il) / ih; - - /* Sanity check */ - if (min_freq >= max_freq || min_freq < 1000) { - printk(KERN_ERR "cpufreq: Can't calculate low frequency !\n"); - rc = -ENODEV; - goto bail; - } - g5_cpu_freqs[0].frequency = max_freq; - g5_cpu_freqs[1].frequency = min_freq; - - /* Set callbacks */ - g5_switch_volt = g5_pfunc_switch_volt; - g5_switch_freq = g5_pfunc_switch_freq; - g5_query_freq = g5_pfunc_query_freq; - - /* Force apply current frequency to make sure everything is in - * sync (voltage is right for example). Firmware may leave us with - * a strange setting ... - */ - g5_switch_volt(CPUFREQ_HIGH); - msleep(10); - g5_pmode_cur = -1; - g5_switch_freq(g5_query_freq()); - - printk(KERN_INFO "Registering G5 CPU frequency driver\n"); - printk(KERN_INFO "Frequency method: i2c/pfunc, " - "Voltage method: %s\n", has_volt ? "i2c/pfunc" : "none"); - printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n", - g5_cpu_freqs[1].frequency/1000, - g5_cpu_freqs[0].frequency/1000, - g5_cpu_freqs[g5_pmode_cur].frequency/1000); - - rc = cpufreq_register_driver(&g5_cpufreq_driver); - bail: - if (rc != 0) { - pmf_put_function(pfunc_cpu_getfreq); - pmf_put_function(pfunc_cpu_setfreq_high); - pmf_put_function(pfunc_cpu_setfreq_low); - pmf_put_function(pfunc_slewing_done); - pmf_put_function(pfunc_cpu0_volt_high); - pmf_put_function(pfunc_cpu0_volt_low); - pmf_put_function(pfunc_cpu1_volt_high); - pmf_put_function(pfunc_cpu1_volt_low); - } - of_node_put(hwclock); - of_node_put(cpuid); - of_node_put(cpunode); - - return rc; -} - -static int __init g5_rm31_cpufreq_init(struct device_node *cpus) -{ - /* NYI */ - return 0; -} - -static int __init g5_cpufreq_init(void) -{ - struct device_node *cpus; - int rc; - - cpus = of_find_node_by_path("/cpus"); - if (cpus == NULL) { - DBG("No /cpus node !\n"); - return -ENODEV; - } - - if (machine_is_compatible("PowerMac7,2") || - machine_is_compatible("PowerMac7,3")) - rc = g5_pm72_cpufreq_init(cpus); - else if (machine_is_compatible("RackMac3,1")) - rc = g5_rm31_cpufreq_init(cpus); - else - rc = g5_neo2_cpufreq_init(cpus); - - of_node_put(cpus); - return rc; -} - module_init(g5_cpufreq_init); diff --git a/trunk/arch/powerpc/platforms/powermac/feature.c b/trunk/arch/powerpc/platforms/powermac/feature.c index 558dd0692092..f6e22da2a5da 100644 --- a/trunk/arch/powerpc/platforms/powermac/feature.c +++ b/trunk/arch/powerpc/platforms/powermac/feature.c @@ -58,11 +58,12 @@ extern int powersave_lowspeed; extern int powersave_nap; extern struct device_node *k2_skiplist[2]; + /* * We use a single global lock to protect accesses. Each driver has * to take care of its own locking */ -DEFINE_SPINLOCK(feature_lock); +static DEFINE_SPINLOCK(feature_lock); #define LOCK(flags) spin_lock_irqsave(&feature_lock, flags); #define UNLOCK(flags) spin_unlock_irqrestore(&feature_lock, flags); @@ -100,17 +101,26 @@ static const char *macio_names[] = "Keylargo", "Pangea", "Intrepid", - "K2", - "Shasta", + "K2" }; -struct device_node *uninorth_node; -u32 __iomem *uninorth_base; +/* + * Uninorth reg. access. Note that Uni-N regs are big endian + */ + +#define UN_REG(r) (uninorth_base + ((r) >> 2)) +#define UN_IN(r) (in_be32(UN_REG(r))) +#define UN_OUT(r,v) (out_be32(UN_REG(r), (v))) +#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v))) +#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v))) + +static struct device_node *uninorth_node; +static u32 __iomem *uninorth_base; static u32 uninorth_rev; -static int uninorth_maj; -static void __iomem *u3_ht_base; +static int uninorth_u3; +static void __iomem *u3_ht; /* * For each motherboard family, we have a table of functions pointers @@ -1389,15 +1399,8 @@ static long g5_fw_enable(struct device_node *node, long param, long value) static long g5_mpic_enable(struct device_node *node, long param, long value) { unsigned long flags; - struct device_node *parent = of_get_parent(node); - int is_u3; - if (parent == NULL) - return 0; - is_u3 = strcmp(parent->name, "u3") == 0 || - strcmp(parent->name, "u4") == 0; - of_node_put(parent); - if (!is_u3) + if (node->parent == NULL || strcmp(node->parent->name, "u3")) return 0; LOCK(flags); @@ -1442,53 +1445,20 @@ static long g5_i2s_enable(struct device_node *node, long param, long value) /* Very crude implementation for now */ struct macio_chip *macio = &macio_chips[0]; unsigned long flags; - int cell; - u32 fcrs[3][3] = { - { 0, - K2_FCR1_I2S0_CELL_ENABLE | - K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE, - KL3_I2S0_CLK18_ENABLE - }, - { KL0_SCC_A_INTF_ENABLE, - K2_FCR1_I2S1_CELL_ENABLE | - K2_FCR1_I2S1_CLK_ENABLE_BIT | K2_FCR1_I2S1_ENABLE, - KL3_I2S1_CLK18_ENABLE - }, - { KL0_SCC_B_INTF_ENABLE, - SH_FCR1_I2S2_CELL_ENABLE | - SH_FCR1_I2S2_CLK_ENABLE_BIT | SH_FCR1_I2S2_ENABLE, - SH_FCR3_I2S2_CLK18_ENABLE - }, - }; - - if (macio->type != macio_keylargo2 && macio->type != macio_shasta) - return -ENODEV; - if (strncmp(node->name, "i2s-", 4)) - return -ENODEV; - cell = node->name[4] - 'a'; - switch(cell) { - case 0: - case 1: - break; - case 2: - if (macio->type == macio_shasta) - break; - default: - return -ENODEV; - } + + if (value == 0) + return 0; /* don't disable yet */ LOCK(flags); - if (value) { - MACIO_BIC(KEYLARGO_FCR0, fcrs[cell][0]); - MACIO_BIS(KEYLARGO_FCR1, fcrs[cell][1]); - MACIO_BIS(KEYLARGO_FCR3, fcrs[cell][2]); - } else { - MACIO_BIC(KEYLARGO_FCR3, fcrs[cell][2]); - MACIO_BIC(KEYLARGO_FCR1, fcrs[cell][1]); - MACIO_BIS(KEYLARGO_FCR0, fcrs[cell][0]); - } + MACIO_BIS(KEYLARGO_FCR3, KL3_CLK45_ENABLE | KL3_CLK49_ENABLE | + KL3_I2S0_CLK18_ENABLE); + udelay(10); + MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_I2S0_CELL_ENABLE | + K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE); udelay(10); + MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_I2S0_RESET); UNLOCK(flags); + udelay(10); return 0; } @@ -1503,7 +1473,7 @@ static long g5_reset_cpu(struct device_node *node, long param, long value) struct device_node *np; macio = &macio_chips[0]; - if (macio->type != macio_keylargo2 && macio->type != macio_shasta) + if (macio->type != macio_keylargo2) return -ENODEV; np = find_path_device("/cpus"); @@ -1542,17 +1512,14 @@ static long g5_reset_cpu(struct device_node *node, long param, long value) */ void g5_phy_disable_cpu1(void) { - if (uninorth_maj == 3) - UN_OUT(U3_API_PHY_CONFIG_1, 0); + UN_OUT(U3_API_PHY_CONFIG_1, 0); } #endif /* CONFIG_POWER4 */ #ifndef CONFIG_POWER4 - -#ifdef CONFIG_PM - -static void keylargo_shutdown(struct macio_chip *macio, int sleep_mode) +static void +keylargo_shutdown(struct macio_chip *macio, int sleep_mode) { u32 temp; @@ -1605,7 +1572,8 @@ static void keylargo_shutdown(struct macio_chip *macio, int sleep_mode) (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); } -static void pangea_shutdown(struct macio_chip *macio, int sleep_mode) +static void +pangea_shutdown(struct macio_chip *macio, int sleep_mode) { u32 temp; @@ -1638,7 +1606,8 @@ static void pangea_shutdown(struct macio_chip *macio, int sleep_mode) (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1); } -static void intrepid_shutdown(struct macio_chip *macio, int sleep_mode) +static void +intrepid_shutdown(struct macio_chip *macio, int sleep_mode) { u32 temp; @@ -1666,6 +1635,124 @@ static void intrepid_shutdown(struct macio_chip *macio, int sleep_mode) } +void pmac_tweak_clock_spreading(int enable) +{ + struct macio_chip *macio = &macio_chips[0]; + + /* Hack for doing clock spreading on some machines PowerBooks and + * iBooks. This implements the "platform-do-clockspreading" OF + * property as decoded manually on various models. For safety, we also + * check the product ID in the device-tree in cases we'll whack the i2c + * chip to make reasonably sure we won't set wrong values in there + * + * Of course, ultimately, we have to implement a real parser for + * the platform-do-* stuff... + */ + + if (macio->type == macio_intrepid) { + struct device_node *clock = + of_find_node_by_path("/uni-n@f8000000/hw-clock"); + if (clock && get_property(clock, "platform-do-clockspreading", + NULL)) { + printk(KERN_INFO "%sabling clock spreading on Intrepid" + " ASIC\n", enable ? "En" : "Dis"); + if (enable) + UN_OUT(UNI_N_CLOCK_SPREADING, 2); + else + UN_OUT(UNI_N_CLOCK_SPREADING, 0); + mdelay(40); + } + of_node_put(clock); + } + + while (machine_is_compatible("PowerBook5,2") || + machine_is_compatible("PowerBook5,3") || + machine_is_compatible("PowerBook6,2") || + machine_is_compatible("PowerBook6,3")) { + struct device_node *ui2c = of_find_node_by_type(NULL, "i2c"); + struct device_node *dt = of_find_node_by_name(NULL, "device-tree"); + u8 buffer[9]; + u32 *productID; + int i, rc, changed = 0; + + if (dt == NULL) + break; + productID = (u32 *)get_property(dt, "pid#", NULL); + if (productID == NULL) + break; + while(ui2c) { + struct device_node *p = of_get_parent(ui2c); + if (p && !strcmp(p->name, "uni-n")) + break; + ui2c = of_find_node_by_type(ui2c, "i2c"); + } + if (ui2c == NULL) + break; + DBG("Trying to bump clock speed for PID: %08x...\n", *productID); + rc = pmac_low_i2c_open(ui2c, 1); + if (rc != 0) + break; + pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined); + rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9); + DBG("read result: %d,", rc); + if (rc != 0) { + pmac_low_i2c_close(ui2c); + break; + } + for (i=0; i<9; i++) + DBG(" %02x", buffer[i]); + DBG("\n"); + + switch(*productID) { + case 0x1182: /* AlBook 12" rev 2 */ + case 0x1183: /* iBook G4 12" */ + buffer[0] = (buffer[0] & 0x8f) | 0x70; + buffer[2] = (buffer[2] & 0x7f) | 0x00; + buffer[5] = (buffer[5] & 0x80) | 0x31; + buffer[6] = (buffer[6] & 0x40) | 0xb0; + buffer[7] = (buffer[7] & 0x00) | (enable ? 0xc0 : 0xba); + buffer[8] = (buffer[8] & 0x00) | 0x30; + changed = 1; + break; + case 0x3142: /* AlBook 15" (ATI M10) */ + case 0x3143: /* AlBook 17" (ATI M10) */ + buffer[0] = (buffer[0] & 0xaf) | 0x50; + buffer[2] = (buffer[2] & 0x7f) | 0x00; + buffer[5] = (buffer[5] & 0x80) | 0x31; + buffer[6] = (buffer[6] & 0x40) | 0xb0; + buffer[7] = (buffer[7] & 0x00) | (enable ? 0xd0 : 0xc0); + buffer[8] = (buffer[8] & 0x00) | 0x30; + changed = 1; + break; + default: + DBG("i2c-hwclock: Machine model not handled\n"); + break; + } + if (!changed) { + pmac_low_i2c_close(ui2c); + break; + } + printk(KERN_INFO "%sabling clock spreading on i2c clock chip\n", + enable ? "En" : "Dis"); + + pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_stdsub); + rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_write, 0x80, buffer, 9); + DBG("write result: %d,", rc); + pmac_low_i2c_setmode(ui2c, pmac_low_i2c_mode_combined); + rc = pmac_low_i2c_xfer(ui2c, 0xd2 | pmac_low_i2c_read, 0x80, buffer, 9); + DBG("read result: %d,", rc); + if (rc != 0) { + pmac_low_i2c_close(ui2c); + break; + } + for (i=0; i<9; i++) + DBG(" %02x", buffer[i]); + pmac_low_i2c_close(ui2c); + break; + } +} + + static int core99_sleep(void) { @@ -1822,8 +1909,6 @@ core99_wake_up(void) return 0; } -#endif /* CONFIG_PM */ - static long core99_sleep_state(struct device_node *node, long param, long value) { @@ -1845,13 +1930,10 @@ core99_sleep_state(struct device_node *node, long param, long value) if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0) return -EPERM; -#ifdef CONFIG_PM if (value == 1) return core99_sleep(); else if (value == 0) return core99_wake_up(); - -#endif /* CONFIG_PM */ return 0; } @@ -1975,9 +2057,7 @@ static struct feature_table_entry core99_features[] = { { PMAC_FTR_USB_ENABLE, core99_usb_enable }, { PMAC_FTR_1394_ENABLE, core99_firewire_enable }, { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power }, -#ifdef CONFIG_PM { PMAC_FTR_SLEEP_STATE, core99_sleep_state }, -#endif #ifdef CONFIG_SMP { PMAC_FTR_RESET_CPU, core99_reset_cpu }, #endif /* CONFIG_SMP */ @@ -2347,14 +2427,6 @@ static struct pmac_mb_def pmac_mb_defs[] = { PMAC_TYPE_POWERMAC_G5_U3L, g5_features, 0, }, - { "PowerMac11,2", "PowerMac G5 Dual Core", - PMAC_TYPE_POWERMAC_G5_U3L, g5_features, - 0, - }, - { "PowerMac12,1", "iMac G5 (iSight)", - PMAC_TYPE_POWERMAC_G5_U3L, g5_features, - 0, - }, { "RackMac3,1", "XServe G5", PMAC_TYPE_XSERVE_G5, g5_features, 0, @@ -2467,11 +2539,6 @@ static int __init probe_motherboard(void) pmac_mb.model_name = "Unknown K2-based"; pmac_mb.features = g5_features; break; - case macio_shasta: - pmac_mb.model_id = PMAC_TYPE_UNKNOWN_SHASTA; - pmac_mb.model_name = "Unknown Shasta-based"; - pmac_mb.features = g5_features; - break; #endif /* CONFIG_POWER4 */ default: return -ENODEV; @@ -2540,8 +2607,6 @@ static int __init probe_motherboard(void) */ static void __init probe_uninorth(void) { - u32 *addrp; - phys_addr_t address; unsigned long actrl; /* Locate core99 Uni-N */ @@ -2549,31 +2614,22 @@ static void __init probe_uninorth(void) /* Locate G5 u3 */ if (uninorth_node == NULL) { uninorth_node = of_find_node_by_name(NULL, "u3"); - uninorth_maj = 3; - } - /* Locate G5 u4 */ - if (uninorth_node == NULL) { - uninorth_node = of_find_node_by_name(NULL, "u4"); - uninorth_maj = 4; - } - if (uninorth_node == NULL) + uninorth_u3 = 1; + } + if (uninorth_node && uninorth_node->n_addrs > 0) { + unsigned long address = uninorth_node->addrs[0].address; + uninorth_base = ioremap(address, 0x40000); + uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); + if (uninorth_u3) + u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000); + } else + uninorth_node = NULL; + + if (!uninorth_node) return; - addrp = (u32 *)get_property(uninorth_node, "reg", NULL); - if (addrp == NULL) - return; - address = of_translate_address(uninorth_node, addrp); - if (address == 0) - return; - uninorth_base = ioremap(address, 0x40000); - uninorth_rev = in_be32(UN_REG(UNI_N_VERSION)); - if (uninorth_maj == 3 || uninorth_maj == 4) - u3_ht_base = ioremap(address + U3_HT_CONFIG_BASE, 0x1000); - - printk(KERN_INFO "Found %s memory controller & host bridge" - " @ 0x%08x revision: 0x%02x\n", uninorth_maj == 3 ? "U3" : - uninorth_maj == 4 ? "U4" : "UniNorth", - (unsigned int)address, uninorth_rev); + printk(KERN_INFO "Found %s memory controller & host bridge, revision: %d\n", + uninorth_u3 ? "U3" : "UniNorth", uninorth_rev); printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base); /* Set the arbitrer QAck delay according to what Apple does @@ -2581,8 +2637,7 @@ static void __init probe_uninorth(void) if (uninorth_rev < 0x11) { actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK; actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : - UNI_N_ARB_CTRL_QACK_DELAY) << - UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; + UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT; UN_OUT(UNI_N_ARB_CTRL, actrl); } @@ -2590,8 +2645,7 @@ static void __init probe_uninorth(void) * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI * memory timeout */ - if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || - uninorth_rev == 0xc0) + if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) || uninorth_rev == 0xc0) UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff); } @@ -2599,17 +2653,18 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ { struct device_node* node; int i; - volatile u32 __iomem *base; - u32 *addrp, *revp; - phys_addr_t addr; - u64 size; + volatile u32 __iomem * base; + u32* revp; - for (node = NULL; (node = of_find_node_by_name(node, name)) != NULL;) { - if (!compat) - break; - if (device_is_compatible(node, compat)) - break; - } + node = find_devices(name); + if (!node || !node->n_addrs) + return; + if (compat) + do { + if (device_is_compatible(node, compat)) + break; + node = node->next; + } while (node); if (!node) return; for(i=0; i= MAX_MACIO_CHIPS) { printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n"); printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name); return; } - addrp = of_get_pci_address(node, 0, &size, NULL); - if (addrp == NULL) { - printk(KERN_ERR "pmac_feature: %s: can't find base !\n", - node->full_name); - return; - } - addr = of_translate_address(node, addrp); - if (addr == 0) { - printk(KERN_ERR "pmac_feature: %s, can't translate base !\n", - node->full_name); - return; - } - base = ioremap(addr, (unsigned long)size); + base = ioremap(node->addrs[0].address, node->addrs[0].size); if (!base) { - printk(KERN_ERR "pmac_feature: %s, can't map mac-io chip !\n", - node->full_name); + printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n"); return; } - if (type == macio_keylargo || type == macio_keylargo2) { + if (type == macio_keylargo) { u32 *did = (u32 *)get_property(node, "device-id", NULL); if (*did == 0x00000025) type = macio_pangea; if (*did == 0x0000003e) type = macio_intrepid; - if (*did == 0x0000004f) - type = macio_shasta; } macio_chips[i].of_node = node; macio_chips[i].type = type; @@ -2748,8 +2787,7 @@ set_initial_features(void) } #ifdef CONFIG_POWER4 - if (macio_chips[0].type == macio_keylargo2 || - macio_chips[0].type == macio_shasta) { + if (macio_chips[0].type == macio_keylargo2) { #ifndef CONFIG_SMP /* On SMP machines running UP, we have the second CPU eating * bus cycles. We need to take it off the bus. This is done @@ -2858,6 +2896,12 @@ set_initial_features(void) MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N); } + /* Some machine models need the clock chip to be properly setup for + * clock spreading now. This should be a platform function but we + * don't do these at the moment + */ + pmac_tweak_clock_spreading(1); + #endif /* CONFIG_POWER4 */ /* On all machines, switch modem & serial ports off */ @@ -2885,6 +2929,9 @@ pmac_feature_init(void) return; } + /* Setup low-level i2c stuffs */ + pmac_init_low_i2c(); + /* Probe machine type */ if (probe_motherboard()) printk(KERN_WARNING "Unknown PowerMac !\n"); @@ -2895,6 +2942,26 @@ pmac_feature_init(void) set_initial_features(); } +int __init pmac_feature_late_init(void) +{ +#if 0 + struct device_node *np; + + /* Request some resources late */ + if (uninorth_node) + request_OF_resource(uninorth_node, 0, NULL); + np = find_devices("hammerhead"); + if (np) + request_OF_resource(np, 0, NULL); + np = find_devices("interrupt-controller"); + if (np) + request_OF_resource(np, 0, NULL); +#endif + return 0; +} + +device_initcall(pmac_feature_late_init); + #if 0 static void dump_HT_speeds(char *name, u32 cfg, u32 frq) { @@ -2917,9 +2984,9 @@ void __init pmac_check_ht_link(void) u8 px_bus, px_devfn; struct pci_controller *px_hose; - (void)in_be32(u3_ht_base + U3_HT_LINK_COMMAND); - ucfg = cfg = in_be32(u3_ht_base + U3_HT_LINK_CONFIG); - ufreq = freq = in_be32(u3_ht_base + U3_HT_LINK_FREQ); + (void)in_be32(u3_ht + U3_HT_LINK_COMMAND); + ucfg = cfg = in_be32(u3_ht + U3_HT_LINK_CONFIG); + ufreq = freq = in_be32(u3_ht + U3_HT_LINK_FREQ); dump_HT_speeds("U3 HyperTransport", cfg, freq); pcix_node = of_find_compatible_node(NULL, "pci", "pci-x"); diff --git a/trunk/arch/powerpc/platforms/powermac/low_i2c.c b/trunk/arch/powerpc/platforms/powermac/low_i2c.c index 535c802b369f..f3f39e8e337a 100644 --- a/trunk/arch/powerpc/platforms/powermac/low_i2c.c +++ b/trunk/arch/powerpc/platforms/powermac/low_i2c.c @@ -1,34 +1,22 @@ /* - * arch/powerpc/platforms/powermac/low_i2c.c + * arch/ppc/platforms/pmac_low_i2c.c * - * Copyright (C) 2003-2005 Ben. Herrenschmidt (benh@kernel.crashing.org) + * Copyright (C) 2003 Ben. Herrenschmidt (benh@kernel.crashing.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * The linux i2c layer isn't completely suitable for our needs for various - * reasons ranging from too late initialisation to semantics not perfectly - * matching some requirements of the apple platform functions etc... - * - * This file thus provides a simple low level unified i2c interface for - * powermac that covers the various types of i2c busses used in Apple machines. - * For now, keywest, PMU and SMU, though we could add Cuda, or other bit - * banging busses found on older chipstes in earlier machines if we ever need - * one of them. - * - * The drivers in this file are synchronous/blocking. In addition, the - * keywest one is fairly slow due to the use of msleep instead of interrupts - * as the interrupt is currently used by i2c-keywest. In the long run, we - * might want to get rid of those high-level interfaces to linux i2c layer - * either completely (converting all drivers) or replacing them all with a - * single stub driver on top of this one. Once done, the interrupt will be - * available for our use. + * This file contains some low-level i2c access routines that + * need to be used by various bits of the PowerMac platform code + * at times where the real asynchronous & interrupt driven driver + * cannot be used. The API borrows some semantics from the darwin + * driver in order to ease the implementation of the platform + * properties parser */ #undef DEBUG -#undef DEBUG_LOW #include #include @@ -37,91 +25,66 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include #include #include #include -#include -#include #include +#define MAX_LOW_I2C_HOST 4 + #ifdef DEBUG #define DBG(x...) do {\ - printk(KERN_DEBUG "low_i2c:" x); \ + printk(KERN_DEBUG "KW:" x); \ } while(0) #else #define DBG(x...) #endif -#ifdef DEBUG_LOW -#define DBG_LOW(x...) do {\ - printk(KERN_DEBUG "low_i2c:" x); \ - } while(0) -#else -#define DBG_LOW(x...) -#endif +struct low_i2c_host; +typedef int (*low_i2c_func_t)(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len); -static int pmac_i2c_force_poll = 1; +struct low_i2c_host +{ + struct device_node *np; /* OF device node */ + struct semaphore mutex; /* Access mutex for use by i2c-keywest */ + low_i2c_func_t func; /* Access function */ + unsigned int is_open : 1; /* Poor man's access control */ + int mode; /* Current mode */ + int channel; /* Current channel */ + int num_channels; /* Number of channels */ + void __iomem *base; /* For keywest-i2c, base address */ + int bsteps; /* And register stepping */ + int speed; /* And speed */ +}; -/* - * A bus structure. Each bus in the system has such a structure associated. +static struct low_i2c_host low_i2c_hosts[MAX_LOW_I2C_HOST]; + +/* No locking is necessary on allocation, we are running way before + * anything can race with us */ -struct pmac_i2c_bus +static struct low_i2c_host *find_low_i2c_host(struct device_node *np) { - struct list_head link; - struct device_node *controller; - struct device_node *busnode; - int type; - int flags; - struct i2c_adapter *adapter; - void *hostdata; - int channel; /* some hosts have multiple */ - int mode; /* current mode */ - struct semaphore sem; - int opened; - int polled; /* open mode */ - struct platform_device *platform_dev; - - /* ops */ - int (*open)(struct pmac_i2c_bus *bus); - void (*close)(struct pmac_i2c_bus *bus); - int (*xfer)(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, - u32 subaddr, u8 *data, int len); -}; + int i; -static LIST_HEAD(pmac_i2c_busses); + for (i = 0; i < MAX_LOW_I2C_HOST; i++) + if (low_i2c_hosts[i].np == np) + return &low_i2c_hosts[i]; + return NULL; +} /* - * Keywest implementation + * + * i2c-keywest implementation (UniNorth, U2, U3, Keylargo's) + * */ -struct pmac_i2c_host_kw -{ - struct semaphore mutex; /* Access mutex for use by - * i2c-keywest */ - void __iomem *base; /* register base address */ - int bsteps; /* register stepping */ - int speed; /* speed */ - int irq; - u8 *data; - unsigned len; - int state; - int rw; - int polled; - int result; - struct completion complete; - spinlock_t lock; - struct timer_list timeout_timer; -}; - +/* + * Keywest i2c definitions borrowed from drivers/i2c/i2c-keywest.h, + * should be moved somewhere in include/asm-ppc/ + */ /* Register indices */ typedef enum { reg_mode = 0, @@ -134,8 +97,6 @@ typedef enum { reg_data } reg_t; -/* The Tumbler audio equalizer can be really slow sometimes */ -#define KW_POLL_TIMEOUT (2*HZ) /* Mode register */ #define KW_I2C_MODE_100KHZ 0x00 @@ -179,9 +140,8 @@ enum { }; #define WRONG_STATE(name) do {\ - printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s " \ - "(isr: %02x)\n", \ - name, __kw_state_names[host->state], isr); \ + printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s (isr: %02x)\n", \ + name, __kw_state_names[state], isr); \ } while(0) static const char *__kw_state_names[] = { @@ -193,137 +153,120 @@ static const char *__kw_state_names[] = { "state_dead" }; -static inline u8 __kw_read_reg(struct pmac_i2c_host_kw *host, reg_t reg) +static inline u8 __kw_read_reg(struct low_i2c_host *host, reg_t reg) { return readb(host->base + (((unsigned int)reg) << host->bsteps)); } -static inline void __kw_write_reg(struct pmac_i2c_host_kw *host, - reg_t reg, u8 val) +static inline void __kw_write_reg(struct low_i2c_host *host, reg_t reg, u8 val) { writeb(val, host->base + (((unsigned)reg) << host->bsteps)); (void)__kw_read_reg(host, reg_subaddr); } -#define kw_write_reg(reg, val) __kw_write_reg(host, reg, val) -#define kw_read_reg(reg) __kw_read_reg(host, reg) +#define kw_write_reg(reg, val) __kw_write_reg(host, reg, val) +#define kw_read_reg(reg) __kw_read_reg(host, reg) + -static u8 kw_i2c_wait_interrupt(struct pmac_i2c_host_kw *host) +/* Don't schedule, the g5 fan controller is too + * timing sensitive + */ +static u8 kw_wait_interrupt(struct low_i2c_host* host) { int i, j; u8 isr; - for (i = 0; i < 1000; i++) { + for (i = 0; i < 100000; i++) { isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK; if (isr != 0) return isr; /* This code is used with the timebase frozen, we cannot rely - * on udelay nor schedule when in polled mode ! - * For now, just use a bogus loop.... + * on udelay ! For now, just use a bogus loop */ - if (host->polled) { - for (j = 1; j < 100000; j++) - mb(); - } else - msleep(1); + for (j = 1; j < 10000; j++) + mb(); } return isr; } -static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr) +static int kw_handle_interrupt(struct low_i2c_host *host, int state, int rw, int *rc, u8 **data, int *len, u8 isr) { u8 ack; - DBG_LOW("kw_handle_interrupt(%s, isr: %x)\n", - __kw_state_names[host->state], isr); - - if (host->state == state_idle) { - printk(KERN_WARNING "low_i2c: Keywest got an out of state" - " interrupt, ignoring\n"); - kw_write_reg(reg_isr, isr); - return; - } + DBG("kw_handle_interrupt(%s, isr: %x)\n", __kw_state_names[state], isr); if (isr == 0) { - if (host->state != state_stop) { - DBG_LOW("KW: Timeout !\n"); - host->result = -EIO; + if (state != state_stop) { + DBG("KW: Timeout !\n"); + *rc = -EIO; goto stop; } - if (host->state == state_stop) { + if (state == state_stop) { ack = kw_read_reg(reg_status); - if (ack & KW_I2C_STAT_BUSY) - kw_write_reg(reg_status, 0); - host->state = state_idle; - kw_write_reg(reg_ier, 0x00); - if (!host->polled) - complete(&host->complete); + if (!(ack & KW_I2C_STAT_BUSY)) { + state = state_idle; + kw_write_reg(reg_ier, 0x00); + } } - return; + return state; } if (isr & KW_I2C_IRQ_ADDR) { ack = kw_read_reg(reg_status); - if (host->state != state_addr) { + if (state != state_addr) { kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); WRONG_STATE("KW_I2C_IRQ_ADDR"); - host->result = -EIO; + *rc = -EIO; goto stop; } - if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { - host->result = -ENODEV; - DBG_LOW("KW: NAK on address\n"); - host->state = state_stop; - return; + if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { + *rc = -ENODEV; + DBG("KW: NAK on address\n"); + return state_stop; } else { - if (host->len == 0) { - kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); - goto stop; - } - if (host->rw) { - host->state = state_read; - if (host->len > 1) - kw_write_reg(reg_control, - KW_I2C_CTL_AAK); + if (rw) { + state = state_read; + if (*len > 1) + kw_write_reg(reg_control, KW_I2C_CTL_AAK); } else { - host->state = state_write; - kw_write_reg(reg_data, *(host->data++)); - host->len--; + state = state_write; + kw_write_reg(reg_data, **data); + (*data)++; (*len)--; } } kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); } if (isr & KW_I2C_IRQ_DATA) { - if (host->state == state_read) { - *(host->data++) = kw_read_reg(reg_data); - host->len--; + if (state == state_read) { + **data = kw_read_reg(reg_data); + (*data)++; (*len)--; kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); - if (host->len == 0) - host->state = state_stop; - else if (host->len == 1) + if ((*len) == 0) + state = state_stop; + else if ((*len) == 1) kw_write_reg(reg_control, 0); - } else if (host->state == state_write) { + } else if (state == state_write) { ack = kw_read_reg(reg_status); if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { - DBG_LOW("KW: nack on data write\n"); - host->result = -EIO; + DBG("KW: nack on data write\n"); + *rc = -EIO; goto stop; - } else if (host->len) { - kw_write_reg(reg_data, *(host->data++)); - host->len--; + } else if (*len) { + kw_write_reg(reg_data, **data); + (*data)++; (*len)--; } else { kw_write_reg(reg_control, KW_I2C_CTL_STOP); - host->state = state_stop; - host->result = 0; + state = state_stop; + *rc = 0; } kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); } else { kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); WRONG_STATE("KW_I2C_IRQ_DATA"); - if (host->state != state_stop) { - host->result = -EIO; + if (state != state_stop) { + *rc = -EIO; goto stop; } } @@ -331,194 +274,98 @@ static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr) if (isr & KW_I2C_IRQ_STOP) { kw_write_reg(reg_isr, KW_I2C_IRQ_STOP); - if (host->state != state_stop) { + if (state != state_stop) { WRONG_STATE("KW_I2C_IRQ_STOP"); - host->result = -EIO; + *rc = -EIO; } - host->state = state_idle; - if (!host->polled) - complete(&host->complete); + return state_idle; } if (isr & KW_I2C_IRQ_START) kw_write_reg(reg_isr, KW_I2C_IRQ_START); - return; + return state; + stop: kw_write_reg(reg_control, KW_I2C_CTL_STOP); - host->state = state_stop; - return; + return state_stop; } -/* Interrupt handler */ -static irqreturn_t kw_i2c_irq(int irq, void *dev_id, struct pt_regs *regs) +static int keywest_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 subaddr, u8 *data, int len) { - struct pmac_i2c_host_kw *host = dev_id; - unsigned long flags; - - spin_lock_irqsave(&host->lock, flags); - del_timer(&host->timeout_timer); - kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr)); - if (host->state != state_idle) { - host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT; - add_timer(&host->timeout_timer); - } - spin_unlock_irqrestore(&host->lock, flags); - return IRQ_HANDLED; -} - -static void kw_i2c_timeout(unsigned long data) -{ - struct pmac_i2c_host_kw *host = (struct pmac_i2c_host_kw *)data; - unsigned long flags; - - spin_lock_irqsave(&host->lock, flags); - kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr)); - if (host->state != state_idle) { - host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT; - add_timer(&host->timeout_timer); - } - spin_unlock_irqrestore(&host->lock, flags); -} - -static int kw_i2c_open(struct pmac_i2c_bus *bus) -{ - struct pmac_i2c_host_kw *host = bus->hostdata; - down(&host->mutex); - return 0; -} - -static void kw_i2c_close(struct pmac_i2c_bus *bus) -{ - struct pmac_i2c_host_kw *host = bus->hostdata; - up(&host->mutex); -} - -static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, - u32 subaddr, u8 *data, int len) -{ - struct pmac_i2c_host_kw *host = bus->hostdata; u8 mode_reg = host->speed; - int use_irq = host->irq != NO_IRQ && !bus->polled; + int state = state_addr; + int rc = 0; /* Setup mode & subaddress if any */ - switch(bus->mode) { - case pmac_i2c_mode_dumb: + switch(host->mode) { + case pmac_low_i2c_mode_dumb: + printk(KERN_ERR "low_i2c: Dumb mode not supported !\n"); return -EINVAL; - case pmac_i2c_mode_std: + case pmac_low_i2c_mode_std: mode_reg |= KW_I2C_MODE_STANDARD; - if (subsize != 0) - return -EINVAL; break; - case pmac_i2c_mode_stdsub: + case pmac_low_i2c_mode_stdsub: mode_reg |= KW_I2C_MODE_STANDARDSUB; - if (subsize != 1) - return -EINVAL; break; - case pmac_i2c_mode_combined: + case pmac_low_i2c_mode_combined: mode_reg |= KW_I2C_MODE_COMBINED; - if (subsize != 1) - return -EINVAL; break; } /* Setup channel & clear pending irqs */ kw_write_reg(reg_isr, kw_read_reg(reg_isr)); - kw_write_reg(reg_mode, mode_reg | (bus->channel << 4)); + kw_write_reg(reg_mode, mode_reg | (host->channel << 4)); kw_write_reg(reg_status, 0); - /* Set up address and r/w bit, strip possible stale bus number from - * address top bits - */ - kw_write_reg(reg_addr, addrdir & 0xff); + /* Set up address and r/w bit */ + kw_write_reg(reg_addr, addr); /* Set up the sub address */ if ((mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB || (mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED) kw_write_reg(reg_subaddr, subaddr); - /* Prepare for async operations */ - host->data = data; - host->len = len; - host->state = state_addr; - host->result = 0; - host->rw = (addrdir & 1); - host->polled = bus->polled; - - /* Enable interrupt if not using polled mode and interrupt is - * available - */ - if (use_irq) { - /* Clear completion */ - INIT_COMPLETION(host->complete); - /* Ack stale interrupts */ - kw_write_reg(reg_isr, kw_read_reg(reg_isr)); - /* Arm timeout */ - host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT; - add_timer(&host->timeout_timer); - /* Enable emission */ - kw_write_reg(reg_ier, KW_I2C_IRQ_MASK); - } - - /* Start sending address */ + /* Start sending address & disable interrupt*/ + kw_write_reg(reg_ier, 0 /*KW_I2C_IRQ_MASK*/); kw_write_reg(reg_control, KW_I2C_CTL_XADDR); - /* Wait for completion */ - if (use_irq) - wait_for_completion(&host->complete); - else { - while(host->state != state_idle) { - unsigned long flags; - - u8 isr = kw_i2c_wait_interrupt(host); - spin_lock_irqsave(&host->lock, flags); - kw_i2c_handle_interrupt(host, isr); - spin_unlock_irqrestore(&host->lock, flags); - } + /* State machine, to turn into an interrupt handler */ + while(state != state_idle) { + u8 isr = kw_wait_interrupt(host); + state = kw_handle_interrupt(host, state, addr & 1, &rc, &data, &len, isr); } - /* Disable emission */ - kw_write_reg(reg_ier, 0); - - return host->result; + return rc; } -static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) +static void keywest_low_i2c_add(struct device_node *np) { - struct pmac_i2c_host_kw *host; - u32 *psteps, *prate, *addrp, steps; + struct low_i2c_host *host = find_low_i2c_host(NULL); + u32 *psteps, *prate, steps, aoffset = 0; + struct device_node *parent; - host = kzalloc(sizeof(struct pmac_i2c_host_kw), GFP_KERNEL); if (host == NULL) { printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", np->full_name); - return NULL; + return; } + memset(host, 0, sizeof(*host)); - /* Apple is kind enough to provide a valid AAPL,address property - * on all i2c keywest nodes so far ... we would have to fallback - * to macio parsing if that wasn't the case - */ - addrp = (u32 *)get_property(np, "AAPL,address", NULL); - if (addrp == NULL) { - printk(KERN_ERR "low_i2c: Can't find address for %s\n", - np->full_name); - kfree(host); - return NULL; - } init_MUTEX(&host->mutex); - init_completion(&host->complete); - spin_lock_init(&host->lock); - init_timer(&host->timeout_timer); - host->timeout_timer.function = kw_i2c_timeout; - host->timeout_timer.data = (unsigned long)host; - + host->np = of_node_get(np); psteps = (u32 *)get_property(np, "AAPL,address-step", NULL); steps = psteps ? (*psteps) : 0x10; for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++) steps >>= 1; + parent = of_get_parent(np); + host->num_channels = 1; + if (parent && parent->name[0] == 'u') { + host->num_channels = 2; + aoffset = 3; + } /* Select interface rate */ - host->speed = KW_I2C_MODE_25KHZ; + host->speed = KW_I2C_MODE_100KHZ; prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL); if (prate) switch(*prate) { case 100: @@ -531,981 +378,146 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) host->speed = KW_I2C_MODE_25KHZ; break; } - if (np->n_intrs > 0) - host->irq = np->intrs[0].line; - else - host->irq = NO_IRQ; - - host->base = ioremap((*addrp), 0x1000); - if (host->base == NULL) { - printk(KERN_ERR "low_i2c: Can't map registers for %s\n", - np->full_name); - kfree(host); - return NULL; - } - - /* Make sure IRA is disabled */ - kw_write_reg(reg_ier, 0); - - /* Request chip interrupt */ - if (request_irq(host->irq, kw_i2c_irq, SA_SHIRQ, "keywest i2c", host)) - host->irq = NO_IRQ; - - printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n", - *addrp, host->irq, np->full_name); - return host; + host->mode = pmac_low_i2c_mode_std; + host->base = ioremap(np->addrs[0].address + aoffset, + np->addrs[0].size); + host->func = keywest_low_i2c_func; } - -static void __init kw_i2c_add(struct pmac_i2c_host_kw *host, - struct device_node *controller, - struct device_node *busnode, - int channel) -{ - struct pmac_i2c_bus *bus; - - bus = kzalloc(sizeof(struct pmac_i2c_bus), GFP_KERNEL); - if (bus == NULL) - return; - - bus->controller = of_node_get(controller); - bus->busnode = of_node_get(busnode); - bus->type = pmac_i2c_bus_keywest; - bus->hostdata = host; - bus->channel = channel; - bus->mode = pmac_i2c_mode_std; - bus->open = kw_i2c_open; - bus->close = kw_i2c_close; - bus->xfer = kw_i2c_xfer; - init_MUTEX(&bus->sem); - if (controller == busnode) - bus->flags = pmac_i2c_multibus; - list_add(&bus->link, &pmac_i2c_busses); - - printk(KERN_INFO " channel %d bus %s\n", channel, - (controller == busnode) ? "" : busnode->full_name); -} - -static void __init kw_i2c_probe(void) -{ - struct device_node *np, *child, *parent; - - /* Probe keywest-i2c busses */ - for (np = NULL; - (np = of_find_compatible_node(np, "i2c","keywest-i2c")) != NULL;){ - struct pmac_i2c_host_kw *host; - int multibus, chans, i; - - /* Found one, init a host structure */ - host = kw_i2c_host_init(np); - if (host == NULL) - continue; - - /* Now check if we have a multibus setup (old style) or if we - * have proper bus nodes. Note that the "new" way (proper bus - * nodes) might cause us to not create some busses that are - * kept hidden in the device-tree. In the future, we might - * want to work around that by creating busses without a node - * but not for now - */ - child = of_get_next_child(np, NULL); - multibus = !child || strcmp(child->name, "i2c-bus"); - of_node_put(child); - - /* For a multibus setup, we get the bus count based on the - * parent type - */ - if (multibus) { - parent = of_get_parent(np); - if (parent == NULL) - continue; - chans = parent->name[0] == 'u' ? 2 : 1; - for (i = 0; i < chans; i++) - kw_i2c_add(host, np, np, i); - } else { - for (child = NULL; - (child = of_get_next_child(np, child)) != NULL;) { - u32 *reg = - (u32 *)get_property(child, "reg", NULL); - if (reg == NULL) - continue; - kw_i2c_add(host, np, child, *reg); - } - } - } -} - - /* * * PMU implementation * */ -#ifdef CONFIG_ADB_PMU -/* - * i2c command block to the PMU - */ -struct pmu_i2c_hdr { - u8 bus; - u8 mode; - u8 bus2; - u8 address; - u8 sub_addr; - u8 comb_addr; - u8 count; - u8 data[]; -}; - -static void pmu_i2c_complete(struct adb_request *req) -{ - complete(req->arg); -} +#ifdef CONFIG_ADB_PMU -static int pmu_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, - u32 subaddr, u8 *data, int len) +static int pmu_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 sub, u8 *data, int len) { - struct adb_request *req = bus->hostdata; - struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req->data[1]; - struct completion comp; - int read = addrdir & 1; - int retry; - int rc = 0; - - /* For now, limit ourselves to 16 bytes transfers */ - if (len > 16) - return -EINVAL; - - init_completion(&comp); - - for (retry = 0; retry < 16; retry++) { - memset(req, 0, sizeof(struct adb_request)); - hdr->bus = bus->channel; - hdr->count = len; - - switch(bus->mode) { - case pmac_i2c_mode_std: - if (subsize != 0) - return -EINVAL; - hdr->address = addrdir; - hdr->mode = PMU_I2C_MODE_SIMPLE; - break; - case pmac_i2c_mode_stdsub: - case pmac_i2c_mode_combined: - if (subsize != 1) - return -EINVAL; - hdr->address = addrdir & 0xfe; - hdr->comb_addr = addrdir; - hdr->sub_addr = subaddr; - if (bus->mode == pmac_i2c_mode_stdsub) - hdr->mode = PMU_I2C_MODE_STDSUB; - else - hdr->mode = PMU_I2C_MODE_COMBINED; - break; - default: - return -EINVAL; - } - - INIT_COMPLETION(comp); - req->data[0] = PMU_I2C_CMD; - req->reply[0] = 0xff; - req->nbytes = sizeof(struct pmu_i2c_hdr) + 1; - req->done = pmu_i2c_complete; - req->arg = ∁ - if (!read && len) { - memcpy(hdr->data, data, len); - req->nbytes += len; - } - rc = pmu_queue_request(req); - if (rc) - return rc; - wait_for_completion(&comp); - if (req->reply[0] == PMU_I2C_STATUS_OK) - break; - msleep(15); - } - if (req->reply[0] != PMU_I2C_STATUS_OK) - return -EIO; - - for (retry = 0; retry < 16; retry++) { - memset(req, 0, sizeof(struct adb_request)); - - /* I know that looks like a lot, slow as hell, but darwin - * does it so let's be on the safe side for now - */ - msleep(15); - - hdr->bus = PMU_I2C_BUS_STATUS; - - INIT_COMPLETION(comp); - req->data[0] = PMU_I2C_CMD; - req->reply[0] = 0xff; - req->nbytes = 2; - req->done = pmu_i2c_complete; - req->arg = ∁ - rc = pmu_queue_request(req); - if (rc) - return rc; - wait_for_completion(&comp); - - if (req->reply[0] == PMU_I2C_STATUS_OK && !read) - return 0; - if (req->reply[0] == PMU_I2C_STATUS_DATAREAD && read) { - int rlen = req->reply_len - 1; - - if (rlen != len) { - printk(KERN_WARNING "low_i2c: PMU returned %d" - " bytes, expected %d !\n", rlen, len); - return -EIO; - } - if (len) - memcpy(data, &req->reply[1], len); - return 0; - } - } - return -EIO; + // TODO + return -ENODEV; } -static void __init pmu_i2c_probe(void) +static void pmu_low_i2c_add(struct device_node *np) { - struct pmac_i2c_bus *bus; - struct device_node *busnode; - int channel, sz; + struct low_i2c_host *host = find_low_i2c_host(NULL); - if (!pmu_present()) - return; - - /* There might or might not be a "pmu-i2c" node, we use that - * or via-pmu itself, whatever we find. I haven't seen a machine - * with separate bus nodes, so we assume a multibus setup - */ - busnode = of_find_node_by_name(NULL, "pmu-i2c"); - if (busnode == NULL) - busnode = of_find_node_by_name(NULL, "via-pmu"); - if (busnode == NULL) + if (host == NULL) { + printk(KERN_ERR "low_i2c: Can't allocate host for %s\n", + np->full_name); return; - - printk(KERN_INFO "PMU i2c %s\n", busnode->full_name); - - /* - * We add bus 1 and 2 only for now, bus 0 is "special" - */ - for (channel = 1; channel <= 2; channel++) { - sz = sizeof(struct pmac_i2c_bus) + sizeof(struct adb_request); - bus = kzalloc(sz, GFP_KERNEL); - if (bus == NULL) - return; - - bus->controller = busnode; - bus->busnode = busnode; - bus->type = pmac_i2c_bus_pmu; - bus->channel = channel; - bus->mode = pmac_i2c_mode_std; - bus->hostdata = bus + 1; - bus->xfer = pmu_i2c_xfer; - init_MUTEX(&bus->sem); - bus->flags = pmac_i2c_multibus; - list_add(&bus->link, &pmac_i2c_busses); - - printk(KERN_INFO " channel %d bus \n", channel); } -} - -#endif /* CONFIG_ADB_PMU */ + memset(host, 0, sizeof(*host)); - -/* - * - * SMU implementation - * - */ - -#ifdef CONFIG_PMAC_SMU - -static void smu_i2c_complete(struct smu_i2c_cmd *cmd, void *misc) -{ - complete(misc); + init_MUTEX(&host->mutex); + host->np = of_node_get(np); + host->num_channels = 3; + host->mode = pmac_low_i2c_mode_std; + host->func = pmu_low_i2c_func; } -static int smu_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, - u32 subaddr, u8 *data, int len) -{ - struct smu_i2c_cmd *cmd = bus->hostdata; - struct completion comp; - int read = addrdir & 1; - int rc = 0; - - if ((read && len > SMU_I2C_READ_MAX) || - ((!read) && len > SMU_I2C_WRITE_MAX)) - return -EINVAL; - - memset(cmd, 0, sizeof(struct smu_i2c_cmd)); - cmd->info.bus = bus->channel; - cmd->info.devaddr = addrdir; - cmd->info.datalen = len; - - switch(bus->mode) { - case pmac_i2c_mode_std: - if (subsize != 0) - return -EINVAL; - cmd->info.type = SMU_I2C_TRANSFER_SIMPLE; - break; - case pmac_i2c_mode_stdsub: - case pmac_i2c_mode_combined: - if (subsize > 3 || subsize < 1) - return -EINVAL; - cmd->info.sublen = subsize; - /* that's big-endian only but heh ! */ - memcpy(&cmd->info.subaddr, ((char *)&subaddr) + (4 - subsize), - subsize); - if (bus->mode == pmac_i2c_mode_stdsub) - cmd->info.type = SMU_I2C_TRANSFER_STDSUB; - else - cmd->info.type = SMU_I2C_TRANSFER_COMBINED; - break; - default: - return -EINVAL; - } - if (!read && len) - memcpy(cmd->info.data, data, len); - - init_completion(&comp); - cmd->done = smu_i2c_complete; - cmd->misc = ∁ - rc = smu_queue_i2c(cmd); - if (rc < 0) - return rc; - wait_for_completion(&comp); - rc = cmd->status; - - if (read && len) - memcpy(data, cmd->info.data, len); - return rc < 0 ? rc : 0; -} +#endif /* CONFIG_ADB_PMU */ -static void __init smu_i2c_probe(void) +void __init pmac_init_low_i2c(void) { - struct device_node *controller, *busnode; - struct pmac_i2c_bus *bus; - u32 *reg; - int sz; - - if (!smu_present()) - return; - - controller = of_find_node_by_name(NULL, "smu-i2c-control"); - if (controller == NULL) - controller = of_find_node_by_name(NULL, "smu"); - if (controller == NULL) - return; - - printk(KERN_INFO "SMU i2c %s\n", controller->full_name); - - /* Look for childs, note that they might not be of the right - * type as older device trees mix i2c busses and other thigns - * at the same level - */ - for (busnode = NULL; - (busnode = of_get_next_child(controller, busnode)) != NULL;) { - if (strcmp(busnode->type, "i2c") && - strcmp(busnode->type, "i2c-bus")) - continue; - reg = (u32 *)get_property(busnode, "reg", NULL); - if (reg == NULL) - continue; - - sz = sizeof(struct pmac_i2c_bus) + sizeof(struct smu_i2c_cmd); - bus = kzalloc(sz, GFP_KERNEL); - if (bus == NULL) - return; - - bus->controller = controller; - bus->busnode = of_node_get(busnode); - bus->type = pmac_i2c_bus_smu; - bus->channel = *reg; - bus->mode = pmac_i2c_mode_std; - bus->hostdata = bus + 1; - bus->xfer = smu_i2c_xfer; - init_MUTEX(&bus->sem); - bus->flags = 0; - list_add(&bus->link, &pmac_i2c_busses); - - printk(KERN_INFO " channel %x bus %s\n", - bus->channel, busnode->full_name); - } -} - -#endif /* CONFIG_PMAC_SMU */ - -/* - * - * Core code - * - */ - + struct device_node *np; -struct pmac_i2c_bus *pmac_i2c_find_bus(struct device_node *node) -{ - struct device_node *p = of_node_get(node); - struct device_node *prev = NULL; - struct pmac_i2c_bus *bus; - - while(p) { - list_for_each_entry(bus, &pmac_i2c_busses, link) { - if (p == bus->busnode) { - if (prev && bus->flags & pmac_i2c_multibus) { - u32 *reg; - reg = (u32 *)get_property(prev, "reg", - NULL); - if (!reg) - continue; - if (((*reg) >> 8) != bus->channel) - continue; - } - of_node_put(p); - of_node_put(prev); - return bus; - } - } - of_node_put(prev); - prev = p; - p = of_get_parent(p); + /* Probe keywest-i2c busses */ + np = of_find_compatible_node(NULL, "i2c", "keywest-i2c"); + while(np) { + keywest_low_i2c_add(np); + np = of_find_compatible_node(np, "i2c", "keywest-i2c"); } - return NULL; -} -EXPORT_SYMBOL_GPL(pmac_i2c_find_bus); - -u8 pmac_i2c_get_dev_addr(struct device_node *device) -{ - u32 *reg = (u32 *)get_property(device, "reg", NULL); - if (reg == NULL) - return 0; - - return (*reg) & 0xff; -} -EXPORT_SYMBOL_GPL(pmac_i2c_get_dev_addr); - -struct device_node *pmac_i2c_get_controller(struct pmac_i2c_bus *bus) -{ - return bus->controller; -} -EXPORT_SYMBOL_GPL(pmac_i2c_get_controller); - -struct device_node *pmac_i2c_get_bus_node(struct pmac_i2c_bus *bus) -{ - return bus->busnode; -} -EXPORT_SYMBOL_GPL(pmac_i2c_get_bus_node); - -int pmac_i2c_get_type(struct pmac_i2c_bus *bus) -{ - return bus->type; -} -EXPORT_SYMBOL_GPL(pmac_i2c_get_type); - -int pmac_i2c_get_flags(struct pmac_i2c_bus *bus) -{ - return bus->flags; -} -EXPORT_SYMBOL_GPL(pmac_i2c_get_flags); - -int pmac_i2c_get_channel(struct pmac_i2c_bus *bus) -{ - return bus->channel; -} -EXPORT_SYMBOL_GPL(pmac_i2c_get_channel); - - -void pmac_i2c_attach_adapter(struct pmac_i2c_bus *bus, - struct i2c_adapter *adapter) -{ - WARN_ON(bus->adapter != NULL); - bus->adapter = adapter; -} -EXPORT_SYMBOL_GPL(pmac_i2c_attach_adapter); - -void pmac_i2c_detach_adapter(struct pmac_i2c_bus *bus, - struct i2c_adapter *adapter) -{ - WARN_ON(bus->adapter != adapter); - bus->adapter = NULL; -} -EXPORT_SYMBOL_GPL(pmac_i2c_detach_adapter); - -struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus) -{ - return bus->adapter; -} -EXPORT_SYMBOL_GPL(pmac_i2c_get_adapter); - -struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter) -{ - struct pmac_i2c_bus *bus; - - list_for_each_entry(bus, &pmac_i2c_busses, link) - if (bus->adapter == adapter) - return bus; - return NULL; -} -EXPORT_SYMBOL_GPL(pmac_i2c_adapter_to_bus); - -extern int pmac_i2c_match_adapter(struct device_node *dev, - struct i2c_adapter *adapter) -{ - struct pmac_i2c_bus *bus = pmac_i2c_find_bus(dev); +#ifdef CONFIG_ADB_PMU + /* Probe PMU busses */ + np = of_find_node_by_name(NULL, "via-pmu"); + if (np) + pmu_low_i2c_add(np); +#endif /* CONFIG_ADB_PMU */ - if (bus == NULL) - return 0; - return (bus->adapter == adapter); + /* TODO: Add CUDA support as well */ } -EXPORT_SYMBOL_GPL(pmac_i2c_match_adapter); int pmac_low_i2c_lock(struct device_node *np) { - struct pmac_i2c_bus *bus, *found = NULL; + struct low_i2c_host *host = find_low_i2c_host(np); - list_for_each_entry(bus, &pmac_i2c_busses, link) { - if (np == bus->controller) { - found = bus; - break; - } - } - if (!found) + if (!host) return -ENODEV; - return pmac_i2c_open(bus, 0); + down(&host->mutex); + return 0; } -EXPORT_SYMBOL_GPL(pmac_low_i2c_lock); +EXPORT_SYMBOL(pmac_low_i2c_lock); int pmac_low_i2c_unlock(struct device_node *np) { - struct pmac_i2c_bus *bus, *found = NULL; + struct low_i2c_host *host = find_low_i2c_host(np); - list_for_each_entry(bus, &pmac_i2c_busses, link) { - if (np == bus->controller) { - found = bus; - break; - } - } - if (!found) + if (!host) return -ENODEV; - pmac_i2c_close(bus); - return 0; -} -EXPORT_SYMBOL_GPL(pmac_low_i2c_unlock); - - -int pmac_i2c_open(struct pmac_i2c_bus *bus, int polled) -{ - int rc; - - down(&bus->sem); - bus->polled = polled || pmac_i2c_force_poll; - bus->opened = 1; - bus->mode = pmac_i2c_mode_std; - if (bus->open && (rc = bus->open(bus)) != 0) { - bus->opened = 0; - up(&bus->sem); - return rc; - } - return 0; -} -EXPORT_SYMBOL_GPL(pmac_i2c_open); - -void pmac_i2c_close(struct pmac_i2c_bus *bus) -{ - WARN_ON(!bus->opened); - if (bus->close) - bus->close(bus); - bus->opened = 0; - up(&bus->sem); -} -EXPORT_SYMBOL_GPL(pmac_i2c_close); - -int pmac_i2c_setmode(struct pmac_i2c_bus *bus, int mode) -{ - WARN_ON(!bus->opened); - - /* Report me if you see the error below as there might be a new - * "combined4" mode that I need to implement for the SMU bus - */ - if (mode < pmac_i2c_mode_dumb || mode > pmac_i2c_mode_combined) { - printk(KERN_ERR "low_i2c: Invalid mode %d requested on" - " bus %s !\n", mode, bus->busnode->full_name); - return -EINVAL; - } - bus->mode = mode; - + up(&host->mutex); return 0; } -EXPORT_SYMBOL_GPL(pmac_i2c_setmode); - -int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize, - u32 subaddr, u8 *data, int len) -{ - int rc; - - WARN_ON(!bus->opened); - - DBG("xfer() chan=%d, addrdir=0x%x, mode=%d, subsize=%d, subaddr=0x%x," - " %d bytes, bus %s\n", bus->channel, addrdir, bus->mode, subsize, - subaddr, len, bus->busnode->full_name); - - rc = bus->xfer(bus, addrdir, subsize, subaddr, data, len); - -#ifdef DEBUG - if (rc) - DBG("xfer error %d\n", rc); -#endif - return rc; -} -EXPORT_SYMBOL_GPL(pmac_i2c_xfer); - -/* some quirks for platform function decoding */ -enum { - pmac_i2c_quirk_invmask = 0x00000001u, -}; - -static void pmac_i2c_devscan(void (*callback)(struct device_node *dev, - int quirks)) -{ - struct pmac_i2c_bus *bus; - struct device_node *np; - static struct whitelist_ent { - char *name; - char *compatible; - int quirks; - } whitelist[] = { - /* XXX Study device-tree's & apple drivers are get the quirks - * right ! - */ - { "i2c-hwclock", NULL, pmac_i2c_quirk_invmask }, - { "i2c-cpu-voltage", NULL, 0}, - { "temp-monitor", NULL, 0 }, - { "supply-monitor", NULL, 0 }, - { NULL, NULL, 0 }, - }; - - /* Only some devices need to have platform functions instanciated - * here. For now, we have a table. Others, like 9554 i2c GPIOs used - * on Xserve, if we ever do a driver for them, will use their own - * platform function instance - */ - list_for_each_entry(bus, &pmac_i2c_busses, link) { - for (np = NULL; - (np = of_get_next_child(bus->busnode, np)) != NULL;) { - struct whitelist_ent *p; - /* If multibus, check if device is on that bus */ - if (bus->flags & pmac_i2c_multibus) - if (bus != pmac_i2c_find_bus(np)) - continue; - for (p = whitelist; p->name != NULL; p++) { - if (strcmp(np->name, p->name)) - continue; - if (p->compatible && - !device_is_compatible(np, p->compatible)) - continue; - callback(np, p->quirks); - break; - } - } - } -} - -#define MAX_I2C_DATA 64 - -struct pmac_i2c_pf_inst -{ - struct pmac_i2c_bus *bus; - u8 addr; - u8 buffer[MAX_I2C_DATA]; - u8 scratch[MAX_I2C_DATA]; - int bytes; - int quirks; -}; - -static void* pmac_i2c_do_begin(struct pmf_function *func, struct pmf_args *args) -{ - struct pmac_i2c_pf_inst *inst; - struct pmac_i2c_bus *bus; - - bus = pmac_i2c_find_bus(func->node); - if (bus == NULL) { - printk(KERN_ERR "low_i2c: Can't find bus for %s (pfunc)\n", - func->node->full_name); - return NULL; - } - if (pmac_i2c_open(bus, 0)) { - printk(KERN_ERR "low_i2c: Can't open i2c bus for %s (pfunc)\n", - func->node->full_name); - return NULL; - } - - /* XXX might need GFP_ATOMIC when called during the suspend process, - * but then, there are already lots of issues with suspending when - * near OOM that need to be resolved, the allocator itself should - * probably make GFP_NOIO implicit during suspend - */ - inst = kzalloc(sizeof(struct pmac_i2c_pf_inst), GFP_KERNEL); - if (inst == NULL) { - pmac_i2c_close(bus); - return NULL; - } - inst->bus = bus; - inst->addr = pmac_i2c_get_dev_addr(func->node); - inst->quirks = (int)(long)func->driver_data; - return inst; -} - -static void pmac_i2c_do_end(struct pmf_function *func, void *instdata) -{ - struct pmac_i2c_pf_inst *inst = instdata; - - if (inst == NULL) - return; - pmac_i2c_close(inst->bus); - if (inst) - kfree(inst); -} - -static int pmac_i2c_do_read(PMF_STD_ARGS, u32 len) -{ - struct pmac_i2c_pf_inst *inst = instdata; - - inst->bytes = len; - return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_read, 0, 0, - inst->buffer, len); -} - -static int pmac_i2c_do_write(PMF_STD_ARGS, u32 len, const u8 *data) -{ - struct pmac_i2c_pf_inst *inst = instdata; - - return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 0, 0, - (u8 *)data, len); -} - -/* This function is used to do the masking & OR'ing for the "rmw" type - * callbacks. Ze should apply the mask and OR in the values in the - * buffer before writing back. The problem is that it seems that - * various darwin drivers implement the mask/or differently, thus - * we need to check the quirks first - */ -static void pmac_i2c_do_apply_rmw(struct pmac_i2c_pf_inst *inst, - u32 len, const u8 *mask, const u8 *val) -{ - int i; - - if (inst->quirks & pmac_i2c_quirk_invmask) { - for (i = 0; i < len; i ++) - inst->scratch[i] = (inst->buffer[i] & mask[i]) | val[i]; - } else { - for (i = 0; i < len; i ++) - inst->scratch[i] = (inst->buffer[i] & ~mask[i]) - | (val[i] & mask[i]); - } -} - -static int pmac_i2c_do_rmw(PMF_STD_ARGS, u32 masklen, u32 valuelen, - u32 totallen, const u8 *maskdata, - const u8 *valuedata) -{ - struct pmac_i2c_pf_inst *inst = instdata; - - if (masklen > inst->bytes || valuelen > inst->bytes || - totallen > inst->bytes || valuelen > masklen) - return -EINVAL; - - pmac_i2c_do_apply_rmw(inst, masklen, maskdata, valuedata); - - return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 0, 0, - inst->scratch, totallen); -} - -static int pmac_i2c_do_read_sub(PMF_STD_ARGS, u8 subaddr, u32 len) -{ - struct pmac_i2c_pf_inst *inst = instdata; - - inst->bytes = len; - return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_read, 1, subaddr, - inst->buffer, len); -} - -static int pmac_i2c_do_write_sub(PMF_STD_ARGS, u8 subaddr, u32 len, - const u8 *data) -{ - struct pmac_i2c_pf_inst *inst = instdata; - - return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 1, - subaddr, (u8 *)data, len); -} +EXPORT_SYMBOL(pmac_low_i2c_unlock); -static int pmac_i2c_do_set_mode(PMF_STD_ARGS, int mode) -{ - struct pmac_i2c_pf_inst *inst = instdata; - - return pmac_i2c_setmode(inst->bus, mode); -} - -static int pmac_i2c_do_rmw_sub(PMF_STD_ARGS, u8 subaddr, u32 masklen, - u32 valuelen, u32 totallen, const u8 *maskdata, - const u8 *valuedata) -{ - struct pmac_i2c_pf_inst *inst = instdata; - - if (masklen > inst->bytes || valuelen > inst->bytes || - totallen > inst->bytes || valuelen > masklen) - return -EINVAL; - - pmac_i2c_do_apply_rmw(inst, masklen, maskdata, valuedata); - - return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 1, - subaddr, inst->scratch, totallen); -} -static int pmac_i2c_do_mask_and_comp(PMF_STD_ARGS, u32 len, - const u8 *maskdata, - const u8 *valuedata) +int pmac_low_i2c_open(struct device_node *np, int channel) { - struct pmac_i2c_pf_inst *inst = instdata; - int i, match; + struct low_i2c_host *host = find_low_i2c_host(np); - /* Get return value pointer, it's assumed to be a u32 */ - if (!args || !args->count || !args->u[0].p) - return -EINVAL; + if (!host) + return -ENODEV; - /* Check buffer */ - if (len > inst->bytes) + if (channel >= host->num_channels) return -EINVAL; - for (i = 0, match = 1; match && i < len; i ++) - if ((inst->buffer[i] & maskdata[i]) != valuedata[i]) - match = 0; - *args->u[0].p = match; - return 0; -} + down(&host->mutex); + host->is_open = 1; + host->channel = channel; -static int pmac_i2c_do_delay(PMF_STD_ARGS, u32 duration) -{ - msleep((duration + 999) / 1000); return 0; } +EXPORT_SYMBOL(pmac_low_i2c_open); - -static struct pmf_handlers pmac_i2c_pfunc_handlers = { - .begin = pmac_i2c_do_begin, - .end = pmac_i2c_do_end, - .read_i2c = pmac_i2c_do_read, - .write_i2c = pmac_i2c_do_write, - .rmw_i2c = pmac_i2c_do_rmw, - .read_i2c_sub = pmac_i2c_do_read_sub, - .write_i2c_sub = pmac_i2c_do_write_sub, - .rmw_i2c_sub = pmac_i2c_do_rmw_sub, - .set_i2c_mode = pmac_i2c_do_set_mode, - .mask_and_compare = pmac_i2c_do_mask_and_comp, - .delay = pmac_i2c_do_delay, -}; - -static void __init pmac_i2c_dev_create(struct device_node *np, int quirks) +int pmac_low_i2c_close(struct device_node *np) { - DBG("dev_create(%s)\n", np->full_name); - - pmf_register_driver(np, &pmac_i2c_pfunc_handlers, - (void *)(long)quirks); -} + struct low_i2c_host *host = find_low_i2c_host(np); -static void __init pmac_i2c_dev_init(struct device_node *np, int quirks) -{ - DBG("dev_create(%s)\n", np->full_name); - - pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_INIT, NULL); -} - -static void pmac_i2c_dev_suspend(struct device_node *np, int quirks) -{ - DBG("dev_suspend(%s)\n", np->full_name); - pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_SLEEP, NULL); -} - -static void pmac_i2c_dev_resume(struct device_node *np, int quirks) -{ - DBG("dev_resume(%s)\n", np->full_name); - pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_WAKE, NULL); -} + if (!host) + return -ENODEV; -void pmac_pfunc_i2c_suspend(void) -{ - pmac_i2c_devscan(pmac_i2c_dev_suspend); -} + host->is_open = 0; + up(&host->mutex); -void pmac_pfunc_i2c_resume(void) -{ - pmac_i2c_devscan(pmac_i2c_dev_resume); + return 0; } +EXPORT_SYMBOL(pmac_low_i2c_close); -/* - * Initialize us: probe all i2c busses on the machine, instantiate - * busses and platform functions as needed. - */ -/* This is non-static as it might be called early by smp code */ -int __init pmac_i2c_init(void) +int pmac_low_i2c_setmode(struct device_node *np, int mode) { - static int i2c_inited; - - if (i2c_inited) - return 0; - i2c_inited = 1; + struct low_i2c_host *host = find_low_i2c_host(np); - /* Probe keywest-i2c busses */ - kw_i2c_probe(); - -#ifdef CONFIG_ADB_PMU - /* Probe PMU i2c busses */ - pmu_i2c_probe(); -#endif - -#ifdef CONFIG_PMAC_SMU - /* Probe SMU i2c busses */ - smu_i2c_probe(); -#endif - - /* Now add plaform functions for some known devices */ - pmac_i2c_devscan(pmac_i2c_dev_create); + if (!host) + return -ENODEV; + WARN_ON(!host->is_open); + host->mode = mode; return 0; } -arch_initcall(pmac_i2c_init); +EXPORT_SYMBOL(pmac_low_i2c_setmode); -/* Since pmac_i2c_init can be called too early for the platform device - * registration, we need to do it at a later time. In our case, subsys - * happens to fit well, though I agree it's a bit of a hack... - */ -static int __init pmac_i2c_create_platform_devices(void) +int pmac_low_i2c_xfer(struct device_node *np, u8 addrdir, u8 subaddr, u8 *data, int len) { - struct pmac_i2c_bus *bus; - int i = 0; - - /* In the case where we are initialized from smp_init(), we must - * not use the timer (and thus the irq). It's safe from now on - * though - */ - pmac_i2c_force_poll = 0; - - /* Create platform devices */ - list_for_each_entry(bus, &pmac_i2c_busses, link) { - bus->platform_dev = - platform_device_alloc("i2c-powermac", i++); - if (bus->platform_dev == NULL) - return -ENOMEM; - bus->platform_dev->dev.platform_data = bus; - platform_device_add(bus->platform_dev); - } + struct low_i2c_host *host = find_low_i2c_host(np); - /* Now call platform "init" functions */ - pmac_i2c_devscan(pmac_i2c_dev_init); + if (!host) + return -ENODEV; + WARN_ON(!host->is_open); - return 0; + return host->func(host, addrdir, subaddr, data, len); } -subsys_initcall(pmac_i2c_create_platform_devices); +EXPORT_SYMBOL(pmac_low_i2c_xfer); + diff --git a/trunk/arch/powerpc/platforms/powermac/nvram.c b/trunk/arch/powerpc/platforms/powermac/nvram.c index 3ebd045a3350..4042e2f06ee0 100644 --- a/trunk/arch/powerpc/platforms/powermac/nvram.c +++ b/trunk/arch/powerpc/platforms/powermac/nvram.c @@ -514,7 +514,7 @@ static void core99_nvram_sync(void) #endif } -static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr) +static int __init core99_nvram_setup(struct device_node *dp) { int i; u32 gen_bank0, gen_bank1; @@ -528,7 +528,7 @@ static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr) printk(KERN_ERR "nvram: can't allocate ram image\n"); return -ENOMEM; } - nvram_data = ioremap(addr, NVRAM_SIZE*2); + nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2); nvram_naddrs = 1; /* Make sure we get the correct case */ DBG("nvram: Checking bank 0...\n"); @@ -549,7 +549,6 @@ static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr) ppc_md.nvram_write = core99_nvram_write; ppc_md.nvram_size = core99_nvram_size; ppc_md.nvram_sync = core99_nvram_sync; - ppc_md.machine_shutdown = core99_nvram_sync; /* * Maybe we could be smarter here though making an exclusive list * of known flash chips is a bit nasty as older OF didn't provide us @@ -570,48 +569,34 @@ static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr) int __init pmac_nvram_init(void) { struct device_node *dp; - struct resource r1, r2; - unsigned int s1 = 0, s2 = 0; int err = 0; nvram_naddrs = 0; - dp = of_find_node_by_name(NULL, "nvram"); + dp = find_devices("nvram"); if (dp == NULL) { printk(KERN_ERR "Can't find NVRAM device\n"); return -ENODEV; } - - /* Try to obtain an address */ - if (of_address_to_resource(dp, 0, &r1) == 0) { - nvram_naddrs = 1; - s1 = (r1.end - r1.start) + 1; - if (of_address_to_resource(dp, 1, &r2) == 0) { - nvram_naddrs = 2; - s2 = (r2.end - r2.start) + 1; - } - } - + nvram_naddrs = dp->n_addrs; is_core_99 = device_is_compatible(dp, "nvram,flash"); - if (is_core_99) { - err = core99_nvram_setup(dp, r1.start); - goto bail; - } - + if (is_core_99) + err = core99_nvram_setup(dp); #ifdef CONFIG_PPC32 - if (_machine == _MACH_chrp && nvram_naddrs == 1) { - nvram_data = ioremap(r1.start, s1); + else if (_machine == _MACH_chrp && nvram_naddrs == 1) { + nvram_data = ioremap(dp->addrs[0].address + isa_mem_base, + dp->addrs[0].size); nvram_mult = 1; ppc_md.nvram_read_val = direct_nvram_read_byte; ppc_md.nvram_write_val = direct_nvram_write_byte; } else if (nvram_naddrs == 1) { - nvram_data = ioremap(r1.start, s1); - nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE; + nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size); + nvram_mult = (dp->addrs[0].size + NVRAM_SIZE - 1) / NVRAM_SIZE; ppc_md.nvram_read_val = direct_nvram_read_byte; ppc_md.nvram_write_val = direct_nvram_write_byte; } else if (nvram_naddrs == 2) { - nvram_addr = ioremap(r1.start, s1); - nvram_data = ioremap(r2.start, s2); + nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size); + nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size); ppc_md.nvram_read_val = indirect_nvram_read_byte; ppc_md.nvram_write_val = indirect_nvram_write_byte; } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) { @@ -620,15 +605,13 @@ int __init pmac_nvram_init(void) ppc_md.nvram_read_val = pmu_nvram_read_byte; ppc_md.nvram_write_val = pmu_nvram_write_byte; #endif /* CONFIG_ADB_PMU */ - } else { + } +#endif + else { printk(KERN_ERR "Incompatible type of NVRAM\n"); - err = -ENXIO; + return -ENXIO; } -#endif /* CONFIG_PPC32 */ -bail: - of_node_put(dp); - if (err == 0) - lookup_partitions(); + lookup_partitions(); return err; } diff --git a/trunk/arch/powerpc/platforms/powermac/pci.c b/trunk/arch/powerpc/platforms/powermac/pci.c index f671ed253901..443be526cde7 100644 --- a/trunk/arch/powerpc/platforms/powermac/pci.c +++ b/trunk/arch/powerpc/platforms/powermac/pci.c @@ -1,7 +1,7 @@ /* * Support for PCI bridges found on Power Macintoshes. * - * Copyright (C) 2003-2005 Benjamin Herrenschmuidt (benh@kernel.crashing.org) + * Copyright (C) 2003 Benjamin Herrenschmuidt (benh@kernel.crashing.org) * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) * * This program is free software; you can redistribute it and/or @@ -25,7 +25,7 @@ #include #include #ifdef CONFIG_PPC64 -//#include +#include #include #endif @@ -44,7 +44,6 @@ static int add_bridge(struct device_node *dev); static int has_uninorth; #ifdef CONFIG_PPC64 static struct pci_controller *u3_agp; -static struct pci_controller *u4_pcie; static struct pci_controller *u3_ht; #endif /* CONFIG_PPC64 */ @@ -98,8 +97,11 @@ static void __init fixup_bus_range(struct device_node *bridge) /* Lookup the "bus-range" property for the hose */ bus_range = (int *) get_property(bridge, "bus-range", &len); - if (bus_range == NULL || len < 2 * sizeof(int)) + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + bridge->full_name); return; + } bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); } @@ -126,14 +128,14 @@ static void __init fixup_bus_range(struct device_node *bridge) */ #define MACRISC_CFA0(devfn, off) \ - ((1 << (unsigned int)PCI_SLOT(dev_fn)) \ - | (((unsigned int)PCI_FUNC(dev_fn)) << 8) \ - | (((unsigned int)(off)) & 0xFCUL)) + ((1 << (unsigned long)PCI_SLOT(dev_fn)) \ + | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \ + | (((unsigned long)(off)) & 0xFCUL)) #define MACRISC_CFA1(bus, devfn, off) \ - ((((unsigned int)(bus)) << 16) \ - |(((unsigned int)(devfn)) << 8) \ - |(((unsigned int)(off)) & 0xFCUL) \ + ((((unsigned long)(bus)) << 16) \ + |(((unsigned long)(devfn)) << 8) \ + |(((unsigned long)(off)) & 0xFCUL) \ |1UL) static unsigned long macrisc_cfg_access(struct pci_controller* hose, @@ -166,8 +168,7 @@ static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, hose = pci_bus_to_host(bus); if (hose == NULL) return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x100) - return PCIBIOS_BAD_REGISTER_NUMBER; + addr = macrisc_cfg_access(hose, bus->number, devfn, offset); if (!addr) return PCIBIOS_DEVICE_NOT_FOUND; @@ -198,8 +199,7 @@ static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, hose = pci_bus_to_host(bus); if (hose == NULL) return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x100) - return PCIBIOS_BAD_REGISTER_NUMBER; + addr = macrisc_cfg_access(hose, bus->number, devfn, offset); if (!addr) return PCIBIOS_DEVICE_NOT_FOUND; @@ -234,13 +234,12 @@ static struct pci_ops macrisc_pci_ops = /* * Verify that a specific (bus, dev_fn) exists on chaos */ -static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) +static int +chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) { struct device_node *np; u32 *vendor, *device; - if (offset >= 0x100) - return PCIBIOS_BAD_REGISTER_NUMBER; np = pci_busdev_to_OF_node(bus, devfn); if (np == NULL) return PCIBIOS_DEVICE_NOT_FOUND; @@ -286,13 +285,15 @@ static struct pci_ops chaos_pci_ops = }; static void __init setup_chaos(struct pci_controller *hose, - struct resource *addr) + struct reg_property *addr) { /* assume a `chaos' bridge */ hose->ops = &chaos_pci_ops; - hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); - hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000); + hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); } +#else +#define setup_chaos(hose, addr) #endif /* CONFIG_PPC32 */ #ifdef CONFIG_PPC64 @@ -325,7 +326,7 @@ static int u3_ht_skip_device(struct pci_controller *hose, else busdn = hose->arch_data; for (dn = busdn->child; dn; dn = dn->sibling) - if (PCI_DN(dn) && PCI_DN(dn)->devfn == devfn) + if (dn->data && PCI_DN(dn)->devfn == devfn) break; if (dn == NULL) return -1; @@ -342,10 +343,10 @@ static int u3_ht_skip_device(struct pci_controller *hose, } #define U3_HT_CFA0(devfn, off) \ - ((((unsigned int)devfn) << 8) | offset) + ((((unsigned long)devfn) << 8) | offset) #define U3_HT_CFA1(bus, devfn, off) \ (U3_HT_CFA0(devfn, off) \ - + (((unsigned int)bus) << 16) \ + + (((unsigned long)bus) << 16) \ + 0x01000000UL) static unsigned long u3_ht_cfg_access(struct pci_controller* hose, @@ -355,11 +356,9 @@ static unsigned long u3_ht_cfg_access(struct pci_controller* hose, /* For now, we don't self probe U3 HT bridge */ if (PCI_SLOT(devfn) == 0) return 0; - return ((unsigned long)hose->cfg_data) + - U3_HT_CFA0(devfn, offset); + return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset); } else - return ((unsigned long)hose->cfg_data) + - U3_HT_CFA1(bus, devfn, offset); + return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset); } static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, @@ -371,8 +370,7 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, hose = pci_bus_to_host(bus); if (hose == NULL) return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x100) - return PCIBIOS_BAD_REGISTER_NUMBER; + addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); if (!addr) return PCIBIOS_DEVICE_NOT_FOUND; @@ -421,8 +419,7 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, hose = pci_bus_to_host(bus); if (hose == NULL) return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x100) - return PCIBIOS_BAD_REGISTER_NUMBER; + addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); if (!addr) return PCIBIOS_DEVICE_NOT_FOUND; @@ -462,112 +459,6 @@ static struct pci_ops u3_ht_pci_ops = u3_ht_read_config, u3_ht_write_config }; - -#define U4_PCIE_CFA0(devfn, off) \ - ((1 << ((unsigned int)PCI_SLOT(dev_fn))) \ - | (((unsigned int)PCI_FUNC(dev_fn)) << 8) \ - | ((((unsigned int)(off)) >> 8) << 28) \ - | (((unsigned int)(off)) & 0xfcU)) - -#define U4_PCIE_CFA1(bus, devfn, off) \ - ((((unsigned int)(bus)) << 16) \ - |(((unsigned int)(devfn)) << 8) \ - | ((((unsigned int)(off)) >> 8) << 28) \ - |(((unsigned int)(off)) & 0xfcU) \ - |1UL) - -static unsigned long u4_pcie_cfg_access(struct pci_controller* hose, - u8 bus, u8 dev_fn, int offset) -{ - unsigned int caddr; - - if (bus == hose->first_busno) { - caddr = U4_PCIE_CFA0(dev_fn, offset); - } else - caddr = U4_PCIE_CFA1(bus, dev_fn, offset); - - /* Uninorth will return garbage if we don't read back the value ! */ - do { - out_le32(hose->cfg_addr, caddr); - } while (in_le32(hose->cfg_addr) != caddr); - - offset &= 0x03; - return ((unsigned long)hose->cfg_data) + offset; -} - -static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 *val) -{ - struct pci_controller *hose; - unsigned long addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x1000) - return PCIBIOS_BAD_REGISTER_NUMBER; - addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - *val = in_8((u8 *)addr); - break; - case 2: - *val = in_le16((u16 *)addr); - break; - default: - *val = in_le32((u32 *)addr); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn, - int offset, int len, u32 val) -{ - struct pci_controller *hose; - unsigned long addr; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x1000) - return PCIBIOS_BAD_REGISTER_NUMBER; - addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - /* - * Note: the caller has already checked that offset is - * suitably aligned and that len is 1, 2 or 4. - */ - switch (len) { - case 1: - out_8((u8 *)addr, val); - (void) in_8((u8 *)addr); - break; - case 2: - out_le16((u16 *)addr, val); - (void) in_le16((u16 *)addr); - break; - default: - out_le32((u32 *)addr, val); - (void) in_le32((u32 *)addr); - break; - } - return PCIBIOS_SUCCESSFUL; -} - -static struct pci_ops u4_pcie_pci_ops = -{ - u4_pcie_read_config, - u4_pcie_write_config -}; - #endif /* CONFIG_PPC64 */ #ifdef CONFIG_PPC32 @@ -641,8 +532,7 @@ static void __init init_p2pbridge(void) } if (early_read_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, &val) < 0) { - printk(KERN_ERR "init_p2pbridge: couldn't read bridge" - " control\n"); + printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n"); return; } val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; @@ -686,38 +576,36 @@ static void __init fixup_nec_usb2(void) continue; early_read_config_dword(hose, bus, devfn, 0xe4, &data); if (data & 1UL) { - printk("Found NEC PD720100A USB2 chip with disabled" - " EHCI, fixing up...\n"); + printk("Found NEC PD720100A USB2 chip with disabled EHCI, fixing up...\n"); data &= ~1UL; early_write_config_dword(hose, bus, devfn, 0xe4, data); - early_write_config_byte(hose, bus, - devfn | 2, PCI_INTERRUPT_LINE, + early_write_config_byte(hose, bus, devfn | 2, PCI_INTERRUPT_LINE, nec->intrs[0].line); } } } static void __init setup_bandit(struct pci_controller *hose, - struct resource *addr) + struct reg_property *addr) { hose->ops = ¯isc_pci_ops; - hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); - hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000); + hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); init_bandit(hose); } static int __init setup_uninorth(struct pci_controller *hose, - struct resource *addr) + struct reg_property *addr) { pci_assign_all_buses = 1; has_uninorth = 1; hose->ops = ¯isc_pci_ops; - hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); - hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000); + hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); /* We "know" that the bridge at f2000000 has the PCI slots. */ - return addr->start == 0xf2000000; + return addr->address == 0xf2000000; } -#endif /* CONFIG_PPC32 */ +#endif #ifdef CONFIG_PPC64 static void __init setup_u3_agp(struct pci_controller* hose) @@ -737,36 +625,15 @@ static void __init setup_u3_agp(struct pci_controller* hose) hose->ops = ¯isc_pci_ops; hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000); hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000); - u3_agp = hose; -} - -static void __init setup_u4_pcie(struct pci_controller* hose) -{ - /* We currently only implement the "non-atomic" config space, to - * be optimised later. - */ - hose->ops = &u4_pcie_pci_ops; - hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000); - hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000); - /* The bus contains a bridge from root -> device, we need to - * make it visible on bus 0 so that we pick the right type - * of config cycles. If we didn't, we would have to force all - * config cycles to be type 1. So we override the "bus-range" - * property here - */ - hose->first_busno = 0x00; - hose->last_busno = 0xff; - u4_pcie = hose; + u3_agp = hose; } static void __init setup_u3_ht(struct pci_controller* hose) { struct device_node *np = (struct device_node *)hose->arch_data; - struct pci_controller *other = NULL; int i, cur; - hose->ops = &u3_ht_pci_ops; /* We hard code the address because of the different size of @@ -800,20 +667,11 @@ static void __init setup_u3_ht(struct pci_controller* hose) u3_ht = hose; - if (u3_agp != NULL) - other = u3_agp; - else if (u4_pcie != NULL) - other = u4_pcie; - - if (other == NULL) { - DBG("U3/4 has no AGP/PCIE, using full resource range\n"); + if (u3_agp == NULL) { + DBG("U3 has no AGP, using full resource range\n"); return; } - /* Fixup bus range vs. PCIE */ - if (u4_pcie) - hose->last_busno = u4_pcie->first_busno - 1; - /* We "remove" the AGP resources from the resources allocated to HT, * that is we create "holes". However, that code does assumptions * that so far happen to be true (cross fingers...), typically that @@ -821,7 +679,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) */ cur = 0; for (i=0; i<3; i++) { - struct resource *res = &other->mem_resources[i]; + struct resource *res = &u3_agp->mem_resources[i]; if (res->flags != IORESOURCE_MEM) continue; /* We don't care about "fine" resources */ @@ -864,7 +722,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) hose->mem_resources[cur-1].end = res->start - 1; } } -#endif /* CONFIG_PPC64 */ +#endif /* * We assume that if we have a G3 powermac, we have one bridge called @@ -875,17 +733,24 @@ static int __init add_bridge(struct device_node *dev) { int len; struct pci_controller *hose; - struct resource rsrc; +#ifdef CONFIG_PPC32 + struct reg_property *addr; +#endif char *disp_name; int *bus_range; - int primary = 1, has_address = 0; + int primary = 1; DBG("Adding PCI host bridge %s\n", dev->full_name); - /* Fetch host bridge registers address */ - has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); - - /* Get bus range if any */ +#ifdef CONFIG_PPC32 + /* XXX fix this */ + addr = (struct reg_property *) get_property(dev, "reg", &len); + if (addr == NULL || len < sizeof(*addr)) { + printk(KERN_WARNING "Can't use %s: no address\n", + dev->full_name); + return -ENODEV; + } +#endif bus_range = (int *) get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s, assume" @@ -905,8 +770,6 @@ static int __init add_bridge(struct device_node *dev) hose->last_busno = bus_range ? bus_range[1] : 0xff; disp_name = NULL; - - /* 64 bits only bridges */ #ifdef CONFIG_PPC64 if (device_is_compatible(dev, "u3-agp")) { setup_u3_agp(hose); @@ -916,37 +779,28 @@ static int __init add_bridge(struct device_node *dev) setup_u3_ht(hose); disp_name = "U3-HT"; primary = 1; - } else if (device_is_compatible(dev, "u4-pcie")) { - setup_u4_pcie(hose); - disp_name = "U4-PCIE"; - primary = 0; } - printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number:" - " %d->%d\n", disp_name, hose->first_busno, hose->last_busno); -#endif /* CONFIG_PPC64 */ - - /* 32 bits only bridges */ -#ifdef CONFIG_PPC32 + printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number: %d->%d\n", + disp_name, hose->first_busno, hose->last_busno); +#else if (device_is_compatible(dev, "uni-north")) { - primary = setup_uninorth(hose, &rsrc); + primary = setup_uninorth(hose, addr); disp_name = "UniNorth"; } else if (strcmp(dev->name, "pci") == 0) { /* XXX assume this is a mpc106 (grackle) */ setup_grackle(hose); disp_name = "Grackle (MPC106)"; } else if (strcmp(dev->name, "bandit") == 0) { - setup_bandit(hose, &rsrc); + setup_bandit(hose, addr); disp_name = "Bandit"; } else if (strcmp(dev->name, "chaos") == 0) { - setup_chaos(hose, &rsrc); + setup_chaos(hose, addr); disp_name = "Chaos"; primary = 0; } - printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. " - "Firmware bus number: %d->%d\n", - disp_name, rsrc.start, hose->first_busno, hose->last_busno); -#endif /* CONFIG_PPC32 */ - + printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. Firmware bus number: %d->%d\n", + disp_name, addr->address, hose->first_busno, hose->last_busno); +#endif DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", hose, hose->cfg_addr, hose->cfg_data); @@ -960,7 +814,8 @@ static int __init add_bridge(struct device_node *dev) return 0; } -static void __init pcibios_fixup_OF_interrupts(void) +static void __init +pcibios_fixup_OF_interrupts(void) { struct pci_dev* dev = NULL; @@ -980,7 +835,8 @@ static void __init pcibios_fixup_OF_interrupts(void) } } -void __init pmac_pcibios_fixup(void) +void __init +pmac_pcibios_fixup(void) { /* Fixup interrupts according to OF tree */ pcibios_fixup_OF_interrupts(); @@ -1043,8 +899,6 @@ void __init pmac_pci_init(void) pci_setup_phb_io(u3_ht, 1); if (u3_agp) pci_setup_phb_io(u3_agp, 0); - if (u4_pcie) - pci_setup_phb_io(u4_pcie, 0); /* * On ppc64, fixup the IO resources on our host bridges as @@ -1057,8 +911,7 @@ void __init pmac_pci_init(void) /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We * assume there is no P2P bridge on the AGP bus, which should be a - * safe assumptions for now. We should do something better in the - * future though + * safe assumptions hopefully. */ if (u3_agp) { struct device_node *np = u3_agp->arch_data; @@ -1066,6 +919,7 @@ void __init pmac_pci_init(void) for (np = np->child; np; np = np->sibling) PCI_DN(np)->busno = 0xf0; } + /* pmac_check_ht_link(); */ /* Tell pci.c to not use the common resource allocation mechanism */ @@ -1272,8 +1126,7 @@ void pmac_pci_fixup_pciata(struct pci_dev* dev) good: pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); if ((progif & 5) != 5) { - printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n", - pci_name(dev)); + printk(KERN_INFO "Forcing PCI IDE into native mode: %s\n", pci_name(dev)); (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5); if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) || (progif & 5) != 5) @@ -1299,8 +1152,7 @@ static void fixup_k2_sata(struct pci_dev* dev) for (i = 0; i < 6; i++) { dev->resource[i].start = dev->resource[i].end = 0; dev->resource[i].flags = 0; - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, - 0); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0); } } else { pci_read_config_word(dev, PCI_COMMAND, &cmd); @@ -1309,8 +1161,7 @@ static void fixup_k2_sata(struct pci_dev* dev) for (i = 0; i < 5; i++) { dev->resource[i].start = dev->resource[i].end = 0; dev->resource[i].flags = 0; - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, - 0); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, 0); } } } diff --git a/trunk/arch/powerpc/platforms/powermac/pfunc_base.c b/trunk/arch/powerpc/platforms/powermac/pfunc_base.c deleted file mode 100644 index 4ffd2a9832a0..000000000000 --- a/trunk/arch/powerpc/platforms/powermac/pfunc_base.c +++ /dev/null @@ -1,405 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define DBG(fmt...) printk(fmt) - -static irqreturn_t macio_gpio_irq(int irq, void *data, struct pt_regs *regs) -{ - pmf_do_irq(data); - - return IRQ_HANDLED; -} - -static int macio_do_gpio_irq_enable(struct pmf_function *func) -{ - if (func->node->n_intrs < 1) - return -EINVAL; - - return request_irq(func->node->intrs[0].line, macio_gpio_irq, 0, - func->node->name, func); -} - -static int macio_do_gpio_irq_disable(struct pmf_function *func) -{ - if (func->node->n_intrs < 1) - return -EINVAL; - - free_irq(func->node->intrs[0].line, func); - return 0; -} - -static int macio_do_gpio_write(PMF_STD_ARGS, u8 value, u8 mask) -{ - u8 __iomem *addr = (u8 __iomem *)func->driver_data; - unsigned long flags; - u8 tmp; - - /* Check polarity */ - if (args && args->count && !args->u[0].v) - value = ~value; - - /* Toggle the GPIO */ - spin_lock_irqsave(&feature_lock, flags); - tmp = readb(addr); - tmp = (tmp & ~mask) | (value & mask); - DBG("Do write 0x%02x to GPIO %s (%p)\n", - tmp, func->node->full_name, addr); - writeb(tmp, addr); - spin_unlock_irqrestore(&feature_lock, flags); - - return 0; -} - -static int macio_do_gpio_read(PMF_STD_ARGS, u8 mask, int rshift, u8 xor) -{ - u8 __iomem *addr = (u8 __iomem *)func->driver_data; - u32 value; - - /* Check if we have room for reply */ - if (args == NULL || args->count == 0 || args->u[0].p == NULL) - return -EINVAL; - - value = readb(addr); - *args->u[0].p = ((value & mask) >> rshift) ^ xor; - - return 0; -} - -static int macio_do_delay(PMF_STD_ARGS, u32 duration) -{ - /* assume we can sleep ! */ - msleep((duration + 999) / 1000); - return 0; -} - -static struct pmf_handlers macio_gpio_handlers = { - .irq_enable = macio_do_gpio_irq_enable, - .irq_disable = macio_do_gpio_irq_disable, - .write_gpio = macio_do_gpio_write, - .read_gpio = macio_do_gpio_read, - .delay = macio_do_delay, -}; - -static void macio_gpio_init_one(struct macio_chip *macio) -{ - struct device_node *gparent, *gp; - - /* - * Find the "gpio" parent node - */ - - for (gparent = NULL; - (gparent = of_get_next_child(macio->of_node, gparent)) != NULL;) - if (strcmp(gparent->name, "gpio") == 0) - break; - if (gparent == NULL) - return; - - DBG("Installing GPIO functions for macio %s\n", - macio->of_node->full_name); - - /* - * Ok, got one, we dont need anything special to track them down, so - * we just create them all - */ - for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;) { - u32 *reg = (u32 *)get_property(gp, "reg", NULL); - unsigned long offset; - if (reg == NULL) - continue; - offset = *reg; - /* Deal with old style device-tree. We can safely hard code the - * offset for now too even if it's a bit gross ... - */ - if (offset < 0x50) - offset += 0x50; - offset += (unsigned long)macio->base; - pmf_register_driver(gp, &macio_gpio_handlers, (void *)offset); - } - - DBG("Calling initial GPIO functions for macio %s\n", - macio->of_node->full_name); - - /* And now we run all the init ones */ - for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;) - pmf_do_functions(gp, NULL, 0, PMF_FLAGS_ON_INIT, NULL); - - /* Note: We do not at this point implement the "at sleep" or "at wake" - * functions. I yet to find any for GPIOs anyway - */ -} - -static int macio_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask) -{ - struct macio_chip *macio = func->driver_data; - unsigned long flags; - - spin_lock_irqsave(&feature_lock, flags); - MACIO_OUT32(offset, (MACIO_IN32(offset) & ~mask) | (value & mask)); - spin_unlock_irqrestore(&feature_lock, flags); - return 0; -} - -static int macio_do_read_reg32(PMF_STD_ARGS, u32 offset) -{ - struct macio_chip *macio = func->driver_data; - - /* Check if we have room for reply */ - if (args == NULL || args->count == 0 || args->u[0].p == NULL) - return -EINVAL; - - *args->u[0].p = MACIO_IN32(offset); - return 0; -} - -static int macio_do_write_reg8(PMF_STD_ARGS, u32 offset, u8 value, u8 mask) -{ - struct macio_chip *macio = func->driver_data; - unsigned long flags; - - spin_lock_irqsave(&feature_lock, flags); - MACIO_OUT8(offset, (MACIO_IN8(offset) & ~mask) | (value & mask)); - spin_unlock_irqrestore(&feature_lock, flags); - return 0; -} - -static int macio_do_read_reg8(PMF_STD_ARGS, u32 offset) -{ - struct macio_chip *macio = func->driver_data; - - /* Check if we have room for reply */ - if (args == NULL || args->count == 0 || args->u[0].p == NULL) - return -EINVAL; - - *((u8 *)(args->u[0].p)) = MACIO_IN8(offset); - return 0; -} - -static int macio_do_read_reg32_msrx(PMF_STD_ARGS, u32 offset, u32 mask, - u32 shift, u32 xor) -{ - struct macio_chip *macio = func->driver_data; - - /* Check if we have room for reply */ - if (args == NULL || args->count == 0 || args->u[0].p == NULL) - return -EINVAL; - - *args->u[0].p = ((MACIO_IN32(offset) & mask) >> shift) ^ xor; - return 0; -} - -static int macio_do_read_reg8_msrx(PMF_STD_ARGS, u32 offset, u32 mask, - u32 shift, u32 xor) -{ - struct macio_chip *macio = func->driver_data; - - /* Check if we have room for reply */ - if (args == NULL || args->count == 0 || args->u[0].p == NULL) - return -EINVAL; - - *((u8 *)(args->u[0].p)) = ((MACIO_IN8(offset) & mask) >> shift) ^ xor; - return 0; -} - -static int macio_do_write_reg32_slm(PMF_STD_ARGS, u32 offset, u32 shift, - u32 mask) -{ - struct macio_chip *macio = func->driver_data; - unsigned long flags; - u32 tmp, val; - - /* Check args */ - if (args == NULL || args->count == 0) - return -EINVAL; - - spin_lock_irqsave(&feature_lock, flags); - tmp = MACIO_IN32(offset); - val = args->u[0].v << shift; - tmp = (tmp & ~mask) | (val & mask); - MACIO_OUT32(offset, tmp); - spin_unlock_irqrestore(&feature_lock, flags); - return 0; -} - -static int macio_do_write_reg8_slm(PMF_STD_ARGS, u32 offset, u32 shift, - u32 mask) -{ - struct macio_chip *macio = func->driver_data; - unsigned long flags; - u32 tmp, val; - - /* Check args */ - if (args == NULL || args->count == 0) - return -EINVAL; - - spin_lock_irqsave(&feature_lock, flags); - tmp = MACIO_IN8(offset); - val = args->u[0].v << shift; - tmp = (tmp & ~mask) | (val & mask); - MACIO_OUT8(offset, tmp); - spin_unlock_irqrestore(&feature_lock, flags); - return 0; -} - -static struct pmf_handlers macio_mmio_handlers = { - .write_reg32 = macio_do_write_reg32, - .read_reg32 = macio_do_read_reg32, - .write_reg8 = macio_do_write_reg8, - .read_reg32 = macio_do_read_reg8, - .read_reg32_msrx = macio_do_read_reg32_msrx, - .read_reg8_msrx = macio_do_read_reg8_msrx, - .write_reg32_slm = macio_do_write_reg32_slm, - .write_reg8_slm = macio_do_write_reg8_slm, - .delay = macio_do_delay, -}; - -static void macio_mmio_init_one(struct macio_chip *macio) -{ - DBG("Installing MMIO functions for macio %s\n", - macio->of_node->full_name); - - pmf_register_driver(macio->of_node, &macio_mmio_handlers, macio); -} - -static struct device_node *unin_hwclock; - -static int unin_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask) -{ - unsigned long flags; - - spin_lock_irqsave(&feature_lock, flags); - /* This is fairly bogus in darwin, but it should work for our needs - * implemeted that way: - */ - UN_OUT(offset, (UN_IN(offset) & ~mask) | (value & mask)); - spin_unlock_irqrestore(&feature_lock, flags); - return 0; -} - - -static struct pmf_handlers unin_mmio_handlers = { - .write_reg32 = unin_do_write_reg32, - .delay = macio_do_delay, -}; - -static void uninorth_install_pfunc(void) -{ - struct device_node *np; - - DBG("Installing functions for UniN %s\n", - uninorth_node->full_name); - - /* - * Install handlers for the bridge itself - */ - pmf_register_driver(uninorth_node, &unin_mmio_handlers, NULL); - pmf_do_functions(uninorth_node, NULL, 0, PMF_FLAGS_ON_INIT, NULL); - - - /* - * Install handlers for the hwclock child if any - */ - for (np = NULL; (np = of_get_next_child(uninorth_node, np)) != NULL;) - if (strcmp(np->name, "hw-clock") == 0) { - unin_hwclock = np; - break; - } - if (unin_hwclock) { - DBG("Installing functions for UniN clock %s\n", - unin_hwclock->full_name); - pmf_register_driver(unin_hwclock, &unin_mmio_handlers, NULL); - pmf_do_functions(unin_hwclock, NULL, 0, PMF_FLAGS_ON_INIT, - NULL); - } -} - -/* We export this as the SMP code might init us early */ -int __init pmac_pfunc_base_install(void) -{ - static int pfbase_inited; - int i; - - if (pfbase_inited) - return 0; - pfbase_inited = 1; - - - DBG("Installing base platform functions...\n"); - - /* - * Locate mac-io chips and install handlers - */ - for (i = 0 ; i < MAX_MACIO_CHIPS; i++) { - if (macio_chips[i].of_node) { - macio_mmio_init_one(&macio_chips[i]); - macio_gpio_init_one(&macio_chips[i]); - } - } - - /* - * Install handlers for northbridge and direct mapped hwclock - * if any. We do not implement the config space access callback - * which is only ever used for functions that we do not call in - * the current driver (enabling/disabling cells in U2, mostly used - * to restore the PCI settings, we do that differently) - */ - if (uninorth_node && uninorth_base) - uninorth_install_pfunc(); - - DBG("All base functions installed\n"); - - return 0; -} - -arch_initcall(pmac_pfunc_base_install); - -#ifdef CONFIG_PM - -/* Those can be called by pmac_feature. Ultimately, I should use a sysdev - * or a device, but for now, that's good enough until I sort out some - * ordering issues. Also, we do not bother with GPIOs, as so far I yet have - * to see a case where a GPIO function has the on-suspend or on-resume bit - */ -void pmac_pfunc_base_suspend(void) -{ - int i; - - for (i = 0 ; i < MAX_MACIO_CHIPS; i++) { - if (macio_chips[i].of_node) - pmf_do_functions(macio_chips[i].of_node, NULL, 0, - PMF_FLAGS_ON_SLEEP, NULL); - } - if (uninorth_node) - pmf_do_functions(uninorth_node, NULL, 0, - PMF_FLAGS_ON_SLEEP, NULL); - if (unin_hwclock) - pmf_do_functions(unin_hwclock, NULL, 0, - PMF_FLAGS_ON_SLEEP, NULL); -} - -void pmac_pfunc_base_resume(void) -{ - int i; - - if (unin_hwclock) - pmf_do_functions(unin_hwclock, NULL, 0, - PMF_FLAGS_ON_WAKE, NULL); - if (uninorth_node) - pmf_do_functions(uninorth_node, NULL, 0, - PMF_FLAGS_ON_WAKE, NULL); - for (i = 0 ; i < MAX_MACIO_CHIPS; i++) { - if (macio_chips[i].of_node) - pmf_do_functions(macio_chips[i].of_node, NULL, 0, - PMF_FLAGS_ON_WAKE, NULL); - } -} - -#endif /* CONFIG_PM */ diff --git a/trunk/arch/powerpc/platforms/powermac/pfunc_core.c b/trunk/arch/powerpc/platforms/powermac/pfunc_core.c deleted file mode 100644 index c32c623001dc..000000000000 --- a/trunk/arch/powerpc/platforms/powermac/pfunc_core.c +++ /dev/null @@ -1,989 +0,0 @@ -/* - * - * FIXME: Properly make this race free with refcounting etc... - * - * FIXME: LOCKING !!! - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* Debug */ -#define LOG_PARSE(fmt...) -#define LOG_ERROR(fmt...) printk(fmt) -#define LOG_BLOB(t,b,c) -#define DBG(fmt...) printk(fmt) - -/* Command numbers */ -#define PMF_CMD_LIST 0 -#define PMF_CMD_WRITE_GPIO 1 -#define PMF_CMD_READ_GPIO 2 -#define PMF_CMD_WRITE_REG32 3 -#define PMF_CMD_READ_REG32 4 -#define PMF_CMD_WRITE_REG16 5 -#define PMF_CMD_READ_REG16 6 -#define PMF_CMD_WRITE_REG8 7 -#define PMF_CMD_READ_REG8 8 -#define PMF_CMD_DELAY 9 -#define PMF_CMD_WAIT_REG32 10 -#define PMF_CMD_WAIT_REG16 11 -#define PMF_CMD_WAIT_REG8 12 -#define PMF_CMD_READ_I2C 13 -#define PMF_CMD_WRITE_I2C 14 -#define PMF_CMD_RMW_I2C 15 -#define PMF_CMD_GEN_I2C 16 -#define PMF_CMD_SHIFT_BYTES_RIGHT 17 -#define PMF_CMD_SHIFT_BYTES_LEFT 18 -#define PMF_CMD_READ_CFG 19 -#define PMF_CMD_WRITE_CFG 20 -#define PMF_CMD_RMW_CFG 21 -#define PMF_CMD_READ_I2C_SUBADDR 22 -#define PMF_CMD_WRITE_I2C_SUBADDR 23 -#define PMF_CMD_SET_I2C_MODE 24 -#define PMF_CMD_RMW_I2C_SUBADDR 25 -#define PMF_CMD_READ_REG32_MASK_SHR_XOR 26 -#define PMF_CMD_READ_REG16_MASK_SHR_XOR 27 -#define PMF_CMD_READ_REG8_MASK_SHR_XOR 28 -#define PMF_CMD_WRITE_REG32_SHL_MASK 29 -#define PMF_CMD_WRITE_REG16_SHL_MASK 30 -#define PMF_CMD_WRITE_REG8_SHL_MASK 31 -#define PMF_CMD_MASK_AND_COMPARE 32 -#define PMF_CMD_COUNT 33 - -/* This structure holds the state of the parser while walking through - * a function definition - */ -struct pmf_cmd { - const void *cmdptr; - const void *cmdend; - struct pmf_function *func; - void *instdata; - struct pmf_args *args; - int error; -}; - -#if 0 -/* Debug output */ -static void print_blob(const char *title, const void *blob, int bytes) -{ - printk("%s", title); - while(bytes--) { - printk("%02x ", *((u8 *)blob)); - blob += 1; - } - printk("\n"); -} -#endif - -/* - * Parser helpers - */ - -static u32 pmf_next32(struct pmf_cmd *cmd) -{ - u32 value; - if ((cmd->cmdend - cmd->cmdptr) < 4) { - cmd->error = 1; - return 0; - } - value = *((u32 *)cmd->cmdptr); - cmd->cmdptr += 4; - return value; -} - -static const void* pmf_next_blob(struct pmf_cmd *cmd, int count) -{ - const void *value; - if ((cmd->cmdend - cmd->cmdptr) < count) { - cmd->error = 1; - return NULL; - } - value = cmd->cmdptr; - cmd->cmdptr += count; - return value; -} - -/* - * Individual command parsers - */ - -#define PMF_PARSE_CALL(name, cmd, handlers, p...) \ - do { \ - if (cmd->error) \ - return -ENXIO; \ - if (handlers == NULL) \ - return 0; \ - if (handlers->name) \ - return handlers->name(cmd->func, cmd->instdata, \ - cmd->args, p); \ - return -1; \ - } while(0) \ - - -static int pmf_parser_write_gpio(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u8 value = (u8)pmf_next32(cmd); - u8 mask = (u8)pmf_next32(cmd); - - LOG_PARSE("pmf: write_gpio(value: %02x, mask: %02x)\n", value, mask); - - PMF_PARSE_CALL(write_gpio, cmd, h, value, mask); -} - -static int pmf_parser_read_gpio(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u8 mask = (u8)pmf_next32(cmd); - int rshift = (int)pmf_next32(cmd); - u8 xor = (u8)pmf_next32(cmd); - - LOG_PARSE("pmf: read_gpio(mask: %02x, rshift: %d, xor: %02x)\n", - mask, rshift, xor); - - PMF_PARSE_CALL(read_gpio, cmd, h, mask, rshift, xor); -} - -static int pmf_parser_write_reg32(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u32 value = pmf_next32(cmd); - u32 mask = pmf_next32(cmd); - - LOG_PARSE("pmf: write_reg32(offset: %08x, value: %08x, mask: %08x)\n", - offset, value, mask); - - PMF_PARSE_CALL(write_reg32, cmd, h, offset, value, mask); -} - -static int pmf_parser_read_reg32(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - - LOG_PARSE("pmf: read_reg32(offset: %08x)\n", offset); - - PMF_PARSE_CALL(read_reg32, cmd, h, offset); -} - - -static int pmf_parser_write_reg16(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u16 value = (u16)pmf_next32(cmd); - u16 mask = (u16)pmf_next32(cmd); - - LOG_PARSE("pmf: write_reg16(offset: %08x, value: %04x, mask: %04x)\n", - offset, value, mask); - - PMF_PARSE_CALL(write_reg16, cmd, h, offset, value, mask); -} - -static int pmf_parser_read_reg16(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - - LOG_PARSE("pmf: read_reg16(offset: %08x)\n", offset); - - PMF_PARSE_CALL(read_reg16, cmd, h, offset); -} - - -static int pmf_parser_write_reg8(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u8 value = (u16)pmf_next32(cmd); - u8 mask = (u16)pmf_next32(cmd); - - LOG_PARSE("pmf: write_reg8(offset: %08x, value: %02x, mask: %02x)\n", - offset, value, mask); - - PMF_PARSE_CALL(write_reg8, cmd, h, offset, value, mask); -} - -static int pmf_parser_read_reg8(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - - LOG_PARSE("pmf: read_reg8(offset: %08x)\n", offset); - - PMF_PARSE_CALL(read_reg8, cmd, h, offset); -} - -static int pmf_parser_delay(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 duration = pmf_next32(cmd); - - LOG_PARSE("pmf: delay(duration: %d us)\n", duration); - - PMF_PARSE_CALL(delay, cmd, h, duration); -} - -static int pmf_parser_wait_reg32(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u32 value = pmf_next32(cmd); - u32 mask = pmf_next32(cmd); - - LOG_PARSE("pmf: wait_reg32(offset: %08x, comp_value: %08x,mask: %08x)\n", - offset, value, mask); - - PMF_PARSE_CALL(wait_reg32, cmd, h, offset, value, mask); -} - -static int pmf_parser_wait_reg16(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u16 value = (u16)pmf_next32(cmd); - u16 mask = (u16)pmf_next32(cmd); - - LOG_PARSE("pmf: wait_reg16(offset: %08x, comp_value: %04x,mask: %04x)\n", - offset, value, mask); - - PMF_PARSE_CALL(wait_reg16, cmd, h, offset, value, mask); -} - -static int pmf_parser_wait_reg8(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u8 value = (u8)pmf_next32(cmd); - u8 mask = (u8)pmf_next32(cmd); - - LOG_PARSE("pmf: wait_reg8(offset: %08x, comp_value: %02x,mask: %02x)\n", - offset, value, mask); - - PMF_PARSE_CALL(wait_reg8, cmd, h, offset, value, mask); -} - -static int pmf_parser_read_i2c(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 bytes = pmf_next32(cmd); - - LOG_PARSE("pmf: read_i2c(bytes: %ud)\n", bytes); - - PMF_PARSE_CALL(read_i2c, cmd, h, bytes); -} - -static int pmf_parser_write_i2c(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 bytes = pmf_next32(cmd); - const void *blob = pmf_next_blob(cmd, bytes); - - LOG_PARSE("pmf: write_i2c(bytes: %ud) ...\n", bytes); - LOG_BLOB("pmf: data: \n", blob, bytes); - - PMF_PARSE_CALL(write_i2c, cmd, h, bytes, blob); -} - - -static int pmf_parser_rmw_i2c(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 maskbytes = pmf_next32(cmd); - u32 valuesbytes = pmf_next32(cmd); - u32 totalbytes = pmf_next32(cmd); - const void *maskblob = pmf_next_blob(cmd, maskbytes); - const void *valuesblob = pmf_next_blob(cmd, valuesbytes); - - LOG_PARSE("pmf: rmw_i2c(maskbytes: %ud, valuebytes: %ud, " - "totalbytes: %d) ...\n", - maskbytes, valuesbytes, totalbytes); - LOG_BLOB("pmf: mask data: \n", maskblob, maskbytes); - LOG_BLOB("pmf: values data: \n", valuesblob, valuesbytes); - - PMF_PARSE_CALL(rmw_i2c, cmd, h, maskbytes, valuesbytes, totalbytes, - maskblob, valuesblob); -} - -static int pmf_parser_read_cfg(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u32 bytes = pmf_next32(cmd); - - LOG_PARSE("pmf: read_cfg(offset: %x, bytes: %ud)\n", offset, bytes); - - PMF_PARSE_CALL(read_cfg, cmd, h, offset, bytes); -} - - -static int pmf_parser_write_cfg(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u32 bytes = pmf_next32(cmd); - const void *blob = pmf_next_blob(cmd, bytes); - - LOG_PARSE("pmf: write_cfg(offset: %x, bytes: %ud)\n", offset, bytes); - LOG_BLOB("pmf: data: \n", blob, bytes); - - PMF_PARSE_CALL(write_cfg, cmd, h, offset, bytes, blob); -} - -static int pmf_parser_rmw_cfg(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u32 maskbytes = pmf_next32(cmd); - u32 valuesbytes = pmf_next32(cmd); - u32 totalbytes = pmf_next32(cmd); - const void *maskblob = pmf_next_blob(cmd, maskbytes); - const void *valuesblob = pmf_next_blob(cmd, valuesbytes); - - LOG_PARSE("pmf: rmw_cfg(maskbytes: %ud, valuebytes: %ud," - " totalbytes: %d) ...\n", - maskbytes, valuesbytes, totalbytes); - LOG_BLOB("pmf: mask data: \n", maskblob, maskbytes); - LOG_BLOB("pmf: values data: \n", valuesblob, valuesbytes); - - PMF_PARSE_CALL(rmw_cfg, cmd, h, offset, maskbytes, valuesbytes, - totalbytes, maskblob, valuesblob); -} - - -static int pmf_parser_read_i2c_sub(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u8 subaddr = (u8)pmf_next32(cmd); - u32 bytes = pmf_next32(cmd); - - LOG_PARSE("pmf: read_i2c_sub(subaddr: %x, bytes: %ud)\n", - subaddr, bytes); - - PMF_PARSE_CALL(read_i2c_sub, cmd, h, subaddr, bytes); -} - -static int pmf_parser_write_i2c_sub(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u8 subaddr = (u8)pmf_next32(cmd); - u32 bytes = pmf_next32(cmd); - const void *blob = pmf_next_blob(cmd, bytes); - - LOG_PARSE("pmf: write_i2c_sub(subaddr: %x, bytes: %ud) ...\n", - subaddr, bytes); - LOG_BLOB("pmf: data: \n", blob, bytes); - - PMF_PARSE_CALL(write_i2c_sub, cmd, h, subaddr, bytes, blob); -} - -static int pmf_parser_set_i2c_mode(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u32 mode = pmf_next32(cmd); - - LOG_PARSE("pmf: set_i2c_mode(mode: %d)\n", mode); - - PMF_PARSE_CALL(set_i2c_mode, cmd, h, mode); -} - - -static int pmf_parser_rmw_i2c_sub(struct pmf_cmd *cmd, struct pmf_handlers *h) -{ - u8 subaddr = (u8)pmf_next32(cmd); - u32 maskbytes = pmf_next32(cmd); - u32 valuesbytes = pmf_next32(cmd); - u32 totalbytes = pmf_next32(cmd); - const void *maskblob = pmf_next_blob(cmd, maskbytes); - const void *valuesblob = pmf_next_blob(cmd, valuesbytes); - - LOG_PARSE("pmf: rmw_i2c_sub(subaddr: %x, maskbytes: %ud, valuebytes: %ud" - ", totalbytes: %d) ...\n", - subaddr, maskbytes, valuesbytes, totalbytes); - LOG_BLOB("pmf: mask data: \n", maskblob, maskbytes); - LOG_BLOB("pmf: values data: \n", valuesblob, valuesbytes); - - PMF_PARSE_CALL(rmw_i2c_sub, cmd, h, subaddr, maskbytes, valuesbytes, - totalbytes, maskblob, valuesblob); -} - -static int pmf_parser_read_reg32_msrx(struct pmf_cmd *cmd, - struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u32 mask = pmf_next32(cmd); - u32 shift = pmf_next32(cmd); - u32 xor = pmf_next32(cmd); - - LOG_PARSE("pmf: read_reg32_msrx(offset: %x, mask: %x, shift: %x," - " xor: %x\n", offset, mask, shift, xor); - - PMF_PARSE_CALL(read_reg32_msrx, cmd, h, offset, mask, shift, xor); -} - -static int pmf_parser_read_reg16_msrx(struct pmf_cmd *cmd, - struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u32 mask = pmf_next32(cmd); - u32 shift = pmf_next32(cmd); - u32 xor = pmf_next32(cmd); - - LOG_PARSE("pmf: read_reg16_msrx(offset: %x, mask: %x, shift: %x," - " xor: %x\n", offset, mask, shift, xor); - - PMF_PARSE_CALL(read_reg16_msrx, cmd, h, offset, mask, shift, xor); -} -static int pmf_parser_read_reg8_msrx(struct pmf_cmd *cmd, - struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u32 mask = pmf_next32(cmd); - u32 shift = pmf_next32(cmd); - u32 xor = pmf_next32(cmd); - - LOG_PARSE("pmf: read_reg8_msrx(offset: %x, mask: %x, shift: %x," - " xor: %x\n", offset, mask, shift, xor); - - PMF_PARSE_CALL(read_reg8_msrx, cmd, h, offset, mask, shift, xor); -} - -static int pmf_parser_write_reg32_slm(struct pmf_cmd *cmd, - struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u32 shift = pmf_next32(cmd); - u32 mask = pmf_next32(cmd); - - LOG_PARSE("pmf: write_reg32_slm(offset: %x, shift: %x, mask: %x\n", - offset, shift, mask); - - PMF_PARSE_CALL(write_reg32_slm, cmd, h, offset, shift, mask); -} - -static int pmf_parser_write_reg16_slm(struct pmf_cmd *cmd, - struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u32 shift = pmf_next32(cmd); - u32 mask = pmf_next32(cmd); - - LOG_PARSE("pmf: write_reg16_slm(offset: %x, shift: %x, mask: %x\n", - offset, shift, mask); - - PMF_PARSE_CALL(write_reg16_slm, cmd, h, offset, shift, mask); -} - -static int pmf_parser_write_reg8_slm(struct pmf_cmd *cmd, - struct pmf_handlers *h) -{ - u32 offset = pmf_next32(cmd); - u32 shift = pmf_next32(cmd); - u32 mask = pmf_next32(cmd); - - LOG_PARSE("pmf: write_reg8_slm(offset: %x, shift: %x, mask: %x\n", - offset, shift, mask); - - PMF_PARSE_CALL(write_reg8_slm, cmd, h, offset, shift, mask); -} - -static int pmf_parser_mask_and_compare(struct pmf_cmd *cmd, - struct pmf_handlers *h) -{ - u32 bytes = pmf_next32(cmd); - const void *maskblob = pmf_next_blob(cmd, bytes); - const void *valuesblob = pmf_next_blob(cmd, bytes); - - LOG_PARSE("pmf: mask_and_compare(length: %ud ...\n", bytes); - LOG_BLOB("pmf: mask data: \n", maskblob, bytes); - LOG_BLOB("pmf: values data: \n", valuesblob, bytes); - - PMF_PARSE_CALL(mask_and_compare, cmd, h, - bytes, maskblob, valuesblob); -} - - -typedef int (*pmf_cmd_parser_t)(struct pmf_cmd *cmd, struct pmf_handlers *h); - -static pmf_cmd_parser_t pmf_parsers[PMF_CMD_COUNT] = -{ - NULL, - pmf_parser_write_gpio, - pmf_parser_read_gpio, - pmf_parser_write_reg32, - pmf_parser_read_reg32, - pmf_parser_write_reg16, - pmf_parser_read_reg16, - pmf_parser_write_reg8, - pmf_parser_read_reg8, - pmf_parser_delay, - pmf_parser_wait_reg32, - pmf_parser_wait_reg16, - pmf_parser_wait_reg8, - pmf_parser_read_i2c, - pmf_parser_write_i2c, - pmf_parser_rmw_i2c, - NULL, /* Bogus command */ - NULL, /* Shift bytes right: NYI */ - NULL, /* Shift bytes left: NYI */ - pmf_parser_read_cfg, - pmf_parser_write_cfg, - pmf_parser_rmw_cfg, - pmf_parser_read_i2c_sub, - pmf_parser_write_i2c_sub, - pmf_parser_set_i2c_mode, - pmf_parser_rmw_i2c_sub, - pmf_parser_read_reg32_msrx, - pmf_parser_read_reg16_msrx, - pmf_parser_read_reg8_msrx, - pmf_parser_write_reg32_slm, - pmf_parser_write_reg16_slm, - pmf_parser_write_reg8_slm, - pmf_parser_mask_and_compare, -}; - -struct pmf_device { - struct list_head link; - struct device_node *node; - struct pmf_handlers *handlers; - struct list_head functions; - struct kref ref; -}; - -static LIST_HEAD(pmf_devices); -static spinlock_t pmf_lock = SPIN_LOCK_UNLOCKED; - -static void pmf_release_device(struct kref *kref) -{ - struct pmf_device *dev = container_of(kref, struct pmf_device, ref); - kfree(dev); -} - -static inline void pmf_put_device(struct pmf_device *dev) -{ - kref_put(&dev->ref, pmf_release_device); -} - -static inline struct pmf_device *pmf_get_device(struct pmf_device *dev) -{ - kref_get(&dev->ref); - return dev; -} - -static inline struct pmf_device *pmf_find_device(struct device_node *np) -{ - struct pmf_device *dev; - - list_for_each_entry(dev, &pmf_devices, link) { - if (dev->node == np) - return pmf_get_device(dev); - } - return NULL; -} - -static int pmf_parse_one(struct pmf_function *func, - struct pmf_handlers *handlers, - void *instdata, struct pmf_args *args) -{ - struct pmf_cmd cmd; - u32 ccode; - int count, rc; - - cmd.cmdptr = func->data; - cmd.cmdend = func->data + func->length; - cmd.func = func; - cmd.instdata = instdata; - cmd.args = args; - cmd.error = 0; - - LOG_PARSE("pmf: func %s, %d bytes, %s...\n", - func->name, func->length, - handlers ? "executing" : "parsing"); - - /* One subcommand to parse for now */ - count = 1; - - while(count-- && cmd.cmdptr < cmd.cmdend) { - /* Get opcode */ - ccode = pmf_next32(&cmd); - /* Check if we are hitting a command list, fetch new count */ - if (ccode == 0) { - count = pmf_next32(&cmd) - 1; - ccode = pmf_next32(&cmd); - } - if (cmd.error) { - LOG_ERROR("pmf: parse error, not enough data\n"); - return -ENXIO; - } - if (ccode >= PMF_CMD_COUNT) { - LOG_ERROR("pmf: command code %d unknown !\n", ccode); - return -ENXIO; - } - if (pmf_parsers[ccode] == NULL) { - LOG_ERROR("pmf: no parser for command %d !\n", ccode); - return -ENXIO; - } - rc = pmf_parsers[ccode](&cmd, handlers); - if (rc != 0) { - LOG_ERROR("pmf: parser for command %d returned" - " error %d\n", ccode, rc); - return rc; - } - } - - /* We are doing an initial parse pass, we need to adjust the size */ - if (handlers == NULL) - func->length = cmd.cmdptr - func->data; - - return 0; -} - -static int pmf_add_function_prop(struct pmf_device *dev, void *driverdata, - const char *name, u32 *data, - unsigned int length) -{ - int count = 0; - struct pmf_function *func = NULL; - - DBG("pmf: Adding functions for platform-do-%s\n", name); - - while (length >= 12) { - /* Allocate a structure */ - func = kzalloc(sizeof(struct pmf_function), GFP_KERNEL); - if (func == NULL) - goto bail; - kref_init(&func->ref); - INIT_LIST_HEAD(&func->irq_clients); - func->node = dev->node; - func->driver_data = driverdata; - func->name = name; - func->phandle = data[0]; - func->flags = data[1]; - data += 2; - length -= 8; - func->data = data; - func->length = length; - func->dev = dev; - DBG("pmf: idx %d: flags=%08x, phandle=%08x " - " %d bytes remaining, parsing...\n", - count+1, func->flags, func->phandle, length); - if (pmf_parse_one(func, NULL, NULL, NULL)) { - kfree(func); - goto bail; - } - length -= func->length; - data = (u32 *)(((u8 *)data) + func->length); - list_add(&func->link, &dev->functions); - pmf_get_device(dev); - count++; - } - bail: - DBG("pmf: Added %d functions\n", count); - - return count; -} - -static int pmf_add_functions(struct pmf_device *dev, void *driverdata) -{ - struct property *pp; -#define PP_PREFIX "platform-do-" - const int plen = strlen(PP_PREFIX); - int count = 0; - - for (pp = dev->node->properties; pp != 0; pp = pp->next) { - char *name; - if (strncmp(pp->name, PP_PREFIX, plen) != 0) - continue; - name = pp->name + plen; - if (strlen(name) && pp->length >= 12) - count += pmf_add_function_prop(dev, driverdata, name, - (u32 *)pp->value, - pp->length); - } - return count; -} - - -int pmf_register_driver(struct device_node *np, - struct pmf_handlers *handlers, - void *driverdata) -{ - struct pmf_device *dev; - unsigned long flags; - int rc = 0; - - if (handlers == NULL) - return -EINVAL; - - DBG("pmf: registering driver for node %s\n", np->full_name); - - spin_lock_irqsave(&pmf_lock, flags); - dev = pmf_find_device(np); - spin_unlock_irqrestore(&pmf_lock, flags); - if (dev != NULL) { - DBG("pmf: already there !\n"); - pmf_put_device(dev); - return -EBUSY; - } - - dev = kzalloc(sizeof(struct pmf_device), GFP_KERNEL); - if (dev == NULL) { - DBG("pmf: no memory !\n"); - return -ENOMEM; - } - kref_init(&dev->ref); - dev->node = of_node_get(np); - dev->handlers = handlers; - INIT_LIST_HEAD(&dev->functions); - - rc = pmf_add_functions(dev, driverdata); - if (rc == 0) { - DBG("pmf: no functions, disposing.. \n"); - of_node_put(np); - kfree(dev); - return -ENODEV; - } - - spin_lock_irqsave(&pmf_lock, flags); - list_add(&dev->link, &pmf_devices); - spin_unlock_irqrestore(&pmf_lock, flags); - - return 0; -} -EXPORT_SYMBOL_GPL(pmf_register_driver); - -struct pmf_function *pmf_get_function(struct pmf_function *func) -{ - if (!try_module_get(func->dev->handlers->owner)) - return NULL; - kref_get(&func->ref); - return func; -} -EXPORT_SYMBOL_GPL(pmf_get_function); - -static void pmf_release_function(struct kref *kref) -{ - struct pmf_function *func = - container_of(kref, struct pmf_function, ref); - pmf_put_device(func->dev); - kfree(func); -} - -static inline void __pmf_put_function(struct pmf_function *func) -{ - kref_put(&func->ref, pmf_release_function); -} - -void pmf_put_function(struct pmf_function *func) -{ - if (func == NULL) - return; - module_put(func->dev->handlers->owner); - __pmf_put_function(func); -} -EXPORT_SYMBOL_GPL(pmf_put_function); - -void pmf_unregister_driver(struct device_node *np) -{ - struct pmf_device *dev; - unsigned long flags; - - DBG("pmf: unregistering driver for node %s\n", np->full_name); - - spin_lock_irqsave(&pmf_lock, flags); - dev = pmf_find_device(np); - if (dev == NULL) { - DBG("pmf: not such driver !\n"); - spin_unlock_irqrestore(&pmf_lock, flags); - return; - } - list_del(&dev->link); - - while(!list_empty(&dev->functions)) { - struct pmf_function *func = - list_entry(dev->functions.next, typeof(*func), link); - list_del(&func->link); - __pmf_put_function(func); - } - - pmf_put_device(dev); - spin_unlock_irqrestore(&pmf_lock, flags); -} -EXPORT_SYMBOL_GPL(pmf_unregister_driver); - -struct pmf_function *__pmf_find_function(struct device_node *target, - const char *name, u32 flags) -{ - struct device_node *actor = of_node_get(target); - struct pmf_device *dev; - struct pmf_function *func, *result = NULL; - char fname[64]; - u32 *prop, ph; - - /* - * Look for a "platform-*" function reference. If we can't find - * one, then we fallback to a direct call attempt - */ - snprintf(fname, 63, "platform-%s", name); - prop = (u32 *)get_property(target, fname, NULL); - if (prop == NULL) - goto find_it; - ph = *prop; - if (ph == 0) - goto find_it; - - /* - * Ok, now try to find the actor. If we can't find it, we fail, - * there is no point in falling back there - */ - of_node_put(actor); - actor = of_find_node_by_phandle(ph); - if (actor == NULL) - return NULL; - find_it: - dev = pmf_find_device(actor); - if (dev == NULL) - return NULL; - - list_for_each_entry(func, &dev->functions, link) { - if (name && strcmp(name, func->name)) - continue; - if (func->phandle && target->node != func->phandle) - continue; - if ((func->flags & flags) == 0) - continue; - result = func; - break; - } - of_node_put(actor); - pmf_put_device(dev); - return result; -} - - -int pmf_register_irq_client(struct device_node *target, - const char *name, - struct pmf_irq_client *client) -{ - struct pmf_function *func; - unsigned long flags; - - spin_lock_irqsave(&pmf_lock, flags); - func = __pmf_find_function(target, name, PMF_FLAGS_INT_GEN); - if (func == NULL) { - spin_unlock_irqrestore(&pmf_lock, flags); - return -ENODEV; - } - list_add(&client->link, &func->irq_clients); - spin_unlock_irqrestore(&pmf_lock, flags); - - return 0; -} -EXPORT_SYMBOL_GPL(pmf_register_irq_client); - -void pmf_unregister_irq_client(struct device_node *np, - const char *name, - struct pmf_irq_client *client) -{ - unsigned long flags; - - spin_lock_irqsave(&pmf_lock, flags); - list_del(&client->link); - spin_unlock_irqrestore(&pmf_lock, flags); -} -EXPORT_SYMBOL_GPL(pmf_unregister_irq_client); - - -void pmf_do_irq(struct pmf_function *func) -{ - unsigned long flags; - struct pmf_irq_client *client; - - /* For now, using a spinlock over the whole function. Can be made - * to drop the lock using 2 lists if necessary - */ - spin_lock_irqsave(&pmf_lock, flags); - list_for_each_entry(client, &func->irq_clients, link) { - if (!try_module_get(client->owner)) - continue; - client->handler(client->data); - module_put(client->owner); - } - spin_unlock_irqrestore(&pmf_lock, flags); -} -EXPORT_SYMBOL_GPL(pmf_do_irq); - - -int pmf_call_one(struct pmf_function *func, struct pmf_args *args) -{ - struct pmf_device *dev = func->dev; - void *instdata = NULL; - int rc = 0; - - DBG(" ** pmf_call_one(%s/%s) **\n", dev->node->full_name, func->name); - - if (dev->handlers->begin) - instdata = dev->handlers->begin(func, args); - rc = pmf_parse_one(func, dev->handlers, instdata, args); - if (dev->handlers->end) - dev->handlers->end(func, instdata); - - return rc; -} -EXPORT_SYMBOL_GPL(pmf_call_one); - -int pmf_do_functions(struct device_node *np, const char *name, - u32 phandle, u32 fflags, struct pmf_args *args) -{ - struct pmf_device *dev; - struct pmf_function *func, *tmp; - unsigned long flags; - int rc = -ENODEV; - - spin_lock_irqsave(&pmf_lock, flags); - - dev = pmf_find_device(np); - if (dev == NULL) { - spin_unlock_irqrestore(&pmf_lock, flags); - return -ENODEV; - } - list_for_each_entry_safe(func, tmp, &dev->functions, link) { - if (name && strcmp(name, func->name)) - continue; - if (phandle && func->phandle && phandle != func->phandle) - continue; - if ((func->flags & fflags) == 0) - continue; - if (pmf_get_function(func) == NULL) - continue; - spin_unlock_irqrestore(&pmf_lock, flags); - rc = pmf_call_one(func, args); - pmf_put_function(func); - spin_lock_irqsave(&pmf_lock, flags); - } - pmf_put_device(dev); - spin_unlock_irqrestore(&pmf_lock, flags); - - return rc; -} -EXPORT_SYMBOL_GPL(pmf_do_functions); - - -struct pmf_function *pmf_find_function(struct device_node *target, - const char *name) -{ - struct pmf_function *func; - unsigned long flags; - - spin_lock_irqsave(&pmf_lock, flags); - func = __pmf_find_function(target, name, PMF_FLAGS_ON_DEMAND); - if (func) - func = pmf_get_function(func); - spin_unlock_irqrestore(&pmf_lock, flags); - return func; -} -EXPORT_SYMBOL_GPL(pmf_find_function); - -int pmf_call_function(struct device_node *target, const char *name, - struct pmf_args *args) -{ - struct pmf_function *func = pmf_find_function(target, name); - int rc; - - if (func == NULL) - return -ENODEV; - - rc = pmf_call_one(func, args); - pmf_put_function(func); - return rc; -} -EXPORT_SYMBOL_GPL(pmf_call_function); - diff --git a/trunk/arch/powerpc/platforms/powermac/pic.c b/trunk/arch/powerpc/platforms/powermac/pic.c index 18bf3011d1e3..90040c49494d 100644 --- a/trunk/arch/powerpc/platforms/powermac/pic.c +++ b/trunk/arch/powerpc/platforms/powermac/pic.c @@ -5,8 +5,8 @@ * in a separate file * * Copyright (C) 1997 Paul Mackerras (paulus@samba.org) - * Copyright (C) 2005 Benjamin Herrenschmidt (benh@kernel.crashing.org) - * IBM, Corp. + * + * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -54,7 +54,12 @@ struct pmac_irq_hw { }; /* Default addresses */ -static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4]; +static volatile struct pmac_irq_hw *pmac_irq_hw[4] = { + (struct pmac_irq_hw *) 0xf3000020, + (struct pmac_irq_hw *) 0xf3000010, + (struct pmac_irq_hw *) 0xf4000020, + (struct pmac_irq_hw *) 0xf4000010, +}; #define GC_LEVEL_MASK 0x3ff00000 #define OHARE_LEVEL_MASK 0x1ff00000 @@ -77,7 +82,8 @@ static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; * since it can lose interrupts (see pmac_set_irq_mask). * -- Cort */ -void __set_lost(unsigned long irq_nr, int nokick) +void +__set_lost(unsigned long irq_nr, int nokick) { if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) { atomic_inc(&ppc_n_lost_interrupts); @@ -86,7 +92,8 @@ void __set_lost(unsigned long irq_nr, int nokick) } } -static void pmac_mask_and_ack_irq(unsigned int irq_nr) +static void +pmac_mask_and_ack_irq(unsigned int irq_nr) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; @@ -217,7 +224,8 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id, struct pt_regs *regs) return IRQ_NONE; } -static int pmac_get_irq(struct pt_regs *regs) +int +pmac_get_irq(struct pt_regs *regs) { int irq; unsigned long bits = 0; @@ -248,40 +256,34 @@ static int pmac_get_irq(struct pt_regs *regs) /* This routine will fix some missing interrupt values in the device tree * on the gatwick mac-io controller used by some PowerBooks - * - * Walking of OF nodes could use a bit more fixing up here, but it's not - * very important as this is all boot time code on static portions of the - * device-tree. - * - * However, the modifications done to "intrs" will have to be removed and - * replaced with proper updates of the "interrupts" properties or - * AAPL,interrupts, yet to be decided, once the dynamic parsing is there. */ -static void __init pmac_fix_gatwick_interrupts(struct device_node *gw, - int irq_base) +static void __init +pmac_fix_gatwick_interrupts(struct device_node *gw, int irq_base) { struct device_node *node; int count; memset(gatwick_int_pool, 0, sizeof(gatwick_int_pool)); + node = gw->child; count = 0; - for (node = NULL; (node = of_get_next_child(gw, node)) != NULL;) { + while(node) + { /* Fix SCC */ - if ((strcasecmp(node->name, "escc") == 0) && node->child) { - if (node->child->n_intrs < 3) { - node->child->intrs = &gatwick_int_pool[count]; - count += 3; + if (strcasecmp(node->name, "escc") == 0) + if (node->child) { + if (node->child->n_intrs < 3) { + node->child->intrs = &gatwick_int_pool[count]; + count += 3; + } + node->child->n_intrs = 3; + node->child->intrs[0].line = 15+irq_base; + node->child->intrs[1].line = 4+irq_base; + node->child->intrs[2].line = 5+irq_base; + printk(KERN_INFO "irq: fixed SCC on second controller (%d,%d,%d)\n", + node->child->intrs[0].line, + node->child->intrs[1].line, + node->child->intrs[2].line); } - node->child->n_intrs = 3; - node->child->intrs[0].line = 15+irq_base; - node->child->intrs[1].line = 4+irq_base; - node->child->intrs[2].line = 5+irq_base; - printk(KERN_INFO "irq: fixed SCC on gatwick" - " (%d,%d,%d)\n", - node->child->intrs[0].line, - node->child->intrs[1].line, - node->child->intrs[2].line); - } /* Fix media-bay & left SWIM */ if (strcasecmp(node->name, "media-bay") == 0) { struct device_node* ya_node; @@ -290,11 +292,12 @@ static void __init pmac_fix_gatwick_interrupts(struct device_node *gw, node->intrs = &gatwick_int_pool[count++]; node->n_intrs = 1; node->intrs[0].line = 29+irq_base; - printk(KERN_INFO "irq: fixed media-bay on gatwick" - " (%d)\n", node->intrs[0].line); + printk(KERN_INFO "irq: fixed media-bay on second controller (%d)\n", + node->intrs[0].line); ya_node = node->child; - while(ya_node) { + while(ya_node) + { if (strcasecmp(ya_node->name, "floppy") == 0) { if (ya_node->n_intrs < 2) { ya_node->intrs = &gatwick_int_pool[count]; @@ -320,6 +323,7 @@ static void __init pmac_fix_gatwick_interrupts(struct device_node *gw, ya_node = ya_node->sibling; } } + node = node->sibling; } if (count > 10) { printk("WARNING !! Gatwick interrupt pool overflow\n"); @@ -334,41 +338,45 @@ static void __init pmac_fix_gatwick_interrupts(struct device_node *gw, * controller. If we find this second ohare, set it up and fix the * interrupt value in the device tree for the ethernet chip. */ -static void __init enable_second_ohare(struct device_node *np) +static int __init enable_second_ohare(void) { unsigned char bus, devfn; unsigned short cmd; + unsigned long addr; + struct device_node *irqctrler = find_devices("pci106b,7"); struct device_node *ether; - /* This code doesn't strictly belong here, it could be part of - * either the PCI initialisation or the feature code. It's kept - * here for historical reasons. - */ - if (pci_device_from_OF_node(np, &bus, &devfn) == 0) { - struct pci_controller* hose = - pci_find_hose_for_OF_device(np); - if (!hose) { - printk(KERN_ERR "Can't find PCI hose for OHare2 !\n"); - return; + if (irqctrler == NULL || irqctrler->n_addrs <= 0) + return -1; + addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40); + pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20); + max_irqs = 64; + if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) { + struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler); + if (!hose) + printk(KERN_ERR "Can't find PCI hose for OHare2 !\n"); + else { + early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + cmd &= ~PCI_COMMAND_IO; + early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd); } - early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - cmd &= ~PCI_COMMAND_IO; - early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd); } /* Fix interrupt for the modem/ethernet combo controller. The number - * in the device tree (27) is bogus (correct for the ethernet-only - * board but not the combo ethernet/modem board). - * The real interrupt is 28 on the second controller -> 28+32 = 60. - */ - ether = of_find_node_by_name(NULL, "pci1011,14"); + in the device tree (27) is bogus (correct for the ethernet-only + board but not the combo ethernet/modem board). + The real interrupt is 28 on the second controller -> 28+32 = 60. + */ + ether = find_devices("pci1011,14"); if (ether && ether->n_intrs > 0) { ether->intrs[0].line = 60; printk(KERN_INFO "irq: Fixed ethernet IRQ to %d\n", ether->intrs[0].line); } - of_node_put(ether); + + /* Return the interrupt number of the cascade */ + return irqctrler->intrs[0].line; } #ifdef CONFIG_XMON @@ -386,251 +394,189 @@ static struct irqaction gatwick_cascade_action = { .mask = CPU_MASK_NONE, .name = "cascade", }; +#endif /* CONFIG_PPC32 */ -static void __init pmac_pic_probe_oldstyle(void) +static int pmac_u3_cascade(struct pt_regs *regs, void *data) { + return mpic_get_one_irq((struct mpic *)data, regs); +} + +void __init pmac_pic_init(void) +{ + struct device_node *irqctrler = NULL; + struct device_node *irqctrler2 = NULL; + struct device_node *np; +#ifdef CONFIG_PPC32 int i; + unsigned long addr; int irq_cascade = -1; - struct device_node *master = NULL; - struct device_node *slave = NULL; - u8 __iomem *addr; - struct resource r; - - /* Set our get_irq function */ - ppc_md.get_irq = pmac_get_irq; +#endif + struct mpic *mpic1, *mpic2; - /* - * Find the interrupt controller type & node + /* We first try to detect Apple's new Core99 chipset, since mac-io + * is quite different on those machines and contains an IBM MPIC2. */ + np = find_type_devices("open-pic"); + while (np) { + if (np->parent && !strcmp(np->parent->name, "u3")) + irqctrler2 = np; + else + irqctrler = np; + np = np->next; + } + if (irqctrler != NULL && irqctrler->n_addrs > 0) { + unsigned char senses[128]; + + printk(KERN_INFO "PowerMac using OpenPIC irq controller at 0x%08x\n", + (unsigned int)irqctrler->addrs[0].address); + pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler, 0, 0); + + prom_get_irq_senses(senses, 0, 128); + mpic1 = mpic_alloc(irqctrler->addrs[0].address, + MPIC_PRIMARY | MPIC_WANTS_RESET, + 0, 0, 128, 252, senses, 128, " OpenPIC "); + BUG_ON(mpic1 == NULL); + mpic_init(mpic1); + + if (irqctrler2 != NULL && irqctrler2->n_intrs > 0 && + irqctrler2->n_addrs > 0) { + printk(KERN_INFO "Slave OpenPIC at 0x%08x hooked on IRQ %d\n", + (u32)irqctrler2->addrs[0].address, + irqctrler2->intrs[0].line); + + pmac_call_feature(PMAC_FTR_ENABLE_MPIC, irqctrler2, 0, 0); + prom_get_irq_senses(senses, 128, 128 + 124); + + /* We don't need to set MPIC_BROKEN_U3 here since we don't have + * hypertransport interrupts routed to it + */ + mpic2 = mpic_alloc(irqctrler2->addrs[0].address, + MPIC_BIG_ENDIAN | MPIC_WANTS_RESET, + 0, 128, 124, 0, senses, 124, + " U3-MPIC "); + BUG_ON(mpic2 == NULL); + mpic_init(mpic2); + mpic_setup_cascade(irqctrler2->intrs[0].line, + pmac_u3_cascade, mpic2); + } +#if defined(CONFIG_XMON) && defined(CONFIG_PPC32) + { + struct device_node* pswitch; + int nmi_irq; + + pswitch = find_devices("programmer-switch"); + if (pswitch && pswitch->n_intrs) { + nmi_irq = pswitch->intrs[0].line; + mpic_irq_set_priority(nmi_irq, 9); + setup_irq(nmi_irq, &xmon_action); + } + } +#endif /* CONFIG_XMON */ + return; + } + irqctrler = NULL; - if ((master = of_find_node_by_name(NULL, "gc")) != NULL) { - max_irqs = max_real_irqs = 32; +#ifdef CONFIG_PPC32 + /* Get the level/edge settings, assume if it's not + * a Grand Central nor an OHare, then it's an Heathrow + * (or Paddington). + */ + ppc_md.get_irq = pmac_get_irq; + if (find_devices("gc")) level_mask[0] = GC_LEVEL_MASK; - } else if ((master = of_find_node_by_name(NULL, "ohare")) != NULL) { - max_irqs = max_real_irqs = 32; + else if (find_devices("ohare")) { level_mask[0] = OHARE_LEVEL_MASK; - /* We might have a second cascaded ohare */ - slave = of_find_node_by_name(NULL, "pci106b,7"); - if (slave) { - max_irqs = 64; - level_mask[1] = OHARE_LEVEL_MASK; - enable_second_ohare(slave); - } - } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) { - max_irqs = max_real_irqs = 64; + level_mask[1] = OHARE_LEVEL_MASK; + } else { level_mask[0] = HEATHROW_LEVEL_MASK; level_mask[1] = 0; - /* We might have a second cascaded heathrow */ - slave = of_find_node_by_name(master, "mac-io"); - - /* Check ordering of master & slave */ - if (device_is_compatible(master, "gatwick")) { - struct device_node *tmp; - BUG_ON(slave == NULL); - tmp = master; - master = slave; - slave = tmp; - } + level_mask[2] = HEATHROW_LEVEL_MASK; + level_mask[3] = 0; + } - /* We found a slave */ - if (slave) { + /* + * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts, + * 1998 G3 Series PowerBooks have 128, + * other powermacs have 32. + * The combo ethernet/modem card for the Powerstar powerbooks + * (2400/3400/3500, ohare based) has a second ohare chip + * effectively making a total of 64. + */ + max_irqs = max_real_irqs = 32; + irqctrler = find_devices("mac-io"); + if (irqctrler) + { + max_real_irqs = 64; + if (irqctrler->next) max_irqs = 128; - level_mask[2] = HEATHROW_LEVEL_MASK; - level_mask[3] = 0; - pmac_fix_gatwick_interrupts(slave, max_real_irqs); - } + else + max_irqs = 64; } - BUG_ON(master == NULL); - - /* Set the handler for the main PIC */ for ( i = 0; i < max_real_irqs ; i++ ) irq_desc[i].handler = &pmac_pic; - /* Get addresses of first controller if we have a node for it */ - BUG_ON(of_address_to_resource(master, 0, &r)); + /* get addresses of first controller */ + if (irqctrler) { + if (irqctrler->n_addrs > 0) { + addr = (unsigned long) + ioremap(irqctrler->addrs[0].address, 0x40); + for (i = 0; i < 2; ++i) + pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) + (addr + (2 - i) * 0x10); + } - /* Map interrupts of primary controller */ - addr = (u8 __iomem *) ioremap(r.start, 0x40); - i = 0; - pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *) - (addr + 0x20); - if (max_real_irqs > 32) - pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *) - (addr + 0x10); - of_node_put(master); - - printk(KERN_INFO "irq: Found primary Apple PIC %s for %d irqs\n", - master->full_name, max_real_irqs); - - /* Map interrupts of cascaded controller */ - if (slave && !of_address_to_resource(slave, 0, &r)) { - addr = (u8 __iomem *)ioremap(r.start, 0x40); - pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *) - (addr + 0x20); - if (max_irqs > 64) - pmac_irq_hw[i++] = - (volatile struct pmac_irq_hw __iomem *) - (addr + 0x10); - irq_cascade = slave->intrs[0].line; - - printk(KERN_INFO "irq: Found slave Apple PIC %s for %d irqs" - " cascade: %d\n", slave->full_name, - max_irqs - max_real_irqs, irq_cascade); + /* get addresses of second controller */ + irqctrler = irqctrler->next; + if (irqctrler && irqctrler->n_addrs > 0) { + addr = (unsigned long) + ioremap(irqctrler->addrs[0].address, 0x40); + for (i = 2; i < 4; ++i) + pmac_irq_hw[i] = (volatile struct pmac_irq_hw*) + (addr + (4 - i) * 0x10); + irq_cascade = irqctrler->intrs[0].line; + if (device_is_compatible(irqctrler, "gatwick")) + pmac_fix_gatwick_interrupts(irqctrler, max_real_irqs); + } + } else { + /* older powermacs have a GC (grand central) or ohare at + f3000000, with interrupt control registers at f3000020. */ + addr = (unsigned long) ioremap(0xf3000000, 0x40); + pmac_irq_hw[0] = (volatile struct pmac_irq_hw *) (addr + 0x20); } - of_node_put(slave); + + /* PowerBooks 3400 and 3500 can have a second controller in a second + ohare chip, on the combo ethernet/modem card */ + if (machine_is_compatible("AAPL,3400/2400") + || machine_is_compatible("AAPL,3500")) + irq_cascade = enable_second_ohare(); /* disable all interrupts in all controllers */ for (i = 0; i * 32 < max_irqs; ++i) out_le32(&pmac_irq_hw[i]->enable, 0); - /* mark level interrupts */ for (i = 0; i < max_irqs; i++) if (level_mask[i >> 5] & (1UL << (i & 0x1f))) irq_desc[i].status = IRQ_LEVEL; - /* Setup handlers for secondary controller and hook cascade irq*/ - if (slave) { + /* get interrupt line of secondary interrupt controller */ + if (irq_cascade >= 0) { + printk(KERN_INFO "irq: secondary controller on irq %d\n", + (int)irq_cascade); for ( i = max_real_irqs ; i < max_irqs ; i++ ) irq_desc[i].handler = &gatwick_pic; setup_irq(irq_cascade, &gatwick_cascade_action); } - printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs); + printk("System has %d possible interrupts\n", max_irqs); + if (max_irqs != max_real_irqs) + printk(KERN_DEBUG "%d interrupts on main controller\n", + max_real_irqs); + #ifdef CONFIG_XMON setup_irq(20, &xmon_action); -#endif -} -#endif /* CONFIG_PPC32 */ - -static int pmac_u3_cascade(struct pt_regs *regs, void *data) -{ - return mpic_get_one_irq((struct mpic *)data, regs); -} - -static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic) -{ -#if defined(CONFIG_XMON) && defined(CONFIG_PPC32) - struct device_node* pswitch; - int nmi_irq; - - pswitch = of_find_node_by_name(NULL, "programmer-switch"); - if (pswitch && pswitch->n_intrs) { - nmi_irq = pswitch->intrs[0].line; - mpic_irq_set_priority(nmi_irq, 9); - setup_irq(nmi_irq, &xmon_action); - } - of_node_put(pswitch); -#endif /* defined(CONFIG_XMON) && defined(CONFIG_PPC32) */ -} - -static struct mpic * __init pmac_setup_one_mpic(struct device_node *np, - int master) -{ - unsigned char senses[128]; - int offset = master ? 0 : 128; - int count = master ? 128 : 124; - const char *name = master ? " MPIC 1 " : " MPIC 2 "; - struct resource r; - struct mpic *mpic; - unsigned int flags = master ? MPIC_PRIMARY : 0; - int rc; - - rc = of_address_to_resource(np, 0, &r); - if (rc) - return NULL; - - pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0); - - prom_get_irq_senses(senses, offset, offset + count); - - flags |= MPIC_WANTS_RESET; - if (get_property(np, "big-endian", NULL)) - flags |= MPIC_BIG_ENDIAN; - - /* Primary Big Endian means HT interrupts. This is quite dodgy - * but works until I find a better way - */ - if (master && (flags & MPIC_BIG_ENDIAN)) - flags |= MPIC_BROKEN_U3; - - mpic = mpic_alloc(r.start, flags, 0, offset, count, master ? 252 : 0, - senses, count, name); - if (mpic == NULL) - return NULL; - - mpic_init(mpic); - - return mpic; - } - -static int __init pmac_pic_probe_mpic(void) -{ - struct mpic *mpic1, *mpic2; - struct device_node *np, *master = NULL, *slave = NULL; - - /* We can have up to 2 MPICs cascaded */ - for (np = NULL; (np = of_find_node_by_type(np, "open-pic")) - != NULL;) { - if (master == NULL && - get_property(np, "interrupts", NULL) == NULL) - master = of_node_get(np); - else if (slave == NULL) - slave = of_node_get(np); - if (master && slave) - break; - } - - /* Check for bogus setups */ - if (master == NULL && slave != NULL) { - master = slave; - slave = NULL; - } - - /* Not found, default to good old pmac pic */ - if (master == NULL) - return -ENODEV; - - /* Set master handler */ - ppc_md.get_irq = mpic_get_irq; - - /* Setup master */ - mpic1 = pmac_setup_one_mpic(master, 1); - BUG_ON(mpic1 == NULL); - - /* Install NMI if any */ - pmac_pic_setup_mpic_nmi(mpic1); - - of_node_put(master); - - /* No slave, let's go out */ - if (slave == NULL || slave->n_intrs < 1) - return 0; - - mpic2 = pmac_setup_one_mpic(slave, 0); - if (mpic2 == NULL) { - printk(KERN_ERR "Failed to setup slave MPIC\n"); - of_node_put(slave); - return 0; - } - mpic_setup_cascade(slave->intrs[0].line, pmac_u3_cascade, mpic2); - - of_node_put(slave); - return 0; -} - - -void __init pmac_pic_init(void) -{ - /* We first try to detect Apple's new Core99 chipset, since mac-io - * is quite different on those machines and contains an IBM MPIC2. - */ - if (pmac_pic_probe_mpic() == 0) - return; - -#ifdef CONFIG_PPC32 - pmac_pic_probe_oldstyle(); -#endif +#endif /* CONFIG_XMON */ +#endif /* CONFIG_PPC32 */ } #if defined(CONFIG_PM) && defined(CONFIG_PPC32) diff --git a/trunk/arch/powerpc/platforms/powermac/pmac.h b/trunk/arch/powerpc/platforms/powermac/pmac.h index 21c7b0f8f329..2ad25e13423e 100644 --- a/trunk/arch/powerpc/platforms/powermac/pmac.h +++ b/trunk/arch/powerpc/platforms/powermac/pmac.h @@ -42,6 +42,10 @@ extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port, unsigned long ctrl_port, int *irq); extern int pmac_nvram_init(void); -extern void pmac_pic_init(void); + +extern struct hw_interrupt_type pmac_pic; + +void pmac_pic_init(void); +int pmac_get_irq(struct pt_regs *regs); #endif /* __PMAC_H__ */ diff --git a/trunk/arch/powerpc/platforms/powermac/setup.c b/trunk/arch/powerpc/platforms/powermac/setup.c index 3b1a9d4fcbc6..7acb0546671f 100644 --- a/trunk/arch/powerpc/platforms/powermac/setup.c +++ b/trunk/arch/powerpc/platforms/powermac/setup.c @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -75,8 +74,8 @@ #include #include #include +#include #include -#include #include "pmac.h" @@ -322,6 +321,16 @@ void __init pmac_setup_arch(void) l2cr_init(); #endif /* CONFIG_PPC32 */ +#ifdef CONFIG_PPC64 + /* Probe motherboard chipset */ + /* this is done earlier in setup_arch for 32-bit */ + pmac_feature_init(); + + /* We can NAP */ + powersave_nap = 1; + printk(KERN_INFO "Using native/NAP idle loop\n"); +#endif + #ifdef CONFIG_KGDB zs_kgdb_hook(0); #endif @@ -345,7 +354,7 @@ void __init pmac_setup_arch(void) #ifdef CONFIG_SMP /* Check for Core99 */ - if (find_devices("uni-n") || find_devices("u3") || find_devices("u4")) + if (find_devices("uni-n") || find_devices("u3")) smp_ops = &core99_smp_ops; #ifdef CONFIG_PPC32 else @@ -612,31 +621,35 @@ static void __init pmac_init_early(void) * and call ioremap */ hpte_init_native(); -#endif - /* Enable early btext debug if requested */ - if (strstr(cmd_line, "btextdbg")) { - udbg_adb_init_early(); - register_early_udbg_console(); + /* Init SCC */ + if (strstr(cmd_line, "sccdbg")) { + sccdbg = 1; + udbg_init_scc(NULL); } - /* Probe motherboard chipset */ - pmac_feature_init(); - - /* We can NAP */ - powersave_nap = 1; - printk(KERN_INFO "Using native/NAP idle loop\n"); - - /* Initialize debug stuff */ - udbg_scc_init(!!strstr(cmd_line, "sccdbg")); - udbg_adb_init(!!strstr(cmd_line, "btextdbg")); - -#ifdef CONFIG_PPC64 /* Setup interrupt mapping options */ ppc64_interrupt_controller = IC_OPEN_PIC; - iommu_init_early_dart(); + iommu_init_early_u3(); +#endif +} + +static void __init pmac_progress(char *s, unsigned short hex) +{ +#ifdef CONFIG_PPC64 + if (sccdbg) { + udbg_puts(s); + udbg_puts("\n"); + return; + } #endif +#ifdef CONFIG_BOOTX_TEXT + if (boot_text_mapped) { + btext_drawstring(s); + btext_drawchar('\n'); + } +#endif /* CONFIG_BOOTX_TEXT */ } /* @@ -650,14 +663,35 @@ static int pmac_check_legacy_ioport(unsigned int baseport) static int __init pmac_declare_of_platform_devices(void) { - struct device_node *np; - - np = of_find_node_by_name(NULL, "valkyrie"); + struct device_node *np, *npp; + + np = find_devices("uni-n"); + if (np) { + for (np = np->child; np != NULL; np = np->sibling) + if (strncmp(np->name, "i2c", 3) == 0) { + of_platform_device_create(np, "uni-n-i2c", + NULL); + break; + } + } + np = find_devices("valkyrie"); if (np) of_platform_device_create(np, "valkyrie", NULL); - np = of_find_node_by_name(NULL, "platinum"); + np = find_devices("platinum"); if (np) of_platform_device_create(np, "platinum", NULL); + + npp = of_find_node_by_name(NULL, "u3"); + if (npp) { + for (np = NULL; (np = of_get_next_child(npp, np)) != NULL;) { + if (strncmp(np->name, "i2c", 3) == 0) { + of_platform_device_create(np, "u3-i2c", NULL); + of_node_put(np); + break; + } + } + of_node_put(npp); + } np = of_find_node_by_type(NULL, "smu"); if (np) { of_platform_device_create(np, "smu", NULL); @@ -684,7 +718,7 @@ static int __init pmac_probe(int platform) * occupies having to be broken up so the DART itself is not * part of the cacheable linar mapping */ - alloc_dart_table(); + alloc_u3_dart_table(); #endif #ifdef CONFIG_PMAC_SMU @@ -700,17 +734,15 @@ static int __init pmac_probe(int platform) } #ifdef CONFIG_PPC64 -/* Move that to pci.c */ -static int pmac_pci_probe_mode(struct pci_bus *bus) +static int pmac_probe_mode(struct pci_bus *bus) { struct device_node *node = bus->sysdata; /* We need to use normal PCI probing for the AGP bus, - * since the device for the AGP bridge isn't in the tree. - */ - if (bus->self == NULL && (device_is_compatible(node, "u3-agp") || - device_is_compatible(node, "u4-pcie"))) + since the device for the AGP bridge isn't in the tree. */ + if (bus->self == NULL && device_is_compatible(node, "u3-agp")) return PCI_PROBE_NORMAL; + return PCI_PROBE_DEVTREE; } #endif @@ -724,7 +756,7 @@ struct machdep_calls __initdata pmac_md = { .init_early = pmac_init_early, .show_cpuinfo = pmac_show_cpuinfo, .init_IRQ = pmac_pic_init, - .get_irq = NULL, /* changed later */ + .get_irq = mpic_get_irq, /* changed later */ .pcibios_fixup = pmac_pcibios_fixup, .restart = pmac_restart, .power_off = pmac_power_off, @@ -736,17 +768,12 @@ struct machdep_calls __initdata pmac_md = { .calibrate_decr = pmac_calibrate_decr, .feature_call = pmac_do_feature_call, .check_legacy_ioport = pmac_check_legacy_ioport, - .progress = udbg_progress, + .progress = pmac_progress, #ifdef CONFIG_PPC64 - .pci_probe_mode = pmac_pci_probe_mode, + .pci_probe_mode = pmac_probe_mode, .idle_loop = native_idle, .enable_pmcs = power4_enable_pmcs, -#ifdef CONFIG_KEXEC - .machine_kexec = default_machine_kexec, - .machine_kexec_prepare = default_machine_kexec_prepare, - .machine_crash_shutdown = default_machine_crash_shutdown, #endif -#endif /* CONFIG_PPC64 */ #ifdef CONFIG_PPC32 .pcibios_enable_device_hook = pmac_pci_enable_device_hook, .pcibios_after_init = pmac_pcibios_after_init, diff --git a/trunk/arch/powerpc/platforms/powermac/smp.c b/trunk/arch/powerpc/platforms/powermac/smp.c index 0df2cdcd805c..fb2a7c798e82 100644 --- a/trunk/arch/powerpc/platforms/powermac/smp.c +++ b/trunk/arch/powerpc/platforms/powermac/smp.c @@ -52,9 +52,8 @@ #include #include #include -#include -#define DEBUG +#undef DEBUG #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) @@ -63,7 +62,6 @@ #endif extern void __secondary_start_pmac_0(void); -extern int pmac_pfunc_base_install(void); #ifdef CONFIG_PPC32 @@ -363,6 +361,7 @@ static void __init psurge_dual_sync_tb(int cpu_nr) set_dec(tb_ticks_per_jiffy); /* XXX fixme */ set_tb(0, 0); + last_jiffy_stamp(cpu_nr) = 0; if (cpu_nr > 0) { mb(); @@ -430,62 +429,15 @@ struct smp_ops_t psurge_smp_ops = { }; #endif /* CONFIG_PPC32 - actually powersurge support */ -/* - * Core 99 and later support - */ - -static void (*pmac_tb_freeze)(int freeze); -static unsigned long timebase; -static int tb_req; - -static void smp_core99_give_timebase(void) -{ - unsigned long flags; - - local_irq_save(flags); - - while(!tb_req) - barrier(); - tb_req = 0; - (*pmac_tb_freeze)(1); - mb(); - timebase = get_tb(); - mb(); - while (timebase) - barrier(); - mb(); - (*pmac_tb_freeze)(0); - mb(); - - local_irq_restore(flags); -} - - -static void __devinit smp_core99_take_timebase(void) -{ - unsigned long flags; - - local_irq_save(flags); - - tb_req = 1; - mb(); - while (!timebase) - barrier(); - mb(); - set_tb(timebase >> 32, timebase & 0xffffffff); - timebase = 0; - mb(); - set_dec(tb_ticks_per_jiffy/2); - - local_irq_restore(flags); -} - #ifdef CONFIG_PPC64 /* * G5s enable/disable the timebase via an i2c-connected clock chip. */ -static struct pmac_i2c_bus *pmac_tb_clock_chip_host; +static struct device_node *pmac_tb_clock_chip_host; static u8 pmac_tb_pulsar_addr; +static void (*pmac_tb_freeze)(int freeze); +static DEFINE_SPINLOCK(timebase_lock); +static unsigned long timebase; static void smp_core99_cypress_tb_freeze(int freeze) { @@ -495,20 +447,19 @@ static void smp_core99_cypress_tb_freeze(int freeze) /* Strangely, the device-tree says address is 0xd2, but darwin * accesses 0xd0 ... */ - pmac_i2c_setmode(pmac_tb_clock_chip_host, - pmac_i2c_mode_combined); - rc = pmac_i2c_xfer(pmac_tb_clock_chip_host, - 0xd0 | pmac_i2c_read, - 1, 0x81, &data, 1); + pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined); + rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, + 0xd0 | pmac_low_i2c_read, + 0x81, &data, 1); if (rc != 0) goto bail; data = (data & 0xf3) | (freeze ? 0x00 : 0x0c); - pmac_i2c_setmode(pmac_tb_clock_chip_host, pmac_i2c_mode_stdsub); - rc = pmac_i2c_xfer(pmac_tb_clock_chip_host, - 0xd0 | pmac_i2c_write, - 1, 0x81, &data, 1); + pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub); + rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, + 0xd0 | pmac_low_i2c_write, + 0x81, &data, 1); bail: if (rc != 0) { @@ -524,20 +475,19 @@ static void smp_core99_pulsar_tb_freeze(int freeze) u8 data; int rc; - pmac_i2c_setmode(pmac_tb_clock_chip_host, - pmac_i2c_mode_combined); - rc = pmac_i2c_xfer(pmac_tb_clock_chip_host, - pmac_tb_pulsar_addr | pmac_i2c_read, - 1, 0x2e, &data, 1); + pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined); + rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, + pmac_tb_pulsar_addr | pmac_low_i2c_read, + 0x2e, &data, 1); if (rc != 0) goto bail; data = (data & 0x88) | (freeze ? 0x11 : 0x22); - pmac_i2c_setmode(pmac_tb_clock_chip_host, pmac_i2c_mode_stdsub); - rc = pmac_i2c_xfer(pmac_tb_clock_chip_host, - pmac_tb_pulsar_addr | pmac_i2c_write, - 1, 0x2e, &data, 1); + pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub); + rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host, + pmac_tb_pulsar_addr | pmac_low_i2c_write, + 0x2e, &data, 1); bail: if (rc != 0) { printk(KERN_ERR "Pulsar Timebase %s rc: %d\n", @@ -546,14 +496,54 @@ static void smp_core99_pulsar_tb_freeze(int freeze) } } -static void __init smp_core99_setup_i2c_hwsync(int ncpus) + +static void smp_core99_give_timebase(void) +{ + /* Open i2c bus for synchronous access */ + if (pmac_low_i2c_open(pmac_tb_clock_chip_host, 0)) + panic("Can't open i2c for TB sync !\n"); + + spin_lock(&timebase_lock); + (*pmac_tb_freeze)(1); + mb(); + timebase = get_tb(); + spin_unlock(&timebase_lock); + + while (timebase) + barrier(); + + spin_lock(&timebase_lock); + (*pmac_tb_freeze)(0); + spin_unlock(&timebase_lock); + + /* Close i2c bus */ + pmac_low_i2c_close(pmac_tb_clock_chip_host); +} + + +static void __devinit smp_core99_take_timebase(void) +{ + while (!timebase) + barrier(); + spin_lock(&timebase_lock); + set_tb(timebase >> 32, timebase & 0xffffffff); + timebase = 0; + spin_unlock(&timebase_lock); +} + +static void __init smp_core99_setup(int ncpus) { struct device_node *cc = NULL; struct device_node *p; - const char *name = NULL; u32 *reg; int ok; + /* HW sync only on these platforms */ + if (!machine_is_compatible("PowerMac7,2") && + !machine_is_compatible("PowerMac7,3") && + !machine_is_compatible("RackMac3,1")) + return; + /* Look for the clock chip */ while ((cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL) { p = of_get_parent(cc); @@ -562,86 +552,124 @@ static void __init smp_core99_setup_i2c_hwsync(int ncpus) if (!ok) continue; - pmac_tb_clock_chip_host = pmac_i2c_find_bus(cc); - if (pmac_tb_clock_chip_host == NULL) - continue; reg = (u32 *)get_property(cc, "reg", NULL); if (reg == NULL) continue; + switch (*reg) { case 0xd2: - if (device_is_compatible(cc,"pulsar-legacy-slewing")) { + if (device_is_compatible(cc, "pulsar-legacy-slewing")) { pmac_tb_freeze = smp_core99_pulsar_tb_freeze; pmac_tb_pulsar_addr = 0xd2; - name = "Pulsar"; + printk(KERN_INFO "Timebase clock is Pulsar chip\n"); } else if (device_is_compatible(cc, "cy28508")) { pmac_tb_freeze = smp_core99_cypress_tb_freeze; - name = "Cypress"; + printk(KERN_INFO "Timebase clock is Cypress chip\n"); } break; case 0xd4: pmac_tb_freeze = smp_core99_pulsar_tb_freeze; pmac_tb_pulsar_addr = 0xd4; - name = "Pulsar"; + printk(KERN_INFO "Timebase clock is Pulsar chip\n"); break; } - if (pmac_tb_freeze != NULL) + if (pmac_tb_freeze != NULL) { + pmac_tb_clock_chip_host = of_get_parent(cc); + of_node_put(cc); break; - } - if (pmac_tb_freeze != NULL) { - /* Open i2c bus for synchronous access */ - if (pmac_i2c_open(pmac_tb_clock_chip_host, 1)) { - printk(KERN_ERR "Failed top open i2c bus for clock" - " sync, fallback to software sync !\n"); - goto no_i2c_sync; } - printk(KERN_INFO "Processor timebase sync using %s i2c clock\n", - name); - return; } - no_i2c_sync: - pmac_tb_freeze = NULL; - pmac_tb_clock_chip_host = NULL; + if (pmac_tb_freeze == NULL) { + smp_ops->give_timebase = smp_generic_give_timebase; + smp_ops->take_timebase = smp_generic_take_timebase; + } } - - -/* - * Newer G5s uses a platform function - */ - -static void smp_core99_pfunc_tb_freeze(int freeze) +/* nothing to do here, caches are already set up by service processor */ +static inline void __devinit core99_init_caches(int cpu) { - struct device_node *cpus; - struct pmf_args args; - - cpus = of_find_node_by_path("/cpus"); - BUG_ON(cpus == NULL); - args.count = 1; - args.u[0].v = !freeze; - pmf_call_function(cpus, "cpu-timebase", &args); - of_node_put(cpus); } #else /* CONFIG_PPC64 */ /* - * SMP G4 use a GPIO to enable/disable the timebase. + * SMP G4 powermacs use a GPIO to enable/disable the timebase. */ static unsigned int core99_tb_gpio; /* Timebase freeze GPIO */ -static void smp_core99_gpio_tb_freeze(int freeze) +static unsigned int pri_tb_hi, pri_tb_lo; +static unsigned int pri_tb_stamp; + +/* not __init, called in sleep/wakeup code */ +void smp_core99_give_timebase(void) { - if (freeze) - pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4); - else - pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0); + unsigned long flags; + unsigned int t; + + /* wait for the secondary to be in take_timebase */ + for (t = 100000; t > 0 && !sec_tb_reset; --t) + udelay(10); + if (!sec_tb_reset) { + printk(KERN_WARNING "Timeout waiting sync on second CPU\n"); + return; + } + + /* freeze the timebase and read it */ + /* disable interrupts so the timebase is disabled for the + shortest possible time */ + local_irq_save(flags); + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4); pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); + mb(); + pri_tb_hi = get_tbu(); + pri_tb_lo = get_tbl(); + pri_tb_stamp = last_jiffy_stamp(smp_processor_id()); + mb(); + + /* tell the secondary we're ready */ + sec_tb_reset = 2; + mb(); + + /* wait for the secondary to have taken it */ + /* note: can't use udelay here, since it needs the timebase running */ + for (t = 10000000; t > 0 && sec_tb_reset; --t) + barrier(); + if (sec_tb_reset) + /* XXX BUG_ON here? */ + printk(KERN_WARNING "Timeout waiting sync(2) on second CPU\n"); + + /* Now, restart the timebase by leaving the GPIO to an open collector */ + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0); + pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0); + local_irq_restore(flags); } +/* not __init, called in sleep/wakeup code */ +void smp_core99_take_timebase(void) +{ + unsigned long flags; + + /* tell the primary we're here */ + sec_tb_reset = 1; + mb(); + + /* wait for the primary to set pri_tb_hi/lo */ + while (sec_tb_reset < 2) + mb(); + + /* set our stuff the same as the primary */ + local_irq_save(flags); + set_dec(1); + set_tb(pri_tb_hi, pri_tb_lo); + last_jiffy_stamp(smp_processor_id()) = pri_tb_stamp; + mb(); -#endif /* !CONFIG_PPC64 */ + /* tell the primary we're done */ + sec_tb_reset = 0; + mb(); + local_irq_restore(flags); +} /* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */ volatile static long int core99_l2_cache; @@ -649,7 +677,6 @@ volatile static long int core99_l3_cache; static void __devinit core99_init_caches(int cpu) { -#ifndef CONFIG_PPC64 if (!cpu_has_feature(CPU_FTR_L2CR)) return; @@ -675,75 +702,29 @@ static void __devinit core99_init_caches(int cpu) _set_L3CR(core99_l3_cache); printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache); } -#endif /* !CONFIG_PPC64 */ } static void __init smp_core99_setup(int ncpus) { -#ifdef CONFIG_PPC64 - - /* i2c based HW sync on some G5s */ - if (machine_is_compatible("PowerMac7,2") || - machine_is_compatible("PowerMac7,3") || - machine_is_compatible("RackMac3,1")) - smp_core99_setup_i2c_hwsync(ncpus); - - /* pfunc based HW sync on recent G5s */ - if (pmac_tb_freeze == NULL) { - struct device_node *cpus = - of_find_node_by_path("/cpus"); - if (cpus && - get_property(cpus, "platform-cpu-timebase", NULL)) { - pmac_tb_freeze = smp_core99_pfunc_tb_freeze; - printk(KERN_INFO "Processor timebase sync using" - " platform function\n"); - } - } - -#else /* CONFIG_PPC64 */ - - /* GPIO based HW sync on ppc32 Core99 */ - if (pmac_tb_freeze == NULL && !machine_is_compatible("MacRISC4")) { - struct device_node *cpu; - u32 *tbprop = NULL; - - core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */ - cpu = of_find_node_by_type(NULL, "cpu"); - if (cpu != NULL) { - tbprop = (u32 *)get_property(cpu, "timebase-enable", - NULL); - if (tbprop) - core99_tb_gpio = *tbprop; - of_node_put(cpu); - } - pmac_tb_freeze = smp_core99_gpio_tb_freeze; - printk(KERN_INFO "Processor timebase sync using" - " GPIO 0x%02x\n", core99_tb_gpio); - } - -#endif /* CONFIG_PPC64 */ - - /* No timebase sync, fallback to software */ - if (pmac_tb_freeze == NULL) { - smp_ops->give_timebase = smp_generic_give_timebase; - smp_ops->take_timebase = smp_generic_take_timebase; - printk(KERN_INFO "Processor timebase sync using software\n"); - } - -#ifndef CONFIG_PPC64 - { - int i; + struct device_node *cpu; + u32 *tbprop = NULL; + int i; - /* XXX should get this from reg properties */ - for (i = 1; i < ncpus; ++i) - smp_hw_index[i] = i; + core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */ + cpu = of_find_node_by_type(NULL, "cpu"); + if (cpu != NULL) { + tbprop = (u32 *)get_property(cpu, "timebase-enable", NULL); + if (tbprop) + core99_tb_gpio = *tbprop; + of_node_put(cpu); } -#endif - /* 32 bits SMP can't NAP */ - if (!machine_is_compatible("MacRISC4")) - powersave_nap = 0; + /* XXX should get this from reg properties */ + for (i = 1; i < ncpus; ++i) + smp_hw_index[i] = i; + powersave_nap = 0; } +#endif static int __init smp_core99_probe(void) { @@ -762,19 +743,8 @@ static int __init smp_core99_probe(void) if (ncpus <= 1) return 1; - /* We need to perform some early initialisations before we can start - * setting up SMP as we are running before initcalls - */ - pmac_pfunc_base_install(); - pmac_i2c_init(); - - /* Setup various bits like timebase sync method, ability to nap, ... */ smp_core99_setup(ncpus); - - /* Install IPIs */ mpic_request_ipis(); - - /* Collect l2cr and l3cr values from CPU 0 */ core99_init_caches(0); return ncpus; @@ -783,15 +753,14 @@ static int __init smp_core99_probe(void) static void __devinit smp_core99_kick_cpu(int nr) { unsigned int save_vector; - unsigned long target, flags; + unsigned long new_vector; + unsigned long flags; volatile unsigned int *vector = ((volatile unsigned int *)(KERNELBASE+0x100)); if (nr < 0 || nr > 3) return; - - if (ppc_md.progress) - ppc_md.progress("smp_core99_kick_cpu", 0x346); + if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346); local_irq_save(flags); local_irq_disable(); @@ -799,11 +768,14 @@ static void __devinit smp_core99_kick_cpu(int nr) /* Save reset vector */ save_vector = *vector; - /* Setup fake reset vector that does + /* Setup fake reset vector that does * b __secondary_start_pmac_0 + nr*8 - KERNELBASE */ - target = (unsigned long) __secondary_start_pmac_0 + nr * 8; - create_branch((unsigned long)vector, target, BRANCH_SET_LINK); + new_vector = (unsigned long) __secondary_start_pmac_0 + nr * 8; + *vector = 0x48000002 + new_vector - KERNELBASE; + + /* flush data cache and inval instruction cache */ + flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); /* Put some life in our friend */ pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0); @@ -833,25 +805,17 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr) mpic_setup_this_cpu(); if (cpu_nr == 0) { -#ifdef CONFIG_PPC64 +#ifdef CONFIG_POWER4 extern void g5_phy_disable_cpu1(void); - /* Close i2c bus if it was used for tb sync */ - if (pmac_tb_clock_chip_host) { - pmac_i2c_close(pmac_tb_clock_chip_host); - pmac_tb_clock_chip_host = NULL; - } - /* If we didn't start the second CPU, we must take * it off the bus */ if (machine_is_compatible("MacRISC4") && num_online_cpus() < 2) g5_phy_disable_cpu1(); -#endif /* CONFIG_PPC64 */ - - if (ppc_md.progress) - ppc_md.progress("core99_setup_cpu 0 done", 0x349); +#endif /* CONFIG_POWER4 */ + if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349); } } diff --git a/trunk/arch/powerpc/platforms/powermac/time.c b/trunk/arch/powerpc/platforms/powermac/time.c index 5d9afa1fa02d..feb0a94e7819 100644 --- a/trunk/arch/powerpc/platforms/powermac/time.c +++ b/trunk/arch/powerpc/platforms/powermac/time.c @@ -258,20 +258,15 @@ int __init via_calibrate_decr(void) volatile unsigned char __iomem *via; int count = VIA_TIMER_FREQ_6 / 100; unsigned int dstart, dend; - struct resource rsrc; - vias = of_find_node_by_name(NULL, "via-cuda"); + vias = find_devices("via-cuda"); if (vias == 0) - vias = of_find_node_by_name(NULL, "via-pmu"); + vias = find_devices("via-pmu"); if (vias == 0) - vias = of_find_node_by_name(NULL, "via"); - if (vias == 0 || of_address_to_resource(vias, 0, &rsrc)) + vias = find_devices("via"); + if (vias == 0 || vias->n_addrs == 0) return 0; - via = ioremap(rsrc.start, rsrc.end - rsrc.start + 1); - if (via == NULL) { - printk(KERN_ERR "Failed to map VIA for timer calibration !\n"); - return 0; - } + via = ioremap(vias->addrs[0].address, vias->addrs[0].size); /* set timer 1 for continuous interrupts */ out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT); diff --git a/trunk/arch/powerpc/platforms/powermac/udbg_adb.c b/trunk/arch/powerpc/platforms/powermac/udbg_adb.c deleted file mode 100644 index 06c8265c2baf..000000000000 --- a/trunk/arch/powerpc/platforms/powermac/udbg_adb.c +++ /dev/null @@ -1,221 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * This implementation is "special", it can "patch" the current - * udbg implementation and work on top of it. It must thus be - * initialized last - */ - -static void (*udbg_adb_old_putc)(char c); -static int (*udbg_adb_old_getc)(void); -static int (*udbg_adb_old_getc_poll)(void); - -static enum { - input_adb_none, - input_adb_pmu, - input_adb_cuda, -} input_type = input_adb_none; - -int xmon_wants_key, xmon_adb_keycode; - -static inline void udbg_adb_poll(void) -{ -#ifdef CONFIG_ADB_PMU - if (input_type == input_adb_pmu) - pmu_poll_adb(); -#endif /* CONFIG_ADB_PMU */ -#ifdef CONFIG_ADB_CUDA - if (input_type == input_adb_cuda) - cuda_poll(); -#endif /* CONFIG_ADB_CUDA */ -} - -#ifdef CONFIG_BOOTX_TEXT - -static int udbg_adb_use_btext; -static int xmon_adb_shiftstate; - -static unsigned char xmon_keytab[128] = - "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */ - "yt123465=97-80]o" /* 0x10 - 0x1f */ - "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */ - "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */ - "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ - "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ - -static unsigned char xmon_shift_keytab[128] = - "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */ - "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */ - "U{IP\rLJ\"K:|" /* 0x20 - 0x2f */ - "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */ - "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ - "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ - -static int udbg_adb_local_getc(void) -{ - int k, t, on; - - xmon_wants_key = 1; - for (;;) { - xmon_adb_keycode = -1; - t = 0; - on = 0; - k = -1; - do { - if (--t < 0) { - on = 1 - on; - btext_drawchar(on? 0xdb: 0x20); - btext_drawchar('\b'); - t = 200000; - } - udbg_adb_poll(); - if (udbg_adb_old_getc_poll) - k = udbg_adb_old_getc_poll(); - } while (k == -1 && xmon_adb_keycode == -1); - if (on) - btext_drawstring(" \b"); - if (k != -1) - return k; - k = xmon_adb_keycode; - - /* test for shift keys */ - if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) { - xmon_adb_shiftstate = (k & 0x80) == 0; - continue; - } - if (k >= 0x80) - continue; /* ignore up transitions */ - k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k]; - if (k != 0) - break; - } - xmon_wants_key = 0; - return k; -} -#endif /* CONFIG_BOOTX_TEXT */ - -static int udbg_adb_getc(void) -{ -#ifdef CONFIG_BOOTX_TEXT - if (udbg_adb_use_btext && input_type != input_adb_none) - return udbg_adb_local_getc(); -#endif - if (udbg_adb_old_getc) - return udbg_adb_old_getc(); - return -1; -} - -/* getc_poll() is not really used, unless you have the xmon-over modem - * hack that doesn't quite concern us here, thus we just poll the low level - * ADB driver to prevent it from timing out and call back the original poll - * routine. - */ -static int udbg_adb_getc_poll(void) -{ - udbg_adb_poll(); - - if (udbg_adb_old_getc_poll) - return udbg_adb_old_getc_poll(); - return -1; -} - -static void udbg_adb_putc(char c) -{ -#ifdef CONFIG_BOOTX_TEXT - if (udbg_adb_use_btext) - btext_drawchar(c); -#endif - if (udbg_adb_old_putc) - return udbg_adb_old_putc(c); -} - -void udbg_adb_init_early(void) -{ -#ifdef CONFIG_BOOTX_TEXT - if (btext_find_display(1) == 0) { - udbg_adb_use_btext = 1; - udbg_putc = udbg_adb_putc; - } -#endif -} - -int udbg_adb_init(int force_btext) -{ - struct device_node *np; - - /* Capture existing callbacks */ - udbg_adb_old_putc = udbg_putc; - udbg_adb_old_getc = udbg_getc; - udbg_adb_old_getc_poll = udbg_getc_poll; - - /* Check if our early init was already called */ - if (udbg_adb_old_putc == udbg_adb_putc) - udbg_adb_old_putc = NULL; -#ifdef CONFIG_BOOTX_TEXT - if (udbg_adb_old_putc == btext_drawchar) - udbg_adb_old_putc = NULL; -#endif - - /* Set ours as output */ - udbg_putc = udbg_adb_putc; - udbg_getc = udbg_adb_getc; - udbg_getc_poll = udbg_adb_getc_poll; - -#ifdef CONFIG_BOOTX_TEXT - /* Check if we should use btext output */ - if (btext_find_display(force_btext) == 0) - udbg_adb_use_btext = 1; -#endif - - /* See if there is a keyboard in the device tree with a parent - * of type "adb". If not, we return a failure, but we keep the - * bext output set for now - */ - for (np = NULL; (np = of_find_node_by_name(np, "keyboard")) != NULL;) { - struct device_node *parent = of_get_parent(np); - int found = (parent && strcmp(parent->type, "adb") == 0); - of_node_put(parent); - if (found) - break; - } - if (np == NULL) - return -ENODEV; - of_node_put(np); - -#ifdef CONFIG_ADB_PMU - if (find_via_pmu()) - input_type = input_adb_pmu; -#endif -#ifdef CONFIG_ADB_CUDA - if (find_via_cuda()) - input_type = input_adb_cuda; -#endif - - /* Same as above: nothing found, keep btext set for output */ - if (input_type == input_adb_none) - return -ENODEV; - - return 0; -} diff --git a/trunk/arch/powerpc/platforms/pseries/Makefile b/trunk/arch/powerpc/platforms/pseries/Makefile index 6accdd155505..06d5ef501218 100644 --- a/trunk/arch/powerpc/platforms/pseries/Makefile +++ b/trunk/arch/powerpc/platforms/pseries/Makefile @@ -1,5 +1,5 @@ obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ - setup.o iommu.o ras.o rtasd.o pci_dlpar.o + setup.o iommu.o ras.o rtasd.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_XICS) += xics.o diff --git a/trunk/arch/powerpc/platforms/pseries/eeh.c b/trunk/arch/powerpc/platforms/pseries/eeh.c index 7fbfd16d72b7..c8d2a40dc5b4 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh.c @@ -1093,15 +1093,6 @@ void eeh_add_device_early(struct device_node *dn) } EXPORT_SYMBOL_GPL(eeh_add_device_early); -void eeh_add_device_tree_early(struct device_node *dn) -{ - struct device_node *sib; - for (sib = dn->child; sib; sib = sib->sibling) - eeh_add_device_tree_early(sib); - eeh_add_device_early(dn); -} -EXPORT_SYMBOL_GPL(eeh_add_device_tree_early); - /** * eeh_add_device_late - perform EEH initialization for the indicated pci device * @dev: pci device for which to set up EEH @@ -1156,23 +1147,6 @@ void eeh_remove_device(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(eeh_remove_device); -void eeh_remove_bus_device(struct pci_dev *dev) -{ - eeh_remove_device(dev); - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - struct pci_bus *bus = dev->subordinate; - struct list_head *ln; - if (!bus) - return; - for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { - struct pci_dev *pdev = pci_dev_b(ln); - if (pdev) - eeh_remove_bus_device(pdev); - } - } -} -EXPORT_SYMBOL_GPL(eeh_remove_bus_device); - static int proc_eeh_show(struct seq_file *m, void *v) { unsigned int cpu; diff --git a/trunk/arch/powerpc/platforms/pseries/iommu.c b/trunk/arch/powerpc/platforms/pseries/iommu.c index 169f9148789c..2043659ea7b1 100644 --- a/trunk/arch/powerpc/platforms/pseries/iommu.c +++ b/trunk/arch/powerpc/platforms/pseries/iommu.c @@ -436,7 +436,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) return; } - ppci = PCI_DN(pdn); + ppci = pdn->data; if (!ppci->iommu_table) { /* Bussubno hasn't been copied yet. * Do it now because iommu_table_setparms_lpar needs it. @@ -483,10 +483,10 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev) * an already allocated iommu table is found and use that. */ - while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL) + while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL) dn = dn->parent; - if (dn && PCI_DN(dn)) { + if (dn && dn->data) { PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table; } else { DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev)); @@ -497,7 +497,7 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti { int err = NOTIFY_OK; struct device_node *np = node; - struct pci_dn *pci = PCI_DN(np); + struct pci_dn *pci = np->data; switch (action) { case PSERIES_RECONFIG_REMOVE: @@ -533,7 +533,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) */ dn = pci_device_to_OF_node(dev); - for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; + for (pdn = dn; pdn && pdn->data && !PCI_DN(pdn)->iommu_table; pdn = pdn->parent) { dma_window = (unsigned int *) get_property(pdn, "ibm,dma-window", NULL); @@ -552,7 +552,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) DBG("Found DMA window, allocating table\n"); } - pci = PCI_DN(pdn); + pci = pdn->data; if (!pci->iommu_table) { /* iommu_table_setparms_lpar needs bussubno. */ pci->bussubno = pci->phb->bus->number; diff --git a/trunk/arch/powerpc/platforms/pseries/lpar.c b/trunk/arch/powerpc/platforms/pseries/lpar.c index 1fe445ab78a6..cf1bc11b3346 100644 --- a/trunk/arch/powerpc/platforms/pseries/lpar.c +++ b/trunk/arch/powerpc/platforms/pseries/lpar.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -61,7 +60,7 @@ extern void pSeries_find_serial_port(void); int vtermno; /* virtual terminal# for udbg */ #define __ALIGNED__ __attribute__((__aligned__(sizeof(long)))) -static void udbg_hvsi_putc(char c) +static void udbg_hvsi_putc(unsigned char c) { /* packet's seqno isn't used anyways */ uint8_t packet[] __ALIGNED__ = { 0xff, 5, 0, 0, c }; @@ -112,7 +111,7 @@ static int udbg_hvsi_getc_poll(void) return ch; } -static int udbg_hvsi_getc(void) +static unsigned char udbg_hvsi_getc(void) { int ch; for (;;) { @@ -128,7 +127,7 @@ static int udbg_hvsi_getc(void) } } -static void udbg_putcLP(char c) +static void udbg_putcLP(unsigned char c) { char buf[16]; unsigned long rc; @@ -173,7 +172,7 @@ static int udbg_getc_pollLP(void) return ch; } -static int udbg_getcLP(void) +static unsigned char udbg_getcLP(void) { int ch; for (;;) { @@ -192,7 +191,7 @@ static int udbg_getcLP(void) /* call this from early_init() for a working debug console on * vterm capable LPAR machines */ -void __init udbg_init_debug_lpar(void) +void udbg_init_debug_lpar(void) { vtermno = 0; udbg_putc = udbg_putcLP; @@ -201,54 +200,63 @@ void __init udbg_init_debug_lpar(void) } /* returns 0 if couldn't find or use /chosen/stdout as console */ -void __init find_udbg_vterm(void) +int find_udbg_vterm(void) { struct device_node *stdout_node; u32 *termno; char *name; - int add_console; + int found = 0; /* find the boot console from /chosen/stdout */ if (!of_chosen) - return; + return 0; name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); if (name == NULL) - return; + return 0; stdout_node = of_find_node_by_path(name); if (!stdout_node) - return; + return 0; + + /* now we have the stdout node; figure out what type of device it is. */ name = (char *)get_property(stdout_node, "name", NULL); if (!name) { printk(KERN_WARNING "stdout node missing 'name' property!\n"); goto out; } - /* The user has requested a console so this is already set up. */ - add_console = !strstr(cmd_line, "console="); - /* Check if it's a virtual terminal */ - if (strncmp(name, "vty", 3) != 0) - goto out; - termno = (u32 *)get_property(stdout_node, "reg", NULL); - if (termno == NULL) - goto out; - vtermno = termno[0]; - - if (device_is_compatible(stdout_node, "hvterm1")) { - udbg_putc = udbg_putcLP; - udbg_getc = udbg_getcLP; - udbg_getc_poll = udbg_getc_pollLP; - if (add_console) - add_preferred_console("hvc", termno[0] & 0xff, NULL); - } else if (device_is_compatible(stdout_node, "hvterm-protocol")) { - vtermno = termno[0]; - udbg_putc = udbg_hvsi_putc; - udbg_getc = udbg_hvsi_getc; - udbg_getc_poll = udbg_hvsi_getc_poll; - if (add_console) - add_preferred_console("hvsi", termno[0] & 0xff, NULL); + if (strncmp(name, "vty", 3) == 0) { + if (device_is_compatible(stdout_node, "hvterm1")) { + termno = (u32 *)get_property(stdout_node, "reg", NULL); + if (termno) { + vtermno = termno[0]; + udbg_putc = udbg_putcLP; + udbg_getc = udbg_getcLP; + udbg_getc_poll = udbg_getc_pollLP; + found = 1; + } + } else if (device_is_compatible(stdout_node, "hvterm-protocol")) { + termno = (u32 *)get_property(stdout_node, "reg", NULL); + if (termno) { + vtermno = termno[0]; + udbg_putc = udbg_hvsi_putc; + udbg_getc = udbg_hvsi_getc; + udbg_getc_poll = udbg_hvsi_getc_poll; + found = 1; + } + } + } else if (strncmp(name, "serial", 6)) { + /* XXX fix ISA serial console */ + printk(KERN_WARNING "serial stdout on LPAR ('%s')! " + "can't print udbg messages\n", + stdout_node->full_name); + } else { + printk(KERN_WARNING "don't know how to print to stdout '%s'\n", + stdout_node->full_name); } + out: of_node_put(stdout_node); + return found; } void vpa_init(int cpu) diff --git a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c b/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c deleted file mode 100644 index 21934784f936..000000000000 --- a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * PCI Dynamic LPAR, PCI Hot Plug and PCI EEH recovery code - * for RPA-compliant PPC64 platform. - * Copyright (C) 2003 Linda Xie - * Copyright (C) 2005 International Business Machines - * - * Updates, 2005, John Rose - * Updates, 2005, Linas Vepstas - * - * 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, GOOD TITLE or - * NON INFRINGEMENT. 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. - */ - -#include -#include - -static struct pci_bus * -find_bus_among_children(struct pci_bus *bus, - struct device_node *dn) -{ - struct pci_bus *child = NULL; - struct list_head *tmp; - struct device_node *busdn; - - busdn = pci_bus_to_OF_node(bus); - if (busdn == dn) - return bus; - - list_for_each(tmp, &bus->children) { - child = find_bus_among_children(pci_bus_b(tmp), dn); - if (child) - break; - }; - return child; -} - -struct pci_bus * -pcibios_find_pci_bus(struct device_node *dn) -{ - struct pci_dn *pdn = dn->data; - - if (!pdn || !pdn->phb || !pdn->phb->bus) - return NULL; - - return find_bus_among_children(pdn->phb->bus, dn); -} - -/** - * pcibios_remove_pci_devices - remove all devices under this bus - * - * Remove all of the PCI devices under this bus both from the - * linux pci device tree, and from the powerpc EEH address cache. - */ -void -pcibios_remove_pci_devices(struct pci_bus *bus) -{ - struct pci_dev *dev, *tmp; - - list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { - eeh_remove_bus_device(dev); - pci_remove_bus_device(dev); - } -} - -/* Must be called before pci_bus_add_devices */ -void -pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) -{ - struct pci_dev *dev; - - list_for_each_entry(dev, &bus->devices, bus_list) { - /* - * Skip already-present devices (which are on the - * global device list.) - */ - if (list_empty(&dev->global_list)) { - int i; - - /* Need to setup IOMMU tables */ - ppc_md.iommu_dev_setup(dev); - - if(fix_bus) - pcibios_fixup_device_resources(dev, bus); - pci_read_irq_line(dev); - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *r = &dev->resource[i]; - - if (r->parent || !r->start || !r->flags) - continue; - pci_claim_resource(dev, i); - } - } - } -} - -static int -pcibios_pci_config_bridge(struct pci_dev *dev) -{ - u8 sec_busno; - struct pci_bus *child_bus; - struct pci_dev *child_dev; - - /* Get busno of downstream bus */ - pci_read_config_byte(dev, PCI_SECONDARY_BUS, &sec_busno); - - /* Add to children of PCI bridge dev->bus */ - child_bus = pci_add_new_bus(dev->bus, dev, sec_busno); - if (!child_bus) { - printk (KERN_ERR "%s: could not add second bus\n", __FUNCTION__); - return -EIO; - } - sprintf(child_bus->name, "PCI Bus #%02x", child_bus->number); - - pci_scan_child_bus(child_bus); - - list_for_each_entry(child_dev, &child_bus->devices, bus_list) { - eeh_add_device_late(child_dev); - } - - /* Fixup new pci devices without touching bus struct */ - pcibios_fixup_new_pci_devices(child_bus, 0); - - /* Make the discovered devices available */ - pci_bus_add_devices(child_bus); - return 0; -} - -/** - * pcibios_add_pci_devices - adds new pci devices to bus - * - * This routine will find and fixup new pci devices under - * the indicated bus. This routine presumes that there - * might already be some devices under this bridge, so - * it carefully tries to add only new devices. (And that - * is how this routine differs from other, similar pcibios - * routines.) - */ -void -pcibios_add_pci_devices(struct pci_bus * bus) -{ - int slotno, num; - struct pci_dev *dev; - struct device_node *dn = pci_bus_to_OF_node(bus); - - eeh_add_device_tree_early(dn); - - /* pci_scan_slot should find all children */ - slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); - num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); - if (num) { - pcibios_fixup_new_pci_devices(bus, 1); - pci_bus_add_devices(bus); - } - - list_for_each_entry(dev, &bus->devices, bus_list) { - eeh_add_device_late (dev); - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) - pcibios_pci_config_bridge(dev); - } -} diff --git a/trunk/arch/powerpc/platforms/pseries/ras.c b/trunk/arch/powerpc/platforms/pseries/ras.c index b046bcf7443d..fbd214d68b07 100644 --- a/trunk/arch/powerpc/platforms/pseries/ras.c +++ b/trunk/arch/powerpc/platforms/pseries/ras.c @@ -49,14 +49,14 @@ #include #include #include -#include - -#include "ras.h" static unsigned char ras_log_buf[RTAS_ERROR_LOG_MAX]; static DEFINE_SPINLOCK(ras_log_buf_lock); -char mce_data_buf[RTAS_ERROR_LOG_MAX]; +char mce_data_buf[RTAS_ERROR_LOG_MAX] +; +/* This is true if we are using the firmware NMI handler (typically LPAR) */ +extern int fwnmi_active; static int ras_get_sensor_state_token; static int ras_check_exception_token; @@ -280,7 +280,7 @@ static void fwnmi_release_errinfo(void) printk("FWNMI: nmi-interlock failed: %d\n", ret); } -int pSeries_system_reset_exception(struct pt_regs *regs) +void pSeries_system_reset_exception(struct pt_regs *regs) { if (fwnmi_active) { struct rtas_error_log *errhdr = fwnmi_get_errinfo(regs); @@ -289,7 +289,6 @@ int pSeries_system_reset_exception(struct pt_regs *regs) } fwnmi_release_errinfo(); } - return 0; /* need to perform reset */ } /* diff --git a/trunk/arch/powerpc/platforms/pseries/ras.h b/trunk/arch/powerpc/platforms/pseries/ras.h deleted file mode 100644 index 0e66b0da55e2..000000000000 --- a/trunk/arch/powerpc/platforms/pseries/ras.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _PSERIES_RAS_H -#define _PSERIES_RAS_H - -struct pt_regs; - -extern int pSeries_system_reset_exception(struct pt_regs *regs); -extern int pSeries_machine_check_exception(struct pt_regs *regs); - -#endif /* _PSERIES_RAS_H */ diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index 8903cf63236a..4a465f067ede 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include "xics.h" @@ -69,7 +68,6 @@ #include #include "plpar_wrappers.h" -#include "ras.h" #ifdef DEBUG #define DBG(fmt...) udbg_printf(fmt) @@ -78,9 +76,16 @@ #endif extern void find_udbg_vterm(void); +extern void system_reset_fwnmi(void); /* from head.S */ +extern void machine_check_fwnmi(void); /* from head.S */ +extern void generic_find_legacy_serial_ports(u64 *physport, + unsigned int *default_speed); int fwnmi_active; /* TRUE if an FWNMI handler is present */ +extern void pSeries_system_reset_exception(struct pt_regs *regs); +extern int pSeries_machine_check_exception(struct pt_regs *regs); + static void pseries_shared_idle(void); static void pseries_dedicated_idle(void); @@ -100,22 +105,18 @@ void pSeries_show_cpuinfo(struct seq_file *m) /* Initialize firmware assisted non-maskable interrupts if * the firmware supports this feature. + * */ static void __init fwnmi_init(void) { - unsigned long system_reset_addr, machine_check_addr; - + int ret; int ibm_nmi_register = rtas_token("ibm,nmi-register"); if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE) return; - - /* If the kernel's not linked at zero we point the firmware at low - * addresses anyway, and use a trampoline to get to the real code. */ - system_reset_addr = __pa(system_reset_fwnmi) - PHYSICAL_START; - machine_check_addr = __pa(machine_check_fwnmi) - PHYSICAL_START; - - if (0 == rtas_call(ibm_nmi_register, 2, 1, NULL, system_reset_addr, - machine_check_addr)) + ret = rtas_call(ibm_nmi_register, 2, 1, NULL, + __pa((unsigned long)system_reset_fwnmi), + __pa((unsigned long)machine_check_fwnmi)); + if (ret == 0) fwnmi_active = 1; } @@ -322,18 +323,15 @@ static void __init pSeries_discover_pic(void) ppc64_interrupt_controller = IC_INVALID; for (np = NULL; (np = of_find_node_by_name(np, "interrupt-controller"));) { typep = (char *)get_property(np, "compatible", NULL); - if (strstr(typep, "open-pic")) { + if (strstr(typep, "open-pic")) ppc64_interrupt_controller = IC_OPEN_PIC; - break; - } else if (strstr(typep, "ppc-xicp")) { + else if (strstr(typep, "ppc-xicp")) ppc64_interrupt_controller = IC_PPC_XIC; - break; - } + else + printk("pSeries_discover_pic: failed to recognize" + " interrupt-controller\n"); + break; } - if (ppc64_interrupt_controller == IC_INVALID) - printk("pSeries_discover_pic: failed to recognize" - " interrupt-controller\n"); - } static void pSeries_mach_cpu_die(void) @@ -367,7 +365,10 @@ static int pseries_set_xdabr(unsigned long dabr) */ static void __init pSeries_init_early(void) { + void *comport; int iommu_off = 0; + unsigned int default_speed; + u64 physport; DBG(" -> pSeries_init_early()\n"); @@ -381,8 +382,17 @@ static void __init pSeries_init_early(void) get_property(of_chosen, "linux,iommu-off", NULL)); } + generic_find_legacy_serial_ports(&physport, &default_speed); + if (platform_is_lpar()) find_udbg_vterm(); + else if (physport) { + /* Map the uart for udbg. */ + comport = (void *)ioremap(physport, 16); + udbg_init_uart(comport, default_speed); + + DBG("Hello World !\n"); + } if (firmware_has_feature(FW_FEATURE_DABR)) ppc_md.set_dabr = pseries_set_dabr; @@ -628,8 +638,5 @@ struct machdep_calls __initdata pSeries_md = { .machine_check_exception = pSeries_machine_check_exception, #ifdef CONFIG_KEXEC .kexec_cpu_down = pseries_kexec_cpu_down, - .machine_kexec = default_machine_kexec, - .machine_kexec_prepare = default_machine_kexec_prepare, - .machine_crash_shutdown = default_machine_crash_shutdown, #endif }; diff --git a/trunk/arch/powerpc/platforms/pseries/xics.c b/trunk/arch/powerpc/platforms/pseries/xics.c index 0c0cfa32eb58..0377decc0719 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.c +++ b/trunk/arch/powerpc/platforms/pseries/xics.c @@ -407,7 +407,7 @@ irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs) smp_message_recv(PPC_MSG_MIGRATE_TASK, regs); } #endif -#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) +#ifdef CONFIG_DEBUGGER if (test_and_clear_bit(PPC_MSG_DEBUGGER_BREAK, &xics_ipi_message[cpu].value)) { mb(); diff --git a/trunk/arch/powerpc/sysdev/Makefile b/trunk/arch/powerpc/sysdev/Makefile index 14b9abde2d27..6b7efcfc352a 100644 --- a/trunk/arch/powerpc/sysdev/Makefile +++ b/trunk/arch/powerpc/sysdev/Makefile @@ -4,6 +4,5 @@ obj-$(CONFIG_PPC_I8259) += i8259.o obj-$(CONFIG_PPC_MPC106) += grackle.o obj-$(CONFIG_BOOKE) += dcr.o obj-$(CONFIG_40x) += dcr.o -obj-$(CONFIG_U3_DART) += dart_iommu.o +obj-$(CONFIG_U3_DART) += u3_iommu.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o -obj-$(CONFIG_83xx) += ipic.o diff --git a/trunk/arch/powerpc/sysdev/dart.h b/trunk/arch/powerpc/sysdev/dart.h index c2d05763ccbe..33ed9ed7fc1e 100644 --- a/trunk/arch/powerpc/sysdev/dart.h +++ b/trunk/arch/powerpc/sysdev/dart.h @@ -20,44 +20,29 @@ #define _POWERPC_SYSDEV_DART_H -/* Offset from base to control register */ -#define DART_CNTL 0 +/* physical base of DART registers */ +#define DART_BASE 0xf8033000UL +/* Offset from base to control register */ +#define DARTCNTL 0 /* Offset from base to exception register */ -#define DART_EXCP_U3 0x10 +#define DARTEXCP 0x10 /* Offset from base to TLB tag registers */ -#define DART_TAGS_U3 0x1000 +#define DARTTAG 0x1000 -/* U4 registers */ -#define DART_BASE_U4 0x10 -#define DART_SIZE_U4 0x20 -#define DART_EXCP_U4 0x30 -#define DART_TAGS_U4 0x1000 /* Control Register fields */ -/* U3 registers */ -#define DART_CNTL_U3_BASE_MASK 0xfffff -#define DART_CNTL_U3_BASE_SHIFT 12 -#define DART_CNTL_U3_FLUSHTLB 0x400 -#define DART_CNTL_U3_ENABLE 0x200 -#define DART_CNTL_U3_SIZE_MASK 0x1ff -#define DART_CNTL_U3_SIZE_SHIFT 0 - -/* U4 registers */ -#define DART_BASE_U4_BASE_MASK 0xffffff -#define DART_BASE_U4_BASE_SHIFT 0 -#define DART_CNTL_U4_FLUSHTLB 0x20000000 -#define DART_CNTL_U4_ENABLE 0x80000000 -#define DART_SIZE_U4_SIZE_MASK 0x1fff -#define DART_SIZE_U4_SIZE_SHIFT 0 - -#define DART_REG(r) (dart + ((r) >> 2)) -#define DART_IN(r) (in_be32(DART_REG(r))) -#define DART_OUT(r,v) (out_be32(DART_REG(r), (v))) +/* base address of table (pfn) */ +#define DARTCNTL_BASE_MASK 0xfffff +#define DARTCNTL_BASE_SHIFT 12 +#define DARTCNTL_FLUSHTLB 0x400 +#define DARTCNTL_ENABLE 0x200 /* size of table in pages */ +#define DARTCNTL_SIZE_MASK 0x1ff +#define DARTCNTL_SIZE_SHIFT 0 /* DART table fields */ diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index 4f26304d0263..58d1cc2023c8 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -13,9 +13,6 @@ */ #undef DEBUG -#undef DEBUG_IPI -#undef DEBUG_IRQ -#undef DEBUG_LOW #include #include @@ -48,11 +45,7 @@ static struct mpic *mpic_primary; static DEFINE_SPINLOCK(mpic_lock); #ifdef CONFIG_PPC32 /* XXX for now */ -#ifdef CONFIG_IRQ_ALL_CPUS -#define distribute_irqs (1) -#else -#define distribute_irqs (0) -#endif +#define distribute_irqs CONFIG_IRQ_ALL_CPUS #endif /* @@ -171,129 +164,70 @@ static void __init mpic_test_broken_ipi(struct mpic *mpic) /* Test if an interrupt is sourced from HyperTransport (used on broken U3s) * to force the edge setting on the MPIC and do the ack workaround. */ -static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source) +static inline int mpic_is_ht_interrupt(struct mpic *mpic, unsigned int source_no) { - if (source >= 128 || !mpic->fixups) + if (source_no >= 128 || !mpic->fixups) return 0; - return mpic->fixups[source].base != NULL; -} - - -static inline void mpic_ht_end_irq(struct mpic *mpic, unsigned int source) -{ - struct mpic_irq_fixup *fixup = &mpic->fixups[source]; - - if (fixup->applebase) { - unsigned int soff = (fixup->index >> 3) & ~3; - unsigned int mask = 1U << (fixup->index & 0x1f); - writel(mask, fixup->applebase + soff); - } else { - spin_lock(&mpic->fixup_lock); - writeb(0x11 + 2 * fixup->index, fixup->base + 2); - writel(fixup->data, fixup->base + 4); - spin_unlock(&mpic->fixup_lock); - } + return mpic->fixups[source_no].base != NULL; } -static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source, - unsigned int irqflags) +static inline void mpic_apic_end_irq(struct mpic *mpic, unsigned int source_no) { - struct mpic_irq_fixup *fixup = &mpic->fixups[source]; - unsigned long flags; + struct mpic_irq_fixup *fixup = &mpic->fixups[source_no]; u32 tmp; - if (fixup->base == NULL) - return; - - DBG("startup_ht_interrupt(%u, %u) index: %d\n", - source, irqflags, fixup->index); - spin_lock_irqsave(&mpic->fixup_lock, flags); - /* Enable and configure */ - writeb(0x10 + 2 * fixup->index, fixup->base + 2); - tmp = readl(fixup->base + 4); - tmp &= ~(0x23U); - if (irqflags & IRQ_LEVEL) - tmp |= 0x22; - writel(tmp, fixup->base + 4); - spin_unlock_irqrestore(&mpic->fixup_lock, flags); + spin_lock(&mpic->fixup_lock); + writeb(0x11 + 2 * fixup->irq, fixup->base); + tmp = readl(fixup->base + 2); + writel(tmp | 0x80000000ul, fixup->base + 2); + /* config writes shouldn't be posted but let's be safe ... */ + (void)readl(fixup->base + 2); + spin_unlock(&mpic->fixup_lock); } -static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source, - unsigned int irqflags) + +static void __init mpic_amd8111_read_irq(struct mpic *mpic, u8 __iomem *devbase) { - struct mpic_irq_fixup *fixup = &mpic->fixups[source]; - unsigned long flags; + int i, irq; u32 tmp; - if (fixup->base == NULL) - return; - - DBG("shutdown_ht_interrupt(%u, %u)\n", source, irqflags); + printk(KERN_INFO "mpic: - Workarounds on AMD 8111 @ %p\n", devbase); - /* Disable */ - spin_lock_irqsave(&mpic->fixup_lock, flags); - writeb(0x10 + 2 * fixup->index, fixup->base + 2); - tmp = readl(fixup->base + 4); - tmp &= ~1U; - writel(tmp, fixup->base + 4); - spin_unlock_irqrestore(&mpic->fixup_lock, flags); + for (i=0; i < 24; i++) { + writeb(0x10 + 2*i, devbase + 0xf2); + tmp = readl(devbase + 0xf4); + if ((tmp & 0x1) || !(tmp & 0x20)) + continue; + irq = (tmp >> 16) & 0xff; + mpic->fixups[irq].irq = i; + mpic->fixups[irq].base = devbase + 0xf2; + } } - -static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase, - unsigned int devfn, u32 vdid) + +static void __init mpic_amd8131_read_irq(struct mpic *mpic, u8 __iomem *devbase) { - int i, irq, n; - u8 __iomem *base; + int i, irq; u32 tmp; - u8 pos; - - for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0; - pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) { - u8 id = readb(devbase + pos + PCI_CAP_LIST_ID); - if (id == PCI_CAP_ID_HT_IRQCONF) { - id = readb(devbase + pos + 3); - if (id == 0x80) - break; - } - } - if (pos == 0) - return; - - base = devbase + pos; - writeb(0x01, base + 2); - n = (readl(base + 4) >> 16) & 0xff; - printk(KERN_INFO "mpic: - HT:%02x.%x [0x%02x] vendor %04x device %04x" - " has %d irqs\n", - devfn >> 3, devfn & 0x7, pos, vdid & 0xffff, vdid >> 16, n + 1); + printk(KERN_INFO "mpic: - Workarounds on AMD 8131 @ %p\n", devbase); - for (i = 0; i <= n; i++) { - writeb(0x10 + 2 * i, base + 2); - tmp = readl(base + 4); + for (i=0; i < 4; i++) { + writeb(0x10 + 2*i, devbase + 0xba); + tmp = readl(devbase + 0xbc); + if ((tmp & 0x1) || !(tmp & 0x20)) + continue; irq = (tmp >> 16) & 0xff; - DBG("HT PIC index 0x%x, irq 0x%x, tmp: %08x\n", i, irq, tmp); - /* mask it , will be unmasked later */ - tmp |= 0x1; - writel(tmp, base + 4); - mpic->fixups[irq].index = i; - mpic->fixups[irq].base = base; - /* Apple HT PIC has a non-standard way of doing EOIs */ - if ((vdid & 0xffff) == 0x106b) - mpic->fixups[irq].applebase = devbase + 0x60; - else - mpic->fixups[irq].applebase = NULL; - writeb(0x11 + 2 * i, base + 2); - mpic->fixups[irq].data = readl(base + 4) | 0x80000000; + mpic->fixups[irq].irq = i; + mpic->fixups[irq].base = devbase + 0xba; } } - -static void __init mpic_scan_ht_pics(struct mpic *mpic) +static void __init mpic_scan_ioapics(struct mpic *mpic) { unsigned int devfn; u8 __iomem *cfgspace; - printk(KERN_INFO "mpic: Setting up HT PICs workarounds for U3/U4\n"); + printk(KERN_INFO "mpic: Setting up IO-APICs workarounds for U3\n"); /* Allocate fixups array */ mpic->fixups = alloc_bootmem(128 * sizeof(struct mpic_irq_fixup)); @@ -303,20 +237,21 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) /* Init spinlock */ spin_lock_init(&mpic->fixup_lock); - /* Map U3 config space. We assume all IO-APICs are on the primary bus - * so we only need to map 64kB. + /* Map u3 config space. We assume all IO-APICs are on the primary bus + * and slot will never be above "0xf" so we only need to map 32k */ - cfgspace = ioremap(0xf2000000, 0x10000); + cfgspace = (unsigned char __iomem *)ioremap(0xf2000000, 0x8000); BUG_ON(cfgspace == NULL); - /* Now we scan all slots. We do a very quick scan, we read the header - * type, vendor ID and device ID only, that's plenty enough + /* Now we scan all slots. We do a very quick scan, we read the header type, + * vendor ID and device ID only, that's plenty enough */ - for (devfn = 0; devfn < 0x100; devfn++) { + for (devfn = 0; devfn < PCI_DEVFN(0x10,0); devfn ++) { u8 __iomem *devbase = cfgspace + (devfn << 8); u8 hdr_type = readb(devbase + PCI_HEADER_TYPE); u32 l = readl(devbase + PCI_VENDOR_ID); - u16 s; + u16 vendor_id, device_id; + int multifunc = 0; DBG("devfn %x, l: %x\n", devfn, l); @@ -324,16 +259,22 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || l == 0xffff0000) goto next; - /* Check if is supports capability lists */ - s = readw(devbase + PCI_STATUS); - if (!(s & PCI_STATUS_CAP_LIST)) - goto next; - - mpic_scan_ht_pic(mpic, devbase, devfn, l); + /* Check if it's a multifunction device (only really used + * to function 0 though + */ + multifunc = !!(hdr_type & 0x80); + vendor_id = l & 0xffff; + device_id = (l >> 16) & 0xffff; + + /* If a known device, go to fixup setup code */ + if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7460) + mpic_amd8111_read_irq(mpic, devbase); + if (vendor_id == PCI_VENDOR_ID_AMD && device_id == 0x7450) + mpic_amd8131_read_irq(mpic, devbase); next: /* next device, if function 0 */ - if (PCI_FUNC(devfn) == 0 && (hdr_type & 0x80) == 0) + if ((PCI_FUNC(devfn) == 0) && !multifunc) devfn += 7; } } @@ -430,31 +371,6 @@ static void mpic_enable_irq(unsigned int irq) break; } } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK); - -#ifdef CONFIG_MPIC_BROKEN_U3 - if (mpic->flags & MPIC_BROKEN_U3) { - unsigned int src = irq - mpic->irq_offset; - if (mpic_is_ht_interrupt(mpic, src) && - (irq_desc[irq].status & IRQ_LEVEL)) - mpic_ht_end_irq(mpic, src); - } -#endif /* CONFIG_MPIC_BROKEN_U3 */ -} - -static unsigned int mpic_startup_irq(unsigned int irq) -{ -#ifdef CONFIG_MPIC_BROKEN_U3 - struct mpic *mpic = mpic_from_irq(irq); - unsigned int src = irq - mpic->irq_offset; - - if (mpic_is_ht_interrupt(mpic, src)) - mpic_startup_ht_interrupt(mpic, src, irq_desc[irq].status); - -#endif /* CONFIG_MPIC_BROKEN_U3 */ - - mpic_enable_irq(irq); - - return 0; } static void mpic_disable_irq(unsigned int irq) @@ -478,27 +394,12 @@ static void mpic_disable_irq(unsigned int irq) } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK)); } -static void mpic_shutdown_irq(unsigned int irq) -{ -#ifdef CONFIG_MPIC_BROKEN_U3 - struct mpic *mpic = mpic_from_irq(irq); - unsigned int src = irq - mpic->irq_offset; - - if (mpic_is_ht_interrupt(mpic, src)) - mpic_shutdown_ht_interrupt(mpic, src, irq_desc[irq].status); - -#endif /* CONFIG_MPIC_BROKEN_U3 */ - - mpic_disable_irq(irq); -} - static void mpic_end_irq(unsigned int irq) { struct mpic *mpic = mpic_from_irq(irq); -#ifdef DEBUG_IRQ DBG("%s: end_irq: %d\n", mpic->name, irq); -#endif + /* We always EOI on end_irq() even for edge interrupts since that * should only lower the priority, the MPIC should have properly * latched another edge interrupt coming in anyway @@ -507,9 +408,8 @@ static void mpic_end_irq(unsigned int irq) #ifdef CONFIG_MPIC_BROKEN_U3 if (mpic->flags & MPIC_BROKEN_U3) { unsigned int src = irq - mpic->irq_offset; - if (mpic_is_ht_interrupt(mpic, src) && - (irq_desc[irq].status & IRQ_LEVEL)) - mpic_ht_end_irq(mpic, src); + if (mpic_is_ht_interrupt(mpic, src)) + mpic_apic_end_irq(mpic, src); } #endif /* CONFIG_MPIC_BROKEN_U3 */ @@ -590,8 +490,6 @@ struct mpic * __init mpic_alloc(unsigned long phys_addr, mpic->name = name; mpic->hc_irq.typename = name; - mpic->hc_irq.startup = mpic_startup_irq; - mpic->hc_irq.shutdown = mpic_shutdown_irq; mpic->hc_irq.enable = mpic_enable_irq; mpic->hc_irq.disable = mpic_disable_irq; mpic->hc_irq.end = mpic_end_irq; @@ -760,10 +658,10 @@ void __init mpic_init(struct mpic *mpic) mpic->irq_count = mpic->num_sources; #ifdef CONFIG_MPIC_BROKEN_U3 - /* Do the HT PIC fixups on U3 broken mpic */ + /* Do the ioapic fixups on U3 broken mpic */ DBG("MPIC flags: %x\n", mpic->flags); if ((mpic->flags & MPIC_BROKEN_U3) && (mpic->flags & MPIC_PRIMARY)) - mpic_scan_ht_pics(mpic); + mpic_scan_ioapics(mpic); #endif /* CONFIG_MPIC_BROKEN_U3 */ for (i = 0; i < mpic->num_sources; i++) { @@ -950,9 +848,7 @@ void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask) BUG_ON(mpic == NULL); -#ifdef DEBUG_IPI DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no); -#endif mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10, mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); @@ -963,28 +859,19 @@ int mpic_get_one_irq(struct mpic *mpic, struct pt_regs *regs) u32 irq; irq = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK; -#ifdef DEBUG_LOW DBG("%s: get_one_irq(): %d\n", mpic->name, irq); -#endif + if (mpic->cascade && irq == mpic->cascade_vec) { -#ifdef DEBUG_LOW DBG("%s: cascading ...\n", mpic->name); -#endif irq = mpic->cascade(regs, mpic->cascade_data); mpic_eoi(mpic); return irq; } if (unlikely(irq == MPIC_VEC_SPURRIOUS)) return -1; - if (irq < MPIC_VEC_IPI_0) { -#ifdef DEBUG_IRQ - DBG("%s: irq %d\n", mpic->name, irq + mpic->irq_offset); -#endif + if (irq < MPIC_VEC_IPI_0) return irq + mpic->irq_offset; - } -#ifdef DEBUG_IPI DBG("%s: ipi %d !\n", mpic->name, irq - MPIC_VEC_IPI_0); -#endif return irq - MPIC_VEC_IPI_0 + mpic->ipi_offset; } diff --git a/trunk/arch/powerpc/sysdev/dart_iommu.c b/trunk/arch/powerpc/sysdev/u3_iommu.c similarity index 65% rename from trunk/arch/powerpc/sysdev/dart_iommu.c rename to trunk/arch/powerpc/sysdev/u3_iommu.c index e00b46b9514e..5c1a26a6d00c 100644 --- a/trunk/arch/powerpc/sysdev/dart_iommu.c +++ b/trunk/arch/powerpc/sysdev/u3_iommu.c @@ -1,27 +1,25 @@ /* - * arch/powerpc/sysdev/dart_iommu.c + * arch/powerpc/sysdev/u3_iommu.c * * Copyright (C) 2004 Olof Johansson , IBM Corporation - * Copyright (C) 2005 Benjamin Herrenschmidt , - * IBM Corporation * * Based on pSeries_iommu.c: * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation * Copyright (C) 2004 Olof Johansson , IBM Corporation * - * Dynamic DMA mapping support, Apple U3, U4 & IBM CPC925 "DART" iommu. - * + * Dynamic DMA mapping support, Apple U3 & IBM CPC925 "DART" iommu. * + * * 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 @@ -59,22 +57,21 @@ static unsigned long dart_tablesize; static u32 *dart_vbase; /* Mapped base address for the dart */ -static unsigned int *__iomem dart; +static unsigned int *dart; /* Dummy val that entries are set to when unused */ static unsigned int dart_emptyval; -static struct iommu_table iommu_table_dart; -static int iommu_table_dart_inited; +static struct iommu_table iommu_table_u3; +static int iommu_table_u3_inited; static int dart_dirty; -static int dart_is_u4; #define DBG(...) static inline void dart_tlb_invalidate_all(void) { unsigned long l = 0; - unsigned int reg, inv_bit; + unsigned int reg; unsigned long limit; DBG("dart: flush\n"); @@ -84,28 +81,29 @@ static inline void dart_tlb_invalidate_all(void) * * Gotcha: Sometimes, the DART won't detect that the bit gets * set. If so, clear it and set it again. - */ + */ limit = 0; - inv_bit = dart_is_u4 ? DART_CNTL_U4_FLUSHTLB : DART_CNTL_U3_FLUSHTLB; retry: - l = 0; - reg = DART_IN(DART_CNTL); - reg |= inv_bit; - DART_OUT(DART_CNTL, reg); + reg = in_be32((unsigned int *)dart+DARTCNTL); + reg |= DARTCNTL_FLUSHTLB; + out_be32((unsigned int *)dart+DARTCNTL, reg); - while ((DART_IN(DART_CNTL) & inv_bit) && l < (1L << limit)) + l = 0; + while ((in_be32((unsigned int *)dart+DARTCNTL) & DARTCNTL_FLUSHTLB) && + l < (1L<it_base) + index; - + /* On U3, all memory is contigous, so we can move this * out of the loop. */ @@ -150,7 +148,7 @@ static void dart_build(struct iommu_table *tbl, long index, static void dart_free(struct iommu_table *tbl, long index, long npages) { unsigned int *dp; - + /* We don't worry about flushing the TLB cache. The only drawback of * not doing it is that we won't catch buggy device drivers doing * bad DMAs, but then no 32-bit architecture ever does either. @@ -162,7 +160,7 @@ static void dart_free(struct iommu_table *tbl, long index, long npages) npages <<= DART_PAGE_FACTOR; dp = ((unsigned int *)tbl->it_base) + index; - + while (npages--) *(dp++) = dart_emptyval; } @@ -170,25 +168,20 @@ static void dart_free(struct iommu_table *tbl, long index, long npages) static int dart_init(struct device_node *dart_node) { + unsigned int regword; unsigned int i; - unsigned long tmp, base, size; - struct resource r; + unsigned long tmp; if (dart_tablebase == 0 || dart_tablesize == 0) { - printk(KERN_INFO "DART: table not allocated, using " - "direct DMA\n"); + printk(KERN_INFO "U3-DART: table not allocated, using direct DMA\n"); return -ENODEV; } - if (of_address_to_resource(dart_node, 0, &r)) - panic("DART: can't get register base ! "); - /* Make sure nothing from the DART range remains in the CPU cache * from a previous mapping that existed before the kernel took * over */ - flush_dcache_phys_range(dart_tablebase, - dart_tablebase + dart_tablesize); + flush_dcache_phys_range(dart_tablebase, dart_tablebase + dart_tablesize); /* Allocate a spare page to map all invalid DART pages. We need to do * that to work around what looks like a problem with the HT bridge @@ -196,16 +189,21 @@ static int dart_init(struct device_node *dart_node) */ tmp = lmb_alloc(DART_PAGE_SIZE, DART_PAGE_SIZE); if (!tmp) - panic("DART: Cannot allocate spare page!"); - dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) & - DARTMAP_RPNMASK); + panic("U3-DART: Cannot allocate spare page!"); + dart_emptyval = DARTMAP_VALID | ((tmp >> DART_PAGE_SHIFT) & DARTMAP_RPNMASK); - /* Map in DART registers */ - dart = ioremap(r.start, r.end - r.start + 1); + /* Map in DART registers. FIXME: Use device node to get base address */ + dart = ioremap(DART_BASE, 0x7000); if (dart == NULL) - panic("DART: Cannot map registers!"); + panic("U3-DART: Cannot map registers!"); - /* Map in DART table */ + /* Set initial control register contents: table base, + * table size and enable bit + */ + regword = DARTCNTL_ENABLE | + ((dart_tablebase >> DART_PAGE_SHIFT) << DARTCNTL_BASE_SHIFT) | + (((dart_tablesize >> DART_PAGE_SHIFT) & DARTCNTL_SIZE_MASK) + << DARTCNTL_SIZE_SHIFT); dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize); /* Fill initial table */ @@ -213,50 +211,36 @@ static int dart_init(struct device_node *dart_node) dart_vbase[i] = dart_emptyval; /* Initialize DART with table base and enable it. */ - base = dart_tablebase >> DART_PAGE_SHIFT; - size = dart_tablesize >> DART_PAGE_SHIFT; - if (dart_is_u4) { - size &= DART_SIZE_U4_SIZE_MASK; - DART_OUT(DART_BASE_U4, base); - DART_OUT(DART_SIZE_U4, size); - DART_OUT(DART_CNTL, DART_CNTL_U4_ENABLE); - } else { - size &= DART_CNTL_U3_SIZE_MASK; - DART_OUT(DART_CNTL, - DART_CNTL_U3_ENABLE | - (base << DART_CNTL_U3_BASE_SHIFT) | - (size << DART_CNTL_U3_SIZE_SHIFT)); - } + out_be32((unsigned int *)dart, regword); /* Invalidate DART to get rid of possible stale TLBs */ dart_tlb_invalidate_all(); - printk(KERN_INFO "DART IOMMU initialized for %s type chipset\n", - dart_is_u4 ? "U4" : "U3"); + printk(KERN_INFO "U3/CPC925 DART IOMMU initialized\n"); return 0; } -static void iommu_table_dart_setup(void) +static void iommu_table_u3_setup(void) { - iommu_table_dart.it_busno = 0; - iommu_table_dart.it_offset = 0; + iommu_table_u3.it_busno = 0; + iommu_table_u3.it_offset = 0; /* it_size is in number of entries */ - iommu_table_dart.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR; + iommu_table_u3.it_size = (dart_tablesize / sizeof(u32)) >> DART_PAGE_FACTOR; /* Initialize the common IOMMU code */ - iommu_table_dart.it_base = (unsigned long)dart_vbase; - iommu_table_dart.it_index = 0; - iommu_table_dart.it_blocksize = 1; - iommu_init_table(&iommu_table_dart); + iommu_table_u3.it_base = (unsigned long)dart_vbase; + iommu_table_u3.it_index = 0; + iommu_table_u3.it_blocksize = 1; + iommu_init_table(&iommu_table_u3); /* Reserve the last page of the DART to avoid possible prefetch * past the DART mapped area */ - set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map); + set_bit(iommu_table_u3.it_size - 1, iommu_table_u3.it_map); } -static void iommu_dev_setup_dart(struct pci_dev *dev) +static void iommu_dev_setup_u3(struct pci_dev *dev) { struct device_node *dn; @@ -270,39 +254,35 @@ static void iommu_dev_setup_dart(struct pci_dev *dev) dn = pci_device_to_OF_node(dev); if (dn) - PCI_DN(dn)->iommu_table = &iommu_table_dart; + PCI_DN(dn)->iommu_table = &iommu_table_u3; } -static void iommu_bus_setup_dart(struct pci_bus *bus) +static void iommu_bus_setup_u3(struct pci_bus *bus) { struct device_node *dn; - if (!iommu_table_dart_inited) { - iommu_table_dart_inited = 1; - iommu_table_dart_setup(); + if (!iommu_table_u3_inited) { + iommu_table_u3_inited = 1; + iommu_table_u3_setup(); } dn = pci_bus_to_OF_node(bus); if (dn) - PCI_DN(dn)->iommu_table = &iommu_table_dart; + PCI_DN(dn)->iommu_table = &iommu_table_u3; } static void iommu_dev_setup_null(struct pci_dev *dev) { } static void iommu_bus_setup_null(struct pci_bus *bus) { } -void iommu_init_early_dart(void) +void iommu_init_early_u3(void) { struct device_node *dn; /* Find the DART in the device-tree */ dn = of_find_compatible_node(NULL, "dart", "u3-dart"); - if (dn == NULL) { - dn = of_find_compatible_node(NULL, "dart", "u4-dart"); - if (dn == NULL) - goto bail; - dart_is_u4 = 1; - } + if (dn == NULL) + return; /* Setup low level TCE operations for the core IOMMU code */ ppc_md.tce_build = dart_build; @@ -310,27 +290,24 @@ void iommu_init_early_dart(void) ppc_md.tce_flush = dart_flush; /* Initialize the DART HW */ - if (dart_init(dn) == 0) { - ppc_md.iommu_dev_setup = iommu_dev_setup_dart; - ppc_md.iommu_bus_setup = iommu_bus_setup_dart; + if (dart_init(dn)) { + /* If init failed, use direct iommu and null setup functions */ + ppc_md.iommu_dev_setup = iommu_dev_setup_null; + ppc_md.iommu_bus_setup = iommu_bus_setup_null; /* Setup pci_dma ops */ - pci_iommu_init(); + pci_direct_iommu_init(); + } else { + ppc_md.iommu_dev_setup = iommu_dev_setup_u3; + ppc_md.iommu_bus_setup = iommu_bus_setup_u3; - return; + /* Setup pci_dma ops */ + pci_iommu_init(); } - - bail: - /* If init failed, use direct iommu and null setup functions */ - ppc_md.iommu_dev_setup = iommu_dev_setup_null; - ppc_md.iommu_bus_setup = iommu_bus_setup_null; - - /* Setup pci_dma ops */ - pci_direct_iommu_init(); } -void __init alloc_dart_table(void) +void __init alloc_u3_dart_table(void) { /* Only reserve DART space if machine has more than 2GB of RAM * or if requested with iommu=on on cmdline. @@ -346,5 +323,5 @@ void __init alloc_dart_table(void) dart_tablebase = (unsigned long) abs_to_virt(lmb_alloc_base(1UL<<24, 1UL<<24, 0x80000000L)); - printk(KERN_INFO "DART table allocated at: %lx\n", dart_tablebase); + printk(KERN_INFO "U3-DART allocated at: %lx\n", dart_tablebase); } diff --git a/trunk/arch/powerpc/xmon/Makefile b/trunk/arch/powerpc/xmon/Makefile index 109d874ecfbe..b20312e5ed27 100644 --- a/trunk/arch/powerpc/xmon/Makefile +++ b/trunk/arch/powerpc/xmon/Makefile @@ -3,5 +3,9 @@ ifdef CONFIG_PPC64 EXTRA_CFLAGS += -mno-minimal-toc endif -obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o start.o \ - nonstdio.o + +obj-$(CONFIG_8xx) += start_8xx.o +obj-$(CONFIG_6xx) += start_32.o +obj-$(CONFIG_4xx) += start_32.o +obj-$(CONFIG_PPC64) += start_64.o +obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o nonstdio.o diff --git a/trunk/arch/powerpc/xmon/start_32.c b/trunk/arch/powerpc/xmon/start_32.c new file mode 100644 index 000000000000..c2464df4217e --- /dev/null +++ b/trunk/arch/powerpc/xmon/start_32.c @@ -0,0 +1,441 @@ +/* + * Copyright (C) 1996 Paul Mackerras. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "nonstdio.h" + +static volatile unsigned char __iomem *sccc, *sccd; +unsigned int TXRDY, RXRDY, DLAB; + +static int use_serial; +static int use_screen; +static int via_modem; +static int xmon_use_sccb; +static struct device_node *channel_node; + +void buf_access(void) +{ + if (DLAB) + sccd[3] &= ~DLAB; /* reset DLAB */ +} + +extern int adb_init(void); + +#ifdef CONFIG_PPC_CHRP +/* + * This looks in the "ranges" property for the primary PCI host bridge + * to find the physical address of the start of PCI/ISA I/O space. + * It is basically a cut-down version of pci_process_bridge_OF_ranges. + */ +static unsigned long chrp_find_phys_io_base(void) +{ + struct device_node *node; + unsigned int *ranges; + unsigned long base = CHRP_ISA_IO_BASE; + int rlen = 0; + int np; + + node = find_devices("isa"); + if (node != NULL) { + node = node->parent; + if (node == NULL || node->type == NULL + || strcmp(node->type, "pci") != 0) + node = NULL; + } + if (node == NULL) + node = find_devices("pci"); + if (node == NULL) + return base; + + ranges = (unsigned int *) get_property(node, "ranges", &rlen); + np = prom_n_addr_cells(node) + 5; + while ((rlen -= np * sizeof(unsigned int)) >= 0) { + if ((ranges[0] >> 24) == 1 && ranges[2] == 0) { + /* I/O space starting at 0, grab the phys base */ + base = ranges[np - 3]; + break; + } + ranges += np; + } + return base; +} +#endif /* CONFIG_PPC_CHRP */ + +void xmon_map_scc(void) +{ +#ifdef CONFIG_PPC_MULTIPLATFORM + volatile unsigned char __iomem *base; + + if (_machine == _MACH_Pmac) { + struct device_node *np; + unsigned long addr; +#ifdef CONFIG_BOOTX_TEXT + if (!use_screen && !use_serial + && !machine_is_compatible("iMac")) { + /* see if there is a keyboard in the device tree + with a parent of type "adb" */ + for (np = find_devices("keyboard"); np; np = np->next) + if (np->parent && np->parent->type + && strcmp(np->parent->type, "adb") == 0) + break; + + /* needs to be hacked if xmon_printk is to be used + from within find_via_pmu() */ +#ifdef CONFIG_ADB_PMU + if (np != NULL && boot_text_mapped && find_via_pmu()) + use_screen = 1; +#endif +#ifdef CONFIG_ADB_CUDA + if (np != NULL && boot_text_mapped && find_via_cuda()) + use_screen = 1; +#endif + } + if (!use_screen && (np = find_devices("escc")) != NULL) { + /* + * look for the device node for the serial port + * we're using and see if it says it has a modem + */ + char *name = xmon_use_sccb? "ch-b": "ch-a"; + char *slots; + int l; + + np = np->child; + while (np != NULL && strcmp(np->name, name) != 0) + np = np->sibling; + if (np != NULL) { + /* XXX should parse this properly */ + channel_node = np; + slots = get_property(np, "slot-names", &l); + if (slots != NULL && l >= 10 + && strcmp(slots+4, "Modem") == 0) + via_modem = 1; + } + } + btext_drawstring("xmon uses "); + if (use_screen) + btext_drawstring("screen and keyboard\n"); + else { + if (via_modem) + btext_drawstring("modem on "); + btext_drawstring(xmon_use_sccb? "printer": "modem"); + btext_drawstring(" port\n"); + } + +#endif /* CONFIG_BOOTX_TEXT */ + +#ifdef CHRP_ESCC + addr = 0xc1013020; +#else + addr = 0xf3013020; +#endif + TXRDY = 4; + RXRDY = 1; + + np = find_devices("mac-io"); + if (np && np->n_addrs) + addr = np->addrs[0].address + 0x13020; + base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE); + sccc = base + (addr & ~PAGE_MASK); + sccd = sccc + 0x10; + + } else { + base = (volatile unsigned char *) isa_io_base; + +#ifdef CONFIG_PPC_CHRP + if (_machine == _MACH_chrp) + base = (volatile unsigned char __iomem *) + ioremap(chrp_find_phys_io_base(), 0x1000); +#endif + + sccc = base + 0x3fd; + sccd = base + 0x3f8; + if (xmon_use_sccb) { + sccc -= 0x100; + sccd -= 0x100; + } + TXRDY = 0x20; + RXRDY = 1; + DLAB = 0x80; + } +#elif defined(CONFIG_GEMINI) + /* should already be mapped by the kernel boot */ + sccc = (volatile unsigned char __iomem *) 0xffeffb0d; + sccd = (volatile unsigned char __iomem *) 0xffeffb08; + TXRDY = 0x20; + RXRDY = 1; + DLAB = 0x80; +#elif defined(CONFIG_405GP) + sccc = (volatile unsigned char __iomem *)0xef600305; + sccd = (volatile unsigned char __iomem *)0xef600300; + TXRDY = 0x20; + RXRDY = 1; + DLAB = 0x80; +#endif /* platform */ +} + +static int scc_initialized = 0; + +void xmon_init_scc(void); +extern void cuda_poll(void); + +static inline void do_poll_adb(void) +{ +#ifdef CONFIG_ADB_PMU + if (sys_ctrler == SYS_CTRLER_PMU) + pmu_poll_adb(); +#endif /* CONFIG_ADB_PMU */ +#ifdef CONFIG_ADB_CUDA + if (sys_ctrler == SYS_CTRLER_CUDA) + cuda_poll(); +#endif /* CONFIG_ADB_CUDA */ +} + +int xmon_write(void *ptr, int nb) +{ + char *p = ptr; + int i, c, ct; + +#ifdef CONFIG_SMP + static unsigned long xmon_write_lock; + int lock_wait = 1000000; + int locked; + + while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0) + if (--lock_wait == 0) + break; +#endif + +#ifdef CONFIG_BOOTX_TEXT + if (use_screen) { + /* write it on the screen */ + for (i = 0; i < nb; ++i) + btext_drawchar(*p++); + goto out; + } +#endif + if (!scc_initialized) + xmon_init_scc(); + ct = 0; + for (i = 0; i < nb; ++i) { + while ((*sccc & TXRDY) == 0) + do_poll_adb(); + c = p[i]; + if (c == '\n' && !ct) { + c = '\r'; + ct = 1; + --i; + } else { + ct = 0; + } + buf_access(); + *sccd = c; + eieio(); + } + + out: +#ifdef CONFIG_SMP + if (!locked) + clear_bit(0, &xmon_write_lock); +#endif + return nb; +} + +int xmon_wants_key; +int xmon_adb_keycode; + +#ifdef CONFIG_BOOTX_TEXT +static int xmon_adb_shiftstate; + +static unsigned char xmon_keytab[128] = + "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */ + "yt123465=97-80]o" /* 0x10 - 0x1f */ + "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */ + "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */ + "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ + "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ + +static unsigned char xmon_shift_keytab[128] = + "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */ + "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */ + "U{IP\rLJ\"K:|" /* 0x20 - 0x2f */ + "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */ + "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */ + "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */ + +static int xmon_get_adb_key(void) +{ + int k, t, on; + + xmon_wants_key = 1; + for (;;) { + xmon_adb_keycode = -1; + t = 0; + on = 0; + do { + if (--t < 0) { + on = 1 - on; + btext_drawchar(on? 0xdb: 0x20); + btext_drawchar('\b'); + t = 200000; + } + do_poll_adb(); + } while (xmon_adb_keycode == -1); + k = xmon_adb_keycode; + if (on) + btext_drawstring(" \b"); + + /* test for shift keys */ + if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) { + xmon_adb_shiftstate = (k & 0x80) == 0; + continue; + } + if (k >= 0x80) + continue; /* ignore up transitions */ + k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k]; + if (k != 0) + break; + } + xmon_wants_key = 0; + return k; +} +#endif /* CONFIG_BOOTX_TEXT */ + +int xmon_readchar(void) +{ +#ifdef CONFIG_BOOTX_TEXT + if (use_screen) + return xmon_get_adb_key(); +#endif + if (!scc_initialized) + xmon_init_scc(); + while ((*sccc & RXRDY) == 0) + do_poll_adb(); + buf_access(); + return *sccd; +} + +int xmon_read_poll(void) +{ + if ((*sccc & RXRDY) == 0) { + do_poll_adb(); + return -1; + } + buf_access(); + return *sccd; +} + +static unsigned char scc_inittab[] = { + 13, 0, /* set baud rate divisor */ + 12, 1, + 14, 1, /* baud rate gen enable, src=rtxc */ + 11, 0x50, /* clocks = br gen */ + 5, 0xea, /* tx 8 bits, assert DTR & RTS */ + 4, 0x46, /* x16 clock, 1 stop */ + 3, 0xc1, /* rx enable, 8 bits */ +}; + +void xmon_init_scc(void) +{ + if ( _machine == _MACH_chrp ) + { + sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */ + sccd[0] = 12; eieio(); /* DLL = 9600 baud */ + sccd[1] = 0; eieio(); + sccd[2] = 0; eieio(); /* FCR = 0 */ + sccd[3] = 3; eieio(); /* LCR = 8N1 */ + sccd[1] = 0; eieio(); /* IER = 0 */ + } + else if ( _machine == _MACH_Pmac ) + { + int i, x; + unsigned long timeout; + + if (channel_node != 0) + pmac_call_feature( + PMAC_FTR_SCC_ENABLE, + channel_node, + PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1); + printk(KERN_INFO "Serial port locked ON by debugger !\n"); + if (via_modem && channel_node != 0) { + unsigned int t0; + + pmac_call_feature( + PMAC_FTR_MODEM_ENABLE, + channel_node, 0, 1); + printk(KERN_INFO "Modem powered up by debugger !\n"); + t0 = get_tbl(); + timeout = 3 * tb_ticks_per_sec; + if (timeout == 0) + /* assume 25MHz if tb_ticks_per_sec not set */ + timeout = 75000000; + while (get_tbl() - t0 < timeout) + eieio(); + } + /* use the B channel if requested */ + if (xmon_use_sccb) { + sccc = (volatile unsigned char *) + ((unsigned long)sccc & ~0x20); + sccd = sccc + 0x10; + } + for (i = 20000; i != 0; --i) { + x = *sccc; eieio(); + } + *sccc = 9; eieio(); /* reset A or B side */ + *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio(); + for (i = 0; i < sizeof(scc_inittab); ++i) { + *sccc = scc_inittab[i]; + eieio(); + } + } + scc_initialized = 1; + if (via_modem) { + for (;;) { + xmon_write("ATE1V1\r", 7); + if (xmon_expect("OK", 5)) { + xmon_write("ATA\r", 4); + if (xmon_expect("CONNECT", 40)) + break; + } + xmon_write("+++", 3); + xmon_expect("OK", 3); + } + } +} + +void xmon_enter(void) +{ +#ifdef CONFIG_ADB_PMU + if (_machine == _MACH_Pmac) { + pmu_suspend(); + } +#endif +} + +void xmon_leave(void) +{ +#ifdef CONFIG_ADB_PMU + if (_machine == _MACH_Pmac) { + pmu_resume(); + } +#endif +} diff --git a/trunk/arch/powerpc/xmon/start.c b/trunk/arch/powerpc/xmon/start_64.c similarity index 100% rename from trunk/arch/powerpc/xmon/start.c rename to trunk/arch/powerpc/xmon/start_64.c diff --git a/trunk/arch/powerpc/xmon/start_8xx.c b/trunk/arch/powerpc/xmon/start_8xx.c new file mode 100644 index 000000000000..4c17b0486ad5 --- /dev/null +++ b/trunk/arch/powerpc/xmon/start_8xx.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 1996 Paul Mackerras. + * Copyright (C) 2000 Dan Malek. + * Quick hack of Paul's code to make XMON work on 8xx processors. Lots + * of assumptions, like the SMC1 is used, it has been initialized by the + * loader at some point, and we can just stuff and suck bytes. + * We rely upon the 8xx uart driver to support us, as the interface + * changes between boot up and operational phases of the kernel. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "nonstdio.h" + +extern int xmon_8xx_write(char *str, int nb); +extern int xmon_8xx_read_poll(void); +extern int xmon_8xx_read_char(void); + +void xmon_map_scc(void) +{ + cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); +} + +void xmon_init_scc(void); + +int xmon_write(void *ptr, int nb) +{ + return(xmon_8xx_write(ptr, nb)); +} + +int xmon_readchar(void) +{ + return xmon_8xx_read_char(); +} + +int xmon_read_poll(void) +{ + return(xmon_8xx_read_poll()); +} diff --git a/trunk/arch/powerpc/xmon/xmon.c b/trunk/arch/powerpc/xmon/xmon.c index 22612ed5379c..c45a6ad5f3b7 100644 --- a/trunk/arch/powerpc/xmon/xmon.c +++ b/trunk/arch/powerpc/xmon/xmon.c @@ -450,6 +450,7 @@ int xmon_core(struct pt_regs *regs, int fromipi) leave: cpu_clear(cpu, cpus_in_xmon); xmon_fault_jmp[cpu] = NULL; + #else /* UP is simple... */ if (in_xmon) { @@ -804,10 +805,7 @@ cmds(struct pt_regs *excp) break; case 'x': case 'X': - return cmd; case EOF: - printf(" \n"); - mdelay(2000); return cmd; case '?': printf(help_string); @@ -1013,7 +1011,7 @@ static long check_bp_loc(unsigned long addr) unsigned int instr; addr &= ~3; - if (!is_kernel_addr(addr)) { + if (addr < KERNELBASE) { printf("Breakpoints may only be placed at kernel addresses\n"); return 0; } @@ -1064,7 +1062,7 @@ bpt_cmds(void) dabr.address = 0; dabr.enabled = 0; if (scanhex(&dabr.address)) { - if (!is_kernel_addr(dabr.address)) { + if (dabr.address < KERNELBASE) { printf(badaddr); break; } diff --git a/trunk/arch/ppc/Kconfig b/trunk/arch/ppc/Kconfig index e396f4591d59..cc3f64c084c5 100644 --- a/trunk/arch/ppc/Kconfig +++ b/trunk/arch/ppc/Kconfig @@ -8,6 +8,9 @@ config MMU bool default y +config UID16 + bool + config GENERIC_HARDIRQS bool default y diff --git a/trunk/arch/ppc/boot/common/util.S b/trunk/arch/ppc/boot/common/util.S index 368ec035e6cd..c96c9f80521e 100644 --- a/trunk/arch/ppc/boot/common/util.S +++ b/trunk/arch/ppc/boot/common/util.S @@ -234,8 +234,7 @@ udelay: * First, flush the data cache in case it was enabled and may be * holding instructions for copy back. */ - .globl flush_instruction_cache -flush_instruction_cache: +_GLOBAL(flush_instruction_cache) mflr r6 bl flush_data_cache @@ -280,8 +279,7 @@ flush_instruction_cache: * Flush data cache * Do this by just reading lots of stuff into the cache. */ - .globl flush_data_cache -flush_data_cache: +_GLOBAL(flush_data_cache) lis r3,cache_flush_buffer@h ori r3,r3,cache_flush_buffer@l li r4,NUM_CACHE_LINES diff --git a/trunk/arch/ppc/boot/images/Makefile b/trunk/arch/ppc/boot/images/Makefile index 58415d5718e3..532e7ef1edb6 100644 --- a/trunk/arch/ppc/boot/images/Makefile +++ b/trunk/arch/ppc/boot/images/Makefile @@ -26,7 +26,7 @@ quiet_cmd_uimage = UIMAGE $@ targets += uImage $(obj)/uImage: $(obj)/vmlinux.gz $(Q)rm -f $@ - $(call cmd,uimage) + $(call if_changed,uimage) @echo -n ' Image: $@ ' @if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi diff --git a/trunk/arch/ppc/configs/TQM8540_defconfig b/trunk/arch/ppc/configs/TQM8540_defconfig deleted file mode 100644 index 99bf3b7a2762..000000000000 --- a/trunk/arch/ppc/configs/TQM8540_defconfig +++ /dev/null @@ -1,973 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.15-rc2 -# Fri Nov 25 17:26:50 2005 -# -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_PPC=y -CONFIG_PPC32=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_EMBEDDED=y -# CONFIG_KALLSYMS is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -# CONFIG_EPOLL is not set -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Block layer -# -# CONFIG_LBD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Processor -# -# CONFIG_6xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set -# CONFIG_8xx is not set -# CONFIG_E200 is not set -CONFIG_E500=y -CONFIG_BOOKE=y -CONFIG_FSL_BOOKE=y -# CONFIG_PHYS_64BIT is not set -CONFIG_SPE=y -CONFIG_MATH_EMULATION=y -# CONFIG_KEXEC is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_PPC_GEN550=y -CONFIG_85xx=y -CONFIG_PPC_INDIRECT_PCI_BE=y - -# -# Freescale 85xx options -# -# CONFIG_MPC8540_ADS is not set -# CONFIG_MPC8548_CDS is not set -# CONFIG_MPC8555_CDS is not set -# CONFIG_MPC8560_ADS is not set -# CONFIG_SBC8560 is not set -# CONFIG_STX_GP3 is not set -CONFIG_TQM8540=y -# CONFIG_TQM8541 is not set -# CONFIG_TQM8555 is not set -# CONFIG_TQM8560 is not set -CONFIG_MPC8540=y - -# -# Platform options -# -# CONFIG_HIGHMEM is not set -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SOFTWARE_SUSPEND is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_PPC_I8259=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_LEGACY_PROC is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set -# CONFIG_RAPIDIO is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_BOOT_LOAD=0x00800000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_CFI_AMDSTD_RETRY=0 -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_TQM85xx=y -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_SL82C105 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_WINDFARM is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -CONFIG_E100=y -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_GIANFAR=y -CONFIG_GFAR_NAPI=y - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -CONFIG_I2C_MPC=y -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -CONFIG_SENSORS_DS1337=y -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_SENSORS_M41T00 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -CONFIG_SENSORS_LM75=y -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -CONFIG_HWMON_DEBUG_CHIP=y - -# -# Misc devices -# - -# -# Multimedia Capabilities Port drivers -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# SN Devices -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_SERIAL_TEXT_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# diff --git a/trunk/arch/ppc/configs/TQM8541_defconfig b/trunk/arch/ppc/configs/TQM8541_defconfig deleted file mode 100644 index 0ff56695d349..000000000000 --- a/trunk/arch/ppc/configs/TQM8541_defconfig +++ /dev/null @@ -1,986 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.15-rc2 -# Wed Nov 30 13:36:28 2005 -# -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_PPC=y -CONFIG_PPC32=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_EMBEDDED=y -# CONFIG_KALLSYMS is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -# CONFIG_EPOLL is not set -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Block layer -# -# CONFIG_LBD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Processor -# -# CONFIG_6xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set -# CONFIG_8xx is not set -# CONFIG_E200 is not set -CONFIG_E500=y -CONFIG_BOOKE=y -CONFIG_FSL_BOOKE=y -# CONFIG_PHYS_64BIT is not set -CONFIG_SPE=y -CONFIG_MATH_EMULATION=y -# CONFIG_KEXEC is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_PPC_GEN550=y -CONFIG_85xx=y -CONFIG_PPC_INDIRECT_PCI_BE=y - -# -# Freescale 85xx options -# -# CONFIG_MPC8540_ADS is not set -# CONFIG_MPC8548_CDS is not set -# CONFIG_MPC8555_CDS is not set -# CONFIG_MPC8560_ADS is not set -# CONFIG_SBC8560 is not set -# CONFIG_STX_GP3 is not set -# CONFIG_TQM8540 is not set -CONFIG_TQM8541=y -# CONFIG_TQM8555 is not set -# CONFIG_TQM8560 is not set -CONFIG_MPC8555=y - -# -# Platform options -# -CONFIG_CPM2=y -# CONFIG_PC_KEYBOARD is not set -# CONFIG_HIGHMEM is not set -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SOFTWARE_SUSPEND is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_PPC_I8259=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_LEGACY_PROC is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_BOOT_LOAD=0x00800000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_CFI_AMDSTD_RETRY=0 -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_TQM85xx=y -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_SL82C105 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_WINDFARM is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -CONFIG_E100=y -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_FS_ENET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_GIANFAR=y -CONFIG_GFAR_NAPI=y - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_CPM is not set -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -CONFIG_I2C_MPC=y -# CONFIG_I2C_MPC8260 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -CONFIG_SENSORS_DS1337=y -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_MAX6900 is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8563 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_SENSORS_M41T00 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -CONFIG_SENSORS_LM75=y -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -CONFIG_HWMON_DEBUG_CHIP=y - -# -# Misc devices -# - -# -# Multimedia Capabilities Port drivers -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# SN Devices -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set -# CONFIG_SCC_ENET is not set -# CONFIG_FEC_ENET is not set - -# -# CPM2 Options -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_KGDB_CONSOLE is not set -# CONFIG_SERIAL_TEXT_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# diff --git a/trunk/arch/ppc/configs/TQM8555_defconfig b/trunk/arch/ppc/configs/TQM8555_defconfig deleted file mode 100644 index 730b3db2e47a..000000000000 --- a/trunk/arch/ppc/configs/TQM8555_defconfig +++ /dev/null @@ -1,983 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.15-rc2 -# Thu Nov 24 17:10:52 2005 -# -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_PPC=y -CONFIG_PPC32=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_EMBEDDED=y -# CONFIG_KALLSYMS is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -# CONFIG_EPOLL is not set -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Block layer -# -# CONFIG_LBD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Processor -# -# CONFIG_6xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set -# CONFIG_8xx is not set -# CONFIG_E200 is not set -CONFIG_E500=y -CONFIG_BOOKE=y -CONFIG_FSL_BOOKE=y -# CONFIG_PHYS_64BIT is not set -CONFIG_SPE=y -CONFIG_MATH_EMULATION=y -# CONFIG_KEXEC is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_PPC_GEN550=y -CONFIG_85xx=y -CONFIG_PPC_INDIRECT_PCI_BE=y - -# -# Freescale 85xx options -# -# CONFIG_MPC8540_ADS is not set -# CONFIG_MPC8548_CDS is not set -# CONFIG_MPC8555_CDS is not set -# CONFIG_MPC8560_ADS is not set -# CONFIG_SBC8560 is not set -# CONFIG_STX_GP3 is not set -# CONFIG_TQM8540 is not set -# CONFIG_TQM8541 is not set -CONFIG_TQM8555=y -# CONFIG_TQM8560 is not set -CONFIG_MPC8555=y - -# -# Platform options -# -CONFIG_CPM2=y -# CONFIG_PC_KEYBOARD is not set -# CONFIG_HIGHMEM is not set -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SOFTWARE_SUSPEND is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_PPC_I8259=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_LEGACY_PROC is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_BOOT_LOAD=0x00800000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_CFI_AMDSTD_RETRY=0 -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_TQM85xx=y -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_SL82C105 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_WINDFARM is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -CONFIG_E100=y -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_FS_ENET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_GIANFAR=y -CONFIG_GFAR_NAPI=y - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_CPM is not set -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -CONFIG_I2C_MPC=y -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -CONFIG_SENSORS_DS1337=y -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_SENSORS_M41T00 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -CONFIG_SENSORS_LM75=y -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -CONFIG_HWMON_DEBUG_CHIP=y - -# -# Misc devices -# - -# -# Multimedia Capabilities Port drivers -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# SN Devices -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set -# CONFIG_SCC_ENET is not set -# CONFIG_FEC_ENET is not set - -# -# CPM2 Options -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_KGDB_CONSOLE is not set -# CONFIG_SERIAL_TEXT_DEBUG is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# diff --git a/trunk/arch/ppc/configs/TQM8560_defconfig b/trunk/arch/ppc/configs/TQM8560_defconfig deleted file mode 100644 index 1d902072825e..000000000000 --- a/trunk/arch/ppc/configs/TQM8560_defconfig +++ /dev/null @@ -1,992 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.15-rc2 -# Wed Nov 30 16:47:53 2005 -# -CONFIG_MMU=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_PPC=y -CONFIG_PPC32=y -CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -CONFIG_ARCH_MAY_HAVE_PC_FDC=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -# CONFIG_HOTPLUG is not set -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_EMBEDDED=y -# CONFIG_KALLSYMS is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -# CONFIG_EPOLL is not set -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Block layer -# -# CONFIG_LBD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -CONFIG_DEFAULT_AS=y -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_NOOP is not set -CONFIG_DEFAULT_IOSCHED="anticipatory" - -# -# Processor -# -# CONFIG_6xx is not set -# CONFIG_40x is not set -# CONFIG_44x is not set -# CONFIG_POWER3 is not set -# CONFIG_POWER4 is not set -# CONFIG_8xx is not set -# CONFIG_E200 is not set -CONFIG_E500=y -CONFIG_BOOKE=y -CONFIG_FSL_BOOKE=y -# CONFIG_PHYS_64BIT is not set -CONFIG_SPE=y -CONFIG_MATH_EMULATION=y -# CONFIG_KEXEC is not set -# CONFIG_CPU_FREQ is not set -# CONFIG_WANT_EARLY_SERIAL is not set -CONFIG_85xx=y -CONFIG_PPC_INDIRECT_PCI_BE=y - -# -# Freescale 85xx options -# -# CONFIG_MPC8540_ADS is not set -# CONFIG_MPC8548_CDS is not set -# CONFIG_MPC8555_CDS is not set -# CONFIG_MPC8560_ADS is not set -# CONFIG_SBC8560 is not set -# CONFIG_STX_GP3 is not set -# CONFIG_TQM8540 is not set -# CONFIG_TQM8541 is not set -# CONFIG_TQM8555 is not set -CONFIG_TQM8560=y -CONFIG_MPC8560=y - -# -# Platform options -# -CONFIG_CPM2=y -# CONFIG_PC_KEYBOARD is not set -# CONFIG_HIGHMEM is not set -# CONFIG_HZ_100 is not set -CONFIG_HZ_250=y -# CONFIG_HZ_1000 is not set -CONFIG_HZ=250 -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_CMDLINE_BOOL is not set -# CONFIG_PM is not set -# CONFIG_SOFTWARE_SUSPEND is not set -CONFIG_SECCOMP=y -CONFIG_ISA_DMA_API=y - -# -# Bus options -# -CONFIG_PPC_I8259=y -CONFIG_PPC_INDIRECT_PCI=y -CONFIG_PCI=y -CONFIG_PCI_DOMAINS=y -# CONFIG_PCI_LEGACY_PROC is not set - -# -# PCCARD (PCMCIA/CardBus) support -# -# CONFIG_PCCARD is not set -# CONFIG_RAPIDIO is not set - -# -# Advanced setup -# -# CONFIG_ADVANCED_OPTIONS is not set - -# -# Default settings for advanced configuration options are used -# -CONFIG_HIGHMEM_START=0xfe000000 -CONFIG_LOWMEM_SIZE=0x30000000 -CONFIG_KERNEL_START=0xc0000000 -CONFIG_TASK_SIZE=0x80000000 -CONFIG_BOOT_LOAD=0x00800000 - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set - -# -# Connector - unified userspace <-> kernelspace linker -# -# CONFIG_CONNECTOR is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -CONFIG_MTD_CMDLINE_PARTS=y - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_CFI_AMDSTD_RETRY=0 -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_TQM85xx=y -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_SX8 is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=32768 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -# CONFIG_BLK_DEV_OFFBOARD is not set -CONFIG_BLK_DEV_GENERIC=y -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_SL82C105 is not set -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5520 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -# CONFIG_IDE_ARM is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_IVB is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set - -# -# Macintosh device drivers -# -# CONFIG_WINDFARM is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# PHY device support -# -CONFIG_PHYLIB=y - -# -# MII PHY device drivers -# -# CONFIG_MARVELL_PHY is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_QSEMI_PHY is not set -# CONFIG_LXT_PHY is not set -# CONFIG_CICADA_PHY is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNGEM is not set -# CONFIG_CASSINI is not set -# CONFIG_NET_VENDOR_3COM is not set - -# -# Tulip family network device support -# -# CONFIG_NET_TULIP is not set -# CONFIG_HP100 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -CONFIG_E100=y -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_FS_ENET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SIS190 is not set -# CONFIG_SKGE is not set -# CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_TIGON3 is not set -# CONFIG_BNX2 is not set -CONFIG_GIANFAR=y -CONFIG_GFAR_NAPI=y - -# -# Ethernet (10000 Mbit) -# -# CONFIG_CHELSIO_T1 is not set -# CONFIG_IXGB is not set -# CONFIG_S2IO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 -# CONFIG_SERIAL_8250_EXTENDED is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_SERIAL_CPM=y -CONFIG_SERIAL_CPM_CONSOLE=y -CONFIG_SERIAL_CPM_SCC1=y -# CONFIG_SERIAL_CPM_SCC2 is not set -# CONFIG_SERIAL_CPM_SCC3 is not set -# CONFIG_SERIAL_CPM_SCC4 is not set -# CONFIG_SERIAL_CPM_SMC1 is not set -# CONFIG_SERIAL_CPM_SMC2 is not set -# CONFIG_SERIAL_JSM is not set -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -CONFIG_GEN_RTC=y -# CONFIG_GEN_RTC_X is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_AGP is not set -# CONFIG_DRM is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set - -# -# I2C support -# -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y - -# -# I2C Algorithms -# -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI1563 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_AMD8111 is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -CONFIG_I2C_MPC=y -# CONFIG_I2C_MPC8260 is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_SCx200_ACB is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_SIS630 is not set -# CONFIG_I2C_SIS96X is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -CONFIG_SENSORS_DS1337=y -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_MAX6900 is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8563 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_SENSORS_M41T00 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_RTC_X1205_I2C is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Dallas's 1-wire bus -# -# CONFIG_W1 is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -CONFIG_SENSORS_LM75=y -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -CONFIG_HWMON_DEBUG_CHIP=y - -# -# Misc devices -# - -# -# Multimedia Capabilities Port drivers -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -# CONFIG_USB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# InfiniBand support -# -# CONFIG_INFINIBAND is not set - -# -# SN Devices -# - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -CONFIG_CRAMFS=y -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -# CONFIG_NLS is not set -# CONFIG_SCC_ENET is not set -# CONFIG_FEC_ENET is not set - -# -# CPM2 Options -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_KGDB_CONSOLE is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# diff --git a/trunk/arch/ppc/kernel/Makefile b/trunk/arch/ppc/kernel/Makefile index e6c1d615bb86..0bb23fce4293 100644 --- a/trunk/arch/ppc/kernel/Makefile +++ b/trunk/arch/ppc/kernel/Makefile @@ -49,4 +49,5 @@ obj-$(CONFIG_TAU) += temp.o ifndef CONFIG_E200 obj-$(CONFIG_FSL_BOOKE) += perfmon_fsl_booke.o endif +obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o endif diff --git a/trunk/arch/ppc/kernel/asm-offsets.c b/trunk/arch/ppc/kernel/asm-offsets.c index 7964bf660e92..fe0e767fb94e 100644 --- a/trunk/arch/ppc/kernel/asm-offsets.c +++ b/trunk/arch/ppc/kernel/asm-offsets.c @@ -131,7 +131,7 @@ main(void) DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); - DEFINE(TI_SIGFRAME, offsetof(struct thread_info, nvgprs_frame)); + DEFINE(TI_SC_NOERR, offsetof(struct thread_info, syscall_noerror)); DEFINE(TI_TASK, offsetof(struct thread_info, task)); DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); diff --git a/trunk/arch/ppc/kernel/entry.S b/trunk/arch/ppc/kernel/entry.S index a48b950722a1..f044edbb454f 100644 --- a/trunk/arch/ppc/kernel/entry.S +++ b/trunk/arch/ppc/kernel/entry.S @@ -200,6 +200,8 @@ _GLOBAL(DoSyscall) bl do_show_syscall #endif /* SHOW_SYSCALLS */ rlwinm r10,r1,0,0,18 /* current_thread_info() */ + li r11,0 + stb r11,TI_SC_NOERR(r10) lwz r11,TI_FLAGS(r10) andi. r11,r11,_TIF_SYSCALL_T_OR_A bne- syscall_dotrace @@ -220,21 +222,25 @@ ret_from_syscall: bl do_show_syscall_exit #endif mr r6,r3 + li r11,-_LAST_ERRNO + cmplw 0,r3,r11 rlwinm r12,r1,0,0,18 /* current_thread_info() */ + blt+ 30f + lbz r11,TI_SC_NOERR(r12) + cmpwi r11,0 + bne 30f + neg r3,r3 + lwz r10,_CCR(r1) /* Set SO bit in CR */ + oris r10,r10,0x1000 + stw r10,_CCR(r1) + /* disable interrupts so current_thread_info()->flags can't change */ - LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ +30: LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ SYNC MTMSRD(r10) lwz r9,TI_FLAGS(r12) - li r8,-_LAST_ERRNO - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL) + andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SIGPENDING|_TIF_NEED_RESCHED) bne- syscall_exit_work - cmplw 0,r3,r8 - blt+ syscall_exit_cont - lwz r11,_CCR(r1) /* Load CR */ - neg r3,r3 - oris r11,r11,0x1000 /* Set SO bit in CR */ - stw r11,_CCR(r1) syscall_exit_cont: #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) /* If the process has its own DBCR0 value, load it up. The single @@ -286,113 +292,46 @@ syscall_dotrace: b syscall_dotrace_cont syscall_exit_work: - andi. r0,r9,_TIF_RESTOREALL - bne- 2f - cmplw 0,r3,r8 - blt+ 1f - andi. r0,r9,_TIF_NOERROR - bne- 1f - lwz r11,_CCR(r1) /* Load CR */ - neg r3,r3 - oris r11,r11,0x1000 /* Set SO bit in CR */ - stw r11,_CCR(r1) - -1: stw r6,RESULT(r1) /* Save result */ + stw r6,RESULT(r1) /* Save result */ stw r3,GPR3(r1) /* Update return value */ -2: andi. r0,r9,(_TIF_PERSYSCALL_MASK) - beq 4f - - /* Clear per-syscall TIF flags if any are set, but _leave_ - _TIF_SAVE_NVGPRS set in r9 since we haven't dealt with that - yet. */ - - li r11,_TIF_PERSYSCALL_MASK - addi r12,r12,TI_FLAGS -3: lwarx r8,0,r12 - andc r8,r8,r11 -#ifdef CONFIG_IBM405_ERR77 - dcbt 0,r12 -#endif - stwcx. r8,0,r12 - bne- 3b - subi r12,r12,TI_FLAGS - -4: /* Anything which requires enabling interrupts? */ - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP|_TIF_SAVE_NVGPRS) - beq 7f - - /* Save NVGPRS if they're not saved already */ + andi. r0,r9,_TIF_SYSCALL_T_OR_A + beq 5f + ori r10,r10,MSR_EE + SYNC + MTMSRD(r10) /* re-enable interrupts */ lwz r4,TRAP(r1) andi. r4,r4,1 - beq 5f + beq 4f SAVE_NVGPRS(r1) li r4,0xc00 stw r4,TRAP(r1) - - /* Re-enable interrupts */ -5: ori r10,r10,MSR_EE - SYNC - MTMSRD(r10) - - andi. r0,r9,_TIF_SAVE_NVGPRS - bne save_user_nvgprs - -save_user_nvgprs_cont: - andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) - beq 7f - +4: addi r3,r1,STACK_FRAME_OVERHEAD bl do_syscall_trace_leave REST_NVGPRS(r1) - -6: lwz r3,GPR3(r1) +2: + lwz r3,GPR3(r1) LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ SYNC MTMSRD(r10) /* disable interrupts again */ rlwinm r12,r1,0,0,18 /* current_thread_info() */ lwz r9,TI_FLAGS(r12) -7: +5: andi. r0,r9,_TIF_NEED_RESCHED - bne 8f + bne 1f lwz r5,_MSR(r1) andi. r5,r5,MSR_PR - beq ret_from_except + beq syscall_exit_cont andi. r0,r9,_TIF_SIGPENDING - beq ret_from_except + beq syscall_exit_cont b do_user_signal -8: +1: ori r10,r10,MSR_EE SYNC MTMSRD(r10) /* re-enable interrupts */ bl schedule - b 6b - -save_user_nvgprs: - lwz r8,TI_SIGFRAME(r12) - -.macro savewords start, end - 1: stw \start,4*(\start)(r8) - .section __ex_table,"a" - .align 2 - .long 1b,save_user_nvgprs_fault - .previous - .if \end - \start - savewords "(\start+1)",\end - .endif -.endm - savewords 14,31 - b save_user_nvgprs_cont - - -save_user_nvgprs_fault: - li r3,11 /* SIGSEGV */ - lwz r4,TI_TASK(r12) - bl force_sigsegv + b 2b - rlwinm r12,r1,0,0,18 /* current_thread_info() */ - lwz r9,TI_FLAGS(r12) - b save_user_nvgprs_cont - #ifdef SHOW_SYSCALLS do_show_syscall: #ifdef SHOW_SYSCALLS_TASK @@ -462,10 +401,28 @@ show_syscalls_task: #endif /* SHOW_SYSCALLS */ /* - * The fork/clone functions need to copy the full register set into - * the child process. Therefore we need to save all the nonvolatile - * registers (r13 - r31) before calling the C code. + * The sigsuspend and rt_sigsuspend system calls can call do_signal + * and thus put the process into the stopped state where we might + * want to examine its user state with ptrace. Therefore we need + * to save all the nonvolatile registers (r13 - r31) before calling + * the C code. */ + .globl ppc_sigsuspend +ppc_sigsuspend: + SAVE_NVGPRS(r1) + lwz r0,TRAP(r1) + rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ + stw r0,TRAP(r1) /* register set saved */ + b sys_sigsuspend + + .globl ppc_rt_sigsuspend +ppc_rt_sigsuspend: + SAVE_NVGPRS(r1) + lwz r0,TRAP(r1) + rlwinm r0,r0,0,0,30 + stw r0,TRAP(r1) + b sys_rt_sigsuspend + .globl ppc_fork ppc_fork: SAVE_NVGPRS(r1) @@ -490,6 +447,14 @@ ppc_clone: stw r0,TRAP(r1) /* register set saved */ b sys_clone + .globl ppc_swapcontext +ppc_swapcontext: + SAVE_NVGPRS(r1) + lwz r0,TRAP(r1) + rlwinm r0,r0,0,0,30 /* clear LSB to indicate full */ + stw r0,TRAP(r1) /* register set saved */ + b sys_swapcontext + /* * Top-level page fault handling. * This is in assembler because if do_page_fault tells us that @@ -661,6 +626,16 @@ END_FTR_SECTION_IFSET(CPU_FTR_601) .long ret_from_except #endif + .globl sigreturn_exit +sigreturn_exit: + subi r1,r3,STACK_FRAME_OVERHEAD + rlwinm r12,r1,0,0,18 /* current_thread_info() */ + lwz r9,TI_FLAGS(r12) + andi. r0,r9,_TIF_SYSCALL_T_OR_A + beq+ ret_from_except_full + bl do_syscall_trace_leave + /* fall through */ + .globl ret_from_except_full ret_from_except_full: REST_NVGPRS(r1) @@ -683,7 +658,7 @@ user_exc_return: /* r10 contains MSR_KERNEL here */ /* Check current_thread_info()->flags */ rlwinm r9,r1,0,0,18 lwz r9,TI_FLAGS(r9) - andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_RESTOREALL) + andi. r0,r9,(_TIF_SIGPENDING|_TIF_NEED_RESCHED) bne do_work restore_user: diff --git a/trunk/arch/ppc/kernel/misc.S b/trunk/arch/ppc/kernel/misc.S index fb5658bba285..5e61124581d0 100644 --- a/trunk/arch/ppc/kernel/misc.S +++ b/trunk/arch/ppc/kernel/misc.S @@ -1197,7 +1197,7 @@ _GLOBAL(sys_call_table) .long sys_ssetmask .long sys_setreuid /* 70 */ .long sys_setregid - .long sys_sigsuspend + .long ppc_sigsuspend .long sys_sigpending .long sys_sethostname .long sys_setrlimit /* 75 */ @@ -1303,7 +1303,7 @@ _GLOBAL(sys_call_table) .long sys_rt_sigpending /* 175 */ .long sys_rt_sigtimedwait .long sys_rt_sigqueueinfo - .long sys_rt_sigsuspend + .long ppc_rt_sigsuspend .long sys_pread64 .long sys_pwrite64 /* 180 */ .long sys_chown @@ -1374,7 +1374,7 @@ _GLOBAL(sys_call_table) .long sys_clock_gettime .long sys_clock_getres .long sys_clock_nanosleep - .long sys_swapcontext + .long ppc_swapcontext .long sys_tgkill /* 250 */ .long sys_utimes .long sys_statfs64 diff --git a/trunk/arch/ppc/kernel/pci.c b/trunk/arch/ppc/kernel/pci.c index 50c75eec8874..f7fae5f153b2 100644 --- a/trunk/arch/ppc/kernel/pci.c +++ b/trunk/arch/ppc/kernel/pci.c @@ -815,7 +815,8 @@ EXPORT_SYMBOL(pci_device_to_OF_node); * to set pci_assign_all_buses to 1 and still use RTAS for PCI * config cycles. */ -struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node) +struct pci_controller* +pci_find_hose_for_OF_device(struct device_node* node) { if (!have_of) return NULL; @@ -941,7 +942,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) { res = NULL; size = ranges[na+4]; - switch ((ranges[0] >> 24) & 0x3) { + switch (ranges[0] >> 24) { case 1: /* I/O space */ if (ranges[2] != 0) break; @@ -955,8 +956,6 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, res = &hose->io_resource; res->flags = IORESOURCE_IO; res->start = ranges[2]; - DBG("PCI: IO 0x%lx -> 0x%lx\n", - res->start, res->start + size - 1); break; case 2: /* memory space */ memno = 0; @@ -974,11 +973,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, if (memno < 3) { res = &hose->mem_resources[memno]; res->flags = IORESOURCE_MEM; - if(ranges[0] & 0x40000000) - res->flags |= IORESOURCE_PREFETCH; res->start = ranges[na+2]; - DBG("PCI: MEM[%d] 0x%lx -> 0x%lx\n", memno, - res->start, res->start + size - 1); } break; } @@ -1811,23 +1806,6 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *addr) EXPORT_SYMBOL(pci_iomap); EXPORT_SYMBOL(pci_iounmap); -unsigned long pci_address_to_pio(phys_addr_t address) -{ - struct pci_controller* hose = hose_head; - - for (; hose; hose = hose->next) { - unsigned int size = hose->io_resource.end - - hose->io_resource.start + 1; - if (address >= hose->io_base_phys && - address < (hose->io_base_phys + size)) { - unsigned long base = - (unsigned long)hose->io_base_virt - _IO_BASE; - return base + (address - hose->io_base_phys); - } - } - return (unsigned int)-1; -} -EXPORT_SYMBOL(pci_address_to_pio); /* * Null PCI config access functions, for the case when we can't diff --git a/trunk/arch/ppc/kernel/ppc_ksyms.c b/trunk/arch/ppc/kernel/ppc_ksyms.c index 95075f99a6d4..bb6a5c6a64be 100644 --- a/trunk/arch/ppc/kernel/ppc_ksyms.c +++ b/trunk/arch/ppc/kernel/ppc_ksyms.c @@ -82,6 +82,10 @@ EXPORT_SYMBOL(ppc_n_lost_interrupts); EXPORT_SYMBOL(ISA_DMA_THRESHOLD); EXPORT_SYMBOL(DMA_MODE_READ); EXPORT_SYMBOL(DMA_MODE_WRITE); +#if defined(CONFIG_PPC_PREP) +EXPORT_SYMBOL(_prep_type); +EXPORT_SYMBOL(ucSystemType); +#endif #if !defined(__INLINE_BITOPS) EXPORT_SYMBOL(set_bit); @@ -307,6 +311,7 @@ EXPORT_SYMBOL(__res); EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); +EXPORT_SYMBOL_GPL(__handle_mm_fault); /* For MOL */ EXPORT_SYMBOL(disarm_decr); #ifdef CONFIG_PPC_STD_MMU extern long mol_trampoline; diff --git a/trunk/arch/ppc/kernel/setup.c b/trunk/arch/ppc/kernel/setup.c index e707c6f6e61b..0eb0b7085e6a 100644 --- a/trunk/arch/ppc/kernel/setup.c +++ b/trunk/arch/ppc/kernel/setup.c @@ -744,9 +744,6 @@ void __init setup_arch(char **cmdline_p) /* so udelay does something sensible, assume <= 1000 bogomips */ loops_per_jiffy = 500000000 / HZ; - if (ppc_md.init_early) - ppc_md.init_early(); - #ifdef CONFIG_PPC_MULTIPLATFORM /* This could be called "early setup arch", it must be done * now because xmon need it diff --git a/trunk/arch/ppc/platforms/85xx/Kconfig b/trunk/arch/ppc/platforms/85xx/Kconfig index 7ddd331a7145..c5bc2821d991 100644 --- a/trunk/arch/ppc/platforms/85xx/Kconfig +++ b/trunk/arch/ppc/platforms/85xx/Kconfig @@ -39,7 +39,7 @@ config MPC8560_ADS config SBC8560 bool "WindRiver PowerQUICC III SBC8560" help - This option enables support for the WindRiver PowerQUICC III + This option enables support for the WindRiver PowerQUICC III SBC8560 board. config STX_GP3 @@ -48,26 +48,6 @@ config STX_GP3 This option enables support for the Silicon Turnkey Express GP3 board. -config TQM8540 - bool "TQ Components TQM8540" - help - This option enablese support for the TQ Components TQM8540 board. - -config TQM8541 - bool "TQ Components TQM8541" - help - This option enablese support for the TQ Components TQM8541 board. - -config TQM8555 - bool "TQ Components TQM8555" - help - This option enablese support for the TQ Components TQM8555 board. - -config TQM8560 - bool "TQ Components TQM8560" - help - This option enablese support for the TQ Components TQM8560 board. - endchoice # It's often necessary to know the specific 85xx processor type. @@ -75,7 +55,7 @@ endchoice # don't need to ask more redundant questions. config MPC8540 bool - depends on MPC8540_ADS || TQM8540 + depends on MPC8540_ADS default y config MPC8548 @@ -85,12 +65,12 @@ config MPC8548 config MPC8555 bool - depends on MPC8555_CDS || TQM8541 || TQM8555 + depends on MPC8555_CDS default y config MPC8560 bool - depends on SBC8560 || MPC8560_ADS || STX_GP3 || TQM8560 + depends on SBC8560 || MPC8560_ADS || STX_GP3 default y config 85xx_PCI2 diff --git a/trunk/arch/ppc/platforms/85xx/Makefile b/trunk/arch/ppc/platforms/85xx/Makefile index 6c4753c144d3..efdf813108f2 100644 --- a/trunk/arch/ppc/platforms/85xx/Makefile +++ b/trunk/arch/ppc/platforms/85xx/Makefile @@ -7,7 +7,3 @@ obj-$(CONFIG_MPC8555_CDS) += mpc85xx_cds_common.o obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads_common.o mpc8560_ads.o obj-$(CONFIG_SBC8560) += sbc85xx.o sbc8560.o obj-$(CONFIG_STX_GP3) += stx_gp3.o -obj-$(CONFIG_TQM8540) += tqm85xx.o -obj-$(CONFIG_TQM8541) += tqm85xx.o -obj-$(CONFIG_TQM8555) += tqm85xx.o -obj-$(CONFIG_TQM8560) += tqm85xx.o diff --git a/trunk/arch/ppc/platforms/85xx/tqm85xx.c b/trunk/arch/ppc/platforms/85xx/tqm85xx.c deleted file mode 100644 index c6dfd8f0f9df..000000000000 --- a/trunk/arch/ppc/platforms/85xx/tqm85xx.c +++ /dev/null @@ -1,419 +0,0 @@ -/* - * arch/ppc/platforms/85xx/tqm85xx.c - * - * TQM85xx (40/41/55/60) board specific routines - * - * Copyright (c) 2005 DENX Software Engineering - * Stefan Roese - * - * Based on original work by - * Kumar Gala - * Copyright 2004 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* for linux/serial_core.h */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifndef CONFIG_PCI -unsigned long isa_io_base = 0; -unsigned long isa_mem_base = 0; -#endif - - -extern unsigned long total_memory; /* in mm/init */ - -unsigned char __res[sizeof (bd_t)]; - -/* Internal interrupts are all Level Sensitive, and Positive Polarity */ -static u_char tqm85xx_openpic_initsenses[] __initdata = { - MPC85XX_INTERNAL_IRQ_SENSES, - 0x0, /* External 0: */ - 0x0, /* External 1: */ -#if defined(CONFIG_PCI) - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 2: PCI INTA */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 3: PCI INTB */ -#else - 0x0, /* External 2: */ - 0x0, /* External 3: */ -#endif - 0x0, /* External 4: */ - 0x0, /* External 5: */ - 0x0, /* External 6: */ - 0x0, /* External 7: */ - (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 8: PHY */ - 0x0, /* External 9: */ - 0x0, /* External 10: */ - 0x0, /* External 11: */ -}; - -static const char *GFAR_PHY_0 = "phy0:2"; -static const char *GFAR_PHY_1 = "phy0:1"; -#ifdef CONFIG_MPC8540 -static const char *GFAR_PHY_3 = "phy0:3"; -#endif - -/* ************************************************************************ - * - * Setup the architecture - * - */ -static void __init -tqm85xx_setup_arch(void) -{ - bd_t *binfo = (bd_t *) __res; - unsigned int freq; - struct gianfar_platform_data *pdata; - struct gianfar_mdio_data *mdata; - -#ifdef CONFIG_MPC8560 - cpm2_reset(); -#endif - - /* get the core frequency */ - freq = binfo->bi_intfreq; - - if (ppc_md.progress) - ppc_md.progress("tqm85xx_setup_arch()", 0); - - /* Set loops_per_jiffy to a half-way reasonable value, - for use until calibrate_delay gets called. */ - loops_per_jiffy = freq / HZ; - -#ifdef CONFIG_PCI - /* setup PCI host bridges */ - mpc85xx_setup_hose(); -#endif - -#ifndef CONFIG_MPC8560 -#if defined(CONFIG_SERIAL_8250) - mpc85xx_early_serial_map(); -#endif - -#ifdef CONFIG_SERIAL_TEXT_DEBUG - /* Invalidate the entry we stole earlier the serial ports - * should be properly mapped */ - invalidate_tlbcam_entry(num_tlbcam_entries - 1); -#endif -#endif /* CONFIG_MPC8560 */ - - /* setup the board related info for the MDIO bus */ - mdata = (struct gianfar_mdio_data *) ppc_sys_get_pdata(MPC85xx_MDIO); - - mdata->irq[0] = MPC85xx_IRQ_EXT8; - mdata->irq[1] = MPC85xx_IRQ_EXT8; - mdata->irq[2] = -1; - mdata->irq[3] = MPC85xx_IRQ_EXT8; - mdata->irq[31] = -1; - mdata->paddr += binfo->bi_immr_base; - - /* setup the board related information for the enet controllers */ - pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); - if (pdata) { - pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = GFAR_PHY_0; - memcpy(pdata->mac_addr, binfo->bi_enetaddr, 6); - } - - pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC2); - if (pdata) { - pdata->board_flags = FSL_GIANFAR_BRD_HAS_PHY_INTR; - pdata->bus_id = GFAR_PHY_1; - memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); - } - -#ifdef CONFIG_MPC8540 - pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); - if (pdata) { - pdata->board_flags = 0; - pdata->bus_id = GFAR_PHY_3; - memcpy(pdata->mac_addr, binfo->bi_enet2addr, 6); - } -#endif - -#ifdef CONFIG_BLK_DEV_INITRD - if (initrd_start) - ROOT_DEV = Root_RAM0; - else -#endif -#ifdef CONFIG_ROOT_NFS - ROOT_DEV = Root_NFS; -#else - ROOT_DEV = Root_HDA1; -#endif -} - -#ifdef CONFIG_MPC8560 -static irqreturn_t cpm2_cascade(int irq, void *dev_id, struct pt_regs *regs) -{ - while ((irq = cpm2_get_irq(regs)) >= 0) - __do_IRQ(irq, regs); - return IRQ_HANDLED; -} - -static struct irqaction cpm2_irqaction = { - .handler = cpm2_cascade, - .flags = SA_INTERRUPT, - .mask = CPU_MASK_NONE, - .name = "cpm2_cascade", -}; -#endif /* CONFIG_MPC8560 */ - -void __init -tqm85xx_init_IRQ(void) -{ - bd_t *binfo = (bd_t *) __res; - - /* Determine the Physical Address of the OpenPIC regs */ - phys_addr_t OpenPIC_PAddr = - binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET; - OpenPIC_Addr = ioremap(OpenPIC_PAddr, MPC85xx_OPENPIC_SIZE); - OpenPIC_InitSenses = tqm85xx_openpic_initsenses; - OpenPIC_NumInitSenses = sizeof (tqm85xx_openpic_initsenses); - - /* Skip reserved space and internal sources */ - openpic_set_sources(0, 32, OpenPIC_Addr + 0x10200); - - /* Map PIC IRQs 0-11 */ - openpic_set_sources(48, 12, OpenPIC_Addr + 0x10000); - - /* we let openpic interrupts starting from an offset, to - * leave space for cascading interrupts underneath. - */ - openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET); - -#ifdef CONFIG_MPC8560 - /* Setup CPM2 PIC */ - cpm2_init_IRQ(); - - setup_irq(MPC85xx_IRQ_CPM, &cpm2_irqaction); -#endif /* CONFIG_MPC8560 */ - - return; -} - -int tqm85xx_show_cpuinfo(struct seq_file *m) -{ - uint pvid, svid, phid1; - uint memsize = total_memory; - bd_t *binfo = (bd_t *) __res; - unsigned int freq; - - /* get the core frequency */ - freq = binfo->bi_intfreq; - - pvid = mfspr(SPRN_PVR); - svid = mfspr(SPRN_SVR); - - seq_printf(m, "Vendor\t\t: TQ Components\n"); - seq_printf(m, "Machine\t\t: TQM%s\n", cur_ppc_sys_spec->ppc_sys_name); - seq_printf(m, "clock\t\t: %dMHz\n", freq / 1000000); - seq_printf(m, "PVR\t\t: 0x%x\n", pvid); - seq_printf(m, "SVR\t\t: 0x%x\n", svid); - - /* Display cpu Pll setting */ - phid1 = mfspr(SPRN_HID1); - seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); - - /* Display the amount of memory */ - seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); - - return 0; -} - -#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_DS1337) -extern ulong ds1337_get_rtc_time(void); -extern int ds1337_set_rtc_time(unsigned long nowtime); - -static int __init -tqm85xx_rtc_hookup(void) -{ - struct timespec tv; - - ppc_md.set_rtc_time = ds1337_set_rtc_time; - ppc_md.get_rtc_time = ds1337_get_rtc_time; - - tv.tv_nsec = 0; - tv.tv_sec = (ppc_md.get_rtc_time)(); - do_settimeofday(&tv); - - return 0; -} -late_initcall(tqm85xx_rtc_hookup); -#endif - -#ifdef CONFIG_PCI -/* - * interrupt routing - */ -int mpc85xx_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 - */ - { - {PIRQA, PIRQB, 0, 0}, - }; - - const long min_idsel = 0x1c, max_idsel = 0x1c, irqs_per_slot = 4; - return PCI_IRQ_TABLE_LOOKUP; -} - -int mpc85xx_exclude_device(u_char bus, u_char devfn) -{ - if (bus == 0 && PCI_SLOT(devfn) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - else - return PCIBIOS_SUCCESSFUL; -} - -#endif /* CONFIG_PCI */ - -#ifdef CONFIG_RAPIDIO -void platform_rio_init(void) -{ - /* 512MB RIO LAW at 0xc0000000 */ - mpc85xx_rio_setup(0xc0000000, 0x20000000); -} -#endif /* CONFIG_RAPIDIO */ - -/* ************************************************************************ */ -void __init -platform_init(unsigned long r3, unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7) -{ - /* parse_bootinfo must always be called first */ - parse_bootinfo(find_bootinfo()); - - /* - * If we were passed in a board information, copy it into the - * residual data area. - */ - if (r3) { - memcpy((void *) __res, (void *) (r3 + KERNELBASE), - sizeof (bd_t)); - } - -#if defined(CONFIG_SERIAL_TEXT_DEBUG) && !defined(CONFIG_MPC8560) - { - bd_t *binfo = (bd_t *) __res; - struct uart_port p; - - /* Use the last TLB entry to map CCSRBAR to allow access to DUART regs */ - settlbcam(num_tlbcam_entries - 1, binfo->bi_immr_base, - binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0); - - memset(&p, 0, sizeof (p)); - p.iotype = SERIAL_IO_MEM; - p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET; - p.uartclk = binfo->bi_busfreq; - - gen550_init(0, &p); - - memset(&p, 0, sizeof (p)); - p.iotype = SERIAL_IO_MEM; - p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET; - p.uartclk = binfo->bi_busfreq; - - gen550_init(1, &p); - } -#endif - -#if defined(CONFIG_BLK_DEV_INITRD) - /* - * If the init RAM disk has been configured in, and there's a valid - * starting address for it, set it up. - */ - if (r4) { - initrd_start = r4 + KERNELBASE; - initrd_end = r5 + KERNELBASE; - } -#endif /* CONFIG_BLK_DEV_INITRD */ - - /* Copy the kernel command line arguments to a safe place. */ - - if (r6) { - *(char *) (r7 + KERNELBASE) = 0; - strcpy(cmd_line, (char *) (r6 + KERNELBASE)); - } - - identify_ppc_sys_by_id(mfspr(SPRN_SVR)); - - /* setup the PowerPC module struct */ - ppc_md.setup_arch = tqm85xx_setup_arch; - ppc_md.show_cpuinfo = tqm85xx_show_cpuinfo; - - ppc_md.init_IRQ = tqm85xx_init_IRQ; - ppc_md.get_irq = openpic_get_irq; - - ppc_md.restart = mpc85xx_restart; - ppc_md.power_off = mpc85xx_power_off; - ppc_md.halt = mpc85xx_halt; - - ppc_md.find_end_of_memory = mpc85xx_find_end_of_memory; - - ppc_md.time_init = NULL; - ppc_md.set_rtc_time = NULL; - ppc_md.get_rtc_time = NULL; - ppc_md.calibrate_decr = mpc85xx_calibrate_decr; - -#ifndef CONFIG_MPC8560 -#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG) - ppc_md.progress = gen550_progress; -#endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */ -#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB) - ppc_md.early_serial_map = mpc85xx_early_serial_map; -#endif /* CONFIG_SERIAL_8250 && CONFIG_KGDB */ -#endif /* CONFIG_MPC8560 */ - - if (ppc_md.progress) - ppc_md.progress("tqm85xx_init(): exit", 0); - - return; -} diff --git a/trunk/arch/ppc/platforms/85xx/tqm85xx.h b/trunk/arch/ppc/platforms/85xx/tqm85xx.h deleted file mode 100644 index 3775eb363fde..000000000000 --- a/trunk/arch/ppc/platforms/85xx/tqm85xx.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * arch/ppc/platforms/85xx/tqm85xx.h - * - * TQM85xx (40/41/55/60) board definitions - * - * Copyright (c) 2005 DENX Software Engineering - * Stefan Roese - * - * 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. - * - */ - -#ifndef __MACH_TQM85XX_H -#define __MACH_TQM85XX_H - -#include -#include -#include - -#define BOARD_CCSRBAR ((uint)0xe0000000) -#define CCSRBAR_SIZE ((uint)1024*1024) - -#define CPM_MAP_ADDR (CCSRBAR + MPC85xx_CPM_OFFSET) - -#define PCI_CFG_ADDR_OFFSET (0x8000) -#define PCI_CFG_DATA_OFFSET (0x8004) - -/* PCI interrupt controller */ -#define PIRQA MPC85xx_IRQ_EXT2 -#define PIRQB MPC85xx_IRQ_EXT3 - -#define MPC85XX_PCI1_LOWER_IO 0x00000000 -#define MPC85XX_PCI1_UPPER_IO 0x00ffffff - -#define MPC85XX_PCI1_LOWER_MEM 0x80000000 -#define MPC85XX_PCI1_UPPER_MEM 0x9fffffff - -#define MPC85XX_PCI1_IO_BASE 0xe2000000 -#define MPC85XX_PCI1_MEM_OFFSET 0x00000000 - -#define MPC85XX_PCI1_IO_SIZE 0x01000000 - -#define BASE_BAUD 115200 - -extern void mpc85xx_setup_hose(void) __init; -extern void mpc85xx_restart(char *cmd); -extern void mpc85xx_power_off(void); -extern void mpc85xx_halt(void); -extern void mpc85xx_init_IRQ(void) __init; -extern unsigned long mpc85xx_find_end_of_memory(void) __init; -extern void mpc85xx_calibrate_decr(void) __init; - -#endif /* __MACH_TQM85XX_H */ diff --git a/trunk/arch/ppc/platforms/chrp_setup.c b/trunk/arch/ppc/platforms/chrp_setup.c index 056ac2a7b5c1..f1b70ab3c6fd 100644 --- a/trunk/arch/ppc/platforms/chrp_setup.c +++ b/trunk/arch/ppc/platforms/chrp_setup.c @@ -404,6 +404,7 @@ static struct irqaction xmon_irqaction = { void __init chrp_init_IRQ(void) { struct device_node *np; + int i; unsigned long chrp_int_ack = 0; unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) diff --git a/trunk/arch/ppc/platforms/prep_setup.c b/trunk/arch/ppc/platforms/prep_setup.c index d06535802003..4415748071dc 100644 --- a/trunk/arch/ppc/platforms/prep_setup.c +++ b/trunk/arch/ppc/platforms/prep_setup.c @@ -72,6 +72,7 @@ TODC_ALLOC(); +unsigned char ucSystemType; unsigned char ucBoardRev; unsigned char ucBoardRevMaj, ucBoardRevMin; @@ -953,6 +954,7 @@ prep_calibrate_decr(void) static void __init prep_init_IRQ(void) { + int i; unsigned int pci_viddid, pci_did; if (OpenPIC_Addr != NULL) { diff --git a/trunk/arch/ppc/syslib/Makefile b/trunk/arch/ppc/syslib/Makefile index 84ef03018d0e..5b7f2b80e56e 100644 --- a/trunk/arch/ppc/syslib/Makefile +++ b/trunk/arch/ppc/syslib/Makefile @@ -96,7 +96,7 @@ ifeq ($(CONFIG_85xx),y) obj-$(CONFIG_PCI) += pci_auto.o endif obj-$(CONFIG_RAPIDIO) += ppc85xx_rio.o -obj-$(CONFIG_83xx) += ppc83xx_setup.o ppc_sys.o \ +obj-$(CONFIG_83xx) += ipic.o ppc83xx_setup.o ppc_sys.o \ mpc83xx_sys.o mpc83xx_devices.o ifeq ($(CONFIG_83xx),y) obj-$(CONFIG_PCI) += pci_auto.o diff --git a/trunk/arch/powerpc/sysdev/ipic.c b/trunk/arch/ppc/syslib/ipic.c similarity index 100% rename from trunk/arch/powerpc/sysdev/ipic.c rename to trunk/arch/ppc/syslib/ipic.c diff --git a/trunk/arch/powerpc/sysdev/ipic.h b/trunk/arch/ppc/syslib/ipic.h similarity index 100% rename from trunk/arch/powerpc/sysdev/ipic.h rename to trunk/arch/ppc/syslib/ipic.h diff --git a/trunk/arch/ppc/syslib/m8xx_setup.c b/trunk/arch/ppc/syslib/m8xx_setup.c index 688616de3cde..1cc3abe6fa43 100644 --- a/trunk/arch/ppc/syslib/m8xx_setup.c +++ b/trunk/arch/ppc/syslib/m8xx_setup.c @@ -135,16 +135,6 @@ static struct irqaction tbint_irqaction = { .name = "tbint", }; -/* per-board overridable init_internal_rtc() function. */ -void __init __attribute__ ((weak)) -init_internal_rtc(void) -{ - /* Disable the RTC one second and alarm interrupts. */ - out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) & ~(RTCSC_SIE | RTCSC_ALE)); - /* Enable the RTC */ - out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) | (RTCSC_RTF | RTCSC_RTE)); -} - /* The decrementer counts at the system (internal) clock frequency divided by * sixteen, or external oscillator divided by four. We force the processor * to use system clock divided by sixteen. @@ -193,7 +183,10 @@ void __init m8xx_calibrate_decr(void) out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_rtcsck, KAPWR_KEY); out_be32(&((immap_t *)IMAP_ADDR)->im_sitk.sitk_tbk, KAPWR_KEY); - init_internal_rtc(); + /* Disable the RTC one second and alarm interrupts. */ + out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) & ~(RTCSC_SIE | RTCSC_ALE)); + /* Enable the RTC */ + out_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc, in_be16(&((immap_t *)IMAP_ADDR)->im_sit.sit_rtcsc) | (RTCSC_RTF | RTCSC_RTE)); /* Enabling the decrementer also enables the timebase interrupts * (or from the other point of view, to get decrementer interrupts diff --git a/trunk/arch/ppc/syslib/m8xx_wdt.c b/trunk/arch/ppc/syslib/m8xx_wdt.c index df6c9557b86a..a21632d37e5a 100644 --- a/trunk/arch/ppc/syslib/m8xx_wdt.c +++ b/trunk/arch/ppc/syslib/m8xx_wdt.c @@ -19,7 +19,6 @@ #include static int wdt_timeout; -int m8xx_has_internal_rtc = 0; static irqreturn_t m8xx_wdt_interrupt(int, void *, struct pt_regs *); static struct irqaction m8xx_wdt_irqaction = { @@ -46,15 +45,35 @@ static irqreturn_t m8xx_wdt_interrupt(int irq, void *dev, struct pt_regs *regs) return IRQ_HANDLED; } -#define SYPCR_SWP 0x1 -#define SYPCR_SWE 0x4 - - -void __init m8xx_wdt_install_irq(volatile immap_t *imap, bd_t *binfo) +void __init m8xx_wdt_handler_install(bd_t * binfo) { + volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR; u32 pitc; + u32 sypcr; u32 pitrtclk; + sypcr = in_be32(&imap->im_siu_conf.sc_sypcr); + + if (!(sypcr & 0x04)) { + printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n", + sypcr); + return; + } + + m8xx_wdt_reset(); + + printk(KERN_NOTICE + "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n", + (sypcr >> 16), sypcr & 0x01); + + wdt_timeout = (sypcr >> 16) & 0xFFFF; + + if (!wdt_timeout) + wdt_timeout = 0xFFFF; + + if (sypcr & 0x01) + wdt_timeout *= 2048; + /* * Fire trigger if half of the wdt ticked down */ @@ -79,67 +98,6 @@ void __init m8xx_wdt_install_irq(volatile immap_t *imap, bd_t *binfo) printk(KERN_NOTICE "m8xx_wdt: keep-alive trigger installed (PITC: 0x%04X)\n", pitc); -} - -static void m8xx_wdt_timer_func(unsigned long data); - -static struct timer_list m8xx_wdt_timer = - TIMER_INITIALIZER(m8xx_wdt_timer_func, 0, 0); - -void m8xx_wdt_stop_timer(void) -{ - del_timer(&m8xx_wdt_timer); -} - -void m8xx_wdt_install_timer(void) -{ - m8xx_wdt_timer.expires = jiffies + (HZ/2); - add_timer(&m8xx_wdt_timer); -} - -static void m8xx_wdt_timer_func(unsigned long data) -{ - m8xx_wdt_reset(); - m8xx_wdt_install_timer(); -} - -void __init m8xx_wdt_handler_install(bd_t * binfo) -{ - volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR; - u32 sypcr; - - sypcr = in_be32(&imap->im_siu_conf.sc_sypcr); - - if (!(sypcr & SYPCR_SWE)) { - printk(KERN_NOTICE "m8xx_wdt: wdt disabled (SYPCR: 0x%08X)\n", - sypcr); - return; - } - - m8xx_wdt_reset(); - - printk(KERN_NOTICE - "m8xx_wdt: active wdt found (SWTC: 0x%04X, SWP: 0x%01X)\n", - (sypcr >> 16), sypcr & SYPCR_SWP); - - wdt_timeout = (sypcr >> 16) & 0xFFFF; - - if (!wdt_timeout) - wdt_timeout = 0xFFFF; - - if (sypcr & SYPCR_SWP) - wdt_timeout *= 2048; - - m8xx_has_internal_rtc = in_be16(&imap->im_sit.sit_rtcsc) & RTCSC_RTE; - - /* if the internal RTC is off use a kernel timer */ - if (!m8xx_has_internal_rtc) { - if (wdt_timeout < (binfo->bi_intfreq/HZ)) - printk(KERN_ERR "m8xx_wdt: timeout too short for ktimer!\n"); - m8xx_wdt_install_timer(); - } else - m8xx_wdt_install_irq(imap, binfo); - wdt_timeout /= binfo->bi_intfreq; } diff --git a/trunk/arch/ppc/syslib/m8xx_wdt.h b/trunk/arch/ppc/syslib/m8xx_wdt.h index e75835f0012b..0d81a9f8155f 100644 --- a/trunk/arch/ppc/syslib/m8xx_wdt.h +++ b/trunk/arch/ppc/syslib/m8xx_wdt.h @@ -9,12 +9,8 @@ #ifndef _PPC_SYSLIB_M8XX_WDT_H #define _PPC_SYSLIB_M8XX_WDT_H -extern int m8xx_has_internal_rtc; - extern void m8xx_wdt_handler_install(bd_t * binfo); extern int m8xx_wdt_get_timeout(void); extern void m8xx_wdt_reset(void); -extern void m8xx_wdt_install_timer(void); -extern void m8xx_wdt_stop_timer(void); #endif /* _PPC_SYSLIB_M8XX_WDT_H */ diff --git a/trunk/arch/s390/kernel/ptrace.c b/trunk/arch/s390/kernel/ptrace.c index cc02232aa96e..8ecda6d66de4 100644 --- a/trunk/arch/s390/kernel/ptrace.c +++ b/trunk/arch/s390/kernel/ptrace.c @@ -712,18 +712,35 @@ sys_ptrace(long request, long pid, long addr, long data) int ret; lock_kernel(); + if (request == PTRACE_TRACEME) { - ret = ptrace_traceme(); - goto out; + /* are we already being traced? */ + ret = -EPERM; + if (current->ptrace & PT_PTRACED) + goto out; + ret = security_ptrace(current->parent, current); + if (ret) + goto out; + /* set the ptrace bit in the process flags. */ + current->ptrace |= PT_PTRACED; + goto out; } - child = ptrace_get_task_struct(pid); - if (IS_ERR(child)) { - ret = PTR_ERR(child); + ret = -EPERM; + if (pid == 1) /* you may not mess with init */ + goto out; + + ret = -ESRCH; + read_lock(&tasklist_lock); + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); + if (!child) goto out; - } ret = do_ptrace(child, request, addr, data); + put_task_struct(child); out: unlock_kernel(); diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index 8cf6d437a630..64f5ae0ff96d 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -14,6 +14,10 @@ config SUPERH gaming console. The SuperH port has a home page at . +config UID16 + bool + default y + config RWSEM_GENERIC_SPINLOCK bool default y diff --git a/trunk/arch/sh64/kernel/time.c b/trunk/arch/sh64/kernel/time.c index 1195af37ee5a..870fe5327e09 100644 --- a/trunk/arch/sh64/kernel/time.c +++ b/trunk/arch/sh64/kernel/time.c @@ -417,7 +417,7 @@ static __init unsigned int get_cpu_hz(void) /* ** Regardless the toolchain, force the compiler to use the ** arbitrary register r3 as a clock tick counter. - ** NOTE: r3 must be in accordance with sh64_rtc_interrupt() + ** NOTE: r3 must be in accordance with rtc_interrupt() */ register unsigned long long __rtc_irq_flag __asm__ ("r3"); @@ -482,8 +482,7 @@ static __init unsigned int get_cpu_hz(void) #endif } -static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id, - struct pt_regs *regs) +static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs) { ctrl_outb(0, RCR1); /* Disable Carry Interrupts */ regs->regs[3] = 1; /* Using r3 */ @@ -492,7 +491,7 @@ static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id, } static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer", NULL, NULL}; -static struct irqaction irq1 = { sh64_rtc_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "rtc", NULL, NULL}; +static struct irqaction irq1 = { rtc_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "rtc", NULL, NULL}; void __init time_init(void) { diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index f944b58cdfe7..56c34e7fd4ee 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -9,6 +9,10 @@ config MMU bool default y +config UID16 + bool + default y + config HIGHMEM bool default y diff --git a/trunk/arch/sparc/kernel/ptrace.c b/trunk/arch/sparc/kernel/ptrace.c index fc470c0e9dc6..475c4c13462c 100644 --- a/trunk/arch/sparc/kernel/ptrace.c +++ b/trunk/arch/sparc/kernel/ptrace.c @@ -286,17 +286,40 @@ asmlinkage void do_ptrace(struct pt_regs *regs) s, (int) request, (int) pid, addr, data, addr2); } #endif - if (request == PTRACE_TRACEME) { - ret = ptrace_traceme(); + int my_ret; + + /* are we already being traced? */ + if (current->ptrace & PT_PTRACED) { + pt_error_return(regs, EPERM); + goto out; + } + my_ret = security_ptrace(current->parent, current); + if (my_ret) { + pt_error_return(regs, -my_ret); + goto out; + } + + /* set the ptrace bit in the process flags. */ + current->ptrace |= PT_PTRACED; pt_succ_return(regs, 0); goto out; } +#ifndef ALLOW_INIT_TRACING + if (pid == 1) { + /* Can't dork with init. */ + pt_error_return(regs, EPERM); + goto out; + } +#endif + read_lock(&tasklist_lock); + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); - child = ptrace_get_task_struct(pid); - if (IS_ERR(child)) { - ret = PTR_ERR(child); - pt_error_return(regs, -ret); + if (!child) { + pt_error_return(regs, ESRCH); goto out; } diff --git a/trunk/arch/sparc64/Kconfig b/trunk/arch/sparc64/Kconfig index b775ceb4cf98..c4b7ad70cd7c 100644 --- a/trunk/arch/sparc64/Kconfig +++ b/trunk/arch/sparc64/Kconfig @@ -309,6 +309,11 @@ config COMPAT depends on SPARC32_COMPAT default y +config UID16 + bool + depends on SPARC32_COMPAT + default y + config BINFMT_ELF32 tristate "Kernel support for 32-bit ELF binaries" depends on SPARC32_COMPAT diff --git a/trunk/arch/sparc64/kernel/ptrace.c b/trunk/arch/sparc64/kernel/ptrace.c index 84d3df2264cb..774ecbb8a031 100644 --- a/trunk/arch/sparc64/kernel/ptrace.c +++ b/trunk/arch/sparc64/kernel/ptrace.c @@ -198,15 +198,39 @@ asmlinkage void do_ptrace(struct pt_regs *regs) } #endif if (request == PTRACE_TRACEME) { - ret = ptrace_traceme(); + int ret; + + /* are we already being traced? */ + if (current->ptrace & PT_PTRACED) { + pt_error_return(regs, EPERM); + goto out; + } + ret = security_ptrace(current->parent, current); + if (ret) { + pt_error_return(regs, -ret); + goto out; + } + + /* set the ptrace bit in the process flags. */ + current->ptrace |= PT_PTRACED; pt_succ_return(regs, 0); goto out; } +#ifndef ALLOW_INIT_TRACING + if (pid == 1) { + /* Can't dork with init. */ + pt_error_return(regs, EPERM); + goto out; + } +#endif + read_lock(&tasklist_lock); + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); - child = ptrace_get_task_struct(pid); - if (IS_ERR(child)) { - ret = PTR_ERR(child); - pt_error_return(regs, -ret); + if (!child) { + pt_error_return(regs, ESRCH); goto out; } diff --git a/trunk/arch/um/Kconfig b/trunk/arch/um/Kconfig index b4ff2e576021..1eb21de9d1b5 100644 --- a/trunk/arch/um/Kconfig +++ b/trunk/arch/um/Kconfig @@ -22,6 +22,10 @@ config SBUS config PCI bool +config UID16 + bool + default y + config GENERIC_CALIBRATE_DELAY bool default y @@ -79,7 +83,7 @@ config KERNEL_HALF_GIGS of physical memory. config MODE_SKAS - bool "Separate Kernel Address Space support" if MODE_TT + bool "Separate Kernel Address Space support" default y help This option controls whether skas (separate kernel address space) diff --git a/trunk/arch/um/drivers/ubd_kern.c b/trunk/arch/um/drivers/ubd_kern.c index 3a93c6f772fa..73f9652b2ee9 100644 --- a/trunk/arch/um/drivers/ubd_kern.c +++ b/trunk/arch/um/drivers/ubd_kern.c @@ -117,7 +117,6 @@ static int ubd_open(struct inode * inode, struct file * filp); static int ubd_release(struct inode * inode, struct file * file); static int ubd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg); -static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo); #define MAX_DEV (8) @@ -126,7 +125,6 @@ static struct block_device_operations ubd_blops = { .open = ubd_open, .release = ubd_release, .ioctl = ubd_ioctl, - .getgeo = ubd_getgeo, }; /* Protected by the queue_lock */ @@ -1060,16 +1058,6 @@ static void do_ubd_request(request_queue_t *q) } } -static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct ubd *dev = bdev->bd_disk->private_data; - - geo->heads = 128; - geo->sectors = 32; - geo->cylinders = dev->size / (128 * 32 * 512); - return 0; -} - static int ubd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { @@ -1082,7 +1070,16 @@ static int ubd_ioctl(struct inode * inode, struct file * file, }; switch (cmd) { + struct hd_geometry g; struct cdrom_volctrl volume; + case HDIO_GETGEO: + if(!loc) return(-EINVAL); + g.heads = 128; + g.sectors = 32; + g.cylinders = dev->size / (128 * 32 * 512); + g.start = get_start_sect(inode->i_bdev); + return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0); + case HDIO_GET_IDENTITY: ubd_id.cyls = dev->size / (128 * 32 * 512); if(copy_to_user((char __user *) arg, (char *) &ubd_id, diff --git a/trunk/arch/um/include/kern_util.h b/trunk/arch/um/include/kern_util.h index 8f4e46d677ab..e5fec5570199 100644 --- a/trunk/arch/um/include/kern_util.h +++ b/trunk/arch/um/include/kern_util.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -10,19 +10,6 @@ #include "sysdep/ptrace.h" #include "sysdep/faultinfo.h" -typedef void (*kern_hndl)(int, union uml_pt_regs *); - -struct kern_handlers { - kern_hndl relay_signal; - kern_hndl winch; - kern_hndl bus_handler; - kern_hndl page_fault; - kern_hndl sigio_handler; - kern_hndl timer_handler; -}; - -extern struct kern_handlers handlinfo_kern; - extern int ncpus; extern char *linux_prog; extern char *gdb_init; @@ -64,6 +51,8 @@ extern void timer_handler(int sig, union uml_pt_regs *regs); extern int set_signals(int enable); extern void force_sigbus(void); extern int pid_to_processor_id(int pid); +extern void block_signals(void); +extern void unblock_signals(void); extern void deliver_signals(void *t); extern int next_syscall_index(int max); extern int next_trap_index(int max); @@ -122,8 +111,6 @@ extern void arch_switch(void); extern void free_irq(unsigned int, void *); extern int um_in_interrupt(void); extern int cpu(void); -extern void segv_handler(int sig, union uml_pt_regs *regs); -extern void sigio_handler(int sig, union uml_pt_regs *regs); #endif diff --git a/trunk/arch/um/include/os.h b/trunk/arch/um/include/os.h index dd72d66cf0ed..c279ee6d89e4 100644 --- a/trunk/arch/um/include/os.h +++ b/trunk/arch/um/include/os.h @@ -9,8 +9,6 @@ #include "uml-config.h" #include "asm/types.h" #include "../os/include/file.h" -#include "sysdep/ptrace.h" -#include "kern_util.h" #define OS_TYPE_FILE 1 #define OS_TYPE_DIR 2 @@ -221,18 +219,4 @@ extern int umid_file_name(char *name, char *buf, int len); extern int set_umid(char *name); extern char *get_umid(void); -/* signal.c */ -extern void set_sigstack(void *sig_stack, int size); -extern void remove_sigstack(void); -extern void set_handler(int sig, void (*handler)(int), int flags, ...); -extern int change_sig(int signal, int on); -extern void block_signals(void); -extern void unblock_signals(void); -extern int get_signals(void); -extern int set_signals(int enable); - -/* trap.c */ -extern void os_fill_handlinfo(struct kern_handlers h); -extern void do_longjmp(void *p, int val); - #endif diff --git a/trunk/arch/um/include/signal_user.h b/trunk/arch/um/include/signal_user.h new file mode 100644 index 000000000000..b075e543d864 --- /dev/null +++ b/trunk/arch/um/include/signal_user.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#ifndef __SIGNAL_USER_H__ +#define __SIGNAL_USER_H__ + +extern int signal_stack_size; + +extern int change_sig(int signal, int on); +extern void set_sigstack(void *stack, int size); +extern void set_handler(int sig, void (*handler)(int), int flags, ...); +extern int set_signals(int enable); +extern int get_signals(void); + +#endif + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/include/user_util.h b/trunk/arch/um/include/user_util.h index c1dbd77b073f..b9984003e603 100644 --- a/trunk/arch/um/include/user_util.h +++ b/trunk/arch/um/include/user_util.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -23,7 +23,12 @@ struct cpu_task { extern struct cpu_task cpu_tasks[]; -extern void (*sig_info[])(int, union uml_pt_regs *); +struct signal_info { + void (*handler)(int, union uml_pt_regs *); + int is_irq; +}; + +extern struct signal_info sig_info[]; extern unsigned long low_physmem; extern unsigned long high_physmem; @@ -59,6 +64,7 @@ extern void setup_machinename(char *machine_out); extern void setup_hostinfo(void); extern void do_exec(int old_pid, int new_pid); extern void tracer_panic(char *msg, ...); +extern void do_longjmp(void *p, int val); extern int detach(int pid, int sig); extern int attach(int pid); extern void kill_child_dead(int pid); diff --git a/trunk/arch/um/kernel/Makefile b/trunk/arch/um/kernel/Makefile index 193cc2b7448d..6f7700593a6f 100644 --- a/trunk/arch/um/kernel/Makefile +++ b/trunk/arch/um/kernel/Makefile @@ -9,8 +9,8 @@ clean-files := obj-y = config.o exec_kern.o exitcode.o \ init_task.o irq.o irq_user.o ksyms.o mem.o physmem.o \ process_kern.o ptrace.o reboot.o resource.o sigio_user.o sigio_kern.o \ - signal_kern.o smp.o syscall_kern.o sysrq.o time.o \ - time_kern.o tlb.o trap_kern.o uaccess.o um_arch.o umid.o \ + signal_kern.o signal_user.o smp.o syscall_kern.o sysrq.o time.o \ + time_kern.o tlb.o trap_kern.o trap_user.o uaccess.o um_arch.o umid.o \ user_util.o obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o diff --git a/trunk/arch/um/kernel/irq_user.c b/trunk/arch/um/kernel/irq_user.c index 0e32f5f4a887..50a2aa35cda9 100644 --- a/trunk/arch/um/kernel/irq_user.c +++ b/trunk/arch/um/kernel/irq_user.c @@ -15,6 +15,7 @@ #include "kern_util.h" #include "user.h" #include "process.h" +#include "signal_user.h" #include "sigio.h" #include "irq_user.h" #include "os.h" diff --git a/trunk/arch/um/kernel/process_kern.c b/trunk/arch/um/kernel/process_kern.c index d2d3f256778c..651abf255bc5 100644 --- a/trunk/arch/um/kernel/process_kern.c +++ b/trunk/arch/um/kernel/process_kern.c @@ -36,6 +36,7 @@ #include "kern_util.h" #include "kern.h" #include "signal_kern.h" +#include "signal_user.h" #include "init.h" #include "irq_user.h" #include "mem_user.h" diff --git a/trunk/arch/um/kernel/reboot.c b/trunk/arch/um/kernel/reboot.c index 6f1a3a288117..a637e885c583 100644 --- a/trunk/arch/um/kernel/reboot.c +++ b/trunk/arch/um/kernel/reboot.c @@ -12,8 +12,6 @@ #include "mode.h" #include "choose-mode.h" -void (*pm_power_off)(void); - #ifdef CONFIG_SMP static void kill_idlers(int me) { diff --git a/trunk/arch/um/kernel/signal_kern.c b/trunk/arch/um/kernel/signal_kern.c index 7b0e0e81c161..03618bd13d55 100644 --- a/trunk/arch/um/kernel/signal_kern.c +++ b/trunk/arch/um/kernel/signal_kern.c @@ -22,6 +22,7 @@ #include "asm/ucontext.h" #include "kern_util.h" #include "signal_kern.h" +#include "signal_user.h" #include "kern.h" #include "frame_kern.h" #include "sigcontext.h" diff --git a/trunk/arch/um/kernel/signal_user.c b/trunk/arch/um/kernel/signal_user.c new file mode 100644 index 000000000000..62f457835fb1 --- /dev/null +++ b/trunk/arch/um/kernel/signal_user.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "user_util.h" +#include "kern_util.h" +#include "user.h" +#include "signal_user.h" +#include "signal_kern.h" +#include "sysdep/sigcontext.h" +#include "sigcontext.h" + +void set_sigstack(void *sig_stack, int size) +{ + stack_t stack = ((stack_t) { .ss_flags = 0, + .ss_sp = (__ptr_t) sig_stack, + .ss_size = size - sizeof(void *) }); + + if(sigaltstack(&stack, NULL) != 0) + panic("enabling signal stack failed, errno = %d\n", errno); +} + +void set_handler(int sig, void (*handler)(int), int flags, ...) +{ + struct sigaction action; + va_list ap; + int mask; + + va_start(ap, flags); + action.sa_handler = handler; + sigemptyset(&action.sa_mask); + while((mask = va_arg(ap, int)) != -1){ + sigaddset(&action.sa_mask, mask); + } + va_end(ap); + action.sa_flags = flags; + action.sa_restorer = NULL; + if(sigaction(sig, &action, NULL) < 0) + panic("sigaction failed"); +} + +int change_sig(int signal, int on) +{ + sigset_t sigset, old; + + sigemptyset(&sigset); + sigaddset(&sigset, signal); + sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old); + 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; + + sigemptyset(&mask); + sigaddset(&mask, SIGVTALRM); + sigaddset(&mask, SIGALRM); + sigaddset(&mask, SIGIO); + if(sigprocmask(type, &mask, NULL) < 0) + panic("Failed to change signal mask - errno = %d", errno); +} + +void block_signals(void) +{ + change_signals(SIG_BLOCK); +} + +void unblock_signals(void) +{ + change_signals(SIG_UNBLOCK); +} + +/* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled + * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to + * be able to profile all of UML, not just the non-critical sections. If + * profiling is not thread-safe, then that is not my problem. We can disable + * profiling when SMP is enabled in that case. + */ +#define SIGIO_BIT 0 +#define SIGVTALRM_BIT 1 + +static int enable_mask(sigset_t *mask) +{ + int sigs; + + sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT; + sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT; + sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT; + return(sigs); +} + +int get_signals(void) +{ + sigset_t mask; + + if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0) + panic("Failed to get signal mask"); + return(enable_mask(&mask)); +} + +int set_signals(int enable) +{ + sigset_t mask; + int ret; + + sigemptyset(&mask); + if(enable & (1 << SIGIO_BIT)) + sigaddset(&mask, SIGIO); + if(enable & (1 << SIGVTALRM_BIT)){ + sigaddset(&mask, SIGVTALRM); + sigaddset(&mask, SIGALRM); + } + + /* This is safe - sigprocmask is guaranteed to copy locally the + * value of new_set, do his work and then, at the end, write to + * old_set. + */ + if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0) + panic("Failed to enable signals"); + ret = enable_mask(&mask); + sigemptyset(&mask); + if((enable & (1 << SIGIO_BIT)) == 0) + sigaddset(&mask, SIGIO); + if((enable & (1 << SIGVTALRM_BIT)) == 0){ + sigaddset(&mask, SIGVTALRM); + sigaddset(&mask, SIGALRM); + } + if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0) + panic("Failed to block signals"); + + return(ret); +} + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/kernel/skas/Makefile b/trunk/arch/um/kernel/skas/Makefile index 7a9fc16d71d4..8de471b59c1c 100644 --- a/trunk/arch/um/kernel/skas/Makefile +++ b/trunk/arch/um/kernel/skas/Makefile @@ -4,7 +4,7 @@ # obj-y := clone.o exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \ - syscall.o tlb.o uaccess.o + syscall.o tlb.o trap_user.o uaccess.o USER_OBJS := process.o clone.o diff --git a/trunk/arch/um/kernel/skas/include/skas.h b/trunk/arch/um/kernel/skas/include/skas.h index 01d489de3986..daa2f85b684c 100644 --- a/trunk/arch/um/kernel/skas/include/skas.h +++ b/trunk/arch/um/kernel/skas/include/skas.h @@ -22,6 +22,7 @@ extern int start_idle_thread(void *stack, void *switch_buf_ptr, extern int user_thread(unsigned long stack, int flags); extern void userspace(union uml_pt_regs *regs); extern void new_thread_proc(void *stack, void (*handler)(int sig)); +extern void remove_sigstack(void); extern void new_thread_handler(int sig); extern void handle_syscall(union uml_pt_regs *regs); extern int map(struct mm_id * mm_idp, unsigned long virt, diff --git a/trunk/arch/um/kernel/skas/process.c b/trunk/arch/um/kernel/skas/process.c index 9264d4021dfe..599d679bd4fc 100644 --- a/trunk/arch/um/kernel/skas/process.c +++ b/trunk/arch/um/kernel/skas/process.c @@ -31,6 +31,7 @@ #include "proc_mm.h" #include "skas_ptrace.h" #include "chan_user.h" +#include "signal_user.h" #include "registers.h" #include "mem.h" #include "uml-config.h" @@ -513,6 +514,16 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) siglongjmp(**switch_buf, 1); } +void remove_sigstack(void) +{ + stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE, + .ss_sp = NULL, + .ss_size = 0 }); + + if(sigaltstack(&stack, NULL) != 0) + panic("disabling signal stack failed, errno = %d\n", errno); +} + void initial_thread_cb_skas(void (*proc)(void *), void *arg) { sigjmp_buf here; diff --git a/trunk/arch/um/kernel/skas/process_kern.c b/trunk/arch/um/kernel/skas/process_kern.c index 09790ccb161c..9c990253966c 100644 --- a/trunk/arch/um/kernel/skas/process_kern.c +++ b/trunk/arch/um/kernel/skas/process_kern.c @@ -14,6 +14,7 @@ #include "asm/atomic.h" #include "kern_util.h" #include "time_user.h" +#include "signal_user.h" #include "skas.h" #include "os.h" #include "user_util.h" diff --git a/trunk/arch/um/os-Linux/skas/trap.c b/trunk/arch/um/kernel/skas/trap_user.c similarity index 53% rename from trunk/arch/um/os-Linux/skas/trap.c rename to trunk/arch/um/kernel/skas/trap_user.c index 9ad5fbec4593..9950a6716fe5 100644 --- a/trunk/arch/um/os-Linux/skas/trap.c +++ b/trunk/arch/um/kernel/skas/trap_user.c @@ -1,10 +1,11 @@ -/* +/* * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) * Licensed under the GPL */ #include #include +#include "signal_user.h" #include "user_util.h" #include "kern_util.h" #include "task.h" @@ -13,13 +14,12 @@ #include "ptrace_user.h" #include "sysdep/ptrace.h" #include "sysdep/ptrace_user.h" -#include "os.h" void sig_handler_common_skas(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; struct skas_regs *r; - void (*handler)(int, union uml_pt_regs *); + struct signal_info *info; int save_errno = errno; int save_user; @@ -34,22 +34,17 @@ void sig_handler_common_skas(int sig, void *sc_ptr) r = &TASK_REGS(get_current())->skas; save_user = r->is_user; r->is_user = 0; - if ( sig == SIGFPE || sig == SIGSEGV || - sig == SIGBUS || sig == SIGILL || - sig == SIGTRAP ) { - GET_FAULTINFO_FROM_SC(r->faultinfo, sc); - } + if ( sig == SIGFPE || sig == SIGSEGV || + sig == SIGBUS || sig == SIGILL || + sig == SIGTRAP ) { + GET_FAULTINFO_FROM_SC(r->faultinfo, sc); + } change_sig(SIGUSR1, 1); + info = &sig_info[sig]; + if(!info->is_irq) unblock_signals(); - handler = sig_info[sig]; - - /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */ - if (sig != SIGIO && sig != SIGWINCH && - sig != SIGVTALRM && sig != SIGALRM) - unblock_signals(); - - handler(sig, (union uml_pt_regs *) r); + (*info->handler)(sig, (union uml_pt_regs *) r); errno = save_errno; r->is_user = save_user; @@ -59,15 +54,25 @@ extern int ptrace_faultinfo; void user_signal(int sig, union uml_pt_regs *regs, int pid) { - void (*handler)(int, union uml_pt_regs *); - int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || - (sig == SIGILL) || (sig == SIGTRAP)); + struct signal_info *info; + int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || + (sig == SIGILL) || (sig == SIGTRAP)); if (segv) get_skas_faultinfo(pid, ®s->skas.faultinfo); - - handler = sig_info[sig]; - handler(sig, (union uml_pt_regs *) regs); + info = &sig_info[sig]; + (*info->handler)(sig, regs); unblock_signals(); } + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/kernel/time.c b/trunk/arch/um/kernel/time.c index 11f518a7e156..c40b611e3d93 100644 --- a/trunk/arch/um/kernel/time.c +++ b/trunk/arch/um/kernel/time.c @@ -14,9 +14,9 @@ #include "kern_util.h" #include "user.h" #include "process.h" +#include "signal_user.h" #include "time_user.h" #include "kern_constants.h" -#include "os.h" /* XXX This really needs to be declared and initialized in a kernel file since * it's in diff --git a/trunk/arch/um/kernel/trap_kern.c b/trunk/arch/um/kernel/trap_kern.c index d56046c2aba2..0d4c10a73607 100644 --- a/trunk/arch/um/kernel/trap_kern.c +++ b/trunk/arch/um/kernel/trap_kern.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -26,13 +26,9 @@ #include "mconsole_kern.h" #include "mem.h" #include "mem_kern.h" -#include "sysdep/sigcontext.h" -#include "sysdep/ptrace.h" -#include "os.h" #ifdef CONFIG_MODE_SKAS #include "skas.h" #endif -#include "os.h" /* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */ int handle_page_fault(unsigned long address, unsigned long ip, @@ -129,25 +125,6 @@ int handle_page_fault(unsigned long address, unsigned long ip, goto out; } -void segv_handler(int sig, union uml_pt_regs *regs) -{ - struct faultinfo * fi = UPT_FAULTINFO(regs); - - if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){ - bad_segv(*fi, UPT_IP(regs)); - return; - } - segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs); -} - -struct kern_handlers handlinfo_kern = { - .relay_signal = relay_signal, - .winch = winch, - .bus_handler = relay_signal, - .page_fault = segv_handler, - .sigio_handler = sigio_handler, - .timer_handler = timer_handler -}; /* * We give a *copy* of the faultinfo in the regs to segv. * This must be done, since nesting SEGVs could overwrite diff --git a/trunk/arch/um/kernel/trap_user.c b/trunk/arch/um/kernel/trap_user.c new file mode 100644 index 000000000000..e9ccd6b8d3c7 --- /dev/null +++ b/trunk/arch/um/kernel/trap_user.c @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) + * Licensed under the GPL + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "init.h" +#include "sysdep/ptrace.h" +#include "sigcontext.h" +#include "sysdep/sigcontext.h" +#include "irq_user.h" +#include "signal_user.h" +#include "time_user.h" +#include "task.h" +#include "mode.h" +#include "choose-mode.h" +#include "kern_util.h" +#include "user_util.h" +#include "os.h" + +void kill_child_dead(int pid) +{ + kill(pid, SIGKILL); + kill(pid, SIGCONT); + do { + int n; + CATCH_EINTR(n = waitpid(pid, NULL, 0)); + if (n > 0) + kill(pid, SIGCONT); + else + break; + } while(1); +} + +void segv_handler(int sig, union uml_pt_regs *regs) +{ + struct faultinfo * fi = UPT_FAULTINFO(regs); + + if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){ + bad_segv(*fi, UPT_IP(regs)); + return; + } + segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs); +} + +void usr2_handler(int sig, union uml_pt_regs *regs) +{ + CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0); +} + +struct signal_info sig_info[] = { + [ SIGTRAP ] { .handler = relay_signal, + .is_irq = 0 }, + [ SIGFPE ] { .handler = relay_signal, + .is_irq = 0 }, + [ SIGILL ] { .handler = relay_signal, + .is_irq = 0 }, + [ SIGWINCH ] { .handler = winch, + .is_irq = 1 }, + [ SIGBUS ] { .handler = bus_handler, + .is_irq = 0 }, + [ SIGSEGV] { .handler = segv_handler, + .is_irq = 0 }, + [ SIGIO ] { .handler = sigio_handler, + .is_irq = 1 }, + [ SIGVTALRM ] { .handler = timer_handler, + .is_irq = 1 }, + [ SIGALRM ] { .handler = timer_handler, + .is_irq = 1 }, + [ SIGUSR2 ] { .handler = usr2_handler, + .is_irq = 0 }, +}; + +void do_longjmp(void *b, int val) +{ + sigjmp_buf *buf = b; + + siglongjmp(*buf, val); +} + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: + */ diff --git a/trunk/arch/um/kernel/tt/exec_kern.c b/trunk/arch/um/kernel/tt/exec_kern.c index 136e54c47d37..065b504a653b 100644 --- a/trunk/arch/um/kernel/tt/exec_kern.c +++ b/trunk/arch/um/kernel/tt/exec_kern.c @@ -14,6 +14,7 @@ #include "kern_util.h" #include "irq_user.h" #include "time_user.h" +#include "signal_user.h" #include "mem_user.h" #include "os.h" #include "tlb.h" diff --git a/trunk/arch/um/kernel/tt/process_kern.c b/trunk/arch/um/kernel/tt/process_kern.c index 14d4622a5fb8..cfaa373a6e77 100644 --- a/trunk/arch/um/kernel/tt/process_kern.c +++ b/trunk/arch/um/kernel/tt/process_kern.c @@ -13,6 +13,7 @@ #include "asm/ptrace.h" #include "asm/tlbflush.h" #include "irq_user.h" +#include "signal_user.h" #include "kern_util.h" #include "user_util.h" #include "os.h" diff --git a/trunk/arch/um/kernel/tt/tracer.c b/trunk/arch/um/kernel/tt/tracer.c index 71daae24e48a..d11e7399d7a1 100644 --- a/trunk/arch/um/kernel/tt/tracer.c +++ b/trunk/arch/um/kernel/tt/tracer.c @@ -19,6 +19,7 @@ #include "sigcontext.h" #include "sysdep/sigcontext.h" #include "os.h" +#include "signal_user.h" #include "user_util.h" #include "mem_user.h" #include "process.h" diff --git a/trunk/arch/um/kernel/tt/trap_user.c b/trunk/arch/um/kernel/tt/trap_user.c index a414c529fbcd..fc108615beaf 100644 --- a/trunk/arch/um/kernel/tt/trap_user.c +++ b/trunk/arch/um/kernel/tt/trap_user.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -8,18 +8,18 @@ #include #include "sysdep/ptrace.h" #include "sysdep/sigcontext.h" +#include "signal_user.h" #include "user_util.h" #include "kern_util.h" #include "task.h" #include "tt.h" -#include "os.h" void sig_handler_common_tt(int sig, void *sc_ptr) { struct sigcontext *sc = sc_ptr; struct tt_regs save_regs, *r; + struct signal_info *info; int save_errno = errno, is_user; - void (*handler)(int, union uml_pt_regs *); /* 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, @@ -40,14 +40,10 @@ void sig_handler_common_tt(int sig, void *sc_ptr) if(sig != SIGUSR2) r->syscall = -1; - handler = sig_info[sig]; - - /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */ - if (sig != SIGIO && sig != SIGWINCH && - sig != SIGVTALRM && sig != SIGALRM) - unblock_signals(); + info = &sig_info[sig]; + if(!info->is_irq) unblock_signals(); - handler(sig, (union uml_pt_regs *) r); + (*info->handler)(sig, (union uml_pt_regs *) r); if(is_user){ interrupt_end(); diff --git a/trunk/arch/um/kernel/um_arch.c b/trunk/arch/um/kernel/um_arch.c index 73747ac19774..26626b2b9172 100644 --- a/trunk/arch/um/kernel/um_arch.c +++ b/trunk/arch/um/kernel/um_arch.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ @@ -363,11 +363,6 @@ 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); - /* - * Setting up handlers to 'sig_info' struct - */ - os_fill_handlinfo(handlinfo_kern); - 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 diff --git a/trunk/arch/um/os-Linux/Makefile b/trunk/arch/um/os-Linux/Makefile index 40c7d6b1df68..11e30b13e318 100644 --- a/trunk/arch/um/os-Linux/Makefile +++ b/trunk/arch/um/os-Linux/Makefile @@ -4,13 +4,11 @@ # obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ - start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o user_syms.o \ - drivers/ sys-$(SUBARCH)/ - -obj-$(CONFIG_MODE_SKAS) += skas/ + start_up.o time.o tt.o tty.o uaccess.o umid.o user_syms.o drivers/ \ + sys-$(SUBARCH)/ USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ - start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o + start_up.o time.o tt.o tty.o uaccess.o umid.o elf_aux.o: $(ARCH_DIR)/kernel-offsets.h CFLAGS_elf_aux.o += -I$(objtree)/arch/um diff --git a/trunk/arch/um/os-Linux/main.c b/trunk/arch/um/os-Linux/main.c index 172c8474453c..23da27d22569 100644 --- a/trunk/arch/um/os-Linux/main.c +++ b/trunk/arch/um/os-Linux/main.c @@ -16,6 +16,7 @@ #include "user_util.h" #include "kern_util.h" #include "mem_user.h" +#include "signal_user.h" #include "time_user.h" #include "irq_user.h" #include "user.h" diff --git a/trunk/arch/um/os-Linux/process.c b/trunk/arch/um/os-Linux/process.c index 39815c6b5e45..d9c52387c4a1 100644 --- a/trunk/arch/um/os-Linux/process.c +++ b/trunk/arch/um/os-Linux/process.c @@ -15,6 +15,7 @@ #include "os.h" #include "user.h" #include "user_util.h" +#include "signal_user.h" #include "process.h" #include "irq_user.h" #include "kern_util.h" diff --git a/trunk/arch/um/os-Linux/signal.c b/trunk/arch/um/os-Linux/signal.c index c1f46a0fef13..c7bfd5ee3925 100644 --- a/trunk/arch/um/os-Linux/signal.c +++ b/trunk/arch/um/os-Linux/signal.c @@ -4,22 +4,9 @@ */ #include -#include -#include -#include -#include -#include -#include -#include -#include "user_util.h" -#include "kern_util.h" -#include "user.h" -#include "signal_kern.h" -#include "sysdep/sigcontext.h" -#include "sysdep/signal.h" -#include "sigcontext.h" #include "time_user.h" #include "mode.h" +#include "sysdep/signal.h" void sig_handler(ARCH_SIGHDLR_PARAM) { @@ -49,138 +36,13 @@ void alarm_handler(ARCH_SIGHDLR_PARAM) switch_timers(1); } -void set_sigstack(void *sig_stack, int size) -{ - stack_t stack = ((stack_t) { .ss_flags = 0, - .ss_sp = (__ptr_t) sig_stack, - .ss_size = size - sizeof(void *) }); - - if(sigaltstack(&stack, NULL) != 0) - panic("enabling signal stack failed, errno = %d\n", errno); -} - -void remove_sigstack(void) -{ - stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE, - .ss_sp = NULL, - .ss_size = 0 }); - - if(sigaltstack(&stack, NULL) != 0) - panic("disabling signal stack failed, errno = %d\n", errno); -} - -void set_handler(int sig, void (*handler)(int), int flags, ...) -{ - struct sigaction action; - va_list ap; - int mask; - - va_start(ap, flags); - action.sa_handler = handler; - sigemptyset(&action.sa_mask); - while((mask = va_arg(ap, int)) != -1){ - sigaddset(&action.sa_mask, mask); - } - va_end(ap); - action.sa_flags = flags; - action.sa_restorer = NULL; - if(sigaction(sig, &action, NULL) < 0) - panic("sigaction failed"); -} - -int change_sig(int signal, int on) -{ - sigset_t sigset, old; - - sigemptyset(&sigset); - sigaddset(&sigset, signal); - sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old); - 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; - - sigemptyset(&mask); - sigaddset(&mask, SIGVTALRM); - sigaddset(&mask, SIGALRM); - sigaddset(&mask, SIGIO); - if(sigprocmask(type, &mask, NULL) < 0) - panic("Failed to change signal mask - errno = %d", errno); -} - -void block_signals(void) -{ - change_signals(SIG_BLOCK); -} - -void unblock_signals(void) -{ - change_signals(SIG_UNBLOCK); -} - -/* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled - * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to - * be able to profile all of UML, not just the non-critical sections. If - * profiling is not thread-safe, then that is not my problem. We can disable - * profiling when SMP is enabled in that case. +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * Emacs will notice this stuff at the end of the file and automatically + * adjust the settings for this buffer only. This must remain at the end + * of the file. + * --------------------------------------------------------------------------- + * Local variables: + * c-file-style: "linux" + * End: */ -#define SIGIO_BIT 0 -#define SIGVTALRM_BIT 1 - -static int enable_mask(sigset_t *mask) -{ - int sigs; - - sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT; - sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT; - sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT; - return(sigs); -} - -int get_signals(void) -{ - sigset_t mask; - - if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0) - panic("Failed to get signal mask"); - return(enable_mask(&mask)); -} - -int set_signals(int enable) -{ - sigset_t mask; - int ret; - - sigemptyset(&mask); - if(enable & (1 << SIGIO_BIT)) - sigaddset(&mask, SIGIO); - if(enable & (1 << SIGVTALRM_BIT)){ - sigaddset(&mask, SIGVTALRM); - sigaddset(&mask, SIGALRM); - } - - /* This is safe - sigprocmask is guaranteed to copy locally the - * value of new_set, do his work and then, at the end, write to - * old_set. - */ - if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0) - panic("Failed to enable signals"); - ret = enable_mask(&mask); - sigemptyset(&mask); - if((enable & (1 << SIGIO_BIT)) == 0) - sigaddset(&mask, SIGIO); - if((enable & (1 << SIGVTALRM_BIT)) == 0){ - sigaddset(&mask, SIGVTALRM); - sigaddset(&mask, SIGALRM); - } - if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0) - panic("Failed to block signals"); - - return(ret); -} diff --git a/trunk/arch/um/os-Linux/skas/Makefile b/trunk/arch/um/os-Linux/skas/Makefile deleted file mode 100644 index eab5386d60a7..000000000000 --- a/trunk/arch/um/os-Linux/skas/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# -# Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com) -# Licensed under the GPL -# - -obj-y := trap.o - -USER_OBJS := trap.o - -include arch/um/scripts/Makefile.rules diff --git a/trunk/arch/um/os-Linux/start_up.c b/trunk/arch/um/os-Linux/start_up.c index b47e5e71d1a5..29a9e3f43763 100644 --- a/trunk/arch/um/os-Linux/start_up.c +++ b/trunk/arch/um/os-Linux/start_up.c @@ -24,6 +24,7 @@ #include "kern_util.h" #include "user.h" #include "signal_kern.h" +#include "signal_user.h" #include "sysdep/ptrace.h" #include "sysdep/sigcontext.h" #include "irq_user.h" diff --git a/trunk/arch/um/os-Linux/trap.c b/trunk/arch/um/os-Linux/trap.c deleted file mode 100644 index 321e1c8e227d..000000000000 --- a/trunk/arch/um/os-Linux/trap.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ - -#include -#include -#include -#include "kern_util.h" -#include "user_util.h" -#include "os.h" -#include "mode.h" - -void usr2_handler(int sig, union uml_pt_regs *regs) -{ - CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0); -} - -void (*sig_info[NSIG])(int, union uml_pt_regs *); - -void os_fill_handlinfo(struct kern_handlers h) -{ - sig_info[SIGTRAP] = h.relay_signal; - sig_info[SIGFPE] = h.relay_signal; - sig_info[SIGILL] = h.relay_signal; - sig_info[SIGWINCH] = h.winch; - sig_info[SIGBUS] = h.bus_handler; - sig_info[SIGSEGV] = h.page_fault; - sig_info[SIGIO] = h.sigio_handler; - sig_info[SIGVTALRM] = h.timer_handler; - sig_info[SIGALRM] = h.timer_handler; - sig_info[SIGUSR2] = usr2_handler; -} - -void do_longjmp(void *b, int val) -{ - sigjmp_buf *buf = b; - - siglongjmp(*buf, val); -} diff --git a/trunk/arch/um/os-Linux/tt.c b/trunk/arch/um/os-Linux/tt.c index cb2648b79d0f..a6db8877931a 100644 --- a/trunk/arch/um/os-Linux/tt.c +++ b/trunk/arch/um/os-Linux/tt.c @@ -23,6 +23,7 @@ #include "kern_util.h" #include "user.h" #include "signal_kern.h" +#include "signal_user.h" #include "sysdep/ptrace.h" #include "sysdep/sigcontext.h" #include "irq_user.h" @@ -49,20 +50,6 @@ int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, return(0); } -void kill_child_dead(int pid) -{ - kill(pid, SIGKILL); - kill(pid, SIGCONT); - do { - int n; - CATCH_EINTR(n = waitpid(pid, NULL, 0)); - if (n > 0) - kill(pid, SIGCONT); - else - break; - } while(1); -} - /* *------------------------- * only for tt mode (will be deleted in future...) diff --git a/trunk/arch/um/sys-i386/signal.c b/trunk/arch/um/sys-i386/signal.c index 7cd1a82dc8c2..16bc19928b3c 100644 --- a/trunk/arch/um/sys-i386/signal.c +++ b/trunk/arch/um/sys-i386/signal.c @@ -10,6 +10,7 @@ #include "asm/uaccess.h" #include "asm/unistd.h" #include "frame_kern.h" +#include "signal_user.h" #include "sigcontext.h" #include "registers.h" #include "mode.h" diff --git a/trunk/arch/v850/Kconfig b/trunk/arch/v850/Kconfig index 04494638b963..310865903234 100644 --- a/trunk/arch/v850/Kconfig +++ b/trunk/arch/v850/Kconfig @@ -10,6 +10,9 @@ mainmenu "uClinux/v850 (w/o MMU) Kernel Configuration" config MMU bool default n +config UID16 + bool + default n config RWSEM_GENERIC_SPINLOCK bool default y diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig index 4f3e925962c3..6ece645e4dbe 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -542,6 +542,11 @@ config SYSVIPC_COMPAT depends on COMPAT && SYSVIPC default y +config UID16 + bool + depends on IA32_EMULATION + default y + endmenu source "net/Kconfig" diff --git a/trunk/arch/x86_64/boot/compressed/misc.c b/trunk/arch/x86_64/boot/compressed/misc.c index cf4b88c416dc..0e10fd84c7cc 100644 --- a/trunk/arch/x86_64/boot/compressed/misc.c +++ b/trunk/arch/x86_64/boot/compressed/misc.c @@ -9,7 +9,7 @@ * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 */ -#include +#include "miscsetup.h" #include #include diff --git a/trunk/arch/x86_64/boot/compressed/miscsetup.h b/trunk/arch/x86_64/boot/compressed/miscsetup.h new file mode 100644 index 000000000000..bb1620531703 --- /dev/null +++ b/trunk/arch/x86_64/boot/compressed/miscsetup.h @@ -0,0 +1,39 @@ +#define NULL 0 +//typedef unsigned int size_t; + + +struct screen_info { + unsigned char orig_x; /* 0x00 */ + unsigned char orig_y; /* 0x01 */ + unsigned short dontuse1; /* 0x02 -- EXT_MEM_K sits here */ + unsigned short orig_video_page; /* 0x04 */ + unsigned char orig_video_mode; /* 0x06 */ + unsigned char orig_video_cols; /* 0x07 */ + unsigned short unused2; /* 0x08 */ + unsigned short orig_video_ega_bx; /* 0x0a */ + unsigned short unused3; /* 0x0c */ + unsigned char orig_video_lines; /* 0x0e */ + unsigned char orig_video_isVGA; /* 0x0f */ + unsigned short orig_video_points; /* 0x10 */ + + /* VESA graphic mode -- linear frame buffer */ + unsigned short lfb_width; /* 0x12 */ + unsigned short lfb_height; /* 0x14 */ + unsigned short lfb_depth; /* 0x16 */ + unsigned long lfb_base; /* 0x18 */ + unsigned long lfb_size; /* 0x1c */ + unsigned short dontuse2, dontuse3; /* 0x20 -- CL_MAGIC and CL_OFFSET here */ + unsigned short lfb_linelength; /* 0x24 */ + unsigned char red_size; /* 0x26 */ + unsigned char red_pos; /* 0x27 */ + unsigned char green_size; /* 0x28 */ + unsigned char green_pos; /* 0x29 */ + unsigned char blue_size; /* 0x2a */ + unsigned char blue_pos; /* 0x2b */ + unsigned char rsvd_size; /* 0x2c */ + unsigned char rsvd_pos; /* 0x2d */ + unsigned short vesapm_seg; /* 0x2e */ + unsigned short vesapm_off; /* 0x30 */ + unsigned short pages; /* 0x32 */ + /* 0x34 -- 0x3f reserved for future expansion */ +}; diff --git a/trunk/arch/x86_64/ia32/ia32entry.S b/trunk/arch/x86_64/ia32/ia32entry.S index 1f0ff5adc80e..df0773c9bdbe 100644 --- a/trunk/arch/x86_64/ia32/ia32entry.S +++ b/trunk/arch/x86_64/ia32/ia32entry.S @@ -643,7 +643,6 @@ ia32_sys_call_table: .quad sys_inotify_init .quad sys_inotify_add_watch .quad sys_inotify_rm_watch - .quad sys_migrate_pages ia32_syscall_end: .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 .quad ni_syscall diff --git a/trunk/arch/x86_64/ia32/ptrace32.c b/trunk/arch/x86_64/ia32/ptrace32.c index 5f4cdfa56901..2a925e2af390 100644 --- a/trunk/arch/x86_64/ia32/ptrace32.c +++ b/trunk/arch/x86_64/ia32/ptrace32.c @@ -196,6 +196,36 @@ static int getreg32(struct task_struct *child, unsigned regno, u32 *val) #undef R32 +static struct task_struct *find_target(int request, int pid, int *err) +{ + struct task_struct *child; + + *err = -EPERM; + if (pid == 1) + return NULL; + + *err = -ESRCH; + read_lock(&tasklist_lock); + child = find_task_by_pid(pid); + if (child) + get_task_struct(child); + read_unlock(&tasklist_lock); + if (child) { + *err = -EPERM; + if (child->pid == 1) + goto out; + *err = ptrace_check_attach(child, request == PTRACE_KILL); + if (*err < 0) + goto out; + return child; + } + out: + if (child) + put_task_struct(child); + return NULL; + +} + asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) { struct task_struct *child; @@ -224,16 +254,9 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) break; } - if (request == PTRACE_TRACEME) - return ptrace_traceme(); - - child = ptrace_get_task_struct(pid); - if (IS_ERR(child)) - return PTR_ERR(child); - - ret = ptrace_check_attach(child, request == PTRACE_KILL); - if (ret < 0) - goto out; + child = find_target(request, pid, &ret); + if (!child) + return ret; childregs = (struct pt_regs *)(child->thread.rsp0 - sizeof(struct pt_regs)); @@ -350,7 +373,6 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data) break; } - out: put_task_struct(child); return ret; } diff --git a/trunk/arch/x86_64/kernel/init_task.c b/trunk/arch/x86_64/kernel/init_task.c index ce31d904d601..e0ba5c1043fd 100644 --- a/trunk/arch/x86_64/kernel/init_task.c +++ b/trunk/arch/x86_64/kernel/init_task.c @@ -44,6 +44,6 @@ EXPORT_SYMBOL(init_task); * section. Since TSS's are completely CPU-local, we want them * on exact cacheline boundaries, to eliminate cacheline ping-pong. */ -DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS; +DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_maxaligned_in_smp = INIT_TSS; #define ALIGN_TO_4K __attribute__((section(".data.init_task"))) diff --git a/trunk/arch/x86_64/kernel/time.c b/trunk/arch/x86_64/kernel/time.c index 43c9fa0f8d5f..74102796e5c0 100644 --- a/trunk/arch/x86_64/kernel/time.c +++ b/trunk/arch/x86_64/kernel/time.c @@ -1075,6 +1075,8 @@ device_initcall(time_init_device); */ #include +extern irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs); + #define DEFAULT_RTC_INT_FREQ 64 #define RTC_NUM_INTS 1 diff --git a/trunk/block/elevator.c b/trunk/block/elevator.c index 99a4d7b2f8ad..39dcccc82ada 100644 --- a/trunk/block/elevator.c +++ b/trunk/block/elevator.c @@ -64,7 +64,7 @@ inline int elv_rq_merge_ok(struct request *rq, struct bio *bio) } EXPORT_SYMBOL(elv_rq_merge_ok); -static inline int elv_try_merge(struct request *__rq, struct bio *bio) +inline int elv_try_merge(struct request *__rq, struct bio *bio) { int ret = ELEVATOR_NO_MERGE; @@ -80,6 +80,7 @@ static inline int elv_try_merge(struct request *__rq, struct bio *bio) return ret; } +EXPORT_SYMBOL(elv_try_merge); static struct elevator_type *elevator_find(const char *name) { diff --git a/trunk/block/ioctl.c b/trunk/block/ioctl.c index 82030e1dfd63..6e278474f9a8 100644 --- a/trunk/block/ioctl.c +++ b/trunk/block/ioctl.c @@ -1,7 +1,6 @@ #include /* for capable() */ #include #include -#include #include #include #include @@ -246,27 +245,6 @@ int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd, set_device_ro(bdev, n); unlock_kernel(); return 0; - case HDIO_GETGEO: { - struct hd_geometry geo; - - if (!arg) - return -EINVAL; - if (!disk->fops->getgeo) - return -ENOTTY; - - /* - * We need to set the startsect first, the driver may - * want to override it. - */ - geo.start = get_start_sect(bdev); - ret = disk->fops->getgeo(bdev, &geo); - if (ret) - return ret; - if (copy_to_user((struct hd_geometry __user *)arg, &geo, - sizeof(geo))) - return -EFAULT; - return 0; - } } lock_kernel(); diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 8e27d0ab0d7c..91d3b4828c49 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -26,8 +26,7 @@ #include #include #include -#include -#include +#include /* * for max sense size @@ -63,15 +62,13 @@ static wait_queue_head_t congestion_wqh[2] = { /* * Controlling structure to kblockd */ -static struct workqueue_struct *kblockd_workqueue; +static struct workqueue_struct *kblockd_workqueue; unsigned long blk_max_low_pfn, blk_max_pfn; EXPORT_SYMBOL(blk_max_low_pfn); EXPORT_SYMBOL(blk_max_pfn); -static DEFINE_PER_CPU(struct list_head, blk_cpu_done); - /* Amount of time in which a process may batch requests */ #define BLK_BATCH_TIME (HZ/50UL) @@ -210,13 +207,6 @@ void blk_queue_merge_bvec(request_queue_t *q, merge_bvec_fn *mbfn) EXPORT_SYMBOL(blk_queue_merge_bvec); -void blk_queue_softirq_done(request_queue_t *q, softirq_done_fn *fn) -{ - q->softirq_done_fn = fn; -} - -EXPORT_SYMBOL(blk_queue_softirq_done); - /** * blk_queue_make_request - define an alternate make_request function for a device * @q: the request queue for the device to be affected @@ -280,7 +270,6 @@ EXPORT_SYMBOL(blk_queue_make_request); static inline void rq_init(request_queue_t *q, struct request *rq) { INIT_LIST_HEAD(&rq->queuelist); - INIT_LIST_HEAD(&rq->donelist); rq->errors = 0; rq->rq_status = RQ_ACTIVE; @@ -297,7 +286,6 @@ static inline void rq_init(request_queue_t *q, struct request *rq) rq->sense = NULL; rq->end_io = NULL; rq->end_io_data = NULL; - rq->completion_data = NULL; } /** @@ -2747,6 +2735,30 @@ static inline int attempt_front_merge(request_queue_t *q, struct request *rq) return 0; } +/** + * blk_attempt_remerge - attempt to remerge active head with next request + * @q: The &request_queue_t belonging to the device + * @rq: The head request (usually) + * + * Description: + * For head-active devices, the queue can easily be unplugged so quickly + * that proper merging is not done on the front request. This may hurt + * performance greatly for some devices. The block layer cannot safely + * do merging on that first request for these queues, but the driver can + * call this function and make it happen any way. Only the driver knows + * when it is safe to do so. + **/ +void blk_attempt_remerge(request_queue_t *q, struct request *rq) +{ + unsigned long flags; + + spin_lock_irqsave(q->queue_lock, flags); + attempt_back_merge(q, rq); + spin_unlock_irqrestore(q->queue_lock, flags); +} + +EXPORT_SYMBOL(blk_attempt_remerge); + static void init_request_from_bio(struct request *req, struct bio *bio) { req->flags |= REQ_CMD; @@ -3274,87 +3286,6 @@ int end_that_request_chunk(struct request *req, int uptodate, int nr_bytes) EXPORT_SYMBOL(end_that_request_chunk); -/* - * splice the completion data to a local structure and hand off to - * process_completion_queue() to complete the requests - */ -static void blk_done_softirq(struct softirq_action *h) -{ - struct list_head *cpu_list; - LIST_HEAD(local_list); - - local_irq_disable(); - cpu_list = &__get_cpu_var(blk_cpu_done); - list_splice_init(cpu_list, &local_list); - local_irq_enable(); - - while (!list_empty(&local_list)) { - struct request *rq = list_entry(local_list.next, struct request, donelist); - - list_del_init(&rq->donelist); - rq->q->softirq_done_fn(rq); - } -} - -#ifdef CONFIG_HOTPLUG_CPU - -static int blk_cpu_notify(struct notifier_block *self, unsigned long action, - void *hcpu) -{ - /* - * If a CPU goes away, splice its entries to the current CPU - * and trigger a run of the softirq - */ - if (action == CPU_DEAD) { - int cpu = (unsigned long) hcpu; - - local_irq_disable(); - list_splice_init(&per_cpu(blk_cpu_done, cpu), - &__get_cpu_var(blk_cpu_done)); - raise_softirq_irqoff(BLOCK_SOFTIRQ); - local_irq_enable(); - } - - return NOTIFY_OK; -} - - -static struct notifier_block __devinitdata blk_cpu_notifier = { - .notifier_call = blk_cpu_notify, -}; - -#endif /* CONFIG_HOTPLUG_CPU */ - -/** - * blk_complete_request - end I/O on a request - * @req: the request being processed - * - * Description: - * Ends all I/O on a request. It does not handle partial completions, - * unless the driver actually implements this in its completionc callback - * through requeueing. Theh actual completion happens out-of-order, - * through a softirq handler. The user must have registered a completion - * callback through blk_queue_softirq_done(). - **/ - -void blk_complete_request(struct request *req) -{ - struct list_head *cpu_list; - unsigned long flags; - - BUG_ON(!req->q->softirq_done_fn); - - local_irq_save(flags); - - cpu_list = &__get_cpu_var(blk_cpu_done); - list_add_tail(&req->donelist, cpu_list); - raise_softirq_irqoff(BLOCK_SOFTIRQ); - - local_irq_restore(flags); -} - -EXPORT_SYMBOL(blk_complete_request); - /* * queue lock must be held */ @@ -3433,8 +3364,6 @@ EXPORT_SYMBOL(kblockd_flush); int __init blk_dev_init(void) { - int i; - kblockd_workqueue = create_workqueue("kblockd"); if (!kblockd_workqueue) panic("Failed to create kblockd\n"); @@ -3448,14 +3377,6 @@ int __init blk_dev_init(void) iocontext_cachep = kmem_cache_create("blkdev_ioc", sizeof(struct io_context), 0, SLAB_PANIC, NULL, NULL); - for (i = 0; i < NR_CPUS; i++) - INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i)); - - open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL); -#ifdef CONFIG_HOTPLUG_CPU - register_cpu_notifier(&blk_cpu_notifier); -#endif - blk_max_low_pfn = max_low_pfn; blk_max_pfn = max_pfn; diff --git a/trunk/block/scsi_ioctl.c b/trunk/block/scsi_ioctl.c index 18de84c8ccd8..c2ac36dfe4f3 100644 --- a/trunk/block/scsi_ioctl.c +++ b/trunk/block/scsi_ioctl.c @@ -190,21 +190,16 @@ static int verify_command(struct file *file, unsigned char *cmd) safe_for_write(GPCMD_SET_STREAMING), }; unsigned char type = cmd_type[cmd[0]]; - int has_write_perm = 0; /* Anybody who can open the device can do a read-safe command */ if (type & CMD_READ_SAFE) return 0; - /* - * file can be NULL from ioctl_by_bdev()... - */ - if (file) - has_write_perm = file->f_mode & FMODE_WRITE; - /* Write-safe commands just require a writable open.. */ - if ((type & CMD_WRITE_SAFE) && has_write_perm) - return 0; + if (type & CMD_WRITE_SAFE) { + if (file->f_mode & FMODE_WRITE) + return 0; + } /* And root can do any command.. */ if (capable(CAP_SYS_RAWIO)) diff --git a/trunk/drivers/acorn/block/mfmhd.c b/trunk/drivers/acorn/block/mfmhd.c index ce074f6f3369..4b65f74d66b1 100644 --- a/trunk/drivers/acorn/block/mfmhd.c +++ b/trunk/drivers/acorn/block/mfmhd.c @@ -129,6 +129,19 @@ static DEFINE_SPINLOCK(mfm_lock); #define MAJOR_NR MFM_ACORN_MAJOR #define QUEUE (mfm_queue) #define CURRENT elv_next_request(mfm_queue) +/* + * This sort of stuff should be in a header file shared with ide.c, hd.c, xd.c etc + */ +#ifndef HDIO_GETGEO +#define HDIO_GETGEO 0x301 +struct hd_geometry { + unsigned char heads; + unsigned char sectors; + unsigned short cylinders; + unsigned long start; +}; +#endif + /* * Configuration section @@ -1140,13 +1153,22 @@ static int mfm_initdrives(void) * The 'front' end of the mfm driver follows... */ -static int mfm_getgeo(struct block_device *bdev, struct hd_geometry *geo) +static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg) { - struct mfm_info *p = bdev->bd_disk->private_data; - - geo->heads = p->heads; - geo->sectors = p->sectors; - geo->cylinders = p->cylinders; + struct mfm_info *p = inode->i_bdev->bd_disk->private_data; + struct hd_geometry *geo = (struct hd_geometry *) arg; + if (cmd != HDIO_GETGEO) + return -EINVAL; + if (!arg) + return -EINVAL; + if (put_user (p->heads, &geo->heads)) + return -EFAULT; + if (put_user (p->sectors, &geo->sectors)) + return -EFAULT; + if (put_user (p->cylinders, &geo->cylinders)) + return -EFAULT; + if (put_user (get_start_sect(inode->i_bdev), &geo->start)) + return -EFAULT; return 0; } @@ -1197,7 +1219,7 @@ void xd_set_geometry(struct block_device *bdev, unsigned char secsptrack, static struct block_device_operations mfm_fops = { .owner = THIS_MODULE, - .getgeo = mfm_getgeo, + .ioctl = mfm_ioctl, }; /* diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index 20c9a37643c7..e3cd0b16031a 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -204,13 +204,11 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size, return AE_OK; } -EXPORT_SYMBOL_GPL(acpi_os_map_memory); void acpi_os_unmap_memory(void __iomem * virt, acpi_size size) { iounmap(virt); } -EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); #ifdef ACPI_FUTURE_USAGE acpi_status diff --git a/trunk/drivers/atm/nicstar.c b/trunk/drivers/atm/nicstar.c index 074abc81ec3d..c57e20dcb0f8 100644 --- a/trunk/drivers/atm/nicstar.c +++ b/trunk/drivers/atm/nicstar.c @@ -2126,7 +2126,8 @@ static void process_rsq(ns_dev *card) if (!ns_rsqe_valid(card->rsq.next)) return; - do { + while (ns_rsqe_valid(card->rsq.next)) + { dequeue_rx(card, card->rsq.next); ns_rsqe_init(card->rsq.next); previous = card->rsq.next; @@ -2134,7 +2135,7 @@ static void process_rsq(ns_dev *card) card->rsq.next = card->rsq.base; else card->rsq.next++; - } while (ns_rsqe_valid(card->rsq.next)); + } writel((((u32) previous) - ((u32) card->rsq.base)), card->membase + RSQH); } diff --git a/trunk/drivers/block/DAC960.c b/trunk/drivers/block/DAC960.c index 4a7bb7dfce85..21097a39a057 100644 --- a/trunk/drivers/block/DAC960.c +++ b/trunk/drivers/block/DAC960.c @@ -92,28 +92,34 @@ static int DAC960_open(struct inode *inode, struct file *file) return 0; } -static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo) +static int DAC960_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { - struct gendisk *disk = bdev->bd_disk; + struct gendisk *disk = inode->i_bdev->bd_disk; DAC960_Controller_T *p = disk->queue->queuedata; int drive_nr = (long)disk->private_data; + struct hd_geometry g; + struct hd_geometry __user *loc = (struct hd_geometry __user *)arg; + + if (cmd != HDIO_GETGEO || !loc) + return -EINVAL; if (p->FirmwareType == DAC960_V1_Controller) { - geo->heads = p->V1.GeometryTranslationHeads; - geo->sectors = p->V1.GeometryTranslationSectors; - geo->cylinders = p->V1.LogicalDriveInformation[drive_nr]. - LogicalDriveSize / (geo->heads * geo->sectors); + g.heads = p->V1.GeometryTranslationHeads; + g.sectors = p->V1.GeometryTranslationSectors; + g.cylinders = p->V1.LogicalDriveInformation[drive_nr]. + LogicalDriveSize / (g.heads * g.sectors); } else { DAC960_V2_LogicalDeviceInfo_T *i = p->V2.LogicalDeviceInformation[drive_nr]; switch (i->DriveGeometry) { case DAC960_V2_Geometry_128_32: - geo->heads = 128; - geo->sectors = 32; + g.heads = 128; + g.sectors = 32; break; case DAC960_V2_Geometry_255_63: - geo->heads = 255; - geo->sectors = 63; + g.heads = 255; + g.sectors = 63; break; default: DAC960_Error("Illegal Logical Device Geometry %d\n", @@ -121,11 +127,12 @@ static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo) return -EINVAL; } - geo->cylinders = i->ConfigurableDeviceSize / - (geo->heads * geo->sectors); + g.cylinders = i->ConfigurableDeviceSize / (g.heads * g.sectors); } - return 0; + g.start = get_start_sect(inode->i_bdev); + + return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; } static int DAC960_media_changed(struct gendisk *disk) @@ -150,7 +157,7 @@ static int DAC960_revalidate_disk(struct gendisk *disk) static struct block_device_operations DAC960_BlockDeviceOperations = { .owner = THIS_MODULE, .open = DAC960_open, - .getgeo = DAC960_getgeo, + .ioctl = DAC960_ioctl, .media_changed = DAC960_media_changed, .revalidate_disk = DAC960_revalidate_disk, }; @@ -3760,7 +3767,7 @@ static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command) if (SenseKey == DAC960_SenseKey_VendorSpecific && AdditionalSenseCode == 0x80 && AdditionalSenseCodeQualifier < - ARRAY_SIZE(DAC960_EventMessages)) + sizeof(DAC960_EventMessages) / sizeof(char *)) DAC960_Critical("Physical Device %d:%d %s\n", Controller, EventLogEntry->Channel, EventLogEntry->TargetID, diff --git a/trunk/drivers/block/acsi.c b/trunk/drivers/block/acsi.c index 196c0ec9cd54..5d2d649f7e8d 100644 --- a/trunk/drivers/block/acsi.c +++ b/trunk/drivers/block/acsi.c @@ -1079,19 +1079,6 @@ static void redo_acsi_request( void ) * ***********************************************************************/ -static int acsi_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct acsi_info_struct *aip = bdev->bd_disk->private_data; - - /* - * Just fake some geometry here, it's nonsense anyway - * To make it easy, use Adaptec's usual 64/32 mapping - */ - geo->heads = 64; - geo->sectors = 32; - geo->cylinders = aip->size >> 11; - return 0; -} static int acsi_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg ) @@ -1099,6 +1086,18 @@ static int acsi_ioctl( struct inode *inode, struct file *file, struct gendisk *disk = inode->i_bdev->bd_disk; struct acsi_info_struct *aip = disk->private_data; switch (cmd) { + case HDIO_GETGEO: + /* HDIO_GETGEO is supported more for getting the partition's + * start sector... */ + { struct hd_geometry *geo = (struct hd_geometry *)arg; + /* just fake some geometry here, it's nonsense anyway; to make it + * easy, use Adaptec's usual 64/32 mapping */ + put_user( 64, &geo->heads ); + put_user( 32, &geo->sectors ); + put_user( aip->size >> 11, &geo->cylinders ); + put_user(get_start_sect(inode->i_bdev), &geo->start); + return 0; + } case SCSI_IOCTL_GET_IDLUN: /* SCSI compatible GET_IDLUN call to get target's ID and LUN number */ put_user( aip->target | (aip->lun << 8), @@ -1593,7 +1592,6 @@ static struct block_device_operations acsi_fops = { .open = acsi_open, .release = acsi_release, .ioctl = acsi_ioctl, - .getgeo = acsi_getgeo, .media_changed = acsi_media_change, .revalidate_disk= acsi_revalidate, }; diff --git a/trunk/drivers/block/amiflop.c b/trunk/drivers/block/amiflop.c index 3c679d30b698..0acbfff8ad28 100644 --- a/trunk/drivers/block/amiflop.c +++ b/trunk/drivers/block/amiflop.c @@ -131,7 +131,7 @@ static struct fd_drive_type drive_types[] = { { FD_DD_5, "DD 5.25", 40, 2, 14716, 13630, 1, 40, 81, 6, 30, 2}, { FD_NODRIVE, "No Drive", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; -static int num_dr_types = ARRAY_SIZE(drive_types); +static int num_dr_types = sizeof(drive_types) / sizeof(drive_types[0]); static int amiga_read(int), dos_read(int); static void amiga_write(int), dos_write(int); @@ -1424,16 +1424,6 @@ static void do_fd_request(request_queue_t * q) redo_fd_request(); } -static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - int drive = MINOR(bdev->bd_dev) & 3; - - geo->heads = unit[drive].type->heads; - geo->sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult; - geo->cylinders = unit[drive].type->tracks; - return 0; -} - static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long param) { @@ -1441,6 +1431,18 @@ static int fd_ioctl(struct inode *inode, struct file *filp, static struct floppy_struct getprm; switch(cmd){ + case HDIO_GETGEO: + { + struct hd_geometry loc; + loc.heads = unit[drive].type->heads; + loc.sectors = unit[drive].dtype->sects * unit[drive].type->sect_mult; + loc.cylinders = unit[drive].type->tracks; + loc.start = 0; + if (copy_to_user((void *)param, (void *)&loc, + sizeof(struct hd_geometry))) + return -EFAULT; + break; + } case FDFMTBEG: get_fdc(drive); if (fd_ref[drive] > 1) { @@ -1650,7 +1652,6 @@ static struct block_device_operations floppy_fops = { .open = floppy_open, .release = floppy_release, .ioctl = fd_ioctl, - .getgeo = fd_getgeo, .media_changed = amiga_floppy_change, }; diff --git a/trunk/drivers/block/aoe/aoeblk.c b/trunk/drivers/block/aoe/aoeblk.c index c05ee8bffd97..0e97fcb9f3a1 100644 --- a/trunk/drivers/block/aoe/aoeblk.c +++ b/trunk/drivers/block/aoe/aoeblk.c @@ -169,26 +169,38 @@ aoeblk_make_request(request_queue_t *q, struct bio *bio) return 0; } +/* This ioctl implementation expects userland to have the device node + * permissions set so that only priviledged users can open an aoe + * block device directly. + */ static int -aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo) +aoeblk_ioctl(struct inode *inode, struct file *filp, uint cmd, ulong arg) { - struct aoedev *d = bdev->bd_disk->private_data; + struct aoedev *d; + + if (!arg) + return -EINVAL; + d = inode->i_bdev->bd_disk->private_data; if ((d->flags & DEVFL_UP) == 0) { printk(KERN_ERR "aoe: aoeblk_ioctl: disk not up\n"); return -ENODEV; } - geo->cylinders = d->geo.cylinders; - geo->heads = d->geo.heads; - geo->sectors = d->geo.sectors; - return 0; + if (cmd == HDIO_GETGEO) { + d->geo.start = get_start_sect(inode->i_bdev); + if (!copy_to_user((void __user *) arg, &d->geo, sizeof d->geo)) + return 0; + return -EFAULT; + } + printk(KERN_INFO "aoe: aoeblk_ioctl: unknown ioctl %d\n", cmd); + return -EINVAL; } static struct block_device_operations aoe_bdops = { .open = aoeblk_open, .release = aoeblk_release, - .getgeo = aoeblk_getgeo, + .ioctl = aoeblk_ioctl, .owner = THIS_MODULE, }; diff --git a/trunk/drivers/block/ataflop.c b/trunk/drivers/block/ataflop.c index 3aa68a5447d6..22bda05fc693 100644 --- a/trunk/drivers/block/ataflop.c +++ b/trunk/drivers/block/ataflop.c @@ -181,7 +181,7 @@ static struct { { 6, TYPE_HD }, /* 31: H1640 <- was H1600 == h1600 for PC */ }; -#define NUM_DISK_MINORS ARRAY_SIZE(minor2disktype) +#define NUM_DISK_MINORS (sizeof(minor2disktype)/sizeof(*minor2disktype)) /* * Maximum disk size (in kilobytes). This default is used whenever the diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index e4e9f255bd1f..d2815b7a9150 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -1,6 +1,6 @@ /* * Disk Array driver for HP SA 5xxx and 6xxx Controllers - * Copyright 2000, 2006 Hewlett-Packard Development Company, L.P. + * Copyright 2000, 2005 Hewlett-Packard Development Company, L.P. * * 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 @@ -47,12 +47,12 @@ #include #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) -#define DRIVER_NAME "HP CISS Driver (v 2.6.10)" -#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,10) +#define DRIVER_NAME "HP CISS Driver (v 2.6.8)" +#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,6,8) /* Embedded module documentation macros - see modules.h */ MODULE_AUTHOR("Hewlett-Packard Company"); -MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.10"); +MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 2.6.8"); MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" " SA6i P600 P800 P400 P400i E200 E200i"); MODULE_LICENSE("GPL"); @@ -103,7 +103,7 @@ static const struct pci_device_id cciss_pci_device_id[] = { }; MODULE_DEVICE_TABLE(pci, cciss_pci_device_id); -#define NR_PRODUCTS ARRAY_SIZE(products) +#define NR_PRODUCTS (sizeof(products)/sizeof(struct board_type)) /* board_id = Subsystem Device ID & Vendor ID * product = Marketing Name for the board @@ -153,7 +153,6 @@ static int cciss_open(struct inode *inode, struct file *filep); static int cciss_release(struct inode *inode, struct file *filep); static int cciss_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg); -static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); static int revalidate_allvol(ctlr_info_t *host); static int cciss_revalidate(struct gendisk *disk); @@ -167,7 +166,7 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, unsigned int block_size, InquiryData_struct *inq_buff, drive_info_struct *drv); static void cciss_getgeometry(int cntl_num); -static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, __u32); + static void start_io( ctlr_info_t *h); static int sendcmd( __u8 cmd, int ctlr, void *buff, size_t size, unsigned int use_unit_num, unsigned int log_unit, __u8 page_code, @@ -195,7 +194,6 @@ static struct block_device_operations cciss_fops = { .open = cciss_open, .release = cciss_release, .ioctl = cciss_ioctl, - .getgeo = cciss_getgeo, #ifdef CONFIG_COMPAT .compat_ioctl = cciss_compat_ioctl, #endif @@ -284,7 +282,7 @@ static int cciss_proc_get_info(char *buffer, char **start, off_t offset, h->product_name, (unsigned long)h->board_id, h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], h->firm_ver[3], - (unsigned int)h->intr[SIMPLE_MODE_INT], + (unsigned int)h->intr, h->num_luns, h->Qdepth, h->commands_outstanding, h->maxQsinceinit, h->max_outstanding, h->maxSG); @@ -635,20 +633,6 @@ static int cciss_ioctl32_big_passthru(struct file *file, unsigned cmd, unsigned return err; } #endif - -static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - drive_info_struct *drv = get_drv(bdev->bd_disk); - - if (!drv->cylinders) - return -ENXIO; - - geo->heads = drv->heads; - geo->sectors = drv->sectors; - geo->cylinders = drv->cylinders; - return 0; -} - /* * ioctl */ @@ -667,6 +651,21 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, #endif /* CCISS_DEBUG */ switch(cmd) { + case HDIO_GETGEO: + { + struct hd_geometry driver_geo; + if (drv->cylinders) { + driver_geo.heads = drv->heads; + driver_geo.sectors = drv->sectors; + driver_geo.cylinders = drv->cylinders; + } else + return -ENXIO; + driver_geo.start= get_start_sect(inode->i_bdev); + if (copy_to_user(argp, &driver_geo, sizeof(struct hd_geometry))) + return -EFAULT; + return(0); + } + case CCISS_GETPCIINFO: { cciss_pci_info_struct pciinfo; @@ -2178,48 +2177,16 @@ static inline void resend_cciss_cmd( ctlr_info_t *h, CommandList_struct *c) start_io(h); } - -static void cciss_softirq_done(struct request *rq) -{ - CommandList_struct *cmd = rq->completion_data; - ctlr_info_t *h = hba[cmd->ctlr]; - u64bit temp64; - int i, ddir; - - if (cmd->Request.Type.Direction == XFER_READ) - ddir = PCI_DMA_FROMDEVICE; - else - ddir = PCI_DMA_TODEVICE; - - /* command did not need to be retried */ - /* unmap the DMA mapping for all the scatter gather elements */ - for(i=0; iHeader.SGList; i++) { - temp64.val32.lower = cmd->SG[i].Addr.lower; - temp64.val32.upper = cmd->SG[i].Addr.upper; - pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); - } - - complete_buffers(rq->bio, rq->errors); - -#ifdef CCISS_DEBUG - printk("Done with %p\n", rq); -#endif /* CCISS_DEBUG */ - - spin_lock_irq(&h->lock); - end_that_request_last(rq, rq->errors); - cmd_free(h, cmd,1); - spin_unlock_irq(&h->lock); -} - /* checks the status of the job and calls complete buffers to mark all - * buffers for the completed job. Note that this function does not need - * to hold the hba/queue lock. + * buffers for the completed job. */ static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd, int timeout) { int status = 1; + int i; int retry_cmd = 0; + u64bit temp64; if (timeout) status = 0; @@ -2327,10 +2294,24 @@ static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd, resend_cciss_cmd(h,cmd); return; } + /* command did not need to be retried */ + /* unmap the DMA mapping for all the scatter gather elements */ + for(i=0; iHeader.SGList; i++) { + temp64.val32.lower = cmd->SG[i].Addr.lower; + temp64.val32.upper = cmd->SG[i].Addr.upper; + pci_unmap_page(hba[cmd->ctlr]->pdev, + temp64.val, cmd->SG[i].Len, + (cmd->Request.Type.Direction == XFER_READ) ? + PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); + } + complete_buffers(cmd->rq->bio, status); - cmd->rq->completion_data = cmd; - cmd->rq->errors = status; - blk_complete_request(cmd->rq); +#ifdef CCISS_DEBUG + printk("Done with %p\n", cmd->rq); +#endif /* CCISS_DEBUG */ + + end_that_request_last(cmd->rq, status ? 1 : -EIO); + cmd_free(h,cmd,1); } /* @@ -2680,60 +2661,6 @@ static int find_PCI_BAR_index(struct pci_dev *pdev, return -1; } -/* If MSI/MSI-X is supported by the kernel we will try to enable it on - * controllers that are capable. If not, we use IO-APIC mode. - */ - -static void __devinit cciss_interrupt_mode(ctlr_info_t *c, struct pci_dev *pdev, __u32 board_id) -{ -#ifdef CONFIG_PCI_MSI - int err; - struct msix_entry cciss_msix_entries[4] = {{0,0}, {0,1}, - {0,2}, {0,3}}; - - /* Some boards advertise MSI but don't really support it */ - if ((board_id == 0x40700E11) || - (board_id == 0x40800E11) || - (board_id == 0x40820E11) || - (board_id == 0x40830E11)) - goto default_int_mode; - - if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { - err = pci_enable_msix(pdev, cciss_msix_entries, 4); - if (!err) { - c->intr[0] = cciss_msix_entries[0].vector; - c->intr[1] = cciss_msix_entries[1].vector; - c->intr[2] = cciss_msix_entries[2].vector; - c->intr[3] = cciss_msix_entries[3].vector; - c->msix_vector = 1; - return; - } - if (err > 0) { - printk(KERN_WARNING "cciss: only %d MSI-X vectors " - "available\n", err); - } else { - printk(KERN_WARNING "cciss: MSI-X init failed %d\n", - err); - } - } - if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) { - if (!pci_enable_msi(pdev)) { - c->intr[SIMPLE_MODE_INT] = pdev->irq; - c->msi_vector = 1; - return; - } else { - printk(KERN_WARNING "cciss: MSI init failed\n"); - c->intr[SIMPLE_MODE_INT] = pdev->irq; - return; - } - } -#endif /* CONFIG_PCI_MSI */ - /* if we get here we're going to use the default interrupt mode */ -default_int_mode: - c->intr[SIMPLE_MODE_INT] = pdev->irq; - return; -} - static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) { ushort subsystem_vendor_id, subsystem_device_id, command; @@ -2794,10 +2721,7 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) printk("board_id = %x\n", board_id); #endif /* CCISS_DEBUG */ -/* If the kernel supports MSI/MSI-X we will try to enable that functionality, - * else we use the IO-APIC interrupt assigned to us by system ROM. - */ - cciss_interrupt_mode(c, pdev, board_id); + c->intr = pdev->irq; /* * Memory base addr is first addr , the second points to the config @@ -2851,7 +2775,7 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) c->board_id = board_id; #ifdef CCISS_DEBUG - print_cfg_table(c->cfgtable); + print_cfg_table(c->cfgtable); #endif /* CCISS_DEBUG */ for(i=0; imajor = COMPAQ_CISS_MAJOR + i; + hba[i]->major = MAJOR_NR + i; rc = register_blkdev(hba[i]->major, hba[i]->devname); if(rc == -EBUSY || rc == -EINVAL) { printk(KERN_ERR @@ -3151,11 +3075,11 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, /* make sure the board interrupts are off */ hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF); - if( request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intr, + if( request_irq(hba[i]->intr, do_cciss_intr, SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, hba[i]->devname, hba[i])) { printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", - hba[i]->intr[SIMPLE_MODE_INT], hba[i]->devname); + hba[i]->intr, hba[i]->devname); goto clean2; } hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL); @@ -3217,17 +3141,15 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, drv->queue = q; q->backing_dev_info.ra_pages = READ_AHEAD; - blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); + blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); - /* This is a hardware imposed limit. */ - blk_queue_max_hw_segments(q, MAXSGENTRIES); + /* This is a hardware imposed limit. */ + blk_queue_max_hw_segments(q, MAXSGENTRIES); - /* This is a limit in the driver and could be eliminated. */ - blk_queue_max_phys_segments(q, MAXSGENTRIES); + /* This is a limit in the driver and could be eliminated. */ + blk_queue_max_phys_segments(q, MAXSGENTRIES); - blk_queue_max_sectors(q, 512); - - blk_queue_softirq_done(q, cciss_softirq_done); + blk_queue_max_sectors(q, 512); q->queuedata = hba[i]; sprintf(disk->disk_name, "cciss/c%dd%d", i, j); @@ -3263,7 +3185,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, NR_CMDS * sizeof( ErrorInfo_struct), hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle); - free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); + free_irq(hba[i]->intr, hba[i]); clean2: unregister_blkdev(hba[i]->major, hba[i]->devname); clean1: @@ -3304,15 +3226,7 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev) printk(KERN_WARNING "Error Flushing cache on controller %d\n", i); } - free_irq(hba[i]->intr[2], hba[i]); - -#ifdef CONFIG_PCI_MSI - if (hba[i]->msix_vector) - pci_disable_msix(hba[i]->pdev); - else if (hba[i]->msi_vector) - pci_disable_msi(hba[i]->pdev); -#endif /* CONFIG_PCI_MSI */ - + free_irq(hba[i]->intr, hba[i]); pci_set_drvdata(pdev, NULL); iounmap(hba[i]->vaddr); cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ diff --git a/trunk/drivers/block/cciss.h b/trunk/drivers/block/cciss.h index b24fc0553ccf..3b0858c83897 100644 --- a/trunk/drivers/block/cciss.h +++ b/trunk/drivers/block/cciss.h @@ -13,6 +13,8 @@ #define IO_OK 0 #define IO_ERROR 1 +#define MAJOR_NR COMPAQ_CISS_MAJOR + struct ctlr_info; typedef struct ctlr_info ctlr_info_t; @@ -63,6 +65,7 @@ struct ctlr_info unsigned long io_mem_addr; unsigned long io_mem_length; CfgTable_struct __iomem *cfgtable; + unsigned int intr; int interrupts_enabled; int major; int max_commands; @@ -71,13 +74,6 @@ struct ctlr_info int num_luns; int highest_lun; int usage_count; /* number of opens all all minor devices */ -# define DOORBELL_INT 0 -# define PERF_MODE_INT 1 -# define SIMPLE_MODE_INT 2 -# define MEMQ_MODE_INT 3 - unsigned int intr[4]; - unsigned int msix_vector; - unsigned int msi_vector; // information about each logical volume drive_info_struct drv[CISS_MAX_LUN]; diff --git a/trunk/drivers/block/cciss_scsi.c b/trunk/drivers/block/cciss_scsi.c index 9e35de05d5c5..2942d32280a5 100644 --- a/trunk/drivers/block/cciss_scsi.c +++ b/trunk/drivers/block/cciss_scsi.c @@ -714,7 +714,7 @@ cciss_scsi_detect(int ctlr) ((struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr)->scsi_host = (void *) sh; sh->hostdata[0] = (unsigned long) hba[ctlr]; - sh->irq = hba[ctlr]->intr[SIMPLE_MODE_INT]; + sh->irq = hba[ctlr]->intr; sh->unique_id = sh->irq; error = scsi_add_host(sh, &hba[ctlr]->pdev->dev); if (error) diff --git a/trunk/drivers/block/cpqarray.c b/trunk/drivers/block/cpqarray.c index 862b9abac0ae..9bddb6874873 100644 --- a/trunk/drivers/block/cpqarray.c +++ b/trunk/drivers/block/cpqarray.c @@ -72,11 +72,11 @@ static ctlr_info_t *hba[MAX_CTLR]; static int eisa[8]; -#define NR_PRODUCTS ARRAY_SIZE(products) +#define NR_PRODUCTS (sizeof(products)/sizeof(struct board_type)) /* board_id = Subsystem Device ID & Vendor ID * product = Marketing Name for the board - * access = Address of the struct of function pointers + * access = Address of the struct of function pointers */ static struct board_type products[] = { { 0x0040110E, "IDA", &smart1_access }, @@ -160,7 +160,6 @@ static int sendcmd( static int ida_open(struct inode *inode, struct file *filep); static int ida_release(struct inode *inode, struct file *filep); static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg); -static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo); static int ida_ctlr_ioctl(ctlr_info_t *h, int dsk, ida_ioctl_t *io); static void do_ida_request(request_queue_t *q); @@ -200,7 +199,6 @@ static struct block_device_operations ida_fops = { .open = ida_open, .release = ida_release, .ioctl = ida_ioctl, - .getgeo = ida_getgeo, .revalidate_disk= ida_revalidate, }; @@ -1126,23 +1124,6 @@ static void ida_timer(unsigned long tdata) h->misc_tflags = 0; } -static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - drv_info_t *drv = get_drv(bdev->bd_disk); - - if (drv->cylinders) { - geo->heads = drv->heads; - geo->sectors = drv->sectors; - geo->cylinders = drv->cylinders; - } else { - geo->heads = 0xff; - geo->sectors = 0x3f; - geo->cylinders = drv->nr_blks / (0xff*0x3f); - } - - return 0; -} - /* * ida_ioctl does some miscellaneous stuff like reporting drive geometry, * setting readahead and submitting commands from userspace to the controller. @@ -1152,10 +1133,27 @@ static int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, drv_info_t *drv = get_drv(inode->i_bdev->bd_disk); ctlr_info_t *host = get_host(inode->i_bdev->bd_disk); int error; + int diskinfo[4]; + struct hd_geometry __user *geo = (struct hd_geometry __user *)arg; ida_ioctl_t __user *io = (ida_ioctl_t __user *)arg; ida_ioctl_t *my_io; switch(cmd) { + case HDIO_GETGEO: + if (drv->cylinders) { + diskinfo[0] = drv->heads; + diskinfo[1] = drv->sectors; + diskinfo[2] = drv->cylinders; + } else { + diskinfo[0] = 0xff; + diskinfo[1] = 0x3f; + diskinfo[2] = drv->nr_blks / (0xff*0x3f); + } + put_user(diskinfo[0], &geo->heads); + put_user(diskinfo[1], &geo->sectors); + put_user(diskinfo[2], &geo->cylinders); + put_user(get_start_sect(inode->i_bdev), &geo->start); + return 0; case IDAGETDRVINFO: if (copy_to_user(&io->c.drv, drv, sizeof(drv_info_t))) return -EFAULT; diff --git a/trunk/drivers/block/floppy.c b/trunk/drivers/block/floppy.c index 374621a512e0..a5b857c5c4b8 100644 --- a/trunk/drivers/block/floppy.c +++ b/trunk/drivers/block/floppy.c @@ -479,6 +479,7 @@ static struct floppy_struct floppy_type[32] = { { 3200,20,2,80,0,0x1C,0x00,0xCF,0x2C,"H1600" }, /* 31 1.6MB 3.5" */ }; +#define NUMBER(x) (sizeof(x) / sizeof(*(x))) #define SECTSIZE (_FD_SECTSIZE(*floppy)) /* Auto-detection: Disk type used until the next media change occurs. */ @@ -3444,23 +3445,6 @@ static int get_floppy_geometry(int drive, int type, struct floppy_struct **g) return 0; } -static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - int drive = (long)bdev->bd_disk->private_data; - int type = ITYPE(drive_state[drive].fd_device); - struct floppy_struct *g; - int ret; - - ret = get_floppy_geometry(drive, type, &g); - if (ret) - return ret; - - geo->heads = g->head; - geo->sectors = g->sect; - geo->cylinders = g->track; - return 0; -} - static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long param) { @@ -3490,6 +3474,23 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, cmd = FDEJECT; } + /* generic block device ioctls */ + switch (cmd) { + /* the following have been inspired by the corresponding + * code for other block devices. */ + struct floppy_struct *g; + case HDIO_GETGEO: + { + struct hd_geometry loc; + ECALL(get_floppy_geometry(drive, type, &g)); + loc.heads = g->head; + loc.sectors = g->sect; + loc.cylinders = g->track; + loc.start = 0; + return _COPYOUT(loc); + } + } + /* convert the old style command into a new style command */ if ((cmd & 0xff00) == 0x0200) { ECALL(normalize_ioctl(&cmd, &size)); @@ -3644,7 +3645,7 @@ static void __init config_types(void) const char *name = NULL; static char temparea[32]; - if (type < ARRAY_SIZE(default_drive_params)) { + if (type < NUMBER(default_drive_params)) { params = &default_drive_params[type].params; if (type) { name = default_drive_params[type].name; @@ -3937,7 +3938,6 @@ static struct block_device_operations floppy_fops = { .open = floppy_open, .release = floppy_release, .ioctl = fd_ioctl, - .getgeo = fd_getgeo, .media_changed = check_floppy_change, .revalidate_disk = floppy_revalidate, }; @@ -3960,7 +3960,7 @@ static void __init register_devfs_entries(int drive) { int base_minor = (drive < 4) ? drive : (124 + drive); - if (UDP->cmos < ARRAY_SIZE(default_drive_params)) { + if (UDP->cmos < NUMBER(default_drive_params)) { int i = 0; do { int minor = base_minor + (table_sup[UDP->cmos][i] << 2); @@ -4218,7 +4218,7 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data) !(allowed_drive_mask & (1 << drive)) || fdc_state[FDC(drive)].version == FDC_NONE) return NULL; - if (((*part >> 2) & 0x1f) >= ARRAY_SIZE(floppy_type)) + if (((*part >> 2) & 0x1f) >= NUMBER(floppy_type)) return NULL; *part = 0; return get_disk(disks[drive]); @@ -4570,7 +4570,7 @@ static void unregister_devfs_entries(int drive) { int i; - if (UDP->cmos < ARRAY_SIZE(default_drive_params)) { + if (UDP->cmos < NUMBER(default_drive_params)) { i = 0; do { devfs_remove("floppy/%d%s", drive, diff --git a/trunk/drivers/block/nbd.c b/trunk/drivers/block/nbd.c index 6997d8e6bfb5..33d6f237b2ed 100644 --- a/trunk/drivers/block/nbd.c +++ b/trunk/drivers/block/nbd.c @@ -174,6 +174,7 @@ static int sock_xmit(struct socket *sock, int send, void *buf, int size, msg.msg_namelen = 0; msg.msg_control = NULL; msg.msg_controllen = 0; + msg.msg_namelen = 0; msg.msg_flags = msg_flags | MSG_NOSIGNAL; if (send) diff --git a/trunk/drivers/block/paride/pd.c b/trunk/drivers/block/paride/pd.c index 62d2464c12f2..fa49d62626ba 100644 --- a/trunk/drivers/block/paride/pd.c +++ b/trunk/drivers/block/paride/pd.c @@ -747,33 +747,32 @@ static int pd_open(struct inode *inode, struct file *file) return 0; } -static int pd_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct pd_unit *disk = bdev->bd_disk->private_data; - - if (disk->alt_geom) { - geo->heads = PD_LOG_HEADS; - geo->sectors = PD_LOG_SECTS; - geo->cylinders = disk->capacity / (geo->heads * geo->sectors); - } else { - geo->heads = disk->heads; - geo->sectors = disk->sectors; - geo->cylinders = disk->cylinders; - } - - return 0; -} - static int pd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct pd_unit *disk = inode->i_bdev->bd_disk->private_data; + struct hd_geometry __user *geo = (struct hd_geometry __user *) arg; + struct hd_geometry g; switch (cmd) { case CDROMEJECT: if (disk->access == 1) pd_special_command(disk, pd_eject); return 0; + case HDIO_GETGEO: + if (disk->alt_geom) { + g.heads = PD_LOG_HEADS; + g.sectors = PD_LOG_SECTS; + g.cylinders = disk->capacity / (g.heads * g.sectors); + } else { + g.heads = disk->heads; + g.sectors = disk->sectors; + g.cylinders = disk->cylinders; + } + g.start = get_start_sect(inode->i_bdev); + if (copy_to_user(geo, &g, sizeof(struct hd_geometry))) + return -EFAULT; + return 0; default: return -EINVAL; } @@ -816,7 +815,6 @@ static struct block_device_operations pd_fops = { .open = pd_open, .release = pd_release, .ioctl = pd_ioctl, - .getgeo = pd_getgeo, .media_changed = pd_check_media, .revalidate_disk= pd_revalidate }; diff --git a/trunk/drivers/block/paride/pf.c b/trunk/drivers/block/paride/pf.c index 852b564e903a..e9746af29b9f 100644 --- a/trunk/drivers/block/paride/pf.c +++ b/trunk/drivers/block/paride/pf.c @@ -205,7 +205,6 @@ static int pf_open(struct inode *inode, struct file *file); static void do_pf_request(request_queue_t * q); static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo); static int pf_release(struct inode *inode, struct file *file); @@ -267,7 +266,6 @@ static struct block_device_operations pf_fops = { .open = pf_open, .release = pf_release, .ioctl = pf_ioctl, - .getgeo = pf_getgeo, .media_changed = pf_check_media, }; @@ -315,34 +313,34 @@ static int pf_open(struct inode *inode, struct file *file) return 0; } -static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct pf_unit *pf = bdev->bd_disk->private_data; - sector_t capacity = get_capacity(pf->disk); - - if (capacity < PF_FD_MAX) { - geo->cylinders = sector_div(capacity, PF_FD_HDS * PF_FD_SPT); - geo->heads = PF_FD_HDS; - geo->sectors = PF_FD_SPT; - } else { - geo->cylinders = sector_div(capacity, PF_HD_HDS * PF_HD_SPT); - geo->heads = PF_HD_HDS; - geo->sectors = PF_HD_SPT; - } - - return 0; -} - static int pf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct pf_unit *pf = inode->i_bdev->bd_disk->private_data; - - if (cmd != CDROMEJECT) - return -EINVAL; - - if (pf->access != 1) + struct hd_geometry __user *geo = (struct hd_geometry __user *) arg; + struct hd_geometry g; + sector_t capacity; + + if (cmd == CDROMEJECT) { + if (pf->access == 1) { + pf_eject(pf); + return 0; + } return -EBUSY; - pf_eject(pf); + } + if (cmd != HDIO_GETGEO) + return -EINVAL; + capacity = get_capacity(pf->disk); + if (capacity < PF_FD_MAX) { + g.cylinders = sector_div(capacity, PF_FD_HDS * PF_FD_SPT); + g.heads = PF_FD_HDS; + g.sectors = PF_FD_SPT; + } else { + g.cylinders = sector_div(capacity, PF_HD_HDS * PF_HD_SPT); + g.heads = PF_HD_HDS; + g.sectors = PF_HD_SPT; + } + if (copy_to_user(geo, &g, sizeof(g))) + return -EFAULT; return 0; } diff --git a/trunk/drivers/block/pktcdvd.c b/trunk/drivers/block/pktcdvd.c index 51b7a5c5b77a..c0233efabeba 100644 --- a/trunk/drivers/block/pktcdvd.c +++ b/trunk/drivers/block/pktcdvd.c @@ -1955,12 +1955,9 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write) if ((ret = blkdev_get(pd->bdev, FMODE_READ, O_RDONLY))) goto out; - if ((ret = bd_claim(pd->bdev, pd))) - goto out_putdev; - if ((ret = pkt_get_last_written(pd, &lba))) { printk("pktcdvd: pkt_get_last_written failed\n"); - goto out_unclaim; + goto out_putdev; } set_capacity(pd->disk, lba << 2); @@ -1970,7 +1967,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write) q = bdev_get_queue(pd->bdev); if (write) { if ((ret = pkt_open_write(pd))) - goto out_unclaim; + goto out_putdev; /* * Some CDRW drives can not handle writes larger than one packet, * even if the size is a multiple of the packet size. @@ -1985,15 +1982,13 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write) } if ((ret = pkt_set_segment_merging(pd, q))) - goto out_unclaim; + goto out_putdev; if (write) printk("pktcdvd: %lukB available on disc\n", lba << 1); return 0; -out_unclaim: - bd_release(pd->bdev); out_putdev: blkdev_put(pd->bdev); out: @@ -2012,7 +2007,6 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush) pkt_lock_door(pd, 0); pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); - bd_release(pd->bdev); blkdev_put(pd->bdev); } diff --git a/trunk/drivers/block/ps2esdi.c b/trunk/drivers/block/ps2esdi.c index 43415f69839f..29d1518be72a 100644 --- a/trunk/drivers/block/ps2esdi.c +++ b/trunk/drivers/block/ps2esdi.c @@ -81,7 +81,8 @@ static void (*current_int_handler) (u_int) = NULL; static void ps2esdi_normal_interrupt_handler(u_int); static void ps2esdi_initial_reset_int_handler(u_int); static void ps2esdi_geometry_int_handler(u_int); -static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo); +static int ps2esdi_ioctl(struct inode *inode, struct file *file, + u_int cmd, u_long arg); static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer); @@ -131,7 +132,7 @@ static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] = static struct block_device_operations ps2esdi_fops = { .owner = THIS_MODULE, - .getgeo = ps2esdi_getgeo, + .ioctl = ps2esdi_ioctl, }; static struct gendisk *ps2esdi_gendisk[2]; @@ -1057,13 +1058,21 @@ static void dump_cmd_complete_status(u_int int_ret_code) } -static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo) +static int ps2esdi_ioctl(struct inode *inode, + struct file *file, u_int cmd, u_long arg) { - struct ps2esdi_i_struct *p = bdev->bd_disk->private_data; - - geo->heads = p->head; - geo->sectors = p->sect; - geo->cylinders = p->cyl; + struct ps2esdi_i_struct *p = inode->i_bdev->bd_disk->private_data; + struct ps2esdi_geometry geom; + + if (cmd != HDIO_GETGEO) + return -EINVAL; + memset(&geom, 0, sizeof(geom)); + geom.heads = p->head; + geom.sectors = p->sect; + geom.cylinders = p->cyl; + geom.start = get_start_sect(inode->i_bdev); + if (copy_to_user((void __user *)arg, &geom, sizeof(geom))) + return -EFAULT; return 0; } diff --git a/trunk/drivers/block/swim3.c b/trunk/drivers/block/swim3.c index 01f042f6f1c4..af7cb2bfd670 100644 --- a/trunk/drivers/block/swim3.c +++ b/trunk/drivers/block/swim3.c @@ -1083,33 +1083,23 @@ static int swim3_add_device(struct device_node *swim) { struct device_node *mediabay; struct floppy_state *fs = &floppy_states[floppy_count]; - struct resource res_reg, res_dma; - if (of_address_to_resource(swim, 0, &res_reg) || - of_address_to_resource(swim, 1, &res_dma)) { - printk(KERN_ERR "swim3: Can't get addresses\n"); - return -EINVAL; - } - if (request_mem_region(res_reg.start, res_reg.end - res_reg.start + 1, - " (reg)") == NULL) { - printk(KERN_ERR "swim3: Can't request register space\n"); + if (swim->n_addrs < 2) + { + printk(KERN_INFO "swim3: expecting 2 addrs (n_addrs:%d, n_intrs:%d)\n", + swim->n_addrs, swim->n_intrs); return -EINVAL; } - if (request_mem_region(res_dma.start, res_dma.end - res_dma.start + 1, - " (dma)") == NULL) { - release_mem_region(res_reg.start, - res_reg.end - res_reg.start + 1); - printk(KERN_ERR "swim3: Can't request DMA space\n"); + + if (swim->n_intrs < 2) + { + printk(KERN_INFO "swim3: expecting 2 intrs (n_addrs:%d, n_intrs:%d)\n", + swim->n_addrs, swim->n_intrs); return -EINVAL; } - if (swim->n_intrs < 2) { - printk(KERN_INFO "swim3: expecting 2 intrs (n_intrs:%d)\n", - swim->n_intrs); - release_mem_region(res_reg.start, - res_reg.end - res_reg.start + 1); - release_mem_region(res_dma.start, - res_dma.end - res_dma.start + 1); + if (!request_OF_resource(swim, 0, NULL)) { + printk(KERN_INFO "swim3: can't request IO resource !\n"); return -EINVAL; } @@ -1120,8 +1110,10 @@ static int swim3_add_device(struct device_node *swim) memset(fs, 0, sizeof(*fs)); spin_lock_init(&fs->lock); fs->state = idle; - fs->swim3 = (struct swim3 __iomem *)ioremap(res_reg.start, 0x200); - fs->dma = (struct dbdma_regs __iomem *)ioremap(res_dma.start, 0x200); + fs->swim3 = (struct swim3 __iomem *) + ioremap(swim->addrs[0].address, 0x200); + fs->dma = (struct dbdma_regs __iomem *) + ioremap(swim->addrs[1].address, 0x200); fs->swim3_intr = swim->intrs[0].line; fs->dma_intr = swim->intrs[1].line; fs->cur_cyl = -1; diff --git a/trunk/drivers/block/sx8.c b/trunk/drivers/block/sx8.c index c0cdc182a8b0..9251f4131b53 100644 --- a/trunk/drivers/block/sx8.c +++ b/trunk/drivers/block/sx8.c @@ -407,7 +407,8 @@ struct carm_array_info { static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static void carm_remove_one (struct pci_dev *pdev); -static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo); +static int carm_bdev_ioctl(struct inode *ino, struct file *fil, + unsigned int cmd, unsigned long arg); static struct pci_device_id carm_pci_tbl[] = { { PCI_VENDOR_ID_PROMISE, 0x8000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, @@ -425,7 +426,7 @@ static struct pci_driver carm_driver = { static struct block_device_operations carm_bd_ops = { .owner = THIS_MODULE, - .getgeo = carm_bdev_getgeo, + .ioctl = carm_bdev_ioctl, }; static unsigned int carm_host_id; @@ -433,14 +434,32 @@ static unsigned long carm_major_alloc; -static int carm_bdev_getgeo(struct block_device *bdev, struct hd_geometry *geo) +static int carm_bdev_ioctl(struct inode *ino, struct file *fil, + unsigned int cmd, unsigned long arg) { - struct carm_port *port = bdev->bd_disk->private_data; + void __user *usermem = (void __user *) arg; + struct carm_port *port = ino->i_bdev->bd_disk->private_data; + struct hd_geometry geom; - geo->heads = (u8) port->dev_geom_head; - geo->sectors = (u8) port->dev_geom_sect; - geo->cylinders = port->dev_geom_cyl; - return 0; + switch (cmd) { + case HDIO_GETGEO: + if (!usermem) + return -EINVAL; + + geom.heads = (u8) port->dev_geom_head; + geom.sectors = (u8) port->dev_geom_sect; + geom.cylinders = port->dev_geom_cyl; + geom.start = get_start_sect(ino->i_bdev); + + if (copy_to_user(usermem, &geom, sizeof(geom))) + return -EFAULT; + return 0; + + default: + break; + } + + return -EOPNOTSUPP; } static const u32 msg_sizes[] = { 32, 64, 128, CARM_MSG_SIZE }; diff --git a/trunk/drivers/block/umem.c b/trunk/drivers/block/umem.c index 15299e7a1ade..0f48301342da 100644 --- a/trunk/drivers/block/umem.c +++ b/trunk/drivers/block/umem.c @@ -809,23 +809,34 @@ static int mm_revalidate(struct gendisk *disk) set_capacity(disk, card->mm_size << 1); return 0; } - -static int mm_getgeo(struct block_device *bdev, struct hd_geometry *geo) +/* +----------------------------------------------------------------------------------- +-- mm_ioctl +----------------------------------------------------------------------------------- +*/ +static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg) { - struct cardinfo *card = bdev->bd_disk->private_data; - int size = card->mm_size * (1024 / MM_HARDSECT); + if (cmd == HDIO_GETGEO) { + struct cardinfo *card = i->i_bdev->bd_disk->private_data; + int size = card->mm_size * (1024 / MM_HARDSECT); + struct hd_geometry geo; + /* + * get geometry: we have to fake one... trim the size to a + * multiple of 2048 (1M): tell we have 32 sectors, 64 heads, + * whatever cylinders. + */ + geo.heads = 64; + geo.sectors = 32; + geo.start = get_start_sect(i->i_bdev); + geo.cylinders = size / (geo.heads * geo.sectors); + + if (copy_to_user((void __user *) arg, &geo, sizeof(geo))) + return -EFAULT; + return 0; + } - /* - * get geometry: we have to fake one... trim the size to a - * multiple of 2048 (1M): tell we have 32 sectors, 64 heads, - * whatever cylinders. - */ - geo->heads = 64; - geo->sectors = 32; - geo->cylinders = size / (geo->heads * geo->sectors); - return 0; + return -EINVAL; } - /* ----------------------------------------------------------------------------------- -- mm_check_change @@ -844,7 +855,7 @@ static int mm_check_change(struct gendisk *disk) */ static struct block_device_operations mm_fops = { .owner = THIS_MODULE, - .getgeo = mm_getgeo, + .ioctl = mm_ioctl, .revalidate_disk= mm_revalidate, .media_changed = mm_check_change, }; diff --git a/trunk/drivers/block/viodasd.c b/trunk/drivers/block/viodasd.c index d1aaf31bd97e..063f0304a163 100644 --- a/trunk/drivers/block/viodasd.c +++ b/trunk/drivers/block/viodasd.c @@ -247,17 +247,43 @@ static int viodasd_release(struct inode *ino, struct file *fil) /* External ioctl entry point. */ -static int viodasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) +static int viodasd_ioctl(struct inode *ino, struct file *fil, + unsigned int cmd, unsigned long arg) { - struct gendisk *disk = bdev->bd_disk; - struct viodasd_device *d = disk->private_data; + unsigned char sectors; + unsigned char heads; + unsigned short cylinders; + struct hd_geometry *geo; + struct gendisk *gendisk; + struct viodasd_device *d; - geo->sectors = d->sectors ? d->sectors : 0; - geo->heads = d->tracks ? d->tracks : 64; - geo->cylinders = d->cylinders ? d->cylinders : - get_capacity(disk) / (geo->cylinders * geo->heads); + switch (cmd) { + case HDIO_GETGEO: + geo = (struct hd_geometry *)arg; + if (geo == NULL) + return -EINVAL; + if (!access_ok(VERIFY_WRITE, geo, sizeof(*geo))) + return -EFAULT; + gendisk = ino->i_bdev->bd_disk; + d = gendisk->private_data; + sectors = d->sectors; + if (sectors == 0) + sectors = 32; + heads = d->tracks; + if (heads == 0) + heads = 64; + cylinders = d->cylinders; + if (cylinders == 0) + cylinders = get_capacity(gendisk) / (sectors * heads); + if (__put_user(sectors, &geo->sectors) || + __put_user(heads, &geo->heads) || + __put_user(cylinders, &geo->cylinders) || + __put_user(get_start_sect(ino->i_bdev), &geo->start)) + return -EFAULT; + return 0; + } - return 0; + return -EINVAL; } /* @@ -267,7 +293,7 @@ static struct block_device_operations viodasd_fops = { .owner = THIS_MODULE, .open = viodasd_open, .release = viodasd_release, - .getgeo = viodasd_getgeo, + .ioctl = viodasd_ioctl, }; /* diff --git a/trunk/drivers/block/xd.c b/trunk/drivers/block/xd.c index cbce7c5e9445..68b6d7b154cf 100644 --- a/trunk/drivers/block/xd.c +++ b/trunk/drivers/block/xd.c @@ -128,12 +128,9 @@ static DEFINE_SPINLOCK(xd_lock); static struct gendisk *xd_gendisk[2]; -static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo); - static struct block_device_operations xd_fops = { .owner = THIS_MODULE, .ioctl = xd_ioctl, - .getgeo = xd_getgeo, }; static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int); static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors; @@ -279,11 +276,11 @@ static u_char __init xd_detect (u_char *controller, unsigned int *address) return(1); } - for (i = 0; i < ARRAY_SIZE(xd_bases); i++) { + for (i = 0; i < (sizeof(xd_bases) / sizeof(xd_bases[0])); i++) { void __iomem *p = ioremap(xd_bases[i], 0x2000); if (!p) continue; - for (j = 1; j < ARRAY_SIZE(xd_sigs); j++) { + for (j = 1; j < (sizeof(xd_sigs) / sizeof(xd_sigs[0])); j++) { const char *s = xd_sigs[j].string; if (check_signature(p + xd_sigs[j].offset, s, strlen(s))) { *controller = j; @@ -333,20 +330,22 @@ static void do_xd_request (request_queue_t * q) } } -static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - XD_INFO *p = bdev->bd_disk->private_data; - - geo->heads = p->heads; - geo->sectors = p->sectors; - geo->cylinders = p->cylinders; - return 0; -} - /* xd_ioctl: handle device ioctl's */ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) { + XD_INFO *p = inode->i_bdev->bd_disk->private_data; + switch (cmd) { + case HDIO_GETGEO: + { + struct hd_geometry g; + struct hd_geometry __user *geom= (void __user *)arg; + g.heads = p->heads; + g.sectors = p->sectors; + g.cylinders = p->cylinders; + g.start = get_start_sect(inode->i_bdev); + return copy_to_user(geom, &g, sizeof(g)) ? -EFAULT : 0; + } case HDIO_SET_DMA: if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (xdc_busy) return -EBUSY; @@ -1018,7 +1017,7 @@ static void __init do_xd_setup (int *integers) case 2: if ((integers[2] > 0) && (integers[2] < 16)) xd_irq = integers[2]; case 1: xd_override = 1; - if ((integers[1] >= 0) && (integers[1] < ARRAY_SIZE(xd_sigs))) + if ((integers[1] >= 0) && (integers[1] < (sizeof(xd_sigs) / sizeof(xd_sigs[0])))) xd_type = integers[1]; case 0: break; default:printk("xd: too many parameters for xd\n"); diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index dd7e6901c575..5ebd06b1b4ca 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -220,14 +220,6 @@ config SYNCLINKMP The module will be called synclinkmp. If you want to do that, say M here. -config SYNCLINK_GT - tristate "SyncLink GT/AC support" - depends on SERIAL_NONSTANDARD - help - Support for SyncLink GT and SyncLink AC families of - synchronous and asynchronous serial adapters - manufactured by Microgate Systems, Ltd. (www.microgate.com) - config N_HDLC tristate "HDLC line discipline support" depends on SERIAL_NONSTANDARD @@ -695,7 +687,7 @@ config NVRAM config RTC tristate "Enhanced Real Time Clock Support" - depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) && !FRV + depends on !PPC32 && !PARISC && !IA64 && !M68K && (!SPARC || PCI) ---help--- If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you @@ -743,7 +735,7 @@ config SGI_IP27_RTC config GEN_RTC tristate "Generic /dev/rtc emulation" - depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC && !FRV + depends on RTC!=y && !IA64 && !ARM && !M32R && !SPARC ---help--- If you say Y here and create a character special file /dev/rtc with major number 10 and minor number 135 using mknod ("man mknod"), you diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index d973d14d8f7f..4aeae687e88a 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -36,7 +36,6 @@ obj-$(CONFIG_RISCOM8) += riscom8.o obj-$(CONFIG_ISI) += isicom.o obj-$(CONFIG_SYNCLINK) += synclink.o obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o -obj-$(CONFIG_SYNCLINK_GT) += synclink_gt.o obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o obj-$(CONFIG_SX) += sx.o generic_serial.o diff --git a/trunk/drivers/char/agp/sworks-agp.c b/trunk/drivers/char/agp/sworks-agp.c index 268f78d926d3..3f8f7fa6b0ff 100644 --- a/trunk/drivers/char/agp/sworks-agp.c +++ b/trunk/drivers/char/agp/sworks-agp.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include "agp.h" diff --git a/trunk/drivers/char/hw_random.c b/trunk/drivers/char/hw_random.c index b3bc2e37e616..49769f59ea1b 100644 --- a/trunk/drivers/char/hw_random.c +++ b/trunk/drivers/char/hw_random.c @@ -169,7 +169,6 @@ static struct pci_device_id rng_pci_tbl[] = { { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, - { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, rng_hw_intel }, diff --git a/trunk/drivers/char/mem.c b/trunk/drivers/char/mem.c index 5b2d18035073..91dd669273e0 100644 --- a/trunk/drivers/char/mem.c +++ b/trunk/drivers/char/mem.c @@ -101,11 +101,6 @@ static inline int valid_phys_addr_range(unsigned long addr, size_t *count) return 1; } - -static inline int valid_mmap_phys_addr_range(unsigned long addr, size_t *size) -{ - return 1; -} #endif /* @@ -233,36 +228,26 @@ static ssize_t write_mem(struct file * file, const char __user * buf, return written; } -#ifndef __HAVE_PHYS_MEM_ACCESS_PROT -static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, - unsigned long size, pgprot_t vma_prot) -{ -#ifdef pgprot_noncached - unsigned long offset = pfn << PAGE_SHIFT; - - if (uncached_access(file, offset)) - return pgprot_noncached(vma_prot); -#endif - return vma_prot; -} -#endif - static int mmap_mem(struct file * file, struct vm_area_struct * vma) { - size_t size = vma->vm_end - vma->vm_start; - - if (!valid_mmap_phys_addr_range(vma->vm_pgoff << PAGE_SHIFT, &size)) - return -EINVAL; - +#if defined(__HAVE_PHYS_MEM_ACCESS_PROT) vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, - size, + vma->vm_end - vma->vm_start, vma->vm_page_prot); +#elif defined(pgprot_noncached) + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + int uncached; + + uncached = uncached_access(file, offset); + if (uncached) + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); +#endif /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, - size, + vma->vm_end-vma->vm_start, vma->vm_page_prot)) return -EAGAIN; return 0; @@ -832,7 +817,7 @@ static ssize_t kmsg_write(struct file * file, const char __user * buf, size_t count, loff_t *ppos) { char *tmp; - ssize_t ret; + int ret; tmp = kmalloc(count + 1, GFP_KERNEL); if (tmp == NULL) @@ -841,9 +826,6 @@ static ssize_t kmsg_write(struct file * file, const char __user * buf, if (!copy_from_user(tmp, buf, count)) { tmp[count] = 0; ret = printk("%s", tmp); - if (ret > count) - /* printk can add a prefix */ - ret = count; } kfree(tmp); return ret; diff --git a/trunk/drivers/char/sonypi.c b/trunk/drivers/char/sonypi.c index f8dd8527c6aa..51a07370e636 100644 --- a/trunk/drivers/char/sonypi.c +++ b/trunk/drivers/char/sonypi.c @@ -471,6 +471,7 @@ struct sonypi_keypress { static struct sonypi_device { struct pci_dev *dev; + struct platform_device *pdev; u16 irq; u16 bits; u16 ioport1; @@ -510,11 +511,6 @@ static struct sonypi_device { #define SONYPI_ACPI_ACTIVE 0 #endif /* CONFIG_ACPI */ -#ifdef CONFIG_ACPI -static struct acpi_device *sonypi_acpi_device; -static int acpi_enabled; -#endif - static int sonypi_ec_write(u8 addr, u8 value) { #ifdef CONFIG_ACPI_EC @@ -868,11 +864,6 @@ static irqreturn_t sonypi_irq(int irq, void *dev_id, struct pt_regs *regs) if (useinput) sonypi_report_input_event(event); -#ifdef CONFIG_ACPI - if (acpi_enabled) - acpi_bus_generate_event(sonypi_acpi_device, 1, event); -#endif - kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); kill_fasync(&sonypi_device.fifo_async, SIGIO, POLL_IN); wake_up_interruptible(&sonypi_device.fifo_proc_list); @@ -1174,38 +1165,45 @@ static int sonypi_disable(void) return 0; } -#ifdef CONFIG_ACPI -static int sonypi_acpi_add(struct acpi_device *device) +#ifdef CONFIG_PM +static int old_camera_power; + +static int sonypi_suspend(struct platform_device *dev, pm_message_t state) { - sonypi_acpi_device = device; - strcpy(acpi_device_name(device), "Sony laptop hotkeys"); - strcpy(acpi_device_class(device), "sony/hotkey"); + old_camera_power = sonypi_device.camera_power; + sonypi_disable(); + return 0; } -static int sonypi_acpi_remove(struct acpi_device *device, int type) +static int sonypi_resume(struct platform_device *dev) { - sonypi_acpi_device = NULL; + sonypi_enable(old_camera_power); return 0; } +#endif + +static void sonypi_shutdown(struct platform_device *dev) +{ + sonypi_disable(); +} -static struct acpi_driver sonypi_acpi_driver = { - .name = "sonypi", - .class = "hkey", - .ids = "SNY6001", - .ops = { - .add = sonypi_acpi_add, - .remove = sonypi_acpi_remove, +static struct platform_driver sonypi_driver = { +#ifdef CONFIG_PM + .suspend = sonypi_suspend, + .resume = sonypi_resume, +#endif + .shutdown = sonypi_shutdown, + .driver = { + .name = "sonypi", }, }; -#endif static int __devinit sonypi_create_input_devices(void) { struct input_dev *jog_dev; struct input_dev *key_dev; int i; - int error; sonypi_device.input_jog_dev = jog_dev = input_allocate_device(); if (!jog_dev) @@ -1221,8 +1219,9 @@ static int __devinit sonypi_create_input_devices(void) sonypi_device.input_key_dev = key_dev = input_allocate_device(); if (!key_dev) { - error = -ENOMEM; - goto err_free_jogdev; + input_free_device(jog_dev); + sonypi_device.input_jog_dev = NULL; + return -ENOMEM; } key_dev->name = "Sony Vaio Keys"; @@ -1235,122 +1234,56 @@ static int __devinit sonypi_create_input_devices(void) if (sonypi_inputkeys[i].inputev) set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit); - error = input_register_device(jog_dev); - if (error) - goto err_free_keydev; - - error = input_register_device(key_dev); - if (error) - goto err_unregister_jogdev; + input_register_device(jog_dev); + input_register_device(key_dev); return 0; - - err_unregister_jogdev: - input_unregister_device(jog_dev); - /* Set to NULL so we don't free it again below */ - jog_dev = NULL; - err_free_keydev: - input_free_device(key_dev); - sonypi_device.input_key_dev = NULL; - err_free_jogdev: - input_free_device(jog_dev); - sonypi_device.input_jog_dev = NULL; - - return error; -} - -static int __devinit sonypi_setup_ioports(struct sonypi_device *dev, - const struct sonypi_ioport_list *ioport_list) -{ - while (ioport_list->port1) { - - if (request_region(ioport_list->port1, - sonypi_device.region_size, - "Sony Programable I/O Device")) { - dev->ioport1 = ioport_list->port1; - dev->ioport2 = ioport_list->port2; - return 0; - } - ioport_list++; - } - - return -EBUSY; -} - -static int __devinit sonypi_setup_irq(struct sonypi_device *dev, - const struct sonypi_irq_list *irq_list) -{ - while (irq_list->irq) { - - if (!request_irq(irq_list->irq, sonypi_irq, - SA_SHIRQ, "sonypi", sonypi_irq)) { - dev->irq = irq_list->irq; - dev->bits = irq_list->bits; - return 0; - } - irq_list++; - } - - return -EBUSY; } -static void __devinit sonypi_display_info(void) +static int __devinit sonypi_probe(void) { - printk(KERN_INFO "sonypi: detected type%d model, " - "verbose = %d, fnkeyinit = %s, camera = %s, " - "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n", - sonypi_device.model, - verbose, - fnkeyinit ? "on" : "off", - camera ? "on" : "off", - compat ? "on" : "off", - mask, - useinput ? "on" : "off", - SONYPI_ACPI_ACTIVE ? "on" : "off"); - printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n", - sonypi_device.irq, - sonypi_device.ioport1, sonypi_device.ioport2); + int i, ret; + struct sonypi_ioport_list *ioport_list; + struct sonypi_irq_list *irq_list; + struct pci_dev *pcidev; - if (minor == -1) - printk(KERN_INFO "sonypi: device allocated minor is %d\n", - sonypi_misc_device.minor); -} + if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_82371AB_3, NULL))) + sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE1; + else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, + PCI_DEVICE_ID_INTEL_ICH6_1, NULL))) + sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3; + else + sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2; -static int __devinit sonypi_probe(struct platform_device *dev) -{ - const struct sonypi_ioport_list *ioport_list; - const struct sonypi_irq_list *irq_list; - struct pci_dev *pcidev; - int error; + sonypi_device.dev = pcidev; spin_lock_init(&sonypi_device.fifo_lock); sonypi_device.fifo = kfifo_alloc(SONYPI_BUF_SIZE, GFP_KERNEL, &sonypi_device.fifo_lock); if (IS_ERR(sonypi_device.fifo)) { printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); - return PTR_ERR(sonypi_device.fifo); + ret = PTR_ERR(sonypi_device.fifo); + goto out_fifo; } init_waitqueue_head(&sonypi_device.fifo_proc_list); init_MUTEX(&sonypi_device.lock); sonypi_device.bluetooth_power = -1; - if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82371AB_3, NULL))) - sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE1; - else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_ICH6_1, NULL))) - sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3; - else - sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2; - if (pcidev && pci_enable_device(pcidev)) { printk(KERN_ERR "sonypi: pci_enable_device failed\n"); - error = -EIO; - goto err_put_pcidev; + ret = -EIO; + goto out_pcienable; + } + + if (minor != -1) + sonypi_misc_device.minor = minor; + if ((ret = misc_register(&sonypi_misc_device))) { + printk(KERN_ERR "sonypi: misc_register failed\n"); + goto out_miscreg; } - sonypi_device.dev = pcidev; if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) { ioport_list = sonypi_type1_ioport_list; @@ -1369,36 +1302,43 @@ static int __devinit sonypi_probe(struct platform_device *dev) irq_list = sonypi_type3_irq_list; } - error = sonypi_setup_ioports(&sonypi_device, ioport_list); - if (error) { - printk(KERN_ERR "sonypi: failed to request ioports\n"); - goto err_disable_pcidev; + for (i = 0; ioport_list[i].port1; i++) { + if (request_region(ioport_list[i].port1, + sonypi_device.region_size, + "Sony Programable I/O Device")) { + /* get the ioport */ + sonypi_device.ioport1 = ioport_list[i].port1; + sonypi_device.ioport2 = ioport_list[i].port2; + break; + } } - - error = sonypi_setup_irq(&sonypi_device, irq_list); - if (error) { - printk(KERN_ERR "sonypi: request_irq failed\n"); - goto err_free_ioports; + if (!sonypi_device.ioport1) { + printk(KERN_ERR "sonypi: request_region failed\n"); + ret = -ENODEV; + goto out_reqreg; } - if (minor != -1) - sonypi_misc_device.minor = minor; - error = misc_register(&sonypi_misc_device); - if (error) { - printk(KERN_ERR "sonypi: misc_register failed\n"); - goto err_free_irq; + for (i = 0; irq_list[i].irq; i++) { + + sonypi_device.irq = irq_list[i].irq; + sonypi_device.bits = irq_list[i].bits; + + if (!request_irq(sonypi_device.irq, sonypi_irq, + SA_SHIRQ, "sonypi", sonypi_irq)) + break; } - sonypi_display_info(); + if (!irq_list[i].irq) { + printk(KERN_ERR "sonypi: request_irq failed\n"); + ret = -ENODEV; + goto out_reqirq; + } if (useinput) { - error = sonypi_create_input_devices(); - if (error) { - printk(KERN_ERR - "sonypi: failed to create input devices\n"); - goto err_miscdev_unregister; - } + ret = sonypi_create_input_devices(); + if (ret) + goto out_inputdevices; spin_lock_init(&sonypi_device.input_fifo_lock); sonypi_device.input_fifo = @@ -1406,104 +1346,91 @@ static int __devinit sonypi_probe(struct platform_device *dev) &sonypi_device.input_fifo_lock); if (IS_ERR(sonypi_device.input_fifo)) { printk(KERN_ERR "sonypi: kfifo_alloc failed\n"); - error = PTR_ERR(sonypi_device.input_fifo); - goto err_inpdev_unregister; + ret = PTR_ERR(sonypi_device.input_fifo); + goto out_infifo; } INIT_WORK(&sonypi_device.input_work, input_keyrelease, NULL); } + sonypi_device.pdev = platform_device_register_simple("sonypi", -1, + NULL, 0); + if (IS_ERR(sonypi_device.pdev)) { + ret = PTR_ERR(sonypi_device.pdev); + goto out_platformdev; + } + sonypi_enable(0); + printk(KERN_INFO "sonypi: Sony Programmable I/O Controller Driver" + "v%s.\n", SONYPI_DRIVER_VERSION); + printk(KERN_INFO "sonypi: detected type%d model, " + "verbose = %d, fnkeyinit = %s, camera = %s, " + "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n", + sonypi_device.model, + verbose, + fnkeyinit ? "on" : "off", + camera ? "on" : "off", + compat ? "on" : "off", + mask, + useinput ? "on" : "off", + SONYPI_ACPI_ACTIVE ? "on" : "off"); + printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n", + sonypi_device.irq, + sonypi_device.ioport1, sonypi_device.ioport2); + + if (minor == -1) + printk(KERN_INFO "sonypi: device allocated minor is %d\n", + sonypi_misc_device.minor); + return 0; - err_inpdev_unregister: +out_platformdev: + kfifo_free(sonypi_device.input_fifo); +out_infifo: input_unregister_device(sonypi_device.input_key_dev); input_unregister_device(sonypi_device.input_jog_dev); - err_miscdev_unregister: - misc_deregister(&sonypi_misc_device); - err_free_irq: +out_inputdevices: free_irq(sonypi_device.irq, sonypi_irq); - err_free_ioports: +out_reqirq: release_region(sonypi_device.ioport1, sonypi_device.region_size); - err_disable_pcidev: +out_reqreg: + misc_deregister(&sonypi_misc_device); +out_miscreg: if (pcidev) pci_disable_device(pcidev); - err_put_pcidev: - pci_dev_put(pcidev); +out_pcienable: kfifo_free(sonypi_device.fifo); - - return error; +out_fifo: + pci_dev_put(sonypi_device.dev); + return ret; } -static int __devexit sonypi_remove(struct platform_device *dev) +static void __devexit sonypi_remove(void) { sonypi_disable(); synchronize_sched(); /* Allow sonypi interrupt to complete. */ flush_scheduled_work(); + platform_device_unregister(sonypi_device.pdev); + if (useinput) { input_unregister_device(sonypi_device.input_key_dev); input_unregister_device(sonypi_device.input_jog_dev); kfifo_free(sonypi_device.input_fifo); } - misc_deregister(&sonypi_misc_device); - free_irq(sonypi_device.irq, sonypi_irq); release_region(sonypi_device.ioport1, sonypi_device.region_size); - - if (sonypi_device.dev) { + misc_deregister(&sonypi_misc_device); + if (sonypi_device.dev) pci_disable_device(sonypi_device.dev); - pci_dev_put(sonypi_device.dev); - } - kfifo_free(sonypi_device.fifo); - - return 0; -} - -#ifdef CONFIG_PM -static int old_camera_power; - -static int sonypi_suspend(struct platform_device *dev, pm_message_t state) -{ - old_camera_power = sonypi_device.camera_power; - sonypi_disable(); - - return 0; -} - -static int sonypi_resume(struct platform_device *dev) -{ - sonypi_enable(old_camera_power); - return 0; -} -#else -#define sonypi_suspend NULL -#define sonypi_resume NULL -#endif - -static void sonypi_shutdown(struct platform_device *dev) -{ - sonypi_disable(); + pci_dev_put(sonypi_device.dev); + printk(KERN_INFO "sonypi: removed.\n"); } -static struct platform_driver sonypi_driver = { - .driver = { - .name = "sonypi", - .owner = THIS_MODULE, - }, - .probe = sonypi_probe, - .remove = __devexit_p(sonypi_remove), - .shutdown = sonypi_shutdown, - .suspend = sonypi_suspend, - .resume = sonypi_resume, -}; - -static struct platform_device *sonypi_platform_device; - static struct dmi_system_id __initdata sonypi_dmi_table[] = { { .ident = "Sony Vaio", @@ -1524,52 +1451,26 @@ static struct dmi_system_id __initdata sonypi_dmi_table[] = { static int __init sonypi_init(void) { - int error; - - printk(KERN_INFO - "sonypi: Sony Programmable I/O Controller Driver v%s.\n", - SONYPI_DRIVER_VERSION); + int ret; if (!dmi_check_system(sonypi_dmi_table)) return -ENODEV; - error = platform_driver_register(&sonypi_driver); - if (error) - return error; - - sonypi_platform_device = platform_device_alloc("sonypi", -1); - if (!sonypi_platform_device) { - error = -ENOMEM; - goto err_driver_unregister; - } - - error = platform_device_add(sonypi_platform_device); - if (error) - goto err_free_device; - -#ifdef CONFIG_ACPI - if (acpi_bus_register_driver(&sonypi_acpi_driver) > 0) - acpi_enabled = 1; -#endif + ret = platform_driver_register(&sonypi_driver); + if (ret) + return ret; - return 0; + ret = sonypi_probe(); + if (ret) + platform_driver_unregister(&sonypi_driver); - err_free_device: - platform_device_put(sonypi_platform_device); - err_driver_unregister: - platform_driver_unregister(&sonypi_driver); - return error; + return ret; } static void __exit sonypi_exit(void) { -#ifdef CONFIG_ACPI - if (acpi_enabled) - acpi_bus_unregister_driver(&sonypi_acpi_driver); -#endif - platform_device_unregister(sonypi_platform_device); platform_driver_unregister(&sonypi_driver); - printk(KERN_INFO "sonypi: removed.\n"); + sonypi_remove(); } module_init(sonypi_init); diff --git a/trunk/drivers/char/synclink_gt.c b/trunk/drivers/char/synclink_gt.c deleted file mode 100644 index 2b9cde94e2f7..000000000000 --- a/trunk/drivers/char/synclink_gt.c +++ /dev/null @@ -1,4501 +0,0 @@ -/* - * $Id: synclink_gt.c,v 4.20 2005/11/08 19:51:55 paulkf Exp $ - * - * Device driver for Microgate SyncLink GT serial adapters. - * - * written by Paul Fulghum for Microgate Corporation - * paulkf@microgate.com - * - * Microgate and SyncLink are trademarks of Microgate Corporation - * - * This code is released under the GNU General Public License (GPL) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * DEBUG OUTPUT DEFINITIONS - * - * uncomment lines below to enable specific types of debug output - * - * DBGINFO information - most verbose output - * DBGERR serious errors - * DBGBH bottom half service routine debugging - * DBGISR interrupt service routine debugging - * DBGDATA output receive and transmit data - * DBGTBUF output transmit DMA buffers and registers - * DBGRBUF output receive DMA buffers and registers - */ - -#define DBGINFO(fmt) if (debug_level >= DEBUG_LEVEL_INFO) printk fmt -#define DBGERR(fmt) if (debug_level >= DEBUG_LEVEL_ERROR) printk fmt -#define DBGBH(fmt) if (debug_level >= DEBUG_LEVEL_BH) printk fmt -#define DBGISR(fmt) if (debug_level >= DEBUG_LEVEL_ISR) printk fmt -#define DBGDATA(info, buf, size, label) if (debug_level >= DEBUG_LEVEL_DATA) trace_block((info), (buf), (size), (label)) -//#define DBGTBUF(info) dump_tbufs(info) -//#define DBGRBUF(info) dump_rbufs(info) - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "linux/synclink.h" - -#ifdef CONFIG_HDLC_MODULE -#define CONFIG_HDLC 1 -#endif - -/* - * module identification - */ -static char *driver_name = "SyncLink GT"; -static char *driver_version = "$Revision: 4.20 $"; -static char *tty_driver_name = "synclink_gt"; -static char *tty_dev_prefix = "ttySLG"; -MODULE_LICENSE("GPL"); -#define MGSL_MAGIC 0x5401 -#define MAX_DEVICES 12 - -static struct pci_device_id pci_table[] = { - {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {PCI_VENDOR_ID_MICROGATE, SYNCLINK_GT4_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {PCI_VENDOR_ID_MICROGATE, SYNCLINK_AC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,}, - {0,}, /* terminate list */ -}; -MODULE_DEVICE_TABLE(pci, pci_table); - -static int init_one(struct pci_dev *dev,const struct pci_device_id *ent); -static void remove_one(struct pci_dev *dev); -static struct pci_driver pci_driver = { - .name = "synclink_gt", - .id_table = pci_table, - .probe = init_one, - .remove = __devexit_p(remove_one), -}; - -static int pci_registered; - -/* - * module configuration and status - */ -static struct slgt_info *slgt_device_list; -static int slgt_device_count; - -static int ttymajor; -static int debug_level; -static int maxframe[MAX_DEVICES]; -static int dosyncppp[MAX_DEVICES]; - -module_param(ttymajor, int, 0); -module_param(debug_level, int, 0); -module_param_array(maxframe, int, NULL, 0); -module_param_array(dosyncppp, int, NULL, 0); - -MODULE_PARM_DESC(ttymajor, "TTY major device number override: 0=auto assigned"); -MODULE_PARM_DESC(debug_level, "Debug syslog output: 0=disabled, 1 to 5=increasing detail"); -MODULE_PARM_DESC(maxframe, "Maximum frame size used by device (4096 to 65535)"); -MODULE_PARM_DESC(dosyncppp, "Enable synchronous net device, 0=disable 1=enable"); - -/* - * tty support and callbacks - */ -#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - -static struct tty_driver *serial_driver; - -static int open(struct tty_struct *tty, struct file * filp); -static void close(struct tty_struct *tty, struct file * filp); -static void hangup(struct tty_struct *tty); -static void set_termios(struct tty_struct *tty, struct termios *old_termios); - -static int write(struct tty_struct *tty, const unsigned char *buf, int count); -static void put_char(struct tty_struct *tty, unsigned char ch); -static void send_xchar(struct tty_struct *tty, char ch); -static void wait_until_sent(struct tty_struct *tty, int timeout); -static int write_room(struct tty_struct *tty); -static void flush_chars(struct tty_struct *tty); -static void flush_buffer(struct tty_struct *tty); -static void tx_hold(struct tty_struct *tty); -static void tx_release(struct tty_struct *tty); - -static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); -static int read_proc(char *page, char **start, off_t off, int count,int *eof, void *data); -static int chars_in_buffer(struct tty_struct *tty); -static void throttle(struct tty_struct * tty); -static void unthrottle(struct tty_struct * tty); -static void set_break(struct tty_struct *tty, int break_state); - -/* - * generic HDLC support and callbacks - */ -#ifdef CONFIG_HDLC -#define dev_to_port(D) (dev_to_hdlc(D)->priv) -static void hdlcdev_tx_done(struct slgt_info *info); -static void hdlcdev_rx(struct slgt_info *info, char *buf, int size); -static int hdlcdev_init(struct slgt_info *info); -static void hdlcdev_exit(struct slgt_info *info); -#endif - - -/* - * device specific structures, macros and functions - */ - -#define SLGT_MAX_PORTS 4 -#define SLGT_REG_SIZE 256 - -/* - * DMA buffer descriptor and access macros - */ -struct slgt_desc -{ - unsigned short count; - unsigned short status; - unsigned int pbuf; /* physical address of data buffer */ - unsigned int next; /* physical address of next descriptor */ - - /* driver book keeping */ - char *buf; /* virtual address of data buffer */ - unsigned int pdesc; /* physical address of this descriptor */ - dma_addr_t buf_dma_addr; -}; - -#define set_desc_buffer(a,b) (a).pbuf = cpu_to_le32((unsigned int)(b)) -#define set_desc_next(a,b) (a).next = cpu_to_le32((unsigned int)(b)) -#define set_desc_count(a,b)(a).count = cpu_to_le16((unsigned short)(b)) -#define set_desc_eof(a,b) (a).status = cpu_to_le16((b) ? (le16_to_cpu((a).status) | BIT0) : (le16_to_cpu((a).status) & ~BIT0)) -#define desc_count(a) (le16_to_cpu((a).count)) -#define desc_status(a) (le16_to_cpu((a).status)) -#define desc_complete(a) (le16_to_cpu((a).status) & BIT15) -#define desc_eof(a) (le16_to_cpu((a).status) & BIT2) -#define desc_crc_error(a) (le16_to_cpu((a).status) & BIT1) -#define desc_abort(a) (le16_to_cpu((a).status) & BIT0) -#define desc_residue(a) ((le16_to_cpu((a).status) & 0x38) >> 3) - -struct _input_signal_events { - int ri_up; - int ri_down; - int dsr_up; - int dsr_down; - int dcd_up; - int dcd_down; - int cts_up; - int cts_down; -}; - -/* - * device instance data structure - */ -struct slgt_info { - void *if_ptr; /* General purpose pointer (used by SPPP) */ - - struct slgt_info *next_device; /* device list link */ - - int magic; - int flags; - - char device_name[25]; - struct pci_dev *pdev; - - int port_count; /* count of ports on adapter */ - int adapter_num; /* adapter instance number */ - int port_num; /* port instance number */ - - /* array of pointers to port contexts on this adapter */ - struct slgt_info *port_array[SLGT_MAX_PORTS]; - - int count; /* count of opens */ - int line; /* tty line instance number */ - unsigned short close_delay; - unsigned short closing_wait; /* time to wait before closing */ - - struct mgsl_icount icount; - - struct tty_struct *tty; - int timeout; - int x_char; /* xon/xoff character */ - int blocked_open; /* # of blocked opens */ - unsigned int read_status_mask; - unsigned int ignore_status_mask; - - wait_queue_head_t open_wait; - wait_queue_head_t close_wait; - - wait_queue_head_t status_event_wait_q; - wait_queue_head_t event_wait_q; - struct timer_list tx_timer; - struct timer_list rx_timer; - - spinlock_t lock; /* spinlock for synchronizing with ISR */ - - struct work_struct task; - u32 pending_bh; - int bh_requested; - int bh_running; - - int isr_overflow; - int irq_requested; /* nonzero if IRQ requested */ - int irq_occurred; /* for diagnostics use */ - - /* device configuration */ - - unsigned int bus_type; - unsigned int irq_level; - unsigned long irq_flags; - - unsigned char __iomem * reg_addr; /* memory mapped registers address */ - u32 phys_reg_addr; - u32 reg_offset; - int reg_addr_requested; - - MGSL_PARAMS params; /* communications parameters */ - u32 idle_mode; - u32 max_frame_size; /* as set by device config */ - - unsigned int raw_rx_size; - unsigned int if_mode; - - /* device status */ - - int rx_enabled; - int rx_restart; - - int tx_enabled; - int tx_active; - - unsigned char signals; /* serial signal states */ - unsigned int init_error; /* initialization error */ - - unsigned char *tx_buf; - int tx_count; - - char flag_buf[MAX_ASYNC_BUFFER_SIZE]; - char char_buf[MAX_ASYNC_BUFFER_SIZE]; - BOOLEAN drop_rts_on_tx_done; - struct _input_signal_events input_signal_events; - - int dcd_chkcount; /* check counts to prevent */ - int cts_chkcount; /* too many IRQs if a signal */ - int dsr_chkcount; /* is floating */ - int ri_chkcount; - - char *bufs; /* virtual address of DMA buffer lists */ - dma_addr_t bufs_dma_addr; /* physical address of buffer descriptors */ - - unsigned int rbuf_count; - struct slgt_desc *rbufs; - unsigned int rbuf_current; - unsigned int rbuf_index; - - unsigned int tbuf_count; - struct slgt_desc *tbufs; - unsigned int tbuf_current; - unsigned int tbuf_start; - - unsigned char *tmp_rbuf; - unsigned int tmp_rbuf_count; - - /* SPPP/Cisco HDLC device parts */ - - int netcount; - int dosyncppp; - spinlock_t netlock; -#ifdef CONFIG_HDLC - struct net_device *netdev; -#endif - -}; - -static MGSL_PARAMS default_params = { - .mode = MGSL_MODE_HDLC, - .loopback = 0, - .flags = HDLC_FLAG_UNDERRUN_ABORT15, - .encoding = HDLC_ENCODING_NRZI_SPACE, - .clock_speed = 0, - .addr_filter = 0xff, - .crc_type = HDLC_CRC_16_CCITT, - .preamble_length = HDLC_PREAMBLE_LENGTH_8BITS, - .preamble = HDLC_PREAMBLE_PATTERN_NONE, - .data_rate = 9600, - .data_bits = 8, - .stop_bits = 1, - .parity = ASYNC_PARITY_NONE -}; - - -#define BH_RECEIVE 1 -#define BH_TRANSMIT 2 -#define BH_STATUS 4 -#define IO_PIN_SHUTDOWN_LIMIT 100 - -#define DMABUFSIZE 256 -#define DESC_LIST_SIZE 4096 - -#define MASK_PARITY BIT1 -#define MASK_FRAMING BIT2 -#define MASK_BREAK BIT3 -#define MASK_OVERRUN BIT4 - -#define GSR 0x00 /* global status */ -#define TDR 0x80 /* tx data */ -#define RDR 0x80 /* rx data */ -#define TCR 0x82 /* tx control */ -#define TIR 0x84 /* tx idle */ -#define TPR 0x85 /* tx preamble */ -#define RCR 0x86 /* rx control */ -#define VCR 0x88 /* V.24 control */ -#define CCR 0x89 /* clock control */ -#define BDR 0x8a /* baud divisor */ -#define SCR 0x8c /* serial control */ -#define SSR 0x8e /* serial status */ -#define RDCSR 0x90 /* rx DMA control/status */ -#define TDCSR 0x94 /* tx DMA control/status */ -#define RDDAR 0x98 /* rx DMA descriptor address */ -#define TDDAR 0x9c /* tx DMA descriptor address */ - -#define RXIDLE BIT14 -#define RXBREAK BIT14 -#define IRQ_TXDATA BIT13 -#define IRQ_TXIDLE BIT12 -#define IRQ_TXUNDER BIT11 /* HDLC */ -#define IRQ_RXDATA BIT10 -#define IRQ_RXIDLE BIT9 /* HDLC */ -#define IRQ_RXBREAK BIT9 /* async */ -#define IRQ_RXOVER BIT8 -#define IRQ_DSR BIT7 -#define IRQ_CTS BIT6 -#define IRQ_DCD BIT5 -#define IRQ_RI BIT4 -#define IRQ_ALL 0x3ff0 -#define IRQ_MASTER BIT0 - -#define slgt_irq_on(info, mask) \ - wr_reg16((info), SCR, (unsigned short)(rd_reg16((info), SCR) | (mask))) -#define slgt_irq_off(info, mask) \ - wr_reg16((info), SCR, (unsigned short)(rd_reg16((info), SCR) & ~(mask))) - -static __u8 rd_reg8(struct slgt_info *info, unsigned int addr); -static void wr_reg8(struct slgt_info *info, unsigned int addr, __u8 value); -static __u16 rd_reg16(struct slgt_info *info, unsigned int addr); -static void wr_reg16(struct slgt_info *info, unsigned int addr, __u16 value); -static __u32 rd_reg32(struct slgt_info *info, unsigned int addr); -static void wr_reg32(struct slgt_info *info, unsigned int addr, __u32 value); - -static void msc_set_vcr(struct slgt_info *info); - -static int startup(struct slgt_info *info); -static int block_til_ready(struct tty_struct *tty, struct file * filp,struct slgt_info *info); -static void shutdown(struct slgt_info *info); -static void program_hw(struct slgt_info *info); -static void change_params(struct slgt_info *info); - -static int register_test(struct slgt_info *info); -static int irq_test(struct slgt_info *info); -static int loopback_test(struct slgt_info *info); -static int adapter_test(struct slgt_info *info); - -static void reset_adapter(struct slgt_info *info); -static void reset_port(struct slgt_info *info); -static void async_mode(struct slgt_info *info); -static void hdlc_mode(struct slgt_info *info); - -static void rx_stop(struct slgt_info *info); -static void rx_start(struct slgt_info *info); -static void reset_rbufs(struct slgt_info *info); -static void free_rbufs(struct slgt_info *info, unsigned int first, unsigned int last); -static void rdma_reset(struct slgt_info *info); -static int rx_get_frame(struct slgt_info *info); -static int rx_get_buf(struct slgt_info *info); - -static void tx_start(struct slgt_info *info); -static void tx_stop(struct slgt_info *info); -static void tx_set_idle(struct slgt_info *info); -static unsigned int free_tbuf_count(struct slgt_info *info); -static void reset_tbufs(struct slgt_info *info); -static void tdma_reset(struct slgt_info *info); -static void tx_load(struct slgt_info *info, const char *buf, unsigned int count); - -static void get_signals(struct slgt_info *info); -static void set_signals(struct slgt_info *info); -static void enable_loopback(struct slgt_info *info); -static void set_rate(struct slgt_info *info, u32 data_rate); - -static int bh_action(struct slgt_info *info); -static void bh_handler(void* context); -static void bh_transmit(struct slgt_info *info); -static void isr_serial(struct slgt_info *info); -static void isr_rdma(struct slgt_info *info); -static void isr_txeom(struct slgt_info *info, unsigned short status); -static void isr_tdma(struct slgt_info *info); -static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs); - -static int alloc_dma_bufs(struct slgt_info *info); -static void free_dma_bufs(struct slgt_info *info); -static int alloc_desc(struct slgt_info *info); -static void free_desc(struct slgt_info *info); -static int alloc_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count); -static void free_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count); - -static int alloc_tmp_rbuf(struct slgt_info *info); -static void free_tmp_rbuf(struct slgt_info *info); - -static void tx_timeout(unsigned long context); -static void rx_timeout(unsigned long context); - -/* - * ioctl handlers - */ -static int get_stats(struct slgt_info *info, struct mgsl_icount __user *user_icount); -static int get_params(struct slgt_info *info, MGSL_PARAMS __user *params); -static int set_params(struct slgt_info *info, MGSL_PARAMS __user *params); -static int get_txidle(struct slgt_info *info, int __user *idle_mode); -static int set_txidle(struct slgt_info *info, int idle_mode); -static int tx_enable(struct slgt_info *info, int enable); -static int tx_abort(struct slgt_info *info); -static int rx_enable(struct slgt_info *info, int enable); -static int modem_input_wait(struct slgt_info *info,int arg); -static int wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr); -static int tiocmget(struct tty_struct *tty, struct file *file); -static int tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear); -static void set_break(struct tty_struct *tty, int break_state); -static int get_interface(struct slgt_info *info, int __user *if_mode); -static int set_interface(struct slgt_info *info, int if_mode); - -/* - * driver functions - */ -static void add_device(struct slgt_info *info); -static void device_init(int adapter_num, struct pci_dev *pdev); -static int claim_resources(struct slgt_info *info); -static void release_resources(struct slgt_info *info); - -/* - * DEBUG OUTPUT CODE - */ -#ifndef DBGINFO -#define DBGINFO(fmt) -#endif -#ifndef DBGERR -#define DBGERR(fmt) -#endif -#ifndef DBGBH -#define DBGBH(fmt) -#endif -#ifndef DBGISR -#define DBGISR(fmt) -#endif - -#ifdef DBGDATA -static void trace_block(struct slgt_info *info, const char *data, int count, const char *label) -{ - int i; - int linecount; - printk("%s %s data:\n",info->device_name, label); - while(count) { - linecount = (count > 16) ? 16 : count; - for(i=0; i < linecount; i++) - printk("%02X ",(unsigned char)data[i]); - for(;i<17;i++) - printk(" "); - for(i=0;i=040 && data[i]<=0176) - printk("%c",data[i]); - else - printk("."); - } - printk("\n"); - data += linecount; - count -= linecount; - } -} -#else -#define DBGDATA(info, buf, size, label) -#endif - -#ifdef DBGTBUF -static void dump_tbufs(struct slgt_info *info) -{ - int i; - printk("tbuf_current=%d\n", info->tbuf_current); - for (i=0 ; i < info->tbuf_count ; i++) { - printk("%d: count=%04X status=%04X\n", - i, le16_to_cpu(info->tbufs[i].count), le16_to_cpu(info->tbufs[i].status)); - } -} -#else -#define DBGTBUF(info) -#endif - -#ifdef DBGRBUF -static void dump_rbufs(struct slgt_info *info) -{ - int i; - printk("rbuf_current=%d\n", info->rbuf_current); - for (i=0 ; i < info->rbuf_count ; i++) { - printk("%d: count=%04X status=%04X\n", - i, le16_to_cpu(info->rbufs[i].count), le16_to_cpu(info->rbufs[i].status)); - } -} -#else -#define DBGRBUF(info) -#endif - -static inline int sanity_check(struct slgt_info *info, char *devname, const char *name) -{ -#ifdef SANITY_CHECK - if (!info) { - printk("null struct slgt_info for (%s) in %s\n", devname, name); - return 1; - } - if (info->magic != MGSL_MAGIC) { - printk("bad magic number struct slgt_info (%s) in %s\n", devname, name); - return 1; - } -#else - if (!info) - return 1; -#endif - return 0; -} - -/** - * line discipline callback wrappers - * - * The wrappers maintain line discipline references - * while calling into the line discipline. - * - * ldisc_receive_buf - pass receive data to line discipline - */ -static void ldisc_receive_buf(struct tty_struct *tty, - const __u8 *data, char *flags, int count) -{ - struct tty_ldisc *ld; - if (!tty) - return; - ld = tty_ldisc_ref(tty); - if (ld) { - if (ld->receive_buf) - ld->receive_buf(tty, data, flags, count); - tty_ldisc_deref(ld); - } -} - -/* tty callbacks */ - -static int open(struct tty_struct *tty, struct file *filp) -{ - struct slgt_info *info; - int retval, line; - unsigned long flags; - - line = tty->index; - if ((line < 0) || (line >= slgt_device_count)) { - DBGERR(("%s: open with invalid line #%d.\n", driver_name, line)); - return -ENODEV; - } - - info = slgt_device_list; - while(info && info->line != line) - info = info->next_device; - if (sanity_check(info, tty->name, "open")) - return -ENODEV; - if (info->init_error) { - DBGERR(("%s init error=%d\n", info->device_name, info->init_error)); - return -ENODEV; - } - - tty->driver_data = info; - info->tty = tty; - - DBGINFO(("%s open, old ref count = %d\n", info->device_name, info->count)); - - /* If port is closing, signal caller to try again */ - if (tty_hung_up_p(filp) || info->flags & ASYNC_CLOSING){ - if (info->flags & ASYNC_CLOSING) - interruptible_sleep_on(&info->close_wait); - retval = ((info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); - goto cleanup; - } - - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; - - spin_lock_irqsave(&info->netlock, flags); - if (info->netcount) { - retval = -EBUSY; - spin_unlock_irqrestore(&info->netlock, flags); - goto cleanup; - } - info->count++; - spin_unlock_irqrestore(&info->netlock, flags); - - if (info->count == 1) { - /* 1st open on this device, init hardware */ - retval = startup(info); - if (retval < 0) - goto cleanup; - } - - retval = block_til_ready(tty, filp, info); - if (retval) { - DBGINFO(("%s block_til_ready rc=%d\n", info->device_name, retval)); - goto cleanup; - } - - retval = 0; - -cleanup: - if (retval) { - if (tty->count == 1) - info->tty = NULL; /* tty layer will release tty struct */ - if(info->count) - info->count--; - } - - DBGINFO(("%s open rc=%d\n", info->device_name, retval)); - return retval; -} - -static void close(struct tty_struct *tty, struct file *filp) -{ - struct slgt_info *info = tty->driver_data; - - if (sanity_check(info, tty->name, "close")) - return; - DBGINFO(("%s close entry, count=%d\n", info->device_name, info->count)); - - if (!info->count) - return; - - if (tty_hung_up_p(filp)) - goto cleanup; - - if ((tty->count == 1) && (info->count != 1)) { - /* - * tty->count is 1 and the tty structure will be freed. - * info->count should be one in this case. - * if it's not, correct it so that the port is shutdown. - */ - DBGERR(("%s close: bad refcount; tty->count=1, " - "info->count=%d\n", info->device_name, info->count)); - info->count = 1; - } - - info->count--; - - /* if at least one open remaining, leave hardware active */ - if (info->count) - goto cleanup; - - info->flags |= ASYNC_CLOSING; - - /* set tty->closing to notify line discipline to - * only process XON/XOFF characters. Only the N_TTY - * discipline appears to use this (ppp does not). - */ - tty->closing = 1; - - /* wait for transmit data to clear all layers */ - - if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) { - DBGINFO(("%s call tty_wait_until_sent\n", info->device_name)); - tty_wait_until_sent(tty, info->closing_wait); - } - - if (info->flags & ASYNC_INITIALIZED) - wait_until_sent(tty, info->timeout); - if (tty->driver->flush_buffer) - tty->driver->flush_buffer(tty); - tty_ldisc_flush(tty); - - shutdown(info); - - tty->closing = 0; - info->tty = NULL; - - if (info->blocked_open) { - if (info->close_delay) { - msleep_interruptible(jiffies_to_msecs(info->close_delay)); - } - wake_up_interruptible(&info->open_wait); - } - - info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); - - wake_up_interruptible(&info->close_wait); - -cleanup: - DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->count)); -} - -static void hangup(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - - if (sanity_check(info, tty->name, "hangup")) - return; - DBGINFO(("%s hangup\n", info->device_name)); - - flush_buffer(tty); - shutdown(info); - - info->count = 0; - info->flags &= ~ASYNC_NORMAL_ACTIVE; - info->tty = NULL; - - wake_up_interruptible(&info->open_wait); -} - -static void set_termios(struct tty_struct *tty, struct termios *old_termios) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - DBGINFO(("%s set_termios\n", tty->driver->name)); - - /* just return if nothing has changed */ - if ((tty->termios->c_cflag == old_termios->c_cflag) - && (RELEVANT_IFLAG(tty->termios->c_iflag) - == RELEVANT_IFLAG(old_termios->c_iflag))) - return; - - change_params(info); - - /* Handle transition to B0 status */ - if (old_termios->c_cflag & CBAUD && - !(tty->termios->c_cflag & CBAUD)) { - info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); - spin_lock_irqsave(&info->lock,flags); - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - } - - /* Handle transition away from B0 status */ - if (!(old_termios->c_cflag & CBAUD) && - tty->termios->c_cflag & CBAUD) { - info->signals |= SerialSignal_DTR; - if (!(tty->termios->c_cflag & CRTSCTS) || - !test_bit(TTY_THROTTLED, &tty->flags)) { - info->signals |= SerialSignal_RTS; - } - spin_lock_irqsave(&info->lock,flags); - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - } - - /* Handle turning off CRTSCTS */ - if (old_termios->c_cflag & CRTSCTS && - !(tty->termios->c_cflag & CRTSCTS)) { - tty->hw_stopped = 0; - tx_release(tty); - } -} - -static int write(struct tty_struct *tty, - const unsigned char *buf, int count) -{ - int ret = 0; - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "write")) - goto cleanup; - DBGINFO(("%s write count=%d\n", info->device_name, count)); - - if (!tty || !info->tx_buf) - goto cleanup; - - if (count > info->max_frame_size) { - ret = -EIO; - goto cleanup; - } - - if (!count) - goto cleanup; - - if (info->params.mode == MGSL_MODE_RAW) { - unsigned int bufs_needed = (count/DMABUFSIZE); - unsigned int bufs_free = free_tbuf_count(info); - if (count % DMABUFSIZE) - ++bufs_needed; - if (bufs_needed > bufs_free) - goto cleanup; - } else { - if (info->tx_active) - goto cleanup; - if (info->tx_count) { - /* send accumulated data from send_char() calls */ - /* as frame and wait before accepting more data. */ - tx_load(info, info->tx_buf, info->tx_count); - goto start; - } - } - - ret = info->tx_count = count; - tx_load(info, buf, count); - goto start; - -start: - if (info->tx_count && !tty->stopped && !tty->hw_stopped) { - spin_lock_irqsave(&info->lock,flags); - if (!info->tx_active) - tx_start(info); - spin_unlock_irqrestore(&info->lock,flags); - } - -cleanup: - DBGINFO(("%s write rc=%d\n", info->device_name, ret)); - return ret; -} - -static void put_char(struct tty_struct *tty, unsigned char ch) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "put_char")) - return; - DBGINFO(("%s put_char(%d)\n", info->device_name, ch)); - if (!tty || !info->tx_buf) - return; - spin_lock_irqsave(&info->lock,flags); - if (!info->tx_active && (info->tx_count < info->max_frame_size)) - info->tx_buf[info->tx_count++] = ch; - spin_unlock_irqrestore(&info->lock,flags); -} - -static void send_xchar(struct tty_struct *tty, char ch) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "send_xchar")) - return; - DBGINFO(("%s send_xchar(%d)\n", info->device_name, ch)); - info->x_char = ch; - if (ch) { - spin_lock_irqsave(&info->lock,flags); - if (!info->tx_enabled) - tx_start(info); - spin_unlock_irqrestore(&info->lock,flags); - } -} - -static void wait_until_sent(struct tty_struct *tty, int timeout) -{ - struct slgt_info *info = tty->driver_data; - unsigned long orig_jiffies, char_time; - - if (!info ) - return; - if (sanity_check(info, tty->name, "wait_until_sent")) - return; - DBGINFO(("%s wait_until_sent entry\n", info->device_name)); - if (!(info->flags & ASYNC_INITIALIZED)) - goto exit; - - orig_jiffies = jiffies; - - /* Set check interval to 1/5 of estimated time to - * send a character, and make it at least 1. The check - * interval should also be less than the timeout. - * Note: use tight timings here to satisfy the NIST-PCTS. - */ - - if (info->params.data_rate) { - char_time = info->timeout/(32 * 5); - if (!char_time) - char_time++; - } else - char_time = 1; - - if (timeout) - char_time = min_t(unsigned long, char_time, timeout); - - while (info->tx_active) { - msleep_interruptible(jiffies_to_msecs(char_time)); - if (signal_pending(current)) - break; - if (timeout && time_after(jiffies, orig_jiffies + timeout)) - break; - } - -exit: - DBGINFO(("%s wait_until_sent exit\n", info->device_name)); -} - -static int write_room(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - int ret; - - if (sanity_check(info, tty->name, "write_room")) - return 0; - ret = (info->tx_active) ? 0 : HDLC_MAX_FRAME_SIZE; - DBGINFO(("%s write_room=%d\n", info->device_name, ret)); - return ret; -} - -static void flush_chars(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "flush_chars")) - return; - DBGINFO(("%s flush_chars entry tx_count=%d\n", info->device_name, info->tx_count)); - - if (info->tx_count <= 0 || tty->stopped || - tty->hw_stopped || !info->tx_buf) - return; - - DBGINFO(("%s flush_chars start transmit\n", info->device_name)); - - spin_lock_irqsave(&info->lock,flags); - if (!info->tx_active && info->tx_count) { - tx_load(info, info->tx_buf,info->tx_count); - tx_start(info); - } - spin_unlock_irqrestore(&info->lock,flags); -} - -static void flush_buffer(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "flush_buffer")) - return; - DBGINFO(("%s flush_buffer\n", info->device_name)); - - spin_lock_irqsave(&info->lock,flags); - if (!info->tx_active) - info->tx_count = 0; - spin_unlock_irqrestore(&info->lock,flags); - - wake_up_interruptible(&tty->write_wait); - tty_wakeup(tty); -} - -/* - * throttle (stop) transmitter - */ -static void tx_hold(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "tx_hold")) - return; - DBGINFO(("%s tx_hold\n", info->device_name)); - spin_lock_irqsave(&info->lock,flags); - if (info->tx_enabled && info->params.mode == MGSL_MODE_ASYNC) - tx_stop(info); - spin_unlock_irqrestore(&info->lock,flags); -} - -/* - * release (start) transmitter - */ -static void tx_release(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "tx_release")) - return; - DBGINFO(("%s tx_release\n", info->device_name)); - spin_lock_irqsave(&info->lock,flags); - if (!info->tx_active && info->tx_count) { - tx_load(info, info->tx_buf, info->tx_count); - tx_start(info); - } - spin_unlock_irqrestore(&info->lock,flags); -} - -/* - * Service an IOCTL request - * - * Arguments - * - * tty pointer to tty instance data - * file pointer to associated file object for device - * cmd IOCTL command code - * arg command argument/context - * - * Return 0 if success, otherwise error code - */ -static int ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct slgt_info *info = tty->driver_data; - struct mgsl_icount cnow; /* kernel counter temps */ - struct serial_icounter_struct __user *p_cuser; /* user space */ - unsigned long flags; - void __user *argp = (void __user *)arg; - - if (sanity_check(info, tty->name, "ioctl")) - return -ENODEV; - DBGINFO(("%s ioctl() cmd=%08X\n", info->device_name, cmd)); - - if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && - (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) { - if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; - } - - switch (cmd) { - case MGSL_IOCGPARAMS: - return get_params(info, argp); - case MGSL_IOCSPARAMS: - return set_params(info, argp); - case MGSL_IOCGTXIDLE: - return get_txidle(info, argp); - case MGSL_IOCSTXIDLE: - return set_txidle(info, (int)arg); - case MGSL_IOCTXENABLE: - return tx_enable(info, (int)arg); - case MGSL_IOCRXENABLE: - return rx_enable(info, (int)arg); - case MGSL_IOCTXABORT: - return tx_abort(info); - case MGSL_IOCGSTATS: - return get_stats(info, argp); - case MGSL_IOCWAITEVENT: - return wait_mgsl_event(info, argp); - case TIOCMIWAIT: - return modem_input_wait(info,(int)arg); - case MGSL_IOCGIF: - return get_interface(info, argp); - case MGSL_IOCSIF: - return set_interface(info,(int)arg); - case TIOCGICOUNT: - spin_lock_irqsave(&info->lock,flags); - cnow = info->icount; - spin_unlock_irqrestore(&info->lock,flags); - p_cuser = argp; - if (put_user(cnow.cts, &p_cuser->cts) || - put_user(cnow.dsr, &p_cuser->dsr) || - put_user(cnow.rng, &p_cuser->rng) || - put_user(cnow.dcd, &p_cuser->dcd) || - put_user(cnow.rx, &p_cuser->rx) || - put_user(cnow.tx, &p_cuser->tx) || - put_user(cnow.frame, &p_cuser->frame) || - put_user(cnow.overrun, &p_cuser->overrun) || - put_user(cnow.parity, &p_cuser->parity) || - put_user(cnow.brk, &p_cuser->brk) || - put_user(cnow.buf_overrun, &p_cuser->buf_overrun)) - return -EFAULT; - return 0; - default: - return -ENOIOCTLCMD; - } - return 0; -} - -/* - * proc fs support - */ -static inline int line_info(char *buf, struct slgt_info *info) -{ - char stat_buf[30]; - int ret; - unsigned long flags; - - ret = sprintf(buf, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n", - info->device_name, info->phys_reg_addr, - info->irq_level, info->max_frame_size); - - /* output current serial signal states */ - spin_lock_irqsave(&info->lock,flags); - get_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - - stat_buf[0] = 0; - stat_buf[1] = 0; - if (info->signals & SerialSignal_RTS) - strcat(stat_buf, "|RTS"); - if (info->signals & SerialSignal_CTS) - strcat(stat_buf, "|CTS"); - if (info->signals & SerialSignal_DTR) - strcat(stat_buf, "|DTR"); - if (info->signals & SerialSignal_DSR) - strcat(stat_buf, "|DSR"); - if (info->signals & SerialSignal_DCD) - strcat(stat_buf, "|CD"); - if (info->signals & SerialSignal_RI) - strcat(stat_buf, "|RI"); - - if (info->params.mode != MGSL_MODE_ASYNC) { - ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d", - info->icount.txok, info->icount.rxok); - if (info->icount.txunder) - ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder); - if (info->icount.txabort) - ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort); - if (info->icount.rxshort) - ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort); - if (info->icount.rxlong) - ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong); - if (info->icount.rxover) - ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover); - if (info->icount.rxcrc) - ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc); - } else { - ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d", - info->icount.tx, info->icount.rx); - if (info->icount.frame) - ret += sprintf(buf+ret, " fe:%d", info->icount.frame); - if (info->icount.parity) - ret += sprintf(buf+ret, " pe:%d", info->icount.parity); - if (info->icount.brk) - ret += sprintf(buf+ret, " brk:%d", info->icount.brk); - if (info->icount.overrun) - ret += sprintf(buf+ret, " oe:%d", info->icount.overrun); - } - - /* Append serial signal status to end */ - ret += sprintf(buf+ret, " %s\n", stat_buf+1); - - ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n", - info->tx_active,info->bh_requested,info->bh_running, - info->pending_bh); - - return ret; -} - -/* Called to print information about devices - */ -static int read_proc(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - int len = 0, l; - off_t begin = 0; - struct slgt_info *info; - - len += sprintf(page, "synclink_gt driver:%s\n", driver_version); - - info = slgt_device_list; - while( info ) { - l = line_info(page + len, info); - len += l; - if (len+begin > off+count) - goto done; - if (len+begin < off) { - begin += len; - len = 0; - } - info = info->next_device; - } - - *eof = 1; -done: - if (off >= len+begin) - return 0; - *start = page + (off-begin); - return ((count < begin+len-off) ? count : begin+len-off); -} - -/* - * return count of bytes in transmit buffer - */ -static int chars_in_buffer(struct tty_struct *tty) -{ - struct slgt_info *info = tty->driver_data; - if (sanity_check(info, tty->name, "chars_in_buffer")) - return 0; - DBGINFO(("%s chars_in_buffer()=%d\n", info->device_name, info->tx_count)); - return info->tx_count; -} - -/* - * signal remote device to throttle send data (our receive data) - */ -static void throttle(struct tty_struct * tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "throttle")) - return; - DBGINFO(("%s throttle\n", info->device_name)); - if (I_IXOFF(tty)) - send_xchar(tty, STOP_CHAR(tty)); - if (tty->termios->c_cflag & CRTSCTS) { - spin_lock_irqsave(&info->lock,flags); - info->signals &= ~SerialSignal_RTS; - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - } -} - -/* - * signal remote device to stop throttling send data (our receive data) - */ -static void unthrottle(struct tty_struct * tty) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - if (sanity_check(info, tty->name, "unthrottle")) - return; - DBGINFO(("%s unthrottle\n", info->device_name)); - if (I_IXOFF(tty)) { - if (info->x_char) - info->x_char = 0; - else - send_xchar(tty, START_CHAR(tty)); - } - if (tty->termios->c_cflag & CRTSCTS) { - spin_lock_irqsave(&info->lock,flags); - info->signals |= SerialSignal_RTS; - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - } -} - -/* - * set or clear transmit break condition - * break_state -1=set break condition, 0=clear - */ -static void set_break(struct tty_struct *tty, int break_state) -{ - struct slgt_info *info = tty->driver_data; - unsigned short value; - unsigned long flags; - - if (sanity_check(info, tty->name, "set_break")) - return; - DBGINFO(("%s set_break(%d)\n", info->device_name, break_state)); - - spin_lock_irqsave(&info->lock,flags); - value = rd_reg16(info, TCR); - if (break_state == -1) - value |= BIT6; - else - value &= ~BIT6; - wr_reg16(info, TCR, value); - spin_unlock_irqrestore(&info->lock,flags); -} - -#ifdef CONFIG_HDLC - -/** - * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) - * set encoding and frame check sequence (FCS) options - * - * dev pointer to network device structure - * encoding serial encoding setting - * parity FCS setting - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, - unsigned short parity) -{ - struct slgt_info *info = dev_to_port(dev); - unsigned char new_encoding; - unsigned short new_crctype; - - /* return error if TTY interface open */ - if (info->count) - return -EBUSY; - - DBGINFO(("%s hdlcdev_attach\n", info->device_name)); - - switch (encoding) - { - case ENCODING_NRZ: new_encoding = HDLC_ENCODING_NRZ; break; - case ENCODING_NRZI: new_encoding = HDLC_ENCODING_NRZI_SPACE; break; - case ENCODING_FM_MARK: new_encoding = HDLC_ENCODING_BIPHASE_MARK; break; - case ENCODING_FM_SPACE: new_encoding = HDLC_ENCODING_BIPHASE_SPACE; break; - case ENCODING_MANCHESTER: new_encoding = HDLC_ENCODING_BIPHASE_LEVEL; break; - default: return -EINVAL; - } - - switch (parity) - { - case PARITY_NONE: new_crctype = HDLC_CRC_NONE; break; - case PARITY_CRC16_PR1_CCITT: new_crctype = HDLC_CRC_16_CCITT; break; - case PARITY_CRC32_PR1_CCITT: new_crctype = HDLC_CRC_32_CCITT; break; - default: return -EINVAL; - } - - info->params.encoding = new_encoding; - info->params.crc_type = new_crctype;; - - /* if network interface up, reprogram hardware */ - if (info->netcount) - program_hw(info); - - return 0; -} - -/** - * called by generic HDLC layer to send frame - * - * skb socket buffer containing HDLC frame - * dev pointer to network device structure - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct slgt_info *info = dev_to_port(dev); - struct net_device_stats *stats = hdlc_stats(dev); - unsigned long flags; - - DBGINFO(("%s hdlc_xmit\n", dev->name)); - - /* stop sending until this frame completes */ - netif_stop_queue(dev); - - /* copy data to device buffers */ - info->tx_count = skb->len; - tx_load(info, skb->data, skb->len); - - /* update network statistics */ - stats->tx_packets++; - stats->tx_bytes += skb->len; - - /* done with socket buffer, so free it */ - dev_kfree_skb(skb); - - /* save start time for transmit timeout detection */ - dev->trans_start = jiffies; - - /* start hardware transmitter if necessary */ - spin_lock_irqsave(&info->lock,flags); - if (!info->tx_active) - tx_start(info); - spin_unlock_irqrestore(&info->lock,flags); - - return 0; -} - -/** - * called by network layer when interface enabled - * claim resources and initialize hardware - * - * dev pointer to network device structure - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_open(struct net_device *dev) -{ - struct slgt_info *info = dev_to_port(dev); - int rc; - unsigned long flags; - - DBGINFO(("%s hdlcdev_open\n", dev->name)); - - /* generic HDLC layer open processing */ - if ((rc = hdlc_open(dev))) - return rc; - - /* arbitrate between network and tty opens */ - spin_lock_irqsave(&info->netlock, flags); - if (info->count != 0 || info->netcount != 0) { - DBGINFO(("%s hdlc_open busy\n", dev->name)); - spin_unlock_irqrestore(&info->netlock, flags); - return -EBUSY; - } - info->netcount=1; - spin_unlock_irqrestore(&info->netlock, flags); - - /* claim resources and init adapter */ - if ((rc = startup(info)) != 0) { - spin_lock_irqsave(&info->netlock, flags); - info->netcount=0; - spin_unlock_irqrestore(&info->netlock, flags); - return rc; - } - - /* assert DTR and RTS, apply hardware settings */ - info->signals |= SerialSignal_RTS + SerialSignal_DTR; - program_hw(info); - - /* enable network layer transmit */ - dev->trans_start = jiffies; - netif_start_queue(dev); - - /* inform generic HDLC layer of current DCD status */ - spin_lock_irqsave(&info->lock, flags); - get_signals(info); - spin_unlock_irqrestore(&info->lock, flags); - hdlc_set_carrier(info->signals & SerialSignal_DCD, dev); - - return 0; -} - -/** - * called by network layer when interface is disabled - * shutdown hardware and release resources - * - * dev pointer to network device structure - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_close(struct net_device *dev) -{ - struct slgt_info *info = dev_to_port(dev); - unsigned long flags; - - DBGINFO(("%s hdlcdev_close\n", dev->name)); - - netif_stop_queue(dev); - - /* shutdown adapter and release resources */ - shutdown(info); - - hdlc_close(dev); - - spin_lock_irqsave(&info->netlock, flags); - info->netcount=0; - spin_unlock_irqrestore(&info->netlock, flags); - - return 0; -} - -/** - * called by network layer to process IOCTL call to network device - * - * dev pointer to network device structure - * ifr pointer to network interface request structure - * cmd IOCTL command code - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - const size_t size = sizeof(sync_serial_settings); - sync_serial_settings new_line; - sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; - struct slgt_info *info = dev_to_port(dev); - unsigned int flags; - - DBGINFO(("%s hdlcdev_ioctl\n", dev->name)); - - /* return error if TTY interface open */ - if (info->count) - return -EBUSY; - - if (cmd != SIOCWANDEV) - return hdlc_ioctl(dev, ifr, cmd); - - switch(ifr->ifr_settings.type) { - case IF_GET_IFACE: /* return current sync_serial_settings */ - - ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; - if (ifr->ifr_settings.size < size) { - ifr->ifr_settings.size = size; /* data size wanted */ - return -ENOBUFS; - } - - flags = info->params.flags & (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | - HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | - HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | - HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); - - switch (flags){ - case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN): new_line.clock_type = CLOCK_EXT; break; - case (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_INT; break; - case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG): new_line.clock_type = CLOCK_TXINT; break; - case (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN): new_line.clock_type = CLOCK_TXFROMRX; break; - default: new_line.clock_type = CLOCK_DEFAULT; - } - - new_line.clock_rate = info->params.clock_speed; - new_line.loopback = info->params.loopback ? 1:0; - - if (copy_to_user(line, &new_line, size)) - return -EFAULT; - return 0; - - case IF_IFACE_SYNC_SERIAL: /* set sync_serial_settings */ - - if(!capable(CAP_NET_ADMIN)) - return -EPERM; - if (copy_from_user(&new_line, line, size)) - return -EFAULT; - - switch (new_line.clock_type) - { - case CLOCK_EXT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_TXCPIN; break; - case CLOCK_TXFROMRX: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_RXCPIN; break; - case CLOCK_INT: flags = HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG; break; - case CLOCK_TXINT: flags = HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_TXC_BRG; break; - case CLOCK_DEFAULT: flags = info->params.flags & - (HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | - HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | - HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | - HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); break; - default: return -EINVAL; - } - - if (new_line.loopback != 0 && new_line.loopback != 1) - return -EINVAL; - - info->params.flags &= ~(HDLC_FLAG_RXC_RXCPIN | HDLC_FLAG_RXC_DPLL | - HDLC_FLAG_RXC_BRG | HDLC_FLAG_RXC_TXCPIN | - HDLC_FLAG_TXC_TXCPIN | HDLC_FLAG_TXC_DPLL | - HDLC_FLAG_TXC_BRG | HDLC_FLAG_TXC_RXCPIN); - info->params.flags |= flags; - - info->params.loopback = new_line.loopback; - - if (flags & (HDLC_FLAG_RXC_BRG | HDLC_FLAG_TXC_BRG)) - info->params.clock_speed = new_line.clock_rate; - else - info->params.clock_speed = 0; - - /* if network interface up, reprogram hardware */ - if (info->netcount) - program_hw(info); - return 0; - - default: - return hdlc_ioctl(dev, ifr, cmd); - } -} - -/** - * called by network layer when transmit timeout is detected - * - * dev pointer to network device structure - */ -static void hdlcdev_tx_timeout(struct net_device *dev) -{ - struct slgt_info *info = dev_to_port(dev); - struct net_device_stats *stats = hdlc_stats(dev); - unsigned long flags; - - DBGINFO(("%s hdlcdev_tx_timeout\n", dev->name)); - - stats->tx_errors++; - stats->tx_aborted_errors++; - - spin_lock_irqsave(&info->lock,flags); - tx_stop(info); - spin_unlock_irqrestore(&info->lock,flags); - - netif_wake_queue(dev); -} - -/** - * called by device driver when transmit completes - * reenable network layer transmit if stopped - * - * info pointer to device instance information - */ -static void hdlcdev_tx_done(struct slgt_info *info) -{ - if (netif_queue_stopped(info->netdev)) - netif_wake_queue(info->netdev); -} - -/** - * called by device driver when frame received - * pass frame to network layer - * - * info pointer to device instance information - * buf pointer to buffer contianing frame data - * size count of data bytes in buf - */ -static void hdlcdev_rx(struct slgt_info *info, char *buf, int size) -{ - struct sk_buff *skb = dev_alloc_skb(size); - struct net_device *dev = info->netdev; - struct net_device_stats *stats = hdlc_stats(dev); - - DBGINFO(("%s hdlcdev_rx\n", dev->name)); - - if (skb == NULL) { - DBGERR(("%s: can't alloc skb, drop packet\n", dev->name)); - stats->rx_dropped++; - return; - } - - memcpy(skb_put(skb, size),buf,size); - - skb->protocol = hdlc_type_trans(skb, info->netdev); - - stats->rx_packets++; - stats->rx_bytes += size; - - netif_rx(skb); - - info->netdev->last_rx = jiffies; -} - -/** - * called by device driver when adding device instance - * do generic HDLC initialization - * - * info pointer to device instance information - * - * returns 0 if success, otherwise error code - */ -static int hdlcdev_init(struct slgt_info *info) -{ - int rc; - struct net_device *dev; - hdlc_device *hdlc; - - /* allocate and initialize network and HDLC layer objects */ - - if (!(dev = alloc_hdlcdev(info))) { - printk(KERN_ERR "%s hdlc device alloc failure\n", info->device_name); - return -ENOMEM; - } - - /* for network layer reporting purposes only */ - dev->mem_start = info->phys_reg_addr; - dev->mem_end = info->phys_reg_addr + SLGT_REG_SIZE - 1; - dev->irq = info->irq_level; - - /* network layer callbacks and settings */ - dev->do_ioctl = hdlcdev_ioctl; - dev->open = hdlcdev_open; - dev->stop = hdlcdev_close; - dev->tx_timeout = hdlcdev_tx_timeout; - dev->watchdog_timeo = 10*HZ; - dev->tx_queue_len = 50; - - /* generic HDLC layer callbacks and settings */ - hdlc = dev_to_hdlc(dev); - hdlc->attach = hdlcdev_attach; - hdlc->xmit = hdlcdev_xmit; - - /* register objects with HDLC layer */ - if ((rc = register_hdlc_device(dev))) { - printk(KERN_WARNING "%s:unable to register hdlc device\n",__FILE__); - free_netdev(dev); - return rc; - } - - info->netdev = dev; - return 0; -} - -/** - * called by device driver when removing device instance - * do generic HDLC cleanup - * - * info pointer to device instance information - */ -static void hdlcdev_exit(struct slgt_info *info) -{ - unregister_hdlc_device(info->netdev); - free_netdev(info->netdev); - info->netdev = NULL; -} - -#endif /* ifdef CONFIG_HDLC */ - -/* - * get async data from rx DMA buffers - */ -static void rx_async(struct slgt_info *info) -{ - struct tty_struct *tty = info->tty; - struct mgsl_icount *icount = &info->icount; - unsigned int start, end; - unsigned char *p; - unsigned char status; - struct slgt_desc *bufs = info->rbufs; - int i, count; - - start = end = info->rbuf_current; - - while(desc_complete(bufs[end])) { - count = desc_count(bufs[end]) - info->rbuf_index; - p = bufs[end].buf + info->rbuf_index; - - DBGISR(("%s rx_async count=%d\n", info->device_name, count)); - DBGDATA(info, p, count, "rx"); - - for(i=0 ; i < count; i+=2, p+=2) { - if (tty) { - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - tty_flip_buffer_push(tty); - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - break; - *tty->flip.char_buf_ptr = *p; - *tty->flip.flag_buf_ptr = 0; - } - icount->rx++; - - if ((status = *(p+1) & (BIT9 + BIT8))) { - if (status & BIT9) - icount->parity++; - else if (status & BIT8) - icount->frame++; - /* discard char if tty control flags say so */ - if (status & info->ignore_status_mask) - continue; - if (tty) { - if (status & BIT9) - *tty->flip.flag_buf_ptr = TTY_PARITY; - else if (status & BIT8) - *tty->flip.flag_buf_ptr = TTY_FRAME; - } - } - if (tty) { - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; - } - } - - if (i < count) { - /* receive buffer not completed */ - info->rbuf_index += i; - info->rx_timer.expires = jiffies + 1; - add_timer(&info->rx_timer); - break; - } - - info->rbuf_index = 0; - free_rbufs(info, end, end); - - if (++end == info->rbuf_count) - end = 0; - - /* if entire list searched then no frame available */ - if (end == start) - break; - } - - if (tty && tty->flip.count) - tty_flip_buffer_push(tty); -} - -/* - * return next bottom half action to perform - */ -static int bh_action(struct slgt_info *info) -{ - unsigned long flags; - int rc; - - spin_lock_irqsave(&info->lock,flags); - - if (info->pending_bh & BH_RECEIVE) { - info->pending_bh &= ~BH_RECEIVE; - rc = BH_RECEIVE; - } else if (info->pending_bh & BH_TRANSMIT) { - info->pending_bh &= ~BH_TRANSMIT; - rc = BH_TRANSMIT; - } else if (info->pending_bh & BH_STATUS) { - info->pending_bh &= ~BH_STATUS; - rc = BH_STATUS; - } else { - /* Mark BH routine as complete */ - info->bh_running = 0; - info->bh_requested = 0; - rc = 0; - } - - spin_unlock_irqrestore(&info->lock,flags); - - return rc; -} - -/* - * perform bottom half processing - */ -static void bh_handler(void* context) -{ - struct slgt_info *info = context; - int action; - - if (!info) - return; - info->bh_running = 1; - - while((action = bh_action(info))) { - switch (action) { - case BH_RECEIVE: - DBGBH(("%s bh receive\n", info->device_name)); - switch(info->params.mode) { - case MGSL_MODE_ASYNC: - rx_async(info); - break; - case MGSL_MODE_HDLC: - while(rx_get_frame(info)); - break; - case MGSL_MODE_RAW: - while(rx_get_buf(info)); - break; - } - /* restart receiver if rx DMA buffers exhausted */ - if (info->rx_restart) - rx_start(info); - break; - case BH_TRANSMIT: - bh_transmit(info); - break; - case BH_STATUS: - DBGBH(("%s bh status\n", info->device_name)); - info->ri_chkcount = 0; - info->dsr_chkcount = 0; - info->dcd_chkcount = 0; - info->cts_chkcount = 0; - break; - default: - DBGBH(("%s unknown action\n", info->device_name)); - break; - } - } - DBGBH(("%s bh_handler exit\n", info->device_name)); -} - -static void bh_transmit(struct slgt_info *info) -{ - struct tty_struct *tty = info->tty; - - DBGBH(("%s bh_transmit\n", info->device_name)); - if (tty) { - tty_wakeup(tty); - wake_up_interruptible(&tty->write_wait); - } -} - -static void dsr_change(struct slgt_info *info) -{ - get_signals(info); - DBGISR(("dsr_change %s signals=%04X\n", info->device_name, info->signals)); - if ((info->dsr_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { - slgt_irq_off(info, IRQ_DSR); - return; - } - info->icount.dsr++; - if (info->signals & SerialSignal_DSR) - info->input_signal_events.dsr_up++; - else - info->input_signal_events.dsr_down++; - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - info->pending_bh |= BH_STATUS; -} - -static void cts_change(struct slgt_info *info) -{ - get_signals(info); - DBGISR(("cts_change %s signals=%04X\n", info->device_name, info->signals)); - if ((info->cts_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { - slgt_irq_off(info, IRQ_CTS); - return; - } - info->icount.cts++; - if (info->signals & SerialSignal_CTS) - info->input_signal_events.cts_up++; - else - info->input_signal_events.cts_down++; - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - info->pending_bh |= BH_STATUS; - - if (info->flags & ASYNC_CTS_FLOW) { - if (info->tty) { - if (info->tty->hw_stopped) { - if (info->signals & SerialSignal_CTS) { - info->tty->hw_stopped = 0; - info->pending_bh |= BH_TRANSMIT; - return; - } - } else { - if (!(info->signals & SerialSignal_CTS)) - info->tty->hw_stopped = 1; - } - } - } -} - -static void dcd_change(struct slgt_info *info) -{ - get_signals(info); - DBGISR(("dcd_change %s signals=%04X\n", info->device_name, info->signals)); - if ((info->dcd_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { - slgt_irq_off(info, IRQ_DCD); - return; - } - info->icount.dcd++; - if (info->signals & SerialSignal_DCD) { - info->input_signal_events.dcd_up++; - } else { - info->input_signal_events.dcd_down++; - } -#ifdef CONFIG_HDLC - if (info->netcount) - hdlc_set_carrier(info->signals & SerialSignal_DCD, info->netdev); -#endif - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - info->pending_bh |= BH_STATUS; - - if (info->flags & ASYNC_CHECK_CD) { - if (info->signals & SerialSignal_DCD) - wake_up_interruptible(&info->open_wait); - else { - if (info->tty) - tty_hangup(info->tty); - } - } -} - -static void ri_change(struct slgt_info *info) -{ - get_signals(info); - DBGISR(("ri_change %s signals=%04X\n", info->device_name, info->signals)); - if ((info->ri_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { - slgt_irq_off(info, IRQ_RI); - return; - } - info->icount.dcd++; - if (info->signals & SerialSignal_RI) { - info->input_signal_events.ri_up++; - } else { - info->input_signal_events.ri_down++; - } - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - info->pending_bh |= BH_STATUS; -} - -static void isr_serial(struct slgt_info *info) -{ - unsigned short status = rd_reg16(info, SSR); - - DBGISR(("%s isr_serial status=%04X\n", info->device_name, status)); - - wr_reg16(info, SSR, status); /* clear pending */ - - info->irq_occurred = 1; - - if (info->params.mode == MGSL_MODE_ASYNC) { - if (status & IRQ_TXIDLE) { - if (info->tx_count) - isr_txeom(info, status); - } - if ((status & IRQ_RXBREAK) && (status & RXBREAK)) { - info->icount.brk++; - /* process break detection if tty control allows */ - if (info->tty) { - if (!(status & info->ignore_status_mask)) { - if (info->read_status_mask & MASK_BREAK) { - *info->tty->flip.flag_buf_ptr = TTY_BREAK; - if (info->flags & ASYNC_SAK) - do_SAK(info->tty); - } - } - } - } - } else { - if (status & (IRQ_TXIDLE + IRQ_TXUNDER)) - isr_txeom(info, status); - - if (status & IRQ_RXIDLE) { - if (status & RXIDLE) - info->icount.rxidle++; - else - info->icount.exithunt++; - wake_up_interruptible(&info->event_wait_q); - } - - if (status & IRQ_RXOVER) - rx_start(info); - } - - if (status & IRQ_DSR) - dsr_change(info); - if (status & IRQ_CTS) - cts_change(info); - if (status & IRQ_DCD) - dcd_change(info); - if (status & IRQ_RI) - ri_change(info); -} - -static void isr_rdma(struct slgt_info *info) -{ - unsigned int status = rd_reg32(info, RDCSR); - - DBGISR(("%s isr_rdma status=%08x\n", info->device_name, status)); - - /* RDCSR (rx DMA control/status) - * - * 31..07 reserved - * 06 save status byte to DMA buffer - * 05 error - * 04 eol (end of list) - * 03 eob (end of buffer) - * 02 IRQ enable - * 01 reset - * 00 enable - */ - wr_reg32(info, RDCSR, status); /* clear pending */ - - if (status & (BIT5 + BIT4)) { - DBGISR(("%s isr_rdma rx_restart=1\n", info->device_name)); - info->rx_restart = 1; - } - info->pending_bh |= BH_RECEIVE; -} - -static void isr_tdma(struct slgt_info *info) -{ - unsigned int status = rd_reg32(info, TDCSR); - - DBGISR(("%s isr_tdma status=%08x\n", info->device_name, status)); - - /* TDCSR (tx DMA control/status) - * - * 31..06 reserved - * 05 error - * 04 eol (end of list) - * 03 eob (end of buffer) - * 02 IRQ enable - * 01 reset - * 00 enable - */ - wr_reg32(info, TDCSR, status); /* clear pending */ - - if (status & (BIT5 + BIT4 + BIT3)) { - // another transmit buffer has completed - // run bottom half to get more send data from user - info->pending_bh |= BH_TRANSMIT; - } -} - -static void isr_txeom(struct slgt_info *info, unsigned short status) -{ - DBGISR(("%s txeom status=%04x\n", info->device_name, status)); - - slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); - tdma_reset(info); - reset_tbufs(info); - if (status & IRQ_TXUNDER) { - unsigned short val = rd_reg16(info, TCR); - wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ - wr_reg16(info, TCR, val); /* clear reset bit */ - } - - if (info->tx_active) { - if (info->params.mode != MGSL_MODE_ASYNC) { - if (status & IRQ_TXUNDER) - info->icount.txunder++; - else if (status & IRQ_TXIDLE) - info->icount.txok++; - } - - info->tx_active = 0; - info->tx_count = 0; - - del_timer(&info->tx_timer); - - if (info->params.mode != MGSL_MODE_ASYNC && info->drop_rts_on_tx_done) { - info->signals &= ~SerialSignal_RTS; - info->drop_rts_on_tx_done = 0; - set_signals(info); - } - -#ifdef CONFIG_HDLC - if (info->netcount) - hdlcdev_tx_done(info); - else -#endif - { - if (info->tty && (info->tty->stopped || info->tty->hw_stopped)) { - tx_stop(info); - return; - } - info->pending_bh |= BH_TRANSMIT; - } - } -} - -/* interrupt service routine - * - * irq interrupt number - * dev_id device ID supplied during interrupt registration - * regs interrupted processor context - */ -static irqreturn_t slgt_interrupt(int irq, void *dev_id, struct pt_regs * regs) -{ - struct slgt_info *info; - unsigned int gsr; - unsigned int i; - - DBGISR(("slgt_interrupt irq=%d entry\n", irq)); - - info = dev_id; - if (!info) - return IRQ_NONE; - - spin_lock(&info->lock); - - while((gsr = rd_reg32(info, GSR) & 0xffffff00)) { - DBGISR(("%s gsr=%08x\n", info->device_name, gsr)); - info->irq_occurred = 1; - for(i=0; i < info->port_count ; i++) { - if (info->port_array[i] == NULL) - continue; - if (gsr & (BIT8 << i)) - isr_serial(info->port_array[i]); - if (gsr & (BIT16 << (i*2))) - isr_rdma(info->port_array[i]); - if (gsr & (BIT17 << (i*2))) - isr_tdma(info->port_array[i]); - } - } - - for(i=0; i < info->port_count ; i++) { - struct slgt_info *port = info->port_array[i]; - - if (port && (port->count || port->netcount) && - port->pending_bh && !port->bh_running && - !port->bh_requested) { - DBGISR(("%s bh queued\n", port->device_name)); - schedule_work(&port->task); - port->bh_requested = 1; - } - } - - spin_unlock(&info->lock); - - DBGISR(("slgt_interrupt irq=%d exit\n", irq)); - return IRQ_HANDLED; -} - -static int startup(struct slgt_info *info) -{ - DBGINFO(("%s startup\n", info->device_name)); - - if (info->flags & ASYNC_INITIALIZED) - return 0; - - if (!info->tx_buf) { - info->tx_buf = kmalloc(info->max_frame_size, GFP_KERNEL); - if (!info->tx_buf) { - DBGERR(("%s can't allocate tx buffer\n", info->device_name)); - return -ENOMEM; - } - } - - info->pending_bh = 0; - - memset(&info->icount, 0, sizeof(info->icount)); - - /* program hardware for current parameters */ - change_params(info); - - if (info->tty) - clear_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags |= ASYNC_INITIALIZED; - - return 0; -} - -/* - * called by close() and hangup() to shutdown hardware - */ -static void shutdown(struct slgt_info *info) -{ - unsigned long flags; - - if (!(info->flags & ASYNC_INITIALIZED)) - return; - - DBGINFO(("%s shutdown\n", info->device_name)); - - /* clear status wait queue because status changes */ - /* can't happen after shutting down the hardware */ - wake_up_interruptible(&info->status_event_wait_q); - wake_up_interruptible(&info->event_wait_q); - - del_timer_sync(&info->tx_timer); - del_timer_sync(&info->rx_timer); - - kfree(info->tx_buf); - info->tx_buf = NULL; - - spin_lock_irqsave(&info->lock,flags); - - tx_stop(info); - rx_stop(info); - - slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); - - if (!info->tty || info->tty->termios->c_cflag & HUPCL) { - info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); - set_signals(info); - } - - spin_unlock_irqrestore(&info->lock,flags); - - if (info->tty) - set_bit(TTY_IO_ERROR, &info->tty->flags); - - info->flags &= ~ASYNC_INITIALIZED; -} - -static void program_hw(struct slgt_info *info) -{ - unsigned long flags; - - spin_lock_irqsave(&info->lock,flags); - - rx_stop(info); - tx_stop(info); - - if (info->params.mode == MGSL_MODE_HDLC || - info->params.mode == MGSL_MODE_RAW || - info->netcount) - hdlc_mode(info); - else - async_mode(info); - - set_signals(info); - - info->dcd_chkcount = 0; - info->cts_chkcount = 0; - info->ri_chkcount = 0; - info->dsr_chkcount = 0; - - slgt_irq_on(info, IRQ_DCD | IRQ_CTS | IRQ_DSR); - get_signals(info); - - if (info->netcount || - (info->tty && info->tty->termios->c_cflag & CREAD)) - rx_start(info); - - spin_unlock_irqrestore(&info->lock,flags); -} - -/* - * reconfigure adapter based on new parameters - */ -static void change_params(struct slgt_info *info) -{ - unsigned cflag; - int bits_per_char; - - if (!info->tty || !info->tty->termios) - return; - DBGINFO(("%s change_params\n", info->device_name)); - - cflag = info->tty->termios->c_cflag; - - /* if B0 rate (hangup) specified then negate DTR and RTS */ - /* otherwise assert DTR and RTS */ - if (cflag & CBAUD) - info->signals |= SerialSignal_RTS + SerialSignal_DTR; - else - info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); - - /* byte size and parity */ - - switch (cflag & CSIZE) { - case CS5: info->params.data_bits = 5; break; - case CS6: info->params.data_bits = 6; break; - case CS7: info->params.data_bits = 7; break; - case CS8: info->params.data_bits = 8; break; - default: info->params.data_bits = 7; break; - } - - info->params.stop_bits = (cflag & CSTOPB) ? 2 : 1; - - if (cflag & PARENB) - info->params.parity = (cflag & PARODD) ? ASYNC_PARITY_ODD : ASYNC_PARITY_EVEN; - else - info->params.parity = ASYNC_PARITY_NONE; - - /* calculate number of jiffies to transmit a full - * FIFO (32 bytes) at specified data rate - */ - bits_per_char = info->params.data_bits + - info->params.stop_bits + 1; - - info->params.data_rate = tty_get_baud_rate(info->tty); - - if (info->params.data_rate) { - info->timeout = (32*HZ*bits_per_char) / - info->params.data_rate; - } - info->timeout += HZ/50; /* Add .02 seconds of slop */ - - if (cflag & CRTSCTS) - info->flags |= ASYNC_CTS_FLOW; - else - info->flags &= ~ASYNC_CTS_FLOW; - - if (cflag & CLOCAL) - info->flags &= ~ASYNC_CHECK_CD; - else - info->flags |= ASYNC_CHECK_CD; - - /* process tty input control flags */ - - info->read_status_mask = IRQ_RXOVER; - if (I_INPCK(info->tty)) - info->read_status_mask |= MASK_PARITY | MASK_FRAMING; - if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) - info->read_status_mask |= MASK_BREAK; - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= MASK_PARITY | MASK_FRAMING; - if (I_IGNBRK(info->tty)) { - info->ignore_status_mask |= MASK_BREAK; - /* If ignoring parity and break indicators, ignore - * overruns too. (For real raw support). - */ - if (I_IGNPAR(info->tty)) - info->ignore_status_mask |= MASK_OVERRUN; - } - - program_hw(info); -} - -static int get_stats(struct slgt_info *info, struct mgsl_icount __user *user_icount) -{ - DBGINFO(("%s get_stats\n", info->device_name)); - if (!user_icount) { - memset(&info->icount, 0, sizeof(info->icount)); - } else { - if (copy_to_user(user_icount, &info->icount, sizeof(struct mgsl_icount))) - return -EFAULT; - } - return 0; -} - -static int get_params(struct slgt_info *info, MGSL_PARAMS __user *user_params) -{ - DBGINFO(("%s get_params\n", info->device_name)); - if (copy_to_user(user_params, &info->params, sizeof(MGSL_PARAMS))) - return -EFAULT; - return 0; -} - -static int set_params(struct slgt_info *info, MGSL_PARAMS __user *new_params) -{ - unsigned long flags; - MGSL_PARAMS tmp_params; - - DBGINFO(("%s set_params\n", info->device_name)); - if (copy_from_user(&tmp_params, new_params, sizeof(MGSL_PARAMS))) - return -EFAULT; - - spin_lock_irqsave(&info->lock, flags); - memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS)); - spin_unlock_irqrestore(&info->lock, flags); - - change_params(info); - - return 0; -} - -static int get_txidle(struct slgt_info *info, int __user *idle_mode) -{ - DBGINFO(("%s get_txidle=%d\n", info->device_name, info->idle_mode)); - if (put_user(info->idle_mode, idle_mode)) - return -EFAULT; - return 0; -} - -static int set_txidle(struct slgt_info *info, int idle_mode) -{ - unsigned long flags; - DBGINFO(("%s set_txidle(%d)\n", info->device_name, idle_mode)); - spin_lock_irqsave(&info->lock,flags); - info->idle_mode = idle_mode; - tx_set_idle(info); - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -static int tx_enable(struct slgt_info *info, int enable) -{ - unsigned long flags; - DBGINFO(("%s tx_enable(%d)\n", info->device_name, enable)); - spin_lock_irqsave(&info->lock,flags); - if (enable) { - if (!info->tx_enabled) - tx_start(info); - } else { - if (info->tx_enabled) - tx_stop(info); - } - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -/* - * abort transmit HDLC frame - */ -static int tx_abort(struct slgt_info *info) -{ - unsigned long flags; - DBGINFO(("%s tx_abort\n", info->device_name)); - spin_lock_irqsave(&info->lock,flags); - tdma_reset(info); - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -static int rx_enable(struct slgt_info *info, int enable) -{ - unsigned long flags; - DBGINFO(("%s rx_enable(%d)\n", info->device_name, enable)); - spin_lock_irqsave(&info->lock,flags); - if (enable) { - if (!info->rx_enabled) - rx_start(info); - } else { - if (info->rx_enabled) - rx_stop(info); - } - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -/* - * wait for specified event to occur - */ -static int wait_mgsl_event(struct slgt_info *info, int __user *mask_ptr) -{ - unsigned long flags; - int s; - int rc=0; - struct mgsl_icount cprev, cnow; - int events; - int mask; - struct _input_signal_events oldsigs, newsigs; - DECLARE_WAITQUEUE(wait, current); - - if (get_user(mask, mask_ptr)) - return -EFAULT; - - DBGINFO(("%s wait_mgsl_event(%d)\n", info->device_name, mask)); - - spin_lock_irqsave(&info->lock,flags); - - /* return immediately if state matches requested events */ - get_signals(info); - s = info->signals; - - events = mask & - ( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) + - ((s & SerialSignal_DCD) ? MgslEvent_DcdActive:MgslEvent_DcdInactive) + - ((s & SerialSignal_CTS) ? MgslEvent_CtsActive:MgslEvent_CtsInactive) + - ((s & SerialSignal_RI) ? MgslEvent_RiActive :MgslEvent_RiInactive) ); - if (events) { - spin_unlock_irqrestore(&info->lock,flags); - goto exit; - } - - /* save current irq counts */ - cprev = info->icount; - oldsigs = info->input_signal_events; - - /* enable hunt and idle irqs if needed */ - if (mask & (MgslEvent_ExitHuntMode+MgslEvent_IdleReceived)) { - unsigned short val = rd_reg16(info, SCR); - if (!(val & IRQ_RXIDLE)) - wr_reg16(info, SCR, (unsigned short)(val | IRQ_RXIDLE)); - } - - set_current_state(TASK_INTERRUPTIBLE); - add_wait_queue(&info->event_wait_q, &wait); - - spin_unlock_irqrestore(&info->lock,flags); - - for(;;) { - schedule(); - if (signal_pending(current)) { - rc = -ERESTARTSYS; - break; - } - - /* get current irq counts */ - spin_lock_irqsave(&info->lock,flags); - cnow = info->icount; - newsigs = info->input_signal_events; - set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&info->lock,flags); - - /* if no change, wait aborted for some reason */ - if (newsigs.dsr_up == oldsigs.dsr_up && - newsigs.dsr_down == oldsigs.dsr_down && - newsigs.dcd_up == oldsigs.dcd_up && - newsigs.dcd_down == oldsigs.dcd_down && - newsigs.cts_up == oldsigs.cts_up && - newsigs.cts_down == oldsigs.cts_down && - newsigs.ri_up == oldsigs.ri_up && - newsigs.ri_down == oldsigs.ri_down && - cnow.exithunt == cprev.exithunt && - cnow.rxidle == cprev.rxidle) { - rc = -EIO; - break; - } - - events = mask & - ( (newsigs.dsr_up != oldsigs.dsr_up ? MgslEvent_DsrActive:0) + - (newsigs.dsr_down != oldsigs.dsr_down ? MgslEvent_DsrInactive:0) + - (newsigs.dcd_up != oldsigs.dcd_up ? MgslEvent_DcdActive:0) + - (newsigs.dcd_down != oldsigs.dcd_down ? MgslEvent_DcdInactive:0) + - (newsigs.cts_up != oldsigs.cts_up ? MgslEvent_CtsActive:0) + - (newsigs.cts_down != oldsigs.cts_down ? MgslEvent_CtsInactive:0) + - (newsigs.ri_up != oldsigs.ri_up ? MgslEvent_RiActive:0) + - (newsigs.ri_down != oldsigs.ri_down ? MgslEvent_RiInactive:0) + - (cnow.exithunt != cprev.exithunt ? MgslEvent_ExitHuntMode:0) + - (cnow.rxidle != cprev.rxidle ? MgslEvent_IdleReceived:0) ); - if (events) - break; - - cprev = cnow; - oldsigs = newsigs; - } - - remove_wait_queue(&info->event_wait_q, &wait); - set_current_state(TASK_RUNNING); - - - if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) { - spin_lock_irqsave(&info->lock,flags); - if (!waitqueue_active(&info->event_wait_q)) { - /* disable enable exit hunt mode/idle rcvd IRQs */ - wr_reg16(info, SCR, - (unsigned short)(rd_reg16(info, SCR) & ~IRQ_RXIDLE)); - } - spin_unlock_irqrestore(&info->lock,flags); - } -exit: - if (rc == 0) - rc = put_user(events, mask_ptr); - return rc; -} - -static int get_interface(struct slgt_info *info, int __user *if_mode) -{ - DBGINFO(("%s get_interface=%x\n", info->device_name, info->if_mode)); - if (put_user(info->if_mode, if_mode)) - return -EFAULT; - return 0; -} - -static int set_interface(struct slgt_info *info, int if_mode) -{ - unsigned long flags; - unsigned char val; - - DBGINFO(("%s set_interface=%x)\n", info->device_name, if_mode)); - spin_lock_irqsave(&info->lock,flags); - info->if_mode = if_mode; - - msc_set_vcr(info); - - /* TCR (tx control) 07 1=RTS driver control */ - val = rd_reg16(info, TCR); - if (info->if_mode & MGSL_INTERFACE_RTS_EN) - val |= BIT7; - else - val &= ~BIT7; - wr_reg16(info, TCR, val); - - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -static int modem_input_wait(struct slgt_info *info,int arg) -{ - unsigned long flags; - int rc; - struct mgsl_icount cprev, cnow; - DECLARE_WAITQUEUE(wait, current); - - /* save current irq counts */ - spin_lock_irqsave(&info->lock,flags); - cprev = info->icount; - add_wait_queue(&info->status_event_wait_q, &wait); - set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&info->lock,flags); - - for(;;) { - schedule(); - if (signal_pending(current)) { - rc = -ERESTARTSYS; - break; - } - - /* get new irq counts */ - spin_lock_irqsave(&info->lock,flags); - cnow = info->icount; - set_current_state(TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&info->lock,flags); - - /* if no change, wait aborted for some reason */ - if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && - cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { - rc = -EIO; - break; - } - - /* check for change in caller specified modem input */ - if ((arg & TIOCM_RNG && cnow.rng != cprev.rng) || - (arg & TIOCM_DSR && cnow.dsr != cprev.dsr) || - (arg & TIOCM_CD && cnow.dcd != cprev.dcd) || - (arg & TIOCM_CTS && cnow.cts != cprev.cts)) { - rc = 0; - break; - } - - cprev = cnow; - } - remove_wait_queue(&info->status_event_wait_q, &wait); - set_current_state(TASK_RUNNING); - return rc; -} - -/* - * return state of serial control and status signals - */ -static int tiocmget(struct tty_struct *tty, struct file *file) -{ - struct slgt_info *info = tty->driver_data; - unsigned int result; - unsigned long flags; - - spin_lock_irqsave(&info->lock,flags); - get_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - - result = ((info->signals & SerialSignal_RTS) ? TIOCM_RTS:0) + - ((info->signals & SerialSignal_DTR) ? TIOCM_DTR:0) + - ((info->signals & SerialSignal_DCD) ? TIOCM_CAR:0) + - ((info->signals & SerialSignal_RI) ? TIOCM_RNG:0) + - ((info->signals & SerialSignal_DSR) ? TIOCM_DSR:0) + - ((info->signals & SerialSignal_CTS) ? TIOCM_CTS:0); - - DBGINFO(("%s tiocmget value=%08X\n", info->device_name, result)); - return result; -} - -/* - * set modem control signals (DTR/RTS) - * - * cmd signal command: TIOCMBIS = set bit TIOCMBIC = clear bit - * TIOCMSET = set/clear signal values - * value bit mask for command - */ -static int tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) -{ - struct slgt_info *info = tty->driver_data; - unsigned long flags; - - DBGINFO(("%s tiocmset(%x,%x)\n", info->device_name, set, clear)); - - if (set & TIOCM_RTS) - info->signals |= SerialSignal_RTS; - if (set & TIOCM_DTR) - info->signals |= SerialSignal_DTR; - if (clear & TIOCM_RTS) - info->signals &= ~SerialSignal_RTS; - if (clear & TIOCM_DTR) - info->signals &= ~SerialSignal_DTR; - - spin_lock_irqsave(&info->lock,flags); - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - return 0; -} - -/* - * block current process until the device is ready to open - */ -static int block_til_ready(struct tty_struct *tty, struct file *filp, - struct slgt_info *info) -{ - DECLARE_WAITQUEUE(wait, current); - int retval; - int do_clocal = 0, extra_count = 0; - unsigned long flags; - - DBGINFO(("%s block_til_ready\n", tty->driver->name)); - - if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ - /* nonblock mode is set or port is not enabled */ - info->flags |= ASYNC_NORMAL_ACTIVE; - return 0; - } - - if (tty->termios->c_cflag & CLOCAL) - do_clocal = 1; - - /* Wait for carrier detect and the line to become - * free (i.e., not in use by the callout). While we are in - * this loop, info->count is dropped by one, so that - * close() knows when to free things. We restore it upon - * exit, either normal or abnormal. - */ - - retval = 0; - add_wait_queue(&info->open_wait, &wait); - - spin_lock_irqsave(&info->lock, flags); - if (!tty_hung_up_p(filp)) { - extra_count = 1; - info->count--; - } - spin_unlock_irqrestore(&info->lock, flags); - info->blocked_open++; - - while (1) { - if ((tty->termios->c_cflag & CBAUD)) { - spin_lock_irqsave(&info->lock,flags); - info->signals |= SerialSignal_RTS + SerialSignal_DTR; - set_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - } - - set_current_state(TASK_INTERRUPTIBLE); - - if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)){ - retval = (info->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS; - break; - } - - spin_lock_irqsave(&info->lock,flags); - get_signals(info); - spin_unlock_irqrestore(&info->lock,flags); - - if (!(info->flags & ASYNC_CLOSING) && - (do_clocal || (info->signals & SerialSignal_DCD)) ) { - break; - } - - if (signal_pending(current)) { - retval = -ERESTARTSYS; - break; - } - - DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); - schedule(); - } - - set_current_state(TASK_RUNNING); - remove_wait_queue(&info->open_wait, &wait); - - if (extra_count) - info->count++; - info->blocked_open--; - - if (!retval) - info->flags |= ASYNC_NORMAL_ACTIVE; - - DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval)); - return retval; -} - -static int alloc_tmp_rbuf(struct slgt_info *info) -{ - info->tmp_rbuf = kmalloc(info->max_frame_size, GFP_KERNEL); - if (info->tmp_rbuf == NULL) - return -ENOMEM; - return 0; -} - -static void free_tmp_rbuf(struct slgt_info *info) -{ - kfree(info->tmp_rbuf); - info->tmp_rbuf = NULL; -} - -/* - * allocate DMA descriptor lists. - */ -static int alloc_desc(struct slgt_info *info) -{ - unsigned int i; - unsigned int pbufs; - - /* allocate memory to hold descriptor lists */ - info->bufs = pci_alloc_consistent(info->pdev, DESC_LIST_SIZE, &info->bufs_dma_addr); - if (info->bufs == NULL) - return -ENOMEM; - - memset(info->bufs, 0, DESC_LIST_SIZE); - - info->rbufs = (struct slgt_desc*)info->bufs; - info->tbufs = ((struct slgt_desc*)info->bufs) + info->rbuf_count; - - pbufs = (unsigned int)info->bufs_dma_addr; - - /* - * Build circular lists of descriptors - */ - - for (i=0; i < info->rbuf_count; i++) { - /* physical address of this descriptor */ - info->rbufs[i].pdesc = pbufs + (i * sizeof(struct slgt_desc)); - - /* physical address of next descriptor */ - if (i == info->rbuf_count - 1) - info->rbufs[i].next = cpu_to_le32(pbufs); - else - info->rbufs[i].next = cpu_to_le32(pbufs + ((i+1) * sizeof(struct slgt_desc))); - set_desc_count(info->rbufs[i], DMABUFSIZE); - } - - for (i=0; i < info->tbuf_count; i++) { - /* physical address of this descriptor */ - info->tbufs[i].pdesc = pbufs + ((info->rbuf_count + i) * sizeof(struct slgt_desc)); - - /* physical address of next descriptor */ - if (i == info->tbuf_count - 1) - info->tbufs[i].next = cpu_to_le32(pbufs + info->rbuf_count * sizeof(struct slgt_desc)); - else - info->tbufs[i].next = cpu_to_le32(pbufs + ((info->rbuf_count + i + 1) * sizeof(struct slgt_desc))); - } - - return 0; -} - -static void free_desc(struct slgt_info *info) -{ - if (info->bufs != NULL) { - pci_free_consistent(info->pdev, DESC_LIST_SIZE, info->bufs, info->bufs_dma_addr); - info->bufs = NULL; - info->rbufs = NULL; - info->tbufs = NULL; - } -} - -static int alloc_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count) -{ - int i; - for (i=0; i < count; i++) { - if ((bufs[i].buf = pci_alloc_consistent(info->pdev, DMABUFSIZE, &bufs[i].buf_dma_addr)) == NULL) - return -ENOMEM; - bufs[i].pbuf = cpu_to_le32((unsigned int)bufs[i].buf_dma_addr); - } - return 0; -} - -static void free_bufs(struct slgt_info *info, struct slgt_desc *bufs, int count) -{ - int i; - for (i=0; i < count; i++) { - if (bufs[i].buf == NULL) - continue; - pci_free_consistent(info->pdev, DMABUFSIZE, bufs[i].buf, bufs[i].buf_dma_addr); - bufs[i].buf = NULL; - } -} - -static int alloc_dma_bufs(struct slgt_info *info) -{ - info->rbuf_count = 32; - info->tbuf_count = 32; - - if (alloc_desc(info) < 0 || - alloc_bufs(info, info->rbufs, info->rbuf_count) < 0 || - alloc_bufs(info, info->tbufs, info->tbuf_count) < 0 || - alloc_tmp_rbuf(info) < 0) { - DBGERR(("%s DMA buffer alloc fail\n", info->device_name)); - return -ENOMEM; - } - reset_rbufs(info); - return 0; -} - -static void free_dma_bufs(struct slgt_info *info) -{ - if (info->bufs) { - free_bufs(info, info->rbufs, info->rbuf_count); - free_bufs(info, info->tbufs, info->tbuf_count); - free_desc(info); - } - free_tmp_rbuf(info); -} - -static int claim_resources(struct slgt_info *info) -{ - if (request_mem_region(info->phys_reg_addr, SLGT_REG_SIZE, "synclink_gt") == NULL) { - DBGERR(("%s reg addr conflict, addr=%08X\n", - info->device_name, info->phys_reg_addr)); - info->init_error = DiagStatus_AddressConflict; - goto errout; - } - else - info->reg_addr_requested = 1; - - info->reg_addr = ioremap(info->phys_reg_addr, PAGE_SIZE); - if (!info->reg_addr) { - DBGERR(("%s cant map device registers, addr=%08X\n", - info->device_name, info->phys_reg_addr)); - info->init_error = DiagStatus_CantAssignPciResources; - goto errout; - } - info->reg_addr += info->reg_offset; - return 0; - -errout: - release_resources(info); - return -ENODEV; -} - -static void release_resources(struct slgt_info *info) -{ - if (info->irq_requested) { - free_irq(info->irq_level, info); - info->irq_requested = 0; - } - - if (info->reg_addr_requested) { - release_mem_region(info->phys_reg_addr, SLGT_REG_SIZE); - info->reg_addr_requested = 0; - } - - if (info->reg_addr) { - iounmap(info->reg_addr - info->reg_offset); - info->reg_addr = NULL; - } -} - -/* Add the specified device instance data structure to the - * global linked list of devices and increment the device count. - */ -static void add_device(struct slgt_info *info) -{ - char *devstr; - - info->next_device = NULL; - info->line = slgt_device_count; - sprintf(info->device_name, "%s%d", tty_dev_prefix, info->line); - - if (info->line < MAX_DEVICES) { - if (maxframe[info->line]) - info->max_frame_size = maxframe[info->line]; - info->dosyncppp = dosyncppp[info->line]; - } - - slgt_device_count++; - - if (!slgt_device_list) - slgt_device_list = info; - else { - struct slgt_info *current_dev = slgt_device_list; - while(current_dev->next_device) - current_dev = current_dev->next_device; - current_dev->next_device = info; - } - - if (info->max_frame_size < 4096) - info->max_frame_size = 4096; - else if (info->max_frame_size > 65535) - info->max_frame_size = 65535; - - switch(info->pdev->device) { - case SYNCLINK_GT_DEVICE_ID: - devstr = "GT"; - break; - case SYNCLINK_GT4_DEVICE_ID: - devstr = "GT4"; - break; - case SYNCLINK_AC_DEVICE_ID: - devstr = "AC"; - info->params.mode = MGSL_MODE_ASYNC; - break; - default: - devstr = "(unknown model)"; - } - printk("SyncLink %s %s IO=%08x IRQ=%d MaxFrameSize=%u\n", - devstr, info->device_name, info->phys_reg_addr, - info->irq_level, info->max_frame_size); - -#ifdef CONFIG_HDLC - hdlcdev_init(info); -#endif -} - -/* - * allocate device instance structure, return NULL on failure - */ -static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev) -{ - struct slgt_info *info; - - info = kmalloc(sizeof(struct slgt_info), GFP_KERNEL); - - if (!info) { - DBGERR(("%s device alloc failed adapter=%d port=%d\n", - driver_name, adapter_num, port_num)); - } else { - memset(info, 0, sizeof(struct slgt_info)); - info->magic = MGSL_MAGIC; - INIT_WORK(&info->task, bh_handler, info); - info->max_frame_size = 4096; - info->raw_rx_size = DMABUFSIZE; - info->close_delay = 5*HZ/10; - info->closing_wait = 30*HZ; - init_waitqueue_head(&info->open_wait); - init_waitqueue_head(&info->close_wait); - init_waitqueue_head(&info->status_event_wait_q); - init_waitqueue_head(&info->event_wait_q); - spin_lock_init(&info->netlock); - memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS)); - info->idle_mode = HDLC_TXIDLE_FLAGS; - info->adapter_num = adapter_num; - info->port_num = port_num; - - init_timer(&info->tx_timer); - info->tx_timer.data = (unsigned long)info; - info->tx_timer.function = tx_timeout; - - init_timer(&info->rx_timer); - info->rx_timer.data = (unsigned long)info; - info->rx_timer.function = rx_timeout; - - /* Copy configuration info to device instance data */ - info->pdev = pdev; - info->irq_level = pdev->irq; - info->phys_reg_addr = pci_resource_start(pdev,0); - - /* veremap works on page boundaries - * map full page starting at the page boundary - */ - info->reg_offset = info->phys_reg_addr & (PAGE_SIZE-1); - info->phys_reg_addr &= ~(PAGE_SIZE-1); - - info->bus_type = MGSL_BUS_TYPE_PCI; - info->irq_flags = SA_SHIRQ; - - info->init_error = -1; /* assume error, set to 0 on successful init */ - } - - return info; -} - -static void device_init(int adapter_num, struct pci_dev *pdev) -{ - struct slgt_info *port_array[SLGT_MAX_PORTS]; - int i; - int port_count = 1; - - if (pdev->device == SYNCLINK_GT4_DEVICE_ID) - port_count = 4; - - /* allocate device instances for all ports */ - for (i=0; i < port_count; ++i) { - port_array[i] = alloc_dev(adapter_num, i, pdev); - if (port_array[i] == NULL) { - for (--i; i >= 0; --i) - kfree(port_array[i]); - return; - } - } - - /* give copy of port_array to all ports and add to device list */ - for (i=0; i < port_count; ++i) { - memcpy(port_array[i]->port_array, port_array, sizeof(port_array)); - add_device(port_array[i]); - port_array[i]->port_count = port_count; - spin_lock_init(&port_array[i]->lock); - } - - /* Allocate and claim adapter resources */ - if (!claim_resources(port_array[0])) { - - alloc_dma_bufs(port_array[0]); - - /* copy resource information from first port to others */ - for (i = 1; i < port_count; ++i) { - port_array[i]->lock = port_array[0]->lock; - port_array[i]->irq_level = port_array[0]->irq_level; - port_array[i]->reg_addr = port_array[0]->reg_addr; - alloc_dma_bufs(port_array[i]); - } - - if (request_irq(port_array[0]->irq_level, - slgt_interrupt, - port_array[0]->irq_flags, - port_array[0]->device_name, - port_array[0]) < 0) { - DBGERR(("%s request_irq failed IRQ=%d\n", - port_array[0]->device_name, - port_array[0]->irq_level)); - } else { - port_array[0]->irq_requested = 1; - adapter_test(port_array[0]); - for (i=1 ; i < port_count ; i++) - port_array[i]->init_error = port_array[0]->init_error; - } - } -} - -static int __devinit init_one(struct pci_dev *dev, - const struct pci_device_id *ent) -{ - if (pci_enable_device(dev)) { - printk("error enabling pci device %p\n", dev); - return -EIO; - } - pci_set_master(dev); - device_init(slgt_device_count, dev); - return 0; -} - -static void __devexit remove_one(struct pci_dev *dev) -{ -} - -static struct tty_operations ops = { - .open = open, - .close = close, - .write = write, - .put_char = put_char, - .flush_chars = flush_chars, - .write_room = write_room, - .chars_in_buffer = chars_in_buffer, - .flush_buffer = flush_buffer, - .ioctl = ioctl, - .throttle = throttle, - .unthrottle = unthrottle, - .send_xchar = send_xchar, - .break_ctl = set_break, - .wait_until_sent = wait_until_sent, - .read_proc = read_proc, - .set_termios = set_termios, - .stop = tx_hold, - .start = tx_release, - .hangup = hangup, - .tiocmget = tiocmget, - .tiocmset = tiocmset, -}; - -static void slgt_cleanup(void) -{ - int rc; - struct slgt_info *info; - struct slgt_info *tmp; - - printk("unload %s %s\n", driver_name, driver_version); - - if (serial_driver) { - if ((rc = tty_unregister_driver(serial_driver))) - DBGERR(("tty_unregister_driver error=%d\n", rc)); - put_tty_driver(serial_driver); - } - - /* reset devices */ - info = slgt_device_list; - while(info) { - reset_port(info); - info = info->next_device; - } - - /* release devices */ - info = slgt_device_list; - while(info) { -#ifdef CONFIG_HDLC - hdlcdev_exit(info); -#endif - free_dma_bufs(info); - free_tmp_rbuf(info); - if (info->port_num == 0) - release_resources(info); - tmp = info; - info = info->next_device; - kfree(tmp); - } - - if (pci_registered) - pci_unregister_driver(&pci_driver); -} - -/* - * Driver initialization entry point. - */ -static int __init slgt_init(void) -{ - int rc; - - printk("%s %s\n", driver_name, driver_version); - - slgt_device_count = 0; - if ((rc = pci_register_driver(&pci_driver)) < 0) { - printk("%s pci_register_driver error=%d\n", driver_name, rc); - return rc; - } - pci_registered = 1; - - if (!slgt_device_list) { - printk("%s no devices found\n",driver_name); - return -ENODEV; - } - - serial_driver = alloc_tty_driver(MAX_DEVICES); - if (!serial_driver) { - rc = -ENOMEM; - goto error; - } - - /* Initialize the tty_driver structure */ - - serial_driver->owner = THIS_MODULE; - serial_driver->driver_name = tty_driver_name; - serial_driver->name = tty_dev_prefix; - serial_driver->major = ttymajor; - serial_driver->minor_start = 64; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - serial_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(serial_driver, &ops); - if ((rc = tty_register_driver(serial_driver)) < 0) { - DBGERR(("%s can't register serial driver\n", driver_name)); - put_tty_driver(serial_driver); - serial_driver = NULL; - goto error; - } - - printk("%s %s, tty major#%d\n", - driver_name, driver_version, - serial_driver->major); - - return 0; - -error: - slgt_cleanup(); - return rc; -} - -static void __exit slgt_exit(void) -{ - slgt_cleanup(); -} - -module_init(slgt_init); -module_exit(slgt_exit); - -/* - * register access routines - */ - -#define CALC_REGADDR() \ - unsigned long reg_addr = ((unsigned long)info->reg_addr) + addr; \ - if (addr >= 0x80) \ - reg_addr += (info->port_num) * 32; - -static __u8 rd_reg8(struct slgt_info *info, unsigned int addr) -{ - CALC_REGADDR(); - return readb((void __iomem *)reg_addr); -} - -static void wr_reg8(struct slgt_info *info, unsigned int addr, __u8 value) -{ - CALC_REGADDR(); - writeb(value, (void __iomem *)reg_addr); -} - -static __u16 rd_reg16(struct slgt_info *info, unsigned int addr) -{ - CALC_REGADDR(); - return readw((void __iomem *)reg_addr); -} - -static void wr_reg16(struct slgt_info *info, unsigned int addr, __u16 value) -{ - CALC_REGADDR(); - writew(value, (void __iomem *)reg_addr); -} - -static __u32 rd_reg32(struct slgt_info *info, unsigned int addr) -{ - CALC_REGADDR(); - return readl((void __iomem *)reg_addr); -} - -static void wr_reg32(struct slgt_info *info, unsigned int addr, __u32 value) -{ - CALC_REGADDR(); - writel(value, (void __iomem *)reg_addr); -} - -static void rdma_reset(struct slgt_info *info) -{ - unsigned int i; - - /* set reset bit */ - wr_reg32(info, RDCSR, BIT1); - - /* wait for enable bit cleared */ - for(i=0 ; i < 1000 ; i++) - if (!(rd_reg32(info, RDCSR) & BIT0)) - break; -} - -static void tdma_reset(struct slgt_info *info) -{ - unsigned int i; - - /* set reset bit */ - wr_reg32(info, TDCSR, BIT1); - - /* wait for enable bit cleared */ - for(i=0 ; i < 1000 ; i++) - if (!(rd_reg32(info, TDCSR) & BIT0)) - break; -} - -/* - * enable internal loopback - * TxCLK and RxCLK are generated from BRG - * and TxD is looped back to RxD internally. - */ -static void enable_loopback(struct slgt_info *info) -{ - /* SCR (serial control) BIT2=looopback enable */ - wr_reg16(info, SCR, (unsigned short)(rd_reg16(info, SCR) | BIT2)); - - if (info->params.mode != MGSL_MODE_ASYNC) { - /* CCR (clock control) - * 07..05 tx clock source (010 = BRG) - * 04..02 rx clock source (010 = BRG) - * 01 auxclk enable (0 = disable) - * 00 BRG enable (1 = enable) - * - * 0100 1001 - */ - wr_reg8(info, CCR, 0x49); - - /* set speed if available, otherwise use default */ - if (info->params.clock_speed) - set_rate(info, info->params.clock_speed); - else - set_rate(info, 3686400); - } -} - -/* - * set baud rate generator to specified rate - */ -static void set_rate(struct slgt_info *info, u32 rate) -{ - unsigned int div; - static unsigned int osc = 14745600; - - /* div = osc/rate - 1 - * - * Round div up if osc/rate is not integer to - * force to next slowest rate. - */ - - if (rate) { - div = osc/rate; - if (!(osc % rate) && div) - div--; - wr_reg16(info, BDR, (unsigned short)div); - } -} - -static void rx_stop(struct slgt_info *info) -{ - unsigned short val; - - /* disable and reset receiver */ - val = rd_reg16(info, RCR) & ~BIT1; /* clear enable bit */ - wr_reg16(info, RCR, (unsigned short)(val | BIT2)); /* set reset bit */ - wr_reg16(info, RCR, val); /* clear reset bit */ - - slgt_irq_off(info, IRQ_RXOVER + IRQ_RXDATA + IRQ_RXIDLE); - - /* clear pending rx interrupts */ - wr_reg16(info, SSR, IRQ_RXIDLE + IRQ_RXOVER); - - rdma_reset(info); - - info->rx_enabled = 0; - info->rx_restart = 0; -} - -static void rx_start(struct slgt_info *info) -{ - unsigned short val; - - slgt_irq_off(info, IRQ_RXOVER + IRQ_RXDATA); - - /* clear pending rx overrun IRQ */ - wr_reg16(info, SSR, IRQ_RXOVER); - - /* reset and disable receiver */ - val = rd_reg16(info, RCR) & ~BIT1; /* clear enable bit */ - wr_reg16(info, RCR, (unsigned short)(val | BIT2)); /* set reset bit */ - wr_reg16(info, RCR, val); /* clear reset bit */ - - rdma_reset(info); - reset_rbufs(info); - - /* set 1st descriptor address */ - wr_reg32(info, RDDAR, info->rbufs[0].pdesc); - - if (info->params.mode != MGSL_MODE_ASYNC) { - /* enable rx DMA and DMA interrupt */ - wr_reg32(info, RDCSR, (BIT2 + BIT0)); - } else { - /* enable saving of rx status, rx DMA and DMA interrupt */ - wr_reg32(info, RDCSR, (BIT6 + BIT2 + BIT0)); - } - - slgt_irq_on(info, IRQ_RXOVER); - - /* enable receiver */ - wr_reg16(info, RCR, (unsigned short)(rd_reg16(info, RCR) | BIT1)); - - info->rx_restart = 0; - info->rx_enabled = 1; -} - -static void tx_start(struct slgt_info *info) -{ - if (!info->tx_enabled) { - wr_reg16(info, TCR, - (unsigned short)(rd_reg16(info, TCR) | BIT1)); - info->tx_enabled = TRUE; - } - - if (info->tx_count) { - info->drop_rts_on_tx_done = 0; - - if (info->params.mode != MGSL_MODE_ASYNC) { - if (info->params.flags & HDLC_FLAG_AUTO_RTS) { - get_signals(info); - if (!(info->signals & SerialSignal_RTS)) { - info->signals |= SerialSignal_RTS; - set_signals(info); - info->drop_rts_on_tx_done = 1; - } - } - - slgt_irq_off(info, IRQ_TXDATA); - slgt_irq_on(info, IRQ_TXUNDER + IRQ_TXIDLE); - /* clear tx idle and underrun status bits */ - wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER)); - - if (!(rd_reg32(info, TDCSR) & BIT0)) { - /* tx DMA stopped, restart tx DMA */ - tdma_reset(info); - /* set 1st descriptor address */ - wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); - if (info->params.mode == MGSL_MODE_RAW) - wr_reg32(info, TDCSR, BIT2 + BIT0); /* IRQ + DMA enable */ - else - wr_reg32(info, TDCSR, BIT0); /* DMA enable */ - } - - if (info->params.mode != MGSL_MODE_RAW) { - info->tx_timer.expires = jiffies + msecs_to_jiffies(5000); - add_timer(&info->tx_timer); - } - } else { - tdma_reset(info); - /* set 1st descriptor address */ - wr_reg32(info, TDDAR, info->tbufs[info->tbuf_start].pdesc); - - slgt_irq_off(info, IRQ_TXDATA); - slgt_irq_on(info, IRQ_TXIDLE); - /* clear tx idle status bit */ - wr_reg16(info, SSR, IRQ_TXIDLE); - - /* enable tx DMA */ - wr_reg32(info, TDCSR, BIT0); - } - - info->tx_active = 1; - } -} - -static void tx_stop(struct slgt_info *info) -{ - unsigned short val; - - del_timer(&info->tx_timer); - - tdma_reset(info); - - /* reset and disable transmitter */ - val = rd_reg16(info, TCR) & ~BIT1; /* clear enable bit */ - wr_reg16(info, TCR, (unsigned short)(val | BIT2)); /* set reset bit */ - wr_reg16(info, TCR, val); /* clear reset */ - - slgt_irq_off(info, IRQ_TXDATA + IRQ_TXIDLE + IRQ_TXUNDER); - - /* clear tx idle and underrun status bit */ - wr_reg16(info, SSR, (unsigned short)(IRQ_TXIDLE + IRQ_TXUNDER)); - - reset_tbufs(info); - - info->tx_enabled = 0; - info->tx_active = 0; -} - -static void reset_port(struct slgt_info *info) -{ - if (!info->reg_addr) - return; - - tx_stop(info); - rx_stop(info); - - info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); - set_signals(info); - - slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); -} - -static void reset_adapter(struct slgt_info *info) -{ - int i; - for (i=0; i < info->port_count; ++i) { - if (info->port_array[i]) - reset_port(info->port_array[i]); - } -} - -static void async_mode(struct slgt_info *info) -{ - unsigned short val; - - slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); - tx_stop(info); - rx_stop(info); - - /* TCR (tx control) - * - * 15..13 mode, 010=async - * 12..10 encoding, 000=NRZ - * 09 parity enable - * 08 1=odd parity, 0=even parity - * 07 1=RTS driver control - * 06 1=break enable - * 05..04 character length - * 00=5 bits - * 01=6 bits - * 10=7 bits - * 11=8 bits - * 03 0=1 stop bit, 1=2 stop bits - * 02 reset - * 01 enable - * 00 auto-CTS enable - */ - val = 0x4000; - - if (info->if_mode & MGSL_INTERFACE_RTS_EN) - val |= BIT7; - - if (info->params.parity != ASYNC_PARITY_NONE) { - val |= BIT9; - if (info->params.parity == ASYNC_PARITY_ODD) - val |= BIT8; - } - - switch (info->params.data_bits) - { - case 6: val |= BIT4; break; - case 7: val |= BIT5; break; - case 8: val |= BIT5 + BIT4; break; - } - - if (info->params.stop_bits != 1) - val |= BIT3; - - if (info->params.flags & HDLC_FLAG_AUTO_CTS) - val |= BIT0; - - wr_reg16(info, TCR, val); - - /* RCR (rx control) - * - * 15..13 mode, 010=async - * 12..10 encoding, 000=NRZ - * 09 parity enable - * 08 1=odd parity, 0=even parity - * 07..06 reserved, must be 0 - * 05..04 character length - * 00=5 bits - * 01=6 bits - * 10=7 bits - * 11=8 bits - * 03 reserved, must be zero - * 02 reset - * 01 enable - * 00 auto-DCD enable - */ - val = 0x4000; - - if (info->params.parity != ASYNC_PARITY_NONE) { - val |= BIT9; - if (info->params.parity == ASYNC_PARITY_ODD) - val |= BIT8; - } - - switch (info->params.data_bits) - { - case 6: val |= BIT4; break; - case 7: val |= BIT5; break; - case 8: val |= BIT5 + BIT4; break; - } - - if (info->params.flags & HDLC_FLAG_AUTO_DCD) - val |= BIT0; - - wr_reg16(info, RCR, val); - - /* CCR (clock control) - * - * 07..05 011 = tx clock source is BRG/16 - * 04..02 010 = rx clock source is BRG - * 01 0 = auxclk disabled - * 00 1 = BRG enabled - * - * 0110 1001 - */ - wr_reg8(info, CCR, 0x69); - - msc_set_vcr(info); - - tx_set_idle(info); - - /* SCR (serial control) - * - * 15 1=tx req on FIFO half empty - * 14 1=rx req on FIFO half full - * 13 tx data IRQ enable - * 12 tx idle IRQ enable - * 11 rx break on IRQ enable - * 10 rx data IRQ enable - * 09 rx break off IRQ enable - * 08 overrun IRQ enable - * 07 DSR IRQ enable - * 06 CTS IRQ enable - * 05 DCD IRQ enable - * 04 RI IRQ enable - * 03 reserved, must be zero - * 02 1=txd->rxd internal loopback enable - * 01 reserved, must be zero - * 00 1=master IRQ enable - */ - val = BIT15 + BIT14 + BIT0; - wr_reg16(info, SCR, val); - - slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER); - - set_rate(info, info->params.data_rate * 16); - - if (info->params.loopback) - enable_loopback(info); -} - -static void hdlc_mode(struct slgt_info *info) -{ - unsigned short val; - - slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); - tx_stop(info); - rx_stop(info); - - /* TCR (tx control) - * - * 15..13 mode, 000=HDLC 001=raw sync - * 12..10 encoding - * 09 CRC enable - * 08 CRC32 - * 07 1=RTS driver control - * 06 preamble enable - * 05..04 preamble length - * 03 share open/close flag - * 02 reset - * 01 enable - * 00 auto-CTS enable - */ - val = 0; - - if (info->params.mode == MGSL_MODE_RAW) - val |= BIT13; - if (info->if_mode & MGSL_INTERFACE_RTS_EN) - val |= BIT7; - - switch(info->params.encoding) - { - case HDLC_ENCODING_NRZB: val |= BIT10; break; - case HDLC_ENCODING_NRZI_MARK: val |= BIT11; break; - case HDLC_ENCODING_NRZI: val |= BIT11 + BIT10; break; - case HDLC_ENCODING_BIPHASE_MARK: val |= BIT12; break; - case HDLC_ENCODING_BIPHASE_SPACE: val |= BIT12 + BIT10; break; - case HDLC_ENCODING_BIPHASE_LEVEL: val |= BIT12 + BIT11; break; - case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break; - } - - switch (info->params.crc_type) - { - case HDLC_CRC_16_CCITT: val |= BIT9; break; - case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break; - } - - if (info->params.preamble != HDLC_PREAMBLE_PATTERN_NONE) - val |= BIT6; - - switch (info->params.preamble_length) - { - case HDLC_PREAMBLE_LENGTH_16BITS: val |= BIT5; break; - case HDLC_PREAMBLE_LENGTH_32BITS: val |= BIT4; break; - case HDLC_PREAMBLE_LENGTH_64BITS: val |= BIT5 + BIT4; break; - } - - if (info->params.flags & HDLC_FLAG_AUTO_CTS) - val |= BIT0; - - wr_reg16(info, TCR, val); - - /* TPR (transmit preamble) */ - - switch (info->params.preamble) - { - case HDLC_PREAMBLE_PATTERN_FLAGS: val = 0x7e; break; - case HDLC_PREAMBLE_PATTERN_ONES: val = 0xff; break; - case HDLC_PREAMBLE_PATTERN_ZEROS: val = 0x00; break; - case HDLC_PREAMBLE_PATTERN_10: val = 0x55; break; - case HDLC_PREAMBLE_PATTERN_01: val = 0xaa; break; - default: val = 0x7e; break; - } - wr_reg8(info, TPR, (unsigned char)val); - - /* RCR (rx control) - * - * 15..13 mode, 000=HDLC 001=raw sync - * 12..10 encoding - * 09 CRC enable - * 08 CRC32 - * 07..03 reserved, must be 0 - * 02 reset - * 01 enable - * 00 auto-DCD enable - */ - val = 0; - - if (info->params.mode == MGSL_MODE_RAW) - val |= BIT13; - - switch(info->params.encoding) - { - case HDLC_ENCODING_NRZB: val |= BIT10; break; - case HDLC_ENCODING_NRZI_MARK: val |= BIT11; break; - case HDLC_ENCODING_NRZI: val |= BIT11 + BIT10; break; - case HDLC_ENCODING_BIPHASE_MARK: val |= BIT12; break; - case HDLC_ENCODING_BIPHASE_SPACE: val |= BIT12 + BIT10; break; - case HDLC_ENCODING_BIPHASE_LEVEL: val |= BIT12 + BIT11; break; - case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: val |= BIT12 + BIT11 + BIT10; break; - } - - switch (info->params.crc_type) - { - case HDLC_CRC_16_CCITT: val |= BIT9; break; - case HDLC_CRC_32_CCITT: val |= BIT9 + BIT8; break; - } - - if (info->params.flags & HDLC_FLAG_AUTO_DCD) - val |= BIT0; - - wr_reg16(info, RCR, val); - - /* CCR (clock control) - * - * 07..05 tx clock source - * 04..02 rx clock source - * 01 auxclk enable - * 00 BRG enable - */ - val = 0; - - if (info->params.flags & HDLC_FLAG_TXC_BRG) - { - // when RxC source is DPLL, BRG generates 16X DPLL - // reference clock, so take TxC from BRG/16 to get - // transmit clock at actual data rate - if (info->params.flags & HDLC_FLAG_RXC_DPLL) - val |= BIT6 + BIT5; /* 011, txclk = BRG/16 */ - else - val |= BIT6; /* 010, txclk = BRG */ - } - else if (info->params.flags & HDLC_FLAG_TXC_DPLL) - val |= BIT7; /* 100, txclk = DPLL Input */ - else if (info->params.flags & HDLC_FLAG_TXC_RXCPIN) - val |= BIT5; /* 001, txclk = RXC Input */ - - if (info->params.flags & HDLC_FLAG_RXC_BRG) - val |= BIT3; /* 010, rxclk = BRG */ - else if (info->params.flags & HDLC_FLAG_RXC_DPLL) - val |= BIT4; /* 100, rxclk = DPLL */ - else if (info->params.flags & HDLC_FLAG_RXC_TXCPIN) - val |= BIT2; /* 001, rxclk = TXC Input */ - - if (info->params.clock_speed) - val |= BIT1 + BIT0; - - wr_reg8(info, CCR, (unsigned char)val); - - if (info->params.flags & (HDLC_FLAG_TXC_DPLL + HDLC_FLAG_RXC_DPLL)) - { - // program DPLL mode - switch(info->params.encoding) - { - case HDLC_ENCODING_BIPHASE_MARK: - case HDLC_ENCODING_BIPHASE_SPACE: - val = BIT7; break; - case HDLC_ENCODING_BIPHASE_LEVEL: - case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: - val = BIT7 + BIT6; break; - default: val = BIT6; // NRZ encodings - } - wr_reg16(info, RCR, (unsigned short)(rd_reg16(info, RCR) | val)); - - // DPLL requires a 16X reference clock from BRG - set_rate(info, info->params.clock_speed * 16); - } - else - set_rate(info, info->params.clock_speed); - - tx_set_idle(info); - - msc_set_vcr(info); - - /* SCR (serial control) - * - * 15 1=tx req on FIFO half empty - * 14 1=rx req on FIFO half full - * 13 tx data IRQ enable - * 12 tx idle IRQ enable - * 11 underrun IRQ enable - * 10 rx data IRQ enable - * 09 rx idle IRQ enable - * 08 overrun IRQ enable - * 07 DSR IRQ enable - * 06 CTS IRQ enable - * 05 DCD IRQ enable - * 04 RI IRQ enable - * 03 reserved, must be zero - * 02 1=txd->rxd internal loopback enable - * 01 reserved, must be zero - * 00 1=master IRQ enable - */ - wr_reg16(info, SCR, BIT15 + BIT14 + BIT0); - - if (info->params.loopback) - enable_loopback(info); -} - -/* - * set transmit idle mode - */ -static void tx_set_idle(struct slgt_info *info) -{ - unsigned char val = 0xff; - - switch(info->idle_mode) - { - case HDLC_TXIDLE_FLAGS: val = 0x7e; break; - case HDLC_TXIDLE_ALT_ZEROS_ONES: val = 0xaa; break; - case HDLC_TXIDLE_ZEROS: val = 0x00; break; - case HDLC_TXIDLE_ONES: val = 0xff; break; - case HDLC_TXIDLE_ALT_MARK_SPACE: val = 0xaa; break; - case HDLC_TXIDLE_SPACE: val = 0x00; break; - case HDLC_TXIDLE_MARK: val = 0xff; break; - } - - wr_reg8(info, TIR, val); -} - -/* - * get state of V24 status (input) signals - */ -static void get_signals(struct slgt_info *info) -{ - unsigned short status = rd_reg16(info, SSR); - - /* clear all serial signals except DTR and RTS */ - info->signals &= SerialSignal_DTR + SerialSignal_RTS; - - if (status & BIT3) - info->signals |= SerialSignal_DSR; - if (status & BIT2) - info->signals |= SerialSignal_CTS; - if (status & BIT1) - info->signals |= SerialSignal_DCD; - if (status & BIT0) - info->signals |= SerialSignal_RI; -} - -/* - * set V.24 Control Register based on current configuration - */ -static void msc_set_vcr(struct slgt_info *info) -{ - unsigned char val = 0; - - /* VCR (V.24 control) - * - * 07..04 serial IF select - * 03 DTR - * 02 RTS - * 01 LL - * 00 RL - */ - - switch(info->if_mode & MGSL_INTERFACE_MASK) - { - case MGSL_INTERFACE_RS232: - val |= BIT5; /* 0010 */ - break; - case MGSL_INTERFACE_V35: - val |= BIT7 + BIT6 + BIT5; /* 1110 */ - break; - case MGSL_INTERFACE_RS422: - val |= BIT6; /* 0100 */ - break; - } - - if (info->signals & SerialSignal_DTR) - val |= BIT3; - if (info->signals & SerialSignal_RTS) - val |= BIT2; - if (info->if_mode & MGSL_INTERFACE_LL) - val |= BIT1; - if (info->if_mode & MGSL_INTERFACE_RL) - val |= BIT0; - wr_reg8(info, VCR, val); -} - -/* - * set state of V24 control (output) signals - */ -static void set_signals(struct slgt_info *info) -{ - unsigned char val = rd_reg8(info, VCR); - if (info->signals & SerialSignal_DTR) - val |= BIT3; - else - val &= ~BIT3; - if (info->signals & SerialSignal_RTS) - val |= BIT2; - else - val &= ~BIT2; - wr_reg8(info, VCR, val); -} - -/* - * free range of receive DMA buffers (i to last) - */ -static void free_rbufs(struct slgt_info *info, unsigned int i, unsigned int last) -{ - int done = 0; - - while(!done) { - /* reset current buffer for reuse */ - info->rbufs[i].status = 0; - if (info->params.mode == MGSL_MODE_RAW) - set_desc_count(info->rbufs[i], info->raw_rx_size); - else - set_desc_count(info->rbufs[i], DMABUFSIZE); - - if (i == last) - done = 1; - if (++i == info->rbuf_count) - i = 0; - } - info->rbuf_current = i; -} - -/* - * mark all receive DMA buffers as free - */ -static void reset_rbufs(struct slgt_info *info) -{ - free_rbufs(info, 0, info->rbuf_count - 1); -} - -/* - * pass receive HDLC frame to upper layer - * - * return 1 if frame available, otherwise 0 - */ -static int rx_get_frame(struct slgt_info *info) -{ - unsigned int start, end; - unsigned short status; - unsigned int framesize = 0; - int rc = 0; - unsigned long flags; - struct tty_struct *tty = info->tty; - unsigned char addr_field = 0xff; - -check_again: - - framesize = 0; - addr_field = 0xff; - start = end = info->rbuf_current; - - for (;;) { - if (!desc_complete(info->rbufs[end])) - goto cleanup; - - if (framesize == 0 && info->params.addr_filter != 0xff) - addr_field = info->rbufs[end].buf[0]; - - framesize += desc_count(info->rbufs[end]); - - if (desc_eof(info->rbufs[end])) - break; - - if (++end == info->rbuf_count) - end = 0; - - if (end == info->rbuf_current) { - if (info->rx_enabled){ - spin_lock_irqsave(&info->lock,flags); - rx_start(info); - spin_unlock_irqrestore(&info->lock,flags); - } - goto cleanup; - } - } - - /* status - * - * 15 buffer complete - * 14..06 reserved - * 05..04 residue - * 02 eof (end of frame) - * 01 CRC error - * 00 abort - */ - status = desc_status(info->rbufs[end]); - - /* ignore CRC bit if not using CRC (bit is undefined) */ - if (info->params.crc_type == HDLC_CRC_NONE) - status &= ~BIT1; - - if (framesize == 0 || - (addr_field != 0xff && addr_field != info->params.addr_filter)) { - free_rbufs(info, start, end); - goto check_again; - } - - if (framesize < 2 || status & (BIT1+BIT0)) { - if (framesize < 2 || (status & BIT0)) - info->icount.rxshort++; - else - info->icount.rxcrc++; - framesize = 0; - -#ifdef CONFIG_HDLC - { - struct net_device_stats *stats = hdlc_stats(info->netdev); - stats->rx_errors++; - stats->rx_frame_errors++; - } -#endif - } else { - /* adjust frame size for CRC, if any */ - if (info->params.crc_type == HDLC_CRC_16_CCITT) - framesize -= 2; - else if (info->params.crc_type == HDLC_CRC_32_CCITT) - framesize -= 4; - } - - DBGBH(("%s rx frame status=%04X size=%d\n", - info->device_name, status, framesize)); - DBGDATA(info, info->rbufs[start].buf, min_t(int, framesize, DMABUFSIZE), "rx"); - - if (framesize) { - if (framesize > info->max_frame_size) - info->icount.rxlong++; - else { - /* copy dma buffer(s) to contiguous temp buffer */ - int copy_count = framesize; - int i = start; - unsigned char *p = info->tmp_rbuf; - info->tmp_rbuf_count = framesize; - - info->icount.rxok++; - - while(copy_count) { - int partial_count = min(copy_count, DMABUFSIZE); - memcpy(p, info->rbufs[i].buf, partial_count); - p += partial_count; - copy_count -= partial_count; - if (++i == info->rbuf_count) - i = 0; - } - -#ifdef CONFIG_HDLC - if (info->netcount) - hdlcdev_rx(info,info->tmp_rbuf, framesize); - else -#endif - ldisc_receive_buf(tty, info->tmp_rbuf, info->flag_buf, framesize); - } - } - free_rbufs(info, start, end); - rc = 1; - -cleanup: - return rc; -} - -/* - * pass receive buffer (RAW synchronous mode) to tty layer - * return 1 if buffer available, otherwise 0 - */ -static int rx_get_buf(struct slgt_info *info) -{ - unsigned int i = info->rbuf_current; - - if (!desc_complete(info->rbufs[i])) - return 0; - DBGDATA(info, info->rbufs[i].buf, desc_count(info->rbufs[i]), "rx"); - DBGINFO(("rx_get_buf size=%d\n", desc_count(info->rbufs[i]))); - ldisc_receive_buf(info->tty, info->rbufs[i].buf, - info->flag_buf, desc_count(info->rbufs[i])); - free_rbufs(info, i, i); - return 1; -} - -static void reset_tbufs(struct slgt_info *info) -{ - unsigned int i; - info->tbuf_current = 0; - for (i=0 ; i < info->tbuf_count ; i++) { - info->tbufs[i].status = 0; - info->tbufs[i].count = 0; - } -} - -/* - * return number of free transmit DMA buffers - */ -static unsigned int free_tbuf_count(struct slgt_info *info) -{ - unsigned int count = 0; - unsigned int i = info->tbuf_current; - - do - { - if (desc_count(info->tbufs[i])) - break; /* buffer in use */ - ++count; - if (++i == info->tbuf_count) - i=0; - } while (i != info->tbuf_current); - - /* last buffer with zero count may be in use, assume it is */ - if (count) - --count; - - return count; -} - -/* - * load transmit DMA buffer(s) with data - */ -static void tx_load(struct slgt_info *info, const char *buf, unsigned int size) -{ - unsigned short count; - unsigned int i; - struct slgt_desc *d; - - if (size == 0) - return; - - DBGDATA(info, buf, size, "tx"); - - info->tbuf_start = i = info->tbuf_current; - - while (size) { - d = &info->tbufs[i]; - if (++i == info->tbuf_count) - i = 0; - - count = (unsigned short)((size > DMABUFSIZE) ? DMABUFSIZE : size); - memcpy(d->buf, buf, count); - - size -= count; - buf += count; - - if (!size && info->params.mode != MGSL_MODE_RAW) - set_desc_eof(*d, 1); /* HDLC: set EOF of last desc */ - else - set_desc_eof(*d, 0); - - set_desc_count(*d, count); - } - - info->tbuf_current = i; -} - -static int register_test(struct slgt_info *info) -{ - static unsigned short patterns[] = - {0x0000, 0xffff, 0xaaaa, 0x5555, 0x6969, 0x9696}; - static unsigned int count = sizeof(patterns)/sizeof(patterns[0]); - unsigned int i; - int rc = 0; - - for (i=0 ; i < count ; i++) { - wr_reg16(info, TIR, patterns[i]); - wr_reg16(info, BDR, patterns[(i+1)%count]); - if ((rd_reg16(info, TIR) != patterns[i]) || - (rd_reg16(info, BDR) != patterns[(i+1)%count])) { - rc = -ENODEV; - break; - } - } - - info->init_error = rc ? 0 : DiagStatus_AddressFailure; - return rc; -} - -static int irq_test(struct slgt_info *info) -{ - unsigned long timeout; - unsigned long flags; - struct tty_struct *oldtty = info->tty; - u32 speed = info->params.data_rate; - - info->params.data_rate = 921600; - info->tty = NULL; - - spin_lock_irqsave(&info->lock, flags); - async_mode(info); - slgt_irq_on(info, IRQ_TXIDLE); - - /* enable transmitter */ - wr_reg16(info, TCR, - (unsigned short)(rd_reg16(info, TCR) | BIT1)); - - /* write one byte and wait for tx idle */ - wr_reg16(info, TDR, 0); - - /* assume failure */ - info->init_error = DiagStatus_IrqFailure; - info->irq_occurred = FALSE; - - spin_unlock_irqrestore(&info->lock, flags); - - timeout=100; - while(timeout-- && !info->irq_occurred) - msleep_interruptible(10); - - spin_lock_irqsave(&info->lock,flags); - reset_port(info); - spin_unlock_irqrestore(&info->lock,flags); - - info->params.data_rate = speed; - info->tty = oldtty; - - info->init_error = info->irq_occurred ? 0 : DiagStatus_IrqFailure; - return info->irq_occurred ? 0 : -ENODEV; -} - -static int loopback_test_rx(struct slgt_info *info) -{ - unsigned char *src, *dest; - int count; - - if (desc_complete(info->rbufs[0])) { - count = desc_count(info->rbufs[0]); - src = info->rbufs[0].buf; - dest = info->tmp_rbuf; - - for( ; count ; count-=2, src+=2) { - /* src=data byte (src+1)=status byte */ - if (!(*(src+1) & (BIT9 + BIT8))) { - *dest = *src; - dest++; - info->tmp_rbuf_count++; - } - } - DBGDATA(info, info->tmp_rbuf, info->tmp_rbuf_count, "rx"); - return 1; - } - return 0; -} - -static int loopback_test(struct slgt_info *info) -{ -#define TESTFRAMESIZE 20 - - unsigned long timeout; - u16 count = TESTFRAMESIZE; - unsigned char buf[TESTFRAMESIZE]; - int rc = -ENODEV; - unsigned long flags; - - struct tty_struct *oldtty = info->tty; - MGSL_PARAMS params; - - memcpy(¶ms, &info->params, sizeof(params)); - - info->params.mode = MGSL_MODE_ASYNC; - info->params.data_rate = 921600; - info->params.loopback = 1; - info->tty = NULL; - - /* build and send transmit frame */ - for (count = 0; count < TESTFRAMESIZE; ++count) - buf[count] = (unsigned char)count; - - info->tmp_rbuf_count = 0; - memset(info->tmp_rbuf, 0, TESTFRAMESIZE); - - /* program hardware for HDLC and enabled receiver */ - spin_lock_irqsave(&info->lock,flags); - async_mode(info); - rx_start(info); - info->tx_count = count; - tx_load(info, buf, count); - tx_start(info); - spin_unlock_irqrestore(&info->lock, flags); - - /* wait for receive complete */ - for (timeout = 100; timeout; --timeout) { - msleep_interruptible(10); - if (loopback_test_rx(info)) { - rc = 0; - break; - } - } - - /* verify received frame length and contents */ - if (!rc && (info->tmp_rbuf_count != count || - memcmp(buf, info->tmp_rbuf, count))) { - rc = -ENODEV; - } - - spin_lock_irqsave(&info->lock,flags); - reset_adapter(info); - spin_unlock_irqrestore(&info->lock,flags); - - memcpy(&info->params, ¶ms, sizeof(info->params)); - info->tty = oldtty; - - info->init_error = rc ? DiagStatus_DmaFailure : 0; - return rc; -} - -static int adapter_test(struct slgt_info *info) -{ - DBGINFO(("testing %s\n", info->device_name)); - if ((info->init_error = register_test(info)) < 0) { - printk("register test failure %s addr=%08X\n", - info->device_name, info->phys_reg_addr); - } else if ((info->init_error = irq_test(info)) < 0) { - printk("IRQ test failure %s IRQ=%d\n", - info->device_name, info->irq_level); - } else if ((info->init_error = loopback_test(info)) < 0) { - printk("loopback test failure %s\n", info->device_name); - } - return info->init_error; -} - -/* - * transmit timeout handler - */ -static void tx_timeout(unsigned long context) -{ - struct slgt_info *info = (struct slgt_info*)context; - unsigned long flags; - - DBGINFO(("%s tx_timeout\n", info->device_name)); - if(info->tx_active && info->params.mode == MGSL_MODE_HDLC) { - info->icount.txtimeout++; - } - spin_lock_irqsave(&info->lock,flags); - info->tx_active = 0; - info->tx_count = 0; - spin_unlock_irqrestore(&info->lock,flags); - -#ifdef CONFIG_HDLC - if (info->netcount) - hdlcdev_tx_done(info); - else -#endif - bh_transmit(info); -} - -/* - * receive buffer polling timer - */ -static void rx_timeout(unsigned long context) -{ - struct slgt_info *info = (struct slgt_info*)context; - unsigned long flags; - - DBGINFO(("%s rx_timeout\n", info->device_name)); - spin_lock_irqsave(&info->lock, flags); - info->pending_bh |= BH_RECEIVE; - spin_unlock_irqrestore(&info->lock, flags); - bh_handler(info); -} - diff --git a/trunk/drivers/char/tpm/Makefile b/trunk/drivers/char/tpm/Makefile index ba4582d160fd..2392e404e8d1 100644 --- a/trunk/drivers/char/tpm/Makefile +++ b/trunk/drivers/char/tpm/Makefile @@ -2,9 +2,6 @@ # Makefile for the kernel tpm device drivers. # obj-$(CONFIG_TCG_TPM) += tpm.o -ifdef CONFIG_ACPI - obj-$(CONFIG_TCG_TPM) += tpm_bios.o -endif obj-$(CONFIG_TCG_NSC) += tpm_nsc.o obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o diff --git a/trunk/drivers/char/tpm/tpm.c b/trunk/drivers/char/tpm/tpm.c index 5a3870477ef1..a9be0e8eaea5 100644 --- a/trunk/drivers/char/tpm/tpm.c +++ b/trunk/drivers/char/tpm/tpm.c @@ -466,7 +466,6 @@ void tpm_remove_hardware(struct device *dev) kfree(chip->vendor->miscdev.name); sysfs_remove_group(&dev->kobj, chip->vendor->attr_group); - tpm_bios_log_teardown(chip->bios_dir); dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES)); @@ -594,8 +593,6 @@ int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry) sysfs_create_group(&dev->kobj, chip->vendor->attr_group); - chip->bios_dir = tpm_bios_log_setup(devname); - return 0; } EXPORT_SYMBOL_GPL(tpm_register_hardware); diff --git a/trunk/drivers/char/tpm/tpm.h b/trunk/drivers/char/tpm/tpm.h index fd3a4beaa53d..159882ca69dd 100644 --- a/trunk/drivers/char/tpm/tpm.h +++ b/trunk/drivers/char/tpm/tpm.h @@ -82,8 +82,6 @@ struct tpm_chip { struct tpm_vendor_specific *vendor; - struct dentry **bios_dir; - struct list_head list; }; @@ -109,16 +107,3 @@ extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *); extern void tpm_remove_hardware(struct device *); extern int tpm_pm_suspend(struct device *, pm_message_t); extern int tpm_pm_resume(struct device *); - -#ifdef CONFIG_ACPI -extern struct dentry ** tpm_bios_log_setup(char *); -extern void tpm_bios_log_teardown(struct dentry **); -#else -static inline struct dentry* tpm_bios_log_setup(char *name) -{ - return NULL; -} -static inline void tpm_bios_log_teardown(struct dentry **dir) -{ -} -#endif diff --git a/trunk/drivers/char/tpm/tpm_bios.c b/trunk/drivers/char/tpm/tpm_bios.c deleted file mode 100644 index aedf7a8e6da7..000000000000 --- a/trunk/drivers/char/tpm/tpm_bios.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * Copyright (C) 2005 IBM Corporation - * - * Authors: - * Seiji Munetoh - * Stefan Berger - * Reiner Sailer - * Kylene Hall - * - * Access to the eventlog extended by the TCG BIOS of PC platform - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include "tpm.h" - -#define TCG_EVENT_NAME_LEN_MAX 255 -#define MAX_TEXT_EVENT 1000 /* Max event string length */ -#define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ - -struct tpm_bios_log { - void *bios_event_log; - void *bios_event_log_end; -}; - -struct acpi_tcpa { - struct acpi_table_header hdr; - u16 reserved; - u32 log_max_len __attribute__ ((packed)); - u32 log_start_addr __attribute__ ((packed)); -}; - -struct tcpa_event { - u32 pcr_index; - u32 event_type; - u8 pcr_value[20]; /* SHA1 */ - u32 event_size; - u8 event_data[0]; -}; - -enum tcpa_event_types { - PREBOOT = 0, - POST_CODE, - UNUSED, - NO_ACTION, - SEPARATOR, - ACTION, - EVENT_TAG, - SCRTM_CONTENTS, - SCRTM_VERSION, - CPU_MICROCODE, - PLATFORM_CONFIG_FLAGS, - TABLE_OF_DEVICES, - COMPACT_HASH, - IPL, - IPL_PARTITION_DATA, - NONHOST_CODE, - NONHOST_CONFIG, - NONHOST_INFO, -}; - -static const char* tcpa_event_type_strings[] = { - "PREBOOT", - "POST CODE", - "", - "NO ACTION", - "SEPARATOR", - "ACTION", - "EVENT TAG", - "S-CRTM Contents", - "S-CRTM Version", - "CPU Microcode", - "Platform Config Flags", - "Table of Devices", - "Compact Hash", - "IPL", - "IPL Partition Data", - "Non-Host Code", - "Non-Host Config", - "Non-Host Info" -}; - -enum tcpa_pc_event_ids { - SMBIOS = 1, - BIS_CERT, - POST_BIOS_ROM, - ESCD, - CMOS, - NVRAM, - OPTION_ROM_EXEC, - OPTION_ROM_CONFIG, - OPTION_ROM_MICROCODE, - S_CRTM_VERSION, - S_CRTM_CONTENTS, - POST_CONTENTS, -}; - -static const char* tcpa_pc_event_id_strings[] = { - "" - "SMBIOS", - "BIS Certificate", - "POST BIOS ", - "ESCD ", - "CMOS", - "NVRAM", - "Option ROM", - "Option ROM config", - "Option ROM microcode", - "S-CRTM Version", - "S-CRTM Contents", - "S-CRTM POST Contents", -}; - -/* returns pointer to start of pos. entry of tcg log */ -static void *tpm_bios_measurements_start(struct seq_file *m, loff_t *pos) -{ - loff_t i; - struct tpm_bios_log *log = m->private; - void *addr = log->bios_event_log; - void *limit = log->bios_event_log_end; - struct tcpa_event *event; - - /* read over *pos measurements */ - for (i = 0; i < *pos; i++) { - event = addr; - - if ((addr + sizeof(struct tcpa_event)) < limit) { - if (event->event_type == 0 && event->event_size == 0) - return NULL; - addr += sizeof(struct tcpa_event) + event->event_size; - } - } - - /* now check if current entry is valid */ - if ((addr + sizeof(struct tcpa_event)) >= limit) - return NULL; - - event = addr; - - if ((event->event_type == 0 && event->event_size == 0) || - ((addr + sizeof(struct tcpa_event) + event->event_size) >= limit)) - return NULL; - - return addr; -} - -static void *tpm_bios_measurements_next(struct seq_file *m, void *v, - loff_t *pos) -{ - struct tcpa_event *event = v; - struct tpm_bios_log *log = m->private; - void *limit = log->bios_event_log_end; - - v += sizeof(struct tcpa_event) + event->event_size; - - /* now check if current entry is valid */ - if ((v + sizeof(struct tcpa_event)) >= limit) - return NULL; - - event = v; - - if (event->event_type == 0 && event->event_size == 0) - return NULL; - - if ((event->event_type == 0 && event->event_size == 0) || - ((v + sizeof(struct tcpa_event) + event->event_size) >= limit)) - return NULL; - - (*pos)++; - return v; -} - -static void tpm_bios_measurements_stop(struct seq_file *m, void *v) -{ -} - -static int get_event_name(char *dest, struct tcpa_event *event, - unsigned char * event_entry) -{ - const char *name = ""; - char data[40] = ""; - int i, n_len = 0, d_len = 0; - u32 event_id, event_data_size; - - switch(event->event_type) { - case PREBOOT: - case POST_CODE: - case UNUSED: - case NO_ACTION: - case SCRTM_CONTENTS: - case SCRTM_VERSION: - case CPU_MICROCODE: - case PLATFORM_CONFIG_FLAGS: - case TABLE_OF_DEVICES: - case COMPACT_HASH: - case IPL: - case IPL_PARTITION_DATA: - case NONHOST_CODE: - case NONHOST_CONFIG: - case NONHOST_INFO: - name = tcpa_event_type_strings[event->event_type]; - n_len = strlen(name); - break; - case SEPARATOR: - case ACTION: - if (MAX_TEXT_EVENT > event->event_size) { - name = event_entry; - n_len = event->event_size; - } - break; - case EVENT_TAG: - event_id = be32_to_cpu(event_entry); - event_data_size = be32_to_cpu(&event_entry[4]); - - /* ToDo Row data -> Base64 */ - - switch (event_id) { - case SMBIOS: - case BIS_CERT: - case CMOS: - case NVRAM: - case OPTION_ROM_EXEC: - case OPTION_ROM_CONFIG: - case OPTION_ROM_MICROCODE: - case S_CRTM_VERSION: - case S_CRTM_CONTENTS: - case POST_CONTENTS: - name = tcpa_pc_event_id_strings[event_id]; - n_len = strlen(name); - break; - case POST_BIOS_ROM: - case ESCD: - name = tcpa_pc_event_id_strings[event_id]; - n_len = strlen(name); - for (i = 0; i < 20; i++) - d_len += sprintf(data, "%02x", - event_entry[8 + i]); - break; - default: - break; - } - default: - break; - } - - return snprintf(dest, MAX_TEXT_EVENT, "[%.*s%.*s]", - n_len, name, d_len, data); - -} - -static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v) -{ - - char *eventname; - char data[4]; - u32 help; - int i, len; - struct tcpa_event *event = (struct tcpa_event *) v; - unsigned char *event_entry = - (unsigned char *) (v + sizeof(struct tcpa_event)); - - eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL); - if (!eventname) { - printk(KERN_ERR "%s: ERROR - No Memory for event name\n ", - __func__); - return -ENOMEM; - } - - /* 1st: PCR used is in little-endian format (4 bytes) */ - help = le32_to_cpu(event->pcr_index); - memcpy(data, &help, 4); - for (i = 0; i < 4; i++) - seq_putc(m, data[i]); - - /* 2nd: SHA1 (20 bytes) */ - for (i = 0; i < 20; i++) - seq_putc(m, event->pcr_value[i]); - - /* 3rd: event type identifier (4 bytes) */ - help = le32_to_cpu(event->event_type); - memcpy(data, &help, 4); - for (i = 0; i < 4; i++) - seq_putc(m, data[i]); - - len = 0; - - len += get_event_name(eventname, event, event_entry); - - /* 4th: filename <= 255 + \'0' delimiter */ - if (len > TCG_EVENT_NAME_LEN_MAX) - len = TCG_EVENT_NAME_LEN_MAX; - - for (i = 0; i < len; i++) - seq_putc(m, eventname[i]); - - /* 5th: delimiter */ - seq_putc(m, '\0'); - - return 0; -} - -static int tpm_bios_measurements_release(struct inode *inode, - struct file *file) -{ - struct seq_file *seq = file->private_data; - struct tpm_bios_log *log = seq->private; - - if (log) { - kfree(log->bios_event_log); - kfree(log); - } - - return seq_release(inode, file); -} - -static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v) -{ - int len = 0; - int i; - char *eventname; - struct tcpa_event *event = v; - unsigned char *event_entry = - (unsigned char *) (v + sizeof(struct tcpa_event)); - - eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL); - if (!eventname) { - printk(KERN_ERR "%s: ERROR - No Memory for event name\n ", - __func__); - return -EFAULT; - } - - seq_printf(m, "%2d ", event->pcr_index); - - /* 2nd: SHA1 */ - for (i = 0; i < 20; i++) - seq_printf(m, "%02x", event->pcr_value[i]); - - /* 3rd: event type identifier */ - seq_printf(m, " %02x", event->event_type); - - len += get_event_name(eventname, event, event_entry); - - /* 4th: eventname <= max + \'0' delimiter */ - seq_printf(m, " %s\n", eventname); - - return 0; -} - -static struct seq_operations tpm_ascii_b_measurments_seqops = { - .start = tpm_bios_measurements_start, - .next = tpm_bios_measurements_next, - .stop = tpm_bios_measurements_stop, - .show = tpm_ascii_bios_measurements_show, -}; - -static struct seq_operations tpm_binary_b_measurments_seqops = { - .start = tpm_bios_measurements_start, - .next = tpm_bios_measurements_next, - .stop = tpm_bios_measurements_stop, - .show = tpm_binary_bios_measurements_show, -}; - -/* read binary bios log */ -static int read_log(struct tpm_bios_log *log) -{ - struct acpi_tcpa *buff; - acpi_status status; - void *virt; - - if (log->bios_event_log != NULL) { - printk(KERN_ERR - "%s: ERROR - Eventlog already initialized\n", - __func__); - return -EFAULT; - } - - /* Find TCPA entry in RSDT (ACPI_LOGICAL_ADDRESSING) */ - status = acpi_get_firmware_table(ACPI_TCPA_SIG, 1, - ACPI_LOGICAL_ADDRESSING, - (struct acpi_table_header **) - &buff); - - if (ACPI_FAILURE(status)) { - printk(KERN_ERR "%s: ERROR - Could not get TCPA table\n", - __func__); - return -EIO; - } - - if (buff->log_max_len == 0) { - printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__); - return -EIO; - } - - /* malloc EventLog space */ - log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL); - if (!log->bios_event_log) { - printk - ("%s: ERROR - Not enough Memory for BIOS measurements\n", - __func__); - return -ENOMEM; - } - - log->bios_event_log_end = log->bios_event_log + buff->log_max_len; - - acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, &virt); - - memcpy(log->bios_event_log, virt, buff->log_max_len); - - acpi_os_unmap_memory(virt, buff->log_max_len); - return 0; -} - -static int tpm_ascii_bios_measurements_open(struct inode *inode, - struct file *file) -{ - int err; - struct tpm_bios_log *log; - struct seq_file *seq; - - log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL); - if (!log) - return -ENOMEM; - - if ((err = read_log(log))) - return err; - - /* now register seq file */ - err = seq_open(file, &tpm_ascii_b_measurments_seqops); - if (!err) { - seq = file->private_data; - seq->private = log; - } else { - kfree(log->bios_event_log); - kfree(log); - } - return err; -} - -struct file_operations tpm_ascii_bios_measurements_ops = { - .open = tpm_ascii_bios_measurements_open, - .read = seq_read, - .llseek = seq_lseek, - .release = tpm_bios_measurements_release, -}; - -static int tpm_binary_bios_measurements_open(struct inode *inode, - struct file *file) -{ - int err; - struct tpm_bios_log *log; - struct seq_file *seq; - - log = kzalloc(sizeof(struct tpm_bios_log), GFP_KERNEL); - if (!log) - return -ENOMEM; - - if ((err = read_log(log))) - return err; - - /* now register seq file */ - err = seq_open(file, &tpm_binary_b_measurments_seqops); - if (!err) { - seq = file->private_data; - seq->private = log; - } else { - kfree(log->bios_event_log); - kfree(log); - } - return err; -} - -struct file_operations tpm_binary_bios_measurements_ops = { - .open = tpm_binary_bios_measurements_open, - .read = seq_read, - .llseek = seq_lseek, - .release = tpm_bios_measurements_release, -}; - -struct dentry **tpm_bios_log_setup(char *name) -{ - struct dentry **ret = NULL, *tpm_dir, *bin_file, *ascii_file; - - tpm_dir = securityfs_create_dir(name, NULL); - if (!tpm_dir) - goto out; - - bin_file = - securityfs_create_file("binary_bios_measurements", - S_IRUSR | S_IRGRP, tpm_dir, NULL, - &tpm_binary_bios_measurements_ops); - if (!bin_file) - goto out_tpm; - - ascii_file = - securityfs_create_file("ascii_bios_measurements", - S_IRUSR | S_IRGRP, tpm_dir, NULL, - &tpm_ascii_bios_measurements_ops); - if (!ascii_file) - goto out_bin; - - ret = kmalloc(3 * sizeof(struct dentry *), GFP_KERNEL); - if (!ret) - goto out_ascii; - - ret[0] = ascii_file; - ret[1] = bin_file; - ret[2] = tpm_dir; - - return ret; - -out_ascii: - securityfs_remove(ascii_file); -out_bin: - securityfs_remove(bin_file); -out_tpm: - securityfs_remove(tpm_dir); -out: - return NULL; -} -EXPORT_SYMBOL_GPL(tpm_bios_log_setup); - -void tpm_bios_log_teardown(struct dentry **lst) -{ - int i; - - for (i = 0; i < 3; i++) - securityfs_remove(lst[i]); -} -EXPORT_SYMBOL_GPL(tpm_bios_log_teardown); diff --git a/trunk/drivers/char/vr41xx_giu.c b/trunk/drivers/char/vr41xx_giu.c index a5b18e086a94..9ac6d43437b3 100644 --- a/trunk/drivers/char/vr41xx_giu.c +++ b/trunk/drivers/char/vr41xx_giu.c @@ -718,7 +718,7 @@ static struct platform_driver giu_device_driver = { }, }; -static int __init vr41xx_giu_init(void) +static int __devinit vr41xx_giu_init(void) { int retval; @@ -733,7 +733,7 @@ static int __init vr41xx_giu_init(void) return retval; } -static void __exit vr41xx_giu_exit(void) +static void __devexit vr41xx_giu_exit(void) { platform_driver_unregister(&giu_device_driver); diff --git a/trunk/drivers/char/watchdog/mpc8xx_wdt.c b/trunk/drivers/char/watchdog/mpc8xx_wdt.c index b2fc71e20850..56d62ba7c6ce 100644 --- a/trunk/drivers/char/watchdog/mpc8xx_wdt.c +++ b/trunk/drivers/char/watchdog/mpc8xx_wdt.c @@ -18,7 +18,6 @@ #include #include #include -#include #include static unsigned long wdt_opened; @@ -26,26 +25,18 @@ static int wdt_status; static void mpc8xx_wdt_handler_disable(void) { - volatile uint __iomem *piscr; - piscr = (uint *)&((immap_t*)IMAP_ADDR)->im_sit.sit_piscr; + volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR; - if (!m8xx_has_internal_rtc) - m8xx_wdt_stop_timer(); - else - out_be32(piscr, in_be32(piscr) & ~(PISCR_PIE | PISCR_PTE)); + imap->im_sit.sit_piscr &= ~(PISCR_PIE | PISCR_PTE); printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler deactivated\n"); } static void mpc8xx_wdt_handler_enable(void) { - volatile uint __iomem *piscr; - piscr = (uint *)&((immap_t*)IMAP_ADDR)->im_sit.sit_piscr; + volatile immap_t *imap = (volatile immap_t *)IMAP_ADDR; - if (!m8xx_has_internal_rtc) - m8xx_wdt_install_timer(); - else - out_be32(piscr, in_be32(piscr) | PISCR_PIE | PISCR_PTE); + imap->im_sit.sit_piscr |= PISCR_PIE | PISCR_PTE; printk(KERN_NOTICE "mpc8xx_wdt: keep-alive handler activated\n"); } @@ -77,6 +68,9 @@ static int mpc8xx_wdt_release(struct inode *inode, struct file *file) static ssize_t mpc8xx_wdt_write(struct file *file, const char *data, size_t len, loff_t * ppos) { + if (ppos != &file->f_pos) + return -ESPIPE; + if (len) m8xx_wdt_reset(); diff --git a/trunk/drivers/char/watchdog/wdt977.c b/trunk/drivers/char/watchdog/wdt977.c index 3843900e94c4..44d49dfacbb3 100644 --- a/trunk/drivers/char/watchdog/wdt977.c +++ b/trunk/drivers/char/watchdog/wdt977.c @@ -1,5 +1,5 @@ /* - * Wdt977 0.04: A Watchdog Device for Netwinder W83977AF chip + * Wdt977 0.03: A Watchdog Device for Netwinder W83977AF chip * * (c) Copyright 1998 Rebel.com (Woody Suwalski ) * @@ -18,8 +18,6 @@ * from minutes to seconds. * 07-Jul-2003 Daniele Bellucci: Audit return code of misc_register in * nwwatchdog_init. - * 25-Oct-2005 Woody Suwalski: Convert addresses to #defs, add spinlocks - * remove limitiation to be used on Netwinders only */ #include @@ -30,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -40,18 +37,8 @@ #include #include -#define WATCHDOG_VERSION "0.04" -#define WATCHDOG_NAME "Wdt977" -#define PFX WATCHDOG_NAME ": " -#define DRIVER_VERSION WATCHDOG_NAME " driver, v" WATCHDOG_VERSION "\n" - -#define IO_INDEX_PORT 0x370 /* on some systems it can be 0x3F0 */ -#define IO_DATA_PORT (IO_INDEX_PORT+1) - -#define UNLOCK_DATA 0x87 -#define LOCK_DATA 0xAA -#define DEVICE_REGISTER 0x07 - +#define PFX "Wdt977: " +#define WATCHDOG_MINOR 130 #define DEFAULT_TIMEOUT 60 /* default timeout in seconds */ @@ -60,7 +47,6 @@ static int timeoutM; /* timeout in minutes */ static unsigned long timer_alive; static int testmode; static char expect_close; -static spinlock_t spinlock; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout,"Watchdog timeout in seconds (60..15300), default=" __MODULE_STRING(DEFAULT_TIMEOUT) ")"); @@ -77,13 +63,9 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CON static int wdt977_start(void) { - unsigned long flags; - - spin_lock_irqsave(&spinlock, flags); - /* unlock the SuperIO chip */ - outb_p(UNLOCK_DATA, IO_INDEX_PORT); - outb_p(UNLOCK_DATA, IO_INDEX_PORT); + outb(0x87,0x370); + outb(0x87,0x370); /* select device Aux2 (device=8) and set watchdog regs F2, F3 and F4 * F2 has the timeout in minutes @@ -91,29 +73,28 @@ static int wdt977_start(void) * at timeout, and to reset timer on kbd/mouse activity (not impl.) * F4 is used to just clear the TIMEOUT'ed state (bit 0) */ - outb_p(DEVICE_REGISTER, IO_INDEX_PORT); - outb_p(0x08, IO_DATA_PORT); - outb_p(0xF2, IO_INDEX_PORT); - outb_p(timeoutM, IO_DATA_PORT); - outb_p(0xF3, IO_INDEX_PORT); - outb_p(0x00, IO_DATA_PORT); /* another setting is 0E for kbd/mouse/LED */ - outb_p(0xF4, IO_INDEX_PORT); - outb_p(0x00, IO_DATA_PORT); + outb(0x07,0x370); + outb(0x08,0x371); + outb(0xF2,0x370); + outb(timeoutM,0x371); + outb(0xF3,0x370); + outb(0x00,0x371); /* another setting is 0E for kbd/mouse/LED */ + outb(0xF4,0x370); + outb(0x00,0x371); /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ /* in test mode watch the bit 1 on F4 to indicate "triggered" */ if (!testmode) { - outb_p(DEVICE_REGISTER, IO_INDEX_PORT); - outb_p(0x07, IO_DATA_PORT); - outb_p(0xE6, IO_INDEX_PORT); - outb_p(0x08, IO_DATA_PORT); + outb(0x07,0x370); + outb(0x07,0x371); + outb(0xE6,0x370); + outb(0x08,0x371); } /* lock the SuperIO chip */ - outb_p(LOCK_DATA, IO_INDEX_PORT); + outb(0xAA,0x370); - spin_unlock_irqrestore(&spinlock, flags); printk(KERN_INFO PFX "activated.\n"); return 0; @@ -125,39 +106,35 @@ static int wdt977_start(void) static int wdt977_stop(void) { - unsigned long flags; - spin_lock_irqsave(&spinlock, flags); - /* unlock the SuperIO chip */ - outb_p(UNLOCK_DATA, IO_INDEX_PORT); - outb_p(UNLOCK_DATA, IO_INDEX_PORT); + outb(0x87,0x370); + outb(0x87,0x370); /* select device Aux2 (device=8) and set watchdog regs F2,F3 and F4 * F3 is reset to its default state * F4 can clear the TIMEOUT'ed state (bit 0) - back to default * We can not use GP17 as a PowerLed, as we use its usage as a RedLed */ - outb_p(DEVICE_REGISTER, IO_INDEX_PORT); - outb_p(0x08, IO_DATA_PORT); - outb_p(0xF2, IO_INDEX_PORT); - outb_p(0xFF, IO_DATA_PORT); - outb_p(0xF3, IO_INDEX_PORT); - outb_p(0x00, IO_DATA_PORT); - outb_p(0xF4, IO_INDEX_PORT); - outb_p(0x00, IO_DATA_PORT); - outb_p(0xF2, IO_INDEX_PORT); - outb_p(0x00, IO_DATA_PORT); + outb(0x07,0x370); + outb(0x08,0x371); + outb(0xF2,0x370); + outb(0xFF,0x371); + outb(0xF3,0x370); + outb(0x00,0x371); + outb(0xF4,0x370); + outb(0x00,0x371); + outb(0xF2,0x370); + outb(0x00,0x371); /* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */ - outb_p(DEVICE_REGISTER, IO_INDEX_PORT); - outb_p(0x07, IO_DATA_PORT); - outb_p(0xE6, IO_INDEX_PORT); - outb_p(0x08, IO_DATA_PORT); + outb(0x07,0x370); + outb(0x07,0x371); + outb(0xE6,0x370); + outb(0x08,0x371); /* lock the SuperIO chip */ - outb_p(LOCK_DATA, IO_INDEX_PORT); + outb(0xAA,0x370); - spin_unlock_irqrestore(&spinlock, flags); printk(KERN_INFO PFX "shutdown.\n"); return 0; @@ -170,23 +147,19 @@ static int wdt977_stop(void) static int wdt977_keepalive(void) { - unsigned long flags; - spin_lock_irqsave(&spinlock, flags); - /* unlock the SuperIO chip */ - outb_p(UNLOCK_DATA, IO_INDEX_PORT); - outb_p(UNLOCK_DATA, IO_INDEX_PORT); + outb(0x87,0x370); + outb(0x87,0x370); /* select device Aux2 (device=8) and kicks watchdog reg F2 */ /* F2 has the timeout in minutes */ - outb_p(DEVICE_REGISTER, IO_INDEX_PORT); - outb_p(0x08, IO_DATA_PORT); - outb_p(0xF2, IO_INDEX_PORT); - outb_p(timeoutM, IO_DATA_PORT); + outb(0x07,0x370); + outb(0x08,0x371); + outb(0xF2,0x370); + outb(timeoutM,0x371); /* lock the SuperIO chip */ - outb_p(LOCK_DATA, IO_INDEX_PORT); - spin_unlock_irqrestore(&spinlock, flags); + outb(0xAA,0x370); return 0; } @@ -225,26 +198,22 @@ static int wdt977_set_timeout(int t) static int wdt977_get_status(int *status) { int new_status; - unsigned long flags; - spin_lock_irqsave(&spinlock, flags); + *status=0; /* unlock the SuperIO chip */ - outb_p(UNLOCK_DATA, IO_INDEX_PORT); - outb_p(UNLOCK_DATA, IO_INDEX_PORT); + outb(0x87,0x370); + outb(0x87,0x370); /* select device Aux2 (device=8) and read watchdog reg F4 */ - outb_p(DEVICE_REGISTER, IO_INDEX_PORT); - outb_p(0x08, IO_DATA_PORT); - outb_p(0xF4, IO_INDEX_PORT); - new_status = inb_p(IO_DATA_PORT); + outb(0x07,0x370); + outb(0x08,0x371); + outb(0xF4,0x370); + new_status = inb(0x371); /* lock the SuperIO chip */ - outb_p(LOCK_DATA, IO_INDEX_PORT); + outb(0xAA,0x370); - spin_unlock_irqrestore(&spinlock, flags); - - *status=0; if (new_status & 1) *status |= WDIOF_CARDRESET; @@ -280,8 +249,8 @@ static int wdt977_release(struct inode *inode, struct file *file) wdt977_stop(); clear_bit(0,&timer_alive); } else { - wdt977_keepalive(); printk(KERN_CRIT PFX "Unexpected close, not stopping watchdog!\n"); + wdt977_keepalive(); } expect_close = 0; return 0; @@ -302,17 +271,14 @@ static int wdt977_release(struct inode *inode, struct file *file) static ssize_t wdt977_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - if (count) - { - if (!nowayout) - { + if (count) { + if (!nowayout) { size_t i; /* In case it was set long ago */ expect_close = 0; - for (i = 0; i != count; i++) - { + for (i = 0; i != count; i++) { char c; if (get_user(c, buf + i)) return -EFAULT; @@ -321,7 +287,6 @@ static ssize_t wdt977_write(struct file *file, const char __user *buf, } } - /* someone wrote to us, we should restart timer */ wdt977_keepalive(); } return count; @@ -343,7 +308,7 @@ static struct watchdog_info ident = { WDIOF_MAGICCLOSE | WDIOF_KEEPALIVEPING, .firmware_version = 1, - .identity = WATCHDOG_NAME, + .identity = "Winbond 83977", }; static int wdt977_ioctl(struct inode *inode, struct file *file, @@ -440,81 +405,50 @@ static struct notifier_block wdt977_notifier = { .notifier_call = wdt977_notify_sys, }; -static int __init wd977_init(void) +static int __init nwwatchdog_init(void) { - int rc; - - //if (!machine_is_netwinder()) - // return -ENODEV; - - printk(KERN_INFO PFX DRIVER_VERSION); - - spin_lock_init(&spinlock); + int retval; + if (!machine_is_netwinder()) + return -ENODEV; /* Check that the timeout value is within it's range ; if not reset to the default */ - if (wdt977_set_timeout(timeout)) - { + if (wdt977_set_timeout(timeout)) { wdt977_set_timeout(DEFAULT_TIMEOUT); printk(KERN_INFO PFX "timeout value must be 60"); +MODULE_AUTHOR("Woody Suwalski "); MODULE_DESCRIPTION("W83977AF Watchdog driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); diff --git a/trunk/drivers/connector/cn_proc.c b/trunk/drivers/connector/cn_proc.c index 385e52930c02..969d2b4aaec0 100644 --- a/trunk/drivers/connector/cn_proc.c +++ b/trunk/drivers/connector/cn_proc.c @@ -34,14 +34,14 @@ static atomic_t proc_event_num_listeners = ATOMIC_INIT(0); static struct cb_id cn_proc_event_id = { CN_IDX_PROC, CN_VAL_PROC }; -/* proc_event_counts is used as the sequence number of the netlink message */ +/* proc_counts is used as the sequence number of the netlink message */ static DEFINE_PER_CPU(__u32, proc_event_counts) = { 0 }; static inline void get_seq(__u32 *ts, int *cpu) { *ts = get_cpu_var(proc_event_counts)++; *cpu = smp_processor_id(); - put_cpu_var(proc_event_counts); + put_cpu_var(proc_counts); } void proc_fork_connector(struct task_struct *task) diff --git a/trunk/drivers/i2c/busses/Kconfig b/trunk/drivers/i2c/busses/Kconfig index 08d5b8fed2dc..4010fe92e72b 100644 --- a/trunk/drivers/i2c/busses/Kconfig +++ b/trunk/drivers/i2c/busses/Kconfig @@ -236,17 +236,27 @@ config I2C_IXP2000 This support is also available as a module. If so, the module will be called i2c-ixp2000. -config I2C_POWERMAC - tristate "Powermac I2C interface" +config I2C_KEYWEST + tristate "Powermac Keywest I2C interface" depends on I2C && PPC_PMAC - default y help - This exposes the various PowerMac i2c interfaces to the linux i2c - layer and to userland. It is used by various drivers on the powemac - platform, thus should generally be enabled. + This supports the use of the I2C interface in the combo-I/O + chip on recent Apple machines. Say Y if you have such a machine. + + This support is also available as a module. If so, the module + will be called i2c-keywest. + +config I2C_PMAC_SMU + tristate "Powermac SMU I2C interface" + depends on I2C && PMAC_SMU + help + This supports the use of the I2C interface in the SMU + chip on recent Apple machines like the iMac G5. It is used + among others by the thermal control driver for those machines. + Say Y if you have such a machine. This support is also available as a module. If so, the module - will be called i2c-powermac. + will be called i2c-pmac-smu. config I2C_MPC tristate "MPC107/824x/85xx/52xx" diff --git a/trunk/drivers/i2c/busses/Makefile b/trunk/drivers/i2c/busses/Makefile index b44831dff683..f1df00f66c6c 100644 --- a/trunk/drivers/i2c/busses/Makefile +++ b/trunk/drivers/i2c/busses/Makefile @@ -19,7 +19,8 @@ obj-$(CONFIG_I2C_ISA) += i2c-isa.o obj-$(CONFIG_I2C_ITE) += i2c-ite.o obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o -obj-$(CONFIG_I2C_POWERMAC) += i2c-powermac.o +obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o +obj-$(CONFIG_I2C_PMAC_SMU) += i2c-pmac-smu.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o diff --git a/trunk/drivers/i2c/busses/i2c-keywest.c b/trunk/drivers/i2c/busses/i2c-keywest.c new file mode 100644 index 000000000000..d61f748278fc --- /dev/null +++ b/trunk/drivers/i2c/busses/i2c-keywest.c @@ -0,0 +1,751 @@ +/* + i2c Support for Apple Keywest I2C Bus Controller + + Copyright (c) 2001 Benjamin Herrenschmidt + + Original work by + + Copyright (c) 2000 Philip Edelbrock + + 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. + + Changes: + + 2001/12/13 BenH New implementation + 2001/12/15 BenH Add support for "byte" and "quick" + transfers. Add i2c_xfer routine. + 2003/09/21 BenH Rework state machine with Paulus help + 2004/01/21 BenH Merge in Greg KH changes, polled mode is back + 2004/02/05 BenH Merge 64 bits fixes from the g5 ppc64 tree + + My understanding of the various modes supported by keywest are: + + - Dumb mode : not implemented, probably direct tweaking of lines + - Standard mode : simple i2c transaction of type + S Addr R/W A Data A Data ... T + - Standard sub mode : combined 8 bit subaddr write with data read + S Addr R/W A SubAddr A Data A Data ... T + - Combined mode : Subaddress and Data sequences appended with no stop + S Addr R/W A SubAddr S Addr R/W A Data A Data ... T + + Currently, this driver uses only Standard mode for i2c xfer, and + smbus byte & quick transfers ; and uses StandardSub mode for + other smbus transfers instead of combined as we need that for the + sound driver to be happy +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "i2c-keywest.h" + +#undef POLLED_MODE + +/* Some debug macros */ +#define WRONG_STATE(name) do {\ + pr_debug("KW: wrong state. Got %s, state: %s (isr: %02x)\n", \ + name, __kw_state_names[iface->state], isr); \ + } while(0) + +#ifdef DEBUG +static const char *__kw_state_names[] = { + "state_idle", + "state_addr", + "state_read", + "state_write", + "state_stop", + "state_dead" +}; +#endif /* DEBUG */ + +MODULE_AUTHOR("Benjamin Herrenschmidt "); +MODULE_DESCRIPTION("I2C driver for Apple's Keywest"); +MODULE_LICENSE("GPL"); + +#ifdef POLLED_MODE +/* Don't schedule, the g5 fan controller is too + * timing sensitive + */ +static u8 +wait_interrupt(struct keywest_iface* iface) +{ + int i; + u8 isr; + + for (i = 0; i < 200000; i++) { + isr = read_reg(reg_isr) & KW_I2C_IRQ_MASK; + if (isr != 0) + return isr; + udelay(10); + } + return isr; +} +#endif /* POLLED_MODE */ + +static void +do_stop(struct keywest_iface* iface, int result) +{ + write_reg(reg_control, KW_I2C_CTL_STOP); + iface->state = state_stop; + iface->result = result; +} + +/* Main state machine for standard & standard sub mode */ +static void +handle_interrupt(struct keywest_iface *iface, u8 isr) +{ + int ack; + + if (isr == 0) { + if (iface->state != state_stop) { + pr_debug("KW: Timeout !\n"); + do_stop(iface, -EIO); + } + if (iface->state == state_stop) { + ack = read_reg(reg_status); + if (!(ack & KW_I2C_STAT_BUSY)) { + iface->state = state_idle; + write_reg(reg_ier, 0x00); +#ifndef POLLED_MODE + complete(&iface->complete); +#endif /* POLLED_MODE */ + } + } + return; + } + + if (isr & KW_I2C_IRQ_ADDR) { + ack = read_reg(reg_status); + if (iface->state != state_addr) { + write_reg(reg_isr, KW_I2C_IRQ_ADDR); + WRONG_STATE("KW_I2C_IRQ_ADDR"); + do_stop(iface, -EIO); + return; + } + if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { + iface->state = state_stop; + iface->result = -ENODEV; + pr_debug("KW: NAK on address\n"); + } else { + /* Handle rw "quick" mode */ + if (iface->datalen == 0) { + do_stop(iface, 0); + } else if (iface->read_write == I2C_SMBUS_READ) { + iface->state = state_read; + if (iface->datalen > 1) + write_reg(reg_control, KW_I2C_CTL_AAK); + } else { + iface->state = state_write; + write_reg(reg_data, *(iface->data++)); + iface->datalen--; + } + } + write_reg(reg_isr, KW_I2C_IRQ_ADDR); + } + + if (isr & KW_I2C_IRQ_DATA) { + if (iface->state == state_read) { + *(iface->data++) = read_reg(reg_data); + write_reg(reg_isr, KW_I2C_IRQ_DATA); + iface->datalen--; + if (iface->datalen == 0) + iface->state = state_stop; + else if (iface->datalen == 1) + write_reg(reg_control, 0); + } else if (iface->state == state_write) { + /* Check ack status */ + ack = read_reg(reg_status); + if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { + pr_debug("KW: nack on data write (%x): %x\n", + iface->data[-1], ack); + do_stop(iface, -EIO); + } else if (iface->datalen) { + write_reg(reg_data, *(iface->data++)); + iface->datalen--; + } else { + write_reg(reg_control, KW_I2C_CTL_STOP); + iface->state = state_stop; + iface->result = 0; + } + write_reg(reg_isr, KW_I2C_IRQ_DATA); + } else { + write_reg(reg_isr, KW_I2C_IRQ_DATA); + WRONG_STATE("KW_I2C_IRQ_DATA"); + if (iface->state != state_stop) + do_stop(iface, -EIO); + } + } + + if (isr & KW_I2C_IRQ_STOP) { + write_reg(reg_isr, KW_I2C_IRQ_STOP); + if (iface->state != state_stop) { + WRONG_STATE("KW_I2C_IRQ_STOP"); + iface->result = -EIO; + } + iface->state = state_idle; + write_reg(reg_ier, 0x00); +#ifndef POLLED_MODE + complete(&iface->complete); +#endif /* POLLED_MODE */ + } + + if (isr & KW_I2C_IRQ_START) + write_reg(reg_isr, KW_I2C_IRQ_START); +} + +#ifndef POLLED_MODE + +/* Interrupt handler */ +static irqreturn_t +keywest_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + struct keywest_iface *iface = (struct keywest_iface *)dev_id; + unsigned long flags; + + spin_lock_irqsave(&iface->lock, flags); + del_timer(&iface->timeout_timer); + handle_interrupt(iface, read_reg(reg_isr)); + if (iface->state != state_idle) { + iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; + add_timer(&iface->timeout_timer); + } + spin_unlock_irqrestore(&iface->lock, flags); + return IRQ_HANDLED; +} + +static void +keywest_timeout(unsigned long data) +{ + struct keywest_iface *iface = (struct keywest_iface *)data; + unsigned long flags; + + pr_debug("timeout !\n"); + spin_lock_irqsave(&iface->lock, flags); + handle_interrupt(iface, read_reg(reg_isr)); + if (iface->state != state_idle) { + iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; + add_timer(&iface->timeout_timer); + } + spin_unlock_irqrestore(&iface->lock, flags); +} + +#endif /* POLLED_MODE */ + +/* + * SMBUS-type transfer entrypoint + */ +static s32 +keywest_smbus_xfer( struct i2c_adapter* adap, + u16 addr, + unsigned short flags, + char read_write, + u8 command, + int size, + union i2c_smbus_data* data) +{ + struct keywest_chan* chan = i2c_get_adapdata(adap); + struct keywest_iface* iface = chan->iface; + int len; + u8* buffer; + u16 cur_word; + int rc = 0; + + if (iface->state == state_dead) + return -ENXIO; + + /* Prepare datas & select mode */ + iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK; + switch (size) { + case I2C_SMBUS_QUICK: + len = 0; + buffer = NULL; + iface->cur_mode |= KW_I2C_MODE_STANDARD; + break; + case I2C_SMBUS_BYTE: + len = 1; + buffer = &data->byte; + iface->cur_mode |= KW_I2C_MODE_STANDARD; + break; + case I2C_SMBUS_BYTE_DATA: + len = 1; + buffer = &data->byte; + iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; + break; + case I2C_SMBUS_WORD_DATA: + len = 2; + cur_word = cpu_to_le16(data->word); + buffer = (u8 *)&cur_word; + iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; + break; + case I2C_SMBUS_BLOCK_DATA: + len = data->block[0]; + buffer = &data->block[1]; + iface->cur_mode |= KW_I2C_MODE_STANDARDSUB; + break; + default: + return -1; + } + + /* Turn a standardsub read into a combined mode access */ + if (read_write == I2C_SMBUS_READ + && (iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB) { + iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK; + iface->cur_mode |= KW_I2C_MODE_COMBINED; + } + + /* Original driver had this limitation */ + if (len > 32) + len = 32; + + if (pmac_low_i2c_lock(iface->node)) + return -ENXIO; + + pr_debug("chan: %d, addr: 0x%x, transfer len: %d, read: %d\n", + chan->chan_no, addr, len, read_write == I2C_SMBUS_READ); + + iface->data = buffer; + iface->datalen = len; + iface->state = state_addr; + iface->result = 0; + iface->read_write = read_write; + + /* Setup channel & clear pending irqs */ + write_reg(reg_isr, read_reg(reg_isr)); + write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4)); + write_reg(reg_status, 0); + + /* Set up address and r/w bit */ + write_reg(reg_addr, + (addr << 1) | ((read_write == I2C_SMBUS_READ) ? 0x01 : 0x00)); + + /* Set up the sub address */ + if ((iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB + || (iface->cur_mode & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED) + write_reg(reg_subaddr, command); + +#ifndef POLLED_MODE + /* Arm timeout */ + iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; + add_timer(&iface->timeout_timer); +#endif + + /* Start sending address & enable interrupt*/ + write_reg(reg_control, KW_I2C_CTL_XADDR); + write_reg(reg_ier, KW_I2C_IRQ_MASK); + +#ifdef POLLED_MODE + pr_debug("using polled mode...\n"); + /* State machine, to turn into an interrupt handler */ + while(iface->state != state_idle) { + unsigned long flags; + + u8 isr = wait_interrupt(iface); + spin_lock_irqsave(&iface->lock, flags); + handle_interrupt(iface, isr); + spin_unlock_irqrestore(&iface->lock, flags); + } +#else /* POLLED_MODE */ + pr_debug("using interrupt mode...\n"); + wait_for_completion(&iface->complete); +#endif /* POLLED_MODE */ + + rc = iface->result; + pr_debug("transfer done, result: %d\n", rc); + + if (rc == 0 && size == I2C_SMBUS_WORD_DATA && read_write == I2C_SMBUS_READ) + data->word = le16_to_cpu(cur_word); + + /* Release sem */ + pmac_low_i2c_unlock(iface->node); + + return rc; +} + +/* + * Generic i2c master transfer entrypoint + */ +static int +keywest_xfer( struct i2c_adapter *adap, + struct i2c_msg *msgs, + int num) +{ + struct keywest_chan* chan = i2c_get_adapdata(adap); + struct keywest_iface* iface = chan->iface; + struct i2c_msg *pmsg; + int i, completed; + int rc = 0; + + if (iface->state == state_dead) + return -ENXIO; + + if (pmac_low_i2c_lock(iface->node)) + return -ENXIO; + + /* Set adapter to standard mode */ + iface->cur_mode &= ~KW_I2C_MODE_MODE_MASK; + iface->cur_mode |= KW_I2C_MODE_STANDARD; + + completed = 0; + for (i = 0; rc >= 0 && i < num;) { + u8 addr; + + pmsg = &msgs[i++]; + addr = pmsg->addr; + if (pmsg->flags & I2C_M_TEN) { + printk(KERN_ERR "i2c-keywest: 10 bits addr not supported !\n"); + rc = -EINVAL; + break; + } + pr_debug("xfer: chan: %d, doing %s %d bytes to 0x%02x - %d of %d messages\n", + chan->chan_no, + pmsg->flags & I2C_M_RD ? "read" : "write", + pmsg->len, addr, i, num); + + /* Setup channel & clear pending irqs */ + write_reg(reg_mode, iface->cur_mode | (chan->chan_no << 4)); + write_reg(reg_isr, read_reg(reg_isr)); + write_reg(reg_status, 0); + + iface->data = pmsg->buf; + iface->datalen = pmsg->len; + iface->state = state_addr; + iface->result = 0; + if (pmsg->flags & I2C_M_RD) + iface->read_write = I2C_SMBUS_READ; + else + iface->read_write = I2C_SMBUS_WRITE; + + /* Set up address and r/w bit */ + if (pmsg->flags & I2C_M_REV_DIR_ADDR) + addr ^= 1; + write_reg(reg_addr, + (addr << 1) | + ((iface->read_write == I2C_SMBUS_READ) ? 0x01 : 0x00)); + +#ifndef POLLED_MODE + /* Arm timeout */ + iface->timeout_timer.expires = jiffies + POLL_TIMEOUT; + add_timer(&iface->timeout_timer); +#endif + + /* Start sending address & enable interrupt*/ + write_reg(reg_ier, KW_I2C_IRQ_MASK); + write_reg(reg_control, KW_I2C_CTL_XADDR); + +#ifdef POLLED_MODE + pr_debug("using polled mode...\n"); + /* State machine, to turn into an interrupt handler */ + while(iface->state != state_idle) { + u8 isr = wait_interrupt(iface); + handle_interrupt(iface, isr); + } +#else /* POLLED_MODE */ + pr_debug("using interrupt mode...\n"); + wait_for_completion(&iface->complete); +#endif /* POLLED_MODE */ + + rc = iface->result; + if (rc == 0) + completed++; + pr_debug("transfer done, result: %d\n", rc); + } + + /* Release sem */ + pmac_low_i2c_unlock(iface->node); + + return completed; +} + +static u32 +keywest_func(struct i2c_adapter * adapter) +{ + return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA; +} + +/* For now, we only handle combined mode (smbus) */ +static struct i2c_algorithm keywest_algorithm = { + .smbus_xfer = keywest_smbus_xfer, + .master_xfer = keywest_xfer, + .functionality = keywest_func, +}; + + +static int +create_iface(struct device_node *np, struct device *dev) +{ + unsigned long steps; + unsigned bsteps, tsize, i, nchan, addroffset; + struct keywest_iface* iface; + u32 *psteps, *prate; + int rc; + + if (np->n_intrs < 1 || np->n_addrs < 1) { + printk(KERN_ERR "%s: Missing interrupt or address !\n", + np->full_name); + return -ENODEV; + } + if (pmac_low_i2c_lock(np)) + return -ENODEV; + + psteps = (u32 *)get_property(np, "AAPL,address-step", NULL); + steps = psteps ? (*psteps) : 0x10; + + /* Hrm... maybe we can be smarter here */ + for (bsteps = 0; (steps & 0x01) == 0; bsteps++) + steps >>= 1; + + if (np->parent->name[0] == 'u') { + nchan = 2; + addroffset = 3; + } else { + addroffset = 0; + nchan = 1; + } + + tsize = sizeof(struct keywest_iface) + + (sizeof(struct keywest_chan) + 4) * nchan; + iface = kzalloc(tsize, GFP_KERNEL); + if (iface == NULL) { + printk(KERN_ERR "i2c-keywest: can't allocate inteface !\n"); + pmac_low_i2c_unlock(np); + return -ENOMEM; + } + spin_lock_init(&iface->lock); + init_completion(&iface->complete); + iface->node = of_node_get(np); + iface->bsteps = bsteps; + iface->chan_count = nchan; + iface->state = state_idle; + iface->irq = np->intrs[0].line; + iface->channels = (struct keywest_chan *) + (((unsigned long)(iface + 1) + 3UL) & ~3UL); + iface->base = ioremap(np->addrs[0].address + addroffset, + np->addrs[0].size); + if (!iface->base) { + printk(KERN_ERR "i2c-keywest: can't map inteface !\n"); + kfree(iface); + pmac_low_i2c_unlock(np); + return -ENOMEM; + } + +#ifndef POLLED_MODE + init_timer(&iface->timeout_timer); + iface->timeout_timer.function = keywest_timeout; + iface->timeout_timer.data = (unsigned long)iface; +#endif + + /* Select interface rate */ + iface->cur_mode = KW_I2C_MODE_100KHZ; + prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL); + if (prate) switch(*prate) { + case 100: + iface->cur_mode = KW_I2C_MODE_100KHZ; + break; + case 50: + iface->cur_mode = KW_I2C_MODE_50KHZ; + break; + case 25: + iface->cur_mode = KW_I2C_MODE_25KHZ; + break; + default: + printk(KERN_WARNING "i2c-keywest: unknown rate %ldKhz, using 100KHz\n", + (long)*prate); + } + + /* Select standard mode by default */ + iface->cur_mode |= KW_I2C_MODE_STANDARD; + + /* Write mode */ + write_reg(reg_mode, iface->cur_mode); + + /* Switch interrupts off & clear them*/ + write_reg(reg_ier, 0x00); + write_reg(reg_isr, KW_I2C_IRQ_MASK); + +#ifndef POLLED_MODE + /* Request chip interrupt */ + rc = request_irq(iface->irq, keywest_irq, SA_INTERRUPT, "keywest i2c", iface); + if (rc) { + printk(KERN_ERR "i2c-keywest: can't get IRQ %d !\n", iface->irq); + iounmap(iface->base); + kfree(iface); + pmac_low_i2c_unlock(np); + return -ENODEV; + } +#endif /* POLLED_MODE */ + + pmac_low_i2c_unlock(np); + dev_set_drvdata(dev, iface); + + for (i=0; ichannels[i]; + + sprintf(chan->adapter.name, "%s %d", np->parent->name, i); + chan->iface = iface; + chan->chan_no = i; + chan->adapter.algo = &keywest_algorithm; + chan->adapter.algo_data = NULL; + chan->adapter.client_register = NULL; + chan->adapter.client_unregister = NULL; + i2c_set_adapdata(&chan->adapter, chan); + chan->adapter.dev.parent = dev; + + rc = i2c_add_adapter(&chan->adapter); + if (rc) { + printk("i2c-keywest.c: Adapter %s registration failed\n", + chan->adapter.name); + i2c_set_adapdata(&chan->adapter, NULL); + } + } + + printk(KERN_INFO "Found KeyWest i2c on \"%s\", %d channel%s, stepping: %d bits\n", + np->parent->name, nchan, nchan > 1 ? "s" : "", bsteps); + + return 0; +} + +static int +dispose_iface(struct device *dev) +{ + struct keywest_iface *iface = dev_get_drvdata(dev); + int i, rc; + + /* Make sure we stop all activity */ + if (pmac_low_i2c_lock(iface->node)) + return -ENODEV; + +#ifndef POLLED_MODE + spin_lock_irq(&iface->lock); + while (iface->state != state_idle) { + spin_unlock_irq(&iface->lock); + msleep(100); + spin_lock_irq(&iface->lock); + } +#endif /* POLLED_MODE */ + iface->state = state_dead; +#ifndef POLLED_MODE + spin_unlock_irq(&iface->lock); + free_irq(iface->irq, iface); +#endif /* POLLED_MODE */ + + pmac_low_i2c_unlock(iface->node); + + /* Release all channels */ + for (i=0; ichan_count; i++) { + struct keywest_chan* chan = &iface->channels[i]; + if (i2c_get_adapdata(&chan->adapter) == NULL) + continue; + rc = i2c_del_adapter(&chan->adapter); + i2c_set_adapdata(&chan->adapter, NULL); + /* We aren't that prepared to deal with this... */ + if (rc) + printk("i2c-keywest.c: i2c_del_adapter failed, that's bad !\n"); + } + iounmap(iface->base); + dev_set_drvdata(dev, NULL); + of_node_put(iface->node); + kfree(iface); + + return 0; +} + +static int +create_iface_macio(struct macio_dev* dev, const struct of_device_id *match) +{ + return create_iface(dev->ofdev.node, &dev->ofdev.dev); +} + +static int +dispose_iface_macio(struct macio_dev* dev) +{ + return dispose_iface(&dev->ofdev.dev); +} + +static int +create_iface_of_platform(struct of_device* dev, const struct of_device_id *match) +{ + return create_iface(dev->node, &dev->dev); +} + +static int +dispose_iface_of_platform(struct of_device* dev) +{ + return dispose_iface(&dev->dev); +} + +static struct of_device_id i2c_keywest_match[] = +{ + { + .type = "i2c", + .compatible = "keywest" + }, + {}, +}; + +static struct macio_driver i2c_keywest_macio_driver = +{ + .owner = THIS_MODULE, + .name = "i2c-keywest", + .match_table = i2c_keywest_match, + .probe = create_iface_macio, + .remove = dispose_iface_macio +}; + +static struct of_platform_driver i2c_keywest_of_platform_driver = +{ + .owner = THIS_MODULE, + .name = "i2c-keywest", + .match_table = i2c_keywest_match, + .probe = create_iface_of_platform, + .remove = dispose_iface_of_platform +}; + +static int __init +i2c_keywest_init(void) +{ + of_register_driver(&i2c_keywest_of_platform_driver); + macio_register_driver(&i2c_keywest_macio_driver); + + return 0; +} + +static void __exit +i2c_keywest_cleanup(void) +{ + of_unregister_driver(&i2c_keywest_of_platform_driver); + macio_unregister_driver(&i2c_keywest_macio_driver); +} + +module_init(i2c_keywest_init); +module_exit(i2c_keywest_cleanup); diff --git a/trunk/drivers/i2c/busses/i2c-keywest.h b/trunk/drivers/i2c/busses/i2c-keywest.h new file mode 100644 index 000000000000..c5022e1ca6ff --- /dev/null +++ b/trunk/drivers/i2c/busses/i2c-keywest.h @@ -0,0 +1,108 @@ +#ifndef __I2C_KEYWEST_H__ +#define __I2C_KEYWEST_H__ + +/* The Tumbler audio equalizer can be really slow sometimes */ +#define POLL_TIMEOUT (2*HZ) + +/* Register indices */ +typedef enum { + reg_mode = 0, + reg_control, + reg_status, + reg_isr, + reg_ier, + reg_addr, + reg_subaddr, + reg_data +} reg_t; + + +/* Mode register */ +#define KW_I2C_MODE_100KHZ 0x00 +#define KW_I2C_MODE_50KHZ 0x01 +#define KW_I2C_MODE_25KHZ 0x02 +#define KW_I2C_MODE_DUMB 0x00 +#define KW_I2C_MODE_STANDARD 0x04 +#define KW_I2C_MODE_STANDARDSUB 0x08 +#define KW_I2C_MODE_COMBINED 0x0C +#define KW_I2C_MODE_MODE_MASK 0x0C +#define KW_I2C_MODE_CHAN_MASK 0xF0 + +/* Control register */ +#define KW_I2C_CTL_AAK 0x01 +#define KW_I2C_CTL_XADDR 0x02 +#define KW_I2C_CTL_STOP 0x04 +#define KW_I2C_CTL_START 0x08 + +/* Status register */ +#define KW_I2C_STAT_BUSY 0x01 +#define KW_I2C_STAT_LAST_AAK 0x02 +#define KW_I2C_STAT_LAST_RW 0x04 +#define KW_I2C_STAT_SDA 0x08 +#define KW_I2C_STAT_SCL 0x10 + +/* IER & ISR registers */ +#define KW_I2C_IRQ_DATA 0x01 +#define KW_I2C_IRQ_ADDR 0x02 +#define KW_I2C_IRQ_STOP 0x04 +#define KW_I2C_IRQ_START 0x08 +#define KW_I2C_IRQ_MASK 0x0F + +/* Physical interface */ +struct keywest_iface +{ + struct device_node *node; + void __iomem * base; + unsigned bsteps; + int irq; + spinlock_t lock; + struct keywest_chan *channels; + unsigned chan_count; + u8 cur_mode; + char read_write; + u8 *data; + unsigned datalen; + int state; + int result; + struct timer_list timeout_timer; + struct completion complete; +}; + +enum { + state_idle, + state_addr, + state_read, + state_write, + state_stop, + state_dead +}; + +/* Channel on an interface */ +struct keywest_chan +{ + struct i2c_adapter adapter; + struct keywest_iface* iface; + unsigned chan_no; +}; + +/* Register access */ + +static inline u8 __read_reg(struct keywest_iface *iface, reg_t reg) +{ + return in_8(iface->base + + (((unsigned)reg) << iface->bsteps)); +} + +static inline void __write_reg(struct keywest_iface *iface, reg_t reg, u8 val) +{ + out_8(iface->base + + (((unsigned)reg) << iface->bsteps), val); + (void)__read_reg(iface, reg_subaddr); +} + +#define write_reg(reg, val) __write_reg(iface, reg, val) +#define read_reg(reg) __read_reg(iface, reg) + + + +#endif /* __I2C_KEYWEST_H__ */ diff --git a/trunk/drivers/i2c/busses/i2c-pmac-smu.c b/trunk/drivers/i2c/busses/i2c-pmac-smu.c new file mode 100644 index 000000000000..bfefe7f7a53d --- /dev/null +++ b/trunk/drivers/i2c/busses/i2c-pmac-smu.c @@ -0,0 +1,315 @@ +/* + i2c Support for Apple SMU Controller + + Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp. + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + 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. + +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int probe; + +MODULE_AUTHOR("Benjamin Herrenschmidt "); +MODULE_DESCRIPTION("I2C driver for Apple's SMU"); +MODULE_LICENSE("GPL"); +module_param(probe, bool, 0); + + +/* Physical interface */ +struct smu_iface +{ + struct i2c_adapter adapter; + struct completion complete; + u32 busid; +}; + +static void smu_i2c_done(struct smu_i2c_cmd *cmd, void *misc) +{ + struct smu_iface *iface = misc; + complete(&iface->complete); +} + +/* + * SMBUS-type transfer entrypoint + */ +static s32 smu_smbus_xfer( struct i2c_adapter* adap, + u16 addr, + unsigned short flags, + char read_write, + u8 command, + int size, + union i2c_smbus_data* data) +{ + struct smu_iface *iface = i2c_get_adapdata(adap); + struct smu_i2c_cmd cmd; + int rc = 0; + int read = (read_write == I2C_SMBUS_READ); + + cmd.info.bus = iface->busid; + cmd.info.devaddr = (addr << 1) | (read ? 0x01 : 0x00); + + /* Prepare datas & select mode */ + switch (size) { + case I2C_SMBUS_QUICK: + cmd.info.type = SMU_I2C_TRANSFER_SIMPLE; + cmd.info.datalen = 0; + break; + case I2C_SMBUS_BYTE: + cmd.info.type = SMU_I2C_TRANSFER_SIMPLE; + cmd.info.datalen = 1; + if (!read) + cmd.info.data[0] = data->byte; + break; + case I2C_SMBUS_BYTE_DATA: + cmd.info.type = SMU_I2C_TRANSFER_STDSUB; + cmd.info.datalen = 1; + cmd.info.sublen = 1; + cmd.info.subaddr[0] = command; + cmd.info.subaddr[1] = 0; + cmd.info.subaddr[2] = 0; + if (!read) + cmd.info.data[0] = data->byte; + break; + case I2C_SMBUS_WORD_DATA: + cmd.info.type = SMU_I2C_TRANSFER_STDSUB; + cmd.info.datalen = 2; + cmd.info.sublen = 1; + cmd.info.subaddr[0] = command; + cmd.info.subaddr[1] = 0; + cmd.info.subaddr[2] = 0; + if (!read) { + cmd.info.data[0] = data->byte & 0xff; + cmd.info.data[1] = (data->byte >> 8) & 0xff; + } + break; + /* Note that these are broken vs. the expected smbus API where + * on reads, the lenght is actually returned from the function, + * but I think the current API makes no sense and I don't want + * any driver that I haven't verified for correctness to go + * anywhere near a pmac i2c bus anyway ... + */ + case I2C_SMBUS_BLOCK_DATA: + cmd.info.type = SMU_I2C_TRANSFER_STDSUB; + cmd.info.datalen = data->block[0] + 1; + if (cmd.info.datalen > 6) + return -EINVAL; + if (!read) + memcpy(cmd.info.data, data->block, cmd.info.datalen); + cmd.info.sublen = 1; + cmd.info.subaddr[0] = command; + cmd.info.subaddr[1] = 0; + cmd.info.subaddr[2] = 0; + break; + case I2C_SMBUS_I2C_BLOCK_DATA: + cmd.info.type = SMU_I2C_TRANSFER_STDSUB; + cmd.info.datalen = data->block[0]; + if (cmd.info.datalen > 7) + return -EINVAL; + if (!read) + memcpy(cmd.info.data, &data->block[1], + cmd.info.datalen); + cmd.info.sublen = 1; + cmd.info.subaddr[0] = command; + cmd.info.subaddr[1] = 0; + cmd.info.subaddr[2] = 0; + break; + + default: + return -EINVAL; + } + + /* Turn a standardsub read into a combined mode access */ + if (read_write == I2C_SMBUS_READ && + cmd.info.type == SMU_I2C_TRANSFER_STDSUB) + cmd.info.type = SMU_I2C_TRANSFER_COMBINED; + + /* Finish filling command and submit it */ + cmd.done = smu_i2c_done; + cmd.misc = iface; + rc = smu_queue_i2c(&cmd); + if (rc < 0) + return rc; + wait_for_completion(&iface->complete); + rc = cmd.status; + + if (!read || rc < 0) + return rc; + + switch (size) { + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + data->byte = cmd.info.data[0]; + break; + case I2C_SMBUS_WORD_DATA: + data->word = ((u16)cmd.info.data[1]) << 8; + data->word |= cmd.info.data[0]; + break; + /* Note that these are broken vs. the expected smbus API where + * on reads, the lenght is actually returned from the function, + * but I think the current API makes no sense and I don't want + * any driver that I haven't verified for correctness to go + * anywhere near a pmac i2c bus anyway ... + */ + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + memcpy(&data->block[0], cmd.info.data, cmd.info.datalen); + break; + } + + return rc; +} + +static u32 +smu_smbus_func(struct i2c_adapter * adapter) +{ + return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA; +} + +/* For now, we only handle combined mode (smbus) */ +static struct i2c_algorithm smu_algorithm = { + .smbus_xfer = smu_smbus_xfer, + .functionality = smu_smbus_func, +}; + +static int create_iface(struct device_node *np, struct device *dev) +{ + struct smu_iface* iface; + u32 *reg, busid; + int rc; + + reg = (u32 *)get_property(np, "reg", NULL); + if (reg == NULL) { + printk(KERN_ERR "i2c-pmac-smu: can't find bus number !\n"); + return -ENXIO; + } + busid = *reg; + + iface = kzalloc(sizeof(struct smu_iface), GFP_KERNEL); + if (iface == NULL) { + printk(KERN_ERR "i2c-pmac-smu: can't allocate inteface !\n"); + return -ENOMEM; + } + init_completion(&iface->complete); + iface->busid = busid; + + dev_set_drvdata(dev, iface); + + sprintf(iface->adapter.name, "smu-i2c-%02x", busid); + iface->adapter.algo = &smu_algorithm; + iface->adapter.algo_data = NULL; + iface->adapter.client_register = NULL; + iface->adapter.client_unregister = NULL; + i2c_set_adapdata(&iface->adapter, iface); + iface->adapter.dev.parent = dev; + + rc = i2c_add_adapter(&iface->adapter); + if (rc) { + printk(KERN_ERR "i2c-pamc-smu.c: Adapter %s registration " + "failed\n", iface->adapter.name); + i2c_set_adapdata(&iface->adapter, NULL); + } + + if (probe) { + unsigned char addr; + printk("Probe: "); + for (addr = 0x00; addr <= 0x7f; addr++) { + if (i2c_smbus_xfer(&iface->adapter,addr, + 0,0,0,I2C_SMBUS_QUICK,NULL) >= 0) + printk("%02x ", addr); + } + printk("\n"); + } + + printk(KERN_INFO "SMU i2c bus %x registered\n", busid); + + return 0; +} + +static int dispose_iface(struct device *dev) +{ + struct smu_iface *iface = dev_get_drvdata(dev); + int rc; + + rc = i2c_del_adapter(&iface->adapter); + i2c_set_adapdata(&iface->adapter, NULL); + /* We aren't that prepared to deal with this... */ + if (rc) + printk("i2c-pmac-smu.c: Failed to remove bus %s !\n", + iface->adapter.name); + dev_set_drvdata(dev, NULL); + kfree(iface); + + return 0; +} + + +static int create_iface_of_platform(struct of_device* dev, + const struct of_device_id *match) +{ + return create_iface(dev->node, &dev->dev); +} + + +static int dispose_iface_of_platform(struct of_device* dev) +{ + return dispose_iface(&dev->dev); +} + + +static struct of_device_id i2c_smu_match[] = +{ + { + .compatible = "smu-i2c", + }, + {}, +}; +static struct of_platform_driver i2c_smu_of_platform_driver = +{ + .name = "i2c-smu", + .match_table = i2c_smu_match, + .probe = create_iface_of_platform, + .remove = dispose_iface_of_platform +}; + + +static int __init i2c_pmac_smu_init(void) +{ + of_register_driver(&i2c_smu_of_platform_driver); + return 0; +} + + +static void __exit i2c_pmac_smu_cleanup(void) +{ + of_unregister_driver(&i2c_smu_of_platform_driver); +} + +module_init(i2c_pmac_smu_init); +module_exit(i2c_pmac_smu_cleanup); diff --git a/trunk/drivers/i2c/busses/i2c-powermac.c b/trunk/drivers/i2c/busses/i2c-powermac.c deleted file mode 100644 index df786eb55295..000000000000 --- a/trunk/drivers/i2c/busses/i2c-powermac.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - i2c Support for Apple SMU Controller - - Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp. - - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - 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. - -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Benjamin Herrenschmidt "); -MODULE_DESCRIPTION("I2C driver for Apple PowerMac"); -MODULE_LICENSE("GPL"); - -/* - * SMBUS-type transfer entrypoint - */ -static s32 i2c_powermac_smbus_xfer( struct i2c_adapter* adap, - u16 addr, - unsigned short flags, - char read_write, - u8 command, - int size, - union i2c_smbus_data* data) -{ - struct pmac_i2c_bus *bus = i2c_get_adapdata(adap); - int rc = 0; - int read = (read_write == I2C_SMBUS_READ); - int addrdir = (addr << 1) | read; - u8 local[2]; - - rc = pmac_i2c_open(bus, 0); - if (rc) - return rc; - - switch (size) { - case I2C_SMBUS_QUICK: - rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std); - if (rc) - goto bail; - rc = pmac_i2c_xfer(bus, addrdir, 0, 0, NULL, 0); - break; - case I2C_SMBUS_BYTE: - rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std); - if (rc) - goto bail; - rc = pmac_i2c_xfer(bus, addrdir, 0, 0, &data->byte, 1); - break; - case I2C_SMBUS_BYTE_DATA: - rc = pmac_i2c_setmode(bus, read ? - pmac_i2c_mode_combined : - pmac_i2c_mode_stdsub); - if (rc) - goto bail; - rc = pmac_i2c_xfer(bus, addrdir, 1, command, &data->byte, 1); - break; - case I2C_SMBUS_WORD_DATA: - rc = pmac_i2c_setmode(bus, read ? - pmac_i2c_mode_combined : - pmac_i2c_mode_stdsub); - if (rc) - goto bail; - if (!read) { - local[0] = data->word & 0xff; - local[1] = (data->word >> 8) & 0xff; - } - rc = pmac_i2c_xfer(bus, addrdir, 1, command, local, 2); - if (rc == 0 && read) { - data->word = ((u16)local[1]) << 8; - data->word |= local[0]; - } - break; - - /* Note that these are broken vs. the expected smbus API where - * on reads, the lenght is actually returned from the function, - * but I think the current API makes no sense and I don't want - * any driver that I haven't verified for correctness to go - * anywhere near a pmac i2c bus anyway ... - * - * I'm also not completely sure what kind of phases to do between - * the actual command and the data (what I am _supposed_ to do that - * is). For now, I assume writes are a single stream and reads have - * a repeat start/addr phase (but not stop in between) - */ - case I2C_SMBUS_BLOCK_DATA: - rc = pmac_i2c_setmode(bus, read ? - pmac_i2c_mode_combined : - pmac_i2c_mode_stdsub); - if (rc) - goto bail; - rc = pmac_i2c_xfer(bus, addrdir, 1, command, data->block, - data->block[0] + 1); - - break; - case I2C_SMBUS_I2C_BLOCK_DATA: - rc = pmac_i2c_setmode(bus, read ? - pmac_i2c_mode_combined : - pmac_i2c_mode_stdsub); - if (rc) - goto bail; - rc = pmac_i2c_xfer(bus, addrdir, 1, command, - read ? data->block : &data->block[1], - data->block[0]); - break; - - default: - rc = -EINVAL; - } - bail: - pmac_i2c_close(bus); - return rc; -} - -/* - * Generic i2c master transfer entrypoint. This driver only support single - * messages (for "lame i2c" transfers). Anything else should use the smbus - * entry point - */ -static int i2c_powermac_master_xfer( struct i2c_adapter *adap, - struct i2c_msg *msgs, - int num) -{ - struct pmac_i2c_bus *bus = i2c_get_adapdata(adap); - int rc = 0; - int read; - int addrdir; - - if (num != 1) - return -EINVAL; - if (msgs->flags & I2C_M_TEN) - return -EINVAL; - read = (msgs->flags & I2C_M_RD) != 0; - addrdir = (msgs->addr << 1) | read; - if (msgs->flags & I2C_M_REV_DIR_ADDR) - addrdir ^= 1; - - rc = pmac_i2c_open(bus, 0); - if (rc) - return rc; - rc = pmac_i2c_setmode(bus, pmac_i2c_mode_std); - if (rc) - goto bail; - rc = pmac_i2c_xfer(bus, addrdir, 0, 0, msgs->buf, msgs->len); - bail: - pmac_i2c_close(bus); - return rc < 0 ? rc : msgs->len; -} - -static u32 i2c_powermac_func(struct i2c_adapter * adapter) -{ - return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | - I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_I2C; -} - -/* For now, we only handle smbus */ -static struct i2c_algorithm i2c_powermac_algorithm = { - .smbus_xfer = i2c_powermac_smbus_xfer, - .master_xfer = i2c_powermac_master_xfer, - .functionality = i2c_powermac_func, -}; - - -static int i2c_powermac_remove(struct device *dev) -{ - struct i2c_adapter *adapter = dev_get_drvdata(dev); - struct pmac_i2c_bus *bus = i2c_get_adapdata(adapter); - int rc; - - rc = i2c_del_adapter(adapter); - pmac_i2c_detach_adapter(bus, adapter); - i2c_set_adapdata(adapter, NULL); - /* We aren't that prepared to deal with this... */ - if (rc) - printk("i2c-powermac.c: Failed to remove bus %s !\n", - adapter->name); - dev_set_drvdata(dev, NULL); - kfree(adapter); - - return 0; -} - - -static int i2c_powermac_probe(struct device *dev) -{ - struct pmac_i2c_bus *bus = dev->platform_data; - struct device_node *parent = NULL; - struct i2c_adapter *adapter; - char name[32], *basename; - int rc; - - if (bus == NULL) - return -EINVAL; - - /* Ok, now we need to make up a name for the interface that will - * match what we used to do in the past, that is basically the - * controller's parent device node for keywest. PMU didn't have a - * naming convention and SMU has a different one - */ - switch(pmac_i2c_get_type(bus)) { - case pmac_i2c_bus_keywest: - parent = of_get_parent(pmac_i2c_get_controller(bus)); - if (parent == NULL) - return -EINVAL; - basename = parent->name; - break; - case pmac_i2c_bus_pmu: - basename = "pmu"; - break; - case pmac_i2c_bus_smu: - /* This is not what we used to do but I'm fixing drivers at - * the same time as this change - */ - basename = "smu"; - break; - default: - return -EINVAL; - } - snprintf(name, 32, "%s %d", basename, pmac_i2c_get_channel(bus)); - of_node_put(parent); - - adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); - if (adapter == NULL) { - printk(KERN_ERR "i2c-powermac: can't allocate inteface !\n"); - return -ENOMEM; - } - dev_set_drvdata(dev, adapter); - strcpy(adapter->name, name); - adapter->algo = &i2c_powermac_algorithm; - i2c_set_adapdata(adapter, bus); - adapter->dev.parent = dev; - pmac_i2c_attach_adapter(bus, adapter); - rc = i2c_add_adapter(adapter); - if (rc) { - printk(KERN_ERR "i2c-powermac: Adapter %s registration " - "failed\n", name); - i2c_set_adapdata(adapter, NULL); - pmac_i2c_detach_adapter(bus, adapter); - } - - printk(KERN_INFO "PowerMac i2c bus %s registered\n", name); - return rc; -} - - -static struct device_driver i2c_powermac_driver = { - .name = "i2c-powermac", - .bus = &platform_bus_type, - .probe = i2c_powermac_probe, - .remove = i2c_powermac_remove, -}; - -static int __init i2c_powermac_init(void) -{ - driver_register(&i2c_powermac_driver); - return 0; -} - - -static void __exit i2c_powermac_cleanup(void) -{ - driver_unregister(&i2c_powermac_driver); -} - -module_init(i2c_powermac_init); -module_exit(i2c_powermac_cleanup); diff --git a/trunk/drivers/i2c/chips/tps65010.c b/trunk/drivers/i2c/chips/tps65010.c index 1af3dfbb8086..e70b3db69edd 100644 --- a/trunk/drivers/i2c/chips/tps65010.c +++ b/trunk/drivers/i2c/chips/tps65010.c @@ -494,7 +494,6 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind) { struct tps65010 *tps; int status; - unsigned long irqflags; if (the_tps) { dev_dbg(&bus->dev, "only one %s for now\n", DRIVER_NAME); @@ -521,14 +520,13 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind) } #ifdef CONFIG_ARM - irqflags = SA_SAMPLE_RANDOM | SA_TRIGGER_LOW; if (machine_is_omap_h2()) { tps->model = TPS65010; omap_cfg_reg(W4_GPIO58); tps->irq = OMAP_GPIO_IRQ(58); omap_request_gpio(58); omap_set_gpio_direction(58, 1); - irqflags |= SA_TRIGGER_FALLING; + set_irq_type(tps->irq, IRQT_FALLING); } if (machine_is_omap_osk()) { tps->model = TPS65010; @@ -536,7 +534,7 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind) tps->irq = OMAP_GPIO_IRQ(OMAP_MPUIO(1)); omap_request_gpio(OMAP_MPUIO(1)); omap_set_gpio_direction(OMAP_MPUIO(1), 1); - irqflags |= SA_TRIGGER_FALLING; + set_irq_type(tps->irq, IRQT_FALLING); } if (machine_is_omap_h3()) { tps->model = TPS65013; @@ -544,12 +542,13 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind) // FIXME set up this board's IRQ ... } #else - irqflags = SA_SAMPLE_RANDOM; +#define set_irq_type(num,trigger) do{}while(0) #endif if (tps->irq > 0) { + set_irq_type(tps->irq, IRQT_LOW); status = request_irq(tps->irq, tps65010_irq, - irqflags, DRIVER_NAME, tps); + SA_SAMPLE_RANDOM, DRIVER_NAME, tps); if (status < 0) { dev_dbg(&tps->client.dev, "can't get IRQ %d, err %d\n", tps->irq, status); diff --git a/trunk/drivers/ide/ide-cd.c b/trunk/drivers/ide/ide-cd.c index e4d55ad32d2f..d31117eb95aa 100644 --- a/trunk/drivers/ide/ide-cd.c +++ b/trunk/drivers/ide/ide-cd.c @@ -1332,6 +1332,8 @@ static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block) if (cdrom_read_from_buffer(drive)) return ide_stopped; + blk_attempt_remerge(drive->queue, rq); + /* Clear the local sector buffer. */ info->nsectors_buffered = 0; @@ -1872,6 +1874,14 @@ static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq) return ide_stopped; } + /* + * for dvd-ram and such media, it's a really big deal to get + * big writes all the time. so scour the queue and attempt to + * remerge requests, often the plugging will not have had time + * to do this properly + */ + blk_attempt_remerge(drive->queue, rq); + info->nsectors_buffered = 0; /* use dma, if possible. we don't need to check more, since we diff --git a/trunk/drivers/ide/ide-disk.c b/trunk/drivers/ide/ide-disk.c index cab362ea0336..4b441720b6ba 100644 --- a/trunk/drivers/ide/ide-disk.c +++ b/trunk/drivers/ide/ide-disk.c @@ -1130,17 +1130,6 @@ static int idedisk_release(struct inode *inode, struct file *filp) return 0; } -static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk); - ide_drive_t *drive = idkp->drive; - - geo->heads = drive->bios_head; - geo->sectors = drive->bios_sect; - geo->cylinders = (u16)drive->bios_cyl; /* truncate */ - return 0; -} - static int idedisk_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { @@ -1175,7 +1164,6 @@ static struct block_device_operations idedisk_ops = { .open = idedisk_open, .release = idedisk_release, .ioctl = idedisk_ioctl, - .getgeo = idedisk_getgeo, .media_changed = idedisk_media_changed, .revalidate_disk= idedisk_revalidate_disk }; diff --git a/trunk/drivers/ide/ide-floppy.c b/trunk/drivers/ide/ide-floppy.c index 5945f551aaaa..fba3fffc2d66 100644 --- a/trunk/drivers/ide/ide-floppy.c +++ b/trunk/drivers/ide/ide-floppy.c @@ -2031,17 +2031,6 @@ static int idefloppy_release(struct inode *inode, struct file *filp) return 0; } -static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct ide_floppy_obj *floppy = ide_floppy_g(bdev->bd_disk); - ide_drive_t *drive = floppy->drive; - - geo->heads = drive->bios_head; - geo->sectors = drive->bios_sect; - geo->cylinders = (u16)drive->bios_cyl; /* truncate */ - return 0; -} - static int idefloppy_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { @@ -2131,7 +2120,6 @@ static struct block_device_operations idefloppy_ops = { .open = idefloppy_open, .release = idefloppy_release, .ioctl = idefloppy_ioctl, - .getgeo = idefloppy_getgeo, .media_changed = idefloppy_media_changed, .revalidate_disk= idefloppy_revalidate_disk }; diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index dea2d4dcc698..b5dc6df8e67d 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -55,22 +55,9 @@ #include #include -void ide_softirq_done(struct request *rq) -{ - request_queue_t *q = rq->q; - - add_disk_randomness(rq->rq_disk); - end_that_request_chunk(rq, rq->errors, rq->data_len); - - spin_lock_irq(q->queue_lock); - end_that_request_last(rq, rq->errors); - spin_unlock_irq(q->queue_lock); -} - int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, int nr_sectors) { - unsigned int nbytes; int ret = 1; BUG_ON(!(rq->flags & REQ_STARTED)); @@ -94,28 +81,17 @@ int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, HWGROUP(drive)->hwif->ide_dma_on(drive); } - /* - * For partial completions (or non fs/pc requests), use the regular - * direct completion path. - */ - nbytes = nr_sectors << 9; - if (rq_all_done(rq, nbytes)) { - rq->errors = uptodate; - rq->data_len = nbytes; + if (!end_that_request_first(rq, uptodate, nr_sectors)) { + add_disk_randomness(rq->rq_disk); + + if (blk_rq_tagged(rq)) + blk_queue_end_tag(drive->queue, rq); + blkdev_dequeue_request(rq); HWGROUP(drive)->rq = NULL; - blk_complete_request(rq); + end_that_request_last(rq, uptodate); ret = 0; - } else { - if (!end_that_request_first(rq, uptodate, nr_sectors)) { - add_disk_randomness(rq->rq_disk); - blkdev_dequeue_request(rq); - HWGROUP(drive)->rq = NULL; - end_that_request_last(rq, uptodate); - ret = 0; - } } - return ret; } EXPORT_SYMBOL(__ide_end_request); @@ -137,10 +113,6 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) unsigned long flags; int ret = 1; - /* - * room for locking improvements here, the calls below don't - * need the queue lock held at all - */ spin_lock_irqsave(&ide_lock, flags); rq = HWGROUP(drive)->rq; diff --git a/trunk/drivers/ide/ide-probe.c b/trunk/drivers/ide/ide-probe.c index 1ddaa71a8f45..02167a5b751d 100644 --- a/trunk/drivers/ide/ide-probe.c +++ b/trunk/drivers/ide/ide-probe.c @@ -1011,8 +1011,6 @@ static int ide_init_queue(ide_drive_t *drive) blk_queue_max_hw_segments(q, max_sg_entries); blk_queue_max_phys_segments(q, max_sg_entries); - blk_queue_softirq_done(q, ide_softirq_done); - /* assign drive queue */ drive->queue = q; diff --git a/trunk/drivers/ide/ide.c b/trunk/drivers/ide/ide.c index b069b13b75a7..4b524f6b3ecd 100644 --- a/trunk/drivers/ide/ide.c +++ b/trunk/drivers/ide/ide.c @@ -1278,6 +1278,19 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device up(&ide_setting_sem); switch (cmd) { + case HDIO_GETGEO: + { + struct hd_geometry geom; + if (!p || (drive->media != ide_disk && drive->media != ide_floppy)) return -EINVAL; + geom.heads = drive->bios_head; + geom.sectors = drive->bios_sect; + geom.cylinders = (u16)drive->bios_cyl; /* truncate */ + geom.start = get_start_sect(bdev); + if (copy_to_user(p, &geom, sizeof(struct hd_geometry))) + return -EFAULT; + return 0; + } + case HDIO_OBSOLETE_IDENTITY: case HDIO_GET_IDENTITY: if (bdev != bdev->bd_contains) diff --git a/trunk/drivers/ide/legacy/hd.c b/trunk/drivers/ide/legacy/hd.c index 6439dec66881..242029c9c0ca 100644 --- a/trunk/drivers/ide/legacy/hd.c +++ b/trunk/drivers/ide/legacy/hd.c @@ -658,14 +658,22 @@ static void do_hd_request (request_queue_t * q) enable_irq(HD_IRQ); } -static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo) +static int hd_ioctl(struct inode * inode, struct file * file, + unsigned int cmd, unsigned long arg) { - struct hd_i_struct *disk = bdev->bd_disk->private_data; - - geo->heads = disk->head; - geo->sectors = disk->sect; - geo->cylinders = disk->cyl; - return 0; + struct hd_i_struct *disk = inode->i_bdev->bd_disk->private_data; + struct hd_geometry __user *loc = (struct hd_geometry __user *) arg; + struct hd_geometry g; + + if (cmd != HDIO_GETGEO) + return -EINVAL; + if (!loc) + return -EINVAL; + g.heads = disk->head; + g.sectors = disk->sect; + g.cylinders = disk->cyl; + g.start = get_start_sect(inode->i_bdev); + return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; } /* @@ -687,7 +695,7 @@ static irqreturn_t hd_interrupt(int irq, void *dev_id, struct pt_regs *regs) } static struct block_device_operations hd_fops = { - .getgeo = hd_getgeo, + .ioctl = hd_ioctl, }; /* diff --git a/trunk/drivers/ide/pci/serverworks.c b/trunk/drivers/ide/pci/serverworks.c index 0d3073f4eab4..ff2e217a8c84 100644 --- a/trunk/drivers/ide/pci/serverworks.c +++ b/trunk/drivers/ide/pci/serverworks.c @@ -69,7 +69,7 @@ static int check_in_drive_lists (ide_drive_t *drive, const char **list) static u8 svwks_ratemask (ide_drive_t *drive) { struct pci_dev *dev = HWIF(drive)->pci_dev; - u8 mode = 0; + u8 mode; if (!svwks_revision) pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision); diff --git a/trunk/drivers/ide/ppc/pmac.c b/trunk/drivers/ide/ppc/pmac.c index 5013b1285e22..16b28357885b 100644 --- a/trunk/drivers/ide/ppc/pmac.c +++ b/trunk/drivers/ide/ppc/pmac.c @@ -1271,7 +1271,7 @@ static int pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) { struct device_node *np = pmif->node; - int *bidp; + int *bidp, i; pmif->cable_80 = 0; pmif->broken_dma = pmif->broken_dma_warn = 0; @@ -1430,7 +1430,7 @@ pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) pmif = &pmac_ide[i]; hwif = &ide_hwifs[i]; - if (macio_resource_count(mdev) == 0) { + if (mdev->ofdev.node->n_addrs == 0) { printk(KERN_WARNING "ide%d: no address for %s\n", i, mdev->ofdev.node->full_name); return -ENXIO; @@ -1686,7 +1686,7 @@ pmac_ide_probe(void) #else macio_register_driver(&pmac_ide_macio_driver); pci_register_driver(&pmac_ide_pci_driver); -#endif +#endif } #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC diff --git a/trunk/drivers/infiniband/core/cm.c b/trunk/drivers/infiniband/core/cm.c index 3a611fe5497e..02110e00d145 100644 --- a/trunk/drivers/infiniband/core/cm.c +++ b/trunk/drivers/infiniband/core/cm.c @@ -308,11 +308,10 @@ static int cm_alloc_id(struct cm_id_private *cm_id_priv) { unsigned long flags; int ret; - static int next_id; do { spin_lock_irqsave(&cm.lock, flags); - ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, next_id++, + ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, 1, (__force int *) &cm_id_priv->id.local_id); spin_unlock_irqrestore(&cm.lock, flags); } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) ); @@ -685,13 +684,6 @@ void ib_destroy_cm_id(struct ib_cm_id *cm_id) cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT); break; case IB_CM_REQ_SENT: - ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg); - spin_unlock_irqrestore(&cm_id_priv->lock, flags); - ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT, - &cm_id_priv->av.port->cm_dev->ca_guid, - sizeof cm_id_priv->av.port->cm_dev->ca_guid, - NULL, 0); - break; case IB_CM_MRA_REQ_RCVD: case IB_CM_REP_SENT: case IB_CM_MRA_REP_RCVD: @@ -702,8 +694,10 @@ void ib_destroy_cm_id(struct ib_cm_id *cm_id) case IB_CM_REP_RCVD: case IB_CM_MRA_REP_SENT: spin_unlock_irqrestore(&cm_id_priv->lock, flags); - ib_send_cm_rej(cm_id, IB_CM_REJ_CONSUMER_DEFINED, - NULL, 0, NULL, 0); + ib_send_cm_rej(cm_id, IB_CM_REJ_TIMEOUT, + &cm_id_priv->av.port->cm_dev->ca_guid, + sizeof cm_id_priv->av.port->cm_dev->ca_guid, + NULL, 0); break; case IB_CM_ESTABLISHED: spin_unlock_irqrestore(&cm_id_priv->lock, flags); diff --git a/trunk/drivers/infiniband/core/user_mad.c b/trunk/drivers/infiniband/core/user_mad.c index c908de8db5a9..eb7f52537ccc 100644 --- a/trunk/drivers/infiniband/core/user_mad.c +++ b/trunk/drivers/infiniband/core/user_mad.c @@ -197,8 +197,8 @@ static void send_handler(struct ib_mad_agent *agent, memcpy(timeout->mad.data, packet->mad.data, sizeof (struct ib_mad_hdr)); - if (queue_packet(file, agent, timeout)) - kfree(timeout); + if (!queue_packet(file, agent, timeout)) + return; } out: kfree(packet); diff --git a/trunk/drivers/infiniband/core/uverbs_cmd.c b/trunk/drivers/infiniband/core/uverbs_cmd.c index a02c5a05c984..a57d021d435a 100644 --- a/trunk/drivers/infiniband/core/uverbs_cmd.c +++ b/trunk/drivers/infiniband/core/uverbs_cmd.c @@ -489,7 +489,6 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, err_unreg: ib_dereg_mr(mr); - atomic_dec(&pd->usecnt); err_up: up(&ib_uverbs_idr_mutex); @@ -594,18 +593,13 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, if (cmd.comp_vector >= file->device->num_comp_vectors) return -EINVAL; + if (cmd.comp_channel >= 0) + ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel); + uobj = kmalloc(sizeof *uobj, GFP_KERNEL); if (!uobj) return -ENOMEM; - if (cmd.comp_channel >= 0) { - ev_file = ib_uverbs_lookup_comp_file(cmd.comp_channel); - if (!ev_file) { - ret = -EINVAL; - goto err; - } - } - uobj->uobject.user_handle = cmd.user_handle; uobj->uobject.context = file->ucontext; uobj->uverbs_file = file; @@ -669,8 +663,6 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file, ib_destroy_cq(cq); err: - if (ev_file) - ib_uverbs_release_ucq(file, ev_file, uobj); kfree(uobj); return ret; } @@ -943,11 +935,6 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, err_destroy: ib_destroy_qp(qp); - atomic_dec(&pd->usecnt); - atomic_dec(&attr.send_cq->usecnt); - atomic_dec(&attr.recv_cq->usecnt); - if (attr.srq) - atomic_dec(&attr.srq->usecnt); err_up: up(&ib_uverbs_idr_mutex); @@ -1461,7 +1448,6 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, attr.sl = cmd.attr.sl; attr.src_path_bits = cmd.attr.src_path_bits; attr.static_rate = cmd.attr.static_rate; - attr.ah_flags = cmd.attr.is_global ? IB_AH_GRH : 0; attr.port_num = cmd.attr.port_num; attr.grh.flow_label = cmd.attr.grh.flow_label; attr.grh.sgid_index = cmd.attr.grh.sgid_index; @@ -1743,7 +1729,6 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file, err_destroy: ib_destroy_srq(srq); - atomic_dec(&pd->usecnt); err_up: up(&ib_uverbs_idr_mutex); diff --git a/trunk/drivers/infiniband/core/verbs.c b/trunk/drivers/infiniband/core/verbs.c index c857361be449..4c15e112736c 100644 --- a/trunk/drivers/infiniband/core/verbs.c +++ b/trunk/drivers/infiniband/core/verbs.c @@ -107,9 +107,9 @@ struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc, if (wc->wc_flags & IB_WC_GRH) { ah_attr.ah_flags = IB_AH_GRH; - ah_attr.grh.dgid = grh->sgid; + ah_attr.grh.dgid = grh->dgid; - ret = ib_find_cached_gid(pd->device, &grh->dgid, &port_num, + ret = ib_find_cached_gid(pd->device, &grh->sgid, &port_num, &gid_index); if (ret) return ERR_PTR(ret); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c b/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c index 22ac72bc20c3..9ed34587fc5c 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -937,6 +937,10 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, if (err) goto out; + MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); + dev_lim->max_srq_sz = (1 << field) - 1; + MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET); + dev_lim->max_qp_sz = (1 << field) - 1; MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSVD_QP_OFFSET); dev_lim->reserved_qps = 1 << (field & 0xf); MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_OFFSET); @@ -1052,10 +1056,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, mthca_dbg(dev, "Flags: %08x\n", dev_lim->flags); if (mthca_is_memfree(dev)) { - MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); - dev_lim->max_srq_sz = 1 << field; - MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET); - dev_lim->max_qp_sz = 1 << field; MTHCA_GET(field, outbox, QUERY_DEV_LIM_RSZ_SRQ_OFFSET); dev_lim->hca.arbel.resize_srq = field & 1; MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SG_RQ_OFFSET); @@ -1087,10 +1087,6 @@ int mthca_QUERY_DEV_LIM(struct mthca_dev *dev, mthca_dbg(dev, "Max ICM size %lld MB\n", (unsigned long long) dev_lim->hca.arbel.max_icm_sz >> 20); } else { - MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_SRQ_SZ_OFFSET); - dev_lim->max_srq_sz = (1 << field) - 1; - MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_QP_SZ_OFFSET); - dev_lim->max_qp_sz = (1 << field) - 1; MTHCA_GET(field, outbox, QUERY_DEV_LIM_MAX_AV_OFFSET); dev_lim->hca.tavor.max_avs = 1 << (field & 0x3f); dev_lim->mpt_entry_sz = MTHCA_MPT_ENTRY_SIZE; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c index 96f1a86bf049..4a8adcef2079 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_cq.c @@ -128,12 +128,12 @@ struct mthca_err_cqe { __be32 my_qpn; u32 reserved1[3]; u8 syndrome; - u8 vendor_err; + u8 reserved2; __be16 db_cnt; - u32 reserved2; + u32 reserved3; __be32 wqe; u8 opcode; - u8 reserved3[2]; + u8 reserved4[2]; u8 owner; }; @@ -253,15 +253,6 @@ void mthca_cq_event(struct mthca_dev *dev, u32 cqn, wake_up(&cq->wait); } -static inline int is_recv_cqe(struct mthca_cqe *cqe) -{ - if ((cqe->opcode & MTHCA_ERROR_CQE_OPCODE_MASK) == - MTHCA_ERROR_CQE_OPCODE_MASK) - return !(cqe->opcode & 0x01); - else - return !(cqe->is_send & 0x80); -} - void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, struct mthca_srq *srq) { @@ -305,7 +296,7 @@ void mthca_cq_clean(struct mthca_dev *dev, u32 cqn, u32 qpn, while ((int) --prod_index - (int) cq->cons_index >= 0) { cqe = get_cqe(cq, prod_index & cq->ibcq.cqe); if (cqe->my_qpn == cpu_to_be32(qpn)) { - if (srq && is_recv_cqe(cqe)) + if (srq) mthca_free_srq_wqe(srq, be32_to_cpu(cqe->wqe)); ++nfreed; } else if (nfreed) @@ -342,8 +333,8 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq, } /* - * For completions in error, only work request ID, status, vendor error - * (and freed resource count for RD) have to be set. + * For completions in error, only work request ID, status (and + * freed resource count for RD) have to be set. */ switch (cqe->syndrome) { case SYNDROME_LOCAL_LENGTH_ERR: @@ -405,8 +396,6 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq, break; } - entry->vendor_err = cqe->vendor_err; - /* * Mem-free HCAs always generate one CQE per WQE, even in the * error case, so we don't have to check the doorbell count, etc. diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_dev.h b/trunk/drivers/infiniband/hw/mthca/mthca_dev.h index 795b379260bf..497ff794ef6a 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/trunk/drivers/infiniband/hw/mthca/mthca_dev.h @@ -43,7 +43,6 @@ #include #include #include -#include #include #include "mthca_provider.h" diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_eq.c b/trunk/drivers/infiniband/hw/mthca/mthca_eq.c index e8a948f087c0..34d68e5a72d8 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_eq.c @@ -484,7 +484,8 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev, u8 intr, struct mthca_eq *eq) { - int npages; + int npages = (nent * MTHCA_EQ_ENTRY_SIZE + PAGE_SIZE - 1) / + PAGE_SIZE; u64 *dma_list = NULL; dma_addr_t t; struct mthca_mailbox *mailbox; @@ -495,7 +496,6 @@ static int __devinit mthca_create_eq(struct mthca_dev *dev, eq->dev = dev; eq->nent = roundup_pow_of_two(max(nent, 2)); - npages = ALIGN(eq->nent * MTHCA_EQ_ENTRY_SIZE, PAGE_SIZE) / PAGE_SIZE; eq->page_list = kmalloc(npages * sizeof *eq->page_list, GFP_KERNEL); diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_main.c b/trunk/drivers/infiniband/hw/mthca/mthca_main.c index 8b00d9a0f6f4..6f94b25f3acd 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_main.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_main.c @@ -261,10 +261,6 @@ static int __devinit mthca_init_tavor(struct mthca_dev *mdev) } err = mthca_dev_lim(mdev, &dev_lim); - if (err) { - mthca_err(mdev, "QUERY_DEV_LIM command failed, aborting.\n"); - goto err_disable; - } profile = default_profile; profile.num_uar = dev_lim.uar_size / PAGE_SIZE; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_mcg.c b/trunk/drivers/infiniband/hw/mthca/mthca_mcg.c index 77bc6c746f43..2fc449da418d 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_mcg.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_mcg.c @@ -111,8 +111,7 @@ static int find_mgm(struct mthca_dev *dev, goto out; if (status) { mthca_err(dev, "READ_MGM returned status %02x\n", status); - err = -EINVAL; - goto out; + return -EINVAL; } if (!memcmp(mgm->gid, zero_gid, 16)) { @@ -127,7 +126,7 @@ static int find_mgm(struct mthca_dev *dev, goto out; *prev = *index; - *index = be32_to_cpu(mgm->next_gid_index) >> 6; + *index = be32_to_cpu(mgm->next_gid_index) >> 5; } while (*index); *index = -1; @@ -154,10 +153,8 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) return PTR_ERR(mailbox); mgm = mailbox->buf; - if (down_interruptible(&dev->mcg_table.sem)) { - err = -EINTR; - goto err_sem; - } + if (down_interruptible(&dev->mcg_table.sem)) + return -EINTR; err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); if (err) @@ -184,8 +181,9 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) err = -EINVAL; goto out; } - memset(mgm, 0, sizeof *mgm); + memcpy(mgm->gid, gid->raw, 16); + mgm->next_gid_index = 0; } for (i = 0; i < MTHCA_QP_PER_MGM; ++i) @@ -211,7 +209,6 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) if (status) { mthca_err(dev, "WRITE_MGM returned status %02x\n", status); err = -EINVAL; - goto out; } if (!link) @@ -226,7 +223,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) goto out; } - mgm->next_gid_index = cpu_to_be32(index << 6); + mgm->next_gid_index = cpu_to_be32(index << 5); err = mthca_WRITE_MGM(dev, prev, mailbox, &status); if (err) @@ -237,12 +234,7 @@ int mthca_multicast_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) } out: - if (err && link && index != -1) { - BUG_ON(index < dev->limits.num_mgms); - mthca_free(&dev->mcg_table.alloc, index); - } up(&dev->mcg_table.sem); - err_sem: mthca_free_mailbox(dev, mailbox); return err; } @@ -263,10 +255,8 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) return PTR_ERR(mailbox); mgm = mailbox->buf; - if (down_interruptible(&dev->mcg_table.sem)) { - err = -EINTR; - goto err_sem; - } + if (down_interruptible(&dev->mcg_table.sem)) + return -EINTR; err = find_mgm(dev, gid->raw, mailbox, &hash, &prev, &index); if (err) @@ -315,11 +305,13 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) if (i != 1) goto out; + goto out; + if (prev == -1) { /* Remove entry from MGM */ - int amgm_index_to_free = be32_to_cpu(mgm->next_gid_index) >> 6; - if (amgm_index_to_free) { - err = mthca_READ_MGM(dev, amgm_index_to_free, + if (be32_to_cpu(mgm->next_gid_index) >> 5) { + err = mthca_READ_MGM(dev, + be32_to_cpu(mgm->next_gid_index) >> 5, mailbox, &status); if (err) goto out; @@ -340,13 +332,9 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) err = -EINVAL; goto out; } - if (amgm_index_to_free) { - BUG_ON(amgm_index_to_free < dev->limits.num_mgms); - mthca_free(&dev->mcg_table.alloc, amgm_index_to_free); - } } else { /* Remove entry from AMGM */ - int curr_next_index = be32_to_cpu(mgm->next_gid_index) >> 6; + index = be32_to_cpu(mgm->next_gid_index) >> 5; err = mthca_READ_MGM(dev, prev, mailbox, &status); if (err) goto out; @@ -356,7 +344,7 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) goto out; } - mgm->next_gid_index = cpu_to_be32(curr_next_index << 6); + mgm->next_gid_index = cpu_to_be32(index << 5); err = mthca_WRITE_MGM(dev, prev, mailbox, &status); if (err) @@ -366,13 +354,10 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) err = -EINVAL; goto out; } - BUG_ON(index < dev->limits.num_mgms); - mthca_free(&dev->mcg_table.alloc, index); } out: up(&dev->mcg_table.sem); - err_sem: mthca_free_mailbox(dev, mailbox); return err; } @@ -380,12 +365,11 @@ int mthca_multicast_detach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) int __devinit mthca_init_mcg_table(struct mthca_dev *dev) { int err; - int table_size = dev->limits.num_mgms + dev->limits.num_amgms; err = mthca_alloc_init(&dev->mcg_table.alloc, - table_size, - table_size - 1, - dev->limits.num_mgms); + dev->limits.num_amgms, + dev->limits.num_amgms - 1, + 0); if (err) return err; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c b/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c index 9fb985a016e9..d72fe95cba08 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -233,7 +233,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj) for (i = 0; i < chunk->npages; ++i) { if (chunk->mem[i].length >= offset) { page = chunk->mem[i].page; - goto out; + break; } offset -= chunk->mem[i].length; } @@ -485,8 +485,6 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar, put_page(db_tab->page[i].mem.page); } } - - kfree(db_tab); } int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type, diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c index 564b6d51c394..7450550db736 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_qp.c @@ -383,10 +383,12 @@ static const struct { [UC] = (IB_QP_CUR_STATE | IB_QP_ALT_PATH | IB_QP_ACCESS_FLAGS | + IB_QP_PKEY_INDEX | IB_QP_PATH_MIG_STATE), [RC] = (IB_QP_CUR_STATE | IB_QP_ALT_PATH | IB_QP_ACCESS_FLAGS | + IB_QP_PKEY_INDEX | IB_QP_MIN_RNR_TIMER | IB_QP_PATH_MIG_STATE), [MLX] = (IB_QP_CUR_STATE | @@ -474,8 +476,9 @@ static const struct { .opt_param = { [UD] = (IB_QP_CUR_STATE | IB_QP_QKEY), - [UC] = (IB_QP_CUR_STATE | - IB_QP_ACCESS_FLAGS), + [UC] = IB_QP_CUR_STATE, + [RC] = (IB_QP_CUR_STATE | + IB_QP_MIN_RNR_TIMER), [MLX] = (IB_QP_CUR_STATE | IB_QP_QKEY), } @@ -519,55 +522,6 @@ static void init_port(struct mthca_dev *dev, int port) mthca_warn(dev, "INIT_IB returned status %02x.\n", status); } -static __be32 get_hw_access_flags(struct mthca_qp *qp, struct ib_qp_attr *attr, - int attr_mask) -{ - u8 dest_rd_atomic; - u32 access_flags; - u32 hw_access_flags = 0; - - if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) - dest_rd_atomic = attr->max_dest_rd_atomic; - else - dest_rd_atomic = qp->resp_depth; - - if (attr_mask & IB_QP_ACCESS_FLAGS) - access_flags = attr->qp_access_flags; - else - access_flags = qp->atomic_rd_en; - - if (!dest_rd_atomic) - access_flags &= IB_ACCESS_REMOTE_WRITE; - - if (access_flags & IB_ACCESS_REMOTE_READ) - hw_access_flags |= MTHCA_QP_BIT_RRE; - if (access_flags & IB_ACCESS_REMOTE_ATOMIC) - hw_access_flags |= MTHCA_QP_BIT_RAE; - if (access_flags & IB_ACCESS_REMOTE_WRITE) - hw_access_flags |= MTHCA_QP_BIT_RWE; - - return cpu_to_be32(hw_access_flags); -} - -static void mthca_path_set(struct ib_ah_attr *ah, struct mthca_qp_path *path) -{ - path->g_mylmc = ah->src_path_bits & 0x7f; - path->rlid = cpu_to_be16(ah->dlid); - path->static_rate = !!ah->static_rate; - - if (ah->ah_flags & IB_AH_GRH) { - path->g_mylmc |= 1 << 7; - path->mgid_index = ah->grh.sgid_index; - path->hop_limit = ah->grh.hop_limit; - path->sl_tclass_flowlabel = - cpu_to_be32((ah->sl << 28) | - (ah->grh.traffic_class << 20) | - (ah->grh.flow_label)); - memcpy(path->rgid, ah->grh.dgid.raw, 16); - } else - path->sl_tclass_flowlabel = cpu_to_be32(ah->sl << 28); -} - int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) { struct mthca_dev *dev = to_mdev(ibqp->device); @@ -637,26 +591,6 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) return -EINVAL; } - if ((attr_mask & IB_QP_PORT) && - (attr->port_num == 0 || attr->port_num > dev->limits.num_ports)) { - mthca_dbg(dev, "Port number (%u) is invalid\n", attr->port_num); - return -EINVAL; - } - - if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && - attr->max_rd_atomic > dev->limits.max_qp_init_rdma) { - mthca_dbg(dev, "Max rdma_atomic as initiator %u too large (max is %d)\n", - attr->max_rd_atomic, dev->limits.max_qp_init_rdma); - return -EINVAL; - } - - if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && - attr->max_dest_rd_atomic > 1 << dev->qp_table.rdb_shift) { - mthca_dbg(dev, "Max rdma_atomic as responder %u too large (max %d)\n", - attr->max_dest_rd_atomic, 1 << dev->qp_table.rdb_shift); - return -EINVAL; - } - mailbox = mthca_alloc_mailbox(dev, GFP_KERNEL); if (IS_ERR(mailbox)) return PTR_ERR(mailbox); @@ -731,14 +665,28 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) } if (attr_mask & IB_QP_RNR_RETRY) { - qp_context->alt_path.rnr_retry = qp_context->pri_path.rnr_retry = - attr->rnr_retry << 5; - qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY | - MTHCA_QP_OPTPAR_ALT_RNR_RETRY); + qp_context->pri_path.rnr_retry = attr->rnr_retry << 5; + qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RNR_RETRY); } if (attr_mask & IB_QP_AV) { - mthca_path_set(&attr->ah_attr, &qp_context->pri_path); + qp_context->pri_path.g_mylmc = attr->ah_attr.src_path_bits & 0x7f; + qp_context->pri_path.rlid = cpu_to_be16(attr->ah_attr.dlid); + qp_context->pri_path.static_rate = !!attr->ah_attr.static_rate; + if (attr->ah_attr.ah_flags & IB_AH_GRH) { + qp_context->pri_path.g_mylmc |= 1 << 7; + qp_context->pri_path.mgid_index = attr->ah_attr.grh.sgid_index; + qp_context->pri_path.hop_limit = attr->ah_attr.grh.hop_limit; + qp_context->pri_path.sl_tclass_flowlabel = + cpu_to_be32((attr->ah_attr.sl << 28) | + (attr->ah_attr.grh.traffic_class << 20) | + (attr->ah_attr.grh.flow_label)); + memcpy(qp_context->pri_path.rgid, + attr->ah_attr.grh.dgid.raw, 16); + } else { + qp_context->pri_path.sl_tclass_flowlabel = + cpu_to_be32(attr->ah_attr.sl << 28); + } qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_PRIMARY_ADDR_PATH); } @@ -747,19 +695,7 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ACK_TIMEOUT); } - if (attr_mask & IB_QP_ALT_PATH) { - if (attr->alt_port_num == 0 || attr->alt_port_num > dev->limits.num_ports) { - mthca_dbg(dev, "Alternate port number (%u) is invalid\n", - attr->alt_port_num); - return -EINVAL; - } - - mthca_path_set(&attr->alt_ah_attr, &qp_context->alt_path); - qp_context->alt_path.port_pkey |= cpu_to_be32(attr->alt_pkey_index | - attr->alt_port_num << 24); - qp_context->alt_path.ackto = attr->alt_timeout << 3; - qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_ALT_ADDR_PATH); - } + /* XXX alt_path */ /* leave rdd as 0 */ qp_context->pd = cpu_to_be32(to_mpd(ibqp->pd)->pd_num); @@ -767,7 +703,9 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) qp_context->wqe_lkey = cpu_to_be32(qp->mr.ibmr.lkey); qp_context->params1 = cpu_to_be32((MTHCA_ACK_REQ_FREQ << 28) | (MTHCA_FLIGHT_LIMIT << 24) | - MTHCA_QP_BIT_SWE); + MTHCA_QP_BIT_SRE | + MTHCA_QP_BIT_SWE | + MTHCA_QP_BIT_SAE); if (qp->sq_policy == IB_SIGNAL_ALL_WR) qp_context->params1 |= cpu_to_be32(MTHCA_QP_BIT_SSC); if (attr_mask & IB_QP_RETRY_CNT) { @@ -776,13 +714,9 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) } if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC) { - if (attr->max_rd_atomic) { - qp_context->params1 |= - cpu_to_be32(MTHCA_QP_BIT_SRE | - MTHCA_QP_BIT_SAE); - qp_context->params1 |= - cpu_to_be32(fls(attr->max_rd_atomic - 1) << 21); - } + qp_context->params1 |= cpu_to_be32(min(attr->max_rd_atomic ? + ffs(attr->max_rd_atomic) - 1 : 0, + 7) << 21); qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_SRA_MAX); } @@ -795,19 +729,71 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) qp_context->snd_db_index = cpu_to_be32(qp->sq.db_index); } - if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) { - if (attr->max_dest_rd_atomic) - qp_context->params2 |= - cpu_to_be32(fls(attr->max_dest_rd_atomic - 1) << 21); + if (attr_mask & IB_QP_ACCESS_FLAGS) { + qp_context->params2 |= + cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_WRITE ? + MTHCA_QP_BIT_RWE : 0); - qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRA_MAX); - } + /* + * Only enable RDMA reads and atomics if we have + * responder resources set to a non-zero value. + */ + if (qp->resp_depth) { + qp_context->params2 |= + cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_READ ? + MTHCA_QP_BIT_RRE : 0); + qp_context->params2 |= + cpu_to_be32(attr->qp_access_flags & IB_ACCESS_REMOTE_ATOMIC ? + MTHCA_QP_BIT_RAE : 0); + } - if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) { - qp_context->params2 |= get_hw_access_flags(qp, attr, attr_mask); qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RWE | MTHCA_QP_OPTPAR_RRE | MTHCA_QP_OPTPAR_RAE); + + qp->atomic_rd_en = attr->qp_access_flags; + } + + if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) { + u8 rra_max; + + if (qp->resp_depth && !attr->max_dest_rd_atomic) { + /* + * Lowering our responder resources to zero. + * Turn off reads RDMA and atomics as responder. + * (RRE/RAE in params2 already zero) + */ + qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE | + MTHCA_QP_OPTPAR_RAE); + } + + if (!qp->resp_depth && attr->max_dest_rd_atomic) { + /* + * Increasing our responder resources from + * zero. Turn on RDMA reads and atomics as + * appropriate. + */ + qp_context->params2 |= + cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_READ ? + MTHCA_QP_BIT_RRE : 0); + qp_context->params2 |= + cpu_to_be32(qp->atomic_rd_en & IB_ACCESS_REMOTE_ATOMIC ? + MTHCA_QP_BIT_RAE : 0); + + qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRE | + MTHCA_QP_OPTPAR_RAE); + } + + for (rra_max = 0; + 1 << rra_max < attr->max_dest_rd_atomic && + rra_max < dev->qp_table.rdb_shift; + ++rra_max) + ; /* nothing */ + + qp_context->params2 |= cpu_to_be32(rra_max << 21); + qp_param->opt_param_mask |= cpu_to_be32(MTHCA_QP_OPTPAR_RRA_MAX); + + qp->resp_depth = attr->max_dest_rd_atomic; } qp_context->params2 |= cpu_to_be32(MTHCA_QP_BIT_RSC); @@ -849,13 +835,8 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) err = -EINVAL; } - if (!err) { + if (!err) qp->state = new_state; - if (attr_mask & IB_QP_ACCESS_FLAGS) - qp->atomic_rd_en = attr->qp_access_flags; - if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC) - qp->resp_depth = attr->max_dest_rd_atomic; - } mthca_free_mailbox(dev, mailbox); @@ -904,13 +885,18 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) return err; } -static int mthca_max_data_size(struct mthca_dev *dev, struct mthca_qp *qp, int desc_sz) +static void mthca_adjust_qp_caps(struct mthca_dev *dev, + struct mthca_pd *pd, + struct mthca_qp *qp) { + int max_data_size; + /* * Calculate the maximum size of WQE s/g segments, excluding * the next segment and other non-data segments. */ - int max_data_size = desc_sz - sizeof (struct mthca_next_seg); + max_data_size = min(dev->limits.max_desc_sz, 1 << qp->sq.wqe_shift) - + sizeof (struct mthca_next_seg); switch (qp->transport) { case MLX: @@ -929,24 +915,11 @@ static int mthca_max_data_size(struct mthca_dev *dev, struct mthca_qp *qp, int d break; } - return max_data_size; -} - -static inline int mthca_max_inline_data(struct mthca_pd *pd, int max_data_size) -{ /* We don't support inline data for kernel QPs (yet). */ - return pd->ibpd.uobject ? max_data_size - MTHCA_INLINE_HEADER_SIZE : 0; -} - -static void mthca_adjust_qp_caps(struct mthca_dev *dev, - struct mthca_pd *pd, - struct mthca_qp *qp) -{ - int max_data_size = mthca_max_data_size(dev, qp, - min(dev->limits.max_desc_sz, - 1 << qp->sq.wqe_shift)); - - qp->max_inline_data = mthca_max_inline_data(pd, max_data_size); + if (!pd->ibpd.uobject) + qp->max_inline_data = 0; + else + qp->max_inline_data = max_data_size - MTHCA_INLINE_HEADER_SIZE; qp->sq.max_gs = min_t(int, dev->limits.max_sg, max_data_size / sizeof (struct mthca_data_seg)); @@ -1213,23 +1186,13 @@ static int mthca_alloc_qp_common(struct mthca_dev *dev, } static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap, - struct mthca_pd *pd, struct mthca_qp *qp) + struct mthca_qp *qp) { - int max_data_size = mthca_max_data_size(dev, qp, dev->limits.max_desc_sz); - /* Sanity check QP size before proceeding */ - if (cap->max_send_wr > dev->limits.max_wqes || - cap->max_recv_wr > dev->limits.max_wqes || - cap->max_send_sge > dev->limits.max_sg || - cap->max_recv_sge > dev->limits.max_sg || - cap->max_inline_data > mthca_max_inline_data(pd, max_data_size)) - return -EINVAL; - - /* - * For MLX transport we need 2 extra S/G entries: - * one for the header and one for the checksum at the end - */ - if (qp->transport == MLX && cap->max_recv_sge + 2 > dev->limits.max_sg) + if (cap->max_send_wr > dev->limits.max_wqes || + cap->max_recv_wr > dev->limits.max_wqes || + cap->max_send_sge > dev->limits.max_sg || + cap->max_recv_sge > dev->limits.max_sg) return -EINVAL; if (mthca_is_memfree(dev)) { @@ -1248,6 +1211,14 @@ static int mthca_set_qp_size(struct mthca_dev *dev, struct ib_qp_cap *cap, MTHCA_INLINE_CHUNK_SIZE) / sizeof (struct mthca_data_seg)); + /* + * For MLX transport we need 2 extra S/G entries: + * one for the header and one for the checksum at the end + */ + if ((qp->transport == MLX && qp->sq.max_gs + 2 > dev->limits.max_sg) || + qp->sq.max_gs > dev->limits.max_sg || qp->rq.max_gs > dev->limits.max_sg) + return -EINVAL; + return 0; } @@ -1262,7 +1233,7 @@ int mthca_alloc_qp(struct mthca_dev *dev, { int err; - err = mthca_set_qp_size(dev, cap, pd, qp); + err = mthca_set_qp_size(dev, cap, qp); if (err) return err; @@ -1305,7 +1276,7 @@ int mthca_alloc_sqp(struct mthca_dev *dev, u32 mqpn = qpn * 2 + dev->qp_table.sqp_start + port - 1; int err; - err = mthca_set_qp_size(dev, cap, pd, &sqp->qp); + err = mthca_set_qp_size(dev, cap, &sqp->qp); if (err) return err; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_srq.c b/trunk/drivers/infiniband/hw/mthca/mthca_srq.c index e7e153d9c4c6..f7d234295efe 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_srq.c @@ -201,7 +201,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, if (mthca_is_memfree(dev)) srq->max = roundup_pow_of_two(srq->max + 1); - ds = max(64UL, + ds = min(64UL, roundup_pow_of_two(sizeof (struct mthca_next_seg) + srq->max_gs * sizeof (struct mthca_data_seg))); srq->wqe_shift = long_log2(ds); diff --git a/trunk/drivers/infiniband/ulp/srp/ib_srp.c b/trunk/drivers/infiniband/ulp/srp/ib_srp.c index dd488d3cffa9..ee9fe226ae99 100644 --- a/trunk/drivers/infiniband/ulp/srp/ib_srp.c +++ b/trunk/drivers/infiniband/ulp/srp/ib_srp.c @@ -39,7 +39,6 @@ #include #include #include -#include #include diff --git a/trunk/drivers/input/keyboard/corgikbd.c b/trunk/drivers/input/keyboard/corgikbd.c index e301ee4ca264..64672d491222 100644 --- a/trunk/drivers/input/keyboard/corgikbd.c +++ b/trunk/drivers/input/keyboard/corgikbd.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -342,9 +343,10 @@ static int __init corgikbd_probe(struct platform_device *pdev) for (i = 0; i < CORGI_KEY_SENSE_NUM; i++) { pxa_gpio_mode(CORGI_GPIO_KEY_SENSE(i) | GPIO_IN); if (request_irq(CORGI_IRQ_GPIO_KEY_SENSE(i), corgikbd_interrupt, - SA_INTERRUPT | SA_TRIGGER_RISING, - "corgikbd", corgikbd)) + SA_INTERRUPT, "corgikbd", corgikbd)) printk(KERN_WARNING "corgikbd: Can't get IRQ: %d!\n", i); + else + set_irq_type(CORGI_IRQ_GPIO_KEY_SENSE(i),IRQT_RISING); } /* Set Strobe lines as outputs - set high */ diff --git a/trunk/drivers/input/keyboard/spitzkbd.c b/trunk/drivers/input/keyboard/spitzkbd.c index 83999d583122..6a15fe3bc527 100644 --- a/trunk/drivers/input/keyboard/spitzkbd.c +++ b/trunk/drivers/input/keyboard/spitzkbd.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -406,9 +407,10 @@ static int __init spitzkbd_probe(struct platform_device *dev) for (i = 0; i < SPITZ_KEY_SENSE_NUM; i++) { pxa_gpio_mode(spitz_senses[i] | GPIO_IN); if (request_irq(IRQ_GPIO(spitz_senses[i]), spitzkbd_interrupt, - SA_INTERRUPT|SA_TRIGGER_RISING, - "Spitzkbd Sense", spitzkbd)) + SA_INTERRUPT, "Spitzkbd Sense", spitzkbd)) printk(KERN_WARNING "spitzkbd: Can't get Sense IRQ: %d!\n", i); + else + set_irq_type(IRQ_GPIO(spitz_senses[i]),IRQT_RISING); } /* Set Strobe lines as outputs - set high */ @@ -420,18 +422,15 @@ static int __init spitzkbd_probe(struct platform_device *dev) pxa_gpio_mode(SPITZ_GPIO_SWA | GPIO_IN); pxa_gpio_mode(SPITZ_GPIO_SWB | GPIO_IN); - request_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd_interrupt, - SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING, - "Spitzkbd Sync", spitzkbd); - request_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd_interrupt, - SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING, - "Spitzkbd PwrOn", spitzkbd); - request_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd_hinge_isr, - SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING, - "Spitzkbd SWA", spitzkbd); - request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, - SA_INTERRUPT | SA_TRIGGER_RISING | SA_TRIGGER_FALLING, - "Spitzkbd SWB", spitzkbd); + request_irq(SPITZ_IRQ_GPIO_SYNC, spitzkbd_interrupt, SA_INTERRUPT, "Spitzkbd Sync", spitzkbd); + request_irq(SPITZ_IRQ_GPIO_ON_KEY, spitzkbd_interrupt, SA_INTERRUPT, "Spitzkbd PwrOn", spitzkbd); + request_irq(SPITZ_IRQ_GPIO_SWA, spitzkbd_hinge_isr, SA_INTERRUPT, "Spitzkbd SWA", spitzkbd); + request_irq(SPITZ_IRQ_GPIO_SWB, spitzkbd_hinge_isr, SA_INTERRUPT, "Spitzkbd SWB", spitzkbd); + + set_irq_type(SPITZ_IRQ_GPIO_SYNC, IRQT_BOTHEDGE); + set_irq_type(SPITZ_IRQ_GPIO_ON_KEY, IRQT_BOTHEDGE); + set_irq_type(SPITZ_IRQ_GPIO_SWA, IRQT_BOTHEDGE); + set_irq_type(SPITZ_IRQ_GPIO_SWB, IRQT_BOTHEDGE); printk(KERN_INFO "input: Spitz Keyboard Registered\n"); diff --git a/trunk/drivers/input/misc/hp_sdc_rtc.c b/trunk/drivers/input/misc/hp_sdc_rtc.c index 1be963961c15..1cd7657f7e42 100644 --- a/trunk/drivers/input/misc/hp_sdc_rtc.c +++ b/trunk/drivers/input/misc/hp_sdc_rtc.c @@ -60,6 +60,8 @@ static struct fasync_struct *hp_sdc_rtc_async_queue; static DECLARE_WAIT_QUEUE_HEAD(hp_sdc_rtc_wait); +static loff_t hp_sdc_rtc_llseek(struct file *file, loff_t offset, int origin); + static ssize_t hp_sdc_rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos); @@ -385,6 +387,11 @@ static int hp_sdc_rtc_set_i8042timer (struct timeval *setto, uint8_t setcmd) return 0; } +static loff_t hp_sdc_rtc_llseek(struct file *file, loff_t offset, int origin) +{ + return -ESPIPE; +} + static ssize_t hp_sdc_rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos) { ssize_t retval; @@ -672,7 +679,7 @@ static int hp_sdc_rtc_ioctl(struct inode *inode, struct file *file, static struct file_operations hp_sdc_rtc_fops = { .owner = THIS_MODULE, - .llseek = no_llseek, + .llseek = hp_sdc_rtc_llseek, .read = hp_sdc_rtc_read, .poll = hp_sdc_rtc_poll, .ioctl = hp_sdc_rtc_ioctl, diff --git a/trunk/drivers/isdn/act2000/act2000.h b/trunk/drivers/isdn/act2000/act2000.h index d4c50512a1ff..b091d1a54125 100644 --- a/trunk/drivers/isdn/act2000/act2000.h +++ b/trunk/drivers/isdn/act2000/act2000.h @@ -181,17 +181,17 @@ typedef struct act2000_card { char regname[35]; /* Name used for request_region */ } act2000_card; -static inline void act2000_schedule_tx(act2000_card *card) +extern __inline__ void act2000_schedule_tx(act2000_card *card) { schedule_work(&card->snd_tq); } -static inline void act2000_schedule_rx(act2000_card *card) +extern __inline__ void act2000_schedule_rx(act2000_card *card) { schedule_work(&card->rcv_tq); } -static inline void act2000_schedule_poll(act2000_card *card) +extern __inline__ void act2000_schedule_poll(act2000_card *card) { schedule_work(&card->poll_tq); } diff --git a/trunk/drivers/isdn/act2000/capi.h b/trunk/drivers/isdn/act2000/capi.h index 49f453c53c64..f6d5f530b86b 100644 --- a/trunk/drivers/isdn/act2000/capi.h +++ b/trunk/drivers/isdn/act2000/capi.h @@ -78,29 +78,29 @@ typedef union actcapi_infoel { /* info element */ typedef struct actcapi_msn { __u8 eaz; __u8 len; /* Length of MSN */ - __u8 msn[15]; -} __attribute__((packed)) actcapi_msn; + __u8 msn[15] __attribute__ ((packed)); +} actcapi_msn; typedef struct actcapi_dlpd { __u8 len; /* Length of structure */ - __u16 dlen; /* Data Length */ - __u8 laa; /* Link Address A */ + __u16 dlen __attribute__ ((packed)); /* Data Length */ + __u8 laa __attribute__ ((packed)); /* Link Address A */ __u8 lab; /* Link Address B */ __u8 modulo; /* Modulo Mode */ __u8 win; /* Window size */ __u8 xid[100]; /* XID Information */ -} __attribute__((packed)) actcapi_dlpd; +} actcapi_dlpd; typedef struct actcapi_ncpd { __u8 len; /* Length of structure */ - __u16 lic; - __u16 hic; - __u16 ltc; - __u16 htc; - __u16 loc; - __u16 hoc; - __u8 modulo; -} __attribute__((packed)) actcapi_ncpd; + __u16 lic __attribute__ ((packed)); + __u16 hic __attribute__ ((packed)); + __u16 ltc __attribute__ ((packed)); + __u16 htc __attribute__ ((packed)); + __u16 loc __attribute__ ((packed)); + __u16 hoc __attribute__ ((packed)); + __u8 modulo __attribute__ ((packed)); +} actcapi_ncpd; #define actcapi_ncpi actcapi_ncpd /* @@ -168,19 +168,19 @@ typedef struct actcapi_msg { __u16 manuf_msg; __u16 controller; actcapi_msn msnmap; - } __attribute ((packed)) manufacturer_req_msn; + } manufacturer_req_msn; /* TODO: TraceInit-req/conf/ind/resp and * TraceDump-req/conf/ind/resp */ struct connect_req { __u8 controller; __u8 bchan; - __u32 infomask; + __u32 infomask __attribute__ ((packed)); __u8 si1; __u8 si2; __u8 eaz; actcapi_addr addr; - } __attribute__ ((packed)) connect_req; + } connect_req; struct connect_conf { __u16 plci; __u16 info; @@ -192,7 +192,7 @@ typedef struct actcapi_msg { __u8 si2; __u8 eaz; actcapi_addr addr; - } __attribute__ ((packed)) connect_ind; + } connect_ind; struct connect_resp { __u16 plci; __u8 rejectcause; @@ -200,14 +200,14 @@ typedef struct actcapi_msg { struct connect_active_ind { __u16 plci; actcapi_addr addr; - } __attribute__ ((packed)) connect_active_ind; + } connect_active_ind; struct connect_active_resp { __u16 plci; } connect_active_resp; struct connect_b3_req { __u16 plci; actcapi_ncpi ncpi; - } __attribute__ ((packed)) connect_b3_req; + } connect_b3_req; struct connect_b3_conf { __u16 plci; __u16 ncci; @@ -217,12 +217,12 @@ typedef struct actcapi_msg { __u16 ncci; __u16 plci; actcapi_ncpi ncpi; - } __attribute__ ((packed)) connect_b3_ind; + } connect_b3_ind; struct connect_b3_resp { __u16 ncci; __u8 rejectcause; - actcapi_ncpi ncpi; - } __attribute__ ((packed)) connect_b3_resp; + actcapi_ncpi ncpi __attribute__ ((packed)); + } connect_b3_resp; struct disconnect_req { __u16 plci; __u8 cause; @@ -241,14 +241,14 @@ typedef struct actcapi_msg { struct connect_b3_active_ind { __u16 ncci; actcapi_ncpi ncpi; - } __attribute__ ((packed)) connect_b3_active_ind; + } connect_b3_active_ind; struct connect_b3_active_resp { __u16 ncci; } connect_b3_active_resp; struct disconnect_b3_req { __u16 ncci; actcapi_ncpi ncpi; - } __attribute__ ((packed)) disconnect_b3_req; + } disconnect_b3_req; struct disconnect_b3_conf { __u16 ncci; __u16 info; @@ -257,7 +257,7 @@ typedef struct actcapi_msg { __u16 ncci; __u16 info; actcapi_ncpi ncpi; - } __attribute__ ((packed)) disconnect_b3_ind; + } disconnect_b3_ind; struct disconnect_b3_resp { __u16 ncci; } disconnect_b3_resp; @@ -265,7 +265,7 @@ typedef struct actcapi_msg { __u16 plci; actcapi_infonr nr; actcapi_infoel el; - } __attribute__ ((packed)) info_ind; + } info_ind; struct info_resp { __u16 plci; } info_resp; @@ -279,8 +279,8 @@ typedef struct actcapi_msg { struct select_b2_protocol_req { __u16 plci; __u8 protocol; - actcapi_dlpd dlpd; - } __attribute__ ((packed)) select_b2_protocol_req; + actcapi_dlpd dlpd __attribute__ ((packed)); + } select_b2_protocol_req; struct select_b2_protocol_conf { __u16 plci; __u16 info; @@ -288,49 +288,49 @@ typedef struct actcapi_msg { struct select_b3_protocol_req { __u16 plci; __u8 protocol; - actcapi_ncpd ncpd; - } __attribute__ ((packed)) select_b3_protocol_req; + actcapi_ncpd ncpd __attribute__ ((packed)); + } select_b3_protocol_req; struct select_b3_protocol_conf { __u16 plci; __u16 info; } select_b3_protocol_conf; struct listen_req { __u8 controller; - __u32 infomask; - __u16 eazmask; - __u16 simask; - } __attribute__ ((packed)) listen_req; + __u32 infomask __attribute__ ((packed)); + __u16 eazmask __attribute__ ((packed)); + __u16 simask __attribute__ ((packed)); + } listen_req; struct listen_conf { __u8 controller; - __u16 info; - } __attribute__ ((packed)) listen_conf; + __u16 info __attribute__ ((packed)); + } listen_conf; struct data_b3_req { __u16 fakencci; __u16 datalen; __u32 unused; __u8 blocknr; - __u16 flags; - } __attribute ((packed)) data_b3_req; + __u16 flags __attribute__ ((packed)); + } data_b3_req; struct data_b3_ind { __u16 fakencci; __u16 datalen; __u32 unused; __u8 blocknr; - __u16 flags; - } __attribute__ ((packed)) data_b3_ind; + __u16 flags __attribute__ ((packed)); + } data_b3_ind; struct data_b3_resp { __u16 ncci; __u8 blocknr; - } __attribute__ ((packed)) data_b3_resp; + } data_b3_resp; struct data_b3_conf { __u16 ncci; __u8 blocknr; - __u16 info; - } __attribute__ ((packed)) data_b3_conf; + __u16 info __attribute__ ((packed)); + } data_b3_conf; } msg; -} __attribute__ ((packed)) actcapi_msg; +} actcapi_msg; -static inline unsigned short +extern __inline__ unsigned short actcapi_nextsmsg(act2000_card *card) { unsigned long flags; diff --git a/trunk/drivers/isdn/capi/capifs.c b/trunk/drivers/isdn/capi/capifs.c index 207cae366256..7b564c0dd996 100644 --- a/trunk/drivers/isdn/capi/capifs.c +++ b/trunk/drivers/isdn/capi/capifs.c @@ -17,8 +17,6 @@ #include #include /* current */ -#include "capifs.h" - MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem"); MODULE_AUTHOR("Carsten Paeth"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/isdn/hardware/eicon/os_4bri.c b/trunk/drivers/isdn/hardware/eicon/os_4bri.c index 11e6f937c1e4..cccfabc1117d 100644 --- a/trunk/drivers/isdn/hardware/eicon/os_4bri.c +++ b/trunk/drivers/isdn/hardware/eicon/os_4bri.c @@ -16,7 +16,6 @@ #include "diva_pci.h" #include "mi_pc.h" #include "dsrv4bri.h" -#include "helpers.h" static void *diva_xdiLoadFileFile = NULL; static dword diva_xdiLoadFileLength = 0; @@ -816,7 +815,7 @@ diva_4bri_cmd_card_proc(struct _diva_os_xdi_adapter *a, return (ret); } -void *xdiLoadFile(char *FileName, dword *FileLength, +void *xdiLoadFile(char *FileName, unsigned long *FileLength, unsigned long lim) { void *ret = diva_xdiLoadFileFile; diff --git a/trunk/drivers/isdn/hardware/eicon/os_bri.c b/trunk/drivers/isdn/hardware/eicon/os_bri.c index f31bba5b16ff..4cc44a5dd1db 100644 --- a/trunk/drivers/isdn/hardware/eicon/os_bri.c +++ b/trunk/drivers/isdn/hardware/eicon/os_bri.c @@ -16,7 +16,6 @@ #include "diva_pci.h" #include "mi_pc.h" #include "pc_maint.h" -#include "dsrv_bri.h" /* ** IMPORTS diff --git a/trunk/drivers/isdn/hardware/eicon/os_pri.c b/trunk/drivers/isdn/hardware/eicon/os_pri.c index a296a846f296..8ac207f75e54 100644 --- a/trunk/drivers/isdn/hardware/eicon/os_pri.c +++ b/trunk/drivers/isdn/hardware/eicon/os_pri.c @@ -18,7 +18,6 @@ #include "pc_maint.h" #include "dsp_tst.h" #include "diva_dma.h" -#include "dsrv_pri.h" /* -------------------------------------------------------------------------- OS Dependent part of XDI driver for DIVA PRI Adapter diff --git a/trunk/drivers/isdn/hisax/Kconfig b/trunk/drivers/isdn/hisax/Kconfig index 0ef560144be3..c82105920d71 100644 --- a/trunk/drivers/isdn/hisax/Kconfig +++ b/trunk/drivers/isdn/hisax/Kconfig @@ -110,7 +110,7 @@ config HISAX_16_3 config HISAX_TELESPCI bool "Teles PCI" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) + depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) help This enables HiSax support for the Teles PCI. See on how to configure it. @@ -238,7 +238,7 @@ config HISAX_MIC config HISAX_NETJET bool "NETjet card" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) + depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) help This enables HiSax support for the NetJet from Traverse Technologies. @@ -249,7 +249,7 @@ config HISAX_NETJET config HISAX_NETJET_U bool "NETspider U card" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) + depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) help This enables HiSax support for the Netspider U interface ISDN card from Traverse Technologies. @@ -317,7 +317,7 @@ config HISAX_GAZEL config HISAX_HFC_PCI bool "HFC PCI-Bus cards" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) + depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) help This enables HiSax support for the HFC-S PCI 2BDS0 based cards. @@ -344,7 +344,7 @@ config HISAX_HFC_SX config HISAX_ENTERNOW_PCI bool "Formula-n enter:now PCI card" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || FRV)) + depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K)) help This enables HiSax support for the Formula-n enter:now PCI ISDN card. diff --git a/trunk/drivers/isdn/hisax/hisax.h b/trunk/drivers/isdn/hisax/hisax.h index 1b85ce166af8..26c545fa223b 100644 --- a/trunk/drivers/isdn/hisax/hisax.h +++ b/trunk/drivers/isdn/hisax/hisax.h @@ -396,17 +396,17 @@ struct isar_hw { struct hdlc_stat_reg { #ifdef __BIG_ENDIAN - u_char fill; - u_char mode; - u_char xml; - u_char cmd; + u_char fill __attribute__((packed)); + u_char mode __attribute__((packed)); + u_char xml __attribute__((packed)); + u_char cmd __attribute__((packed)); #else - u_char cmd; - u_char xml; - u_char mode; - u_char fill; + u_char cmd __attribute__((packed)); + u_char xml __attribute__((packed)); + u_char mode __attribute__((packed)); + u_char fill __attribute__((packed)); #endif -} __attribute__((packed)); +}; struct hdlc_hw { union { diff --git a/trunk/drivers/isdn/hisax/hisax_fcpcipnp.h b/trunk/drivers/isdn/hisax/hisax_fcpcipnp.h index 21fbcedf3a94..bd8a22e4d6a2 100644 --- a/trunk/drivers/isdn/hisax/hisax_fcpcipnp.h +++ b/trunk/drivers/isdn/hisax/hisax_fcpcipnp.h @@ -12,17 +12,17 @@ enum { struct hdlc_stat_reg { #ifdef __BIG_ENDIAN - u_char fill; - u_char mode; - u_char xml; - u_char cmd; + u_char fill __attribute__((packed)); + u_char mode __attribute__((packed)); + u_char xml __attribute__((packed)); + u_char cmd __attribute__((packed)); #else - u_char cmd; - u_char xml; - u_char mode; - u_char fill; + u_char cmd __attribute__((packed)); + u_char xml __attribute__((packed)); + u_char mode __attribute__((packed)); + u_char fill __attribute__((packed)); #endif -} __attribute__((packed)); +}; struct fritz_bcs { struct hisax_b_if b_if; diff --git a/trunk/drivers/isdn/sc/command.c b/trunk/drivers/isdn/sc/command.c index b4b24335f716..19f2fcf0ae4a 100644 --- a/trunk/drivers/isdn/sc/command.c +++ b/trunk/drivers/isdn/sc/command.c @@ -43,6 +43,7 @@ extern int send_and_receive(int, unsigned int, unsigned char, unsigned char, RspMessage *, int); extern int sendmessage(int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int *); +extern inline void pullphone(char *, char *); #ifdef DEBUG /* diff --git a/trunk/drivers/macintosh/Kconfig b/trunk/drivers/macintosh/Kconfig index 7d4a0ac28c06..a0ea44c3e8b1 100644 --- a/trunk/drivers/macintosh/Kconfig +++ b/trunk/drivers/macintosh/Kconfig @@ -149,14 +149,14 @@ config MAC_EMUMOUSEBTN config THERM_WINDTUNNEL tristate "Support for thermal management on Windtunnel G4s" - depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64 + depends on I2C && I2C_KEYWEST && PPC_PMAC && !PPC_PMAC64 help This driver provides some thermostat and fan control for the desktop G4 "Windtunnel" config THERM_ADT746X tristate "Support for thermal mgmnt on laptops with ADT 746x chipset" - depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64 + depends on I2C && I2C_KEYWEST && PPC_PMAC && !PPC_PMAC64 help This driver provides some thermostat and fan control for the iBook G4, and the ATI based aluminium PowerBooks, allowing slighlty @@ -164,7 +164,7 @@ config THERM_ADT746X config THERM_PM72 tristate "Support for thermal management on PowerMac G5" - depends on I2C && I2C_POWERMAC && PPC_PMAC64 + depends on I2C && I2C_KEYWEST && PPC_PMAC64 help This driver provides thermostat and fan control for the desktop G5 machines. @@ -175,14 +175,14 @@ config WINDFARM config WINDFARM_PM81 tristate "Support for thermal management on iMac G5" depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU - select I2C_POWERMAC + select I2C_PMAC_SMU help This driver provides thermal control for the iMacG5 config WINDFARM_PM91 tristate "Support for thermal management on PowerMac9,1" depends on WINDFARM && I2C && CPU_FREQ_PMAC64 && PMAC_SMU - select I2C_POWERMAC + select I2C_PMAC_SMU help This driver provides thermal control for the PowerMac9,1 which is the recent (SMU based) single CPU desktop G5 diff --git a/trunk/drivers/macintosh/macio_asic.c b/trunk/drivers/macintosh/macio_asic.c index 2a545ceb523b..228e1852a836 100644 --- a/trunk/drivers/macintosh/macio_asic.c +++ b/trunk/drivers/macintosh/macio_asic.c @@ -3,13 +3,6 @@ * a MacIO ASIC. Interface to new driver model mostly * stolen from the PCI version. * - * Copyright (C) 2005 Ben. Herrenschmidt (benh@kernel.crashing.org) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * * TODO: * * - Don't probe below media bay by default, but instead provide @@ -225,14 +218,12 @@ postcore_initcall(macio_bus_driver_init); /** - * macio_release_dev - free a macio device structure when all users of it are - * finished. + * macio_release_dev - free a macio device structure when all users of it are finished. * @dev: device that's been disconnected * - * Will be called only by the device core when all users of this macio device - * are done. This currently means never as we don't hot remove any macio - * device yet, though that will happen with mediabay based devices in a later - * implementation. + * Will be called only by the device core when all users of this macio device are + * done. This currently means never as we don't hot remove any macio device yet, + * though that will happen with mediabay based devices in a later implementation. */ static void macio_release_dev(struct device *dev) { @@ -251,114 +242,49 @@ static void macio_release_dev(struct device *dev) * If this routine returns non-null, then the resource is completely * skipped. */ -static int macio_resource_quirks(struct device_node *np, struct resource *res, - int index) +static int macio_resource_quirks(struct device_node *np, struct resource *res, int index) { if (res->flags & IORESOURCE_MEM) { /* Grand Central has too large resource 0 on some machines */ - if (index == 0 && !strcmp(np->name, "gc")) + if (index == 0 && !strcmp(np->name, "gc")) { + np->addrs[0].size = 0x20000; res->end = res->start + 0x1ffff; - + } /* Airport has bogus resource 2 */ if (index >= 2 && !strcmp(np->name, "radio")) return 1; - -#ifndef CONFIG_PPC64 /* DBDMAs may have bogus sizes */ - if ((res->start & 0x0001f000) == 0x00008000) + if ((res->start & 0x0001f000) == 0x00008000) { + np->addrs[index].size = 0x100; res->end = res->start + 0xff; -#endif /* CONFIG_PPC64 */ - - /* ESCC parent eats child resources. We could have added a - * level of hierarchy, but I don't really feel the need - * for it - */ + } + /* ESCC parent eats child resources. We could have added a level of hierarchy, + * but I don't really feel the need for it */ if (!strcmp(np->name, "escc")) return 1; - /* ESCC has bogus resources >= 3 */ - if (index >= 3 && !(strcmp(np->name, "ch-a") && - strcmp(np->name, "ch-b"))) + if (index >= 3 && !(strcmp(np->name, "ch-a") && strcmp(np->name, "ch-b"))) return 1; - /* Media bay has too many resources, keep only first one */ if (index > 0 && !strcmp(np->name, "media-bay")) return 1; - /* Some older IDE resources have bogus sizes */ if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") && strcmp(np->type, "ide") && strcmp(np->type, "ata"))) { - if (index == 0 && (res->end - res->start) > 0xfff) + if (index == 0 && np->addrs[0].size > 0x1000) { + np->addrs[0].size = 0x1000; res->end = res->start + 0xfff; - if (index == 1 && (res->end - res->start) > 0xff) + } + if (index == 1 && np->addrs[1].size > 0x100) { + np->addrs[1].size = 0x100; res->end = res->start + 0xff; + } } } return 0; } -static void macio_setup_interrupts(struct macio_dev *dev) -{ - struct device_node *np = dev->ofdev.node; - int i,j; - - /* For now, we use pre-parsed entries in the device-tree for - * interrupt routing and addresses, but we should change that - * to dynamically parsed entries and so get rid of most of the - * clutter in struct device_node - */ - for (i = j = 0; i < np->n_intrs; i++) { - struct resource *res = &dev->interrupt[j]; - - if (j >= MACIO_DEV_COUNT_IRQS) - break; - res->start = np->intrs[i].line; - res->flags = IORESOURCE_IO; - if (np->intrs[j].sense) - res->flags |= IORESOURCE_IRQ_LOWLEVEL; - else - res->flags |= IORESOURCE_IRQ_HIGHEDGE; - res->name = dev->ofdev.dev.bus_id; - if (macio_resource_quirks(np, res, i)) - memset(res, 0, sizeof(struct resource)); - else - j++; - } - dev->n_interrupts = j; -} - -static void macio_setup_resources(struct macio_dev *dev, - struct resource *parent_res) -{ - struct device_node *np = dev->ofdev.node; - struct resource r; - int index; - - for (index = 0; of_address_to_resource(np, index, &r) == 0; index++) { - struct resource *res = &dev->resource[index]; - if (index >= MACIO_DEV_COUNT_RESOURCES) - break; - *res = r; - res->name = dev->ofdev.dev.bus_id; - - if (macio_resource_quirks(np, res, index)) { - memset(res, 0, sizeof(struct resource)); - continue; - } - /* Currently, we consider failure as harmless, this may - * change in the future, once I've found all the device - * tree bugs in older machines & worked around them - */ - if (insert_resource(parent_res, res)) { - printk(KERN_WARNING "Can't request resource " - "%d for MacIO device %s\n", - index, dev->ofdev.dev.bus_id); - } - } - dev->n_resources = index; -} - /** * macio_add_one_device - Add one device from OF node to the device tree * @chip: pointer to the macio_chip holding the device @@ -368,13 +294,12 @@ static void macio_setup_resources(struct macio_dev *dev, * When media-bay is changed to hotswap drivers, this function will * be exposed to the bay driver some way... */ -static struct macio_dev * macio_add_one_device(struct macio_chip *chip, - struct device *parent, - struct device_node *np, - struct macio_dev *in_bay, +static struct macio_dev * macio_add_one_device(struct macio_chip *chip, struct device *parent, + struct device_node *np, struct macio_dev *in_bay, struct resource *parent_res) { struct macio_dev *dev; + int i, j; u32 *reg; if (np == NULL) @@ -401,8 +326,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, /* MacIO itself has a different reg, we use it's PCI base */ if (np == chip->of_node) { - sprintf(dev->ofdev.dev.bus_id, "%1d.%08lx:%.*s", - chip->lbus.index, + sprintf(dev->ofdev.dev.bus_id, "%1d.%08lx:%.*s", chip->lbus.index, #ifdef CONFIG_PCI pci_resource_start(chip->lbus.pdev, 0), #else @@ -411,16 +335,57 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, MAX_NODE_NAME_SIZE, np->name); } else { reg = (u32 *)get_property(np, "reg", NULL); - sprintf(dev->ofdev.dev.bus_id, "%1d.%08x:%.*s", - chip->lbus.index, + sprintf(dev->ofdev.dev.bus_id, "%1d.%08x:%.*s", chip->lbus.index, reg ? *reg : 0, MAX_NODE_NAME_SIZE, np->name); } - /* Setup interrupts & resources */ - macio_setup_interrupts(dev); - macio_setup_resources(dev, parent_res); + /* For now, we use pre-parsed entries in the device-tree for + * interrupt routing and addresses, but we should change that + * to dynamically parsed entries and so get rid of most of the + * clutter in struct device_node + */ + for (i = j = 0; i < np->n_intrs; i++) { + struct resource *res = &dev->interrupt[j]; + + if (j >= MACIO_DEV_COUNT_IRQS) + break; + res->start = np->intrs[i].line; + res->flags = IORESOURCE_IO; + if (np->intrs[j].sense) + res->flags |= IORESOURCE_IRQ_LOWLEVEL; + else + res->flags |= IORESOURCE_IRQ_HIGHEDGE; + res->name = dev->ofdev.dev.bus_id; + if (macio_resource_quirks(np, res, i)) + memset(res, 0, sizeof(struct resource)); + else + j++; + } + dev->n_interrupts = j; + for (i = j = 0; i < np->n_addrs; i++) { + struct resource *res = &dev->resource[j]; + + if (j >= MACIO_DEV_COUNT_RESOURCES) + break; + res->start = np->addrs[i].address; + res->end = np->addrs[i].address + np->addrs[i].size - 1; + res->flags = IORESOURCE_MEM; + res->name = dev->ofdev.dev.bus_id; + if (macio_resource_quirks(np, res, i)) + memset(res, 0, sizeof(struct resource)); + else { + j++; + /* Currently, we consider failure as harmless, this may + * change in the future, once I've found all the device + * tree bugs in older machines & worked around them + */ + if (insert_resource(parent_res, res)) + printk(KERN_WARNING "Can't request resource %d for MacIO" + " device %s\n", i, dev->ofdev.dev.bus_id); + } + } + dev->n_resources = j; - /* Register with core */ if (of_device_register(&dev->ofdev) != 0) { printk(KERN_DEBUG"macio: device registration error for %s!\n", dev->ofdev.dev.bus_id); @@ -477,42 +442,36 @@ static void macio_pci_add_devices(struct macio_chip *chip) /* First scan 1st level */ for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { - if (macio_skip_device(np)) - continue; - of_node_get(np); - mdev = macio_add_one_device(chip, &rdev->ofdev.dev, np, NULL, - root_res); - if (mdev == NULL) - of_node_put(np); - else if (strncmp(np->name, "media-bay", 9) == 0) - mbdev = mdev; - else if (strncmp(np->name, "escc", 4) == 0) - sdev = mdev; - } - - /* Add media bay devices if any */ - if (mbdev) - for (np = NULL; (np = of_get_next_child(mbdev->ofdev.node, np)) - != NULL;) { - if (macio_skip_device(np)) - continue; + if (!macio_skip_device(np)) { of_node_get(np); - if (macio_add_one_device(chip, &mbdev->ofdev.dev, np, - mbdev, root_res) == NULL) + mdev = macio_add_one_device(chip, &rdev->ofdev.dev, np, NULL, root_res); + if (mdev == NULL) of_node_put(np); + else if (strncmp(np->name, "media-bay", 9) == 0) + mbdev = mdev; + else if (strncmp(np->name, "escc", 4) == 0) + sdev = mdev; } + } + /* Add media bay devices if any */ + if (mbdev) + for (np = NULL; (np = of_get_next_child(mbdev->ofdev.node, np)) != NULL;) + if (!macio_skip_device(np)) { + of_node_get(np); + if (macio_add_one_device(chip, &mbdev->ofdev.dev, np, mbdev, + root_res) == NULL) + of_node_put(np); + } /* Add serial ports if any */ if (sdev) { - for (np = NULL; (np = of_get_next_child(sdev->ofdev.node, np)) - != NULL;) { - if (macio_skip_device(np)) - continue; - of_node_get(np); - if (macio_add_one_device(chip, &sdev->ofdev.dev, np, - NULL, root_res) == NULL) - of_node_put(np); - } + for (np = NULL; (np = of_get_next_child(sdev->ofdev.node, np)) != NULL;) + if (!macio_skip_device(np)) { + of_node_get(np); + if (macio_add_one_device(chip, &sdev->ofdev.dev, np, NULL, + root_res) == NULL) + of_node_put(np); + } } } @@ -560,8 +519,7 @@ void macio_unregister_driver(struct macio_driver *drv) * Returns 0 on success, or %EBUSY on error. A warning * message is also printed on failure. */ -int macio_request_resource(struct macio_dev *dev, int resource_no, - const char *name) +int macio_request_resource(struct macio_dev *dev, int resource_no, const char *name) { if (macio_resource_len(dev, resource_no) == 0) return 0; @@ -648,20 +606,20 @@ static int __devinit macio_pci_probe(struct pci_dev *pdev, const struct pci_devi if (ent->vendor != PCI_VENDOR_ID_APPLE) return -ENODEV; - /* Note regarding refcounting: We assume pci_device_to_OF_node() is - * ported to new OF APIs and returns a node with refcount incremented. + /* Note regarding refcounting: We assume pci_device_to_OF_node() is ported + * to new OF APIs and returns a node with refcount incremented. This isn't + * the case today, but on the other hand ppc32 doesn't do refcounting. This + * will have to be fixed when going to ppc64. --BenH. */ np = pci_device_to_OF_node(pdev); if (np == NULL) return -ENODEV; - /* The above assumption is wrong !!! - * fix that here for now until I fix the arch code - */ + /* This assumption is wrong, fix that here for now until I fix the arch */ of_node_get(np); - /* We also assume that pmac_feature will have done a get() on nodes - * stored in the macio chips array + /* We also assume that pmac_feature will have done a get() on nodes stored + * in the macio chips array */ chip = macio_find(np, macio_unknown); of_node_put(np); @@ -681,9 +639,9 @@ static int __devinit macio_pci_probe(struct pci_dev *pdev, const struct pci_devi /* * HACK ALERT: The WallStreet PowerBook and some OHare based machines - * have 2 macio ASICs. I must probe the "main" one first or IDE - * ordering will be incorrect. So I put on "hold" the second one since - * it seem to appear first on PCI + * have 2 macio ASICs. I must probe the "main" one first or IDE ordering + * will be incorrect. So I put on "hold" the second one since it seem to + * appear first on PCI */ if (chip->type == macio_gatwick || chip->type == macio_ohareII) if (macio_chips[0].lbus.pdev == NULL) { diff --git a/trunk/drivers/macintosh/mediabay.c b/trunk/drivers/macintosh/mediabay.c index 8dbf2852bae0..b856bb67169c 100644 --- a/trunk/drivers/macintosh/mediabay.c +++ b/trunk/drivers/macintosh/mediabay.c @@ -647,7 +647,6 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de struct media_bay_info* bay; u32 __iomem *regbase; struct device_node *ofnode; - unsigned long base; int i; ofnode = mdev->ofdev.node; @@ -657,11 +656,10 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de if (macio_request_resources(mdev, "media-bay")) return -EBUSY; /* Media bay registers are located at the beginning of the - * mac-io chip, for now, we trick and align down the first - * resource passed in + * mac-io chip, we get the parent address for now (hrm...) */ - base = macio_resource_start(mdev, 0) & 0xffff0000u; - regbase = (u32 __iomem *)ioremap(base, 0x100); + regbase = (u32 __iomem *) + ioremap(ofnode->parent->addrs[0].address, 0x100); if (regbase == NULL) { macio_release_resources(mdev); return -ENOMEM; diff --git a/trunk/drivers/macintosh/smu.c b/trunk/drivers/macintosh/smu.c index db2ae71d07ef..e8378274d710 100644 --- a/trunk/drivers/macintosh/smu.c +++ b/trunk/drivers/macintosh/smu.c @@ -53,7 +53,7 @@ #undef DEBUG_SMU #ifdef DEBUG_SMU -#define DPRINTK(fmt, args...) do { printk(KERN_DEBUG fmt , ##args); } while (0) +#define DPRINTK(fmt, args...) do { udbg_printf(KERN_DEBUG fmt , ##args); } while (0) #else #define DPRINTK(fmt, args...) do { } while (0) #endif @@ -94,8 +94,6 @@ struct smu_device { static struct smu_device *smu; static DECLARE_MUTEX(smu_part_access); -static void smu_i2c_retry(unsigned long data); - /* * SMU driver low level stuff */ @@ -471,6 +469,7 @@ int __init smu_init (void) smu->of_node = np; smu->db_irq = NO_IRQ; smu->msg_irq = NO_IRQ; + init_timer(&smu->i2c_timer); /* smu_cmdbuf_abs is in the low 2G of RAM, can be converted to a * 32 bits value safely @@ -545,10 +544,6 @@ static int smu_late_init(void) if (!smu) return 0; - init_timer(&smu->i2c_timer); - smu->i2c_timer.function = smu_i2c_retry; - smu->i2c_timer.data = (unsigned long)smu; - /* * Try to request the interrupts */ @@ -575,10 +570,7 @@ static int smu_late_init(void) return 0; } -/* This has to be before arch_initcall as the low i2c stuff relies on the - * above having been done before we reach arch_initcalls - */ -core_initcall(smu_late_init); +arch_initcall(smu_late_init); /* * sysfs visibility @@ -588,10 +580,20 @@ static void smu_expose_childs(void *unused) { struct device_node *np; - for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;) + for (np = NULL; (np = of_get_next_child(smu->of_node, np)) != NULL;) { + if (device_is_compatible(np, "smu-i2c")) { + char name[32]; + u32 *reg = (u32 *)get_property(np, "reg", NULL); + + if (reg == NULL) + continue; + sprintf(name, "smu-i2c-%02x", *reg); + of_platform_device_create(np, name, &smu->of_dev->dev); + } if (device_is_compatible(np, "smu-sensors")) - of_platform_device_create(np, "smu-sensors", - &smu->of_dev->dev); + of_platform_device_create(np, "smu-sensors", &smu->of_dev->dev); + } + } static DECLARE_WORK(smu_expose_childs_work, smu_expose_childs, NULL); @@ -710,13 +712,13 @@ static void smu_i2c_complete_command(struct smu_i2c_cmd *cmd, int fail) static void smu_i2c_retry(unsigned long data) { - struct smu_i2c_cmd *cmd = smu->cmd_i2c_cur; + struct smu_i2c_cmd *cmd = (struct smu_i2c_cmd *)data; DPRINTK("SMU: i2c failure, requeuing...\n"); /* requeue command simply by resetting reply_len */ cmd->pdata[0] = 0xff; - cmd->scmd.reply_len = sizeof(cmd->pdata); + cmd->scmd.reply_len = 0x10; smu_queue_cmd(&cmd->scmd); } @@ -745,8 +747,10 @@ static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc) */ if (fail && --cmd->retries > 0) { DPRINTK("SMU: i2c failure, starting timer...\n"); - BUG_ON(cmd != smu->cmd_i2c_cur); - mod_timer(&smu->i2c_timer, jiffies + msecs_to_jiffies(5)); + smu->i2c_timer.function = smu_i2c_retry; + smu->i2c_timer.data = (unsigned long)cmd; + smu->i2c_timer.expires = jiffies + msecs_to_jiffies(5); + add_timer(&smu->i2c_timer); return; } @@ -760,7 +764,7 @@ static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc) /* Ok, initial command complete, now poll status */ scmd->reply_buf = cmd->pdata; - scmd->reply_len = sizeof(cmd->pdata); + scmd->reply_len = 0x10; scmd->data_buf = cmd->pdata; scmd->data_len = 1; cmd->pdata[0] = 0; @@ -782,7 +786,7 @@ int smu_queue_i2c(struct smu_i2c_cmd *cmd) cmd->scmd.done = smu_i2c_low_completion; cmd->scmd.misc = cmd; cmd->scmd.reply_buf = cmd->pdata; - cmd->scmd.reply_len = sizeof(cmd->pdata); + cmd->scmd.reply_len = 0x10; cmd->scmd.data_buf = (u8 *)(char *)&cmd->info; cmd->scmd.status = 1; cmd->stage = 0; @@ -905,13 +909,10 @@ static struct smu_sdbp_header *smu_create_sdb_partition(int id) struct property *prop; /* First query the partition info */ - DPRINTK("SMU: Query partition infos ... (irq=%d)\n", smu->db_irq); smu_queue_simple(&cmd, SMU_CMD_PARTITION_COMMAND, 2, smu_done_complete, &comp, SMU_CMD_PARTITION_LATEST, id); wait_for_completion(&comp); - DPRINTK("SMU: done, status: %d, reply_len: %d\n", - cmd.cmd.status, cmd.cmd.reply_len); /* Partition doesn't exist (or other error) */ if (cmd.cmd.status != 0 || cmd.cmd.reply_len != 6) @@ -974,8 +975,6 @@ struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size, sprintf(pname, "sdb-partition-%02x", id); - DPRINTK("smu_get_sdb_partition(%02x)\n", id); - if (interruptible) { int rc; rc = down_interruptible(&smu_part_access); @@ -987,7 +986,6 @@ struct smu_sdbp_header *__smu_get_sdb_partition(int id, unsigned int *size, part = (struct smu_sdbp_header *)get_property(smu->of_node, pname, size); if (part == NULL) { - DPRINTK("trying to extract from SMU ...\n"); part = smu_create_sdb_partition(id); if (part != NULL && size) *size = part->len << 2; diff --git a/trunk/drivers/macintosh/via-cuda.c b/trunk/drivers/macintosh/via-cuda.c index 2d9d79150403..d843a6c9c6df 100644 --- a/trunk/drivers/macintosh/via-cuda.c +++ b/trunk/drivers/macintosh/via-cuda.c @@ -127,34 +127,39 @@ struct adb_driver via_cuda_driver = { #endif /* CONFIG_ADB */ #ifdef CONFIG_PPC -int __init find_via_cuda(void) +int __init +find_via_cuda(void) { - struct adb_request req; - phys_addr_t taddr; - u32 *reg; int err; + struct adb_request req; if (vias != 0) return 1; - vias = of_find_node_by_name(NULL, "via-cuda"); + vias = find_devices("via-cuda"); if (vias == 0) return 0; + if (vias->next != 0) + printk(KERN_WARNING "Warning: only using 1st via-cuda\n"); + +#if 0 + { int i; + + printk("find_via_cuda: node = %p, addrs =", vias->node); + for (i = 0; i < vias->n_addrs; ++i) + printk(" %x(%x)", vias->addrs[i].address, vias->addrs[i].size); + printk(", intrs ="); + for (i = 0; i < vias->n_intrs; ++i) + printk(" %x", vias->intrs[i].line); + printk("\n"); } +#endif - reg = (u32 *)get_property(vias, "reg", NULL); - if (reg == NULL) { - printk(KERN_ERR "via-cuda: No \"reg\" property !\n"); - goto fail; - } - taddr = of_translate_address(vias, reg); - if (taddr == 0) { - printk(KERN_ERR "via-cuda: Can't translate address !\n"); - goto fail; - } - via = ioremap(taddr, 0x2000); - if (via == NULL) { - printk(KERN_ERR "via-cuda: Can't map address !\n"); - goto fail; + if (vias->n_addrs != 1 || vias->n_intrs != 1) { + printk(KERN_ERR "via-cuda: expecting 1 address (%d) and 1 interrupt (%d)\n", + vias->n_addrs, vias->n_intrs); + if (vias->n_addrs < 1 || vias->n_intrs < 1) + return 0; } + via = ioremap(vias->addrs->address, 0x2000); cuda_state = idle; sys_ctrler = SYS_CTRLER_CUDA; @@ -180,11 +185,6 @@ int __init find_via_cuda(void) cuda_poll(); return 1; - - fail: - of_node_put(vias); - vias = NULL; - return 0; } #endif /* CONFIG_PPC */ @@ -193,6 +193,10 @@ static int __init via_cuda_start(void) if (via == NULL) return -ENODEV; +#ifdef CONFIG_PPC + request_OF_resource(vias, 0, NULL); +#endif + if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) { printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ); return -EAGAIN; diff --git a/trunk/drivers/macintosh/via-pmu.c b/trunk/drivers/macintosh/via-pmu.c index 6eb93e45fcd3..564043508569 100644 --- a/trunk/drivers/macintosh/via-pmu.c +++ b/trunk/drivers/macintosh/via-pmu.c @@ -55,8 +55,6 @@ #include #include #include -#include -#include #include #include #include @@ -149,7 +147,6 @@ static struct device_node *vias; static int pmu_kind = PMU_UNKNOWN; static int pmu_fully_inited = 0; static int pmu_has_adb; -static struct device_node *gpio_node; static unsigned char __iomem *gpio_reg = NULL; static int gpio_irq = -1; static int gpio_irq_enabled = -1; @@ -160,8 +157,8 @@ static int pmu_version; static int drop_interrupts; #if defined(CONFIG_PM) && defined(CONFIG_PPC32) static int option_lid_wakeup = 1; -#endif /* CONFIG_PM && CONFIG_PPC32 */ static int sleep_in_progress; +#endif /* CONFIG_PM && CONFIG_PPC32 */ static unsigned long async_req_locks; static unsigned int pmu_irq_stats[11]; @@ -199,6 +196,7 @@ static int pmu_adb_reset_bus(void); #endif /* CONFIG_ADB */ static int init_pmu(void); +static int pmu_queue_request(struct adb_request *req); static void pmu_start(void); static irqreturn_t via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs); static irqreturn_t gpio1_interrupt(int irq, void *arg, struct pt_regs *regs); @@ -297,26 +295,22 @@ static struct backlight_controller pmu_backlight_controller = { }; #endif /* CONFIG_PMAC_BACKLIGHT */ -int __init find_via_pmu(void) +int +find_via_pmu(void) { - u64 taddr; - u32 *reg; - if (via != 0) return 1; - vias = of_find_node_by_name(NULL, "via-pmu"); - if (vias == NULL) + vias = find_devices("via-pmu"); + if (vias == 0) return 0; + if (vias->next != 0) + printk(KERN_WARNING "Warning: only using 1st via-pmu\n"); - reg = (u32 *)get_property(vias, "reg", NULL); - if (reg == NULL) { - printk(KERN_ERR "via-pmu: No \"reg\" property !\n"); - goto fail; - } - taddr = of_translate_address(vias, reg); - if (taddr == OF_BAD_ADDR) { - printk(KERN_ERR "via-pmu: Can't translate address !\n"); - goto fail; + if (vias->n_addrs < 1 || vias->n_intrs < 1) { + printk(KERN_ERR "via-pmu: %d addresses, %d interrupts!\n", + vias->n_addrs, vias->n_intrs); + if (vias->n_addrs < 1 || vias->n_intrs < 1) + return 0; } spin_lock_init(&pmu_lock); @@ -337,8 +331,7 @@ int __init find_via_pmu(void) pmu_kind = PMU_HEATHROW_BASED; else if (device_is_compatible(vias->parent, "Keylargo") || device_is_compatible(vias->parent, "K2-Keylargo")) { - struct device_node *gpiop; - u64 gaddr = OF_BAD_ADDR; + struct device_node *gpio, *gpiop; pmu_kind = PMU_KEYLARGO_BASED; pmu_has_adb = (find_type_devices("adb") != NULL); @@ -348,24 +341,19 @@ int __init find_via_pmu(void) PMU_INT_TICK | PMU_INT_ENVIRONMENT; - gpiop = of_find_node_by_name(NULL, "gpio"); - if (gpiop) { - reg = (u32 *)get_property(gpiop, "reg", NULL); - if (reg) - gaddr = of_translate_address(gpiop, reg); - if (gaddr != OF_BAD_ADDR) - gpio_reg = ioremap(gaddr, 0x10); + gpiop = find_devices("gpio"); + if (gpiop && gpiop->n_addrs) { + gpio_reg = ioremap(gpiop->addrs->address, 0x10); + gpio = find_devices("extint-gpio1"); + if (gpio == NULL) + gpio = find_devices("pmu-interrupt"); + if (gpio && gpio->parent == gpiop && gpio->n_intrs) + gpio_irq = gpio->intrs[0].line; } - if (gpio_reg == NULL) - printk(KERN_ERR "via-pmu: Can't find GPIO reg !\n"); } else pmu_kind = PMU_UNKNOWN; - via = ioremap(taddr, 0x2000); - if (via == NULL) { - printk(KERN_ERR "via-pmu: Can't map address !\n"); - goto fail; - } + via = ioremap(vias->addrs->address, 0x2000); out_8(&via[IER], IER_CLR | 0x7f); /* disable all intrs */ out_8(&via[IFR], 0x7f); /* clear IFR */ @@ -377,25 +365,23 @@ int __init find_via_pmu(void) return 0; } - printk(KERN_INFO "PMU driver v%d initialized for %s, firmware: %02x\n", + printk(KERN_INFO "PMU driver %d initialized for %s, firmware: %02x\n", PMU_DRIVER_VERSION, pbook_type[pmu_kind], pmu_version); sys_ctrler = SYS_CTRLER_PMU; return 1; - fail: - of_node_put(vias); - vias = NULL; - return 0; } #ifdef CONFIG_ADB -static int pmu_probe(void) +static int +pmu_probe(void) { return vias == NULL? -ENODEV: 0; } -static int __init pmu_init(void) +static int __init +pmu_init(void) { if (vias == NULL) return -ENODEV; @@ -419,7 +405,7 @@ static int __init via_pmu_start(void) bright_req_2.complete = 1; batt_req.complete = 1; -#ifndef CONFIG_PPC_MERGE +#if defined(CONFIG_PPC32) && !defined(CONFIG_PPC_MERGE) if (pmu_kind == PMU_KEYLARGO_BASED) openpic_set_irq_priority(vias->intrs[0].line, OPENPIC_PRIORITY_DEFAULT + 1); @@ -432,22 +418,10 @@ static int __init via_pmu_start(void) return -EAGAIN; } - if (pmu_kind == PMU_KEYLARGO_BASED) { - gpio_node = of_find_node_by_name(NULL, "extint-gpio1"); - if (gpio_node == NULL) - gpio_node = of_find_node_by_name(NULL, - "pmu-interrupt"); - if (gpio_node && gpio_node->n_intrs > 0) - gpio_irq = gpio_node->intrs[0].line; - - if (gpio_irq != -1) { - if (request_irq(gpio_irq, gpio1_interrupt, 0, - "GPIO1 ADB", (void *)0)) - printk(KERN_ERR "pmu: can't get irq %d" - " (GPIO1)\n", gpio_irq); - else - gpio_irq_enabled = 1; - } + if (pmu_kind == PMU_KEYLARGO_BASED && gpio_irq != -1) { + if (request_irq(gpio_irq, gpio1_interrupt, 0, "GPIO1 ADB", (void *)0)) + printk(KERN_ERR "pmu: can't get irq %d (GPIO1)\n", gpio_irq); + gpio_irq_enabled = 1; } /* Enable interrupts */ @@ -480,6 +454,9 @@ static int __init via_pmu_dev_init(void) if (vias == NULL) return -ENODEV; +#ifndef CONFIG_PPC64 + request_OF_resource(vias, 0, NULL); +#endif #ifdef CONFIG_PMAC_BACKLIGHT /* Enable backlight */ register_backlight_controller(&pmu_backlight_controller, NULL, "pmu"); @@ -1394,6 +1371,7 @@ pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) } pmu_done(req); } else { +#if defined(CONFIG_XMON) && !defined(CONFIG_PPC64) if (len == 4 && data[1] == 0x2c) { extern int xmon_wants_key, xmon_adb_keycode; if (xmon_wants_key) { @@ -1401,6 +1379,7 @@ pmu_handle_data(unsigned char *data, int len, struct pt_regs *regs) return; } } +#endif /* defined(CONFIG_XMON) && !defined(CONFIG_PPC64) */ #ifdef CONFIG_ADB /* * XXX On the [23]400 the PMU gives us an up @@ -1803,6 +1782,258 @@ pmu_present(void) return via != 0; } +struct pmu_i2c_hdr { + u8 bus; + u8 mode; + u8 bus2; + u8 address; + u8 sub_addr; + u8 comb_addr; + u8 count; +}; + +int +pmu_i2c_combined_read(int bus, int addr, int subaddr, u8* data, int len) +{ + struct adb_request req; + struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1]; + int retry; + int rc; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + hdr->bus = bus; + hdr->address = addr & 0xfe; + hdr->mode = PMU_I2C_MODE_COMBINED; + hdr->bus2 = 0; + hdr->sub_addr = subaddr; + hdr->comb_addr = addr | 1; + hdr->count = len; + + req.nbytes = sizeof(struct pmu_i2c_hdr) + 1; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + req.reply[0] = 0xff; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + break; + mdelay(15); + } + if (req.reply[0] != PMU_I2C_STATUS_OK) + return -1; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + mdelay(15); + + hdr->bus = PMU_I2C_BUS_STATUS; + req.reply[0] = 0xff; + + req.nbytes = 2; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_DATAREAD) { + memcpy(data, &req.reply[1], req.reply_len - 1); + return req.reply_len - 1; + } + } + return -1; +} + +int +pmu_i2c_stdsub_write(int bus, int addr, int subaddr, u8* data, int len) +{ + struct adb_request req; + struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1]; + int retry; + int rc; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + hdr->bus = bus; + hdr->address = addr & 0xfe; + hdr->mode = PMU_I2C_MODE_STDSUB; + hdr->bus2 = 0; + hdr->sub_addr = subaddr; + hdr->comb_addr = addr & 0xfe; + hdr->count = len; + + req.data[0] = PMU_I2C_CMD; + memcpy(&req.data[sizeof(struct pmu_i2c_hdr) + 1], data, len); + req.nbytes = sizeof(struct pmu_i2c_hdr) + len + 1; + req.reply_expected = 0; + req.reply_len = 0; + req.reply[0] = 0xff; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + break; + mdelay(15); + } + if (req.reply[0] != PMU_I2C_STATUS_OK) + return -1; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + mdelay(15); + + hdr->bus = PMU_I2C_BUS_STATUS; + req.reply[0] = 0xff; + + req.nbytes = 2; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + return len; + } + return -1; +} + +int +pmu_i2c_simple_read(int bus, int addr, u8* data, int len) +{ + struct adb_request req; + struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1]; + int retry; + int rc; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + hdr->bus = bus; + hdr->address = addr | 1; + hdr->mode = PMU_I2C_MODE_SIMPLE; + hdr->bus2 = 0; + hdr->sub_addr = 0; + hdr->comb_addr = 0; + hdr->count = len; + + req.data[0] = PMU_I2C_CMD; + req.nbytes = sizeof(struct pmu_i2c_hdr) + 1; + req.reply_expected = 0; + req.reply_len = 0; + req.reply[0] = 0xff; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + break; + mdelay(15); + } + if (req.reply[0] != PMU_I2C_STATUS_OK) + return -1; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + mdelay(15); + + hdr->bus = PMU_I2C_BUS_STATUS; + req.reply[0] = 0xff; + + req.nbytes = 2; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_DATAREAD) { + memcpy(data, &req.reply[1], req.reply_len - 1); + return req.reply_len - 1; + } + } + return -1; +} + +int +pmu_i2c_simple_write(int bus, int addr, u8* data, int len) +{ + struct adb_request req; + struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req.data[1]; + int retry; + int rc; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + hdr->bus = bus; + hdr->address = addr & 0xfe; + hdr->mode = PMU_I2C_MODE_SIMPLE; + hdr->bus2 = 0; + hdr->sub_addr = 0; + hdr->comb_addr = 0; + hdr->count = len; + + req.data[0] = PMU_I2C_CMD; + memcpy(&req.data[sizeof(struct pmu_i2c_hdr) + 1], data, len); + req.nbytes = sizeof(struct pmu_i2c_hdr) + len + 1; + req.reply_expected = 0; + req.reply_len = 0; + req.reply[0] = 0xff; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + break; + mdelay(15); + } + if (req.reply[0] != PMU_I2C_STATUS_OK) + return -1; + + for (retry=0; retry<16; retry++) { + memset(&req, 0, sizeof(req)); + + mdelay(15); + + hdr->bus = PMU_I2C_BUS_STATUS; + req.reply[0] = 0xff; + + req.nbytes = 2; + req.reply_expected = 0; + req.reply_len = 0; + req.data[0] = PMU_I2C_CMD; + rc = pmu_queue_request(&req); + if (rc) + return rc; + while(!req.complete) + pmu_poll(); + if (req.reply[0] == PMU_I2C_STATUS_OK) + return len; + } + return -1; +} + #ifdef CONFIG_PM static LIST_HEAD(sleep_notifiers); @@ -2107,9 +2338,8 @@ pmac_suspend_devices(void) return -EBUSY; } - /* Call platform functions marked "on sleep" */ - pmac_pfunc_i2c_suspend(); - pmac_pfunc_base_suspend(); + /* Disable clock spreading on some machines */ + pmac_tweak_clock_spreading(0); /* Stop preemption */ preempt_disable(); @@ -2181,9 +2411,8 @@ pmac_wakeup_devices(void) mdelay(10); preempt_enable(); - /* Call platform functions marked "on wake" */ - pmac_pfunc_base_resume(); - pmac_pfunc_i2c_resume(); + /* Re-enable clock spreading on some machines */ + pmac_tweak_clock_spreading(1); /* Resume devices */ device_resume(); @@ -2901,13 +3130,16 @@ static int __init init_pmu_sysfs(void) subsys_initcall(init_pmu_sysfs); EXPORT_SYMBOL(pmu_request); -EXPORT_SYMBOL(pmu_queue_request); EXPORT_SYMBOL(pmu_poll); EXPORT_SYMBOL(pmu_poll_adb); EXPORT_SYMBOL(pmu_wait_complete); EXPORT_SYMBOL(pmu_suspend); EXPORT_SYMBOL(pmu_resume); EXPORT_SYMBOL(pmu_unlock); +EXPORT_SYMBOL(pmu_i2c_combined_read); +EXPORT_SYMBOL(pmu_i2c_stdsub_write); +EXPORT_SYMBOL(pmu_i2c_simple_read); +EXPORT_SYMBOL(pmu_i2c_simple_write); #if defined(CONFIG_PM) && defined(CONFIG_PPC32) EXPORT_SYMBOL(pmu_enable_irled); EXPORT_SYMBOL(pmu_battery_count); diff --git a/trunk/drivers/macintosh/windfarm_lm75_sensor.c b/trunk/drivers/macintosh/windfarm_lm75_sensor.c index 906d3ecae6e6..57460e46c89f 100644 --- a/trunk/drivers/macintosh/windfarm_lm75_sensor.c +++ b/trunk/drivers/macintosh/windfarm_lm75_sensor.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "windfarm.h" @@ -158,21 +157,53 @@ static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter, static int wf_lm75_attach(struct i2c_adapter *adapter) { - struct device_node *busnode, *dev; - struct pmac_i2c_bus *bus; + u8 bus_id; + struct device_node *smu, *bus, *dev; + + /* We currently only deal with LM75's hanging off the SMU + * i2c busses. If we extend that driver to other/older + * machines, we should split this function into SMU-i2c, + * keywest-i2c, PMU-i2c, ... + */ DBG("wf_lm75: adapter %s detected\n", adapter->name); - bus = pmac_i2c_adapter_to_bus(adapter); - if (bus == NULL) - return -ENODEV; - busnode = pmac_i2c_get_bus_node(bus); + if (strncmp(adapter->name, "smu-i2c-", 8) != 0) + return 0; + smu = of_find_node_by_type(NULL, "smu"); + if (smu == NULL) + return 0; + + /* Look for the bus in the device-tree */ + bus_id = (u8)simple_strtoul(adapter->name + 8, NULL, 16); + + DBG("wf_lm75: bus ID is %x\n", bus_id); + + /* Look for sensors subdir */ + for (bus = NULL; + (bus = of_get_next_child(smu, bus)) != NULL;) { + u32 *reg; + + if (strcmp(bus->name, "i2c")) + continue; + reg = (u32 *)get_property(bus, "reg", NULL); + if (reg == NULL) + continue; + if (bus_id == *reg) + break; + } + of_node_put(smu); + if (bus == NULL) { + printk(KERN_WARNING "windfarm: SMU i2c bus 0x%x not found" + " in device-tree !\n", bus_id); + return 0; + } DBG("wf_lm75: bus found, looking for device...\n"); /* Now look for lm75(s) in there */ for (dev = NULL; - (dev = of_get_next_child(busnode, dev)) != NULL;) { + (dev = of_get_next_child(bus, dev)) != NULL;) { const char *loc = get_property(dev, "hwsensor-location", NULL); u32 *reg = (u32 *)get_property(dev, "reg", NULL); @@ -186,6 +217,9 @@ static int wf_lm75_attach(struct i2c_adapter *adapter) else if (device_is_compatible(dev, "ds1775")) wf_lm75_create(adapter, *reg, 1, loc); } + + of_node_put(bus); + return 0; } diff --git a/trunk/drivers/macintosh/windfarm_smu_controls.c b/trunk/drivers/macintosh/windfarm_smu_controls.c index 4d811600bdab..2c3158c81ff2 100644 --- a/trunk/drivers/macintosh/windfarm_smu_controls.c +++ b/trunk/drivers/macintosh/windfarm_smu_controls.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/macintosh/windfarm_smu_sensors.c b/trunk/drivers/macintosh/windfarm_smu_sensors.c index 1a00d9c75a23..b558cc209d49 100644 --- a/trunk/drivers/macintosh/windfarm_smu_sensors.c +++ b/trunk/drivers/macintosh/windfarm_smu_sensors.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index e423a16ba3c9..1b76fb29fb70 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -3598,21 +3598,12 @@ static int set_disk_faulty(mddev_t *mddev, dev_t dev) return 0; } -static int md_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - mddev_t *mddev = bdev->bd_disk->private_data; - - geo->heads = 2; - geo->sectors = 4; - geo->cylinders = get_capacity(mddev->gendisk) / 8; - return 0; -} - static int md_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int err = 0; void __user *argp = (void __user *)arg; + struct hd_geometry __user *loc = argp; mddev_t *mddev = NULL; if (!capable(CAP_SYS_ADMIN)) @@ -3774,6 +3765,24 @@ static int md_ioctl(struct inode *inode, struct file *file, * 4 sectors (with a BIG number of cylinders...). This drives * dosfs just mad... ;-) */ + case HDIO_GETGEO: + if (!loc) { + err = -EINVAL; + goto abort_unlock; + } + err = put_user (2, (char __user *) &loc->heads); + if (err) + goto abort_unlock; + err = put_user (4, (char __user *) &loc->sectors); + if (err) + goto abort_unlock; + err = put_user(get_capacity(mddev->gendisk)/8, + (short __user *) &loc->cylinders); + if (err) + goto abort_unlock; + err = put_user (get_start_sect(inode->i_bdev), + (long __user *) &loc->start); + goto done_unlock; } /* @@ -3902,7 +3911,6 @@ static struct block_device_operations md_fops = .open = md_open, .release = md_release, .ioctl = md_ioctl, - .getgeo = md_getgeo, .media_changed = md_media_changed, .revalidate_disk= md_revalidate, }; diff --git a/trunk/drivers/md/raid0.c b/trunk/drivers/md/raid0.c index d03f99cf4b7d..abbca150202b 100644 --- a/trunk/drivers/md/raid0.c +++ b/trunk/drivers/md/raid0.c @@ -306,6 +306,9 @@ static int raid0_run (mddev_t *mddev) printk("raid0 : conf->hash_spacing is %llu blocks.\n", (unsigned long long)conf->hash_spacing); { +#if __GNUC__ < 3 + volatile +#endif sector_t s = mddev->array_size; sector_t space = conf->hash_spacing; int round; @@ -436,6 +439,9 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio) { +#if __GNUC__ < 3 + volatile +#endif sector_t x = block >> conf->preshift; sector_div(x, (u32)conf->hash_spacing); zone = conf->hash_table[x]; diff --git a/trunk/drivers/media/common/saa7146_fops.c b/trunk/drivers/media/common/saa7146_fops.c index b614612be7b4..09ec964dec5c 100644 --- a/trunk/drivers/media/common/saa7146_fops.c +++ b/trunk/drivers/media/common/saa7146_fops.c @@ -253,10 +253,7 @@ static int fops_open(struct inode *inode, struct file *file) if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { DEB_S(("initializing vbi...\n")); - if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) - result = saa7146_vbi_uops.open(dev,file); - if (dev->ext_vv_data->vbi_fops.open) - dev->ext_vv_data->vbi_fops.open(inode, file); + result = saa7146_vbi_uops.open(dev,file); } else { DEB_S(("initializing video...\n")); result = saa7146_video_uops.open(dev,file); @@ -292,10 +289,7 @@ static int fops_release(struct inode *inode, struct file *file) return -ERESTARTSYS; if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) - saa7146_vbi_uops.release(dev,file); - if (dev->ext_vv_data->vbi_fops.release) - dev->ext_vv_data->vbi_fops.release(inode, file); + saa7146_vbi_uops.release(dev,file); } else { saa7146_video_uops.release(dev,file); } @@ -338,7 +332,6 @@ static int fops_mmap(struct file *file, struct vm_area_struct * vma) BUG(); return 0; } - return videobuf_mmap_mapper(q,vma); } @@ -388,10 +381,7 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof } case V4L2_BUF_TYPE_VBI_CAPTURE: { // DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count)); - if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) - return saa7146_vbi_uops.read(file,data,count,ppos); - else - return -EINVAL; + return saa7146_vbi_uops.read(file,data,count,ppos); } break; default: @@ -400,31 +390,12 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof } } -static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) -{ - struct saa7146_fh *fh = file->private_data; - - switch (fh->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - return -EINVAL; - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (fh->dev->ext_vv_data->vbi_fops.write) - return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos); - else - return -EINVAL; - default: - BUG(); - return -EINVAL; - } -} - static struct file_operations video_fops = { .owner = THIS_MODULE, .open = fops_open, .release = fops_release, .read = fops_read, - .write = fops_write, .poll = fops_poll, .mmap = fops_mmap, .ioctl = fops_ioctl, @@ -496,8 +467,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM); saa7146_video_uops.init(dev,vv); - if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE) - saa7146_vbi_uops.init(dev,vv); + saa7146_vbi_uops.init(dev,vv); dev->vv_data = vv; dev->vv_callback = &vv_callback; diff --git a/trunk/drivers/media/common/saa7146_hlp.c b/trunk/drivers/media/common/saa7146_hlp.c index 33bec8a6843b..ec52dff8cb69 100644 --- a/trunk/drivers/media/common/saa7146_hlp.c +++ b/trunk/drivers/media/common/saa7146_hlp.c @@ -562,26 +562,19 @@ static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int int b_depth = vv->ov_fmt->depth; int b_bpl = vv->ov_fb.fmt.bytesperline; - /* The unsigned long cast is to remove a 64-bit compile warning since - it looks like a 64-bit address is cast to a 32-bit value, even - though the base pointer is really a 32-bit physical address that - goes into a 32-bit DMA register. - FIXME: might not work on some 64-bit platforms, but see the FIXME - in struct v4l2_framebuffer (videodev2.h) for that. - */ - u32 base = (u32)(unsigned long)vv->ov_fb.base; + u32 base = (u32)vv->ov_fb.base; struct saa7146_video_dma vdma1; /* calculate memory offsets for picture, look if we shall top-down-flip */ vdma1.pitch = 2*b_bpl; if ( 0 == vv->vflip ) { - vdma1.base_even = base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); + vdma1.base_even = (u32)base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); vdma1.base_odd = vdma1.base_even + (vdma1.pitch / 2); vdma1.prot_addr = vdma1.base_even + (w_height * (vdma1.pitch / 2)); } else { - vdma1.base_even = base + ((w_y+w_height) * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); + vdma1.base_even = (u32)base + ((w_y+w_height) * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); vdma1.base_odd = vdma1.base_even - (vdma1.pitch / 2); vdma1.prot_addr = vdma1.base_odd - (w_height * (vdma1.pitch / 2)); } diff --git a/trunk/drivers/media/common/saa7146_vbi.c b/trunk/drivers/media/common/saa7146_vbi.c index 468d3c959075..063986ec16b5 100644 --- a/trunk/drivers/media/common/saa7146_vbi.c +++ b/trunk/drivers/media/common/saa7146_vbi.c @@ -500,9 +500,9 @@ static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff } struct saa7146_use_ops saa7146_vbi_uops = { - .init = vbi_init, - .open = vbi_open, + .init = vbi_init, + .open = vbi_open, .release = vbi_close, .irq_done = vbi_irq_done, - .read = vbi_read, + .read = vbi_read, }; diff --git a/trunk/drivers/media/common/saa7146_video.c b/trunk/drivers/media/common/saa7146_video.c index 7ebac7949df3..1d961023b837 100644 --- a/trunk/drivers/media/common/saa7146_video.c +++ b/trunk/drivers/media/common/saa7146_video.c @@ -151,8 +151,8 @@ static int try_win(struct saa7146_dev *dev, struct v4l2_window *win) if (V4L2_FIELD_ANY == field) { field = (win->w.height > maxh/2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_TOP; + ? V4L2_FIELD_INTERLACED + : V4L2_FIELD_TOP; } switch (field) { case V4L2_FIELD_TOP: @@ -1114,6 +1114,10 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int return 0; } case VIDIOC_OVERLAY: + + + + { int on = *(int *)arg; int err = 0; @@ -1355,6 +1359,7 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) saa7146_buffer_queue(fh->dev,&vv->video_q,buf); } + static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { struct file *file = q->priv_data; diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/trunk/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 0b940e152b79..21a9045b3ef6 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-fe-tuner.c @@ -298,7 +298,7 @@ static int flexcop_fe_request_firmware(struct dvb_frontend* fe, const struct fir } static int lgdt3303_pll_set(struct dvb_frontend* fe, - struct dvb_frontend_parameters* params) + struct dvb_frontend_parameters* params) { struct flexcop_device *fc = fe->dvb->priv; u8 buf[4]; @@ -485,16 +485,12 @@ static struct stv0297_config alps_tdee4_stv0297_config = { /* try to figure out the frontend, each card/box can have on of the following list */ int flexcop_frontend_init(struct flexcop_device *fc) { - struct dvb_frontend_ops *ops; - /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { - ops = fc->fe->ops; - - ops->set_voltage = flexcop_set_voltage; + fc->fe->ops->set_voltage = flexcop_set_voltage; - fc->fe_sleep = ops->sleep; - ops->sleep = flexcop_sleep; + fc->fe_sleep = fc->fe->ops->sleep; + fc->fe->ops->sleep = flexcop_sleep; fc->dev_type = FC_SKY; info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address); @@ -526,17 +522,15 @@ int flexcop_frontend_init(struct flexcop_device *fc) } else /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { - ops = fc->fe->ops; - - ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; - ops->diseqc_send_burst = flexcop_diseqc_send_burst; - ops->set_tone = flexcop_set_tone; - ops->set_voltage = flexcop_set_voltage; + fc->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; + fc->fe->ops->diseqc_send_burst = flexcop_diseqc_send_burst; + fc->fe->ops->set_tone = flexcop_set_tone; + fc->fe->ops->set_voltage = flexcop_set_voltage; - fc->fe_sleep = ops->sleep; - ops->sleep = flexcop_sleep; + fc->fe_sleep = fc->fe->ops->sleep; + fc->fe->ops->sleep = flexcop_sleep; - fc->dev_type = FC_SKY_OLD; + fc->dev_type = FC_SKY_OLD; info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address); } @@ -546,9 +540,8 @@ int flexcop_frontend_init(struct flexcop_device *fc) } else { if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { err("frontend registration failed!"); - ops = fc->fe->ops; - if (ops->release != NULL) - ops->release(fc->fe); + if (fc->fe->ops->release != NULL) + fc->fe->ops->release(fc->fe); fc->fe = NULL; return -EINVAL; } diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-reg.h b/trunk/drivers/media/dvb/b2c2/flexcop-reg.h index 3153f9513c63..23cc6431e2b8 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-reg.h +++ b/trunk/drivers/media/dvb/b2c2/flexcop-reg.h @@ -39,13 +39,11 @@ extern const char *flexcop_device_names[]; /* FlexCop IBI Registers */ #if defined(__LITTLE_ENDIAN) #include "flexcop_ibi_value_le.h" -#else -#if defined(__BIG_ENDIAN) +#elif defined(__BIG_ENDIAN) #include "flexcop_ibi_value_be.h" #else #error no endian defined #endif -#endif #define fc_data_Tag_ID_DVB 0x3e #define fc_data_Tag_ID_ATSC 0x3f diff --git a/trunk/drivers/media/dvb/bt8xx/dst.c b/trunk/drivers/media/dvb/bt8xx/dst.c index 3a2ff1cc24b7..8977c7a313df 100644 --- a/trunk/drivers/media/dvb/bt8xx/dst.c +++ b/trunk/drivers/media/dvb/bt8xx/dst.c @@ -1341,40 +1341,30 @@ static int dst_read_snr(struct dvb_frontend *fe, u16 *snr) return 0; } -static int dst_set_frontend(struct dvb_frontend* fe, - struct dvb_frontend_parameters* p, - unsigned int mode_flags, - int *delay, - fe_status_t *status) +static int dst_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) { struct dst_state *state = fe->demodulator_priv; - if (p != NULL) { - dst_set_freq(state, p->frequency); - dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); + dst_set_freq(state, p->frequency); + dprintk(verbose, DST_DEBUG, 1, "Set Frequency=[%d]", p->frequency); - if (state->dst_type == DST_TYPE_IS_SAT) { - if (state->type_flags & DST_TYPE_HAS_OBS_REGS) - dst_set_inversion(state, p->inversion); - dst_set_fec(state, p->u.qpsk.fec_inner); - dst_set_symbolrate(state, p->u.qpsk.symbol_rate); - dst_set_polarization(state); - dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); - - } else if (state->dst_type == DST_TYPE_IS_TERR) - dst_set_bandwidth(state, p->u.ofdm.bandwidth); - else if (state->dst_type == DST_TYPE_IS_CABLE) { - dst_set_fec(state, p->u.qam.fec_inner); - dst_set_symbolrate(state, p->u.qam.symbol_rate); - dst_set_modulation(state, p->u.qam.modulation); - } - dst_write_tuna(fe); - } + if (state->dst_type == DST_TYPE_IS_SAT) { + if (state->type_flags & DST_TYPE_HAS_OBS_REGS) + dst_set_inversion(state, p->inversion); + dst_set_fec(state, p->u.qpsk.fec_inner); + dst_set_symbolrate(state, p->u.qpsk.symbol_rate); + dst_set_polarization(state); + dprintk(verbose, DST_DEBUG, 1, "Set Symbolrate=[%d]", p->u.qpsk.symbol_rate); - if (!(mode_flags & FE_TUNE_MODE_ONESHOT)) - dst_read_status(fe, status); + } else if (state->dst_type == DST_TYPE_IS_TERR) + dst_set_bandwidth(state, p->u.ofdm.bandwidth); + else if (state->dst_type == DST_TYPE_IS_CABLE) { + dst_set_fec(state, p->u.qam.fec_inner); + dst_set_symbolrate(state, p->u.qam.symbol_rate); + dst_set_modulation(state, p->u.qam.modulation); + } + dst_write_tuna(fe); - *delay = HZ/10; return 0; } @@ -1455,7 +1445,7 @@ static struct dvb_frontend_ops dst_dvbt_ops = { .release = dst_release, .init = dst_init, - .tune = dst_set_frontend, + .set_frontend = dst_set_frontend, .get_frontend = dst_get_frontend, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, @@ -1479,7 +1469,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = { .release = dst_release, .init = dst_init, - .tune = dst_set_frontend, + .set_frontend = dst_set_frontend, .get_frontend = dst_get_frontend, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, @@ -1506,7 +1496,7 @@ static struct dvb_frontend_ops dst_dvbc_ops = { .release = dst_release, .init = dst_init, - .tune = dst_set_frontend, + .set_frontend = dst_set_frontend, .get_frontend = dst_get_frontend, .read_status = dst_read_status, .read_signal_strength = dst_read_signal_strength, diff --git a/trunk/drivers/media/dvb/bt8xx/dst_ca.c b/trunk/drivers/media/dvb/bt8xx/dst_ca.c index c650b4bf7f5f..2239651969c8 100644 --- a/trunk/drivers/media/dvb/bt8xx/dst_ca.c +++ b/trunk/drivers/media/dvb/bt8xx/dst_ca.c @@ -283,17 +283,16 @@ static int handle_dst_tag(struct dst_state *state, struct ca_msg *p_ca_message, hw_buffer->msg[4] = 0x03; hw_buffer->msg[5] = length & 0xff; hw_buffer->msg[6] = 0x00; - /* * Need to compute length for EN50221 section 8.3.2, for the time being * assuming 8.3.2 is not applicable */ memcpy(&hw_buffer->msg[7], &p_ca_message->msg[4], length); } - return 0; } + static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 length, u8 reply) { if ((dst_put_ci(state, hw_buffer->msg, length, hw_buffer->msg, reply)) < 0) { diff --git a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 01b4e0aac049..77977e9c013e 100644 --- a/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/trunk/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -600,6 +600,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) struct dst_state* state = NULL; switch(type) { +#ifdef BTTV_BOARD_DVICO_DVBT_LITE case BTTV_BOARD_DVICO_DVBT_LITE: card->fe = mt352_attach(&thomson_dtt7579_config, card->i2c_adapter); if (card->fe != NULL) { @@ -607,15 +608,22 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) card->fe->ops->info.frequency_max = 862000000; } break; +#endif +#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: lgdt330x_reset(card); card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); if (card->fe != NULL) dprintk ("dvb_bt8xx: lgdt330x detected\n"); break; +#endif +#ifdef BTTV_BOARD_TWINHAN_VP3021 + case BTTV_BOARD_TWINHAN_VP3021: +#else case BTTV_BOARD_NEBULA_DIGITV: +#endif /* * It is possible to determine the correct frontend using the I2C bus (see the Nebula SDK); * this would be a cleaner solution than trying each frontend in turn. @@ -804,7 +812,9 @@ static int dvb_bt8xx_probe(struct device *dev) card->irq_err_ignore = 0; break; +#ifdef BTTV_BOARD_DVICO_DVBT_LITE case BTTV_BOARD_DVICO_DVBT_LITE: +#endif card->gpio_mode = 0x0400C060; card->op_sync_orin = 0; card->irq_err_ignore = 0; @@ -813,13 +823,19 @@ static int dvb_bt8xx_probe(struct device *dev) * DA_APP(parallel) */ break; +#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: +#endif card->gpio_mode = 0x0400c060; card->op_sync_orin = BT878_RISC_SYNC_MASK; card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; break; +#ifdef BTTV_BOARD_TWINHAN_VP3021 + case BTTV_BOARD_TWINHAN_VP3021: +#else case BTTV_BOARD_NEBULA_DIGITV: +#endif case BTTV_BOARD_AVDVBT_761: card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); card->op_sync_orin = 0; diff --git a/trunk/drivers/media/dvb/cinergyT2/Kconfig b/trunk/drivers/media/dvb/cinergyT2/Kconfig index 6018fcdba1e6..7cf4c4a888ec 100644 --- a/trunk/drivers/media/dvb/cinergyT2/Kconfig +++ b/trunk/drivers/media/dvb/cinergyT2/Kconfig @@ -21,35 +21,35 @@ config DVB_CINERGYT2_TUNING config DVB_CINERGYT2_STREAM_URB_COUNT int "Number of queued USB Request Blocks for Highspeed Stream Transfers" depends on DVB_CINERGYT2_TUNING - default "32" + default "32" help USB Request Blocks for Highspeed Stream transfers are scheduled in a queue for the Host Controller. Usually the default value is a safe choice. - You may increase this number if you are using this device in a - Server Environment with many high-traffic USB Highspeed devices + You may increase this number if you are using this device in a + Server Environment with many high-traffic USB Highspeed devices sharing the same USB bus. config DVB_CINERGYT2_STREAM_BUF_SIZE int "Size of URB Stream Buffers for Highspeed Transfers" depends on DVB_CINERGYT2_TUNING - default "512" + default "512" help Should be a multiple of native buffer size of 512 bytes. Default value is a safe choice. - You may increase this number if you are using this device in a - Server Environment with many high-traffic USB Highspeed devices + You may increase this number if you are using this device in a + Server Environment with many high-traffic USB Highspeed devices sharing the same USB bus. config DVB_CINERGYT2_QUERY_INTERVAL int "Status update interval [milliseconds]" depends on DVB_CINERGYT2_TUNING - default "250" + default "250" help This is the interval for status readouts from the demodulator. You may try lower values if you need more responsive signal quality @@ -64,9 +64,9 @@ config DVB_CINERGYT2_QUERY_INTERVAL config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE bool "Register the onboard IR Remote Control Receiver as Input Device" depends on DVB_CINERGYT2_TUNING - default "yes" + default "yes" help - Enable this option if you want to use the onboard Infrared Remote + Enable this option if you want to use the onboard Infrared Remote Control Receiver as Linux-Input device. Right now only the keycode table for the default Remote Control @@ -77,7 +77,7 @@ config DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE config DVB_CINERGYT2_RC_QUERY_INTERVAL int "Infrared Remote Controller update interval [milliseconds]" depends on DVB_CINERGYT2_TUNING && DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE - default "50" + default "50" help If you have a very fast-repeating remote control you can try lower values, for normal consumer receivers the default value should be diff --git a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c index c4b4c5b6b7c8..1d69bf031fb9 100644 --- a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -131,8 +131,6 @@ struct cinergyt2 { wait_queue_head_t poll_wq; int pending_fe_events; - int disconnect_pending; - atomic_t inuse; void *streambuf; dma_addr_t streambuf_dmahandle; @@ -345,7 +343,7 @@ static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed) struct dvb_demux *demux = dvbdmxfeed->demux; struct cinergyt2 *cinergyt2 = demux->priv; - if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) + if (down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; if (cinergyt2->streaming == 0) @@ -361,7 +359,7 @@ static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed) struct dvb_demux *demux = dvbdmxfeed->demux; struct cinergyt2 *cinergyt2 = demux->priv; - if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) + if (down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; if (--cinergyt2->streaming == 0) @@ -481,37 +479,23 @@ static int cinergyt2_open (struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; struct cinergyt2 *cinergyt2 = dvbdev->priv; - int err = -ERESTARTSYS; - - if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) - return -ERESTARTSYS; + int err; - if ((err = dvb_generic_open(inode, file))) { - up(&cinergyt2->sem); + if ((err = dvb_generic_open(inode, file))) return err; - } + if (down_interruptible(&cinergyt2->sem)) + return -ERESTARTSYS; if ((file->f_flags & O_ACCMODE) != O_RDONLY) { cinergyt2_sleep(cinergyt2, 0); schedule_delayed_work(&cinergyt2->query_work, HZ/2); } - atomic_inc(&cinergyt2->inuse); - up(&cinergyt2->sem); return 0; } -static void cinergyt2_unregister(struct cinergyt2 *cinergyt2) -{ - dvb_unregister_device(cinergyt2->fedev); - dvb_unregister_adapter(&cinergyt2->adapter); - - cinergyt2_free_stream_urbs(cinergyt2); - kfree(cinergyt2); -} - static int cinergyt2_release (struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; @@ -520,7 +504,7 @@ static int cinergyt2_release (struct inode *inode, struct file *file) if (down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; - if (!cinergyt2->disconnect_pending && (file->f_flags & O_ACCMODE) != O_RDONLY) { + if ((file->f_flags & O_ACCMODE) != O_RDONLY) { cancel_delayed_work(&cinergyt2->query_work); flush_scheduled_work(); cinergyt2_sleep(cinergyt2, 1); @@ -528,11 +512,6 @@ static int cinergyt2_release (struct inode *inode, struct file *file) up(&cinergyt2->sem); - if (atomic_dec_and_test(&cinergyt2->inuse) && cinergyt2->disconnect_pending) { - warn("delayed unregister in release"); - cinergyt2_unregister(cinergyt2); - } - return dvb_generic_release(inode, file); } @@ -540,14 +519,7 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct { struct dvb_device *dvbdev = file->private_data; struct cinergyt2 *cinergyt2 = dvbdev->priv; - - if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) - return -ERESTARTSYS; - poll_wait(file, &cinergyt2->poll_wq, wait); - - up(&cinergyt2->sem); - return (POLLIN | POLLRDNORM | POLLPRI); } @@ -592,15 +564,10 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, (__u16 __user *) arg); case FE_READ_UNCORRECTED_BLOCKS: - { - uint32_t unc_count; - - unc_count = stat->uncorrected_block_count; - stat->uncorrected_block_count = 0; - /* UNC are already converted to host byte order... */ - return put_user(unc_count,(__u32 __user *) arg); - } + return put_user(stat->uncorrected_block_count, + (__u32 __user *) arg); + case FE_SET_FRONTEND: { struct dvbt_set_parameters_msg *param = &cinergyt2->param; @@ -613,7 +580,7 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, if (copy_from_user(&p, (void __user*) arg, sizeof(p))) return -EFAULT; - if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) + if (down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS; @@ -724,7 +691,7 @@ static void cinergyt2_query_rc (void *data) struct cinergyt2_rc_event rc_events[12]; int n, len, i; - if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) + if (down_interruptible(&cinergyt2->sem)) return; len = cinergyt2_command(cinergyt2, buf, sizeof(buf), @@ -819,6 +786,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) { cancel_delayed_work(&cinergyt2->rc_query_work); + flush_scheduled_work(); input_unregister_device(cinergyt2->rc_input_dev); } @@ -849,7 +817,7 @@ static void cinergyt2_query (void *data) uint8_t lock_bits; uint32_t unc; - if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) + if (down_interruptible(&cinergyt2->sem)) return; unc = s->uncorrected_block_count; @@ -949,25 +917,28 @@ static void cinergyt2_disconnect (struct usb_interface *intf) { struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); - flush_scheduled_work(); + if (down_interruptible(&cinergyt2->sem)) + return; cinergyt2_unregister_rc(cinergyt2); - cancel_delayed_work(&cinergyt2->query_work); - wake_up_interruptible(&cinergyt2->poll_wq); - cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx); - cinergyt2->disconnect_pending = 1; + dvb_net_release(&cinergyt2->dvbnet); + dvb_dmxdev_release(&cinergyt2->dmxdev); + dvb_dmx_release(&cinergyt2->demux); + dvb_unregister_device(cinergyt2->fedev); + dvb_unregister_adapter(&cinergyt2->adapter); - if (!atomic_read(&cinergyt2->inuse)) - cinergyt2_unregister(cinergyt2); + cinergyt2_free_stream_urbs(cinergyt2); + up(&cinergyt2->sem); + kfree(cinergyt2); } static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state) { struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); - if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) + if (down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; if (state.event > PM_EVENT_ON) { @@ -990,7 +961,7 @@ static int cinergyt2_resume (struct usb_interface *intf) struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf); struct dvbt_set_parameters_msg *param = &cinergyt2->param; - if (cinergyt2->disconnect_pending || down_interruptible(&cinergyt2->sem)) + if (down_interruptible(&cinergyt2->sem)) return -ERESTARTSYS; if (!cinergyt2->sleeping) { @@ -1043,3 +1014,4 @@ module_exit (cinergyt2_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Holger Waechtler, Daniel Mack"); + diff --git a/trunk/drivers/media/dvb/dvb-core/Kconfig b/trunk/drivers/media/dvb/dvb-core/Kconfig index 12ee912a5705..a9a7b3421048 100644 --- a/trunk/drivers/media/dvb/dvb-core/Kconfig +++ b/trunk/drivers/media/dvb/dvb-core/Kconfig @@ -5,7 +5,7 @@ config DVB_CORE help DVB core utility functions for device handling, software fallbacks etc. Say Y when you have a DVB card and want to use it. Say Y if your want - to build your drivers outside the kernel, but need the DVB core. All + to build your drivers outside the kernel, but need the DVB core. All in-kernel drivers will select this automatically if needed. If unsure say N. diff --git a/trunk/drivers/media/dvb/dvb-core/Makefile b/trunk/drivers/media/dvb/dvb-core/Makefile index 7adb50c1e8eb..c6baac20f529 100644 --- a/trunk/drivers/media/dvb/dvb-core/Makefile +++ b/trunk/drivers/media/dvb/dvb-core/Makefile @@ -3,7 +3,7 @@ # dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ - dvb_ca_en50221.o dvb_frontend.o \ + dvb_ca_en50221.o dvb_frontend.o \ dvb_net.o dvb_ringbuffer.o obj-$(CONFIG_DVB_CORE) += dvb-core.o diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index 4bb779aeff6a..5956c35d34ac 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_ca_en50221.c @@ -1745,7 +1745,9 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) for (i = 0; i < ca->slot_count; i++) { dvb_ca_en50221_slot_shutdown(ca, i); - vfree(ca->slot_info[i].rx_buffer.data); + if (ca->slot_info[i].rx_buffer.data != NULL) { + vfree(ca->slot_info[i].rx_buffer.data); + } } kfree(ca->slot_info); dvb_unregister_device(ca->dvbdev); diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_filter.c b/trunk/drivers/media/dvb/dvb-core/dvb_filter.c index 772003fb1821..c49fd0bd7181 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_filter.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_filter.c @@ -409,16 +409,16 @@ static u8 *skip_pes_header(u8 **bufp) if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */ if (buf[7] & PTS_ONLY) - pts = buf+9; + pts = buf+9; else pts = NULL; buf = inbuf + 9 + inbuf[8]; } else { /* mpeg1 */ for (buf = inbuf + 6; *buf == 0xff; buf++) - if (buf == inbuf + 6 + 16) { - break; - } + if (buf == inbuf + 6 + 16) { + break; + } if ((*buf & 0xc0) == 0x40) - buf += 2; + buf += 2; skip = mpeg1_skip_table [*buf >> 4]; if (skip == 5 || skip == 10) pts = buf; else pts = NULL; @@ -529,9 +529,9 @@ static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_t pic->picture_header = 0; pic->sequence_header_data = ( INIT_HORIZONTAL_SIZE << 20 ) - | ( INIT_VERTICAL_SIZE << 8 ) - | ( INIT_ASPECT_RATIO << 4 ) - | ( INIT_FRAME_RATE ); + | ( INIT_VERTICAL_SIZE << 8 ) + | ( INIT_ASPECT_RATIO << 4 ) + | ( INIT_FRAME_RATE ); pic->mpeg1_flag = 0; pic->vinfo.horizontal_size = INIT_DISP_HORIZONTAL_SIZE; diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index 4a08c4ab6730..95ea5095e07e 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -92,7 +92,6 @@ static DECLARE_MUTEX(frontend_mutex); struct dvb_frontend_private { - /* thread/frontend values */ struct dvb_device *dvbdev; struct dvb_frontend_parameters parameters; struct dvb_fe_events events; @@ -101,25 +100,20 @@ struct dvb_frontend_private { wait_queue_head_t wait_queue; pid_t thread_pid; unsigned long release_jiffies; - unsigned int exit; - unsigned int wakeup; - fe_status_t status; - unsigned long tune_mode_flags; - unsigned int delay; - - /* swzigzag values */ - unsigned int state; - unsigned int bending; + int state; + int bending; int lnb_drift; - unsigned int inversion; - unsigned int auto_step; - unsigned int auto_sub_step; - unsigned int started_auto_step; - unsigned int min_delay; - unsigned int max_drift; - unsigned int step_size; - int quality; - unsigned int check_wrapped; + int inversion; + int auto_step; + int auto_sub_step; + int started_auto_step; + int min_delay; + int max_drift; + int step_size; + int exit; + int wakeup; + fe_status_t status; + fe_sec_tone_mode_t tone; }; @@ -214,21 +208,21 @@ static void dvb_frontend_init(struct dvb_frontend *fe) fe->ops->init(fe); } -static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepriv, int locked) +static void update_delay(int *quality, int *delay, int min_delay, int locked) { - int q2; + int q2; - dprintk ("%s\n", __FUNCTION__); + dprintk ("%s\n", __FUNCTION__); - if (locked) - (fepriv->quality) = (fepriv->quality * 220 + 36*256) / 256; - else - (fepriv->quality) = (fepriv->quality * 220 + 0) / 256; + if (locked) + (*quality) = (*quality * 220 + 36*256) / 256; + else + (*quality) = (*quality * 220 + 0) / 256; - q2 = fepriv->quality - 128; - q2 *= q2; + q2 = *quality - 128; + q2 *= q2; - fepriv->delay = fepriv->min_delay + q2 * HZ / (128*128); + *delay = min_delay + q2 * HZ / (128*128); } /** @@ -238,7 +232,7 @@ static void dvb_frontend_swzigzag_update_delay(struct dvb_frontend_private *fepr * @param check_wrapped Checks if an iteration has completed. DO NOT SET ON THE FIRST ATTEMPT * @returns Number of complete iterations that have been performed. */ -static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wrapped) +static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped) { int autoinversion; int ready = 0; @@ -327,129 +321,6 @@ static int dvb_frontend_swzigzag_autotune(struct dvb_frontend *fe, int check_wra return 0; } -static void dvb_frontend_swzigzag(struct dvb_frontend *fe) -{ - fe_status_t s; - struct dvb_frontend_private *fepriv = fe->frontend_priv; - - /* if we've got no parameters, just keep idling */ - if (fepriv->state & FESTATE_IDLE) { - fepriv->delay = 3*HZ; - fepriv->quality = 0; - return; - } - - /* in SCAN mode, we just set the frontend when asked and leave it alone */ - if (fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT) { - if (fepriv->state & FESTATE_RETUNE) { - if (fe->ops->set_frontend) - fe->ops->set_frontend(fe, &fepriv->parameters); - fepriv->state = FESTATE_TUNED; - } - fepriv->delay = 3*HZ; - fepriv->quality = 0; - return; - } - - /* get the frontend status */ - if (fepriv->state & FESTATE_RETUNE) { - s = 0; - } else { - if (fe->ops->read_status) - fe->ops->read_status(fe, &s); - if (s != fepriv->status) { - dvb_frontend_add_event(fe, s); - fepriv->status = s; - } - } - - /* if we're not tuned, and we have a lock, move to the TUNED state */ - if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) { - dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); - fepriv->state = FESTATE_TUNED; - - /* if we're tuned, then we have determined the correct inversion */ - if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && - (fepriv->parameters.inversion == INVERSION_AUTO)) { - fepriv->parameters.inversion = fepriv->inversion; - } - return; - } - - /* if we are tuned already, check we're still locked */ - if (fepriv->state & FESTATE_TUNED) { - dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); - - /* we're tuned, and the lock is still good... */ - if (s & FE_HAS_LOCK) { - return; - } else { /* if we _WERE_ tuned, but now don't have a lock */ - fepriv->state = FESTATE_ZIGZAG_FAST; - fepriv->started_auto_step = fepriv->auto_step; - fepriv->check_wrapped = 0; - } - } - - /* don't actually do anything if we're in the LOSTLOCK state, - * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ - if ((fepriv->state & FESTATE_LOSTLOCK) && - (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { - dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); - return; - } - - /* don't do anything if we're in the DISEQC state, since this - * might be someone with a motorized dish controlled by DISEQC. - * If its actually a re-tune, there will be a SET_FRONTEND soon enough. */ - if (fepriv->state & FESTATE_DISEQC) { - dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); - return; - } - - /* if we're in the RETUNE state, set everything up for a brand - * new scan, keeping the current inversion setting, as the next - * tune is _very_ likely to require the same */ - if (fepriv->state & FESTATE_RETUNE) { - fepriv->lnb_drift = 0; - fepriv->auto_step = 0; - fepriv->auto_sub_step = 0; - fepriv->started_auto_step = 0; - fepriv->check_wrapped = 0; - } - - /* fast zigzag. */ - if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) { - fepriv->delay = fepriv->min_delay; - - /* peform a tune */ - if (dvb_frontend_swzigzag_autotune(fe, fepriv->check_wrapped)) { - /* OK, if we've run out of trials at the fast speed. - * Drop back to slow for the _next_ attempt */ - fepriv->state = FESTATE_SEARCHING_SLOW; - fepriv->started_auto_step = fepriv->auto_step; - return; - } - fepriv->check_wrapped = 1; - - /* if we've just retuned, enter the ZIGZAG_FAST state. - * This ensures we cannot return from an - * FE_SET_FRONTEND ioctl before the first frontend tune - * occurs */ - if (fepriv->state & FESTATE_RETUNE) { - fepriv->state = FESTATE_TUNING_FAST; - } - } - - /* slow zigzag */ - if (fepriv->state & FESTATE_SEARCHING_SLOW) { - dvb_frontend_swzigzag_update_delay(fepriv, s & FE_HAS_LOCK); - - /* Note: don't bother checking for wrapping; we stay in this - * state until we get a lock */ - dvb_frontend_swzigzag_autotune(fe, 0); - } -} - static int dvb_frontend_is_exiting(struct dvb_frontend *fe) { struct dvb_frontend_private *fepriv = fe->frontend_priv; @@ -459,7 +330,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe) if (fepriv->dvbdev->writers == 1) if (time_after(jiffies, fepriv->release_jiffies + - dvb_shutdown_timeout * HZ)) + dvb_shutdown_timeout * HZ)) return 1; return 0; @@ -484,14 +355,18 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe) wake_up_interruptible(&fepriv->wait_queue); } +/* + * FIXME: use linux/kthread.h + */ static int dvb_frontend_thread(void *data) { struct dvb_frontend *fe = data; struct dvb_frontend_private *fepriv = fe->frontend_priv; unsigned long timeout; char name [15]; + int quality = 0, delay = 3*HZ; fe_status_t s; - struct dvb_frontend_parameters *params; + int check_wrapped = 0; dprintk("%s\n", __FUNCTION__); @@ -502,9 +377,6 @@ static int dvb_frontend_thread(void *data) sigfillset(¤t->blocked); unlock_kernel(); - fepriv->check_wrapped = 0; - fepriv->quality = 0; - fepriv->delay = 3*HZ; fepriv->status = 0; dvb_frontend_init(fe); fepriv->wakeup = 0; @@ -514,7 +386,7 @@ static int dvb_frontend_thread(void *data) timeout = wait_event_interruptible_timeout(fepriv->wait_queue, dvb_frontend_should_wakeup(fe), - fepriv->delay); + delay); if (0 != dvb_frontend_is_exiting(fe)) { /* got signal or quitting */ break; @@ -525,22 +397,108 @@ static int dvb_frontend_thread(void *data) if (down_interruptible(&fepriv->sem)) break; - /* do an iteration of the tuning loop */ - if (fe->ops->tune) { - /* have we been asked to retune? */ - params = NULL; - if (fepriv->state & FESTATE_RETUNE) { - params = &fepriv->parameters; - fepriv->state = FESTATE_TUNED; - } + /* if we've got no parameters, just keep idling */ + if (fepriv->state & FESTATE_IDLE) { + delay = 3*HZ; + quality = 0; + continue; + } - fe->ops->tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s); + /* get the frontend status */ + if (fepriv->state & FESTATE_RETUNE) { + s = 0; + } else { + if (fe->ops->read_status) + fe->ops->read_status(fe, &s); if (s != fepriv->status) { dvb_frontend_add_event(fe, s); fepriv->status = s; } - } else { - dvb_frontend_swzigzag(fe); + } + /* if we're not tuned, and we have a lock, move to the TUNED state */ + if ((fepriv->state & FESTATE_WAITFORLOCK) && (s & FE_HAS_LOCK)) { + update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); + fepriv->state = FESTATE_TUNED; + + /* if we're tuned, then we have determined the correct inversion */ + if ((!(fe->ops->info.caps & FE_CAN_INVERSION_AUTO)) && + (fepriv->parameters.inversion == INVERSION_AUTO)) { + fepriv->parameters.inversion = fepriv->inversion; + } + continue; + } + + /* if we are tuned already, check we're still locked */ + if (fepriv->state & FESTATE_TUNED) { + update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); + + /* we're tuned, and the lock is still good... */ + if (s & FE_HAS_LOCK) + continue; + else { /* if we _WERE_ tuned, but now don't have a lock */ + fepriv->state = FESTATE_ZIGZAG_FAST; + fepriv->started_auto_step = fepriv->auto_step; + check_wrapped = 0; + } + } + + /* don't actually do anything if we're in the LOSTLOCK state, + * the frontend is set to FE_CAN_RECOVER, and the max_drift is 0 */ + if ((fepriv->state & FESTATE_LOSTLOCK) && + (fe->ops->info.caps & FE_CAN_RECOVER) && (fepriv->max_drift == 0)) { + update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); + continue; + } + + /* don't do anything if we're in the DISEQC state, since this + * might be someone with a motorized dish controlled by DISEQC. + * If its actually a re-tune, there will be a SET_FRONTEND soon enough. */ + if (fepriv->state & FESTATE_DISEQC) { + update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); + continue; + } + + /* if we're in the RETUNE state, set everything up for a brand + * new scan, keeping the current inversion setting, as the next + * tune is _very_ likely to require the same */ + if (fepriv->state & FESTATE_RETUNE) { + fepriv->lnb_drift = 0; + fepriv->auto_step = 0; + fepriv->auto_sub_step = 0; + fepriv->started_auto_step = 0; + check_wrapped = 0; + } + + /* fast zigzag. */ + if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) { + delay = fepriv->min_delay; + + /* peform a tune */ + if (dvb_frontend_autotune(fe, check_wrapped)) { + /* OK, if we've run out of trials at the fast speed. + * Drop back to slow for the _next_ attempt */ + fepriv->state = FESTATE_SEARCHING_SLOW; + fepriv->started_auto_step = fepriv->auto_step; + continue; + } + check_wrapped = 1; + + /* if we've just retuned, enter the ZIGZAG_FAST state. + * This ensures we cannot return from an + * FE_SET_FRONTEND ioctl before the first frontend tune + * occurs */ + if (fepriv->state & FESTATE_RETUNE) { + fepriv->state = FESTATE_TUNING_FAST; + } + } + + /* slow zigzag */ + if (fepriv->state & FESTATE_SEARCHING_SLOW) { + update_delay(&quality, &delay, fepriv->min_delay, s & FE_HAS_LOCK); + + /* Note: don't bother checking for wrapping; we stay in this + * state until we get a lock */ + dvb_frontend_autotune(fe, 0); } } @@ -775,6 +733,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, err = fe->ops->set_tone(fe, (fe_sec_tone_mode_t) parg); fepriv->state = FESTATE_DISEQC; fepriv->status = 0; + fepriv->tone = (fe_sec_tone_mode_t) parg; } break; @@ -788,7 +747,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, case FE_DISHNETWORK_SEND_LEGACY_CMD: if (fe->ops->dishnetwork_send_legacy_command) { - err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned long) parg); + err = fe->ops->dishnetwork_send_legacy_command(fe, (unsigned int) parg); fepriv->state = FESTATE_DISEQC; fepriv->status = 0; } else if (fe->ops->set_voltage) { @@ -808,13 +767,13 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, * initialization, so parg is 8 bits and does not * include the initialization or start bit */ - unsigned long cmd = ((unsigned long) parg) << 1; + unsigned int cmd = ((unsigned int) parg) << 1; struct timeval nexttime; struct timeval tv[10]; int i; u8 last = 1; if (dvb_frontend_debug) - printk("%s switch command: 0x%04lx\n", __FUNCTION__, cmd); + printk("%s switch command: 0x%04x\n", __FUNCTION__, cmd); do_gettimeofday(&nexttime); if (dvb_frontend_debug) memcpy(&tv[0], &nexttime, sizeof(struct timeval)); @@ -855,7 +814,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, case FE_ENABLE_HIGH_LNB_VOLTAGE: if (fe->ops->enable_high_lnb_voltage) - err = fe->ops->enable_high_lnb_voltage(fe, (long) parg); + err = fe->ops->enable_high_lnb_voltage(fe, (int) parg); break; case FE_SET_FRONTEND: { @@ -932,10 +891,6 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, err = fe->ops->get_frontend(fe, (struct dvb_frontend_parameters*) parg); } break; - - case FE_SET_FRONTEND_TUNE_MODE: - fepriv->tune_mode_flags = (unsigned long) parg; - break; }; up (&fepriv->sem); @@ -977,9 +932,6 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) /* empty event queue */ fepriv->events.eventr = fepriv->events.eventw = 0; - - /* normal tune mode when opened R/W */ - fepriv->tune_mode_flags &= ~FE_TUNE_MODE_ONESHOT; } return ret; @@ -1038,6 +990,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, init_MUTEX (&fepriv->events.sem); fe->dvb = dvb; fepriv->inversion = INVERSION_OFF; + fepriv->tone = SEC_TONE_OFF; printk ("DVB: registering frontend %i (%s)...\n", fe->dvb->num, diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h index 70a6d14efda7..1e0840d02f1f 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -58,18 +58,9 @@ struct dvb_frontend_ops { int (*init)(struct dvb_frontend* fe); int (*sleep)(struct dvb_frontend* fe); - /* if this is set, it overrides the default swzigzag */ - int (*tune)(struct dvb_frontend* fe, - struct dvb_frontend_parameters* params, - unsigned int mode_flags, - int *delay, - fe_status_t *status); - - /* these two are only used for the swzigzag code */ int (*set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); - int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings); - int (*get_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); + int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings); int (*read_status)(struct dvb_frontend* fe, fe_status_t* status); int (*read_ber)(struct dvb_frontend* fe, u32* ber); @@ -83,9 +74,8 @@ struct dvb_frontend_ops { int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); - int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg); - int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); - int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); + int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, int arg); + int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd); }; #define MAX_EVENT 8 diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_net.c b/trunk/drivers/media/dvb/dvb-core/dvb_net.c index 6711eb6a058c..86bba81e851e 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_net.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_net.c @@ -1222,7 +1222,7 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype) return if_num; } -static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned long num) +static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned int num) { struct net_device *net = dvbnet->device[num]; struct dvb_net_priv *priv; @@ -1296,9 +1296,9 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file, if (!capable(CAP_SYS_ADMIN)) return -EPERM; - if ((unsigned long) parg >= DVB_NET_DEVICES_MAX) + if ((unsigned int) parg >= DVB_NET_DEVICES_MAX) return -EINVAL; - ret = dvb_net_remove_if(dvbnet, (unsigned long) parg); + ret = dvb_net_remove_if(dvbnet, (unsigned int) parg); if (!ret) module_put(dvbdev->adapter->module); return ret; diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_ringbuffer.c b/trunk/drivers/media/dvb/dvb-core/dvb_ringbuffer.c index 77ad2410f4d3..283c6e9339a4 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_ringbuffer.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_ringbuffer.c @@ -112,10 +112,10 @@ ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, in split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; if (split > 0) { if (!usermem) - memcpy(buf, rbuf->data+rbuf->pread, split); + memcpy(buf, rbuf->data+rbuf->pread, split); else - if (copy_to_user(buf, rbuf->data+rbuf->pread, split)) - return -EFAULT; + if (copy_to_user(buf, rbuf->data+rbuf->pread, split)) + return -EFAULT; buf += split; todo -= split; rbuf->pread = 0; @@ -124,7 +124,7 @@ ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len, in memcpy(buf, rbuf->data+rbuf->pread, todo); else if (copy_to_user(buf, rbuf->data+rbuf->pread, todo)) - return -EFAULT; + return -EFAULT; rbuf->pread = (rbuf->pread + todo) % rbuf->size; @@ -167,7 +167,7 @@ ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t le } ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, - int offset, u8* buf, size_t len, int usermem) + int offset, u8* buf, size_t len, int usermem) { size_t todo; size_t split; @@ -183,10 +183,10 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; if (split > 0) { if (!usermem) - memcpy(buf, rbuf->data+idx, split); + memcpy(buf, rbuf->data+idx, split); else - if (copy_to_user(buf, rbuf->data+idx, split)) - return -EFAULT; + if (copy_to_user(buf, rbuf->data+idx, split)) + return -EFAULT; buf += split; todo -= split; idx = 0; @@ -195,7 +195,7 @@ ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, memcpy(buf, rbuf->data+idx, todo); else if (copy_to_user(buf, rbuf->data+idx, todo)) - return -EFAULT; + return -EFAULT; return len; } @@ -209,12 +209,12 @@ void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx) // clean up disposed packets while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) { if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) { - pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8; - pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1); - DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE); + pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8; + pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1); + DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE); } else { - // first packet is not disposed, so we stop cleaning now - break; + // first packet is not disposed, so we stop cleaning now + break; } } } @@ -242,8 +242,8 @@ ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* curpktstatus = rbuf->data[(idx + 2) % rbuf->size]; if (curpktstatus == PKT_READY) { - *pktlen = curpktlen; - return idx; + *pktlen = curpktlen; + return idx; } consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE; diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_ringbuffer.h b/trunk/drivers/media/dvb/dvb-core/dvb_ringbuffer.h index 6d2560972771..fa476f662f82 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_ringbuffer.h +++ b/trunk/drivers/media/dvb/dvb-core/dvb_ringbuffer.h @@ -106,7 +106,7 @@ extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf); ** returns number of bytes transferred or -EFAULT */ extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, - size_t len, int usermem); + size_t len, int usermem); /* write routines & macros */ @@ -121,7 +121,7 @@ extern ssize_t dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, ** returns number of bytes transferred or -EFAULT */ extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, - size_t len); + size_t len); /** @@ -133,7 +133,7 @@ extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL. */ extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, - size_t len); + size_t len); /** * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this @@ -149,7 +149,7 @@ extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, * returns Number of bytes read, or -EFAULT. */ extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, - int offset, u8* buf, size_t len, int usermem); + int offset, u8* buf, size_t len, int usermem); /** * Dispose of a packet in the ring buffer. diff --git a/trunk/drivers/media/dvb/dvb-core/dvbdev.c b/trunk/drivers/media/dvb/dvb-core/dvbdev.c index 06b696e9acbd..a4aee8665854 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvbdev.c +++ b/trunk/drivers/media/dvb/dvb-core/dvbdev.c @@ -92,10 +92,10 @@ static int dvb_device_open(struct inode *inode, struct file *file) old_fops = file->f_op; file->f_op = fops_get(dvbdev->fops); if(file->f_op->open) - err = file->f_op->open(inode,file); + err = file->f_op->open(inode,file); if (err) { - fops_put(file->f_op); - file->f_op = fops_get(old_fops); + fops_put(file->f_op); + file->f_op = fops_get(old_fops); } fops_put(old_fops); return err; @@ -356,18 +356,18 @@ int dvb_usercopy(struct inode *inode, struct file *file, case _IOC_WRITE: case (_IOC_WRITE | _IOC_READ): if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { - parg = sbuf; + parg = sbuf; } else { - /* too big to allocate from stack */ - mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); - if (NULL == mbuf) - return -ENOMEM; - parg = mbuf; + /* too big to allocate from stack */ + mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); + if (NULL == mbuf) + return -ENOMEM; + parg = mbuf; } err = -EFAULT; if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) - goto out; + goto out; break; } @@ -384,7 +384,7 @@ int dvb_usercopy(struct inode *inode, struct file *file, case _IOC_READ: case (_IOC_WRITE | _IOC_READ): if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) - err = -EFAULT; + err = -EFAULT; break; } diff --git a/trunk/drivers/media/dvb/dvb-core/dvbdev.h b/trunk/drivers/media/dvb/dvb-core/dvbdev.h index 74ed5853f0fb..0cc6e4a0e27c 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvbdev.h +++ b/trunk/drivers/media/dvb/dvb-core/dvbdev.h @@ -97,7 +97,7 @@ we simply define out own dvb_usercopy(), which will hopefully become generic_usercopy() someday... */ extern int dvb_usercopy(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, + unsigned int cmd, unsigned long arg, int (*func)(struct inode *inode, struct file *file, unsigned int cmd, void *arg)); diff --git a/trunk/drivers/media/dvb/dvb-usb/Kconfig b/trunk/drivers/media/dvb/dvb-usb/Kconfig index 90a69d343b79..54e2b29076b1 100644 --- a/trunk/drivers/media/dvb/dvb-usb/Kconfig +++ b/trunk/drivers/media/dvb/dvb-usb/Kconfig @@ -37,16 +37,16 @@ config DVB_USB_DIBUSB_MB DiBcom () equipped with a DiB3000M-B demodulator. Devices supported by this driver: - Artec T1 USB1.1 boxes - Avermedia AverTV DVBT USB1.1 - Compro Videomate DVB-U2000 - DVB-T USB - DiBcom USB1.1 reference devices (non-public) - Grandtec DVB-T USB - Hama DVB-T USB1.1-Box - KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0 - TwinhanDTV Magic Box (VP7041e) TwinhanDTV USB-Ter (VP7041) + TwinhanDTV Magic Box (VP7041e) + KWorld/JetWay/ADSTech V-Stream XPERT DTV - DVB-T USB1.1 and USB2.0 + Hama DVB-T USB1.1-Box + DiBcom USB1.1 reference devices (non-public) Ultima Electronic/Artec T1 USB TVBOX + Compro Videomate DVB-U2000 - DVB-T USB + Grandtec DVB-T USB + Avermedia AverTV DVBT USB1.1 + Artec T1 USB1.1 boxes The VP7041 seems to be identical to "CTS Portable" (Chinese Television System). @@ -54,12 +54,6 @@ config DVB_USB_DIBUSB_MB Say Y if you own such a device and want to use it. You should build it as a module. -config DVB_USB_DIBUSB_MB_FAULTY - bool "Support faulty USB IDs" - depends on DVB_USB_DIBUSB_MB - help - Support for faulty USB IDs due to an invalid EEPROM on some Artec devices. - config DVB_USB_DIBUSB_MC tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)" depends on DVB_USB @@ -69,8 +63,8 @@ config DVB_USB_DIBUSB_MC DiBcom () equipped with a DiB3000M-C/P demodulator. Devices supported by this driver: - Artec T1 USB2.0 boxes DiBcom USB2.0 reference devices (non-public) + Artec T1 USB2.0 boxes Say Y if you own such a device and want to use it. You should build it as a module. diff --git a/trunk/drivers/media/dvb/dvb-usb/cxusb.c b/trunk/drivers/media/dvb/dvb-usb/cxusb.c index 358ed153865f..d05fab01cccd 100644 --- a/trunk/drivers/media/dvb/dvb-usb/cxusb.c +++ b/trunk/drivers/media/dvb/dvb-usb/cxusb.c @@ -11,11 +11,10 @@ * design, so it can be reused for the "analogue-only" device (if it will * appear at all). * - * TODO: Use the cx25840-driver for the analogue part + * TODO: check if the cx25840-driver (from ivtv) can be used for the analogue + * part * * Copyright (C) 2005 Patrick Boettcher (patrick.boettcher@desy.de) - * Copyright (C) 2005 Michael Krufky (mkrufky@m1k.net) - * Copyright (C) 2006 Chris Pascoe (c.pascoe@itee.uq.edu.au) * * 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 @@ -26,9 +25,6 @@ #include "cxusb.h" #include "cx22702.h" -#include "lgdt330x.h" -#include "mt352.h" -#include "mt352_priv.h" /* debug */ int dvb_usb_cxusb_debug; @@ -160,99 +156,6 @@ static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff) return 0; } -static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) -{ - struct dvb_usb_rc_key *keymap = d->props.rc_key_map; - u8 ircode[4]; - int i; - - cxusb_ctrl_msg(d, CMD_GET_IR_CODE, NULL, 0, ircode, 4); - - *event = 0; - *state = REMOTE_NO_KEY_PRESSED; - - for (i = 0; i < d->props.rc_key_map_size; i++) { - if (keymap[i].custom == ircode[2] && - keymap[i].data == ircode[3]) { - *event = keymap[i].event; - *state = REMOTE_KEY_PRESSED; - - return 0; - } - } - - return 0; -} - -struct dvb_usb_rc_key dvico_mce_rc_keys[] = { - { 0xfe, 0x02, KEY_TV }, - { 0xfe, 0x0e, KEY_MP3 }, - { 0xfe, 0x1a, KEY_DVD }, - { 0xfe, 0x1e, KEY_FAVORITES }, - { 0xfe, 0x16, KEY_SETUP }, - { 0xfe, 0x46, KEY_POWER2 }, - { 0xfe, 0x0a, KEY_EPG }, - { 0xfe, 0x49, KEY_BACK }, - { 0xfe, 0x4d, KEY_MENU }, - { 0xfe, 0x51, KEY_UP }, - { 0xfe, 0x5b, KEY_LEFT }, - { 0xfe, 0x5f, KEY_RIGHT }, - { 0xfe, 0x53, KEY_DOWN }, - { 0xfe, 0x5e, KEY_OK }, - { 0xfe, 0x59, KEY_INFO }, - { 0xfe, 0x55, KEY_TAB }, - { 0xfe, 0x0f, KEY_PREVIOUSSONG },/* Replay */ - { 0xfe, 0x12, KEY_NEXTSONG }, /* Skip */ - { 0xfe, 0x42, KEY_ENTER }, /* Windows/Start */ - { 0xfe, 0x15, KEY_VOLUMEUP }, - { 0xfe, 0x05, KEY_VOLUMEDOWN }, - { 0xfe, 0x11, KEY_CHANNELUP }, - { 0xfe, 0x09, KEY_CHANNELDOWN }, - { 0xfe, 0x52, KEY_CAMERA }, - { 0xfe, 0x5a, KEY_TUNER }, /* Live */ - { 0xfe, 0x19, KEY_OPEN }, - { 0xfe, 0x0b, KEY_1 }, - { 0xfe, 0x17, KEY_2 }, - { 0xfe, 0x1b, KEY_3 }, - { 0xfe, 0x07, KEY_4 }, - { 0xfe, 0x50, KEY_5 }, - { 0xfe, 0x54, KEY_6 }, - { 0xfe, 0x48, KEY_7 }, - { 0xfe, 0x4c, KEY_8 }, - { 0xfe, 0x58, KEY_9 }, - { 0xfe, 0x13, KEY_ANGLE }, /* Aspect */ - { 0xfe, 0x03, KEY_0 }, - { 0xfe, 0x1f, KEY_ZOOM }, - { 0xfe, 0x43, KEY_REWIND }, - { 0xfe, 0x47, KEY_PLAYPAUSE }, - { 0xfe, 0x4f, KEY_FASTFORWARD }, - { 0xfe, 0x57, KEY_MUTE }, - { 0xfe, 0x0d, KEY_STOP }, - { 0xfe, 0x01, KEY_RECORD }, - { 0xfe, 0x4e, KEY_POWER }, -}; - -static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) -{ - static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 }; - static u8 reset [] = { RESET, 0x80 }; - static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; - static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; - static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; - static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; - - mt352_write(fe, clock_config, sizeof(clock_config)); - udelay(200); - mt352_write(fe, reset, sizeof(reset)); - mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); - - mt352_write(fe, agc_cfg, sizeof(agc_cfg)); - mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); - mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); - - return 0; -} - struct cx22702_config cxusb_cx22702_config = { .demod_address = 0x63, @@ -262,47 +165,17 @@ struct cx22702_config cxusb_cx22702_config = { .pll_set = dvb_usb_pll_set_i2c, }; -struct lgdt330x_config cxusb_lgdt330x_config = { - .demod_address = 0x0e, - .demod_chip = LGDT3303, - .pll_set = dvb_usb_pll_set_i2c, -}; - -struct mt352_config cxusb_dee1601_config = { - .demod_address = 0x0f, - .demod_init = cxusb_dee1601_demod_init, - .pll_set = dvb_usb_pll_set, -}; - /* Callbacks for DVB USB */ -static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_device *d) +static int cxusb_tuner_attach(struct dvb_usb_device *d) { u8 bpll[4] = { 0x0b, 0xdc, 0x9c, 0xa0 }; d->pll_addr = 0x61; - memcpy(d->pll_init, bpll, 4); + memcpy(d->pll_init,bpll,4); d->pll_desc = &dvb_pll_fmd1216me; return 0; } -static int cxusb_lgh064f_tuner_attach(struct dvb_usb_device *d) -{ - u8 bpll[4] = { 0x00, 0x00, 0x18, 0x50 }; - /* bpll[2] : unset bit 3, set bits 4&5 - bpll[3] : 0x50 - digital, 0x20 - analog */ - d->pll_addr = 0x61; - memcpy(d->pll_init, bpll, 4); - d->pll_desc = &dvb_pll_tdvs_tua6034; - return 0; -} - -static int cxusb_dee1601_tuner_attach(struct dvb_usb_device *d) -{ - d->pll_addr = 0x61; - d->pll_desc = &dvb_pll_thomson_dtt7579; - return 0; -} - -static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d) +static int cxusb_frontend_attach(struct dvb_usb_device *d) { u8 b; if (usb_set_interface(d->udev,0,6) < 0) @@ -316,84 +189,22 @@ static int cxusb_cx22702_frontend_attach(struct dvb_usb_device *d) return -EIO; } -static int cxusb_lgdt330x_frontend_attach(struct dvb_usb_device *d) -{ - if (usb_set_interface(d->udev,0,7) < 0) - err("set interface failed"); - - cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); - - if ((d->fe = lgdt330x_attach(&cxusb_lgdt330x_config, &d->i2c_adap)) != NULL) - return 0; - - return -EIO; -} - -static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d) -{ - if (usb_set_interface(d->udev,0,0) < 0) - err("set interface failed"); - - cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0); - - if ((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) - return 0; - - return -EIO; -} - -/* - * DViCO bluebird firmware needs the "warm" product ID to be patched into the - * firmware file before download. - */ - -#define BLUEBIRD_01_ID_OFFSET 6638 -static int bluebird_patch_dvico_firmware_download(struct usb_device *udev, const struct firmware *fw) -{ - if (fw->size < BLUEBIRD_01_ID_OFFSET + 4) - return -EINVAL; - - if (fw->data[BLUEBIRD_01_ID_OFFSET] == (USB_VID_DVICO & 0xff) && - fw->data[BLUEBIRD_01_ID_OFFSET + 1] == USB_VID_DVICO >> 8) { - - /* FIXME: are we allowed to change the fw-data ? */ - fw->data[BLUEBIRD_01_ID_OFFSET + 2] = udev->descriptor.idProduct + 1; - fw->data[BLUEBIRD_01_ID_OFFSET + 3] = udev->descriptor.idProduct >> 8; - - return usb_cypress_load_firmware(udev,fw,CYPRESS_FX2); - } - - return -EINVAL; -} - /* DVB USB Driver stuff */ -static struct dvb_usb_properties cxusb_medion_properties; -static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties; -static struct dvb_usb_properties cxusb_bluebird_dee1601_properties; +static struct dvb_usb_properties cxusb_properties; static int cxusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - if (dvb_usb_device_init(intf,&cxusb_medion_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&cxusb_bluebird_lgh064f_properties,THIS_MODULE,NULL) == 0 || - dvb_usb_device_init(intf,&cxusb_bluebird_dee1601_properties,THIS_MODULE,NULL) == 0) { - return 0; - } - - return -EINVAL; + return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE,NULL); } static struct usb_device_id cxusb_table [] = { { USB_DEVICE(USB_VID_MEDION, USB_PID_MEDION_MD95700) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_COLD) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_LG064F_WARM) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_COLD) }, - { USB_DEVICE(USB_VID_DVICO, USB_PID_DVICO_BLUEBIRD_DEE1601_WARM) }, {} /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, cxusb_table); -static struct dvb_usb_properties cxusb_medion_properties = { +static struct dvb_usb_properties cxusb_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = CYPRESS_FX2, @@ -402,8 +213,8 @@ static struct dvb_usb_properties cxusb_medion_properties = { .streaming_ctrl = cxusb_streaming_ctrl, .power_ctrl = cxusb_power_ctrl, - .frontend_attach = cxusb_cx22702_frontend_attach, - .tuner_attach = cxusb_fmd1216me_tuner_attach, + .frontend_attach = cxusb_frontend_attach, + .tuner_attach = cxusb_tuner_attach, .i2c_algo = &cxusb_i2c_algo, @@ -429,91 +240,6 @@ static struct dvb_usb_properties cxusb_medion_properties = { } }; -static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-bluebird-01.fw", - .download_firmware = bluebird_patch_dvico_firmware_download, - /* use usb alt setting 0 for EP4 transfer (dvb-t), - use usb alt setting 7 for EP2 transfer (atsc) */ - - .size_of_priv = sizeof(struct cxusb_state), - - .streaming_ctrl = cxusb_streaming_ctrl, - .power_ctrl = cxusb_power_ctrl, - .frontend_attach = cxusb_lgdt330x_frontend_attach, - .tuner_attach = cxusb_lgh064f_tuner_attach, - - .i2c_algo = &cxusb_i2c_algo, - - .generic_bulk_ctrl_endpoint = 0x01, - /* parameter for the MPEG2-data transfer */ - .urb = { - .type = DVB_USB_BULK, - .count = 5, - .endpoint = 0x02, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - - .num_device_descs = 1, - .devices = { - { "DViCO FusionHDTV5 USB Gold", - { &cxusb_table[1], NULL }, - { &cxusb_table[2], NULL }, - }, - } -}; - -static struct dvb_usb_properties cxusb_bluebird_dee1601_properties = { - .caps = DVB_USB_IS_AN_I2C_ADAPTER, - - .usb_ctrl = DEVICE_SPECIFIC, - .firmware = "dvb-usb-bluebird-01.fw", - .download_firmware = bluebird_patch_dvico_firmware_download, - /* use usb alt setting 0 for EP4 transfer (dvb-t), - use usb alt setting 7 for EP2 transfer (atsc) */ - - .size_of_priv = sizeof(struct cxusb_state), - - .streaming_ctrl = cxusb_streaming_ctrl, - .power_ctrl = cxusb_power_ctrl, - .frontend_attach = cxusb_dee1601_frontend_attach, - .tuner_attach = cxusb_dee1601_tuner_attach, - - .i2c_algo = &cxusb_i2c_algo, - - .rc_interval = 150, - .rc_key_map = dvico_mce_rc_keys, - .rc_key_map_size = ARRAY_SIZE(dvico_mce_rc_keys), - .rc_query = cxusb_rc_query, - - .generic_bulk_ctrl_endpoint = 0x01, - /* parameter for the MPEG2-data transfer */ - .urb = { - .type = DVB_USB_BULK, - .count = 5, - .endpoint = 0x04, - .u = { - .bulk = { - .buffersize = 8192, - } - } - }, - - .num_device_descs = 1, - .devices = { - { "DViCO FusionHDTV DVB-T Dual USB", - { &cxusb_table[3], NULL }, - { &cxusb_table[4], NULL }, - }, - } -}; - static struct usb_driver cxusb_driver = { .name = "dvb_usb_cxusb", .probe = cxusb_probe, diff --git a/trunk/drivers/media/dvb/dvb-usb/cxusb.h b/trunk/drivers/media/dvb/dvb-usb/cxusb.h index 087c99427853..135c2a81f581 100644 --- a/trunk/drivers/media/dvb/dvb-usb/cxusb.h +++ b/trunk/drivers/media/dvb/dvb-usb/cxusb.h @@ -21,8 +21,6 @@ extern int dvb_usb_cxusb_debug; #define CMD_STREAMING_ON 0x36 #define CMD_STREAMING_OFF 0x37 -#define CMD_GET_IR_CODE 0x47 - #define CMD_ANALOG 0x50 #define CMD_DIGITAL 0x51 diff --git a/trunk/drivers/media/dvb/dvb-usb/dibusb-mb.c b/trunk/drivers/media/dvb/dvb-usb/dibusb-mb.c index dd5a13195886..52ac3e5adf5d 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/trunk/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -65,11 +65,11 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_device *d) d->tuner_pass_ctrl(d->fe,0,msg[0].addr); if (b2[0] == 0xfe) { - info("This device has the Thomson Cable onboard. Which is default."); + info("this device has the Thomson Cable onboard. Which is default."); dibusb_thomson_tuner_attach(d); } else { u8 bpll[4] = { 0x0b, 0xf5, 0x85, 0xab }; - info("This device has the Panasonic ENV77H11D5 onboard."); + info("this device has the Panasonic ENV77H11D5 onboard."); d->pll_addr = 0x60; memcpy(d->pll_init,bpll,4); d->pll_desc = &dvb_pll_tda665x; @@ -98,15 +98,15 @@ static int dibusb_probe(struct usb_interface *intf, /* do not change the order of the ID table */ static struct usb_device_id dibusb_dib3000mb_table [] = { -/* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD) }, -/* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM) }, +/* 00 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_COLD)}, +/* 01 */ { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_AVERMEDIA_DVBT_USB_WARM)}, /* 02 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_COLD) }, /* 03 */ { USB_DEVICE(USB_VID_COMPRO, USB_PID_COMPRO_DVBU2000_WARM) }, /* 04 */ { USB_DEVICE(USB_VID_COMPRO_UNK, USB_PID_COMPRO_DVBU2000_UNK_COLD) }, /* 05 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_COLD) }, /* 06 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_MOD3000_WARM) }, -/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) }, -/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) }, +/* 07 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_COLD) }, +/* 08 */ { USB_DEVICE(USB_VID_EMPIA, USB_PID_KWORLD_VSTREAM_WARM) }, /* 09 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_COLD) }, /* 10 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_GRANDTEC_DVBT_USB_WARM) }, /* 11 */ { USB_DEVICE(USB_VID_GRANDTEC, USB_PID_DIBCOM_MOD3000_COLD) }, @@ -117,34 +117,27 @@ static struct usb_device_id dibusb_dib3000mb_table [] = { /* 16 */ { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7041_WARM) }, /* 17 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_COLD) }, /* 18 */ { USB_DEVICE(USB_VID_TWINHAN, USB_PID_TWINHAN_VP7041_WARM) }, -/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) }, -/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) }, -/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, -/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, +/* 19 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_COLD) }, +/* 20 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_WARM) }, +/* 21 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_COLD) }, +/* 22 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_AN2235_WARM) }, /* 23 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_COLD) }, /* device ID with default DIBUSB2_0-firmware and with the hacked firmware */ /* 24 */ { USB_DEVICE(USB_VID_ADSTECH, USB_PID_ADSTECH_USB2_WARM) }, -/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) }, -/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) }, +/* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) }, +/* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) }, /* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, -/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, -/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, +/* 28 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_COLD) }, +/* 29 */ { USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ULTIMA_TVBOX_USB2_WARM) }, -/* - * XXX: As Artec just 'forgot' to program the EEPROM on some Artec T1 devices - * we don't catch these faulty IDs (namely 'Cypress FX1 USB controller') that - * have been left on the device. If you don't have such a device but an Artec - * device that's supposed to work with this driver but is not detected by it, - * free to enable CONFIG_DVB_USB_DIBUSB_MB_FAULTY via your kernel config. - */ +// #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs -#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY +#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs /* 30 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, #endif - { } /* Terminating entry */ }; MODULE_DEVICE_TABLE (usb, dibusb_dib3000mb_table); @@ -264,7 +257,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { } }, -#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY +#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs .num_device_descs = 2, #else .num_device_descs = 1, @@ -274,12 +267,11 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { { &dibusb_dib3000mb_table[20], NULL }, { &dibusb_dib3000mb_table[21], NULL }, }, -#ifdef CONFIG_DVB_USB_DIBUSB_MB_FAULTY +#ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", { &dibusb_dib3000mb_table[30], NULL }, { NULL }, }, - { NULL }, #endif } }; @@ -331,7 +323,6 @@ static struct dvb_usb_properties dibusb2_0b_properties = { { &dibusb_dib3000mb_table[27], NULL }, { NULL } }, - { NULL }, } }; @@ -378,7 +369,6 @@ static struct dvb_usb_properties artec_t1_usb2_properties = { { &dibusb_dib3000mb_table[28], NULL }, { &dibusb_dib3000mb_table[29], NULL }, }, - { NULL }, } }; diff --git a/trunk/drivers/media/dvb/dvb-usb/digitv.c b/trunk/drivers/media/dvb/dvb-usb/digitv.c index e6c55c9c9417..450417a9e64b 100644 --- a/trunk/drivers/media/dvb/dvb-usb/digitv.c +++ b/trunk/drivers/media/dvb/dvb-usb/digitv.c @@ -32,7 +32,7 @@ static int digitv_ctrl_msg(struct dvb_usb_device *d, sndbuf[1] = vv; sndbuf[2] = wo ? wlen : rlen; - if (wo) { + if (!wo) { memcpy(&sndbuf[3],wbuf,wlen); dvb_usb_generic_write(d,sndbuf,7); } else { diff --git a/trunk/drivers/media/dvb/dvb-usb/dtt200u.c b/trunk/drivers/media/dvb/dvb-usb/dtt200u.c index 130ea7f21f5e..6e2bac873445 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/trunk/drivers/media/dvb/dvb-usb/dtt200u.c @@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = { .cold_ids = { &dtt200u_usb_table[0], NULL }, .warm_ids = { &dtt200u_usb_table[1], NULL }, }, - { 0 }, + { NULL }, } }; @@ -160,7 +160,7 @@ static struct dvb_usb_properties wt220u_properties = { .pid_filter_count = 15, .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-wt220u-02.fw", + .firmware = "dvb-usb-wt220u-01.fw", .power_ctrl = dtt200u_power_ctrl, .streaming_ctrl = dtt200u_streaming_ctrl, @@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = { .cold_ids = { &dtt200u_usb_table[2], NULL }, .warm_ids = { &dtt200u_usb_table[3], NULL }, }, - { 0 }, + { NULL }, } }; diff --git a/trunk/drivers/media/dvb/dvb-usb/dtt200u.h b/trunk/drivers/media/dvb/dvb-usb/dtt200u.h index 005b0a7df358..6f1f3042e21a 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dtt200u.h +++ b/trunk/drivers/media/dvb/dvb-usb/dtt200u.h @@ -13,7 +13,6 @@ #define _DVB_USB_DTT200U_H_ #define DVB_USB_LOG_PREFIX "dtt200u" - #include "dvb-usb.h" extern int dvb_usb_dtt200u_debug; @@ -26,15 +25,15 @@ extern int dvb_usb_dtt200u_debug; * 88 - locking 2 bytes (0x80 0x40 == no signal, 0x89 0x20 == nice signal) */ -#define GET_SPEED 0x00 -#define GET_TUNE_STATUS 0x81 -#define GET_RC_CODE 0x84 -#define GET_CONFIGURATION 0x88 -#define GET_AGC 0x89 -#define GET_SNR 0x8a -#define GET_VIT_ERR_CNT 0x8c -#define GET_RS_ERR_CNT 0x8d -#define GET_RS_UNCOR_BLK_CNT 0x8e +#define GET_SPEED 0x00 +#define GET_TUNE_STATUS 0x81 +#define GET_RC_CODE 0x84 +#define GET_CONFIGURATION 0x88 +#define GET_AGC 0x89 +#define GET_SNR 0x8a +#define GET_VIT_ERR_CNT 0x8c +#define GET_RS_ERR_CNT 0x8d +#define GET_RS_UNCOR_BLK_CNT 0x8e /* write * 01 - init @@ -45,12 +44,12 @@ extern int dvb_usb_dtt200u_debug; * 08 - transfer switch */ -#define SET_INIT 0x01 -#define SET_RF_FREQ 0x02 -#define SET_BANDWIDTH 0x03 -#define SET_PID_FILTER 0x04 -#define RESET_PID_FILTER 0x05 -#define SET_STREAMING 0x08 +#define SET_INIT 0x01 +#define SET_RF_FREQ 0x02 +#define SET_BANDWIDTH 0x03 +#define SET_PID_FILTER 0x04 +#define RESET_PID_FILTER 0x05 +#define SET_STREAMING 0x08 extern struct dvb_frontend * dtt200u_fe_attach(struct dvb_usb_device *d); diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-common.h b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-common.h index a3460bf2d9fa..7300489d3e24 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-common.h +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-common.h @@ -24,7 +24,7 @@ extern int dvb_usb_disable_rc_polling; #define deb_mem(args...) dprintk(dvb_usb_debug,0x80,args) /* commonly used methods */ -extern int dvb_usb_download_firmware(struct usb_device *, struct dvb_usb_properties *); +extern int usb_cypress_load_firmware(struct usb_device *, const char *, int); extern int dvb_usb_urb_submit(struct dvb_usb_device *); extern int dvb_usb_urb_kill(struct dvb_usb_device *); diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c index 8535895819fb..5244e39770a0 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c @@ -9,6 +9,7 @@ */ #include "dvb-usb-common.h" +#include #include struct usb_cypress_controller { @@ -18,10 +19,9 @@ struct usb_cypress_controller { }; static struct usb_cypress_controller cypress[] = { - { .id = DEVICE_SPECIFIC, .name = "Device specific", .cpu_cs_register = 0 }, - { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 }, - { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 }, - { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, + { .id = CYPRESS_AN2135, .name = "Cypress AN2135", .cpu_cs_register = 0x7f92 }, + { .id = CYPRESS_AN2235, .name = "Cypress AN2235", .cpu_cs_register = 0x7f92 }, + { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, }; /* @@ -30,117 +30,71 @@ static struct usb_cypress_controller cypress[] = { static int usb_cypress_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len) { return usb_control_msg(udev, usb_sndctrlpipe(udev,0), - 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000); + 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ); } -int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type) +int usb_cypress_load_firmware(struct usb_device *udev, const char *filename, int type) { - struct hexline hx; - u8 reset; - int ret,pos=0; - - /* stop the CPU */ - reset = 1; - if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) - err("could not stop the USB controller CPU."); - - while ((ret = dvb_usb_get_hexline(fw,&hx,&pos)) > 0) { - deb_fw("writing to address 0x%04x (buffer: 0x%02x %02x)\n",hx.addr,hx.len,hx.chk); - ret = usb_cypress_writemem(udev,hx.addr,hx.data,hx.len); + const struct firmware *fw = NULL; + u16 addr; + u8 *b,*p; + int ret = 0,i; - if (ret != hx.len) { - err("error while transferring firmware " - "(transferred size: %d, block size: %d)", - ret,hx.len); - ret = -EINVAL; - break; - } - } - if (ret < 0) { - err("firmware download failed at %d with %d",pos,ret); + if ((ret = request_firmware(&fw, filename, &udev->dev)) != 0) { + err("did not find the firmware file. (%s) " + "Please see linux/Documentation/dvb/ for more details on firmware-problems.", + filename); return ret; } - if (ret == 0) { + info("downloading firmware from file '%s' to the '%s'",filename,cypress[type].name); + + p = kmalloc(fw->size,GFP_KERNEL); + if (p != NULL) { + u8 reset; + /* + * you cannot use the fw->data as buffer for + * usb_control_msg, a new buffer has to be + * created + */ + memcpy(p,fw->data,fw->size); + + /* stop the CPU */ + reset = 1; + if ((ret = usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1)) != 1) + err("could not stop the USB controller CPU."); + for(i = 0; p[i+3] == 0 && i < fw->size; ) { + b = (u8 *) &p[i]; + addr = cpu_to_le16( *((u16 *) &b[1]) ); + + deb_fw("writing to address 0x%04x (buffer: 0x%02x%02x)\n",addr,b[1],b[2]); + + ret = usb_cypress_writemem(udev,addr,&b[4],b[0]); + + if (ret != b[0]) { + err("error while transferring firmware " + "(transferred size: %d, block size: %d)", + ret,b[0]); + ret = -EINVAL; + break; + } + i += 5 + b[0]; + } + /* length in ret */ + if (ret > 0) + ret = 0; /* restart the CPU */ reset = 0; if (ret || usb_cypress_writemem(udev,cypress[type].cpu_cs_register,&reset,1) != 1) { err("could not restart the USB controller CPU."); ret = -EINVAL; } - } else - ret = -EIO; - - return ret; -} -EXPORT_SYMBOL(usb_cypress_load_firmware); - -int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_properties *props) -{ - int ret; - const struct firmware *fw = NULL; - - if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) { - err("did not find the firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)", - props->firmware,ret); - return ret; - } - - info("downloading firmware from file '%s'",props->firmware); - switch (props->usb_ctrl) { - case CYPRESS_AN2135: - case CYPRESS_AN2235: - case CYPRESS_FX2: - ret = usb_cypress_load_firmware(udev, fw, props->usb_ctrl); - break; - case DEVICE_SPECIFIC: - if (props->download_firmware) - ret = props->download_firmware(udev,fw); - else { - err("BUG: driver didn't specified a download_firmware-callback, although it claims to have a DEVICE_SPECIFIC one."); - ret = -EINVAL; - } - break; - default: - ret = -EINVAL; - break; + kfree(p); + } else { + ret = -ENOMEM; } - release_firmware(fw); - return ret; -} - -int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos) -{ - u8 *b = (u8 *) &fw->data[*pos]; - int data_offs = 4; - if (*pos >= fw->size) - return 0; - memset(hx,0,sizeof(struct hexline)); - - hx->len = b[0]; - - if ((*pos + hx->len + 4) >= fw->size) - return -EINVAL; - - hx->addr = le16_to_cpu( *((u16 *) &b[1]) ); - hx->type = b[3]; - - if (hx->type == 0x04) { - /* b[4] and b[5] are the Extended linear address record data field */ - hx->addr |= (b[4] << 24) | (b[5] << 16); -/* hx->len -= 2; - data_offs += 2; */ - } - memcpy(hx->data,&b[data_offs],hx->len); - hx->chk = b[hx->len + data_offs]; - - *pos += hx->len + 5; - - return *pos; + return ret; } -EXPORT_SYMBOL(dvb_usb_get_hexline); - diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c index 9b254532af4d..da970947dfc7 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c @@ -52,8 +52,9 @@ int dvb_usb_pll_init_i2c(struct dvb_frontend *fe) struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 }; int ret = 0; - /* if pll_desc is not used */ - if (d->pll_desc == NULL) + /* if there is nothing to initialize */ + if (d->pll_init[0] == 0x00 && d->pll_init[1] == 0x00 && + d->pll_init[2] == 0x00 && d->pll_init[3] == 0x00) return 0; if (d->tuner_pass_ctrl) @@ -79,9 +80,6 @@ int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep { struct dvb_usb_device *d = fe->dvb->priv; - if (d->pll_desc == NULL) - return 0; - deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc); b[0] = d->pll_addr << 1; diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index d22934383226..6be99e537e12 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -86,15 +86,11 @@ #define USB_PID_WINTV_NOVA_T_USB2_COLD 0x9300 #define USB_PID_WINTV_NOVA_T_USB2_WARM 0x9301 #define USB_PID_NEBULA_DIGITV 0x0201 +#define USB_PID_DVICO_BLUEBIRD_LGZ201 0xdb00 +#define USB_PID_DVICO_BLUEBIRD_TH7579 0xdb10 #define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 -#define USB_PID_DVICO_BLUEBIRD_LG064F_COLD 0xd500 -#define USB_PID_DVICO_BLUEBIRD_LG064F_WARM 0xd501 -#define USB_PID_DVICO_BLUEBIRD_LGZ201_COLD 0xdb00 -#define USB_PID_DVICO_BLUEBIRD_LGZ201_WARM 0xdb01 -#define USB_PID_DVICO_BLUEBIRD_TH7579_COLD 0xdb10 -#define USB_PID_DVICO_BLUEBIRD_TH7579_WARM 0xdb11 -#define USB_PID_DVICO_BLUEBIRD_DEE1601_COLD 0xdb50 -#define USB_PID_DVICO_BLUEBIRD_DEE1601_WARM 0xdb51 +#define USB_PID_DVICO_BLUEBIRD_LGZ201_1 0xdb01 +#define USB_PID_DVICO_BLUEBIRD_TH7579_2 0xdb11 #define USB_PID_MEDION_MD95700 0x0932 #define USB_PID_KYE_DVB_T_COLD 0x701e #define USB_PID_KYE_DVB_T_WARM 0x701f diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-init.c index 2e23060cbbca..dd8e0b94edba 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-init.c @@ -138,9 +138,6 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties int ret = -ENOMEM,cold=0; - if (du != NULL) - *du = NULL; - if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) { deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n"); return -ENODEV; @@ -148,40 +145,38 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties if (cold) { info("found a '%s' in cold state, will try to load a firmware",desc->name); - ret = dvb_usb_download_firmware(udev,props); - if (!props->no_reconnect) + ret = usb_cypress_load_firmware(udev,props->firmware,props->usb_ctrl); + } else { + info("found a '%s' in warm state.",desc->name); + d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL); + if (d == NULL) { + err("no memory for 'struct dvb_usb_device'"); return ret; - } - - info("found a '%s' in warm state.",desc->name); - d = kmalloc(sizeof(struct dvb_usb_device),GFP_KERNEL); - if (d == NULL) { - err("no memory for 'struct dvb_usb_device'"); - return ret; - } - memset(d,0,sizeof(struct dvb_usb_device)); - - d->udev = udev; - memcpy(&d->props,props,sizeof(struct dvb_usb_properties)); - d->desc = desc; - d->owner = owner; - - if (d->props.size_of_priv > 0) { - d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL); - if (d->priv == NULL) { - err("no memory for priv in 'struct dvb_usb_device'"); - kfree(d); - return -ENOMEM; } - memset(d->priv,0,d->props.size_of_priv); - } + memset(d,0,sizeof(struct dvb_usb_device)); + + d->udev = udev; + memcpy(&d->props,props,sizeof(struct dvb_usb_properties)); + d->desc = desc; + d->owner = owner; + + if (d->props.size_of_priv > 0) { + d->priv = kmalloc(d->props.size_of_priv,GFP_KERNEL); + if (d->priv == NULL) { + err("no memory for priv in 'struct dvb_usb_device'"); + kfree(d); + return -ENOMEM; + } + memset(d->priv,0,d->props.size_of_priv); + } - usb_set_intfdata(intf, d); + usb_set_intfdata(intf, d); - if (du != NULL) - *du = d; + if (du != NULL) + *du = d; - ret = dvb_usb_init(d); + ret = dvb_usb_init(d); + } if (ret == 0) info("%s successfully initialized and connected.",desc->name); diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h b/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h index dd568396e594..b4a1a98006c7 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -10,8 +10,8 @@ #include #include +#include #include -#include #include "dvb_frontend.h" #include "dvb_demux.h" @@ -94,11 +94,7 @@ struct dvb_usb_device; * @usb_ctrl: which USB device-side controller is in use. Needed for firmware * download. * @firmware: name of the firmware file. - * @download_firmware: called to download the firmware when the usb_ctrl is - * DEVICE_SPECIFIC. - * @no_reconnect: device doesn't do a reconnect after downloading the firmware, - so do the warm initialization right after it - + * * @size_of_priv: how many bytes shall be allocated for the private field * of struct dvb_usb_device. * @@ -146,14 +142,11 @@ struct dvb_usb_properties { int caps; int pid_filter_count; -#define DEVICE_SPECIFIC 0 -#define CYPRESS_AN2135 1 -#define CYPRESS_AN2235 2 -#define CYPRESS_FX2 3 +#define CYPRESS_AN2135 0 +#define CYPRESS_AN2235 1 +#define CYPRESS_FX2 2 int usb_ctrl; - const char firmware[FIRMWARE_NAME_MAX]; - int (*download_firmware) (struct usb_device *, const struct firmware *); - int no_reconnect; + const char *firmware; int size_of_priv; @@ -333,15 +326,5 @@ extern int dvb_usb_pll_init_i2c(struct dvb_frontend *); extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]); extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *); -/* commonly used firmware download types and function */ -struct hexline { - u8 len; - u32 addr; - u8 type; - u8 data[255]; - u8 chk; -}; -extern int dvb_usb_get_hexline(const struct firmware *, struct hexline *, int *); -extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type); #endif diff --git a/trunk/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/trunk/drivers/media/dvb/dvb-usb/nova-t-usb2.c index 412039d8dbae..fac48fc7a4ac 100644 --- a/trunk/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/trunk/drivers/media/dvb/dvb-usb/nova-t-usb2.c @@ -129,6 +129,10 @@ static int nova_t_read_mac_address (struct dvb_usb_device *d, u8 mac[6]) dibusb_read_eeprom_byte(d,i, &b); mac[5 - (i - 136)] = b; + +/* deb_ee("%02x ",b); + if ((i+1) % 16 == 0) + deb_ee("\n");*/ } return 0; @@ -149,7 +153,7 @@ static struct usb_device_id nova_t_table [] = { /* 01 */ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_WINTV_NOVA_T_USB2_WARM) }, { } /* Terminating entry */ }; -MODULE_DEVICE_TABLE(usb, nova_t_table); +MODULE_DEVICE_TABLE (usb, nova_t_table); static struct dvb_usb_properties nova_t_properties = { .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_IS_AN_I2C_ADAPTER, @@ -194,7 +198,6 @@ static struct dvb_usb_properties nova_t_properties = { { &nova_t_table[0], NULL }, { &nova_t_table[1], NULL }, }, - { NULL }, } }; diff --git a/trunk/drivers/media/dvb/dvb-usb/vp702x-fe.c b/trunk/drivers/media/dvb/dvb-usb/vp702x-fe.c index 0885d9fb2bf2..104b5d016c7b 100644 --- a/trunk/drivers/media/dvb/dvb-usb/vp702x-fe.c +++ b/trunk/drivers/media/dvb/dvb-usb/vp702x-fe.c @@ -190,7 +190,7 @@ static int vp702x_fe_get_frontend(struct dvb_frontend* fe, } static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd *m) + struct dvb_diseqc_master_cmd *m) { struct vp702x_fe_state *st = fe->demodulator_priv; u8 cmd[8],ibuf[10]; diff --git a/trunk/drivers/media/dvb/dvb-usb/vp702x.h b/trunk/drivers/media/dvb/dvb-usb/vp702x.h index a808d48e7bf2..4a3e8c7eca2b 100644 --- a/trunk/drivers/media/dvb/dvb-usb/vp702x.h +++ b/trunk/drivers/media/dvb/dvb-usb/vp702x.h @@ -13,47 +13,47 @@ extern int dvb_usb_vp702x_debug; /* commands are read and written with USB control messages */ /* consecutive read/write operation */ -#define REQUEST_OUT 0xB2 -#define REQUEST_IN 0xB3 +#define REQUEST_OUT 0xB2 +#define REQUEST_IN 0xB3 /* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0 * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer * the returning buffer looks as follows * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */ -#define GET_TUNER_STATUS 0x05 +#define GET_TUNER_STATUS 0x05 /* additional in buffer: * 0 1 2 3 4 5 6 7 8 * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */ -#define GET_SYSTEM_STRING 0x06 +#define GET_SYSTEM_STRING 0x06 /* additional in buffer: * 0 1 2 3 4 5 6 7 8 * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */ -#define SET_DISEQC_CMD 0x08 +#define SET_DISEQC_CMD 0x08 /* additional out buffer: * 0 1 2 3 4 * len X1 X2 X3 X4 * additional in buffer: * 0 1 2 - * N/A 0 0 b[1] == b[2] == 0 -> success, failure otherwise */ + * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */ -#define SET_LNB_POWER 0x09 +#define SET_LNB_POWER 0x09 /* additional out buffer: * 0 1 2 * 0x00 0xff 1 = on, 0 = off * additional in buffer: * 0 1 2 - * N/A 0 0 b[1] == b[2] == 0 -> success failure otherwise */ + * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */ -#define GET_MAC_ADDRESS 0x0A +#define GET_MAC_ADDRESS 0x0A /* #define GET_MAC_ADDRESS 0x0B */ /* additional in buffer: * 0 1 2 3 4 5 6 7 8 * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */ -#define SET_PID_FILTER 0x11 +#define SET_PID_FILTER 0x11 /* additional in buffer: * 0 1 ... 14 15 16 * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */ @@ -64,38 +64,39 @@ extern int dvb_usb_vp702x_debug; * freq0 freq1 divstep srate0 srate1 srate2 flag chksum */ + /* one direction requests */ -#define READ_REMOTE_REQ 0xB4 +#define READ_REMOTE_REQ 0xB4 /* IN i: 0; v: 0; b[0] == request, b[1] == key */ -#define READ_PID_NUMBER_REQ 0xB5 +#define READ_PID_NUMBER_REQ 0xB5 /* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */ -#define WRITE_EEPROM_REQ 0xB6 +#define WRITE_EEPROM_REQ 0xB6 /* OUT i: offset; v: value to write; no extra buffer */ -#define READ_EEPROM_REQ 0xB7 +#define READ_EEPROM_REQ 0xB7 /* IN i: bufferlen; v: offset; buffer with bufferlen bytes */ -#define READ_STATUS 0xB8 +#define READ_STATUS 0xB8 /* IN i: 0; v: 0; bufferlen 10 */ -#define READ_TUNER_REG_REQ 0xB9 +#define READ_TUNER_REG_REQ 0xB9 /* IN i: 0; v: register; b[0] = value */ -#define READ_FX2_REG_REQ 0xBA +#define READ_FX2_REG_REQ 0xBA /* IN i: offset; v: 0; b[0] = value */ -#define WRITE_FX2_REG_REQ 0xBB +#define WRITE_FX2_REG_REQ 0xBB /* OUT i: offset; v: value to write; 1 byte extra buffer */ -#define SET_TUNER_POWER_REQ 0xBC +#define SET_TUNER_POWER_REQ 0xBC /* IN i: 0 = power off, 1 = power on */ -#define WRITE_TUNER_REG_REQ 0xBD +#define WRITE_TUNER_REG_REQ 0xBD /* IN i: register, v: value to write, no extra buffer */ -#define RESET_TUNER 0xBE +#define RESET_TUNER 0xBE /* IN i: 0, v: 0, no extra buffer */ extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); diff --git a/trunk/drivers/media/dvb/dvb-usb/vp7045.c b/trunk/drivers/media/dvb/dvb-usb/vp7045.c index 028204956bb0..3835235b68df 100644 --- a/trunk/drivers/media/dvb/dvb-usb/vp7045.c +++ b/trunk/drivers/media/dvb/dvb-usb/vp7045.c @@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = { .cold_ids = { &vp7045_usb_table[2], NULL }, .warm_ids = { &vp7045_usb_table[3], NULL }, }, - { 0 }, + { NULL }, } }; diff --git a/trunk/drivers/media/dvb/frontends/Kconfig b/trunk/drivers/media/dvb/frontends/Kconfig index db3a8b40031e..8e269e1c1f9d 100644 --- a/trunk/drivers/media/dvb/frontends/Kconfig +++ b/trunk/drivers/media/dvb/frontends/Kconfig @@ -16,12 +16,6 @@ config DVB_CX24110 help A DVB-S tuner module. Say Y when you want to support this frontend. -config DVB_CX24123 - tristate "Conexant CX24123 based" - depends on DVB_CORE - help - A DVB-S tuner module. Say Y when you want to support this frontend. - config DVB_TDA8083 tristate "Philips TDA8083 based" depends on DVB_CORE @@ -56,19 +50,18 @@ comment "DVB-T (terrestrial) frontends" depends on DVB_CORE config DVB_SP8870 - tristate "Spase sp8870 based" + tristate "Spase sp8870 based" depends on DVB_CORE select FW_LOADER help - A DVB-T tuner module. Say Y when you want to support this frontend. + A DVB-T tuner module. Say Y when you want to support this frontend. This driver needs external firmware. Please use the command "/Documentation/dvb/get_dvb_firmware sp8870" to - download/extract it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). + download/extract it, and then copy it to /usr/lib/hotplug/firmware. config DVB_SP887X - tristate "Spase sp887x based" + tristate "Spase sp887x based" depends on DVB_CORE select FW_LOADER help @@ -76,8 +69,7 @@ config DVB_SP887X This driver needs external firmware. Please use the command "/Documentation/dvb/get_dvb_firmware sp887x" to - download/extract it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). + download/extract it, and then copy it to /usr/lib/hotplug/firmware. config DVB_CX22700 tristate "Conexant CX22700 based" @@ -86,10 +78,10 @@ config DVB_CX22700 A DVB-T tuner module. Say Y when you want to support this frontend. config DVB_CX22702 - tristate "Conexant cx22702 demodulator (OFDM)" - depends on DVB_CORE - help - A DVB-T tuner module. Say Y when you want to support this frontend. + tristate "Conexant cx22702 demodulator (OFDM)" + depends on DVB_CORE + help + A DVB-T tuner module. Say Y when you want to support this frontend. config DVB_L64781 tristate "LSI L64781" @@ -106,9 +98,8 @@ config DVB_TDA1004X This driver needs external firmware. Please use the commands "/Documentation/dvb/get_dvb_firmware tda10045", - "/Documentation/dvb/get_dvb_firmware tda10046" to - download/extract them, and then copy them to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). + "/Documentation/dvb/get_dvb_firmware tda10046" to + download/extract them, and then copy them to /usr/lib/hotplug/firmware. config DVB_NXT6000 tristate "NxtWave Communications NXT6000 based" @@ -149,13 +140,13 @@ config DVB_VES1820 tristate "VLSI VES1820 based" depends on DVB_CORE help - A DVB-C tuner module. Say Y when you want to support this frontend. + A DVB-C tuner module. Say Y when you want to support this frontend. config DVB_TDA10021 tristate "Philips TDA10021 based" depends on DVB_CORE help - A DVB-C tuner module. Say Y when you want to support this frontend. + A DVB-C tuner module. Say Y when you want to support this frontend. config DVB_STV0297 tristate "ST STV0297 based" @@ -173,11 +164,6 @@ config DVB_NXT2002 help An ATSC 8VSB tuner module. Say Y when you want to support this frontend. - This driver needs external firmware. Please use the command - "/Documentation/dvb/get_dvb_firmware nxt2002" to - download/extract it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - config DVB_NXT200X tristate "Nextwave NXT2002/NXT2004 based" depends on DVB_CORE @@ -186,12 +172,6 @@ config DVB_NXT200X An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. - This driver needs external firmware. Please use the commands - "/Documentation/dvb/get_dvb_firmware nxt2002" and - "/Documentation/dvb/get_dvb_firmware nxt2004" to - download/extract them, and then copy them to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). - config DVB_OR51211 tristate "or51211 based (pcHDTV HD2000 card)" depends on DVB_CORE diff --git a/trunk/drivers/media/dvb/frontends/Makefile b/trunk/drivers/media/dvb/frontends/Makefile index 615ec830e1c9..a98760fe08a1 100644 --- a/trunk/drivers/media/dvb/frontends/Makefile +++ b/trunk/drivers/media/dvb/frontends/Makefile @@ -32,4 +32,3 @@ obj-$(CONFIG_DVB_OR51132) += or51132.o obj-$(CONFIG_DVB_BCM3510) += bcm3510.o obj-$(CONFIG_DVB_S5H1420) += s5h1420.o obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o -obj-$(CONFIG_DVB_CX24123) += cx24123.o diff --git a/trunk/drivers/media/dvb/frontends/bcm3510.c b/trunk/drivers/media/dvb/frontends/bcm3510.c index 3b132bafd4de..8ceb9a33c7af 100644 --- a/trunk/drivers/media/dvb/frontends/bcm3510.c +++ b/trunk/drivers/media/dvb/frontends/bcm3510.c @@ -255,7 +255,7 @@ static int bcm3510_bert_reset(struct bcm3510_state *st) bcm3510_register_value b; int ret; - if ((ret = bcm3510_readB(st,0xfa,&b)) < 0) + if ((ret < bcm3510_readB(st,0xfa,&b)) < 0) return ret; b.BERCTL_fa.RESYNC = 0; bcm3510_writeB(st,0xfa,b); @@ -623,13 +623,13 @@ static int bcm3510_download_firmware(struct dvb_frontend* fe) err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret); return ret; } - deb_info("got firmware: %zd\n",fw->size); + deb_info("got firmware: %d\n",fw->size); b = fw->data; for (i = 0; i < fw->size;) { addr = le16_to_cpu( *( (u16 *)&b[i] ) ); len = le16_to_cpu( *( (u16 *)&b[i+2] ) ); - deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04zx\n",addr,len,fw->size); + deb_info("firmware chunk, addr: 0x%04x, len: 0x%04x, total length: 0x%04x\n",addr,len,fw->size); if ((ret = bcm3510_write_ram(st,addr,&b[i+4],len)) < 0) { err("firmware download failed: %d\n",ret); return ret; diff --git a/trunk/drivers/media/dvb/frontends/cx22702.c b/trunk/drivers/media/dvb/frontends/cx22702.c index 0fc899f81c5e..5de0e6d350b1 100644 --- a/trunk/drivers/media/dvb/frontends/cx22702.c +++ b/trunk/drivers/media/dvb/frontends/cx22702.c @@ -195,16 +195,6 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet return 0; } -static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) -{ - struct cx22702_state* state = fe->demodulator_priv; - dprintk ("%s(%d)\n", __FUNCTION__, enable); - if (enable) - return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe); - else - return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) | 1); -} - /* Talk to the demod, set the FEC, GUARD, QAM settings etc */ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { @@ -212,7 +202,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet struct cx22702_state* state = fe->demodulator_priv; /* set PLL */ - cx22702_i2c_gate_ctrl(fe, 1); + cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); if (state->config->pll_set) { state->config->pll_set(fe, p); } else if (state->config->pll_desc) { @@ -226,7 +216,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet } else { BUG(); } - cx22702_i2c_gate_ctrl(fe, 0); + cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); /* set inversion */ cx22702_set_inversion (state, p->inversion); @@ -359,10 +349,11 @@ static int cx22702_init (struct dvb_frontend* fe) cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02); /* init PLL */ - if (state->config->pll_init) + if (state->config->pll_init) { + cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) & 0xfe); state->config->pll_init(fe); - - cx22702_i2c_gate_ctrl(fe, 0); + cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) | 1); + } return 0; } @@ -540,7 +531,6 @@ static struct dvb_frontend_ops cx22702_ops = { .read_signal_strength = cx22702_read_signal_strength, .read_snr = cx22702_read_snr, .read_ucblocks = cx22702_read_ucblocks, - .i2c_gate_ctrl = cx22702_i2c_gate_ctrl, }; module_param(debug, int, 0644); diff --git a/trunk/drivers/media/dvb/frontends/cx24110.c b/trunk/drivers/media/dvb/frontends/cx24110.c index d15d32c51dc5..0c4db80ec332 100644 --- a/trunk/drivers/media/dvb/frontends/cx24110.c +++ b/trunk/drivers/media/dvb/frontends/cx24110.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "dvb_frontend.h" #include "cx24110.h" @@ -55,7 +56,7 @@ static int debug; static struct {u8 reg; u8 data;} cx24110_regdata[]= /* Comments beginning with @ denote this value should - be the default */ + be the default */ {{0x09,0x01}, /* SoftResetAll */ {0x09,0x00}, /* release reset */ {0x01,0xe8}, /* MSB of code rate 27.5MS/s */ @@ -66,26 +67,26 @@ static struct {u8 reg; u8 data;} cx24110_regdata[]= {0x07,0x01}, /* @ Fclk, i.e. sampling clock, 60MHz */ {0x0a,0x00}, /* @ partial chip disables, do not set */ {0x0b,0x01}, /* set output clock in gapped mode, start signal low - active for first byte */ + active for first byte */ {0x0c,0x11}, /* no parity bytes, large hold time, serial data out */ {0x0d,0x6f}, /* @ RS Sync/Unsync thresholds */ {0x10,0x40}, /* chip doc is misleading here: write bit 6 as 1 - to avoid starting the BER counter. Reset the - CRC test bit. Finite counting selected */ + to avoid starting the BER counter. Reset the + CRC test bit. Finite counting selected */ {0x15,0xff}, /* @ size of the limited time window for RS BER - estimation. It is *256 RS blocks, this - gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ + estimation. It is *256 RS blocks, this + gives approx. 2.6 sec at 27.5MS/s, rate 3/4 */ {0x16,0x00}, /* @ enable all RS output ports */ {0x17,0x04}, /* @ time window allowed for the RS to sync */ {0x18,0xae}, /* @ allow all standard DVB code rates to be scanned - for automatically */ + for automatically */ /* leave the current code rate and normalization - registers as they are after reset... */ + registers as they are after reset... */ {0x21,0x10}, /* @ during AutoAcq, search each viterbi setting - only once */ + only once */ {0x23,0x18}, /* @ size of the limited time window for Viterbi BER - estimation. It is *65536 channel bits, i.e. - approx. 38ms at 27.5MS/s, rate 3/4 */ + estimation. It is *65536 channel bits, i.e. + approx. 38ms at 27.5MS/s, rate 3/4 */ {0x24,0x24}, /* do not trigger Viterbi CRC test. Finite count window */ /* leave front-end AGC parameters at default values */ /* leave decimation AGC parameters at default values */ diff --git a/trunk/drivers/media/dvb/frontends/cx24123.c b/trunk/drivers/media/dvb/frontends/cx24123.c deleted file mode 100644 index d661c6f9cbe5..000000000000 --- a/trunk/drivers/media/dvb/frontends/cx24123.c +++ /dev/null @@ -1,889 +0,0 @@ -/* - Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver - - Copyright (C) 2005 Steven Toth - - Support for KWorld DVB-S 100 by Vadim Catana - - 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. -*/ - -#include -#include -#include -#include -#include - -#include "dvb_frontend.h" -#include "cx24123.h" - -static int debug; -#define dprintk(args...) \ - do { \ - if (debug) printk (KERN_DEBUG "cx24123: " args); \ - } while (0) - -struct cx24123_state -{ - struct i2c_adapter* i2c; - struct dvb_frontend_ops ops; - const struct cx24123_config* config; - - struct dvb_frontend frontend; - - u32 lastber; - u16 snr; - u8 lnbreg; - - /* Some PLL specifics for tuning */ - u32 VCAarg; - u32 VGAarg; - u32 bandselectarg; - u32 pllarg; - - /* The Demod/Tuner can't easily provide these, we cache them */ - u32 currentfreq; - u32 currentsymbolrate; -}; - -/* Various tuner defaults need to be established for a given symbol rate Sps */ -static struct -{ - u32 symbolrate_low; - u32 symbolrate_high; - u32 VCAslope; - u32 VCAoffset; - u32 VGA1offset; - u32 VGA2offset; - u32 VCAprogdata; - u32 VGAprogdata; -} cx24123_AGC_vals[] = -{ - { - .symbolrate_low = 1000000, - .symbolrate_high = 4999999, - .VCAslope = 0x07, - .VCAoffset = 0x0f, - .VGA1offset = 0x1f8, - .VGA2offset = 0x1f8, - .VGAprogdata = (2 << 18) | (0x1f8 << 9) | 0x1f8, - .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x07, - }, - { - .symbolrate_low = 5000000, - .symbolrate_high = 14999999, - .VCAslope = 0x1f, - .VCAoffset = 0x1f, - .VGA1offset = 0x1e0, - .VGA2offset = 0x180, - .VGAprogdata = (2 << 18) | (0x180 << 9) | 0x1e0, - .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x1f, - }, - { - .symbolrate_low = 15000000, - .symbolrate_high = 45000000, - .VCAslope = 0x3f, - .VCAoffset = 0x3f, - .VGA1offset = 0x180, - .VGA2offset = 0x100, - .VGAprogdata = (2 << 18) | (0x100 << 9) | 0x180, - .VCAprogdata = (4 << 18) | (0x07 << 9) | 0x3f, - }, -}; - -/* - * Various tuner defaults need to be established for a given frequency kHz. - * fixme: The bounds on the bands do not match the doc in real life. - * fixme: Some of them have been moved, other might need adjustment. - */ -static struct -{ - u32 freq_low; - u32 freq_high; - u32 bandselect; - u32 VCOdivider; - u32 VCOnumber; - u32 progdata; -} cx24123_bandselect_vals[] = -{ - { - .freq_low = 950000, - .freq_high = 1018999, - .bandselect = 0x40, - .VCOdivider = 4, - .VCOnumber = 7, - .progdata = (0 << 18) | (0 << 9) | 0x40, - }, - { - .freq_low = 1019000, - .freq_high = 1074999, - .bandselect = 0x80, - .VCOdivider = 4, - .VCOnumber = 8, - .progdata = (0 << 18) | (0 << 9) | 0x80, - }, - { - .freq_low = 1075000, - .freq_high = 1227999, - .bandselect = 0x01, - .VCOdivider = 2, - .VCOnumber = 1, - .progdata = (0 << 18) | (1 << 9) | 0x01, - }, - { - .freq_low = 1228000, - .freq_high = 1349999, - .bandselect = 0x02, - .VCOdivider = 2, - .VCOnumber = 2, - .progdata = (0 << 18) | (1 << 9) | 0x02, - }, - { - .freq_low = 1350000, - .freq_high = 1481999, - .bandselect = 0x04, - .VCOdivider = 2, - .VCOnumber = 3, - .progdata = (0 << 18) | (1 << 9) | 0x04, - }, - { - .freq_low = 1482000, - .freq_high = 1595999, - .bandselect = 0x08, - .VCOdivider = 2, - .VCOnumber = 4, - .progdata = (0 << 18) | (1 << 9) | 0x08, - }, - { - .freq_low = 1596000, - .freq_high = 1717999, - .bandselect = 0x10, - .VCOdivider = 2, - .VCOnumber = 5, - .progdata = (0 << 18) | (1 << 9) | 0x10, - }, - { - .freq_low = 1718000, - .freq_high = 1855999, - .bandselect = 0x20, - .VCOdivider = 2, - .VCOnumber = 6, - .progdata = (0 << 18) | (1 << 9) | 0x20, - }, - { - .freq_low = 1856000, - .freq_high = 2035999, - .bandselect = 0x40, - .VCOdivider = 2, - .VCOnumber = 7, - .progdata = (0 << 18) | (1 << 9) | 0x40, - }, - { - .freq_low = 2036000, - .freq_high = 2149999, - .bandselect = 0x80, - .VCOdivider = 2, - .VCOnumber = 8, - .progdata = (0 << 18) | (1 << 9) | 0x80, - }, -}; - -static struct { - u8 reg; - u8 data; -} cx24123_regdata[] = -{ - {0x00, 0x03}, /* Reset system */ - {0x00, 0x00}, /* Clear reset */ - {0x01, 0x3b}, /* Apply sensible defaults, from an i2c sniffer */ - {0x03, 0x07}, - {0x04, 0x10}, - {0x05, 0x04}, - {0x06, 0x31}, - {0x0d, 0x02}, - {0x0e, 0x03}, - {0x0f, 0xfe}, - {0x10, 0x01}, - {0x14, 0x01}, - {0x15, 0x98}, - {0x16, 0x00}, - {0x17, 0x01}, - {0x1b, 0x05}, - {0x1c, 0x80}, - {0x1d, 0x00}, - {0x1e, 0x00}, - {0x20, 0x41}, - {0x21, 0x15}, - {0x27, 0x14}, - {0x28, 0x46}, - {0x29, 0x00}, - {0x2a, 0xb0}, - {0x2b, 0x73}, - {0x2c, 0x00}, - {0x2d, 0x00}, - {0x2e, 0x00}, - {0x2f, 0x00}, - {0x30, 0x00}, - {0x31, 0x00}, - {0x32, 0x8c}, - {0x33, 0x00}, - {0x34, 0x00}, - {0x35, 0x03}, - {0x36, 0x02}, - {0x37, 0x3a}, - {0x3a, 0x00}, /* Enable AGC accumulator */ - {0x44, 0x00}, - {0x45, 0x00}, - {0x46, 0x05}, - {0x56, 0x41}, - {0x57, 0xff}, - {0x67, 0x83}, -}; - -static int cx24123_writereg(struct cx24123_state* state, int reg, int data) -{ - u8 buf[] = { reg, data }; - struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; - int err; - - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk("%s: writereg error(err == %i, reg == 0x%02x," - " data == 0x%02x)\n", __FUNCTION__, err, reg, data); - return -EREMOTEIO; - } - - return 0; -} - -static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data) -{ - u8 buf[] = { reg, data }; - /* fixme: put the intersil addr int the config */ - struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 }; - int err; - - if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { - printk("%s: writelnbreg error (err == %i, reg == 0x%02x," - " data == 0x%02x)\n", __FUNCTION__, err, reg, data); - return -EREMOTEIO; - } - - /* cache the write, no way to read back */ - state->lnbreg = data; - - return 0; -} - -static int cx24123_readreg(struct cx24123_state* state, u8 reg) -{ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - struct i2c_msg msg[] = { - { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } - }; - - ret = i2c_transfer(state->i2c, msg, 2); - - if (ret != 2) { - printk("%s: reg=0x%x (error=%d)\n", __FUNCTION__, reg, ret); - return ret; - } - - return b1[0]; -} - -static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg) -{ - return state->lnbreg; -} - -static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion) -{ - switch (inversion) { - case INVERSION_OFF: - cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) & 0x7f); - cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80); - break; - case INVERSION_ON: - cx24123_writereg(state, 0x0e, cx24123_readreg(state, 0x0e) | 0x80); - cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) | 0x80); - break; - case INVERSION_AUTO: - cx24123_writereg(state, 0x10, cx24123_readreg(state, 0x10) & 0x7f); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_inversion_t *inversion) -{ - u8 val; - - val = cx24123_readreg(state, 0x1b) >> 7; - - if (val == 0) - *inversion = INVERSION_OFF; - else - *inversion = INVERSION_ON; - - return 0; -} - -static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec) -{ - if ( (fec < FEC_NONE) || (fec > FEC_AUTO) ) - fec = FEC_AUTO; - - /* Hardware has 5/11 and 3/5 but are never unused */ - switch (fec) { - case FEC_NONE: - return cx24123_writereg(state, 0x0f, 0x01); - case FEC_1_2: - return cx24123_writereg(state, 0x0f, 0x02); - case FEC_2_3: - return cx24123_writereg(state, 0x0f, 0x04); - case FEC_3_4: - return cx24123_writereg(state, 0x0f, 0x08); - case FEC_5_6: - return cx24123_writereg(state, 0x0f, 0x20); - case FEC_7_8: - return cx24123_writereg(state, 0x0f, 0x80); - case FEC_AUTO: - return cx24123_writereg(state, 0x0f, 0xae); - default: - return -EOPNOTSUPP; - } -} - -static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec) -{ - int ret; - u8 val; - - ret = cx24123_readreg (state, 0x1b); - if (ret < 0) - return ret; - val = ret & 0x07; - switch (val) { - case 1: - *fec = FEC_1_2; - break; - case 3: - *fec = FEC_2_3; - break; - case 4: - *fec = FEC_3_4; - break; - case 5: - *fec = FEC_4_5; - break; - case 6: - *fec = FEC_5_6; - break; - case 7: - *fec = FEC_7_8; - break; - case 2: /* *fec = FEC_3_5; break; */ - case 0: /* *fec = FEC_5_11; break; */ - *fec = FEC_AUTO; - break; - default: - *fec = FEC_NONE; // can't happen - } - - return 0; -} - -/* fixme: Symbol rates < 3MSps may not work because of precision loss */ -static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate) -{ - u32 val; - - val = (srate / 1185) * 100; - - /* Compensate for scaling up, by removing 17 symbols per 1Msps */ - val = val - (17 * (srate / 1000000)); - - cx24123_writereg(state, 0x08, (val >> 16) & 0xff ); - cx24123_writereg(state, 0x09, (val >> 8) & 0xff ); - cx24123_writereg(state, 0x0a, (val ) & 0xff ); - - return 0; -} - -/* - * Based on the required frequency and symbolrate, the tuner AGC has to be configured - * and the correct band selected. Calculate those values - */ -static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - u32 ndiv = 0, adiv = 0, vco_div = 0; - int i = 0; - - /* Defaults for low freq, low rate */ - state->VCAarg = cx24123_AGC_vals[0].VCAprogdata; - state->VGAarg = cx24123_AGC_vals[0].VGAprogdata; - state->bandselectarg = cx24123_bandselect_vals[0].progdata; - vco_div = cx24123_bandselect_vals[0].VCOdivider; - - /* For the given symbolerate, determine the VCA and VGA programming bits */ - for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++) - { - if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) && - (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { - state->VCAarg = cx24123_AGC_vals[i].VCAprogdata; - state->VGAarg = cx24123_AGC_vals[i].VGAprogdata; - } - } - - /* For the given frequency, determine the bandselect programming bits */ - for (i = 0; i < sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); i++) - { - if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) && - (cx24123_bandselect_vals[i].freq_high >= p->frequency) ) { - state->bandselectarg = cx24123_bandselect_vals[i].progdata; - vco_div = cx24123_bandselect_vals[i].VCOdivider; - } - } - - /* Determine the N/A dividers for the requested lband freq (in kHz). */ - /* Note: 10111 (kHz) is the Crystal Freq and divider of 10. */ - ndiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) / 32) & 0x1ff; - adiv = ( ((p->frequency * vco_div) / (10111 / 10) / 2) % 32) & 0x1f; - - if (adiv == 0) - adiv++; - - /* determine the correct pll frequency values. */ - /* Command 11, refdiv 11, cpump polarity 1, cpump current 3mA 10. */ - state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (2 << 14); - state->pllarg |= (ndiv << 5) | adiv; - - return 0; -} - -/* - * Tuner data is 21 bits long, must be left-aligned in data. - * Tuner cx24109 is written through a dedicated 3wire interface on the demod chip. - */ -static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_parameters *p, u32 data) -{ - struct cx24123_state *state = fe->demodulator_priv; - unsigned long timeout; - - /* align the 21 bytes into to bit23 boundary */ - data = data << 3; - - /* Reset the demod pll word length to 0x15 bits */ - cx24123_writereg(state, 0x21, 0x15); - - /* write the msb 8 bits, wait for the send to be completed */ - timeout = jiffies + msecs_to_jiffies(40); - cx24123_writereg(state, 0x22, (data >> 16) & 0xff); - while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { - if (time_after(jiffies, timeout)) { - printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); - return -EREMOTEIO; - } - msleep(10); - } - - /* send another 8 bytes, wait for the send to be completed */ - timeout = jiffies + msecs_to_jiffies(40); - cx24123_writereg(state, 0x22, (data>>8) & 0xff ); - while ((cx24123_readreg(state, 0x20) & 0x40) == 0) { - if (time_after(jiffies, timeout)) { - printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); - return -EREMOTEIO; - } - msleep(10); - } - - /* send the lower 5 bits of this byte, padded with 3 LBB, wait for the send to be completed */ - timeout = jiffies + msecs_to_jiffies(40); - cx24123_writereg(state, 0x22, (data) & 0xff ); - while ((cx24123_readreg(state, 0x20) & 0x80)) { - if (time_after(jiffies, timeout)) { - printk("%s: demodulator is not responding, possibly hung, aborting.\n", __FUNCTION__); - return -EREMOTEIO; - } - msleep(10); - } - - /* Trigger the demod to configure the tuner */ - cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) | 2); - cx24123_writereg(state, 0x20, cx24123_readreg(state, 0x20) & 0xfd); - - return 0; -} - -static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - - if (cx24123_pll_calculate(fe, p) != 0) { - printk("%s: cx24123_pll_calcutate failed\n",__FUNCTION__); - return -EINVAL; - } - - /* Write the new VCO/VGA */ - cx24123_pll_writereg(fe, p, state->VCAarg); - cx24123_pll_writereg(fe, p, state->VGAarg); - - /* Write the new bandselect and pll args */ - cx24123_pll_writereg(fe, p, state->bandselectarg); - cx24123_pll_writereg(fe, p, state->pllarg); - - return 0; -} - -static int cx24123_initfe(struct dvb_frontend* fe) -{ - struct cx24123_state *state = fe->demodulator_priv; - int i; - - /* Configure the demod to a good set of defaults */ - for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) - cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); - - if (state->config->pll_init) - state->config->pll_init(fe); - - /* Configure the LNB for 14V */ - if (state->config->use_isl6421) - cx24123_writelnbreg(state, 0x0, 0x2a); - - return 0; -} - -static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) -{ - struct cx24123_state *state = fe->demodulator_priv; - u8 val; - - switch (state->config->use_isl6421) { - - case 1: - - val = cx24123_readlnbreg(state, 0x0); - - switch (voltage) { - case SEC_VOLTAGE_13: - return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */ - case SEC_VOLTAGE_18: - return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */ - case SEC_VOLTAGE_OFF: - return cx24123_writelnbreg(state, 0x0, val & 0x30); - default: - return -EINVAL; - }; - - case 0: - - val = cx24123_readreg(state, 0x29); - - switch (voltage) { - case SEC_VOLTAGE_13: - dprintk("%s: setting voltage 13V\n", __FUNCTION__); - if (state->config->enable_lnb_voltage) - state->config->enable_lnb_voltage(fe, 1); - return cx24123_writereg(state, 0x29, val | 0x80); - case SEC_VOLTAGE_18: - dprintk("%s: setting voltage 18V\n", __FUNCTION__); - if (state->config->enable_lnb_voltage) - state->config->enable_lnb_voltage(fe, 1); - return cx24123_writereg(state, 0x29, val & 0x7f); - case SEC_VOLTAGE_OFF: - dprintk("%s: setting voltage off\n", __FUNCTION__); - if (state->config->enable_lnb_voltage) - state->config->enable_lnb_voltage(fe, 0); - return 0; - default: - return -EINVAL; - }; - } - - return 0; -} - -static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, - struct dvb_diseqc_master_cmd *cmd) -{ - /* fixme: Implement diseqc */ - printk("%s: No support yet\n",__FUNCTION__); - - return -ENOTSUPP; -} - -static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status) -{ - struct cx24123_state *state = fe->demodulator_priv; - - int sync = cx24123_readreg(state, 0x14); - int lock = cx24123_readreg(state, 0x20); - - *status = 0; - if (lock & 0x01) - *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; - if (sync & 0x04) - *status |= FE_HAS_VITERBI; - if (sync & 0x08) - *status |= FE_HAS_CARRIER; - if (sync & 0x80) - *status |= FE_HAS_SYNC | FE_HAS_LOCK; - - return 0; -} - -/* - * Configured to return the measurement of errors in blocks, because no UCBLOCKS value - * is available, so this value doubles up to satisfy both measurements - */ -static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber) -{ - struct cx24123_state *state = fe->demodulator_priv; - - state->lastber = - ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) | - (cx24123_readreg(state, 0x1d) << 8 | - cx24123_readreg(state, 0x1e)); - - /* Do the signal quality processing here, it's derived from the BER. */ - /* Scale the BER from a 24bit to a SNR 16 bit where higher = better */ - if (state->lastber < 5000) - state->snr = 655*100; - else if ( (state->lastber >= 5000) && (state->lastber < 55000) ) - state->snr = 655*90; - else if ( (state->lastber >= 55000) && (state->lastber < 150000) ) - state->snr = 655*80; - else if ( (state->lastber >= 150000) && (state->lastber < 250000) ) - state->snr = 655*70; - else if ( (state->lastber >= 250000) && (state->lastber < 450000) ) - state->snr = 655*65; - else - state->snr = 0; - - *ber = state->lastber; - - return 0; -} - -static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) -{ - struct cx24123_state *state = fe->demodulator_priv; - *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */ - - return 0; -} - -static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr) -{ - struct cx24123_state *state = fe->demodulator_priv; - *snr = state->snr; - - return 0; -} - -static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) -{ - struct cx24123_state *state = fe->demodulator_priv; - *ucblocks = state->lastber; - - return 0; -} - -static int cx24123_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - - if (state->config->set_ts_params) - state->config->set_ts_params(fe, 0); - - state->currentfreq=p->frequency; - state->currentsymbolrate = p->u.qpsk.symbol_rate; - - cx24123_set_inversion(state, p->inversion); - cx24123_set_fec(state, p->u.qpsk.fec_inner); - cx24123_set_symbolrate(state, p->u.qpsk.symbol_rate); - cx24123_pll_tune(fe, p); - - /* Enable automatic aquisition and reset cycle */ - cx24123_writereg(state, 0x03, (cx24123_readreg(state, 0x03) | 0x07)); - cx24123_writereg(state, 0x00, 0x10); - cx24123_writereg(state, 0x00, 0); - - return 0; -} - -static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) -{ - struct cx24123_state *state = fe->demodulator_priv; - - if (cx24123_get_inversion(state, &p->inversion) != 0) { - printk("%s: Failed to get inversion status\n",__FUNCTION__); - return -EREMOTEIO; - } - if (cx24123_get_fec(state, &p->u.qpsk.fec_inner) != 0) { - printk("%s: Failed to get fec status\n",__FUNCTION__); - return -EREMOTEIO; - } - p->frequency = state->currentfreq; - p->u.qpsk.symbol_rate = state->currentsymbolrate; - - return 0; -} - -static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) -{ - struct cx24123_state *state = fe->demodulator_priv; - u8 val; - - switch (state->config->use_isl6421) { - case 1: - - val = cx24123_readlnbreg(state, 0x0); - - switch (tone) { - case SEC_TONE_ON: - return cx24123_writelnbreg(state, 0x0, val | 0x10); - case SEC_TONE_OFF: - return cx24123_writelnbreg(state, 0x0, val & 0x2f); - default: - printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); - return -EINVAL; - } - - case 0: - - val = cx24123_readreg(state, 0x29); - - switch (tone) { - case SEC_TONE_ON: - dprintk("%s: setting tone on\n", __FUNCTION__); - return cx24123_writereg(state, 0x29, val | 0x10); - case SEC_TONE_OFF: - dprintk("%s: setting tone off\n",__FUNCTION__); - return cx24123_writereg(state, 0x29, val & 0xef); - default: - printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone); - return -EINVAL; - } - } - - return 0; -} - -static void cx24123_release(struct dvb_frontend* fe) -{ - struct cx24123_state* state = fe->demodulator_priv; - dprintk("%s\n",__FUNCTION__); - kfree(state); -} - -static struct dvb_frontend_ops cx24123_ops; - -struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, - struct i2c_adapter* i2c) -{ - struct cx24123_state* state = NULL; - int ret; - - dprintk("%s\n",__FUNCTION__); - - /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct cx24123_state), GFP_KERNEL); - if (state == NULL) { - printk("Unable to kmalloc\n"); - goto error; - } - - /* setup the state */ - state->config = config; - state->i2c = i2c; - memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops)); - state->lastber = 0; - state->snr = 0; - state->lnbreg = 0; - state->VCAarg = 0; - state->VGAarg = 0; - state->bandselectarg = 0; - state->pllarg = 0; - state->currentfreq = 0; - state->currentsymbolrate = 0; - - /* check if the demod is there */ - ret = cx24123_readreg(state, 0x00); - if ((ret != 0xd1) && (ret != 0xe1)) { - printk("Version != d1 or e1\n"); - goto error; - } - - /* create dvb_frontend */ - state->frontend.ops = &state->ops; - state->frontend.demodulator_priv = state; - return &state->frontend; - -error: - kfree(state); - - return NULL; -} - -static struct dvb_frontend_ops cx24123_ops = { - - .info = { - .name = "Conexant CX24123/CX24109", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 1011, /* kHz for QPSK frontends */ - .frequency_tolerance = 29500, - .symbol_rate_min = 1000000, - .symbol_rate_max = 45000000, - .caps = FE_CAN_INVERSION_AUTO | - FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_RECOVER - }, - - .release = cx24123_release, - - .init = cx24123_initfe, - .set_frontend = cx24123_set_frontend, - .get_frontend = cx24123_get_frontend, - .read_status = cx24123_read_status, - .read_ber = cx24123_read_ber, - .read_signal_strength = cx24123_read_signal_strength, - .read_snr = cx24123_read_snr, - .read_ucblocks = cx24123_read_ucblocks, - .diseqc_send_master_cmd = cx24123_send_diseqc_msg, - .set_tone = cx24123_set_tone, - .set_voltage = cx24123_set_voltage, -}; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); - -MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24123/cx24109 hardware"); -MODULE_AUTHOR("Steven Toth"); -MODULE_LICENSE("GPL"); - -EXPORT_SYMBOL(cx24123_attach); diff --git a/trunk/drivers/media/dvb/frontends/cx24123.h b/trunk/drivers/media/dvb/frontends/cx24123.h deleted file mode 100644 index 0c922b5e9263..000000000000 --- a/trunk/drivers/media/dvb/frontends/cx24123.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Conexant cx24123/cx24109 - DVB QPSK Satellite demod/tuner driver - - Copyright (C) 2005 Steven Toth - - 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. -*/ - -#ifndef CX24123_H -#define CX24123_H - -#include - -struct cx24123_config -{ - /* the demodulator's i2c address */ - u8 demod_address; - - /* - cards like Hauppauge Nova-S Plus/Nova-SE2 use an Intersil ISL6421 chip - for LNB control, while KWorld DVB-S 100 use the LNBDC and LNBTone bits - from register 0x29 of the CX24123 demodulator - */ - int use_isl6421; - - /* PLL maintenance */ - int (*pll_init)(struct dvb_frontend* fe); - int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); - - /* Need to set device param for start_dma */ - int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); - - void (*enable_lnb_voltage)(struct dvb_frontend* fe, int on); -}; - -extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, - struct i2c_adapter* i2c); - -#endif /* CX24123_H */ diff --git a/trunk/drivers/media/dvb/frontends/dvb-pll.c b/trunk/drivers/media/dvb/frontends/dvb-pll.c index a3d57ce9dd12..f857b869616c 100644 --- a/trunk/drivers/media/dvb/frontends/dvb-pll.c +++ b/trunk/drivers/media/dvb/frontends/dvb-pll.c @@ -107,19 +107,18 @@ struct dvb_pll_desc dvb_pll_microtune_4042 = { }; EXPORT_SYMBOL(dvb_pll_microtune_4042); -struct dvb_pll_desc dvb_pll_thomson_dtt761x = { - /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ - .name = "Thomson dtt761x", - .min = 57000000, - .max = 863000000, +struct dvb_pll_desc dvb_pll_thomson_dtt7611 = { + .name = "Thomson dtt7611", + .min = 44000000, + .max = 958000000, .count = 3, .entries = { - { 147000000, 44000000, 62500, 0x8e, 0x39 }, - { 417000000, 44000000, 62500, 0x8e, 0x3a }, + { 157250000, 44000000, 62500, 0x8e, 0x39 }, + { 454000000, 44000000, 62500, 0x8e, 0x3a }, { 999999999, 44000000, 62500, 0x8e, 0x3c }, }, }; -EXPORT_SYMBOL(dvb_pll_thomson_dtt761x); +EXPORT_SYMBOL(dvb_pll_thomson_dtt7611); struct dvb_pll_desc dvb_pll_unknown_1 = { .name = "unknown 1", /* used by dntv live dvb-t */ diff --git a/trunk/drivers/media/dvb/frontends/dvb-pll.h b/trunk/drivers/media/dvb/frontends/dvb-pll.h index 24d4d2e9acd8..497d31dcf41e 100644 --- a/trunk/drivers/media/dvb/frontends/dvb-pll.h +++ b/trunk/drivers/media/dvb/frontends/dvb-pll.h @@ -25,7 +25,7 @@ extern struct dvb_pll_desc dvb_pll_thomson_dtt759x; extern struct dvb_pll_desc dvb_pll_thomson_dtt7610; extern struct dvb_pll_desc dvb_pll_lg_z201; extern struct dvb_pll_desc dvb_pll_microtune_4042; -extern struct dvb_pll_desc dvb_pll_thomson_dtt761x; +extern struct dvb_pll_desc dvb_pll_thomson_dtt7611; extern struct dvb_pll_desc dvb_pll_unknown_1; extern struct dvb_pll_desc dvb_pll_tua6010xs; diff --git a/trunk/drivers/media/dvb/frontends/lgdt330x.c b/trunk/drivers/media/dvb/frontends/lgdt330x.c index 9d214643b87a..cb5301865d07 100644 --- a/trunk/drivers/media/dvb/frontends/lgdt330x.c +++ b/trunk/drivers/media/dvb/frontends/lgdt330x.c @@ -27,7 +27,6 @@ * DViCO FusionHDTV 3 Gold-T * DViCO FusionHDTV 5 Gold * DViCO FusionHDTV 5 Lite - * DViCO FusionHDTV 5 USB Gold * Air2PC/AirStar 2 ATSC 3rd generation (HD5000) * * TODO: @@ -403,8 +402,6 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe, state->config->pll_set(fe, param); /* Keep track of the new frequency */ - /* FIXME this is the wrong way to do this... */ - /* The tuner is shared with the video4linux analog API */ state->current_frequency = param->frequency; lgdt330x_SwReset(state); diff --git a/trunk/drivers/media/dvb/frontends/mt312.c b/trunk/drivers/media/dvb/frontends/mt312.c index ec4e641acc64..8d672283c93d 100644 --- a/trunk/drivers/media/dvb/frontends/mt312.c +++ b/trunk/drivers/media/dvb/frontends/mt312.c @@ -501,8 +501,7 @@ static int mt312_set_frontend(struct dvb_frontend* fe, case ID_VP310: // For now we will do this only for the VP310. // It should be better for the mt312 as well, but tunning will be slower. ACCJr 09/29/03 - ret = mt312_readreg(state, CONFIG, &config_val); - if (ret < 0) + if ((ret = mt312_readreg(state, CONFIG, &config_val) < 0)) return ret; if (p->u.qpsk.symbol_rate >= 30000000) //Note that 30MS/s should use 90MHz { diff --git a/trunk/drivers/media/dvb/frontends/nxt2002.c b/trunk/drivers/media/dvb/frontends/nxt2002.c index 4f263e65ba14..52c416043a62 100644 --- a/trunk/drivers/media/dvb/frontends/nxt2002.c +++ b/trunk/drivers/media/dvb/frontends/nxt2002.c @@ -22,8 +22,7 @@ /* * This driver needs external firmware. Please use the command * "/Documentation/dvb/get_dvb_firmware nxt2002" to - * download/extract it, and then copy it to /usr/lib/hotplug/firmware - * or /lib/firmware (depending on configuration of firmware hotplug). + * download/extract it, and then copy it to /usr/lib/hotplug/firmware. */ #define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" #define CRC_CCIT_MASK 0x1021 diff --git a/trunk/drivers/media/dvb/frontends/nxt6000.c b/trunk/drivers/media/dvb/frontends/nxt6000.c index a16eeba0020d..a458a3bfff70 100644 --- a/trunk/drivers/media/dvb/frontends/nxt6000.c +++ b/trunk/drivers/media/dvb/frontends/nxt6000.c @@ -574,11 +574,11 @@ static struct dvb_frontend_ops nxt6000_ops = { .symbol_rate_max = 9360000, /* FIXME */ .symbol_rate_tolerance = 4000, .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | - FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | - FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO, + FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | + FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | + FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO, }, .release = nxt6000_release, diff --git a/trunk/drivers/media/dvb/frontends/or51211.c b/trunk/drivers/media/dvb/frontends/or51211.c index 7c3aed1f546b..531f76246e5f 100644 --- a/trunk/drivers/media/dvb/frontends/or51211.c +++ b/trunk/drivers/media/dvb/frontends/or51211.c @@ -25,8 +25,7 @@ /* * This driver needs external firmware. Please use the command * "/Documentation/dvb/get_dvb_firmware or51211" to - * download/extract it, and then copy it to /usr/lib/hotplug/firmware - * or /lib/firmware (depending on configuration of firmware hotplug). + * download/extract it, and then copy it to /usr/lib/hotplug/firmware. */ #define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw" @@ -113,7 +112,7 @@ static int or51211_load_firmware (struct dvb_frontend* fe, u8 tudata[585]; int i; - dprintk("Firmware is %zd bytes\n",fw->size); + dprintk("Firmware is %d bytes\n",fw->size); /* Get eprom data */ tudata[0] = 17; diff --git a/trunk/drivers/media/dvb/frontends/s5h1420.c b/trunk/drivers/media/dvb/frontends/s5h1420.c index d69477596921..18715091aed8 100644 --- a/trunk/drivers/media/dvb/frontends/s5h1420.c +++ b/trunk/drivers/media/dvb/frontends/s5h1420.c @@ -521,8 +521,8 @@ static void s5h1420_setfec_inversion(struct s5h1420_state* state, case FEC_3_4: s5h1420_writereg(state, 0x30, 0x04); - s5h1420_writereg(state, 0x31, 0x12 | inversion); - break; + s5h1420_writereg(state, 0x31, 0x12 | inversion); + break; case FEC_5_6: s5h1420_writereg(state, 0x30, 0x08); diff --git a/trunk/drivers/media/dvb/frontends/sp8870.c b/trunk/drivers/media/dvb/frontends/sp8870.c index 73829e647e50..fc06cd6b46c3 100644 --- a/trunk/drivers/media/dvb/frontends/sp8870.c +++ b/trunk/drivers/media/dvb/frontends/sp8870.c @@ -22,8 +22,7 @@ /* * This driver needs external firmware. Please use the command * "/Documentation/dvb/get_dvb_firmware alps_tdlb7" to - * download/extract it, and then copy it to /usr/lib/hotplug/firmware - * or /lib/firmware (depending on configuration of firmware hotplug). + * download/extract it, and then copy it to /usr/lib/hotplug/firmware. */ #define SP8870_DEFAULT_FIRMWARE "dvb-fe-sp8870.fw" diff --git a/trunk/drivers/media/dvb/frontends/sp887x.c b/trunk/drivers/media/dvb/frontends/sp887x.c index eb8a602198ca..e3b665782243 100644 --- a/trunk/drivers/media/dvb/frontends/sp887x.c +++ b/trunk/drivers/media/dvb/frontends/sp887x.c @@ -5,8 +5,7 @@ /* * This driver needs external firmware. Please use the command * "/Documentation/dvb/get_dvb_firmware sp887x" to - * download/extract it, and then copy it to /usr/lib/hotplug/firmware - * or /lib/firmware (depending on configuration of firmware hotplug). + * download/extract it, and then copy it to /usr/lib/hotplug/firmware. */ #define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw" @@ -582,7 +581,7 @@ static struct dvb_frontend_ops sp887x_ops = { .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | - FE_CAN_RECOVER + FE_CAN_RECOVER }, .release = sp887x_release, diff --git a/trunk/drivers/media/dvb/frontends/stv0299.c b/trunk/drivers/media/dvb/frontends/stv0299.c index 5bcd00f792e6..177d71d56b67 100644 --- a/trunk/drivers/media/dvb/frontends/stv0299.c +++ b/trunk/drivers/media/dvb/frontends/stv0299.c @@ -131,13 +131,6 @@ static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len return ret == 2 ? 0 : ret; } -int stv0299_enable_plli2c (struct dvb_frontend* fe) -{ - struct stv0299_state* state = fe->demodulator_priv; - - return stv0299_writeregI(state, 0x05, 0xb5); /* enable i2c repeater on stv0299 */ -} - static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec) { dprintk ("%s\n", __FUNCTION__); @@ -394,7 +387,7 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag }; } -static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd) +static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) { struct stv0299_state* state = fe->demodulator_priv; u8 reg0x08; @@ -414,7 +407,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd = cmd << 1; if (debug_legacy_dish_switch) - printk ("%s switch command: 0x%04lx\n",__FUNCTION__, cmd); + printk ("%s switch command: 0x%04x\n",__FUNCTION__, cmd); do_gettimeofday (&nexttime); if (debug_legacy_dish_switch) @@ -724,6 +717,5 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " "Andreas Oberritter, Andrew de Quincey, Kenneth Aafløy"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(stv0299_enable_plli2c); EXPORT_SYMBOL(stv0299_writereg); EXPORT_SYMBOL(stv0299_attach); diff --git a/trunk/drivers/media/dvb/frontends/stv0299.h b/trunk/drivers/media/dvb/frontends/stv0299.h index 32c87b4c2f13..9af3d71c89db 100644 --- a/trunk/drivers/media/dvb/frontends/stv0299.h +++ b/trunk/drivers/media/dvb/frontends/stv0299.h @@ -94,7 +94,6 @@ struct stv0299_config }; extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); -extern int stv0299_enable_plli2c (struct dvb_frontend* fe); extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, struct i2c_adapter* i2c); diff --git a/trunk/drivers/media/dvb/frontends/tda10021.c b/trunk/drivers/media/dvb/frontends/tda10021.c index 21255cac9793..425cd19136fe 100644 --- a/trunk/drivers/media/dvb/frontends/tda10021.c +++ b/trunk/drivers/media/dvb/frontends/tda10021.c @@ -95,7 +95,7 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) u8 b0 [] = { reg }; u8 b1 [] = { 0 }; struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 }, - { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; + { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; int ret; ret = i2c_transfer (state->i2c, msg, 2); @@ -434,7 +434,7 @@ static struct dvb_frontend_ops tda10021_ops = { .frequency_max = 858000000, .symbol_rate_min = (XIN/2)/64, /* SACLK/64 == (XIN/2)/64 */ .symbol_rate_max = (XIN/2)/4, /* SACLK/4 */ -#if 0 + #if 0 .frequency_tolerance = ???, .symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */ #endif diff --git a/trunk/drivers/media/dvb/frontends/tda1004x.c b/trunk/drivers/media/dvb/frontends/tda1004x.c index c63e9a5084eb..dd02aff467fe 100644 --- a/trunk/drivers/media/dvb/frontends/tda1004x.c +++ b/trunk/drivers/media/dvb/frontends/tda1004x.c @@ -23,8 +23,7 @@ * This driver needs external firmware. Please use the commands * "/Documentation/dvb/get_dvb_firmware tda10045", * "/Documentation/dvb/get_dvb_firmware tda10046" to - * download/extract them, and then copy them to /usr/lib/hotplug/firmware - * or /lib/firmware (depending on configuration of firmware hotplug). + * download/extract them, and then copy them to /usr/lib/hotplug/firmware. */ #define TDA10045_DEFAULT_FIRMWARE "dvb-fe-tda10045.fw" #define TDA10046_DEFAULT_FIRMWARE "dvb-fe-tda10046.fw" @@ -272,57 +271,32 @@ static int tda10045h_set_bandwidth(struct tda1004x_state *state, static int tda10046h_set_bandwidth(struct tda1004x_state *state, fe_bandwidth_t bandwidth) { - static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 }; - static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f }; - static u8 bandwidth_8mhz_53M[] = { 0x5c, 0x32, 0xc2, 0x96, 0x6d }; - - static u8 bandwidth_6mhz_48M[] = { 0x70, 0x02, 0x49, 0x24, 0x92 }; - static u8 bandwidth_7mhz_48M[] = { 0x60, 0x02, 0xaa, 0xaa, 0xab }; - static u8 bandwidth_8mhz_48M[] = { 0x54, 0x03, 0x0c, 0x30, 0xc3 }; - int tda10046_clk53m; - - if ((state->config->if_freq == TDA10046_FREQ_045) || - (state->config->if_freq == TDA10046_FREQ_052)) - tda10046_clk53m = 0; - else - tda10046_clk53m = 1; + static u8 bandwidth_6mhz[] = { 0x80, 0x15, 0xfe, 0xab, 0x8e }; + static u8 bandwidth_7mhz[] = { 0x6e, 0x02, 0x53, 0xc8, 0x25 }; + static u8 bandwidth_8mhz[] = { 0x60, 0x12, 0xa8, 0xe4, 0xbd }; + switch (bandwidth) { case BANDWIDTH_6_MHZ: - if (tda10046_clk53m) - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_53M, - sizeof(bandwidth_6mhz_53M)); - else - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz_48M, - sizeof(bandwidth_6mhz_48M)); + tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_6mhz, sizeof(bandwidth_6mhz)); if (state->config->if_freq == TDA10046_FREQ_045) { - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xab); + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x09); + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x4f); } break; case BANDWIDTH_7_MHZ: - if (tda10046_clk53m) - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_53M, - sizeof(bandwidth_7mhz_53M)); - else - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz_48M, - sizeof(bandwidth_7mhz_48M)); + tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_7mhz, sizeof(bandwidth_7mhz)); if (state->config->if_freq == TDA10046_FREQ_045) { - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00); + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0a); + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x79); } break; case BANDWIDTH_8_MHZ: - if (tda10046_clk53m) - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_53M, - sizeof(bandwidth_8mhz_53M)); - else - tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz_48M, - sizeof(bandwidth_8mhz_48M)); + tda1004x_write_buf(state, TDA10046H_TIME_WREF1, bandwidth_8mhz, sizeof(bandwidth_8mhz)); if (state->config->if_freq == TDA10046_FREQ_045) { - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x55); + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b); + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3); } break; @@ -444,22 +418,9 @@ static int tda10045_fwupload(struct dvb_frontend* fe) static void tda10046_init_plls(struct dvb_frontend* fe) { struct tda1004x_state* state = fe->demodulator_priv; - int tda10046_clk53m; - - if ((state->config->if_freq == TDA10046_FREQ_045) || - (state->config->if_freq == TDA10046_FREQ_052)) - tda10046_clk53m = 0; - else - tda10046_clk53m = 1; tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0); - if(tda10046_clk53m) { - printk(KERN_INFO "tda1004x: setting up plls for 53MHz sampling clock\n"); - tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x08); // PLL M = 8 - } else { - printk(KERN_INFO "tda1004x: setting up plls for 48MHz sampling clock\n"); - tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3 - } + tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x0a); // PLL M = 10 if (state->config->xtal_freq == TDA10046_XTAL_4M ) { dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__); tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 @@ -467,32 +428,26 @@ static void tda10046_init_plls(struct dvb_frontend* fe) dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__); tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3 } - if(tda10046_clk53m) - tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x67); - else - tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 0x72); - /* Note clock frequency is handled implicitly */ + tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); switch (state->config->if_freq) { - case TDA10046_FREQ_045: - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x00); - break; - case TDA10046_FREQ_052: - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0d); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xc7); - break; case TDA10046_FREQ_3617: - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x59); + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); break; case TDA10046_FREQ_3613: - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd7); - tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x3f); + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x13); + break; + case TDA10046_FREQ_045: + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b); + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xa3); + break; + case TDA10046_FREQ_052: + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0c); + tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x06); break; } tda10046h_set_bandwidth(state, BANDWIDTH_8_MHZ); // default bandwidth 8 MHz - /* let the PLLs settle */ - msleep(120); } static int tda10046_fwupload(struct dvb_frontend* fe) @@ -507,13 +462,13 @@ static int tda10046_fwupload(struct dvb_frontend* fe) /* let the clocks recover from sleep */ msleep(5); - /* The PLLs need to be reprogrammed after sleep */ - tda10046_init_plls(fe); - /* don't re-upload unless necessary */ if (tda1004x_check_upload_ok(state) == 0) return 0; + /* set parameters */ + tda10046_init_plls(fe); + if (state->config->request_firmware != NULL) { /* request the firmware, this will block until someone uploads it */ printk(KERN_INFO "tda1004x: waiting for firmware upload...\n"); @@ -529,6 +484,7 @@ static int tda10046_fwupload(struct dvb_frontend* fe) return ret; } else { /* boot from firmware eeprom */ + /* Hac Note: we might need to do some GPIO Magic here */ printk(KERN_INFO "tda1004x: booting from eeprom\n"); tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4); msleep(300); @@ -650,9 +606,10 @@ static int tda10046_init(struct dvb_frontend* fe) // tda setup tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer - tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream - tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer + tda1004x_write_byteI(state, TDA1004X_AUTO, 7); // select HP stream + tda1004x_write_byteI(state, TDA1004X_CONFC1, 8); // disable pulse killer + tda10046_init_plls(fe); switch (state->config->agc_config) { case TDA10046_AGC_DEFAULT: tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x00); // AGC setup @@ -669,22 +626,25 @@ static int tda10046_init(struct dvb_frontend* fe) case TDA10046_AGC_TDA827X: tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x02); // AGC setup tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // AGC Threshold - tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize - tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x6a); // set AGC polarities + tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x0E); // Gain Renormalize + tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x60); // set AGC polarities break; } - tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38); tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x61); // Turn both AGC outputs on tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // } tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // } tda1004x_write_byteI(state, TDA10046H_AGC_IF_MAX, 0xff); // } - tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 0x12); // IF gain 2, TUN gain 1 + tda1004x_write_byteI(state, TDA10046H_AGC_GAINS, 1); // IF gain 2, TUN gain 1 tda1004x_write_byteI(state, TDA10046H_CVBER_CTRL, 0x1a); // 10^6 VBER measurement bits tda1004x_write_byteI(state, TDA1004X_CONF_TS1, 7); // MPEG2 interface config tda1004x_write_byteI(state, TDA1004X_CONF_TS2, 0xc0); // MPEG2 interface config tda1004x_write_mask(state, 0x3a, 0x80, state->config->invert_oclk << 7); + tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0xe1); // tristate setup + tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcc); // GPIO output config + tda1004x_write_byteI(state, TDA10046H_GPIO_SELECT, 8); // GPIO select + state->initialised = 1; return 0; } @@ -726,9 +686,9 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, // Set standard params.. or put them to auto if ((fe_params->u.ofdm.code_rate_HP == FEC_AUTO) || - (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) || - (fe_params->u.ofdm.constellation == QAM_AUTO) || - (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) { + (fe_params->u.ofdm.code_rate_LP == FEC_AUTO) || + (fe_params->u.ofdm.constellation == QAM_AUTO) || + (fe_params->u.ofdm.hierarchy_information == HIERARCHY_AUTO)) { tda1004x_write_mask(state, TDA1004X_AUTO, 1, 1); // enable auto tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x03, 0); // turn off constellation bits tda1004x_write_mask(state, TDA1004X_IN_CONF1, 0x60, 0); // turn off hierarchy bits @@ -891,7 +851,6 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) { struct tda1004x_state* state = fe->demodulator_priv; - dprintk("%s\n", __FUNCTION__); // inversion status @@ -916,18 +875,16 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete break; } break; + case TDA1004X_DEMOD_TDA10046: switch (tda1004x_read_byte(state, TDA10046H_TIME_WREF1)) { - case 0x5c: - case 0x54: + case 0x60: fe_params->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; break; - case 0x6a: - case 0x60: + case 0x6e: fe_params->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; break; - case 0x7b: - case 0x70: + case 0x80: fe_params->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; break; } diff --git a/trunk/drivers/media/dvb/pluto2/Kconfig b/trunk/drivers/media/dvb/pluto2/Kconfig index 84f8f9f52869..f02842be0d60 100644 --- a/trunk/drivers/media/dvb/pluto2/Kconfig +++ b/trunk/drivers/media/dvb/pluto2/Kconfig @@ -8,7 +8,7 @@ config DVB_PLUTO2 Support for PCI cards based on the Pluto2 FPGA like the Satelco Easywatch Mobile Terrestrial DVB-T Receiver. - Since these cards have no MPEG decoder onboard, they transmit + Since these cards have no MPEG decoder onboard, they transmit only compressed MPEG data over the PCI bus, so you need an external software decoder to watch TV on your computer. diff --git a/trunk/drivers/media/dvb/ttpci/Kconfig b/trunk/drivers/media/dvb/ttpci/Kconfig index 5b2aadb8385c..fa5034a9ecf5 100644 --- a/trunk/drivers/media/dvb/ttpci/Kconfig +++ b/trunk/drivers/media/dvb/ttpci/Kconfig @@ -18,10 +18,9 @@ config DVB_AV7110 This driver only supports the fullfeatured cards with onboard MPEG2 decoder. - This driver needs an external firmware. Please use the script - "/Documentation/dvb/get_dvb_firmware av7110" to - download/extract it, and then copy it to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). + This driver needs an external firmware. Please use the script + "/Documentation/dvb/get_dvb_firmware av7110" to + download/extract it, and then copy it to /usr/lib/hotplug/firmware. Say Y if you own such a card and want to use it. diff --git a/trunk/drivers/media/dvb/ttpci/Makefile b/trunk/drivers/media/dvb/ttpci/Makefile index a690730ac39d..825ab1c38a4f 100644 --- a/trunk/drivers/media/dvb/ttpci/Makefile +++ b/trunk/drivers/media/dvb/ttpci/Makefile @@ -16,7 +16,7 @@ EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ hostprogs-y := fdump ifdef CONFIG_DVB_AV7110_FIRMWARE -$(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h +$(obj)/av7110.o: $(obj)/fdump $(obj)/av7110_firm.h $(obj)/av7110_firm.h: $(obj)/fdump $(CONFIG_DVB_AV7110_FIRMWARE_FILE) dvb_ttpci_fw $@ diff --git a/trunk/drivers/media/dvb/ttpci/av7110.c b/trunk/drivers/media/dvb/ttpci/av7110.c index 8ce4146f55f1..7dae91e5863c 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110.c +++ b/trunk/drivers/media/dvb/ttpci/av7110.c @@ -133,13 +133,7 @@ static void init_av7110_av(struct av7110 *av7110) /* remaining inits according to card and frontend type */ av7110->analog_tuner_flags = 0; av7110->current_input = 0; - if (dev->pci->subsystem_vendor == 0x13c2 && dev->pci->subsystem_device == 0x000a) { - printk("dvb-ttpci: MSP3415 audio DAC @ card %d\n", - av7110->dvb_adapter.num); - av7110->adac_type = DVB_ADAC_MSP34x5; - av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 0); // SPDIF on - } - else if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { + if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", av7110->dvb_adapter.num); av7110->adac_type = DVB_ADAC_CRYSTAL; @@ -162,10 +156,10 @@ static void init_av7110_av(struct av7110 *av7110) else { av7110->adac_type = adac; printk("dvb-ttpci: adac type set to %d @ card %d\n", - av7110->adac_type, av7110->dvb_adapter.num); + av7110->dvb_adapter.num, av7110->adac_type); } - if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP34x0) { + if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { // switch DVB SCART on ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); if (ret < 0) @@ -196,17 +190,19 @@ static void recover_arm(struct av7110 *av7110) av7110_bootarm(av7110); msleep(100); - - init_av7110_av(av7110); - - /* card-specific recovery */ - if (av7110->recover) - av7110->recover(av7110); - restart_feeds(av7110); av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config); } +static void arm_error(struct av7110 *av7110) +{ + dprintk(4, "%p\n",av7110); + + av7110->arm_errors++; + av7110->arm_ready = 0; + recover_arm(av7110); +} + static void av7110_arm_sync(struct av7110 *av7110) { av7110->arm_rmmod = 1; @@ -244,22 +240,26 @@ static int arm_thread(void *data) if (down_interruptible(&av7110->dcomlock)) break; + newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2); up(&av7110->dcomlock); - if (newloops == av7110->arm_loops || av7110->arm_errors > 3) { + if (newloops == av7110->arm_loops) { printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", av7110->dvb_adapter.num); - recover_arm(av7110); + arm_error(av7110); + av7710_set_video_mode(av7110, vidmode); + + init_av7110_av(av7110); if (down_interruptible(&av7110->dcomlock)) break; + newloops = rdebi(av7110, DEBINOSWAP, STATUS_LOOPS, 0, 2) - 1; up(&av7110->dcomlock); } av7110->arm_loops = newloops; - av7110->arm_errors = 0; } av7110->arm_thread = NULL; @@ -510,6 +510,10 @@ static void gpioirq(unsigned long data) iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2); av7110->video_size.h = h_ar & 0xfff; + dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n", + av7110->video_size.w, + av7110->video_size.h, + av7110->video_size.aspect_ratio); event.type = VIDEO_EVENT_SIZE_CHANGED; event.u.size.w = av7110->video_size.w; @@ -531,11 +535,6 @@ static void gpioirq(unsigned long data) event.u.size.aspect_ratio = VIDEO_FORMAT_4_3; av7110->videostate.video_format = VIDEO_FORMAT_4_3; } - - dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n", - av7110->video_size.w, av7110->video_size.h, - av7110->video_size.aspect_ratio); - dvb_video_add_event(av7110, &event); break; } @@ -715,8 +714,6 @@ static struct dvb_device dvbdev_osd = { static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, u16 subpid, u16 pcrpid) { - u16 aflags = 0; - dprintk(4, "%p\n", av7110); if (vpid == 0x1fff || apid == 0x1fff || @@ -728,11 +725,8 @@ static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, av7110->pids[DMX_PES_PCR] = 0; } - if (av7110->audiostate.bypass_mode) - aflags |= 0x8000; - - return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 6, - pcrpid, vpid, apid, ttpid, subpid, aflags); + return av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, MultiPID, 5, + pcrpid, vpid, apid, ttpid, subpid); } int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, @@ -1049,7 +1043,7 @@ static void restart_feeds(struct av7110 *av7110) struct dvb_demux *dvbdmx = &av7110->demux; struct dvb_demux_feed *feed; int mode; - int i, j; + int i; dprintk(4, "%p\n", av7110); @@ -1057,21 +1051,10 @@ static void restart_feeds(struct av7110 *av7110) av7110->playing = 0; av7110->rec_mode = 0; - for (i = 0; i < dvbdmx->feednum; i++) { + for (i = 0; i < dvbdmx->filternum; i++) { feed = &dvbdmx->feed[i]; - if (feed->state == DMX_STATE_GO) { - if (feed->type == DMX_TYPE_SEC) { - for (j = 0; j < dvbdmx->filternum; j++) { - if (dvbdmx->filter[j].type != DMX_TYPE_SEC) - continue; - if (dvbdmx->filter[j].filter.parent != &feed->feed.sec) - continue; - if (dvbdmx->filter[j].state == DMX_STATE_GO) - dvbdmx->filter[j].state = DMX_STATE_READY; - } - } + if (feed->state == DMX_STATE_GO) av7110_start_feed(feed); - } } if (mode) @@ -1500,9 +1483,9 @@ static int get_firmware(struct av7110* av7110) if (ret == -ENOENT) { printk(KERN_ERR "dvb-ttpci: could not load firmware," " file not found: dvb-ttpci-01.fw\n"); - printk(KERN_ERR "dvb-ttpci: usually this should be in " - "/usr/lib/hotplug/firmware or /lib/firmware\n"); - printk(KERN_ERR "dvb-ttpci: and can be downloaded from" + printk(KERN_ERR "dvb-ttpci: usually this should be in" + " /usr/lib/hotplug/firmware\n"); + printk(KERN_ERR "dvb-ttpci: and can be downloaded here" " http://www.linuxtv.org/download/dvb/firmware/\n"); } else printk(KERN_ERR "dvb-ttpci: cannot request firmware" @@ -2127,10 +2110,8 @@ static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_p struct av7110* av7110 = fe->dvb->priv; int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) { - av7110->saved_fe_params = *params; + if (!ret) ret = av7110->fe_set_frontend(fe, params); - } return ret; } @@ -2172,10 +2153,8 @@ static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, struct av7110* av7110 = fe->dvb->priv; int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) { - av7110->saved_master_cmd = *cmd; + if (!ret) ret = av7110->fe_diseqc_send_master_cmd(fe, cmd); - } return ret; } @@ -2184,10 +2163,8 @@ static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_ struct av7110* av7110 = fe->dvb->priv; int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) { - av7110->saved_minicmd = minicmd; + if (!ret) ret = av7110->fe_diseqc_send_burst(fe, minicmd); - } return ret; } @@ -2196,10 +2173,8 @@ static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) struct av7110* av7110 = fe->dvb->priv; int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) { - av7110->saved_tone = tone; + if (!ret) ret = av7110->fe_set_tone(fe, tone); - } return ret; } @@ -2208,14 +2183,12 @@ static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t volta struct av7110* av7110 = fe->dvb->priv; int ret = av7110_fe_lock_fix(av7110, 0); - if (!ret) { - av7110->saved_voltage = voltage; + if (!ret) ret = av7110->fe_set_voltage(fe, voltage); - } return ret; } -static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned long cmd) +static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd) { struct av7110* av7110 = fe->dvb->priv; @@ -2225,23 +2198,6 @@ static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, un return ret; } -static void dvb_s_recover(struct av7110* av7110) -{ - av7110_fe_init(av7110->fe); - - av7110_fe_set_voltage(av7110->fe, av7110->saved_voltage); - if (av7110->saved_master_cmd.msg_len) { - msleep(20); - av7110_fe_diseqc_send_master_cmd(av7110->fe, &av7110->saved_master_cmd); - } - msleep(20); - av7110_fe_diseqc_send_burst(av7110->fe, av7110->saved_minicmd); - msleep(20); - av7110_fe_set_tone(av7110->fe, av7110->saved_tone); - - av7110_fe_set_frontend(av7110->fe, &av7110->saved_fe_params); -} - static u8 read_pwm(struct av7110* av7110) { u8 b = 0xff; @@ -2279,7 +2235,6 @@ static int frontend_init(struct av7110 *av7110) av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; av7110->fe->ops->set_tone = av7110_set_tone; - av7110->recover = dvb_s_recover; break; } @@ -2289,17 +2244,15 @@ static int frontend_init(struct av7110 *av7110) av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; av7110->fe->ops->set_tone = av7110_set_tone; - av7110->recover = dvb_s_recover; break; } // Try the grundig 29504-451 - av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); + av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); if (av7110->fe) { av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; av7110->fe->ops->set_tone = av7110_set_tone; - av7110->recover = dvb_s_recover; break; } @@ -2321,12 +2274,12 @@ static int frontend_init(struct av7110 *av7110) case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X // ALPS TDLB7 - av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); + av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); break; case 0x0002: // Hauppauge/TT DVB-C premium rev2.X - av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); + av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); break; case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */ @@ -2336,7 +2289,6 @@ static int frontend_init(struct av7110 *av7110) av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; av7110->fe->ops->set_tone = av7110_set_tone; - av7110->recover = dvb_s_recover; } break; @@ -2362,11 +2314,8 @@ static int frontend_init(struct av7110 *av7110) case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */ /* ALPS BSBE1 */ av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); - if (av7110->fe) { + if (av7110->fe) av7110->fe->ops->set_voltage = lnbp21_set_voltage; - av7110->fe->ops->dishnetwork_send_legacy_command = NULL; - av7110->recover = dvb_s_recover; - } break; } } diff --git a/trunk/drivers/media/dvb/ttpci/av7110.h b/trunk/drivers/media/dvb/ttpci/av7110.h index 6ea30df2e823..cce00ef293e9 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110.h +++ b/trunk/drivers/media/dvb/ttpci/av7110.h @@ -98,8 +98,7 @@ struct av7110 { int adac_type; /* audio DAC type */ #define DVB_ADAC_TI 0 #define DVB_ADAC_CRYSTAL 1 -#define DVB_ADAC_MSP34x0 2 -#define DVB_ADAC_MSP34x5 3 +#define DVB_ADAC_MSP 2 #define DVB_ADAC_NONE -1 @@ -229,9 +228,6 @@ struct av7110 { struct dvb_video_events video_events; video_size_t video_size; - u16 wssMode; - u16 wssData; - u32 ir_config; u32 ir_command; void (*ir_handler)(struct av7110 *av7110, u32 ircom); @@ -249,15 +245,6 @@ struct av7110 { struct dvb_frontend* fe; fe_status_t fe_status; - - /* crash recovery */ - void (*recover)(struct av7110* av7110); - struct dvb_frontend_parameters saved_fe_params; - fe_sec_voltage_t saved_voltage; - fe_sec_tone_mode_t saved_tone; - struct dvb_diseqc_master_cmd saved_master_cmd; - fe_sec_mini_cmd_t saved_minicmd; - int (*fe_init)(struct dvb_frontend* fe); int (*fe_read_status)(struct dvb_frontend* fe, fe_status_t* status); int (*fe_diseqc_reset_overload)(struct dvb_frontend* fe); @@ -265,7 +252,7 @@ struct av7110 { int (*fe_diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); - int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); + int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd); int (*fe_set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); }; diff --git a/trunk/drivers/media/dvb/ttpci/av7110_av.c b/trunk/drivers/media/dvb/ttpci/av7110_av.c index 400facec7407..0696a5a4f855 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_av.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_av.c @@ -309,7 +309,7 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright) i2c_writereg(av7110, 0x20, 0x04, volright); return 0; - case DVB_ADAC_MSP34x0: + case DVB_ADAC_MSP: vol = (volleft > volright) ? volleft : volright; val = (vol * 0x73 / 255) << 8; if (vol > 0) @@ -1256,9 +1256,7 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, break; case AUDIO_SET_BYPASS_MODE: - if (FW_VERSION(av7110->arm_app) < 0x2621) - ret = -EINVAL; - av7110->audiostate.bypass_mode = (int)arg; + ret = -EINVAL; break; case AUDIO_CHANNEL_SELECT: @@ -1297,11 +1295,7 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, break; case AUDIO_GET_CAPABILITIES: - if (FW_VERSION(av7110->arm_app) < 0x2621) - *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; - else - *(unsigned int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_DTS | AUDIO_CAP_AC3 | - AUDIO_CAP_MP1 | AUDIO_CAP_MP2; + *(int *)parg = AUDIO_CAP_LPCM | AUDIO_CAP_MP1 | AUDIO_CAP_MP2; break; case AUDIO_CLEAR_BUFFER: diff --git a/trunk/drivers/media/dvb/ttpci/av7110_hw.c b/trunk/drivers/media/dvb/ttpci/av7110_hw.c index cb377452b57d..87106e8bf35b 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_hw.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_hw.c @@ -230,8 +230,6 @@ int av7110_bootarm(struct av7110 *av7110) dprintk(4, "%p\n", av7110); - av7110->arm_ready = 0; - saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); /* Disable DEBI and GPIO irq */ @@ -363,7 +361,6 @@ static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) break; if (err) { printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for COMMAND idle\n", __FUNCTION__); - av7110->arm_errors++; return -ETIMEDOUT; } msleep(1); @@ -1209,9 +1206,9 @@ int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap) switch (cap->cmd) { case OSD_CAP_MEMSIZE: if (FW_4M_SDRAM(av7110->arm_app)) - cap->val = 1000000; + cap->val = 1000000; else - cap->val = 92000; + cap->val = 92000; return 0; default: return -EINVAL; diff --git a/trunk/drivers/media/dvb/ttpci/av7110_hw.h b/trunk/drivers/media/dvb/ttpci/av7110_hw.h index 84b83299b8be..2a5e87ba1052 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_hw.h +++ b/trunk/drivers/media/dvb/ttpci/av7110_hw.h @@ -167,8 +167,7 @@ enum av7110_encoder_command { LoadVidCode, SetMonitorType, SetPanScanType, - SetFreezeMode, - SetWSSConfig + SetFreezeMode }; enum av7110_rec_play_state { diff --git a/trunk/drivers/media/dvb/ttpci/av7110_ir.c b/trunk/drivers/media/dvb/ttpci/av7110_ir.c index 9138132ad25f..f5e59fc924af 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_ir.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_ir.c @@ -17,8 +17,6 @@ static int av_cnt; static struct av7110 *av_list[4]; static struct input_dev *input_dev; -static u8 delay_timer_finished; - static u16 key_map [256] = { KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_BACK, 0, KEY_POWER, KEY_MUTE, 0, KEY_INFO, @@ -114,16 +112,13 @@ static void av7110_emit_key(unsigned long parm) if (timer_pending(&keyup_timer)) { del_timer(&keyup_timer); if (keyup_timer.data != keycode || new_toggle != old_toggle) { - delay_timer_finished = 0; input_event(input_dev, EV_KEY, keyup_timer.data, !!0); input_event(input_dev, EV_KEY, keycode, !0); } else - if (delay_timer_finished) - input_event(input_dev, EV_KEY, keycode, 2); - } else { - delay_timer_finished = 0; + input_event(input_dev, EV_KEY, keycode, 2); + + } else input_event(input_dev, EV_KEY, keycode, !0); - } keyup_timer.expires = jiffies + UP_TIMEOUT; keyup_timer.data = keycode; @@ -150,8 +145,7 @@ static void input_register_keys(void) static void input_repeat_key(unsigned long data) { - /* called by the input driver after rep[REP_DELAY] ms */ - delay_timer_finished = 1; + /* dummy routine to disable autorepeat in the input driver */ } diff --git a/trunk/drivers/media/dvb/ttpci/av7110_v4l.c b/trunk/drivers/media/dvb/ttpci/av7110_v4l.c index 94cf38c7e8a8..b5aea4129fa7 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_v4l.c @@ -490,58 +490,6 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); break; } - case VIDIOC_G_SLICED_VBI_CAP: - { - struct v4l2_sliced_vbi_cap *cap = arg; - dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n"); - memset(cap, 0, sizeof *cap); - if (FW_VERSION(av7110->arm_app) >= 0x2623) { - cap->service_set = V4L2_SLICED_WSS_625; - cap->service_lines[0][23] = V4L2_SLICED_WSS_625; - } - break; - } - case VIDIOC_G_FMT: - { - struct v4l2_format *f = arg; - dprintk(2, "VIDIOC_G_FMT:\n"); - if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT || - FW_VERSION(av7110->arm_app) < 0x2623) - return -EAGAIN; /* handled by core driver */ - memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); - if (av7110->wssMode) { - f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; - f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; - f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data); - } - break; - } - case VIDIOC_S_FMT: - { - struct v4l2_format *f = arg; - dprintk(2, "VIDIOC_S_FMT\n"); - if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT || - FW_VERSION(av7110->arm_app) < 0x2623) - return -EAGAIN; /* handled by core driver */ - if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 && - f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) { - memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); - /* WSS controlled by firmware */ - av7110->wssMode = 0; - av7110->wssData = 0; - return av7110_fw_cmd(av7110, COMTYPE_ENCODER, - SetWSSConfig, 1, 0); - } else { - memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced); - f->fmt.sliced.service_set = V4L2_SLICED_WSS_625; - f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625; - f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data); - /* WSS controlled by userspace */ - av7110->wssMode = 1; - av7110->wssData = 0; - } - break; - } default: printk("no such ioctl\n"); return -ENOIOCTLCMD; @@ -549,46 +497,6 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) return 0; } -static int av7110_vbi_reset(struct inode *inode, struct file *file) -{ - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - struct av7110 *av7110 = (struct av7110*) dev->ext_priv; - - dprintk(2, "%s\n", __FUNCTION__); - av7110->wssMode = 0; - av7110->wssData = 0; - if (FW_VERSION(av7110->arm_app) < 0x2623) - return 0; - else - return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0); -} - -static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos) -{ - struct saa7146_fh *fh = file->private_data; - struct saa7146_dev *dev = fh->dev; - struct av7110 *av7110 = (struct av7110*) dev->ext_priv; - struct v4l2_sliced_vbi_data d; - int rc; - - dprintk(2, "%s\n", __FUNCTION__); - if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d) - return -EINVAL; - if (copy_from_user(&d, data, count)) - return -EFAULT; - if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23) - return -EINVAL; - if (d.id) { - av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0]; - rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, - 2, 1, av7110->wssData); - } else { - av7110->wssData = 0; - rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0); - } - return (rc < 0) ? rc : count; -} /**************************************************************************** * INITIALIZATION @@ -604,9 +512,6 @@ static struct saa7146_extension_ioctls ioctls[] = { { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE }, { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, - { VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE }, - { VIDIOC_G_FMT, SAA7146_BEFORE }, - { VIDIOC_S_FMT, SAA7146_BEFORE }, { 0, 0 } }; @@ -682,7 +587,7 @@ int av7110_init_analog_module(struct av7110 *av7110) printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n", av7110->dvb_adapter.num); - av7110->adac_type = DVB_ADAC_MSP34x0; + av7110->adac_type = DVB_ADAC_MSP; msleep(100); // the probing above resets the msp... msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); @@ -787,11 +692,12 @@ int av7110_init_v4l(struct av7110 *av7110) saa7146_vv_release(dev); return -ENODEV; } - if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { - ERR(("cannot register vbi v4l2 device. skipping.\n")); - } else { - if (av7110->analog_tuner_flags) + if (av7110->analog_tuner_flags) { + if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { + ERR(("cannot register vbi v4l2 device. skipping.\n")); + } else { av7110->analog_tuner_flags |= ANALOG_TUNER_VBI; + } } return 0; } @@ -872,7 +778,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) static struct saa7146_ext_vv av7110_vv_data_st = { .inputs = 1, .audios = 1, - .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT, + .capabilities = 0, .flags = 0, .stds = &standard[0], @@ -881,16 +787,12 @@ static struct saa7146_ext_vv av7110_vv_data_st = { .ioctls = &ioctls[0], .ioctl = av7110_ioctl, - - .vbi_fops.open = av7110_vbi_reset, - .vbi_fops.release = av7110_vbi_reset, - .vbi_fops.write = av7110_vbi_write, }; static struct saa7146_ext_vv av7110_vv_data_c = { .inputs = 1, .audios = 1, - .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT, + .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE, .flags = SAA7146_USE_PORT_B_FOR_VBI, .stds = &standard[0], @@ -899,9 +801,5 @@ static struct saa7146_ext_vv av7110_vv_data_c = { .ioctls = &ioctls[0], .ioctl = av7110_ioctl, - - .vbi_fops.open = av7110_vbi_reset, - .vbi_fops.release = av7110_vbi_reset, - .vbi_fops.write = av7110_vbi_write, }; diff --git a/trunk/drivers/media/dvb/ttpci/budget-av.c b/trunk/drivers/media/dvb/ttpci/budget-av.c index f9d00452e639..9f51bae7194c 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-av.c +++ b/trunk/drivers/media/dvb/ttpci/budget-av.c @@ -127,7 +127,7 @@ static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int ad saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); udelay(1); - result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1); + result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 0); if (result == -ETIMEDOUT) budget_av->slot_status = 0; @@ -145,7 +145,7 @@ static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int a saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI); udelay(1); - result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1); + result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 0); if (result == -ETIMEDOUT) budget_av->slot_status = 0; @@ -192,7 +192,7 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) { struct budget_av *budget_av = (struct budget_av *) ca->data; struct saa7146_dev *saa = budget_av->budget.dev; - int timeout = 50; // 5 seconds (4.4.6 Ready) + int timeout = 500; // 5 seconds (4.4.6 Ready) if (slot != 0) return -EINVAL; @@ -256,37 +256,19 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open { struct budget_av *budget_av = (struct budget_av *) ca->data; struct saa7146_dev *saa = budget_av->budget.dev; - int cam_present = 0; if (slot != 0) return -EINVAL; - if (!budget_av->slot_status) - { - // first of all test the card detect line + if (!budget_av->slot_status) { saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); udelay(1); if (saa7146_read(saa, PSR) & MASK_06) { - cam_present = 1; - } - saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); - - // that is unreliable however, so try and read from IO memory - if (!cam_present) - { - saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); - if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) != -ETIMEDOUT) - { - cam_present = 1; - } - } - - // did we find something? - if (cam_present) { printk(KERN_INFO "budget-av: cam inserted\n"); budget_av->slot_status = 1; } + saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); } else if (!open) { saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT) @@ -502,140 +484,6 @@ static int philips_su1278_ty_ci_pll_set(struct dvb_frontend *fe, return 0; } -#define MIN2(a,b) ((a) < (b) ? (a) : (b)) -#define MIN3(a,b,c) MIN2(MIN2(a,b),c) - -static int philips_su1278sh2_tua6100_pll_set(struct dvb_frontend *fe, - struct i2c_adapter *i2c, - struct dvb_frontend_parameters *params) -{ - u8 reg0 [2] = { 0x00, 0x00 }; - u8 reg1 [4] = { 0x01, 0x00, 0x00, 0x00 }; - u8 reg2 [3] = { 0x02, 0x00, 0x00 }; - int _fband; - int first_ZF; - int R, A, N, P, M; - struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = NULL,.len = 0 }; - int freq = params->frequency; - - first_ZF = (freq) / 1000; - - if (abs(MIN2(abs(first_ZF-1190),abs(first_ZF-1790))) < - abs(MIN3(abs(first_ZF-1202),abs(first_ZF-1542),abs(first_ZF-1890)))) - _fband = 2; - else - _fband = 3; - - if (_fband == 2) { - if (((first_ZF >= 950) && (first_ZF < 1350)) || - ((first_ZF >= 1430) && (first_ZF < 1950))) - reg0[1] = 0x07; - else if (((first_ZF >= 1350) && (first_ZF < 1430)) || - ((first_ZF >= 1950) && (first_ZF < 2150))) - reg0[1] = 0x0B; - } - - if(_fband == 3) { - if (((first_ZF >= 950) && (first_ZF < 1350)) || - ((first_ZF >= 1455) && (first_ZF < 1950))) - reg0[1] = 0x07; - else if (((first_ZF >= 1350) && (first_ZF < 1420)) || - ((first_ZF >= 1950) && (first_ZF < 2150))) - reg0[1] = 0x0B; - else if ((first_ZF >= 1420) && (first_ZF < 1455)) - reg0[1] = 0x0F; - } - - if (first_ZF > 1525) - reg1[1] |= 0x80; - else - reg1[1] &= 0x7F; - - if (_fband == 2) { - if (first_ZF > 1430) { /* 1430MHZ */ - reg1[1] &= 0xCF; /* N2 */ - reg2[1] &= 0xCF; /* R2 */ - reg2[1] |= 0x10; - } else { - reg1[1] &= 0xCF; /* N2 */ - reg1[1] |= 0x20; - reg2[1] &= 0xCF; /* R2 */ - reg2[1] |= 0x10; - } - } - - if (_fband == 3) { - if ((first_ZF >= 1455) && - (first_ZF < 1630)) { - reg1[1] &= 0xCF; /* N2 */ - reg1[1] |= 0x20; - reg2[1] &= 0xCF; /* R2 */ - } else { - if (first_ZF < 1455) { - reg1[1] &= 0xCF; /* N2 */ - reg1[1] |= 0x20; - reg2[1] &= 0xCF; /* R2 */ - reg2[1] |= 0x10; - } else { - if (first_ZF >= 1630) { - reg1[1] &= 0xCF; /* N2 */ - reg2[1] &= 0xCF; /* R2 */ - reg2[1] |= 0x10; - } - } - } - } - - /* set ports, enable P0 for symbol rates > 4Ms/s */ - if (params->u.qpsk.symbol_rate >= 4000000) - reg1[1] |= 0x0c; - else - reg1[1] |= 0x04; - - reg2[1] |= 0x0c; - - R = 64; - A = 64; - P = 64; //32 - - M = (freq * R) / 4; /* in Mhz */ - N = (M - A * 1000) / (P * 1000); - - reg1[1] |= (N >> 9) & 0x03; - reg1[2] = (N >> 1) & 0xff; - reg1[3] = (N << 7) & 0x80; - - reg2[1] |= (R >> 8) & 0x03; - reg2[2] = R & 0xFF; /* R */ - - reg1[3] |= A & 0x7f; /* A */ - - if (P == 64) - reg1[1] |= 0x40; /* Prescaler 64/65 */ - - reg0[1] |= 0x03; - - /* already enabled - do not reenable i2c repeater or TX fails */ - msg.buf = reg0; - msg.len = sizeof(reg0); - if (i2c_transfer(i2c, &msg, 1) != 1) - return -EIO; - - stv0299_enable_plli2c(fe); - msg.buf = reg1; - msg.len = sizeof(reg1); - if (i2c_transfer(i2c, &msg, 1) != 1) - return -EIO; - - stv0299_enable_plli2c(fe); - msg.buf = reg2; - msg.len = sizeof(reg2); - if (i2c_transfer(i2c, &msg, 1) != 1) - return -EIO; - - return 0; -} - static u8 typhoon_cinergy1200s_inittab[] = { 0x01, 0x15, 0x02, 0x30, @@ -705,18 +553,6 @@ static struct stv0299_config cinergy_1200s_config = { .pll_set = philips_su1278_ty_ci_pll_set, }; -static struct stv0299_config cinergy_1200s_1894_0010_config = { - .demod_address = 0x68, - .inittab = typhoon_cinergy1200s_inittab, - .mclk = 88000000UL, - .invert = 1, - .skip_reinit = 0, - .lock_output = STV0229_LOCKOUTPUT_1, - .volt13_op0_op1 = STV0299_VOLT13_OP0, - .min_delay_ms = 100, - .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate, - .pll_set = philips_su1278sh2_tua6100_pll_set, -}; static int philips_cu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { @@ -913,15 +749,6 @@ static void frontend_init(struct budget_av *budget_av) switch (saa->pci->subsystem_device) { case SUBID_DVBS_KNC1: - if (saa->pci->subsystem_vendor == 0x1894) { - fe = stv0299_attach(&cinergy_1200s_1894_0010_config, - &budget_av->budget.i2c_adap); - } else { - fe = stv0299_attach(&typhoon_config, - &budget_av->budget.i2c_adap); - } - break; - case SUBID_DVBS_KNC1_PLUS: case SUBID_DVBS_TYPHOON: fe = stv0299_attach(&typhoon_config, @@ -1176,7 +1003,6 @@ MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T); static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56), MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010), - MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010), MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), diff --git a/trunk/drivers/media/dvb/ttpci/budget-core.c b/trunk/drivers/media/dvb/ttpci/budget-core.c index 633e68c341c8..017fcbccb8cc 100644 --- a/trunk/drivers/media/dvb/ttpci/budget-core.c +++ b/trunk/drivers/media/dvb/ttpci/budget-core.c @@ -404,7 +404,9 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, tasklet_init(&budget->vpe_tasklet, vpeirq, (unsigned long) budget); /* frontend power on */ - if (bi->type != BUDGET_FS_ACTIVY) + if (bi->type == BUDGET_FS_ACTIVY) + saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); + else saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); if (budget_register(budget) == 0) { diff --git a/trunk/drivers/media/dvb/ttpci/budget.c b/trunk/drivers/media/dvb/ttpci/budget.c index 238c77b52f89..fafe6407b3d0 100644 --- a/trunk/drivers/media/dvb/ttpci/budget.c +++ b/trunk/drivers/media/dvb/ttpci/budget.c @@ -112,7 +112,6 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long * Routines for the Fujitsu Siemens Activy budget card * 22 kHz tone and DiSEqC are handled by the frontend. * Voltage must be set here. - * GPIO 1: LNBP EN, GPIO 2: LNBP VSEL */ static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) { @@ -122,16 +121,11 @@ static int SetVoltage_Activy (struct budget *budget, fe_sec_voltage_t voltage) switch (voltage) { case SEC_VOLTAGE_13: - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTLO); break; case SEC_VOLTAGE_18: - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI); break; - case SEC_VOLTAGE_OFF: - saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); - break; default: return -EINVAL; } @@ -212,7 +206,7 @@ static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) return 0; } -static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, long arg) +static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend* fe, int arg) { struct budget* budget = (struct budget*) fe->dvb->priv; u8 buf; @@ -586,7 +580,6 @@ static void frontend_init(struct budget *budget) if (budget->dvb_frontend) { budget->dvb_frontend->ops->set_voltage = lnbp21_set_voltage; budget->dvb_frontend->ops->enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; - budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; if (lnbp21_init(budget)) { printk("%s: No LNBP21 found!\n", __FUNCTION__); goto error_out; @@ -631,7 +624,7 @@ static void frontend_init(struct budget *budget) budget->dvb_frontend = stv0299_attach(&alps_bsru6_config, &budget->i2c_adap); if (budget->dvb_frontend) { budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; - budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; + break; } break; @@ -639,7 +632,7 @@ static void frontend_init(struct budget *budget) budget->dvb_frontend = tda8083_attach(&grundig_29504_451_config, &budget->i2c_adap); if (budget->dvb_frontend) { budget->dvb_frontend->ops->set_voltage = siemens_budget_set_voltage; - budget->dvb_frontend->ops->dishnetwork_send_legacy_command = NULL; + break; } break; diff --git a/trunk/drivers/media/dvb/ttpci/ttpci-eeprom.c b/trunk/drivers/media/dvb/ttpci/ttpci-eeprom.c index 1f31e91195b0..18aa22b5478d 100644 --- a/trunk/drivers/media/dvb/ttpci/ttpci-eeprom.c +++ b/trunk/drivers/media/dvb/ttpci/ttpci-eeprom.c @@ -13,7 +13,7 @@ Holger Waechtler Convergence Copyright (C) 2002-2003 Ralph Metzler - Metzler Brothers Systementwicklung GbR + Metzler Brothers Systementwicklung GbR 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 diff --git a/trunk/drivers/media/dvb/ttusb-budget/Kconfig b/trunk/drivers/media/dvb/ttusb-budget/Kconfig index 914587d52b57..c6c1d41a2efb 100644 --- a/trunk/drivers/media/dvb/ttusb-budget/Kconfig +++ b/trunk/drivers/media/dvb/ttusb-budget/Kconfig @@ -10,7 +10,7 @@ config DVB_TTUSB_BUDGET Support for external USB adapters designed by Technotrend and produced by Hauppauge, shipped under the brand name 'Nova-USB'. - These devices don't have a MPEG decoder built in, so you need + These devices don't have a MPEG decoder built in, so you need an external software decoder to watch TV. Say Y if you own such a device and want to use it. diff --git a/trunk/drivers/media/dvb/ttusb-dec/Kconfig b/trunk/drivers/media/dvb/ttusb-dec/Kconfig index 83611012ef34..c334526af66f 100644 --- a/trunk/drivers/media/dvb/ttusb-dec/Kconfig +++ b/trunk/drivers/media/dvb/ttusb-dec/Kconfig @@ -8,15 +8,14 @@ config DVB_TTUSB_DEC produced by Hauppauge, shipped under the brand name 'DEC2000-t' and 'DEC3000-s'. - Even if these devices have a MPEG decoder built in, they transmit + Even if these devices have a MPEG decoder built in, they transmit only compressed MPEG data over the USB bus, so you need an external software decoder to watch TV on your computer. - This driver needs external firmware. Please use the commands - "/Documentation/dvb/get_dvb_firmware dec2000t", - "/Documentation/dvb/get_dvb_firmware dec2540t", - "/Documentation/dvb/get_dvb_firmware dec3000s", - download/extract them, and then copy them to /usr/lib/hotplug/firmware - or /lib/firmware (depending on configuration of firmware hotplug). + This driver needs external firmware. Please use the commands + "/Documentation/dvb/get_dvb_firmware dec2000t", + "/Documentation/dvb/get_dvb_firmware dec2540t", + "/Documentation/dvb/get_dvb_firmware dec3000s", + download/extract them, and then copy them to /usr/lib/hotplug/firmware. Say Y if you own such a device and want to use it. diff --git a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c index d8966d1d25ee..8abc21890129 100644 --- a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -369,7 +369,7 @@ static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) { - struct ttusb_dec *dec = priv; + struct ttusb_dec *dec = (struct ttusb_dec *)priv; dec->audio_filter->feed->cb.ts(data, 188, NULL, 0, &dec->audio_filter->feed->feed.ts, @@ -380,7 +380,7 @@ static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data) { - struct ttusb_dec *dec = priv; + struct ttusb_dec *dec = (struct ttusb_dec *)priv; dec->video_filter->feed->cb.ts(data, 188, NULL, 0, &dec->video_filter->feed->feed.ts, @@ -965,8 +965,8 @@ static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed) case DMX_TS_PES_TELETEXT: dec->pid[DMX_PES_TELETEXT] = dvbdmxfeed->pid; - dprintk(" pes_type: DMX_TS_PES_TELETEXT(not supported)\n"); - return -ENOSYS; + dprintk(" pes_type: DMX_TS_PES_TELETEXT\n"); + break; case DMX_TS_PES_PCR: dprintk(" pes_type: DMX_TS_PES_PCR\n"); @@ -975,8 +975,8 @@ static int ttusb_dec_start_ts_feed(struct dvb_demux_feed *dvbdmxfeed) break; case DMX_TS_PES_OTHER: - dprintk(" pes_type: DMX_TS_PES_OTHER(not supported)\n"); - return -ENOSYS; + dprintk(" pes_type: DMX_TS_PES_OTHER\n"); + break; default: dprintk(" pes_type: unknown (%d)\n", dvbdmxfeed->pes_type); @@ -1182,7 +1182,7 @@ static void ttusb_dec_init_tasklet(struct ttusb_dec *dec) (unsigned long)dec); } -static int ttusb_init_rc( struct ttusb_dec *dec) +static int ttusb_init_rc(struct ttusb_dec *dec) { struct input_dev *input_dev; u8 b[] = { 0x00, 0x01 }; @@ -1203,12 +1203,13 @@ static int ttusb_init_rc( struct ttusb_dec *dec) input_dev->keycode = rc_keys; for (i = 0; i < ARRAY_SIZE(rc_keys); i++) - set_bit(rc_keys[i], input_dev->keybit); + set_bit(rc_keys[i], input_dev->keybit); input_register_device(input_dev); if (usb_submit_urb(dec->irq_urb, GFP_KERNEL)) printk("%s: usb_submit_urb failed\n",__FUNCTION__); + /* enable irq pipe */ ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL); @@ -1394,7 +1395,6 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) /* We can't trust the USB IDs that some firmwares give the box */ switch (model) { - case 0x00070001: case 0x00070008: case 0x0007000c: ttusb_dec_set_model(dec, TTUSB_DEC3000S); @@ -1588,7 +1588,7 @@ static int fe_send_command(struct dvb_frontend* fe, const u8 command, int param_length, const u8 params[], int *result_length, u8 cmd_result[]) { - struct ttusb_dec* dec = fe->dvb->priv; + struct ttusb_dec* dec = (struct ttusb_dec*) fe->dvb->priv; return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result); } diff --git a/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c index a5a46175fa09..725af3af5b27 100644 --- a/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c +++ b/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c @@ -42,39 +42,8 @@ struct ttusbdecfe_state { static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status) { - struct ttusbdecfe_state* state = fe->demodulator_priv; - u8 b[] = { 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }; - u8 result[4]; - int len, ret; - - *status=0; - - ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result); - if(ret) - return ret; - - if(len != 4) { - printk(KERN_ERR "%s: unexpected reply\n", __FUNCTION__); - return -EIO; - } - - switch(result[3]) { - case 1: /* not tuned yet */ - case 2: /* no signal/no lock*/ - break; - case 3: /* signal found and locked*/ - *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | - FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; - break; - case 4: - *status = FE_TIMEDOUT; - break; - default: - pr_info("%s: returned unknown value: %d\n", - __FUNCTION__, result[3]); - return -EIO; - } + *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | + FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; return 0; } @@ -95,16 +64,6 @@ static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_fron return 0; } -static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe, - struct dvb_frontend_tune_settings* fesettings) -{ - fesettings->min_delay_ms = 1500; - /* Drift compensation makes no sense for DVB-T */ - fesettings->step_size = 0; - fesettings->max_drift = 0; - return 0; -} - static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; @@ -253,8 +212,6 @@ static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = { .set_frontend = ttusbdecfe_dvbt_set_frontend, - .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings, - .read_status = ttusbdecfe_read_status, }; @@ -266,11 +223,11 @@ static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = { .frequency_min = 950000, .frequency_max = 2150000, .frequency_stepsize = 125, - .symbol_rate_min = 1000000, /* guessed */ - .symbol_rate_max = 45000000, /* guessed */ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | - FE_CAN_QPSK + FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO, }, .release = ttusbdecfe_release, diff --git a/trunk/drivers/media/radio/miropcm20-radio.c b/trunk/drivers/media/radio/miropcm20-radio.c index dc292da2605f..c2ebe8754a95 100644 --- a/trunk/drivers/media/radio/miropcm20-radio.c +++ b/trunk/drivers/media/radio/miropcm20-radio.c @@ -220,7 +220,6 @@ static struct file_operations pcm20_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = pcm20_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/radio/radio-aimslab.c b/trunk/drivers/media/radio/radio-aimslab.c index 914deab4e044..877c770558e9 100644 --- a/trunk/drivers/media/radio/radio-aimslab.c +++ b/trunk/drivers/media/radio/radio-aimslab.c @@ -299,7 +299,6 @@ static struct file_operations rtrack_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = rt_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/radio/radio-aztech.c b/trunk/drivers/media/radio/radio-aztech.c index 523be820f9c6..5319a9c9a979 100644 --- a/trunk/drivers/media/radio/radio-aztech.c +++ b/trunk/drivers/media/radio/radio-aztech.c @@ -256,7 +256,6 @@ static struct file_operations aztech_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = az_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/radio/radio-cadet.c b/trunk/drivers/media/radio/radio-cadet.c index f1b5ac81e9d2..9b0406318f2d 100644 --- a/trunk/drivers/media/radio/radio-cadet.c +++ b/trunk/drivers/media/radio/radio-cadet.c @@ -490,7 +490,6 @@ static struct file_operations cadet_fops = { .release = cadet_release, .read = cadet_read, .ioctl = cadet_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/radio/radio-gemtek-pci.c b/trunk/drivers/media/radio/radio-gemtek-pci.c index 42c8fce04aa2..630cc786d0a4 100644 --- a/trunk/drivers/media/radio/radio-gemtek-pci.c +++ b/trunk/drivers/media/radio/radio-gemtek-pci.c @@ -301,7 +301,6 @@ static struct file_operations gemtek_pci_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = gemtek_pci_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/radio/radio-gemtek.c b/trunk/drivers/media/radio/radio-gemtek.c index 47173be97b9f..6418f03b9ce4 100644 --- a/trunk/drivers/media/radio/radio-gemtek.c +++ b/trunk/drivers/media/radio/radio-gemtek.c @@ -233,7 +233,6 @@ static struct file_operations gemtek_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = gemtek_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/radio/radio-maestro.c b/trunk/drivers/media/radio/radio-maestro.c index c30effdf711f..e5e2021a7312 100644 --- a/trunk/drivers/media/radio/radio-maestro.c +++ b/trunk/drivers/media/radio/radio-maestro.c @@ -72,7 +72,6 @@ static struct file_operations maestro_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = radio_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/radio/radio-maxiradio.c b/trunk/drivers/media/radio/radio-maxiradio.c index 30869308332a..02d39a50d5ed 100644 --- a/trunk/drivers/media/radio/radio-maxiradio.c +++ b/trunk/drivers/media/radio/radio-maxiradio.c @@ -80,7 +80,6 @@ static struct file_operations maxiradio_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = radio_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; static struct video_device maxiradio_radio = diff --git a/trunk/drivers/media/radio/radio-rtrack2.c b/trunk/drivers/media/radio/radio-rtrack2.c index 28a47c9e7a81..b2256d675b44 100644 --- a/trunk/drivers/media/radio/radio-rtrack2.c +++ b/trunk/drivers/media/radio/radio-rtrack2.c @@ -199,7 +199,6 @@ static struct file_operations rtrack2_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = rt_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/radio/radio-sf16fmi.c b/trunk/drivers/media/radio/radio-sf16fmi.c index 0229f792a059..6f03ce4dd7b0 100644 --- a/trunk/drivers/media/radio/radio-sf16fmi.c +++ b/trunk/drivers/media/radio/radio-sf16fmi.c @@ -225,7 +225,6 @@ static struct file_operations fmi_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = fmi_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/radio/radio-sf16fmr2.c b/trunk/drivers/media/radio/radio-sf16fmr2.c index 26632cead09a..71971e9bb342 100644 --- a/trunk/drivers/media/radio/radio-sf16fmr2.c +++ b/trunk/drivers/media/radio/radio-sf16fmr2.c @@ -356,7 +356,6 @@ static struct file_operations fmr2_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = fmr2_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/radio/radio-terratec.c b/trunk/drivers/media/radio/radio-terratec.c index fcfde2e4f195..b03573c6840e 100644 --- a/trunk/drivers/media/radio/radio-terratec.c +++ b/trunk/drivers/media/radio/radio-terratec.c @@ -276,7 +276,6 @@ static struct file_operations terratec_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = tt_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/radio/radio-trust.c b/trunk/drivers/media/radio/radio-trust.c index 5a099a50d4d0..b300bedf7c74 100644 --- a/trunk/drivers/media/radio/radio-trust.c +++ b/trunk/drivers/media/radio/radio-trust.c @@ -255,7 +255,6 @@ static struct file_operations trust_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = tr_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/radio/radio-typhoon.c b/trunk/drivers/media/radio/radio-typhoon.c index 8ac9a8ef9094..f304f3c14763 100644 --- a/trunk/drivers/media/radio/radio-typhoon.c +++ b/trunk/drivers/media/radio/radio-typhoon.c @@ -261,7 +261,6 @@ static struct file_operations typhoon_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = typhoon_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/radio/radio-zoltrix.c b/trunk/drivers/media/radio/radio-zoltrix.c index d590e80c922e..4c6d6fb49034 100644 --- a/trunk/drivers/media/radio/radio-zoltrix.c +++ b/trunk/drivers/media/radio/radio-zoltrix.c @@ -313,7 +313,6 @@ static struct file_operations zoltrix_fops = .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = zol_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index 2fe260fff85d..fc87efc5049c 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -7,15 +7,6 @@ menu "Video For Linux" comment "Video Adapters" -config VIDEO_ADV_DEBUG - bool "Enable advanced debug functionality" - depends on VIDEO_DEV - default n - ---help--- - Say Y here to enable advanced debugging functionality on some - V4L devices. - In doubt, say N. - config VIDEO_BT848 tristate "BT848 Video For Linux" depends on VIDEO_DEV && PCI && I2C @@ -351,6 +342,6 @@ config VIDEO_DECODER depends on VIDEO_DEV && I2C && EXPERIMENTAL ---help--- Say Y here to compile drivers for SAA7115, SAA7127 and CX25840 - video decoders. + video decoders. endmenu diff --git a/trunk/drivers/media/video/Makefile b/trunk/drivers/media/video/Makefile index dd24896906fe..82060f9909d8 100644 --- a/trunk/drivers/media/video/Makefile +++ b/trunk/drivers/media/video/Makefile @@ -3,19 +3,15 @@ # bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ - bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \ - bttv-input.o + bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o zr36067-objs := zoran_procfs.o zoran_device.o \ zoran_driver.o zoran_card.o tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o - -msp3400-objs := msp3400-driver.o msp3400-kthreads.o - -obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o compat_ioctl32.o +obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ - tda7432.o tda9875.o ir-kbd-i2c.o + tda7432.o tda9875.o ir-kbd-i2c.o ir-kbd-gpio.o obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o obj-$(CONFIG_VIDEO_ZR36120) += zoran.o diff --git a/trunk/drivers/media/video/arv.c b/trunk/drivers/media/video/arv.c index 7d5a068353f2..881cdcb1875d 100644 --- a/trunk/drivers/media/video/arv.c +++ b/trunk/drivers/media/video/arv.c @@ -749,7 +749,6 @@ static struct file_operations ar_fops = { .release = video_exclusive_release, .read = ar_read, .ioctl = ar_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/video/bt832.c b/trunk/drivers/media/video/bt832.c index dda4aa6bef27..1c3ff5f38a6d 100644 --- a/trunk/drivers/media/video/bt832.c +++ b/trunk/drivers/media/video/bt832.c @@ -30,9 +30,8 @@ #include #include #include -#include -#include +#include #include "bttv.h" #include "bt832.h" @@ -43,11 +42,10 @@ static unsigned short normal_i2c[] = { I2C_BT832_ALT1>>1, I2C_BT832_ALT2>>1, I2C_CLIENT_END }; I2C_CLIENT_INSMOD; -int debug = 0; /* debug output */ -module_param(debug, int, 0644); - /* ---------------------------------------------------------------------- */ +#define dprintk if (debug) printk + static int bt832_detach(struct i2c_client *client); @@ -63,26 +61,23 @@ int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf) int i,rc; buf[0]=0x80; // start at register 0 with auto-increment if (1 != (rc = i2c_master_send(i2c_client_s,buf,1))) - v4l_err(i2c_client_s,"i2c i/o error: rc == %d (should be 1)\n",rc); + printk("bt832: i2c i/o error: rc == %d (should be 1)\n",rc); for(i=0;i<65;i++) buf[i]=0; if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65))) - v4l_err(i2c_client_s,"i2c i/o error: rc == %d (should be 65)\n",rc); + printk("bt832: i2c i/o error: rc == %d (should be 65)\n",rc); // Note: On READ the first byte is the current index // (e.g. 0x80, what we just wrote) - if(debug>1) { + if(1) { int i; - v4l_dbg(2,i2c_client_s,"hexdump:"); + printk("BT832 hexdump:\n"); for(i=1;i<65;i++) { if(i!=1) { - if(((i-1)%8)==0) printk(" "); - if(((i-1)%16)==0) { - printk("\n"); - v4l_dbg(2,i2c_client_s,"hexdump:"); - } + if(((i-1)%8)==0) printk(" "); + if(((i-1)%16)==0) printk("\n"); } printk(" %02x",buf[i]); } @@ -101,56 +96,56 @@ int bt832_init(struct i2c_client *i2c_client_s) bt832_hexdump(i2c_client_s,buf); if(buf[0x40] != 0x31) { - v4l_err(i2c_client_s,"This i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]); + printk("bt832: this i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]); kfree(buf); return 0; } - v4l_err(i2c_client_s,"Write 0 tp VPSTATUS\n"); + printk("Write 0 tp VPSTATUS\n"); buf[0]=BT832_VP_STATUS; // Reg.52 buf[1]= 0x00; if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) - v4l_err(i2c_client_s,"i2c i/o error VPS: rc == %d (should be 2)\n",rc); + printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); bt832_hexdump(i2c_client_s,buf); // Leave low power mode: - v4l_err(i2c_client_s,"leave low power mode.\n"); + printk("Bt832: leave low power mode.\n"); buf[0]=BT832_CAM_SETUP0; //0x39 57 buf[1]=0x08; if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) - v4l_err(i2c_client_s,"i2c i/o error LLPM: rc == %d (should be 2)\n",rc); + printk("bt832: i2c i/o error LLPM: rc == %d (should be 2)\n",rc); bt832_hexdump(i2c_client_s,buf); - v4l_info(i2c_client_s,"Write 0 tp VPSTATUS\n"); + printk("Write 0 tp VPSTATUS\n"); buf[0]=BT832_VP_STATUS; // Reg.52 buf[1]= 0x00; if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) - v4l_err(i2c_client_s,"i2c i/o error VPS: rc == %d (should be 2)\n",rc); + printk("bt832: i2c i/o error VPS: rc == %d (should be 2)\n",rc); bt832_hexdump(i2c_client_s,buf); // Enable Output - v4l_info(i2c_client_s,"Enable Output\n"); + printk("Enable Output\n"); buf[0]=BT832_VP_CONTROL1; // Reg.40 buf[1]= 0x27 & (~0x01); // Default | !skip if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) - v4l_err(i2c_client_s,"i2c i/o error EO: rc == %d (should be 2)\n",rc); + printk("bt832: i2c i/o error EO: rc == %d (should be 2)\n",rc); bt832_hexdump(i2c_client_s,buf); // for testing (even works when no camera attached) - v4l_info(i2c_client_s,"*** Generate NTSC M Bars *****\n"); + printk("bt832: *** Generate NTSC M Bars *****\n"); buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally if (2 != (rc = i2c_master_send(i2c_client_s,buf,2))) - v4l_info(i2c_client_s,"i2c i/o error MBAR: rc == %d (should be 2)\n",rc); + printk("bt832: i2c i/o error MBAR: rc == %d (should be 2)\n",rc); - v4l_info(i2c_client_s,"Camera Present: %s\n", + printk("Bt832: Camera Present: %s\n", (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no"); bt832_hexdump(i2c_client_s,buf); @@ -164,9 +159,13 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind) { struct bt832 *t; + printk("bt832_attach\n"); + client_template.adapter = adap; client_template.addr = addr; + printk("bt832: chip found @ 0x%x\n", addr<<1); + if (NULL == (t = kmalloc(sizeof(*t), GFP_KERNEL))) return -ENOMEM; memset(t,0,sizeof(*t)); @@ -174,9 +173,6 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind) i2c_set_clientdata(&t->client, t); i2c_attach_client(&t->client); - v4l_info(&t->client,"chip found @ 0x%x\n", addr<<1); - - if(! bt832_init(&t->client)) { bt832_detach(&t->client); return -1; @@ -187,8 +183,13 @@ static int bt832_attach(struct i2c_adapter *adap, int addr, int kind) static int bt832_probe(struct i2c_adapter *adap) { +#ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, bt832_attach); +#else + if (adap->id == I2C_HW_B_BT848) + return i2c_probe(adap, &addr_data, bt832_attach); +#endif return 0; } @@ -196,7 +197,7 @@ static int bt832_detach(struct i2c_client *client) { struct bt832 *t = i2c_get_clientdata(client); - v4l_info(&t->client,"dettach\n"); + printk("bt832: detach.\n"); i2c_detach_client(client); kfree(t); return 0; @@ -207,8 +208,7 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct bt832 *t = i2c_get_clientdata(client); - if (debug>1) - v4l_i2c_print_ioctl(&t->client,cmd); + printk("bt832: command %x\n",cmd); switch (cmd) { case BT832_HEXDUMP: { @@ -219,7 +219,7 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg) } break; case BT832_REATTACH: - v4l_info(&t->client,"re-attach\n"); + printk("bt832: re-attach\n"); i2c_del_driver(&driver); i2c_add_driver(&driver); break; @@ -231,9 +231,9 @@ bt832_command(struct i2c_client *client, unsigned int cmd, void *arg) static struct i2c_driver driver = { .driver = { - .name = "bt832", + .name = "i2c bt832 driver", }, - .id = 0, /* FIXME */ + .id = -1, /* FIXME */ .attach_adapter = bt832_probe, .detach_client = bt832_detach, .command = bt832_command, diff --git a/trunk/drivers/media/video/bttv-cards.c b/trunk/drivers/media/video/bttv-cards.c index 1621ab133d23..012be639aa18 100644 --- a/trunk/drivers/media/video/bttv-cards.c +++ b/trunk/drivers/media/video/bttv-cards.c @@ -38,7 +38,6 @@ #include #include "bttvp.h" -#include /* fwd decl */ static void boot_msp34xx(struct bttv *btv, int pin); @@ -293,9 +292,6 @@ static struct CARD { /* likely broken, vendor id doesn't match the other magic views ... * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */ - /* Duplicate PCI ID, reconfigure for this board during the eeprom read. - * { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB, "Hauppauge ImpactVCB" }, */ - /* DVB cards (using pci function .1 for mpeg data xfer) */ { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, @@ -2140,6 +2136,7 @@ struct tvcard bttv_tvcards[] = { .has_remote = 1, .gpiomask = 0x1b, .no_gpioirq = 1, + .any_irq = 1, }, [BTTV_BOARD_PV143] = { /* Jorge Boncompte - DTI2 */ @@ -2820,22 +2817,6 @@ struct tvcard bttv_tvcards[] = { .tuner_addr = ADDR_UNSET, .has_radio = 1, }, - /* ---- card 0x8f ---------------------------------- */ - [BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = { - .name = "Hauppauge ImpactVCB (bt878)", - .video_inputs = 4, - .audio_inputs = 0, - .tuner = -1, - .svhs = -1, - .gpiomask = 0x0f, /* old: 7 */ - .muxsel = { 0, 1, 3, 2}, /* Composite 0-3 */ - .no_msp34xx = 1, - .no_tda9875 = 1, - .no_tda7432 = 1, - .tuner_type = -1, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - }, }; static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards); @@ -3056,33 +3037,26 @@ static void miro_pinnacle_gpio(struct bttv *btv) switch (id) { case 1: info = "PAL / mono"; - btv->tda9887_conf = TDA9887_INTERCARRIER; break; case 2: info = "PAL+SECAM / stereo"; btv->has_radio = 1; - btv->tda9887_conf = TDA9887_QSS; break; case 3: info = "NTSC / stereo"; btv->has_radio = 1; - btv->tda9887_conf = TDA9887_QSS; break; case 4: info = "PAL+SECAM / mono"; - btv->tda9887_conf = TDA9887_QSS; break; case 5: info = "NTSC / mono"; - btv->tda9887_conf = TDA9887_INTERCARRIER; break; case 6: info = "NTSC / stereo"; - btv->tda9887_conf = TDA9887_INTERCARRIER; break; case 7: info = "PAL / stereo"; - btv->tda9887_conf = TDA9887_INTERCARRIER; break; default: info = "oops: unknown card"; @@ -3093,7 +3067,8 @@ static void miro_pinnacle_gpio(struct bttv *btv) printk(KERN_INFO "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n", btv->c.nr, id, info, btv->has_radio ? "yes" : "no"); - btv->tuner_type = TUNER_MT2032; + btv->tuner_type = 33; + btv->pinnacle_id = id; } } @@ -3395,9 +3370,9 @@ void __devinit bttv_init_card2(struct bttv *btv) bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup); } - if (btv->tda9887_conf) { - bttv_call_i2c_clients(btv, TDA9887_SET_CONFIG, - &btv->tda9887_conf); + if (btv->pinnacle_id != UNSET) { + bttv_call_i2c_clients(btv, AUDC_CONFIG_PINNACLE, + &btv->pinnacle_id); } btv->svhs = bttv_tvcards[btv->c.type].svhs; @@ -3412,6 +3387,8 @@ void __devinit bttv_init_card2(struct bttv *btv) btv->has_remote=1; if (!bttv_tvcards[btv->c.type].no_gpioirq) btv->gpioirq=1; + if (bttv_tvcards[btv->c.type].any_irq) + btv->any_irq = 1; if (bttv_tvcards[btv->c.type].audio_hook) btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook; @@ -3447,7 +3424,7 @@ void __devinit bttv_init_card2(struct bttv *btv) /* tuner modules */ tda9887 = 0; - if (btv->tda9887_conf) + if (btv->pinnacle_id != UNSET) tda9887 = 1; if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb && bttv_I2CRead(btv, I2C_TDA9887, "TDA9887") >=0) @@ -3494,21 +3471,6 @@ static void __devinit hauppauge_eeprom(struct bttv *btv) tveeprom_hauppauge_analog(&btv->i2c_client, &tv, eeprom_data); btv->tuner_type = tv.tuner_type; btv->has_radio = tv.has_radio; - - printk("bttv%d: Hauppauge eeprom indicates model#%d\n", - btv->c.nr, tv.model); - - /* - * Some of the 878 boards have duplicate PCI IDs. Switch the board - * type based on model #. - */ - if(tv.model == 64900) { - printk("bttv%d: Switching board type from %s to %s\n", - btv->c.nr, - bttv_tvcards[btv->c.type].name, - bttv_tvcards[BTTV_BOARD_HAUPPAUGE_IMPACTVCB].name); - btv->c.type = BTTV_BOARD_HAUPPAUGE_IMPACTVCB; - } } static int terratec_active_radio_upgrade(struct bttv *btv) diff --git a/trunk/drivers/media/video/bttv-driver.c b/trunk/drivers/media/video/bttv-driver.c index 0e6970346788..1ddf9ba613ef 100644 --- a/trunk/drivers/media/video/bttv-driver.c +++ b/trunk/drivers/media/video/bttv-driver.c @@ -34,14 +34,13 @@ #include #include #include -#include "bttvp.h" -#include - #include #include #include +#include "bttvp.h" + #include "rds.h" @@ -211,9 +210,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { .vdelay = 0x20, .vbipack = 255, .sram = 0, - /* ITU-R frame line number of the first VBI line - we can capture, of the first and second field. */ - .vbistart = { 7,320 }, },{ .v4l2_id = V4L2_STD_NTSC_M, .name = "NTSC", @@ -230,7 +226,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { .vdelay = 0x1a, .vbipack = 144, .sram = 1, - .vbistart = { 10, 273 }, },{ .v4l2_id = V4L2_STD_SECAM, .name = "SECAM", @@ -247,7 +242,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { .vdelay = 0x20, .vbipack = 255, .sram = 0, /* like PAL, correct? */ - .vbistart = { 7, 320 }, },{ .v4l2_id = V4L2_STD_PAL_Nc, .name = "PAL-Nc", @@ -264,7 +258,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { .vdelay = 0x1a, .vbipack = 144, .sram = -1, - .vbistart = { 7, 320 }, },{ .v4l2_id = V4L2_STD_PAL_M, .name = "PAL-M", @@ -281,7 +274,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { .vdelay = 0x1a, .vbipack = 144, .sram = -1, - .vbistart = { 10, 273 }, },{ .v4l2_id = V4L2_STD_PAL_N, .name = "PAL-N", @@ -298,7 +290,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { .vdelay = 0x20, .vbipack = 144, .sram = -1, - .vbistart = { 7, 320}, },{ .v4l2_id = V4L2_STD_NTSC_M_JP, .name = "NTSC-JP", @@ -315,7 +306,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { .vdelay = 0x16, .vbipack = 144, .sram = -1, - .vbistart = {10, 273}, },{ /* that one hopefully works with the strange timing * which video recorders produce when playing a NTSC @@ -336,7 +326,6 @@ const struct bttv_tvnorm bttv_tvnorms[] = { .vbipack = 255, .vtotal = 524, .sram = -1, - .vbistart = { 10, 273 }, } }; static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms); @@ -1521,6 +1510,14 @@ static struct videobuf_queue_ops bttv_video_qops = { .buf_release = buffer_release, }; +static const char *v4l1_ioctls[] = { + "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT", + "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ", + "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT", + "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", + "SMICROCODE", "GVBIFMT", "SVBIFMT" }; +#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) + static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg) { switch (cmd) { @@ -2209,9 +2206,22 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, unsigned long flags; int retval = 0; - if (bttv_debug > 1) - v4l_print_ioctl(btv->c.name, cmd); - + if (bttv_debug > 1) { + switch (_IOC_TYPE(cmd)) { + case 'v': + printk("bttv%d: ioctl 0x%x (v4l1, VIDIOC%s)\n", + btv->c.nr, cmd, (_IOC_NR(cmd) < V4L1_IOCTLS) ? + v4l1_ioctls[_IOC_NR(cmd)] : "???"); + break; + case 'V': + printk("bttv%d: ioctl 0x%x (v4l2, %s)\n", + btv->c.nr, cmd, v4l2_ioctl_names[_IOC_NR(cmd)]); + break; + default: + printk("bttv%d: ioctl 0x%x (???)\n", + btv->c.nr, cmd); + } + } if (btv->errors) bttv_reinit_bt848(btv); @@ -2560,10 +2570,10 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, fmt->count[0] = fmt2.fmt.vbi.count[0]; fmt->start[1] = fmt2.fmt.vbi.start[1]; fmt->count[1] = fmt2.fmt.vbi.count[1]; - if (fmt2.fmt.vbi.flags & V4L2_VBI_UNSYNC) - fmt->flags |= VBI_UNSYNC; - if (fmt2.fmt.vbi.flags & V4L2_VBI_INTERLACED) - fmt->flags |= VBI_INTERLACED; + if (fmt2.fmt.vbi.flags & VBI_UNSYNC) + fmt->flags |= V4L2_VBI_UNSYNC; + if (fmt2.fmt.vbi.flags & VBI_INTERLACED) + fmt->flags |= V4L2_VBI_INTERLACED; return 0; } case VIDIOCSVBIFMT: @@ -3110,7 +3120,6 @@ static struct file_operations bttv_fops = .open = bttv_open, .release = bttv_release, .ioctl = bttv_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, .read = bttv_read, .mmap = bttv_mmap, @@ -3220,7 +3229,6 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, case VIDIOCSFREQ: case VIDIOCGAUDIO: case VIDIOCSAUDIO: - case VIDIOC_LOG_STATUS: return bttv_common_ioctls(btv,cmd,arg); default: @@ -3693,8 +3701,8 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs) btv=(struct bttv *)dev_id; - if (btv->custom_irq) - handled = btv->custom_irq(btv); + if (btv->any_irq) + handled = bttv_any_irq(&btv->c); count=0; while (1) { @@ -3730,9 +3738,9 @@ static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs) if (astat&BT848_INT_VSYNC) btv->field_count++; - if ((astat & BT848_INT_GPINT) && btv->remote) { + if (astat & BT848_INT_GPINT) { wake_up(&btv->gpioq); - bttv_input_irq(btv); + bttv_gpio_irq(&btv->c); } if (astat & BT848_INT_I2CDONE) { @@ -3938,6 +3946,7 @@ static int __devinit bttv_probe(struct pci_dev *dev, btv->i2c_rc = -1; btv->tuner_type = UNSET; + btv->pinnacle_id = UNSET; btv->new_input = UNSET; btv->has_radio=radio[btv->c.nr]; @@ -4056,11 +4065,11 @@ static int __devinit bttv_probe(struct pci_dev *dev, } /* add subdevices */ + if (btv->has_remote) + bttv_sub_add_device(&btv->c, "remote"); if (bttv_tvcards[btv->c.type].has_dvb) bttv_sub_add_device(&btv->c, "dvb"); - bttv_input_init(btv); - /* everything is fine */ bttv_num++; return 0; @@ -4095,7 +4104,6 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev) /* tell gpio modules we are leaving ... */ btv->shutdown=1; wake_up(&btv->gpioq); - bttv_input_fini(btv); bttv_sub_del_devices(&btv->c); /* unregister i2c_bus + input */ @@ -4245,7 +4253,7 @@ static int bttv_init_module(void) bttv_check_chipset(); bus_register(&bttv_sub_bus_type); - return pci_register_driver(&bttv_pci_driver); + return pci_module_init(&bttv_pci_driver); } static void bttv_cleanup_module(void) diff --git a/trunk/drivers/media/video/bttv-gpio.c b/trunk/drivers/media/video/bttv-gpio.c index 575ce8b8e714..616a5b7e510c 100644 --- a/trunk/drivers/media/video/bttv-gpio.c +++ b/trunk/drivers/media/video/bttv-gpio.c @@ -113,6 +113,24 @@ void bttv_gpio_irq(struct bttv_core *core) } } +int bttv_any_irq(struct bttv_core *core) +{ + struct bttv_sub_driver *drv; + struct bttv_sub_device *dev; + struct list_head *item; + int handled = 0; + + list_for_each(item,&core->subs) { + dev = list_entry(item,struct bttv_sub_device,list); + drv = to_bttv_sub_drv(dev->dev.driver); + if (drv && drv->any_irq) { + if (drv->any_irq(dev)) + handled = 1; + } + } + return handled; +} + /* ----------------------------------------------------------------------- */ /* external: sub-driver register/unregister */ diff --git a/trunk/drivers/media/video/bttv-i2c.c b/trunk/drivers/media/video/bttv-i2c.c index 748d630c7fe4..d6418c023d39 100644 --- a/trunk/drivers/media/video/bttv-i2c.c +++ b/trunk/drivers/media/video/bttv-i2c.c @@ -28,12 +28,11 @@ #include #include #include - -#include "bttvp.h" -#include #include #include +#include "bttvp.h" + static struct i2c_algo_bit_data bttv_i2c_algo_bit_template; static struct i2c_adapter bttv_i2c_adap_sw_template; static struct i2c_adapter bttv_i2c_adap_hw_template; @@ -106,8 +105,10 @@ static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = { static struct i2c_adapter bttv_i2c_adap_sw_template = { .owner = THIS_MODULE, +#ifdef I2C_CLASS_TV_ANALOG .class = I2C_CLASS_TV_ANALOG, - .name = "bttv", +#endif + .name = "bt848", .id = I2C_HW_B_BT848, .client_register = attach_inform, }; @@ -274,8 +275,10 @@ static struct i2c_algorithm bttv_algo = { }; static struct i2c_adapter bttv_i2c_adap_hw_template = { - .owner = THIS_MODULE, + .owner = THIS_MODULE, +#ifdef I2C_CLASS_TV_ANALOG .class = I2C_CLASS_TV_ANALOG, +#endif .name = "bt878", .id = I2C_HW_B_BT848 /* FIXME */, .algo = &bttv_algo, @@ -438,10 +441,12 @@ int __devinit init_bttv_i2c(struct bttv *btv) i2c_set_adapdata(&btv->c.i2c_adap, btv); btv->i2c_client.adapter = &btv->c.i2c_adap; +#ifdef I2C_CLASS_TV_ANALOG if (bttv_tvcards[btv->c.type].no_video) btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG; if (bttv_tvcards[btv->c.type].has_dvb) btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL; +#endif if (btv->use_i2c_hw) { btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap); diff --git a/trunk/drivers/media/video/bttv-vbi.c b/trunk/drivers/media/video/bttv-vbi.c index 72afdd64b882..f4f58c60f152 100644 --- a/trunk/drivers/media/video/bttv-vbi.c +++ b/trunk/drivers/media/video/bttv-vbi.c @@ -31,12 +31,6 @@ #include #include "bttvp.h" -/* Offset from line sync pulse leading edge (0H) in 1 / sampling_rate: - bt8x8 /HRESET pulse starts at 0H and has length 64 / fCLKx1 (E|O_VTC - HSFMT = 0). VBI_HDELAY (always 0) is an offset from the trailing edge - of /HRESET in 1 / fCLKx1, and the sampling_rate tvnorm->Fsc is fCLKx2. */ -#define VBI_OFFSET ((64 + 0) * 2) - #define VBI_DEFLINES 16 #define VBI_MAXLINES 32 @@ -169,30 +163,40 @@ void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines) void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f) { const struct bttv_tvnorm *tvnorm; - s64 count0,count1,count; + u32 start0,start1; + s32 count0,count1,count; tvnorm = &bttv_tvnorms[fh->btv->tvnorm]; f->type = V4L2_BUF_TYPE_VBI_CAPTURE; f->fmt.vbi.sampling_rate = tvnorm->Fsc; f->fmt.vbi.samples_per_line = 2048; f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; - f->fmt.vbi.offset = VBI_OFFSET; + f->fmt.vbi.offset = 244; f->fmt.vbi.flags = 0; + switch (fh->btv->tvnorm) { + case 1: /* NTSC */ + start0 = 10; + start1 = 273; + break; + case 0: /* PAL */ + case 2: /* SECAM */ + default: + start0 = 7; + start1 = 320; + } - /* s64 to prevent overflow. */ - count0 = (s64) f->fmt.vbi.start[0] + f->fmt.vbi.count[0] - - tvnorm->vbistart[0]; - count1 = (s64) f->fmt.vbi.start[1] + f->fmt.vbi.count[1] - - tvnorm->vbistart[1]; - count = clamp (max (count0, count1), 1LL, (s64) VBI_MAXLINES); + count0 = (f->fmt.vbi.start[0] + f->fmt.vbi.count[0]) - start0; + count1 = (f->fmt.vbi.start[1] + f->fmt.vbi.count[1]) - start1; + count = max(count0,count1); + if (count > VBI_MAXLINES) + count = VBI_MAXLINES; + if (count < 1) + count = 1; - f->fmt.vbi.start[0] = tvnorm->vbistart[0]; - f->fmt.vbi.start[1] = tvnorm->vbistart[1]; + f->fmt.vbi.start[0] = start0; + f->fmt.vbi.start[1] = start1; f->fmt.vbi.count[0] = count; f->fmt.vbi.count[1] = count; - - f->fmt.vbi.reserved[0] = 0; - f->fmt.vbi.reserved[1] = 0; } void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f) @@ -205,12 +209,21 @@ void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f) f->fmt.vbi.sampling_rate = tvnorm->Fsc; f->fmt.vbi.samples_per_line = 2048; f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; - f->fmt.vbi.offset = VBI_OFFSET; - f->fmt.vbi.start[0] = tvnorm->vbistart[0]; - f->fmt.vbi.start[1] = tvnorm->vbistart[1]; + f->fmt.vbi.offset = 244; f->fmt.vbi.count[0] = fh->lines; f->fmt.vbi.count[1] = fh->lines; f->fmt.vbi.flags = 0; + switch (fh->btv->tvnorm) { + case 1: /* NTSC */ + f->fmt.vbi.start[0] = 10; + f->fmt.vbi.start[1] = 273; + break; + case 0: /* PAL */ + case 2: /* SECAM */ + default: + f->fmt.vbi.start[0] = 7; + f->fmt.vbi.start[1] = 319; + } } /* ----------------------------------------------------------------------- */ diff --git a/trunk/drivers/media/video/bttv.h b/trunk/drivers/media/video/bttv.h index 9feaa6bab207..93298f06e019 100644 --- a/trunk/drivers/media/video/bttv.h +++ b/trunk/drivers/media/video/bttv.h @@ -16,8 +16,6 @@ #include #include -#include -#include /* ---------------------------------------------------------- */ /* exported by bttv-cards.c */ @@ -165,7 +163,6 @@ #define BTTV_BOARD_OSPREY440 0x8c #define BTTV_BOARD_ASOUND_SKYEYE 0x8d #define BTTV_BOARD_SABRENT_TVFM 0x8e -#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f /* i2c address list */ #define I2C_TSA5522 0xc2 @@ -213,34 +210,6 @@ struct bttv_core { struct bttv; - -struct bttv_ir { - struct input_dev *dev; - struct ir_input_state ir; - char name[32]; - char phys[32]; - - /* Usual gpio signalling */ - - u32 mask_keycode; - u32 mask_keydown; - u32 mask_keyup; - u32 polling; - u32 last_gpio; - struct work_struct work; - struct timer_list timer; - - /* RC5 gpio */ - u32 rc5_gpio; - struct timer_list timer_end; /* timer_end for code completion */ - struct timer_list timer_keyup; /* timer_end for key release */ - u32 last_rc5; /* last good rc5 code */ - u32 last_bit; /* last raw bit seen */ - u32 code; /* raw code under construction */ - struct timeval base_time; /* time of last seen code */ - int active; /* building raw code */ -}; - struct tvcard { char *name; @@ -266,6 +235,7 @@ struct tvcard unsigned int has_dvb:1; unsigned int has_remote:1; unsigned int no_gpioirq:1; + unsigned int any_irq:1; /* other settings */ unsigned int pll; @@ -365,6 +335,7 @@ struct bttv_sub_driver { struct device_driver drv; char wanted[BUS_ID_SIZE]; void (*gpio_irq)(struct bttv_sub_device *sub); + int (*any_irq)(struct bttv_sub_device *sub); }; #define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) @@ -392,10 +363,6 @@ extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, unsigned char b2, int both); extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr); -extern int bttv_input_init(struct bttv *dev); -extern void bttv_input_fini(struct bttv *dev); -extern void bttv_input_irq(struct bttv *dev); - #endif /* _BTTV_H_ */ /* * Local variables: diff --git a/trunk/drivers/media/video/bttvp.h b/trunk/drivers/media/video/bttvp.h index dd00c20ab95e..1e6a5632c3c7 100644 --- a/trunk/drivers/media/video/bttvp.h +++ b/trunk/drivers/media/video/bttvp.h @@ -73,8 +73,6 @@ #define UNSET (-1U) -#define clamp(x, low, high) min (max (low, x), high) - /* ---------------------------------------------------------- */ struct bttv_tvnorm { @@ -90,9 +88,6 @@ struct bttv_tvnorm { u8 vbipack; u16 vtotal; int sram; - /* ITU-R frame line number of the first VBI line we can - capture, of the first and second field. */ - u16 vbistart[2]; }; extern const struct bttv_tvnorm bttv_tvnorms[]; @@ -214,6 +209,7 @@ extern struct bus_type bttv_sub_bus_type; int bttv_sub_add_device(struct bttv_core *core, char *name); int bttv_sub_del_devices(struct bttv_core *core); void bttv_gpio_irq(struct bttv_core *core); +int bttv_any_irq(struct bttv_core *core); /* ---------------------------------------------------------- */ @@ -274,13 +270,12 @@ struct bttv { /* card configuration info */ unsigned int cardid; /* pci subsystem id (bt878 based ones) */ unsigned int tuner_type; /* tuner chip type */ - unsigned int tda9887_conf; + unsigned int pinnacle_id; unsigned int svhs; struct bttv_pll_info pll; int triton1; int gpioirq; - int (*custom_irq)(struct bttv *btv); - + int any_irq; int use_i2c_hw; /* old gpio interface */ @@ -305,7 +300,7 @@ struct bttv { /* infrared remote */ int has_remote; - struct bttv_ir *remote; + struct bttv_input *remote; /* locking */ spinlock_t s_lock; diff --git a/trunk/drivers/media/video/bw-qcam.c b/trunk/drivers/media/video/bw-qcam.c index 6bad93ef969f..0065d0c240d1 100644 --- a/trunk/drivers/media/video/bw-qcam.c +++ b/trunk/drivers/media/video/bw-qcam.c @@ -875,7 +875,6 @@ static struct file_operations qcam_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = qcam_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .read = qcam_read, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/video/c-qcam.c b/trunk/drivers/media/video/c-qcam.c index 9976db4f6da8..75442ec49f35 100644 --- a/trunk/drivers/media/video/c-qcam.c +++ b/trunk/drivers/media/video/c-qcam.c @@ -687,7 +687,6 @@ static struct file_operations qcam_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = qcam_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .read = qcam_read, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/video/compat_ioctl32.c b/trunk/drivers/media/video/compat_ioctl32.c deleted file mode 100644 index 6194b0125576..000000000000 --- a/trunk/drivers/media/video/compat_ioctl32.c +++ /dev/null @@ -1,732 +0,0 @@ -/* - * ioctl32.c: Conversion between 32bit and 64bit native ioctls. - * Separated from fs stuff by Arnd Bergmann - * - * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) - * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) - * Copyright (C) 2001,2002 Andi Kleen, SuSE Labs - * Copyright (C) 2003 Pavel Machek (pavel@suse.cz) - * Copyright (C) 2005 Philippe De Muyter (phdm@macqel.be) - * - * These routines maintain argument size conversion between 32bit and 64bit - * ioctls. - */ - -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_COMPAT -struct video_tuner32 { - compat_int_t tuner; - char name[32]; - compat_ulong_t rangelow, rangehigh; - u32 flags; /* It is really u32 in videodev.h */ - u16 mode, signal; -}; - -static int get_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) -{ - if(get_user(kp->tuner, &up->tuner)) - return -EFAULT; - __copy_from_user(kp->name, up->name, 32); - __get_user(kp->rangelow, &up->rangelow); - __get_user(kp->rangehigh, &up->rangehigh); - __get_user(kp->flags, &up->flags); - __get_user(kp->mode, &up->mode); - __get_user(kp->signal, &up->signal); - return 0; -} - -static int put_video_tuner32(struct video_tuner *kp, struct video_tuner32 __user *up) -{ - if(put_user(kp->tuner, &up->tuner)) - return -EFAULT; - __copy_to_user(up->name, kp->name, 32); - __put_user(kp->rangelow, &up->rangelow); - __put_user(kp->rangehigh, &up->rangehigh); - __put_user(kp->flags, &up->flags); - __put_user(kp->mode, &up->mode); - __put_user(kp->signal, &up->signal); - return 0; -} - -struct video_buffer32 { - compat_caddr_t base; - compat_int_t height, width, depth, bytesperline; -}; - -static int get_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up) -{ - u32 tmp; - - if (get_user(tmp, &up->base)) - return -EFAULT; - - /* This is actually a physical address stored - * as a void pointer. - */ - kp->base = (void *)(unsigned long) tmp; - - __get_user(kp->height, &up->height); - __get_user(kp->width, &up->width); - __get_user(kp->depth, &up->depth); - __get_user(kp->bytesperline, &up->bytesperline); - return 0; -} - -static int put_video_buffer32(struct video_buffer *kp, struct video_buffer32 __user *up) -{ - u32 tmp = (u32)((unsigned long)kp->base); - - if(put_user(tmp, &up->base)) - return -EFAULT; - __put_user(kp->height, &up->height); - __put_user(kp->width, &up->width); - __put_user(kp->depth, &up->depth); - __put_user(kp->bytesperline, &up->bytesperline); - return 0; -} - -struct video_clip32 { - s32 x, y, width, height; /* Its really s32 in videodev.h */ - compat_caddr_t next; -}; - -struct video_window32 { - u32 x, y, width, height, chromakey, flags; - compat_caddr_t clips; - compat_int_t clipcount; -}; - -static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - int ret = -ENOIOCTLCMD; - - if (file->f_op->unlocked_ioctl) - ret = file->f_op->unlocked_ioctl(file, cmd, arg); - else if (file->f_op->ioctl) { - lock_kernel(); - ret = file->f_op->ioctl(file->f_dentry->d_inode, file, cmd, arg); - unlock_kernel(); - } - - return ret; -} - - -/* You get back everything except the clips... */ -static int put_video_window32(struct video_window *kp, struct video_window32 __user *up) -{ - if(put_user(kp->x, &up->x)) - return -EFAULT; - __put_user(kp->y, &up->y); - __put_user(kp->width, &up->width); - __put_user(kp->height, &up->height); - __put_user(kp->chromakey, &up->chromakey); - __put_user(kp->flags, &up->flags); - __put_user(kp->clipcount, &up->clipcount); - return 0; -} - -struct v4l2_clip32 -{ - struct v4l2_rect c; - compat_caddr_t next; -}; - -struct v4l2_window32 -{ - struct v4l2_rect w; - enum v4l2_field field; - __u32 chromakey; - compat_caddr_t clips; /* actually struct v4l2_clip32 * */ - __u32 clipcount; - compat_caddr_t bitmap; -}; - -static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) -{ - if (copy_from_user(&kp->w, &up->w, sizeof(up->w))) - return -EFAULT; - __get_user(kp->field, &up->field); - __get_user(kp->chromakey, &up->chromakey); - __get_user(kp->clipcount, &up->clipcount); - if (kp->clipcount > 2048) - return -EINVAL; - if (kp->clipcount) { - struct v4l2_clip32 *uclips = compat_ptr(up->clips); - struct v4l2_clip *kclips; - int n = kp->clipcount; - - kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip)); - kp->clips = kclips; - while (--n >= 0) { - copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c)); - kclips->next = n ? kclips + 1 : 0; - uclips += 1; - kclips += 1; - } - } else - kp->clips = 0; - return 0; -} - -static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) -{ - if (copy_to_user(&up->w, &kp->w, sizeof(up->w))) - return -EFAULT; - __put_user(kp->field, &up->field); - __put_user(kp->chromakey, &up->chromakey); - __put_user(kp->clipcount, &up->clipcount); - return 0; -} - -static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) -{ - return copy_from_user(kp, up, sizeof(struct v4l2_pix_format)); -} - -static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) -{ - return copy_to_user(up, kp, sizeof(struct v4l2_pix_format)); -} - -static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) -{ - return copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)); -} - -static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) -{ - return copy_to_user(up, kp, sizeof(struct v4l2_vbi_format)); -} - -struct v4l2_format32 -{ - enum v4l2_buf_type type; - union - { - struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE - struct v4l2_window32 win; // V4L2_BUF_TYPE_VIDEO_OVERLAY - struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE - __u8 raw_data[200]; // user-defined - } fmt; -}; - -static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) -{ - if(get_user(kp->type, &up->type)) - return -EFAULT; - switch (kp->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - return get_v4l2_window32(&kp->fmt.win, &up->fmt.win); - case V4L2_BUF_TYPE_VBI_CAPTURE: - return get_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi); - default: - printk("compat_ioctl : unexpected VIDIOC_FMT type %d\n", - kp->type); - return -ENXIO; - } -} - -static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) -{ - if(put_user(kp->type, &up->type)) - return -EFAULT; - switch (kp->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); - case V4L2_BUF_TYPE_VIDEO_OVERLAY: - return put_v4l2_window32(&kp->fmt.win, &up->fmt.win); - case V4L2_BUF_TYPE_VBI_CAPTURE: - return put_v4l2_vbi_format(&kp->fmt.vbi, &up->fmt.vbi); - default: - return -ENXIO; - } -} - -struct v4l2_standard32 -{ - __u32 index; - __u32 id[2]; /* __u64 would get the alignment wrong */ - __u8 name[24]; - struct v4l2_fract frameperiod; /* Frames, not fields */ - __u32 framelines; - __u32 reserved[4]; -}; - -static int get_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up) -{ - /* other fields are not set by the user, nor used by the driver */ - return get_user(kp->index, &up->index); -} - -static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 __user *up) -{ - if(put_user(kp->index, &up->index)) - return -EFAULT; - __copy_to_user(up->id, &kp->id, sizeof(__u64)); - __copy_to_user(up->name, kp->name, 24); - __put_user(kp->frameperiod, &up->frameperiod); - __put_user(kp->framelines, &up->framelines); - __copy_to_user(up->reserved, kp->reserved, 4 * sizeof(__u32)); - return 0; -} - -struct v4l2_buffer32 -{ - __u32 index; - enum v4l2_buf_type type; - __u32 bytesused; - __u32 flags; - enum v4l2_field field; - struct compat_timeval timestamp; - struct v4l2_timecode timecode; - __u32 sequence; - - /* memory location */ - enum v4l2_memory memory; - union { - __u32 offset; - compat_long_t userptr; - } m; - __u32 length; - __u32 input; - __u32 reserved; -}; - -static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up) -{ - - if (get_user(kp->index, &up->index)) - return -EFAULT; - __get_user(kp->type, &up->type); - __get_user(kp->flags, &up->flags); - __get_user(kp->memory, &up->memory); - __get_user(kp->input, &up->input); - switch(kp->memory) { - case V4L2_MEMORY_MMAP: - break; - case V4L2_MEMORY_USERPTR: - { - unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr); - - __get_user(kp->length, &up->length); - __get_user(kp->m.userptr, &tmp); - } - break; - case V4L2_MEMORY_OVERLAY: - __get_user(kp->m.offset, &up->m.offset); - break; - } - return 0; -} - -static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up) -{ - if (put_user(kp->index, &up->index)) - return -EFAULT; - __put_user(kp->type, &up->type); - __put_user(kp->flags, &up->flags); - __put_user(kp->memory, &up->memory); - __put_user(kp->input, &up->input); - switch(kp->memory) { - case V4L2_MEMORY_MMAP: - __put_user(kp->length, &up->length); - __put_user(kp->m.offset, &up->m.offset); - break; - case V4L2_MEMORY_USERPTR: - __put_user(kp->length, &up->length); - __put_user(kp->m.userptr, &up->m.userptr); - break; - case V4L2_MEMORY_OVERLAY: - __put_user(kp->m.offset, &up->m.offset); - break; - } - __put_user(kp->bytesused, &up->bytesused); - __put_user(kp->field, &up->field); - __put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec); - __put_user(kp->timestamp.tv_usec, &up->timestamp.tv_usec); - __copy_to_user(&up->timecode, &kp->timecode, sizeof(struct v4l2_timecode)); - __put_user(kp->sequence, &up->sequence); - __put_user(kp->reserved, &up->reserved); - return 0; -} - -struct v4l2_framebuffer32 -{ - __u32 capability; - __u32 flags; - compat_caddr_t base; - struct v4l2_pix_format fmt; -}; - -static int get_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up) -{ - u32 tmp; - - if (get_user(tmp, &up->base)) - return -EFAULT; - kp->base = compat_ptr(tmp); - __get_user(kp->capability, &up->capability); - __get_user(kp->flags, &up->flags); - get_v4l2_pix_format(&kp->fmt, &up->fmt); - return 0; -} - -static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_framebuffer32 __user *up) -{ - u32 tmp = (u32)((unsigned long)kp->base); - - if(put_user(tmp, &up->base)) - return -EFAULT; - __put_user(kp->capability, &up->capability); - __put_user(kp->flags, &up->flags); - put_v4l2_pix_format(&kp->fmt, &up->fmt); - return 0; -} - -struct v4l2_input32 /* identical layout, but different size */ -{ - __u32 index; /* Which input */ - __u8 name[32]; /* Label */ - __u32 type; /* Type of input */ - __u32 audioset; /* Associated audios (bitfield) */ - __u32 tuner; /* Associated tuner */ - __u32 std[2]; /* __u64 would get the padding wrong */ - __u32 status; - __u32 reserved[4]; -}; - -#define VIDIOCGTUNER32 _IOWR('v',4, struct video_tuner32) -#define VIDIOCSTUNER32 _IOW('v',5, struct video_tuner32) -#define VIDIOCGWIN32 _IOR('v',9, struct video_window32) -#define VIDIOCSWIN32 _IOW('v',10, struct video_window32) -#define VIDIOCGFBUF32 _IOR('v',11, struct video_buffer32) -#define VIDIOCSFBUF32 _IOW('v',12, struct video_buffer32) -#define VIDIOCGFREQ32 _IOR('v',14, u32) -#define VIDIOCSFREQ32 _IOW('v',15, u32) - -#define VIDIOC_G_FMT32 _IOWR ('V', 4, struct v4l2_format32) -#define VIDIOC_S_FMT32 _IOWR ('V', 5, struct v4l2_format32) -#define VIDIOC_QUERYBUF32 _IOWR ('V', 9, struct v4l2_buffer32) -#define VIDIOC_G_FBUF32 _IOR ('V', 10, struct v4l2_framebuffer32) -#define VIDIOC_S_FBUF32 _IOW ('V', 11, struct v4l2_framebuffer32) -/* VIDIOC_OVERLAY is now _IOW, but was _IOWR */ -#define VIDIOC_OVERLAY32 _IOWR ('V', 14, compat_int_t) -#define VIDIOC_QBUF32 _IOWR ('V', 15, struct v4l2_buffer32) -#define VIDIOC_DQBUF32 _IOWR ('V', 17, struct v4l2_buffer32) -#define VIDIOC_STREAMON32 _IOW ('V', 18, compat_int_t) -#define VIDIOC_STREAMOFF32 _IOW ('V', 19, compat_int_t) -#define VIDIOC_ENUMSTD32 _IOWR ('V', 25, struct v4l2_standard32) -#define VIDIOC_ENUMINPUT32 _IOWR ('V', 26, struct v4l2_input32) -/* VIDIOC_S_CTRL is now _IOWR, but was _IOW */ -#define VIDIOC_S_CTRL32 _IOW ('V', 28, struct v4l2_control) -#define VIDIOC_G_INPUT32 _IOR ('V', 38, compat_int_t) -#define VIDIOC_S_INPUT32 _IOWR ('V', 39, compat_int_t) -#define VIDIOC_TRY_FMT32 _IOWR ('V', 64, struct v4l2_format32) - -enum { - MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip) -}; - -static int do_set_window(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct video_window32 __user *up = compat_ptr(arg); - struct video_window __user *vw; - struct video_clip __user *p; - int nclips; - u32 n; - - if (get_user(nclips, &up->clipcount)) - return -EFAULT; - - /* Peculiar interface... */ - if (nclips < 0) - nclips = VIDEO_CLIPMAP_SIZE; - - if (nclips > MaxClips) - return -ENOMEM; - - vw = compat_alloc_user_space(sizeof(struct video_window) + - nclips * sizeof(struct video_clip)); - - p = nclips ? (struct video_clip __user *)(vw + 1) : NULL; - - if (get_user(n, &up->x) || put_user(n, &vw->x) || - get_user(n, &up->y) || put_user(n, &vw->y) || - get_user(n, &up->width) || put_user(n, &vw->width) || - get_user(n, &up->height) || put_user(n, &vw->height) || - get_user(n, &up->chromakey) || put_user(n, &vw->chromakey) || - get_user(n, &up->flags) || put_user(n, &vw->flags) || - get_user(n, &up->clipcount) || put_user(n, &vw->clipcount) || - get_user(n, &up->clips) || put_user(p, &vw->clips)) - return -EFAULT; - - if (nclips) { - struct video_clip32 __user *u = compat_ptr(n); - int i; - if (!u) - return -EINVAL; - for (i = 0; i < nclips; i++, u++, p++) { - s32 v; - if (get_user(v, &u->x) || - put_user(v, &p->x) || - get_user(v, &u->y) || - put_user(v, &p->y) || - get_user(v, &u->width) || - put_user(v, &p->width) || - get_user(v, &u->height) || - put_user(v, &p->height) || - put_user(NULL, &p->next)) - return -EFAULT; - } - } - - return native_ioctl(file, VIDIOCSWIN, (unsigned long)vw); -} - -static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - union { - struct video_tuner vt; - struct video_buffer vb; - struct video_window vw; - struct v4l2_format v2f; - struct v4l2_buffer v2b; - struct v4l2_framebuffer v2fb; - struct v4l2_standard v2s; - unsigned long vx; - } karg; - void __user *up = compat_ptr(arg); - int compatible_arg = 1; - int err = 0; - - /* First, convert the command. */ - switch(cmd) { - case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break; - case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break; - case VIDIOCGWIN32: cmd = VIDIOCGWIN; break; - case VIDIOCGFBUF32: cmd = VIDIOCGFBUF; break; - case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break; - case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break; - case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break; - case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break; - case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break; - case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break; - case VIDIOC_QBUF32: cmd = VIDIOC_QBUF; break; - case VIDIOC_DQBUF32: cmd = VIDIOC_DQBUF; break; - case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break; - case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break; - case VIDIOC_G_FBUF32: cmd = VIDIOC_G_FBUF; break; - case VIDIOC_S_FBUF32: cmd = VIDIOC_S_FBUF; break; - case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break; - case VIDIOC_ENUMSTD32: cmd = VIDIOC_ENUMSTD; break; - case VIDIOC_ENUMINPUT32: cmd = VIDIOC_ENUMINPUT; break; - case VIDIOC_S_CTRL32: cmd = VIDIOC_S_CTRL; break; - case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; - case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; - case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break; - }; - - switch(cmd) { - case VIDIOCSTUNER: - case VIDIOCGTUNER: - err = get_video_tuner32(&karg.vt, up); - compatible_arg = 0; - - break; - - case VIDIOCSFBUF: - err = get_video_buffer32(&karg.vb, up); - compatible_arg = 0; - break; - - case VIDIOCSFREQ: - case VIDIOC_S_INPUT: - case VIDIOC_OVERLAY: - case VIDIOC_STREAMON: - case VIDIOC_STREAMOFF: - err = get_user(karg.vx, (u32 __user *)up); - compatible_arg = 0; - break; - - case VIDIOC_S_FBUF: - err = get_v4l2_framebuffer32(&karg.v2fb, up); - compatible_arg = 0; - break; - - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_TRY_FMT: - err = get_v4l2_format32(&karg.v2f, up); - compatible_arg = 0; - break; - - case VIDIOC_QUERYBUF: - case VIDIOC_QBUF: - case VIDIOC_DQBUF: - err = get_v4l2_buffer32(&karg.v2b, up); - compatible_arg = 0; - break; - - case VIDIOC_ENUMSTD: - err = get_v4l2_standard32(&karg.v2s, up); - compatible_arg = 0; - break; - - case VIDIOCGWIN: - case VIDIOCGFBUF: - case VIDIOCGFREQ: - case VIDIOC_G_FBUF: - case VIDIOC_G_INPUT: - compatible_arg = 0; - }; - - if(err) - goto out; - - if(compatible_arg) - err = native_ioctl(file, cmd, (unsigned long)up); - else { - mm_segment_t old_fs = get_fs(); - - set_fs(KERNEL_DS); - err = native_ioctl(file, cmd, (unsigned long)&karg); - set_fs(old_fs); - } - if(err == 0) { - switch(cmd) { - case VIDIOCGTUNER: - err = put_video_tuner32(&karg.vt, up); - break; - - case VIDIOCGWIN: - err = put_video_window32(&karg.vw, up); - break; - - case VIDIOCGFBUF: - err = put_video_buffer32(&karg.vb, up); - break; - - case VIDIOC_G_FBUF: - err = put_v4l2_framebuffer32(&karg.v2fb, up); - break; - - case VIDIOC_G_FMT: - case VIDIOC_S_FMT: - case VIDIOC_TRY_FMT: - err = put_v4l2_format32(&karg.v2f, up); - break; - - case VIDIOC_QUERYBUF: - case VIDIOC_QBUF: - case VIDIOC_DQBUF: - err = put_v4l2_buffer32(&karg.v2b, up); - break; - - case VIDIOC_ENUMSTD: - err = put_v4l2_standard32(&karg.v2s, up); - break; - - case VIDIOCGFREQ: - case VIDIOC_G_INPUT: - err = put_user(((u32)karg.vx), (u32 __user *)up); - break; - }; - } -out: - return err; -} - -long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) -{ - int ret = -ENOIOCTLCMD; - - if (!file->f_op->ioctl) - return ret; - - switch (cmd) { - case VIDIOCSWIN32: - ret = do_set_window(file, cmd, arg); - break; - case VIDIOCGTUNER32: - case VIDIOCSTUNER32: - case VIDIOCGWIN32: - case VIDIOCGFBUF32: - case VIDIOCSFBUF32: - case VIDIOCGFREQ32: - case VIDIOCSFREQ32: - case VIDIOC_QUERYCAP: - case VIDIOC_ENUM_FMT: - case VIDIOC_G_FMT32: - case VIDIOC_S_FMT32: - case VIDIOC_REQBUFS: - case VIDIOC_QUERYBUF32: - case VIDIOC_G_FBUF32: - case VIDIOC_S_FBUF32: - case VIDIOC_OVERLAY32: - case VIDIOC_QBUF32: - case VIDIOC_DQBUF32: - case VIDIOC_STREAMON32: - case VIDIOC_STREAMOFF32: - case VIDIOC_G_PARM: - case VIDIOC_G_STD: - case VIDIOC_S_STD: - case VIDIOC_ENUMSTD32: - case VIDIOC_ENUMINPUT32: - case VIDIOC_G_CTRL: - case VIDIOC_S_CTRL32: - case VIDIOC_QUERYCTRL: - case VIDIOC_G_INPUT32: - case VIDIOC_S_INPUT32: - case VIDIOC_TRY_FMT32: - ret = do_video_ioctl(file, cmd, arg); - break; - - /* Little v, the video4linux ioctls (conflict?) */ - case VIDIOCGCAP: - case VIDIOCGCHAN: - case VIDIOCSCHAN: - case VIDIOCGPICT: - case VIDIOCSPICT: - case VIDIOCCAPTURE: - case VIDIOCKEY: - case VIDIOCGAUDIO: - case VIDIOCSAUDIO: - case VIDIOCSYNC: - case VIDIOCMCAPTURE: - case VIDIOCGMBUF: - case VIDIOCGUNIT: - case VIDIOCGCAPTURE: - case VIDIOCSCAPTURE: - - /* BTTV specific... */ - case _IOW('v', BASE_VIDIOCPRIVATE+0, char [256]): - case _IOR('v', BASE_VIDIOCPRIVATE+1, char [256]): - case _IOR('v' , BASE_VIDIOCPRIVATE+2, unsigned int): - case _IOW('v' , BASE_VIDIOCPRIVATE+3, char [16]): /* struct bttv_pll_info */ - case _IOR('v' , BASE_VIDIOCPRIVATE+4, int): - case _IOR('v' , BASE_VIDIOCPRIVATE+5, int): - case _IOR('v' , BASE_VIDIOCPRIVATE+6, int): - case _IOR('v' , BASE_VIDIOCPRIVATE+7, int): - ret = native_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); - break; - } - return ret; -} -#else -long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) -{ - return -ENOIOCTLCMD; -} -#endif -EXPORT_SYMBOL_GPL(v4l_compat_ioctl32); - -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/media/video/cpia.c b/trunk/drivers/media/video/cpia.c index 9f59541155d9..b7ec9bf45085 100644 --- a/trunk/drivers/media/video/cpia.c +++ b/trunk/drivers/media/video/cpia.c @@ -3807,7 +3807,6 @@ static struct file_operations cpia_fops = { .read = cpia_read, .mmap = cpia_mmap, .ioctl = cpia_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/video/cs53l32a.c b/trunk/drivers/media/video/cs53l32a.c index b421068f7ea3..643ead1a87ee 100644 --- a/trunk/drivers/media/video/cs53l32a.c +++ b/trunk/drivers/media/video/cs53l32a.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC"); MODULE_AUTHOR("Martin Vaughan"); @@ -39,6 +39,21 @@ module_param(debug, bool, 0644); MODULE_PARM_DESC(debug, "Debugging messages\n\t\t\t0=Off (default), 1=On"); +#define cs53l32a_dbg(fmt, arg...) \ + do { \ + if (debug) \ + printk(KERN_INFO "%s debug %d-%04x: " fmt, \ + client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); \ + } while (0) + +#define cs53l32a_err(fmt, arg...) do { \ + printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) +#define cs53l32a_info(fmt, arg...) do { \ + printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) + static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END }; @@ -59,59 +74,50 @@ static int cs53l32a_read(struct i2c_client *client, u8 reg) static int cs53l32a_command(struct i2c_client *client, unsigned int cmd, void *arg) { - struct v4l2_audio *input = arg; - struct v4l2_control *ctrl = arg; + int *input = arg; switch (cmd) { - case VIDIOC_S_AUDIO: - /* There are 2 physical inputs, but the second input can be - placed in two modes, the first mode bypasses the PGA (gain), - the second goes through the PGA. Hence there are three - possible inputs to choose from. */ - if (input->index > 2) { - v4l_err(client, "Invalid input %d.\n", input->index); - return -EINVAL; - } - cs53l32a_write(client, 0x01, 0x01 + (input->index << 4)); - break; - - case VIDIOC_G_AUDIO: - memset(input, 0, sizeof(*input)); - input->index = (cs53l32a_read(client, 0x01) >> 4) & 3; - break; - - case VIDIOC_G_CTRL: - if (ctrl->id == V4L2_CID_AUDIO_MUTE) { - ctrl->value = (cs53l32a_read(client, 0x03) & 0xc0) != 0; + case AUDC_SET_INPUT: + switch (*input) { + case AUDIO_TUNER: + cs53l32a_write(client, 0x01, 0x01); break; - } - if (ctrl->id != V4L2_CID_AUDIO_VOLUME) + case AUDIO_EXTERN: + cs53l32a_write(client, 0x01, 0x21); + break; + case AUDIO_MUTE: + cs53l32a_write(client, 0x03, 0xF0); + break; + case AUDIO_UNMUTE: + cs53l32a_write(client, 0x03, 0x30); + break; + default: + cs53l32a_err("Invalid input %d.\n", *input); return -EINVAL; - ctrl->value = (s8)cs53l32a_read(client, 0x04); + } break; case VIDIOC_S_CTRL: - if (ctrl->id == V4L2_CID_AUDIO_MUTE) { - cs53l32a_write(client, 0x03, ctrl->value ? 0xf0 : 0x30); + { + struct v4l2_control *ctrl = arg; + + if (ctrl->id != V4L2_CID_AUDIO_VOLUME) + return -EINVAL; + if (ctrl->value > 12 || ctrl->value < -90) + return -EINVAL; + cs53l32a_write(client, 0x04, (u8) ctrl->value); + cs53l32a_write(client, 0x05, (u8) ctrl->value); break; } - if (ctrl->id != V4L2_CID_AUDIO_VOLUME) - return -EINVAL; - if (ctrl->value > 12 || ctrl->value < -96) - return -EINVAL; - cs53l32a_write(client, 0x04, (u8) ctrl->value); - cs53l32a_write(client, 0x05, (u8) ctrl->value); - break; case VIDIOC_LOG_STATUS: { u8 v = cs53l32a_read(client, 0x01); u8 m = cs53l32a_read(client, 0x03); - s8 vol = cs53l32a_read(client, 0x04); - v4l_info(client, "Input: %d%s\n", (v >> 4) & 3, + cs53l32a_info("Input: %s%s\n", + v == 0x21 ? "external line in" : "tuner", (m & 0xC0) ? " (muted)" : ""); - v4l_info(client, "Volume: %d dB\n", vol); break; } @@ -151,12 +157,12 @@ static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind) client->driver = &i2c_driver; snprintf(client->name, sizeof(client->name) - 1, "cs53l32a"); - v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name); + cs53l32a_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name); for (i = 1; i <= 7; i++) { u8 v = cs53l32a_read(client, i); - v4l_dbg(1, client, "Read Reg %d %02x\n", i, v); + cs53l32a_dbg("Read Reg %d %02x\n", i, v); } /* Set cs53l32a internal register for Adaptec 2010/2410 setup */ @@ -174,7 +180,7 @@ static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind) for (i = 1; i <= 7; i++) { u8 v = cs53l32a_read(client, i); - v4l_dbg(1, client, "Read Reg %d %02x\n", i, v); + cs53l32a_dbg("Read Reg %d %02x\n", i, v); } i2c_attach_client(client); @@ -184,7 +190,11 @@ static int cs53l32a_attach(struct i2c_adapter *adapter, int address, int kind) static int cs53l32a_probe(struct i2c_adapter *adapter) { +#ifdef I2C_CLASS_TV_ANALOG if (adapter->class & I2C_CLASS_TV_ANALOG) +#else + if (adapter->id == I2C_HW_B_BT848) +#endif return i2c_probe(adapter, &addr_data, cs53l32a_attach); return 0; } diff --git a/trunk/drivers/media/video/cx25840/cx25840-audio.c b/trunk/drivers/media/video/cx25840/cx25840-audio.c index cb9a7981e408..740908f8027d 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-audio.c +++ b/trunk/drivers/media/video/cx25840/cx25840-audio.c @@ -23,13 +23,11 @@ #include "cx25840.h" -static int set_audclk_freq(struct i2c_client *client, u32 freq) +inline static int set_audclk_freq(struct i2c_client *client, + enum v4l2_audio_clock_freq freq) { struct cx25840_state *state = i2c_get_clientdata(client); - if (freq != 32000 && freq != 44100 && freq != 48000) - return -EINVAL; - /* assert soft reset */ cx25840_and_or(client, 0x810, ~0x1, 0x01); @@ -37,9 +35,10 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */ cx25840_write(client, 0x127, 0x50); - if (state->aud_input != CX25840_AUDIO_SERIAL) { + switch (state->audio_input) { + case AUDIO_TUNER: switch (freq) { - case 32000: + case V4L2_AUDCLK_32_KHZ: /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x0f040610); @@ -52,7 +51,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) cx25840_write4(client, 0x90c, 0x7ff70108); break; - case 44100: + case V4L2_AUDCLK_441_KHZ: /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x0f040910); @@ -65,7 +64,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) cx25840_write4(client, 0x90c, 0x596d0108); break; - case 48000: + case V4L2_AUDCLK_48_KHZ: /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x0f040a10); @@ -78,9 +77,14 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) cx25840_write4(client, 0x90c, 0xaa4f0108); break; } - } else { + break; + + case AUDIO_EXTERN_1: + case AUDIO_EXTERN_2: + case AUDIO_INTERN: + case AUDIO_RADIO: switch (freq) { - case 32000: + case V4L2_AUDCLK_32_KHZ: /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x0f04081e); @@ -99,7 +103,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) cx25840_write(client, 0x127, 0x54); break; - case 44100: + case V4L2_AUDCLK_441_KHZ: /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x0f040918); @@ -115,7 +119,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) cx25840_write4(client, 0x90c, 0x85730108); break; - case 48000: + case V4L2_AUDCLK_48_KHZ: /* VID_PLL and AUX_PLL */ cx25840_write4(client, 0x108, 0x0f040a18); @@ -131,6 +135,7 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) cx25840_write4(client, 0x90c, 0x55550108); break; } + break; } /* deassert soft reset */ @@ -141,36 +146,51 @@ static int set_audclk_freq(struct i2c_client *client, u32 freq) return 0; } -void cx25840_audio_set_path(struct i2c_client *client) +static int set_input(struct i2c_client *client, int audio_input) { struct cx25840_state *state = i2c_get_clientdata(client); + cx25840_dbg("set audio input (%d)\n", audio_input); + /* stop microcontroller */ cx25840_and_or(client, 0x803, ~0x10, 0); /* Mute everything to prevent the PFFT! */ cx25840_write(client, 0x8d3, 0x1f); - if (state->aud_input == CX25840_AUDIO_SERIAL) { + switch (audio_input) { + case AUDIO_TUNER: + /* Set Path1 to Analog Demod Main Channel */ + cx25840_write4(client, 0x8d0, 0x7038061f); + + /* When the microcontroller detects the + * audio format, it will unmute the lines */ + cx25840_and_or(client, 0x803, ~0x10, 0x10); + break; + + case AUDIO_EXTERN_1: + case AUDIO_EXTERN_2: + case AUDIO_INTERN: + case AUDIO_RADIO: /* Set Path1 to Serial Audio Input */ cx25840_write4(client, 0x8d0, 0x12100101); /* The microcontroller should not be started for the * non-tuner inputs: autodetection is specific for * TV audio. */ - } else { - /* Set Path1 to Analog Demod Main Channel */ - cx25840_write4(client, 0x8d0, 0x7038061f); + break; - /* When the microcontroller detects the - * audio format, it will unmute the lines */ - cx25840_and_or(client, 0x803, ~0x10, 0x10); + default: + cx25840_dbg("Invalid audio input selection %d\n", audio_input); + return -EINVAL; } - set_audclk_freq(client, state->audclk_freq); + state->audio_input = audio_input; + + return set_audclk_freq(client, state->audclk_freq); } -static int get_volume(struct i2c_client *client) +inline static int get_volume(struct i2c_client *client) { /* Volume runs +18dB to -96dB in 1/2dB steps * change to fit the msp3400 -114dB to +12dB range */ @@ -181,7 +201,7 @@ static int get_volume(struct i2c_client *client) return vol << 9; } -static void set_volume(struct i2c_client *client, int volume) +inline static void set_volume(struct i2c_client *client, int volume) { /* First convert the volume to msp3400 values (0-127) */ int vol = volume >> 9; @@ -198,7 +218,7 @@ static void set_volume(struct i2c_client *client, int volume) cx25840_write(client, 0x8d4, 228 - (vol * 2)); } -static int get_bass(struct i2c_client *client) +inline static int get_bass(struct i2c_client *client) { /* bass is 49 steps +12dB to -12dB */ @@ -208,13 +228,13 @@ static int get_bass(struct i2c_client *client) return bass; } -static void set_bass(struct i2c_client *client, int bass) +inline static void set_bass(struct i2c_client *client, int bass) { /* PATH1_EQ_BASS_VOL */ cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff)); } -static int get_treble(struct i2c_client *client) +inline static int get_treble(struct i2c_client *client) { /* treble is 49 steps +12dB to -12dB */ @@ -224,13 +244,13 @@ static int get_treble(struct i2c_client *client) return treble; } -static void set_treble(struct i2c_client *client, int treble) +inline static void set_treble(struct i2c_client *client, int treble) { /* PATH1_EQ_TREBLE_VOL */ cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff)); } -static int get_balance(struct i2c_client *client) +inline static int get_balance(struct i2c_client *client) { /* balance is 7 bit, 0 to -96dB */ @@ -244,7 +264,7 @@ static int get_balance(struct i2c_client *client) return balance << 8; } -static void set_balance(struct i2c_client *client, int balance) +inline static void set_balance(struct i2c_client *client, int balance) { int bal = balance >> 8; if (bal > 0x80) { @@ -260,17 +280,17 @@ static void set_balance(struct i2c_client *client, int balance) } } -static int get_mute(struct i2c_client *client) +inline static int get_mute(struct i2c_client *client) { /* check SRC1_MUTE_EN */ return cx25840_read(client, 0x8d3) & 0x2 ? 1 : 0; } -static void set_mute(struct i2c_client *client, int mute) +inline static void set_mute(struct i2c_client *client, int mute) { struct cx25840_state *state = i2c_get_clientdata(client); - if (state->aud_input != CX25840_AUDIO_SERIAL) { + if (state->audio_input == AUDIO_TUNER) { /* Must turn off microcontroller in order to mute sound. * Not sure if this is the best method, but it does work. * If the microcontroller is running, then it will undo any @@ -294,9 +314,10 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) struct v4l2_control *ctrl = arg; switch (cmd) { + case AUDC_SET_INPUT: + return set_input(client, *(int *)arg); case VIDIOC_INT_AUDIO_CLOCK_FREQ: - return set_audclk_freq(client, *(u32 *)arg); - + return set_audclk_freq(client, *(enum v4l2_audio_clock_freq *)arg); case VIDIOC_G_CTRL: switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: @@ -318,7 +339,6 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) return -EINVAL; } break; - case VIDIOC_S_CTRL: switch (ctrl->id) { case V4L2_CID_AUDIO_VOLUME: @@ -340,7 +360,6 @@ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg) return -EINVAL; } break; - default: return -EINVAL; } diff --git a/trunk/drivers/media/video/cx25840/cx25840-core.c b/trunk/drivers/media/video/cx25840/cx25840-core.c index d45237d508c4..3b09f46dddf6 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-core.c +++ b/trunk/drivers/media/video/cx25840/cx25840-core.c @@ -43,11 +43,11 @@ MODULE_LICENSE("GPL"); static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; -int debug = 0; +int cx25840_debug = 0; -module_param(debug, bool, 0644); +module_param(cx25840_debug, bool, 0644); -MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]"); +MODULE_PARM_DESC(cx25840_debug, "Debugging messages [0=Off (default) 1=On]"); I2C_CLIENT_INSMOD; @@ -115,13 +115,13 @@ int cx25840_and_or(struct i2c_client *client, u16 addr, u8 and_mask, /* ----------------------------------------------------------------------- */ -static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, - enum cx25840_audio_input aud_input); +static int set_input(struct i2c_client *, enum cx25840_input); +static void input_change(struct i2c_client *); static void log_status(struct i2c_client *client); /* ----------------------------------------------------------------------- */ -static void init_dll1(struct i2c_client *client) +static inline void init_dll1(struct i2c_client *client) { /* This is the Hauppauge sequence used to * initialize the Delay Lock Loop 1 (ADC DLL). */ @@ -135,7 +135,7 @@ static void init_dll1(struct i2c_client *client) cx25840_write(client, 0x15b, 0x10); } -static void init_dll2(struct i2c_client *client) +static inline void init_dll2(struct i2c_client *client) { /* This is the Hauppauge sequence used to * initialize the Delay Lock Loop 2 (ADC DLL). */ @@ -195,8 +195,10 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw) /* AC97 shift */ cx25840_write(client, 0x8cf, 0x0f); - /* (re)set input */ - set_input(client, state->vid_input, state->aud_input); + /* (re)set video input */ + set_input(client, state->input); + /* (re)set audio input */ + cx25840_audio(client, AUDC_SET_INPUT, &state->audio_input); /* start microcontroller */ cx25840_and_or(client, 0x803, ~0x10, 0x10); @@ -221,7 +223,7 @@ static void input_change(struct i2c_client *client) cx25840_write(client, 0x80b, 0x10); } else if (std & V4L2_STD_NTSC) { /* NTSC */ - if (state->pvr150_workaround) { + if (state->cardtype == CARDTYPE_PVR150_WORKAROUND) { /* Certain Hauppauge PVR150 models have a hardware bug that causes audio to drop out. For these models the audio standard must be set explicitly. @@ -257,68 +259,72 @@ static void input_change(struct i2c_client *client) } } -static int set_input(struct i2c_client *client, enum cx25840_video_input vid_input, - enum cx25840_audio_input aud_input) +static int set_input(struct i2c_client *client, enum cx25840_input input) { struct cx25840_state *state = i2c_get_clientdata(client); - u8 is_composite = (vid_input >= CX25840_COMPOSITE1 && - vid_input <= CX25840_COMPOSITE8); - u8 reg; - v4l_dbg(1, client, "decoder set video input %d, audio input %d\n", - vid_input, aud_input); + cx25840_dbg("decoder set input (%d)\n", input); - if (is_composite) { - reg = 0xf0 + (vid_input - CX25840_COMPOSITE1); - } else { - int luma = vid_input & 0xf0; - int chroma = vid_input & 0xf00; + switch (input) { + case CX25840_TUNER: + cx25840_dbg("now setting Tuner input\n"); - if ((vid_input & ~0xff0) || - luma < CX25840_SVIDEO_LUMA1 || luma > CX25840_SVIDEO_LUMA4 || - chroma < CX25840_SVIDEO_CHROMA4 || chroma > CX25840_SVIDEO_CHROMA8) { - v4l_err(client, "0x%04x is not a valid video input!\n", vid_input); - return -EINVAL; + if (state->cardtype == CARDTYPE_PVR150 || + state->cardtype == CARDTYPE_PVR150_WORKAROUND) { + /* CH_SEL_ADC2=1 */ + cx25840_and_or(client, 0x102, ~0x2, 0x02); } - reg = 0xf0 + ((luma - CX25840_SVIDEO_LUMA1) >> 4); - if (chroma >= CX25840_SVIDEO_CHROMA7) { - reg &= 0x3f; - reg |= (chroma - CX25840_SVIDEO_CHROMA7) >> 2; + + /* Video Input Control */ + if (state->cardtype == CARDTYPE_PG600) { + cx25840_write(client, 0x103, 0x11); } else { - reg &= 0xcf; - reg |= (chroma - CX25840_SVIDEO_CHROMA4) >> 4; + cx25840_write(client, 0x103, 0x46); + } + + /* INPUT_MODE=0 */ + cx25840_and_or(client, 0x401, ~0x6, 0x00); + break; + + case CX25840_COMPOSITE0: + case CX25840_COMPOSITE1: + cx25840_dbg("now setting Composite input\n"); + + /* Video Input Control */ + if (state->cardtype == CARDTYPE_PG600) { + cx25840_write(client, 0x103, 0x00); + } else { + cx25840_write(client, 0x103, 0x02); + } + + /* INPUT_MODE=0 */ + cx25840_and_or(client, 0x401, ~0x6, 0x00); + break; + + case CX25840_SVIDEO0: + case CX25840_SVIDEO1: + cx25840_dbg("now setting S-Video input\n"); + + /* CH_SEL_ADC2=0 */ + cx25840_and_or(client, 0x102, ~0x2, 0x00); + + /* Video Input Control */ + if (state->cardtype == CARDTYPE_PG600) { + cx25840_write(client, 0x103, 0x02); + } else { + cx25840_write(client, 0x103, 0x10); } - } - switch (aud_input) { - case CX25840_AUDIO_SERIAL: - /* do nothing, use serial audio input */ + /* INPUT_MODE=1 */ + cx25840_and_or(client, 0x401, ~0x6, 0x02); break; - case CX25840_AUDIO4: reg &= ~0x30; break; - case CX25840_AUDIO5: reg &= ~0x30; reg |= 0x10; break; - case CX25840_AUDIO6: reg &= ~0x30; reg |= 0x20; break; - case CX25840_AUDIO7: reg &= ~0xc0; break; - case CX25840_AUDIO8: reg &= ~0xc0; reg |= 0x40; break; default: - v4l_err(client, "0x%04x is not a valid audio input!\n", aud_input); + cx25840_err("%d is not a valid input!\n", input); return -EINVAL; } - cx25840_write(client, 0x103, reg); - /* Set INPUT_MODE to Composite (0) or S-Video (1) */ - cx25840_and_or(client, 0x401, ~0x6, is_composite ? 0 : 0x02); - /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ - cx25840_and_or(client, 0x102, ~0x2, (reg & 0x80) == 0 ? 2 : 0); - /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ - if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30) - cx25840_and_or(client, 0x102, ~0x4, 4); - else - cx25840_and_or(client, 0x102, ~0x4, 0); - - state->vid_input = vid_input; - state->aud_input = aud_input; - cx25840_audio_set_path(client); + state->input = input; input_change(client); return 0; } @@ -389,14 +395,23 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) struct cx25840_state *state = i2c_get_clientdata(client); switch (ctrl->id) { - case CX25840_CID_ENABLE_PVR150_WORKAROUND: - state->pvr150_workaround = ctrl->value; - set_input(client, state->vid_input, state->aud_input); + case CX25840_CID_CARDTYPE: + switch (ctrl->value) { + case CARDTYPE_PVR150: + case CARDTYPE_PVR150_WORKAROUND: + case CARDTYPE_PG600: + state->cardtype = ctrl->value; + break; + default: + return -ERANGE; + } + + set_input(client, state->input); break; case V4L2_CID_BRIGHTNESS: if (ctrl->value < 0 || ctrl->value > 255) { - v4l_err(client, "invalid brightness setting %d\n", + cx25840_err("invalid brightness setting %d\n", ctrl->value); return -ERANGE; } @@ -406,7 +421,7 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) case V4L2_CID_CONTRAST: if (ctrl->value < 0 || ctrl->value > 127) { - v4l_err(client, "invalid contrast setting %d\n", + cx25840_err("invalid contrast setting %d\n", ctrl->value); return -ERANGE; } @@ -416,7 +431,7 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) case V4L2_CID_SATURATION: if (ctrl->value < 0 || ctrl->value > 127) { - v4l_err(client, "invalid saturation setting %d\n", + cx25840_err("invalid saturation setting %d\n", ctrl->value); return -ERANGE; } @@ -427,7 +442,7 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) case V4L2_CID_HUE: if (ctrl->value < -127 || ctrl->value > 127) { - v4l_err(client, "invalid hue setting %d\n", ctrl->value); + cx25840_err("invalid hue setting %d\n", ctrl->value); return -ERANGE; } @@ -440,9 +455,6 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_BALANCE: case V4L2_CID_AUDIO_MUTE: return cx25840_audio(client, VIDIOC_S_CTRL, ctrl); - - default: - return -EINVAL; } return 0; @@ -453,11 +465,11 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) struct cx25840_state *state = i2c_get_clientdata(client); switch (ctrl->id) { - case CX25840_CID_ENABLE_PVR150_WORKAROUND: - ctrl->value = state->pvr150_workaround; + case CX25840_CID_CARDTYPE: + ctrl->value = state->cardtype; break; case V4L2_CID_BRIGHTNESS: - ctrl->value = (s8)cx25840_read(client, 0x414) + 128; + ctrl->value = cx25840_read(client, 0x414) + 128; break; case V4L2_CID_CONTRAST: ctrl->value = cx25840_read(client, 0x415) >> 1; @@ -466,7 +478,7 @@ static int get_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) ctrl->value = cx25840_read(client, 0x420) >> 1; break; case V4L2_CID_HUE: - ctrl->value = (s8)cx25840_read(client, 0x422); + ctrl->value = cx25840_read(client, 0x422); break; case V4L2_CID_AUDIO_VOLUME: case V4L2_CID_AUDIO_BASS: @@ -515,7 +527,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { - v4l_err(client, "%dx%d is not a valid size!\n", + cx25840_err("%dx%d is not a valid size!\n", pix->width, pix->height); return -ERANGE; } @@ -533,7 +545,7 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) else filter = 3; - v4l_dbg(1, client, "decoder set size %dx%d -> scale %ux%u\n", + cx25840_dbg("decoder set size %dx%d -> scale %ux%u\n", pix->width, pix->height, HSC, VSC); /* HSCALE=HSC */ @@ -562,98 +574,17 @@ static int set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt) /* ----------------------------------------------------------------------- */ -static struct v4l2_queryctrl cx25840_qctrl[] = { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 128, - .flags = 0, - }, { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 64, - .flags = 0, - }, { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 64, - .flags = 0, - }, { - .id = V4L2_CID_HUE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Hue", - .minimum = -128, - .maximum = 127, - .step = 1, - .default_value = 0, - .flags = 0, - }, { - .id = V4L2_CID_AUDIO_VOLUME, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Volume", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 58880, - .flags = 0, - }, { - .id = V4L2_CID_AUDIO_BALANCE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Balance", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 32768, - .flags = 0, - }, { - .id = V4L2_CID_AUDIO_MUTE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mute", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - .flags = 0, - }, { - .id = V4L2_CID_AUDIO_BASS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Bass", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 32768, - }, { - .id = V4L2_CID_AUDIO_TREBLE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Treble", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 32768, - }, -}; - -/* ----------------------------------------------------------------------- */ - static int cx25840_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct cx25840_state *state = i2c_get_clientdata(client); struct v4l2_tuner *vt = arg; + int result = 0; switch (cmd) { + case 0: + break; + #ifdef CONFIG_VIDEO_ADV_DEBUG /* ioctls to allow direct access to the * cx25840 registers for testing */ @@ -684,16 +615,18 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, return cx25840_vbi(client, cmd, arg); case VIDIOC_INT_AUDIO_CLOCK_FREQ: - return cx25840_audio(client, cmd, arg); + case AUDC_SET_INPUT: + result = cx25840_audio(client, cmd, arg); + break; case VIDIOC_STREAMON: - v4l_dbg(1, client, "enable output\n"); + cx25840_dbg("enable output\n"); cx25840_write(client, 0x115, 0x8c); cx25840_write(client, 0x116, 0x07); break; case VIDIOC_STREAMOFF: - v4l_dbg(1, client, "disable output\n"); + cx25840_dbg("disable output\n"); cx25840_write(client, 0x115, 0x00); cx25840_write(client, 0x116, 0x00); break; @@ -703,58 +636,28 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, break; case VIDIOC_G_CTRL: - return get_v4lctrl(client, (struct v4l2_control *)arg); + result = get_v4lctrl(client, (struct v4l2_control *)arg); + break; case VIDIOC_S_CTRL: - return set_v4lctrl(client, (struct v4l2_control *)arg); - - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *qc = arg; - int i; - - for (i = 0; i < ARRAY_SIZE(cx25840_qctrl); i++) - if (qc->id && qc->id == cx25840_qctrl[i].id) { - memcpy(qc, &cx25840_qctrl[i], sizeof(*qc)); - return 0; - } - return -EINVAL; - } + result = set_v4lctrl(client, (struct v4l2_control *)arg); + break; case VIDIOC_G_STD: *(v4l2_std_id *)arg = cx25840_get_v4lstd(client); break; case VIDIOC_S_STD: - state->radio = 0; - return set_v4lstd(client, *(v4l2_std_id *)arg); - - case AUDC_SET_RADIO: - state->radio = 1; + result = set_v4lstd(client, *(v4l2_std_id *)arg); break; case VIDIOC_G_INPUT: - *(int *)arg = state->vid_input; + *(int *)arg = state->input; break; case VIDIOC_S_INPUT: - return set_input(client, *(enum cx25840_video_input *)arg, state->aud_input); - - case VIDIOC_S_AUDIO: - { - struct v4l2_audio *input = arg; - - return set_input(client, state->vid_input, input->index); - } - - case VIDIOC_G_AUDIO: - { - struct v4l2_audio *input = arg; - - memset(input, 0, sizeof(*input)); - input->index = state->aud_input; + result = set_input(client, *(int *)arg); break; - } case VIDIOC_S_FREQUENCY: input_change(client); @@ -767,9 +670,6 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, u8 vpres = cx25840_read(client, 0x80a) & 0x10; int val = 0; - if (state->radio) - break; - vt->capability |= V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; @@ -824,10 +724,12 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, break; case VIDIOC_G_FMT: - return get_v4lfmt(client, (struct v4l2_format *)arg); + result = get_v4lfmt(client, (struct v4l2_format *)arg); + break; case VIDIOC_S_FMT: - return set_v4lfmt(client, (struct v4l2_format *)arg); + result = set_v4lfmt(client, (struct v4l2_format *)arg); + break; case VIDIOC_INT_RESET: cx25840_initialize(client, 0); @@ -839,10 +741,11 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, break; default: + cx25840_err("invalid ioctl %x\n", cmd); return -EINVAL; } - return 0; + return result; } /* ----------------------------------------------------------------------- */ @@ -872,7 +775,7 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, client->driver = &i2c_driver_cx25840; snprintf(client->name, sizeof(client->name) - 1, "cx25840"); - v4l_dbg(1, client, "detecting cx25840 client on address 0x%x\n", address << 1); + cx25840_dbg("detecting cx25840 client on address 0x%x\n", address << 1); device_id = cx25840_read(client, 0x101) << 8; device_id |= cx25840_read(client, 0x100); @@ -880,12 +783,12 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, /* The high byte of the device ID should be * 0x84 if chip is present */ if ((device_id & 0xff00) != 0x8400) { - v4l_dbg(1, client, "cx25840 not found\n"); + cx25840_dbg("cx25840 not found\n"); kfree(client); return 0; } - v4l_info(client, "cx25%3x-2%x found @ 0x%x (%s)\n", + cx25840_info("cx25%3x-2%x found @ 0x%x (%s)\n", (device_id & 0xfff0) >> 4, (device_id & 0x0f) < 3 ? (device_id & 0x0f) + 1 : 3, address << 1, adapter->name); @@ -898,10 +801,10 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, i2c_set_clientdata(client, state); memset(state, 0, sizeof(struct cx25840_state)); - state->vid_input = CX25840_COMPOSITE7; - state->aud_input = CX25840_AUDIO8; - state->audclk_freq = 48000; - state->pvr150_workaround = 0; + state->input = CX25840_TUNER; + state->audclk_freq = V4L2_AUDCLK_48_KHZ; + state->audio_input = AUDIO_TUNER; + state->cardtype = CARDTYPE_PVR150; cx25840_initialize(client, 1); @@ -912,7 +815,11 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, static int cx25840_attach_adapter(struct i2c_adapter *adapter) { +#ifdef I2C_CLASS_TV_ANALOG if (adapter->class & I2C_CLASS_TV_ANALOG) +#else + if (adapter->id == I2C_HW_B_BT848) +#endif return i2c_probe(adapter, &addr_data, &cx25840_detect_client); return 0; } @@ -939,7 +846,9 @@ static struct i2c_driver i2c_driver_cx25840 = { .driver = { .name = "cx25840", }, + .id = I2C_DRIVERID_CX25840, + .attach_adapter = cx25840_attach_adapter, .detach_client = cx25840_detach_client, .command = cx25840_command, @@ -983,13 +892,11 @@ static void log_status(struct i2c_client *client) u8 pref_mode = cx25840_read(client, 0x809); u8 afc0 = cx25840_read(client, 0x80b); u8 mute_ctl = cx25840_read(client, 0x8d3); - int vid_input = state->vid_input; - int aud_input = state->aud_input; char *p; - v4l_info(client, "Video signal: %spresent\n", + cx25840_info("Video signal: %spresent\n", (microctrl_vidfmt & 0x10) ? "" : "not "); - v4l_info(client, "Detected format: %s\n", + cx25840_info("Detected format: %s\n", fmt_strs[gen_stat1 & 0xf]); switch (mod_det_stat0) { @@ -1004,7 +911,7 @@ static void log_status(struct i2c_client *client) case 0xfe: p = "forced mode"; break; default: p = "not defined"; } - v4l_info(client, "Detected audio mode: %s\n", p); + cx25840_info("Detected audio mode: %s\n", p); switch (mod_det_stat1) { case 0x00: p = "not defined"; break; @@ -1030,10 +937,10 @@ static void log_status(struct i2c_client *client) case 0xff: p = "no detected audio standard"; break; default: p = "not defined"; } - v4l_info(client, "Detected audio standard: %s\n", p); - v4l_info(client, "Audio muted: %s\n", + cx25840_info("Detected audio standard: %s\n", p); + cx25840_info("Audio muted: %s\n", (mute_ctl & 0x2) ? "yes" : "no"); - v4l_info(client, "Audio microcontroller: %s\n", + cx25840_info("Audio microcontroller: %s\n", (download_ctl & 0x10) ? "running" : "stopped"); switch (audio_config >> 4) { @@ -1055,7 +962,7 @@ static void log_status(struct i2c_client *client) case 0x0f: p = "automatic detection"; break; default: p = "undefined"; } - v4l_info(client, "Configured audio standard: %s\n", p); + cx25840_info("Configured audio standard: %s\n", p); if ((audio_config >> 4) < 0xF) { switch (audio_config & 0xF) { @@ -1072,7 +979,7 @@ static void log_status(struct i2c_client *client) case 0x0a: p = "SAP"; break; default: p = "undefined"; } - v4l_info(client, "Configured audio mode: %s\n", p); + cx25840_info("Configured audio mode: %s\n", p); } else { switch (audio_config & 0xF) { case 0x00: p = "BG"; break; @@ -1088,27 +995,30 @@ static void log_status(struct i2c_client *client) case 0x0f: p = "automatic standard and mode detection"; break; default: p = "undefined"; } - v4l_info(client, "Configured audio system: %s\n", p); + cx25840_info("Configured audio system: %s\n", p); } - v4l_info(client, "Specified standard: %s\n", + cx25840_info("Specified standard: %s\n", vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); - if (vid_input >= CX25840_COMPOSITE1 && - vid_input <= CX25840_COMPOSITE8) { - v4l_info(client, "Specified video input: Composite %d\n", - vid_input - CX25840_COMPOSITE1 + 1); - } else { - v4l_info(client, "Specified video input: S-Video (Luma In%d, Chroma In%d)\n", - (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); + switch (state->input) { + case CX25840_COMPOSITE0: p = "Composite 0"; break; + case CX25840_COMPOSITE1: p = "Composite 1"; break; + case CX25840_SVIDEO0: p = "S-Video 0"; break; + case CX25840_SVIDEO1: p = "S-Video 1"; break; + case CX25840_TUNER: p = "Tuner"; break; } - if (aud_input) { - v4l_info(client, "Specified audio input: Tuner (In%d)\n", aud_input); - } else { - v4l_info(client, "Specified audio input: External\n"); + cx25840_info("Specified input: %s\n", p); + cx25840_info("Specified audio input: %s\n", + state->audio_input == 0 ? "Tuner" : "External"); + + switch (state->audclk_freq) { + case V4L2_AUDCLK_441_KHZ: p = "44.1 kHz"; break; + case V4L2_AUDCLK_48_KHZ: p = "48 kHz"; break; + case V4L2_AUDCLK_32_KHZ: p = "32 kHz"; break; + default: p = "undefined"; } - - v4l_info(client, "Specified audioclock freq: %d Hz\n", state->audclk_freq); + cx25840_info("Specified audioclock freq: %s\n", p); switch (pref_mode & 0xf) { case 0: p = "mono/language A"; break; @@ -1121,7 +1031,7 @@ static void log_status(struct i2c_client *client) case 7: p = "language AB"; break; default: p = "undefined"; } - v4l_info(client, "Preferred audio mode: %s\n", p); + cx25840_info("Preferred audio mode: %s\n", p); if ((audio_config & 0xf) == 0xf) { switch ((afc0 >> 3) & 0x3) { @@ -1130,7 +1040,7 @@ static void log_status(struct i2c_client *client) case 2: p = "autodetect"; break; default: p = "undefined"; } - v4l_info(client, "Selected 65 MHz format: %s\n", p); + cx25840_info("Selected 65 MHz format: %s\n", p); switch (afc0 & 0x7) { case 0: p = "chroma"; break; @@ -1140,6 +1050,6 @@ static void log_status(struct i2c_client *client) case 4: p = "autodetect"; break; default: p = "undefined"; } - v4l_info(client, "Selected 45 MHz format: %s\n", p); + cx25840_info("Selected 45 MHz format: %s\n", p); } } diff --git a/trunk/drivers/media/video/cx25840/cx25840-firmware.c b/trunk/drivers/media/video/cx25840/cx25840-firmware.c index e1a7823d82cd..df9d50a75542 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-firmware.c +++ b/trunk/drivers/media/video/cx25840/cx25840-firmware.c @@ -15,6 +15,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + #include #include #include @@ -37,7 +38,7 @@ module_param(firmware, charp, 0444); MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]"); MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); -static void set_i2c_delay(struct i2c_client *client, int delay) +static inline void set_i2c_delay(struct i2c_client *client, int delay) { struct i2c_algo_bit_data *algod = client->adapter->algo_data; @@ -51,7 +52,7 @@ static void set_i2c_delay(struct i2c_client *client, int delay) } } -static void start_fw_load(struct i2c_client *client) +static inline void start_fw_load(struct i2c_client *client) { /* DL_ADDR_LB=0 DL_ADDR_HB=0 */ cx25840_write(client, 0x800, 0x00); @@ -65,7 +66,7 @@ static void start_fw_load(struct i2c_client *client) set_i2c_delay(client, 3); } -static void end_fw_load(struct i2c_client *client) +static inline void end_fw_load(struct i2c_client *client) { if (fastfw) set_i2c_delay(client, 10); @@ -76,47 +77,38 @@ static void end_fw_load(struct i2c_client *client) cx25840_write(client, 0x803, 0x03); } -static int check_fw_load(struct i2c_client *client, int size) +static inline int check_fw_load(struct i2c_client *client, int size) { /* DL_ADDR_HB DL_ADDR_LB */ int s = cx25840_read(client, 0x801) << 8; s |= cx25840_read(client, 0x800); if (size != s) { - v4l_err(client, "firmware %s load failed\n", firmware); + cx25840_err("firmware %s load failed\n", firmware); return -EINVAL; } - v4l_info(client, "loaded %s firmware (%d bytes)\n", firmware, size); + cx25840_info("loaded %s firmware (%d bytes)\n", firmware, size); return 0; } -static int fw_write(struct i2c_client *client, u8 * data, int size) +static inline int fw_write(struct i2c_client *client, u8 * data, int size) { - int sent; - - if ((sent = i2c_master_send(client, data, size)) < size) { + if (i2c_master_send(client, data, size) < size) { if (fastfw) { - v4l_err(client, "333MHz i2c firmware load failed\n"); + cx25840_err("333MHz i2c firmware load failed\n"); fastfw = 0; set_i2c_delay(client, 10); - if (sent > 2) { - u16 dl_addr = cx25840_read(client, 0x801) << 8; - dl_addr |= cx25840_read(client, 0x800); - dl_addr -= sent - 2; - cx25840_write(client, 0x801, dl_addr >> 8); - cx25840_write(client, 0x800, dl_addr & 0xff); - } - if (i2c_master_send(client, data, size) < size) { - v4l_err(client, "100MHz i2c firmware load failed\n"); + cx25840_err + ("100MHz i2c firmware load failed\n"); return -ENOSYS; } } else { - v4l_err(client, "firmware load i2c failure\n"); + cx25840_err("firmware load i2c failure\n"); return -ENOSYS; } @@ -132,7 +124,7 @@ int cx25840_loadfw(struct i2c_client *client) int size, send, retval; if (request_firmware(&fw, firmware, FWDEV(client)) != 0) { - v4l_err(client, "unable to open firmware %s\n", firmware); + cx25840_err("unable to open firmware %s\n", firmware); return -EINVAL; } diff --git a/trunk/drivers/media/video/cx25840/cx25840-vbi.c b/trunk/drivers/media/video/cx25840/cx25840-vbi.c index 04d879da7d63..13ba4e15ddea 100644 --- a/trunk/drivers/media/video/cx25840/cx25840-vbi.c +++ b/trunk/drivers/media/video/cx25840/cx25840-vbi.c @@ -22,7 +22,7 @@ #include "cx25840.h" -static int odd_parity(u8 c) +static inline int odd_parity(u8 c) { c ^= (c >> 4); c ^= (c >> 2); @@ -31,7 +31,7 @@ static int odd_parity(u8 c) return c & 1; } -static int decode_vps(u8 * dst, u8 * p) +static inline int decode_vps(u8 * dst, u8 * p) { static const u8 biphase_tbl[] = { 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, diff --git a/trunk/drivers/media/video/cx25840/cx25840.h b/trunk/drivers/media/video/cx25840/cx25840.h index fd22f30dcc1b..40aa59f9c525 100644 --- a/trunk/drivers/media/video/cx25840/cx25840.h +++ b/trunk/drivers/media/video/cx25840/cx25840.h @@ -24,60 +24,48 @@ #include #include -/* ENABLE_PVR150_WORKAROUND activates a workaround for a hardware bug that is - present in Hauppauge PVR-150 (and possibly PVR-500) cards that have - certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The +extern int cx25840_debug; + +#define cx25840_dbg(fmt, arg...) do { if (cx25840_debug) \ + printk(KERN_INFO "%s debug %d-%04x: " fmt, \ + client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) + +#define cx25840_err(fmt, arg...) do { \ + printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) + +#define cx25840_info(fmt, arg...) do { \ + printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) + +#define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0) + +/* The CARDTYPE_PVR150_WORKAROUND cardtype activates a workaround for a + hardware bug that is present in PVR150 (and possible PVR500) cards that + have certain NTSC tuners (tveeprom model numbers 85, 99 and 112). The audio autodetect fails on some channels for these models and the workaround is to select the audio standard explicitly. Many thanks to Hauppauge for providing this information. */ -#define CX25840_CID_ENABLE_PVR150_WORKAROUND (V4L2_CID_PRIVATE_BASE+0) - -enum cx25840_video_input { - /* Composite video inputs In1-In8 */ - CX25840_COMPOSITE1 = 1, - CX25840_COMPOSITE2, - CX25840_COMPOSITE3, - CX25840_COMPOSITE4, - CX25840_COMPOSITE5, - CX25840_COMPOSITE6, - CX25840_COMPOSITE7, - CX25840_COMPOSITE8, - - /* S-Video inputs consist of one luma input (In1-In4) ORed with one - chroma input (In5-In8) */ - CX25840_SVIDEO_LUMA1 = 0x10, - CX25840_SVIDEO_LUMA2 = 0x20, - CX25840_SVIDEO_LUMA3 = 0x30, - CX25840_SVIDEO_LUMA4 = 0x40, - CX25840_SVIDEO_CHROMA4 = 0x400, - CX25840_SVIDEO_CHROMA5 = 0x500, - CX25840_SVIDEO_CHROMA6 = 0x600, - CX25840_SVIDEO_CHROMA7 = 0x700, - CX25840_SVIDEO_CHROMA8 = 0x800, - - /* S-Video aliases for common luma/chroma combinations */ - CX25840_SVIDEO1 = 0x510, - CX25840_SVIDEO2 = 0x620, - CX25840_SVIDEO3 = 0x730, - CX25840_SVIDEO4 = 0x840, +enum cx25840_cardtype { + CARDTYPE_PVR150, + CARDTYPE_PG600, + CARDTYPE_PVR150_WORKAROUND, }; -enum cx25840_audio_input { - /* Audio inputs: serial or In4-In8 */ - CX25840_AUDIO_SERIAL, - CX25840_AUDIO4 = 4, - CX25840_AUDIO5, - CX25840_AUDIO6, - CX25840_AUDIO7, - CX25840_AUDIO8, +enum cx25840_input { + CX25840_TUNER, + CX25840_COMPOSITE0, + CX25840_COMPOSITE1, + CX25840_SVIDEO0, + CX25840_SVIDEO1 }; struct cx25840_state { - int pvr150_workaround; - int radio; - enum cx25840_video_input vid_input; - enum cx25840_audio_input aud_input; - u32 audclk_freq; + enum cx25840_cardtype cardtype; + enum cx25840_input input; + int audio_input; + enum v4l2_audio_clock_freq audclk_freq; }; /* ----------------------------------------------------------------------- */ @@ -96,7 +84,6 @@ int cx25840_loadfw(struct i2c_client *client); /* ----------------------------------------------------------------------- */ /* cx25850-audio.c */ int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg); -void cx25840_audio_set_path(struct i2c_client *client); /* ----------------------------------------------------------------------- */ /* cx25850-vbi.c */ diff --git a/trunk/drivers/media/video/cx88/Kconfig b/trunk/drivers/media/video/cx88/Kconfig index 76fcb4e995c9..85ba4106dc79 100644 --- a/trunk/drivers/media/video/cx88/Kconfig +++ b/trunk/drivers/media/video/cx88/Kconfig @@ -29,21 +29,6 @@ config VIDEO_CX88_DVB You must also select one or more DVB/ATSC demodulators. If you are unsure which you need, choose all of them. -config VIDEO_CX88_ALSA - tristate "ALSA DMA audio support" - depends on VIDEO_CX88 && SND - select SND_PCM_OSS - ---help--- - This is a video4linux driver for direct (DMA) audio on - Conexant 2388x based TV cards. - It only works with boards with function 01 enabled. - To check if your board supports, use lspci -n. - If supported, you should see 1471:8801 or 1471:8811 - PCI device. - - To compile this driver as a module, choose M here: the - module will be called cx88-alsa. - config VIDEO_CX88_DVB_ALL_FRONTENDS bool "Build all supported frontends for cx2388x based TV cards" default y @@ -53,7 +38,6 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS select DVB_CX22702 select DVB_LGDT330X select DVB_NXT200X - select DVB_CX24123 ---help--- This builds cx88-dvb with all currently supported frontend demodulators. If you wish to tweak your configuration, and @@ -105,12 +89,3 @@ config VIDEO_CX88_DVB_NXT200X ---help--- This adds ATSC 8VSB and QAM64/256 support for cards based on the Connexant 2388x chip and the NXT2002/NXT2004 demodulator. - -config VIDEO_CX88_DVB_CX24123 - bool "Conexant CX24123 DVB-S Support" - default y - depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS - select DVB_CX24123 - ---help--- - This adds DVB-S support for cards based on the - Connexant 2388x chip and the CX24123 demodulator. diff --git a/trunk/drivers/media/video/cx88/Makefile b/trunk/drivers/media/video/cx88/Makefile index e4b2134fe567..54401b02b7ce 100644 --- a/trunk/drivers/media/video/cx88/Makefile +++ b/trunk/drivers/media/video/cx88/Makefile @@ -4,7 +4,7 @@ cx8800-objs := cx88-video.o cx88-vbi.o cx8802-objs := cx88-mpeg.o obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o -obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o cx88-vp3054-i2c.o +obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o EXTRA_CFLAGS += -I$(src)/.. EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core @@ -16,7 +16,5 @@ extra-cflags-$(CONFIG_DVB_OR51132) += -DHAVE_OR51132=1 extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1 extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 -extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1 -extra-cflags-$(CONFIG_VIDEO_CX88_DVB)+= -DHAVE_VP3054_I2C=1 EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) diff --git a/trunk/drivers/media/video/cx88/cx88-alsa.c b/trunk/drivers/media/video/cx88/cx88-alsa.c deleted file mode 100644 index 7695b521eb35..000000000000 --- a/trunk/drivers/media/video/cx88/cx88-alsa.c +++ /dev/null @@ -1,848 +0,0 @@ -/* - * - * Support for audio capture - * PCI function #1 of the cx2388x. - * - * (c) 2005,2006 Ricardo Cerqueira - * (c) 2005 Mauro Carvalho Chehab - * Based on a dummy cx88 module by Gerd Knorr - * Based on dummy.c by Jaroslav Kysela - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cx88.h" -#include "cx88-reg.h" - -#define dprintk(level,fmt, arg...) if (debug >= level) \ - printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg) - -#define dprintk_core(level,fmt, arg...) if (debug >= level) \ - printk(KERN_DEBUG "%s/1: " fmt, chip->core->name , ## arg) - - -/**************************************************************************** - Data type declarations - Can be moded to a header file later - ****************************************************************************/ - -/* These can be replaced after done */ -#define MIXER_ADDR_LAST MAX_CX88_INPUT - -struct cx88_audio_dev { - struct cx88_core *core; - struct cx88_dmaqueue q; - - /* pci i/o */ - struct pci_dev *pci; - unsigned char pci_rev,pci_lat; - - /* audio controls */ - int irq; - - snd_card_t *card; - - spinlock_t reg_lock; - - unsigned int dma_size; - unsigned int period_size; - unsigned int num_periods; - - struct videobuf_dmabuf dma_risc; - - int mixer_volume[MIXER_ADDR_LAST+1][2]; - int capture_source[MIXER_ADDR_LAST+1][2]; - - long int read_count; - long int read_offset; - - struct cx88_buffer *buf; - - long opened; - snd_pcm_substream_t *substream; - -}; -typedef struct cx88_audio_dev snd_cx88_card_t; - - - -/**************************************************************************** - Module global static vars - ****************************************************************************/ - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ -static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1}; -static snd_card_t *snd_cx88_cards[SNDRV_CARDS]; - -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled."); - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for cx88x capture interface(s)."); - - -/**************************************************************************** - Module macros - ****************************************************************************/ - -MODULE_DESCRIPTION("ALSA driver module for cx2388x based TV cards"); -MODULE_AUTHOR("Ricardo Cerqueira"); -MODULE_AUTHOR("Mauro Carvalho Chehab "); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{Conexant,23881}," - "{{Conexant,23882}," - "{{Conexant,23883}"); -static unsigned int debug = 0; -module_param(debug,int,0644); -MODULE_PARM_DESC(debug,"enable debug messages"); - -/**************************************************************************** - Module specific funtions - ****************************************************************************/ - -/* - * BOARD Specific: Sets audio DMA - */ - -int _cx88_start_audio_dma(snd_cx88_card_t *chip) -{ - struct cx88_buffer *buf = chip->buf; - struct cx88_core *core=chip->core; - struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25]; - - - dprintk(1, "Starting audio DMA for %i bytes/line and %i (%i) lines at address %08x\n",buf->bpl, chip->num_periods, audio_ch->fifo_size / buf->bpl, audio_ch->fifo_start); - - /* setup fifo + format - out channel */ - cx88_sram_channel_setup(chip->core, &cx88_sram_channels[SRAM_CH25], - buf->bpl, buf->risc.dma); - - /* sets bpl size */ - cx_write(MO_AUDD_LNGTH, buf->bpl); - - /* reset counter */ - cx_write(MO_AUDD_GPCNTRL,GP_COUNT_CONTROL_RESET); - - dprintk(1,"Enabling IRQ, setting mask from 0x%x to 0x%x\n",chip->core->pci_irqmask,(chip->core->pci_irqmask | 0x02)); - /* enable irqs */ - cx_set(MO_PCI_INTMSK, chip->core->pci_irqmask | 0x02); - - - /* Enables corresponding bits at AUD_INT_STAT */ - cx_write(MO_AUD_INTMSK, - (1<<16)| - (1<<12)| - (1<<4)| - (1<<0) - ); - - /* start dma */ - cx_set(MO_DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */ - cx_set(MO_AUD_DMACNTRL, 0x11); /* audio downstream FIFO and RISC enable */ - - if (debug) - cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]); - - return 0; -} - -/* - * BOARD Specific: Resets audio DMA - */ -int _cx88_stop_audio_dma(snd_cx88_card_t *chip) -{ - struct cx88_core *core=chip->core; - dprintk(1, "Stopping audio DMA\n"); - - /* stop dma */ - cx_clear(MO_AUD_DMACNTRL, 0x11); - - /* disable irqs */ - cx_clear(MO_PCI_INTMSK, 0x02); - cx_clear(MO_AUD_INTMSK, - (1<<16)| - (1<<12)| - (1<<4)| - (1<<0) - ); - - if (debug) - cx88_sram_channel_dump(chip->core, &cx88_sram_channels[SRAM_CH25]); - - return 0; -} - -#define MAX_IRQ_LOOP 10 - -/* - * BOARD Specific: IRQ dma bits - */ -static char *cx88_aud_irqs[32] = { - "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */ - NULL, /* reserved */ - "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */ - NULL, /* reserved */ - "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */ - NULL, /* reserved */ - "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */ - NULL, /* reserved */ - "opc_err", "par_err", "rip_err", /* 16-18 */ - "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */ -}; - -/* - * BOARD Specific: Threats IRQ audio specific calls - */ -static void cx8801_aud_irq(snd_cx88_card_t *chip) -{ - struct cx88_core *core = chip->core; - u32 status, mask; - u32 count; - - status = cx_read(MO_AUD_INTSTAT); - mask = cx_read(MO_AUD_INTMSK); - if (0 == (status & mask)) { - spin_unlock(&chip->reg_lock); - return; - } - cx_write(MO_AUD_INTSTAT, status); - if (debug > 1 || (status & mask & ~0xff)) - cx88_print_irqbits(core->name, "irq aud", - cx88_aud_irqs, status, mask); - /* risc op code error */ - if (status & (1 << 16)) { - printk(KERN_WARNING "%s/0: audio risc op code error\n",core->name); - cx_clear(MO_AUD_DMACNTRL, 0x11); - cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH25]); - } - - /* risc1 downstream */ - if (status & 0x01) { - spin_lock(&chip->reg_lock); - count = cx_read(MO_AUDD_GPCNT); - spin_unlock(&chip->reg_lock); - if (chip->read_count == 0) - chip->read_count += chip->dma_size; - } - - if (chip->read_count >= chip->period_size) { - dprintk(2, "Elapsing period\n"); - snd_pcm_period_elapsed(chip->substream); - } - - dprintk(3,"Leaving audio IRQ handler...\n"); - - /* FIXME: Any other status should deserve a special handling? */ -} - -/* - * BOARD Specific: Handles IRQ calls - */ -static irqreturn_t cx8801_irq(int irq, void *dev_id, struct pt_regs *regs) -{ - snd_cx88_card_t *chip = dev_id; - struct cx88_core *core = chip->core; - u32 status; - int loop, handled = 0; - - for (loop = 0; loop < MAX_IRQ_LOOP; loop++) { - status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x02); - if (0 == status) - goto out; - dprintk( 3, "cx8801_irq\n" ); - dprintk( 3, " loop: %d/%d\n", loop, MAX_IRQ_LOOP ); - dprintk( 3, " status: %d\n", status ); - handled = 1; - cx_write(MO_PCI_INTSTAT, status); - - if (status & 0x02) - { - dprintk( 2, " ALSA IRQ handling\n" ); - cx8801_aud_irq(chip); - } - }; - - if (MAX_IRQ_LOOP == loop) { - dprintk( 0, "clearing mask\n" ); - dprintk(1,"%s/0: irq loop -- clearing mask\n", - core->name); - cx_clear(MO_PCI_INTMSK,0x02); - } - - out: - return IRQ_RETVAL(handled); -} - - -static int dsp_buffer_free(snd_cx88_card_t *chip) -{ - BUG_ON(!chip->dma_size); - - dprintk(2,"Freeing buffer\n"); - videobuf_dma_pci_unmap(chip->pci, &chip->dma_risc); - videobuf_dma_free(&chip->dma_risc); - btcx_riscmem_free(chip->pci,&chip->buf->risc); - kfree(chip->buf); - - chip->dma_size = 0; - - return 0; -} - -/**************************************************************************** - ALSA PCM Interface - ****************************************************************************/ - -/* - * Digital hardware definition - */ -static snd_pcm_hardware_t snd_cx88_digital_hw = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - - .rates = SNDRV_PCM_RATE_48000, - .rate_min = 48000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = (2*2048), - .period_bytes_min = 256, - .period_bytes_max = 2048, - .periods_min = 2, - .periods_max = 16, -}; - -/* - * audio pcm capture runtime free - */ -static void snd_card_cx88_runtime_free(snd_pcm_runtime_t *runtime) -{ -} -/* - * audio pcm capture open callback - */ -static int snd_cx88_pcm_open(snd_pcm_substream_t *substream) -{ - snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - int err; - - if (test_and_set_bit(0, &chip->opened)) - return -EBUSY; - - err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); - if (err < 0) - goto _error; - - chip->substream = substream; - - chip->read_count = 0; - chip->read_offset = 0; - - runtime->private_free = snd_card_cx88_runtime_free; - runtime->hw = snd_cx88_digital_hw; - - return 0; -_error: - dprintk(1,"Error opening PCM!\n"); - clear_bit(0, &chip->opened); - smp_mb__after_clear_bit(); - return err; -} - -/* - * audio close callback - */ -static int snd_cx88_close(snd_pcm_substream_t *substream) -{ - snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); - - clear_bit(0, &chip->opened); - smp_mb__after_clear_bit(); - - return 0; -} - -/* - * hw_params callback - */ -static int snd_cx88_hw_params(snd_pcm_substream_t * substream, - snd_pcm_hw_params_t * hw_params) -{ - snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); - struct cx88_buffer *buf; - - if (substream->runtime->dma_area) { - dsp_buffer_free(chip); - substream->runtime->dma_area = NULL; - } - - - chip->period_size = params_period_bytes(hw_params); - chip->num_periods = params_periods(hw_params); - chip->dma_size = chip->period_size * params_periods(hw_params); - - BUG_ON(!chip->dma_size); - - dprintk(1,"Setting buffer\n"); - - buf = kmalloc(sizeof(*buf),GFP_KERNEL); - if (NULL == buf) - return -ENOMEM; - memset(buf,0,sizeof(*buf)); - - - buf->vb.memory = V4L2_MEMORY_MMAP; - buf->vb.width = chip->period_size; - buf->vb.height = chip->num_periods; - buf->vb.size = chip->dma_size; - buf->vb.field = V4L2_FIELD_NONE; - - videobuf_dma_init(&buf->vb.dma); - videobuf_dma_init_kernel(&buf->vb.dma,PCI_DMA_FROMDEVICE, - (PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT)); - - videobuf_dma_pci_map(chip->pci,&buf->vb.dma); - - - cx88_risc_databuffer(chip->pci, &buf->risc, - buf->vb.dma.sglist, - buf->vb.width, buf->vb.height); - - buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - - buf->vb.state = STATE_PREPARED; - - buf->bpl = chip->period_size; - chip->buf = buf; - chip->dma_risc = buf->vb.dma; - - dprintk(1,"Buffer ready at %u\n",chip->dma_risc.nr_pages); - substream->runtime->dma_area = chip->dma_risc.vmalloc; - return 0; -} - -/* - * hw free callback - */ -static int snd_cx88_hw_free(snd_pcm_substream_t * substream) -{ - - snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); - - if (substream->runtime->dma_area) { - dsp_buffer_free(chip); - substream->runtime->dma_area = NULL; - } - - return 0; -} - -/* - * prepare callback - */ -static int snd_cx88_prepare(snd_pcm_substream_t *substream) -{ - return 0; -} - - -/* - * trigger callback - */ -static int snd_cx88_card_trigger(snd_pcm_substream_t *substream, int cmd) -{ - snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); - int err; - - spin_lock(&chip->reg_lock); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - err=_cx88_start_audio_dma(chip); - break; - case SNDRV_PCM_TRIGGER_STOP: - err=_cx88_stop_audio_dma(chip); - break; - default: - err=-EINVAL; - break; - } - - spin_unlock(&chip->reg_lock); - - return err; -} - -/* - * pointer callback - */ -static snd_pcm_uframes_t snd_cx88_pointer(snd_pcm_substream_t *substream) -{ - snd_cx88_card_t *chip = snd_pcm_substream_chip(substream); - snd_pcm_runtime_t *runtime = substream->runtime; - - if (chip->read_count) { - chip->read_count -= snd_pcm_lib_period_bytes(substream); - chip->read_offset += snd_pcm_lib_period_bytes(substream); - if (chip->read_offset == chip->dma_size) - chip->read_offset = 0; - } - - dprintk(2, "Pointer time, will return %li, read %li\n",chip->read_offset,chip->read_count); - return bytes_to_frames(runtime, chip->read_offset); - -} - -/* - * operators - */ -static snd_pcm_ops_t snd_cx88_pcm_ops = { - .open = snd_cx88_pcm_open, - .close = snd_cx88_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_cx88_hw_params, - .hw_free = snd_cx88_hw_free, - .prepare = snd_cx88_prepare, - .trigger = snd_cx88_card_trigger, - .pointer = snd_cx88_pointer, -}; - -/* - * create a PCM device - */ -static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name) -{ - int err; - snd_pcm_t *pcm; - - err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm); - if (err < 0) - return err; - pcm->private_data = chip; - strcpy(pcm->name, name); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx88_pcm_ops); - - return 0; -} - -/**************************************************************************** - CONTROL INTERFACE - ****************************************************************************/ -static int snd_cx88_capture_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *info) -{ - info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - info->count = 1; - info->value.integer.min = 0; - info->value.integer.max = 0x3f; - - return 0; -} - -/* OK - TODO: test it */ -static int snd_cx88_capture_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value) -{ - snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); - struct cx88_core *core=chip->core; - - value->value.integer.value[0] = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f); - - return 0; -} - -/* OK - TODO: test it */ -static int snd_cx88_capture_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *value) -{ - snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); - struct cx88_core *core=chip->core; - int v; - u32 old_control; - - spin_lock_irq(&chip->reg_lock); - old_control = 0x3f - (cx_read(AUD_VOL_CTL) & 0x3f); - v = 0x3f - (value->value.integer.value[0] & 0x3f); - cx_andor(AUD_VOL_CTL, 0x3f, v); - spin_unlock_irq(&chip->reg_lock); - - return v != old_control; -} - -static snd_kcontrol_new_t snd_cx88_capture_volume = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Volume", - .info = snd_cx88_capture_volume_info, - .get = snd_cx88_capture_volume_get, - .put = snd_cx88_capture_volume_put, -}; - - -/**************************************************************************** - Basic Flow for Sound Devices - ****************************************************************************/ - -/* - * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio - * Only boards with eeprom and byte 1 at eeprom=1 have it - */ - -struct pci_device_id cx88_audio_pci_tbl[] = { - {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, - {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, - {0, } -}; -MODULE_DEVICE_TABLE(pci, cx88_audio_pci_tbl); - -/* - * Chip-specific destructor - */ - -static int snd_cx88_free(snd_cx88_card_t *chip) -{ - - if (chip->irq >= 0){ - synchronize_irq(chip->irq); - free_irq(chip->irq, chip); - } - - cx88_core_put(chip->core,chip->pci); - - pci_disable_device(chip->pci); - return 0; -} - -/* - * Component Destructor - */ -static void snd_cx88_dev_free(snd_card_t * card) -{ - snd_cx88_card_t *chip = card->private_data; - - snd_cx88_free(chip); -} - - -/* - * Alsa Constructor - Component probe - */ - -static int devno=0; -static int __devinit snd_cx88_create(snd_card_t *card, struct pci_dev *pci, - snd_cx88_card_t **rchip) -{ - snd_cx88_card_t *chip; - struct cx88_core *core; - int err; - - *rchip = NULL; - - err = pci_enable_device(pci); - if (err < 0) - return err; - - pci_set_master(pci); - - chip = (snd_cx88_card_t *) card->private_data; - - core = cx88_core_get(pci); - - if (!pci_dma_supported(pci,0xffffffff)) { - dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name); - err = -EIO; - cx88_core_put(core,pci); - return err; - } - - - /* pci init */ - chip->card = card; - chip->pci = pci; - chip->irq = -1; - spin_lock_init(&chip->reg_lock); - - cx88_reset(core); - if (NULL == core) { - err = -EINVAL; - kfree (chip); - return err; - } - chip->core = core; - - /* get irq */ - err = request_irq(chip->pci->irq, cx8801_irq, - SA_SHIRQ | SA_INTERRUPT, chip->core->name, chip); - if (err < 0) { - dprintk(0, "%s: can't get IRQ %d\n", - chip->core->name, chip->pci->irq); - return err; - } - - /* print pci info */ - pci_read_config_byte(pci, PCI_CLASS_REVISION, &chip->pci_rev); - pci_read_config_byte(pci, PCI_LATENCY_TIMER, &chip->pci_lat); - - dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%lx\n", core->name, devno, - pci_name(pci), chip->pci_rev, pci->irq, - chip->pci_lat,pci_resource_start(pci,0)); - - chip->irq = pci->irq; - synchronize_irq(chip->irq); - - snd_card_set_dev(card, &pci->dev); - - *rchip = chip; - - return 0; -} - -static int __devinit cx88_audio_initdev(struct pci_dev *pci, - const struct pci_device_id *pci_id) -{ - snd_card_t *card; - snd_cx88_card_t *chip; - int err; - - if (devno >= SNDRV_CARDS) - return (-ENODEV); - - if (!enable[devno]) { - ++devno; - return (-ENOENT); - } - - card = snd_card_new(index[devno], id[devno], THIS_MODULE, sizeof(snd_cx88_card_t)); - if (!card) - return (-ENOMEM); - - card->private_free = snd_cx88_dev_free; - - err = snd_cx88_create(card, pci, &chip); - if (err < 0) - return (err); - - err = snd_cx88_pcm(chip, 0, "CX88 Digital"); - - if (err < 0) { - snd_card_free(card); - return (err); - } - - err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_capture_volume, chip)); - if (err < 0) { - snd_card_free(card); - return (err); - } - - strcpy (card->driver, "CX88x"); - sprintf(card->shortname, "Conexant CX%x", pci->device); - sprintf(card->longname, "%s at %#lx", - card->shortname, pci_resource_start(pci, 0)); - strcpy (card->mixername, "CX88"); - - dprintk (0, "%s/%i: ALSA support for cx2388x boards\n", - card->driver,devno); - - err = snd_card_register(card); - if (err < 0) { - snd_card_free(card); - return (err); - } - snd_cx88_cards[devno] = card; - - pci_set_drvdata(pci,card); - - devno++; - return 0; -} -/* - * ALSA destructor - */ -static void __devexit cx88_audio_finidev(struct pci_dev *pci) -{ - struct cx88_audio_dev *card = pci_get_drvdata(pci); - - snd_card_free((void *)card); - - pci_set_drvdata(pci, NULL); - - devno--; -} - -/* - * PCI driver definition - */ - -static struct pci_driver cx88_audio_pci_driver = { - .name = "cx88_audio", - .id_table = cx88_audio_pci_tbl, - .probe = cx88_audio_initdev, - .remove = cx88_audio_finidev, - SND_PCI_PM_CALLBACKS -}; - -/**************************************************************************** - LINUX MODULE INIT - ****************************************************************************/ - -/* - * module init - */ -static int cx88_audio_init(void) -{ - printk(KERN_INFO "cx2388x alsa driver version %d.%d.%d loaded\n", - (CX88_VERSION_CODE >> 16) & 0xff, - (CX88_VERSION_CODE >> 8) & 0xff, - CX88_VERSION_CODE & 0xff); -#ifdef SNAPSHOT - printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", - SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); -#endif - return pci_register_driver(&cx88_audio_pci_driver); -} - -/* - * module remove - */ -static void cx88_audio_fini(void) -{ - - pci_unregister_driver(&cx88_audio_pci_driver); -} - -module_init(cx88_audio_init); -module_exit(cx88_audio_fini); - -/* ----------------------------------------------------------- */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/trunk/drivers/media/video/cx88/cx88-blackbird.c b/trunk/drivers/media/video/cx88/cx88-blackbird.c index a49062119313..74e57a53116f 100644 --- a/trunk/drivers/media/video/cx88/cx88-blackbird.c +++ b/trunk/drivers/media/video/cx88/cx88-blackbird.c @@ -32,10 +32,10 @@ #include #include "cx88.h" -#include MODULE_DESCRIPTION("driver for cx2388x/cx23416 based mpeg encoder cards"); -MODULE_AUTHOR("Jelle Foks , Gerd Knorr [SuSE Labs]"); +MODULE_AUTHOR("Jelle Foks "); +MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); MODULE_LICENSE("GPL"); static unsigned int mpegbufs = 32; @@ -1375,7 +1375,7 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, struct cx88_core *core = dev->core; if (debug > 1) - v4l_print_ioctl(core->name,cmd); + cx88_print_ioctl(core->name,cmd); switch (cmd) { @@ -1689,18 +1689,6 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev, memcpy(&dev->params,&default_mpeg_params,sizeof(default_mpeg_params)); memcpy(&dev->dnr_params,&default_dnr_params,sizeof(default_dnr_params)); - if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN) { - - if (core->tuner_formats & V4L2_STD_525_60) { - dev->height = 480; - dev->params.vi_frame_rate = 30; - } else { - dev->height = 576; - dev->params.vi_frame_rate = 25; - } - - } - err = cx8802_init_common(dev); if (0 != err) goto fail_free; diff --git a/trunk/drivers/media/video/cx88/cx88-cards.c b/trunk/drivers/media/video/cx88/cx88-cards.c index a76d54503b6f..951709aa88ba 100644 --- a/trunk/drivers/media/video/cx88/cx88-cards.c +++ b/trunk/drivers/media/video/cx88/cx88-cards.c @@ -611,12 +611,12 @@ struct cx88_board cx88_boards[] = { .input = {{ .type = CX88_VMUX_TELEVISION, .vmux = 0, - .gpio0 = 0xed1a, + .gpio0 = 0xed12, /* internal decoder */ .gpio2 = 0x00ff, },{ .type = CX88_VMUX_DEBUG, .vmux = 0, - .gpio0 = 0xff01, + .gpio0 = 0xff01, /* mono from tuner chip */ },{ .type = CX88_VMUX_COMPOSITE1, .vmux = 1, @@ -708,7 +708,7 @@ struct cx88_board cx88_boards[] = { }, [CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T] = { .name = "DViCO FusionHDTV 3 Gold-T", - .tuner_type = TUNER_THOMSON_DTT761X, + .tuner_type = TUNER_THOMSON_DTT7611, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, @@ -897,158 +897,6 @@ struct cx88_board cx88_boards[] = { .gpio3 = 0x0000, }}, }, - [CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1] = { - .name = "Hauppauge Nova-S-Plus DVB-S", - .tuner_type = TUNER_ABSENT, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_DVB, - .vmux = 0, - },{ - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - },{ - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - }}, - .dvb = 1, - }, - [CX88_BOARD_HAUPPAUGE_NOVASE2_S1] = { - .name = "Hauppauge Nova-SE2 DVB-S", - .tuner_type = TUNER_ABSENT, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_DVB, - .vmux = 0, - }}, - .dvb = 1, - }, - [CX88_BOARD_KWORLD_DVBS_100] = { - .name = "KWorld DVB-S 100", - .tuner_type = TUNER_ABSENT, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_DVB, - .vmux = 0, - },{ - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - },{ - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - }}, - .dvb = 1, - }, - [CX88_BOARD_HAUPPAUGE_HVR1100] = { - .name = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid", - .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT, - .input = {{ - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - },{ - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - },{ - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - }}, - /* fixme: Add radio support */ - .dvb = 1, - }, - [CX88_BOARD_HAUPPAUGE_HVR1100LP] = { - .name = "Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile)", - .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT, - .input = {{ - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - },{ - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - }}, - /* fixme: Add radio support */ - .dvb = 1, - }, - [CX88_BOARD_DNTV_LIVE_DVB_T_PRO] = { - .name = "digitalnow DNTV Live! DVB-T Pro", - .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE | - TDA9887_PORT2_ACTIVE, - .input = {{ - .type = CX88_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0xf80808, - },{ - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0xf80808, - },{ - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0xf80808, - }}, - .radio = { - .type = CX88_RADIO, - .gpio0 = 0xf80808, - }, - .dvb = 1, - }, - [CX88_BOARD_KWORLD_DVB_T_CX22702] = { - /* Kworld V-stream Xpert DVB-T with Thomson tuner */ - /* DTT 7579 Conexant CX22702-19 Conexant CX2388x */ - /* Manenti Marco */ - .name = "KWorld/VStream XPert DVB-T with cx22702", - .tuner_type = TUNER_ABSENT, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0x0700, - .gpio2 = 0x0101, - },{ - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0x0700, - .gpio2 = 0x0101, - }}, - .dvb = 1, - }, - [CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL] = { - .name = "DViCO FusionHDTV DVB-T Dual Digital", - .tuner_type = TUNER_ABSENT, /* No analog tuner */ - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX88_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0x000027df, - },{ - .type = CX88_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0x000027df, - }}, - .dvb = 1, - }, - }; const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); @@ -1196,54 +1044,6 @@ struct cx88_subid cx88_subids[] = { .subvendor = 0x1461, .subdevice = 0x000a, .card = CX88_BOARD_AVERTV_303, - },{ - .subvendor = 0x0070, - .subdevice = 0x9200, - .card = CX88_BOARD_HAUPPAUGE_NOVASE2_S1, - },{ - .subvendor = 0x0070, - .subdevice = 0x9201, - .card = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1, - },{ - .subvendor = 0x0070, - .subdevice = 0x9202, - .card = CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1, - },{ - .subvendor = 0x17de, - .subdevice = 0x08b2, - .card = CX88_BOARD_KWORLD_DVBS_100, - },{ - .subvendor = 0x0070, - .subdevice = 0x9400, - .card = CX88_BOARD_HAUPPAUGE_HVR1100, - },{ - .subvendor = 0x0070, - .subdevice = 0x9402, - .card = CX88_BOARD_HAUPPAUGE_HVR1100, - },{ - .subvendor = 0x0070, - .subdevice = 0x9800, - .card = CX88_BOARD_HAUPPAUGE_HVR1100LP, - },{ - .subvendor = 0x0070, - .subdevice = 0x9802, - .card = CX88_BOARD_HAUPPAUGE_HVR1100LP, - },{ - .subvendor = 0x0070, - .subdevice = 0x9001, - .card = CX88_BOARD_HAUPPAUGE_DVB_T1, - },{ - .subvendor = 0x1822, - .subdevice = 0x0025, - .card = CX88_BOARD_DNTV_LIVE_DVB_T_PRO, - },{ - .subvendor = 0x17de, - .subdevice = 0x08a1, - .card = CX88_BOARD_KWORLD_DVB_T_CX22702, - },{ - .subvendor = 0x18ac, - .subdevice = 0xdb50, - .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL, }, }; const unsigned int cx88_idcount = ARRAY_SIZE(cx88_subids); @@ -1275,19 +1075,20 @@ static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) core->name, core->tuner_type, eeprom_data[0]); } + +/* ----------------------------------------------------------------------- */ + static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) { struct tveeprom tv; tveeprom_hauppauge_analog(&core->i2c_client, &tv, eeprom_data); core->tuner_type = tv.tuner_type; - core->tuner_formats = tv.tuner_formats; core->has_radio = tv.has_radio; /* Make sure we support the board model */ switch (tv.model) { - case 28552: /* WinTV-PVR 'Roslyn' (No IR) */ case 90002: /* Nova-T-PCI (9002) */ case 92001: /* Nova-S-Plus (Video and IR) */ case 92002: /* Nova-S-Plus (Video and IR) */ @@ -1295,9 +1096,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) case 90500: /* Nova-T-PCI (oem) */ case 90501: /* Nova-T-PCI (oem/IR) */ case 92000: /* Nova-SE2 (OEM, No Video or IR) */ - case 94009: /* WinTV-HVR1100 (Video and IR Retail) */ - case 94501: /* WinTV-HVR1100 (Video and IR OEM) */ - case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */ + /* known */ break; default: @@ -1412,21 +1211,12 @@ void cx88_card_setup(struct cx88_core *core) if (0 == core->i2c_rc) leadtek_eeprom(core,eeprom); break; - case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: - case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: case CX88_BOARD_HAUPPAUGE_DVB_T1: - case CX88_BOARD_HAUPPAUGE_HVR1100: - case CX88_BOARD_HAUPPAUGE_HVR1100LP: if (0 == core->i2c_rc) hauppauge_eeprom(core,eeprom); break; - case CX88_BOARD_KWORLD_DVBS_100: - cx_write(MO_GP0_IO, 0x000007f8); - cx_write(MO_GP1_IO, 0x00000001); - break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: - case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: /* GPIO0:0 is hooked to mt352 reset pin */ cx_set(MO_GP0_IO, 0x00000101); cx_clear(MO_GP0_IO, 0x00000001); @@ -1442,9 +1232,6 @@ void cx88_card_setup(struct cx88_core *core) cx_clear(MO_GP0_IO, 0x00000007); cx_set(MO_GP2_IO, 0x00000101); break; - case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: - cx_write(MO_GP0_IO, 0x00080808); - break; case CX88_BOARD_ATI_HDTVWONDER: if (0 == core->i2c_rc) { /* enable tuner */ diff --git a/trunk/drivers/media/video/cx88/cx88-core.c b/trunk/drivers/media/video/cx88/cx88-core.c index 9975be1aca38..bb6eb54e19ce 100644 --- a/trunk/drivers/media/video/cx88/cx88-core.c +++ b/trunk/drivers/media/video/cx88/cx88-core.c @@ -34,7 +34,6 @@ #include #include "cx88.h" -#include MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); MODULE_AUTHOR("Gerd Knorr [SuSE Labs]"); @@ -77,6 +76,60 @@ static unsigned int cx88_devcount; static LIST_HEAD(cx88_devlist); static DECLARE_MUTEX(devlist); +/* ------------------------------------------------------------------ */ +/* debug help functions */ + +static const char *v4l1_ioctls[] = { + "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT", + "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ", + "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT", + "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", + "SMICROCODE", "GVBIFMT", "SVBIFMT" }; +#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) + +static const char *v4l2_ioctls[] = { + "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT", + "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF", + "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON", + "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD", + "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER", + "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL", + "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43", + "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT", + "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR", + "S_MODULATOR" +}; +#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) + +void cx88_print_ioctl(char *name, unsigned int cmd) +{ + char *dir; + + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: dir = "--"; break; + case _IOC_READ: dir = "r-"; break; + case _IOC_WRITE: dir = "-w"; break; + case _IOC_READ | _IOC_WRITE: dir = "rw"; break; + default: dir = "??"; break; + } + switch (_IOC_TYPE(cmd)) { + case 'v': + printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n", + name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ? + v4l1_ioctls[_IOC_NR(cmd)] : "???"); + break; + case 'V': + printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n", + name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ? + v4l2_ioctls[_IOC_NR(cmd)] : "???"); + break; + default: + printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n", + name, cmd, dir, _IOC_NR(cmd)); + } +} + +/* ------------------------------------------------------------------ */ #define NO_SYNC_LINE (-1U) static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist, @@ -238,9 +291,9 @@ cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf) * channel 22 (u video) - 2.0k * channel 23 (v video) - 2.0k * channel 24 (vbi) - 4.0k - * channels 25+26 (audio) - 4.0k + * channels 25+26 (audio) - 0.5k * channel 28 (mpeg) - 4.0k - * TOTAL = 29.0k + * TOTAL = 25.5k * * Every channel has 160 bytes control data (64 bytes instruction * queue and 6 CDT entries), which is close to 2k total. @@ -306,7 +359,7 @@ struct sram_channel cx88_sram_channels[] = { .ctrl_start = 0x180680, .cdt = 0x180680 + 64, .fifo_start = 0x185400, - .fifo_size = 0x001000, + .fifo_size = 0x000200, .ptr1_reg = MO_DMA25_PTR1, .ptr2_reg = MO_DMA25_PTR2, .cnt1_reg = MO_DMA25_CNT1, @@ -318,7 +371,7 @@ struct sram_channel cx88_sram_channels[] = { .ctrl_start = 0x180720, .cdt = 0x180680 + 64, /* same as audio IN */ .fifo_start = 0x185400, /* same as audio IN */ - .fifo_size = 0x001000, /* same as audio IN */ + .fifo_size = 0x000200, /* same as audio IN */ .ptr1_reg = MO_DMA26_PTR1, .ptr2_reg = MO_DMA26_PTR2, .cnt1_reg = MO_DMA26_CNT1, @@ -329,7 +382,7 @@ struct sram_channel cx88_sram_channels[] = { .cmds_start = 0x180200, .ctrl_start = 0x1807C0, .cdt = 0x1807C0 + 64, - .fifo_start = 0x186400, + .fifo_start = 0x185600, .fifo_size = 0x001000, .ptr1_reg = MO_DMA28_PTR1, .ptr2_reg = MO_DMA28_PTR2, @@ -795,6 +848,7 @@ int cx88_start_audio_dma(struct cx88_core *core) /* start dma */ cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */ + return 0; } @@ -1154,6 +1208,7 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci) /* ------------------------------------------------------------------ */ +EXPORT_SYMBOL(cx88_print_ioctl); EXPORT_SYMBOL(cx88_print_irqbits); EXPORT_SYMBOL(cx88_core_irq); diff --git a/trunk/drivers/media/video/cx88/cx88-dvb.c b/trunk/drivers/media/video/cx88/cx88-dvb.c index 42c012aaa849..99ea955f5987 100644 --- a/trunk/drivers/media/video/cx88/cx88-dvb.c +++ b/trunk/drivers/media/video/cx88/cx88-dvb.c @@ -3,7 +3,7 @@ * device driver for Conexant 2388x based TV cards * MPEG Transport Stream (DVB) routines * - * (c) 2004, 2005 Chris Pascoe + * (c) 2004 Chris Pascoe * (c) 2004 Gerd Knorr [SuSE Labs] * * This program is free software; you can redistribute it and/or modify @@ -31,14 +31,10 @@ #include "cx88.h" #include "dvb-pll.h" -#include #ifdef HAVE_MT352 # include "mt352.h" # include "mt352_priv.h" -# ifdef HAVE_VP3054_I2C -# include "cx88-vp3054-i2c.h" -# endif #endif #ifdef HAVE_CX22702 # include "cx22702.h" @@ -52,9 +48,6 @@ #ifdef HAVE_NXT200X # include "nxt200x.h" #endif -#ifdef HAVE_CX24123 -# include "cx24123.h" -#endif MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); MODULE_AUTHOR("Chris Pascoe "); @@ -132,27 +125,6 @@ static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) return 0; } -static int dvico_dual_demod_init(struct dvb_frontend *fe) -{ - static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 }; - static u8 reset [] = { RESET, 0x80 }; - static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; - static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; - static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; - static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; - - mt352_write(fe, clock_config, sizeof(clock_config)); - udelay(200); - mt352_write(fe, reset, sizeof(reset)); - mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); - - mt352_write(fe, agc_cfg, sizeof(agc_cfg)); - mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); - mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); - - return 0; -} - static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) { static u8 clock_config [] = { 0x89, 0x38, 0x39 }; @@ -200,98 +172,6 @@ static struct mt352_config dntv_live_dvbt_config = { .demod_init = dntv_live_dvbt_demod_init, .pll_set = mt352_pll_set, }; - -static struct mt352_config dvico_fusionhdtv_dual = { - .demod_address = 0x0F, - .demod_init = dvico_dual_demod_init, - .pll_set = mt352_pll_set, -}; - -#ifdef HAVE_VP3054_I2C -static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) -{ - static u8 clock_config [] = { 0x89, 0x38, 0x38 }; - static u8 reset [] = { 0x50, 0x80 }; - static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; - static u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF, - 0x00, 0xFF, 0x00, 0x40, 0x40 }; - static u8 dntv_extra[] = { 0xB5, 0x7A }; - static u8 capt_range_cfg[] = { 0x75, 0x32 }; - - mt352_write(fe, clock_config, sizeof(clock_config)); - udelay(2000); - mt352_write(fe, reset, sizeof(reset)); - mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); - - mt352_write(fe, agc_cfg, sizeof(agc_cfg)); - udelay(2000); - mt352_write(fe, dntv_extra, sizeof(dntv_extra)); - mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); - - return 0; -} - -static int philips_fmd1216_pll_init(struct dvb_frontend *fe) -{ - struct cx8802_dev *dev= fe->dvb->priv; - - /* this message is to set up ATC and ALC */ - static u8 fmd1216_init[] = { 0x0b, 0xdc, 0x9c, 0xa0 }; - struct i2c_msg msg = - { .addr = dev->core->pll_addr, .flags = 0, - .buf = fmd1216_init, .len = sizeof(fmd1216_init) }; - int err; - - if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { - if (err < 0) - return err; - else - return -EREMOTEIO; - } - - return 0; -} - -static int dntv_live_dvbt_pro_pll_set(struct dvb_frontend* fe, - struct dvb_frontend_parameters* params, - u8* pllbuf) -{ - struct cx8802_dev *dev= fe->dvb->priv; - struct i2c_msg msg = - { .addr = dev->core->pll_addr, .flags = 0, - .buf = pllbuf+1, .len = 4 }; - int err; - - /* Switch PLL to DVB mode */ - err = philips_fmd1216_pll_init(fe); - if (err) - return err; - - /* Tune PLL */ - pllbuf[0] = dev->core->pll_addr << 1; - dvb_pll_configure(dev->core->pll_desc, pllbuf+1, - params->frequency, - params->u.ofdm.bandwidth); - if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { - printk(KERN_WARNING "cx88-dvb: %s error " - "(addr %02x <- %02x, err = %i)\n", - __FUNCTION__, pllbuf[0], pllbuf[1], err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - - return 0; -} - -static struct mt352_config dntv_live_dvbt_pro_config = { - .demod_address = 0x0f, - .no_tuner = 1, - .demod_init = dntv_live_dvbt_pro_demod_init, - .pll_set = dntv_live_dvbt_pro_pll_set, -}; -#endif #endif #ifdef HAVE_CX22702 @@ -308,12 +188,6 @@ static struct cx22702_config hauppauge_novat_config = { .pll_address = 0x61, .pll_desc = &dvb_pll_thomson_dtt759x, }; -static struct cx22702_config hauppauge_hvr1100_config = { - .demod_address = 0x63, - .output_mode = CX22702_SERIAL_OUTPUT, - .pll_address = 0x61, - .pll_desc = &dvb_pll_fmd1216me, -}; #endif #ifdef HAVE_OR51132 @@ -440,40 +314,6 @@ static struct nxt200x_config ati_hdtvwonder = { }; #endif -#ifdef HAVE_CX24123 -static int cx24123_set_ts_param(struct dvb_frontend* fe, - int is_punctured) -{ - struct cx8802_dev *dev= fe->dvb->priv; - dev->ts_gen_cntrl = 0x2; - return 0; -} - -static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on) -{ - struct cx8802_dev *dev= fe->dvb->priv; - struct cx88_core *core = dev->core; - - if (on) - cx_write(MO_GP0_IO, 0x000006f9); - else - cx_write(MO_GP0_IO, 0x000006fB); -} - -static struct cx24123_config hauppauge_novas_config = { - .demod_address = 0x55, - .use_isl6421 = 1, - .set_ts_params = cx24123_set_ts_param, -}; - -static struct cx24123_config kworld_dvbs_100_config = { - .demod_address = 0x15, - .use_isl6421 = 0, - .set_ts_params = cx24123_set_ts_param, - .enable_lnb_voltage = cx24123_enable_lnb_voltage, -}; -#endif - static int dvb_register(struct cx8802_dev *dev) { /* init struct videobuf_dvb */ @@ -489,16 +329,10 @@ static int dvb_register(struct cx8802_dev *dev) break; case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: case CX88_BOARD_CONEXANT_DVB_T1: - case CX88_BOARD_KWORLD_DVB_T_CX22702: case CX88_BOARD_WINFAST_DTV1000: dev->dvb.frontend = cx22702_attach(&connexant_refboard_config, &dev->core->i2c_adap); break; - case CX88_BOARD_HAUPPAUGE_HVR1100: - case CX88_BOARD_HAUPPAUGE_HVR1100LP: - dev->dvb.frontend = cx22702_attach(&hauppauge_hvr1100_config, - &dev->core->i2c_adap); - break; #endif #ifdef HAVE_MT352 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: @@ -521,24 +355,6 @@ static int dvb_register(struct cx8802_dev *dev) dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config, &dev->core->i2c_adap); break; - case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: -#ifdef HAVE_VP3054_I2C - dev->core->pll_addr = 0x61; - dev->core->pll_desc = &dvb_pll_fmd1216me; - dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_pro_config, - &((struct vp3054_i2c_state *)dev->card_priv)->adap); -#else - printk("%s: built without vp3054 support\n", dev->core->name); -#endif - break; - case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: - /* The tin box says DEE1601, but it seems to be DTT7579 - * compatible, with a slightly different MT352 AGC gain. */ - dev->core->pll_addr = 0x61; - dev->core->pll_desc = &dvb_pll_thomson_dtt7579; - dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dual, - &dev->core->i2c_adap); - break; #endif #ifdef HAVE_OR51132 case CX88_BOARD_PCHDTV_HD3000: @@ -577,7 +393,7 @@ static int dvb_register(struct cx8802_dev *dev) cx_set(MO_GP0_IO, 9); mdelay(200); dev->core->pll_addr = 0x61; - dev->core->pll_desc = &dvb_pll_thomson_dtt761x; + dev->core->pll_desc = &dvb_pll_thomson_dtt7611; dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold, &dev->core->i2c_adap); } @@ -604,17 +420,6 @@ static int dvb_register(struct cx8802_dev *dev) dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder, &dev->core->i2c_adap); break; -#endif -#ifdef HAVE_CX24123 - case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: - case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: - dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config, - &dev->core->i2c_adap); - break; - case CX88_BOARD_KWORLD_DVBS_100: - dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config, - &dev->core->i2c_adap); - break; #endif default: printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", @@ -668,12 +473,6 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev, if (0 != err) goto fail_free; -#ifdef HAVE_VP3054_I2C - err = vp3054_i2c_probe(dev); - if (0 != err) - goto fail_free; -#endif - /* dvb stuff */ printk("%s/2: cx2388x based dvb card\n", core->name); videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops, @@ -685,9 +484,6 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev, err = dvb_register(dev); if (0 != err) goto fail_fini; - - /* Maintain a reference to cx88-video can query the 8802 device. */ - core->dvbdev = dev; return 0; fail_fini: @@ -703,16 +499,9 @@ static void __devexit dvb_remove(struct pci_dev *pci_dev) { struct cx8802_dev *dev = pci_get_drvdata(pci_dev); - /* Destroy any 8802 reference. */ - dev->core->dvbdev = NULL; - /* dvb */ videobuf_dvb_unregister(&dev->dvb); -#ifdef HAVE_VP3054_I2C - vp3054_i2c_remove(dev); -#endif - /* common */ cx8802_fini_common(dev); cx88_core_put(dev->core,dev->pci); diff --git a/trunk/drivers/media/video/cx88/cx88-i2c.c b/trunk/drivers/media/video/cx88/cx88-i2c.c index f720901e9638..4a8fb161b16a 100644 --- a/trunk/drivers/media/video/cx88/cx88-i2c.c +++ b/trunk/drivers/media/video/cx88/cx88-i2c.c @@ -30,7 +30,6 @@ #include #include "cx88.h" -#include static unsigned int i2c_debug = 0; module_param(i2c_debug, int, 0644); @@ -136,17 +135,7 @@ void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg) { if (0 != core->i2c_rc) return; - - if (core->dvbdev) { - if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl) - core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1); - - i2c_clients_command(&core->i2c_adap, cmd, arg); - - if (core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl) - core->dvbdev->dvb.frontend->ops->i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0); - } else - i2c_clients_command(&core->i2c_adap, cmd, arg); + i2c_clients_command(&core->i2c_adap, cmd, arg); } static struct i2c_algo_bit_data cx8800_i2c_algo_template = { diff --git a/trunk/drivers/media/video/cx88/cx88-input.c b/trunk/drivers/media/video/cx88/cx88-input.c index 286c85b6bdf9..461019dca901 100644 --- a/trunk/drivers/media/video/cx88/cx88-input.c +++ b/trunk/drivers/media/video/cx88/cx88-input.c @@ -5,7 +5,7 @@ * * Copyright (c) 2003 Pavel Machek * Copyright (c) 2004 Gerd Knorr - * Copyright (c) 2004, 2005 Chris Pascoe + * Copyright (c) 2004 Chris Pascoe * * 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 @@ -29,9 +29,10 @@ #include #include -#include "cx88.h" #include +#include "cx88.h" + /* ---------------------------------------------------------------------- */ /* DigitalNow DNTV Live DVB-T Remote */ @@ -257,114 +258,6 @@ static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = { /* ---------------------------------------------------------------------- */ -/* AVERTV STUDIO 303 Remote */ -static IR_KEYTAB_TYPE ir_codes_avertv_303[IR_KEYTAB_SIZE] = { - [ 0x2a ] = KEY_KP1, - [ 0x32 ] = KEY_KP2, - [ 0x3a ] = KEY_KP3, - [ 0x4a ] = KEY_KP4, - [ 0x52 ] = KEY_KP5, - [ 0x5a ] = KEY_KP6, - [ 0x6a ] = KEY_KP7, - [ 0x72 ] = KEY_KP8, - [ 0x7a ] = KEY_KP9, - [ 0x0e ] = KEY_KP0, - - [ 0x02 ] = KEY_POWER, - [ 0x22 ] = KEY_VIDEO, - [ 0x42 ] = KEY_AUDIO, - [ 0x62 ] = KEY_ZOOM, - [ 0x0a ] = KEY_TV, - [ 0x12 ] = KEY_CD, - [ 0x1a ] = KEY_TEXT, - - [ 0x16 ] = KEY_SUBTITLE, - [ 0x1e ] = KEY_REWIND, - [ 0x06 ] = KEY_PRINT, - - [ 0x2e ] = KEY_SEARCH, - [ 0x36 ] = KEY_SLEEP, - [ 0x3e ] = KEY_SHUFFLE, - [ 0x26 ] = KEY_MUTE, - - [ 0x4e ] = KEY_RECORD, - [ 0x56 ] = KEY_PAUSE, - [ 0x5e ] = KEY_STOP, - [ 0x46 ] = KEY_PLAY, - - [ 0x6e ] = KEY_RED, - [ 0x0b ] = KEY_GREEN, - [ 0x66 ] = KEY_YELLOW, - [ 0x03 ] = KEY_BLUE, - - [ 0x76 ] = KEY_LEFT, - [ 0x7e ] = KEY_RIGHT, - [ 0x13 ] = KEY_DOWN, - [ 0x1b ] = KEY_UP, -}; - -/* ---------------------------------------------------------------------- */ - -/* DigitalNow DNTV Live! DVB-T Pro Remote */ -static IR_KEYTAB_TYPE ir_codes_dntv_live_dvbt_pro[IR_KEYTAB_SIZE] = { - [ 0x16 ] = KEY_POWER, - [ 0x5b ] = KEY_HOME, - - [ 0x55 ] = KEY_TV, /* live tv */ - [ 0x58 ] = KEY_TUNER, /* digital Radio */ - [ 0x5a ] = KEY_RADIO, /* FM radio */ - [ 0x59 ] = KEY_DVD, /* dvd menu */ - [ 0x03 ] = KEY_1, - [ 0x01 ] = KEY_2, - [ 0x06 ] = KEY_3, - [ 0x09 ] = KEY_4, - [ 0x1d ] = KEY_5, - [ 0x1f ] = KEY_6, - [ 0x0d ] = KEY_7, - [ 0x19 ] = KEY_8, - [ 0x1b ] = KEY_9, - [ 0x0c ] = KEY_CANCEL, - [ 0x15 ] = KEY_0, - [ 0x4a ] = KEY_CLEAR, - [ 0x13 ] = KEY_BACK, - [ 0x00 ] = KEY_TAB, - [ 0x4b ] = KEY_UP, - [ 0x4e ] = KEY_LEFT, - [ 0x4f ] = KEY_OK, - [ 0x52 ] = KEY_RIGHT, - [ 0x51 ] = KEY_DOWN, - [ 0x1e ] = KEY_VOLUMEUP, - [ 0x0a ] = KEY_VOLUMEDOWN, - [ 0x02 ] = KEY_CHANNELDOWN, - [ 0x05 ] = KEY_CHANNELUP, - [ 0x11 ] = KEY_RECORD, - [ 0x14 ] = KEY_PLAY, - [ 0x4c ] = KEY_PAUSE, - [ 0x1a ] = KEY_STOP, - [ 0x40 ] = KEY_REWIND, - [ 0x12 ] = KEY_FASTFORWARD, - [ 0x41 ] = KEY_PREVIOUSSONG, /* replay |< */ - [ 0x42 ] = KEY_NEXTSONG, /* skip >| */ - [ 0x54 ] = KEY_CAMERA, /* capture */ - [ 0x50 ] = KEY_LANGUAGE, /* sap */ - [ 0x47 ] = KEY_TV2, /* pip */ - [ 0x4d ] = KEY_SCREEN, - [ 0x43 ] = KEY_SUBTITLE, - [ 0x10 ] = KEY_MUTE, - [ 0x49 ] = KEY_AUDIO, /* l/r */ - [ 0x07 ] = KEY_SLEEP, - [ 0x08 ] = KEY_VIDEO, /* a/v */ - [ 0x0e ] = KEY_PREVIOUS, /* recall */ - [ 0x45 ] = KEY_ZOOM, /* zoom + */ - [ 0x46 ] = KEY_ANGLE, /* zoom - */ - [ 0x56 ] = KEY_RED, - [ 0x57 ] = KEY_GREEN, - [ 0x5c ] = KEY_YELLOW, - [ 0x5d ] = KEY_BLUE, -}; - -/* ---------------------------------------------------------------------- */ - struct cx88_IR { struct cx88_core *core; struct input_dev *input; @@ -373,7 +266,7 @@ struct cx88_IR { char phys[32]; /* sample from gpio pin 16 */ - u32 sampling; + int sampling; u32 samples[16]; int scount; unsigned long release; @@ -491,13 +384,10 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: ir_codes = ir_codes_cinergy_1400; ir_type = IR_TYPE_PD; - ir->sampling = 0xeb04; /* address */ + ir->sampling = 1; break; case CX88_BOARD_HAUPPAUGE: case CX88_BOARD_HAUPPAUGE_DVB_T1: - case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: - case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: - case CX88_BOARD_HAUPPAUGE_HVR1100: ir_codes = ir_codes_hauppauge_new; ir_type = IR_TYPE_RC5; ir->sampling = 1; @@ -537,19 +427,6 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->mask_keyup = 0x40; ir->polling = 1; /* ms */ break; - case CX88_BOARD_AVERTV_303: - case CX88_BOARD_AVERTV_STUDIO_303: - ir_codes = ir_codes_avertv_303; - ir->gpio_addr = MO_GP2_IO; - ir->mask_keycode = 0xfb; - ir->mask_keydown = 0x02; - ir->polling = 50; /* ms */ - break; - case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: - ir_codes = ir_codes_dntv_live_dvbt_pro; - ir_type = IR_TYPE_PD; - ir->sampling = 0xff00; /* address */ - break; } if (NULL == ir_codes) { @@ -607,10 +484,6 @@ int cx88_ir_fini(struct cx88_core *core) if (NULL == ir) return 0; - if (ir->sampling) { - cx_write(MO_DDSCFG_IO, 0x0); - core->pci_irqmask &= ~(1 << 18); - } if (ir->polling) { del_timer(&ir->timer); flush_scheduled_work(); @@ -662,7 +535,6 @@ void cx88_ir_irq(struct cx88_core *core) /* decode it */ switch (core->board) { case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: - case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4); if (ircode == 0xffffffff) { /* decoding error */ @@ -678,7 +550,7 @@ void cx88_ir_irq(struct cx88_core *core) break; } - if ((ircode & 0xffff) != (ir->sampling & 0xffff)) { /* wrong address */ + if ((ircode & 0xffff) != 0xeb04) { /* wrong address */ ir_dprintk("pulse distance decoded wrong address\n"); break; } @@ -695,8 +567,6 @@ void cx88_ir_irq(struct cx88_core *core) break; case CX88_BOARD_HAUPPAUGE: case CX88_BOARD_HAUPPAUGE_DVB_T1: - case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: - case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7); ir_dprintk("biphase decoded: %x\n", ircode); if ((ircode & 0xfffff000) != 0x3000) diff --git a/trunk/drivers/media/video/cx88/cx88-mpeg.c b/trunk/drivers/media/video/cx88/cx88-mpeg.c index c79cc1d2bf8b..35e6d0c2b872 100644 --- a/trunk/drivers/media/video/cx88/cx88-mpeg.c +++ b/trunk/drivers/media/video/cx88/cx88-mpeg.c @@ -78,11 +78,6 @@ static int cx8802_start_dma(struct cx8802_dev *dev, case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: cx_write(TS_SOP_STAT, 1<<13); break; - case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: - case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: - cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */ - udelay(100); - break; default: cx_write(TS_SOP_STAT, 0x00); break; diff --git a/trunk/drivers/media/video/cx88/cx88-tvaudio.c b/trunk/drivers/media/video/cx88/cx88-tvaudio.c index 24118e43e73a..a1b120c8a9b5 100644 --- a/trunk/drivers/media/video/cx88/cx88-tvaudio.c +++ b/trunk/drivers/media/video/cx88/cx88-tvaudio.c @@ -132,22 +132,14 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl) { u32 volume; -#ifndef USING_CX88_ALSA /* restart dma; This avoids buzz in NICAM and is good in others */ cx88_stop_audio_dma(core); -#endif cx_write(AUD_RATE_THRES_DMD, 0x000000C0); -#ifndef USING_CX88_ALSA cx88_start_audio_dma(core); -#endif if (cx88_boards[core->board].blackbird) { /* sets sound input from external adc */ - if (core->board == CX88_BOARD_HAUPPAUGE_ROSLYN) - cx_clear(AUD_CTL, EN_I2SIN_ENABLE); - else - cx_set(AUD_CTL, EN_I2SIN_ENABLE); - + cx_set(AUD_CTL, EN_I2SIN_ENABLE); cx_write(AUD_I2SINPUTCNTL, 4); cx_write(AUD_BAUDRATE, 1); /* 'pass-thru mode': this enables the i2s output to the mpeg encoder */ diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index 9a02515fe18b..24a48f8a48c1 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -33,7 +33,6 @@ #include #include "cx88.h" -#include /* Include V4L1 specific functions. Should be removed soon */ #include @@ -241,7 +240,7 @@ static struct cx88_ctrl cx8800_ctls[] = { .minimum = 0, .maximum = 0xff, .step = 1, - .default_value = 0x3f, + .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, }, .off = 0, @@ -272,7 +271,7 @@ static struct cx88_ctrl cx8800_ctls[] = { .minimum = 0, .maximum = 0xff, .step = 1, - .default_value = 0x7f, + .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, }, .off = 0, @@ -286,7 +285,6 @@ static struct cx88_ctrl cx8800_ctls[] = { .name = "Mute", .minimum = 0, .maximum = 1, - .default_value = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, }, .reg = AUD_VOL_CTL, @@ -300,7 +298,7 @@ static struct cx88_ctrl cx8800_ctls[] = { .minimum = 0, .maximum = 0x3f, .step = 1, - .default_value = 0x1f, + .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, }, .reg = AUD_VOL_CTL, @@ -919,9 +917,6 @@ static int get_control(struct cx88_core *core, struct v4l2_control *ctl) ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift; break; } - printk("get_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", - ctl->id, c->reg, ctl->value, - c->mask, c->sreg ? " [shadowed]" : ""); return 0; } @@ -930,13 +925,13 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl) { /* struct cx88_core *core = dev->core; */ struct cx88_ctrl *c = NULL; - u32 value,mask; + u32 v_sat_value; + u32 value; int i; - for (i = 0; i < CX8800_CTLS; i++) { - if (cx8800_ctls[i].v.id == ctl->id) { + + for (i = 0; i < CX8800_CTLS; i++) + if (cx8800_ctls[i].v.id == ctl->id) c = &cx8800_ctls[i]; - } - } if (NULL == c) return -EINVAL; @@ -944,7 +939,6 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl) ctl->value = c->v.minimum; if (ctl->value > c->v.maximum) ctl->value = c->v.maximum; - mask=c->mask; switch (ctl->id) { case V4L2_CID_AUDIO_BALANCE: value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; @@ -954,44 +948,56 @@ static int set_control(struct cx88_core *core, struct v4l2_control *ctl) break; case V4L2_CID_SATURATION: /* special v_sat handling */ - - value = ((ctl->value - c->off) << c->shift) & c->mask; - - if (core->tvnorm->id & V4L2_STD_SECAM) { - /* For SECAM, both U and V sat should be equal */ - value=value<<8|value; - } else { - /* Keeps U Saturation proportional to V Sat */ - value=(value*0x5a)/0x7f<<8|value; - } - mask=0xffff; - break; + v_sat_value = ctl->value - (0x7f - 0x5a); + if (v_sat_value > 0xff) + v_sat_value = 0xff; + if (v_sat_value < 0x00) + v_sat_value = 0x00; + cx_andor(MO_UV_SATURATION, 0xff00, v_sat_value << 8); + /* fall through to default route for u_sat */ default: value = ((ctl->value - c->off) << c->shift) & c->mask; break; } - printk("set_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n", - ctl->id, c->reg, value, - mask, c->sreg ? " [shadowed]" : ""); + dprintk(1,"set_control id=0x%X reg=0x%x val=0x%x%s\n", + ctl->id, c->reg, value, c->sreg ? " [shadowed]" : ""); if (c->sreg) { - cx_sandor(c->sreg, c->reg, mask, value); + cx_sandor(c->sreg, c->reg, c->mask, value); } else { - cx_andor(c->reg, mask, value); + cx_andor(c->reg, c->mask, value); } return 0; } +/* static void init_controls(struct cx8800_dev *dev) */ static void init_controls(struct cx88_core *core) { - struct v4l2_control ctrl; - int i; + static struct v4l2_control mute = { + .id = V4L2_CID_AUDIO_MUTE, + .value = 1, + }; + static struct v4l2_control volume = { + .id = V4L2_CID_AUDIO_VOLUME, + .value = 0x3f, + }; + static struct v4l2_control hue = { + .id = V4L2_CID_HUE, + .value = 0x80, + }; + static struct v4l2_control contrast = { + .id = V4L2_CID_CONTRAST, + .value = 0x80, + }; + static struct v4l2_control brightness = { + .id = V4L2_CID_BRIGHTNESS, + .value = 0x80, + }; - for (i = 0; i < CX8800_CTLS; i++) { - ctrl.id=cx8800_ctls[i].v.id; - ctrl.value=cx8800_ctls[i].v.default_value - +cx8800_ctls[i].off; - set_control(core, &ctrl); - } + set_control(core,&mute); + set_control(core,&volume); + set_control(core,&hue); + set_control(core,&contrast); + set_control(core,&brightness); } /* ------------------------------------------------------------------ */ @@ -1119,7 +1125,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, int err; if (video_debug > 1) - v4l_print_ioctl(core->name,cmd); + cx88_print_ioctl(core->name,cmd); switch (cmd) { /* --- capabilities ------------------------------------------ */ @@ -1255,7 +1261,7 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, dprintk( 1, "CORE IOCTL: 0x%x\n", cmd ); if (video_debug > 1) - v4l_print_ioctl(core->name,cmd); + cx88_print_ioctl(core->name,cmd); switch (cmd) { /* ---------- tv norms ---------- */ @@ -1475,7 +1481,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, struct cx88_core *core = dev->core; if (video_debug > 1) - v4l_print_ioctl(core->name,cmd); + cx88_print_ioctl(core->name,cmd); switch (cmd) { case VIDIOC_QUERYCAP: @@ -1734,7 +1740,6 @@ static struct file_operations video_fops = .poll = video_poll, .mmap = video_mmap, .ioctl = video_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; @@ -1762,7 +1767,6 @@ static struct file_operations radio_fops = .open = video_open, .release = video_release, .ioctl = radio_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; @@ -1924,8 +1928,8 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, /* initial device configuration */ down(&core->lock); - cx88_set_tvnorm(core,tvnorms); init_controls(core); + cx88_set_tvnorm(core,tvnorms); video_mux(core,0); up(&core->lock); diff --git a/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.c b/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.c deleted file mode 100644 index 372cd29cedbd..000000000000 --- a/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - - cx88-vp3054-i2c.c -- support for the secondary I2C bus of the - DNTV Live! DVB-T Pro (VP-3054), wired as: - GPIO[0] -> SCL, GPIO[1] -> SDA - - (c) 2005 Chris Pascoe - - 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. - -*/ - -#include -#include -#include - -#include - -#include "cx88.h" -#include "cx88-vp3054-i2c.h" - - -/* ----------------------------------------------------------------------- */ - -static void vp3054_bit_setscl(void *data, int state) -{ - struct cx8802_dev *dev = data; - struct cx88_core *core = dev->core; - struct vp3054_i2c_state *vp3054_i2c = dev->card_priv; - - if (state) { - vp3054_i2c->state |= 0x0001; /* SCL high */ - vp3054_i2c->state &= ~0x0100; /* external pullup */ - } else { - vp3054_i2c->state &= ~0x0001; /* SCL low */ - vp3054_i2c->state |= 0x0100; /* drive pin */ - } - cx_write(MO_GP0_IO, 0x010000 | vp3054_i2c->state); - cx_read(MO_GP0_IO); -} - -static void vp3054_bit_setsda(void *data, int state) -{ - struct cx8802_dev *dev = data; - struct cx88_core *core = dev->core; - struct vp3054_i2c_state *vp3054_i2c = dev->card_priv; - - if (state) { - vp3054_i2c->state |= 0x0002; /* SDA high */ - vp3054_i2c->state &= ~0x0200; /* tristate pin */ - } else { - vp3054_i2c->state &= ~0x0002; /* SDA low */ - vp3054_i2c->state |= 0x0200; /* drive pin */ - } - cx_write(MO_GP0_IO, 0x020000 | vp3054_i2c->state); - cx_read(MO_GP0_IO); -} - -static int vp3054_bit_getscl(void *data) -{ - struct cx8802_dev *dev = data; - struct cx88_core *core = dev->core; - u32 state; - - state = cx_read(MO_GP0_IO); - return (state & 0x01) ? 1 : 0; -} - -static int vp3054_bit_getsda(void *data) -{ - struct cx8802_dev *dev = data; - struct cx88_core *core = dev->core; - u32 state; - - state = cx_read(MO_GP0_IO); - return (state & 0x02) ? 1 : 0; -} - -/* ----------------------------------------------------------------------- */ - -static struct i2c_algo_bit_data vp3054_i2c_algo_template = { - .setsda = vp3054_bit_setsda, - .setscl = vp3054_bit_setscl, - .getsda = vp3054_bit_getsda, - .getscl = vp3054_bit_getscl, - .udelay = 16, - .mdelay = 10, - .timeout = 200, -}; - -/* ----------------------------------------------------------------------- */ - -static struct i2c_adapter vp3054_i2c_adap_template = { - .name = "cx2388x", - .owner = THIS_MODULE, - .id = I2C_HW_B_CX2388x, -}; - -static struct i2c_client vp3054_i2c_client_template = { - .name = "VP-3054", -}; - -int vp3054_i2c_probe(struct cx8802_dev *dev) -{ - struct cx88_core *core = dev->core; - struct vp3054_i2c_state *vp3054_i2c; - int rc; - - if (core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO) - return 0; - - dev->card_priv = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL); - if (dev->card_priv == NULL) - return -ENOMEM; - vp3054_i2c = dev->card_priv; - - memcpy(&vp3054_i2c->adap, &vp3054_i2c_adap_template, - sizeof(vp3054_i2c->adap)); - memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template, - sizeof(vp3054_i2c->algo)); - memcpy(&vp3054_i2c->client, &vp3054_i2c_client_template, - sizeof(vp3054_i2c->client)); - - vp3054_i2c->adap.class |= I2C_CLASS_TV_DIGITAL; - - vp3054_i2c->adap.dev.parent = &dev->pci->dev; - strlcpy(vp3054_i2c->adap.name, core->name, - sizeof(vp3054_i2c->adap.name)); - vp3054_i2c->algo.data = dev; - i2c_set_adapdata(&vp3054_i2c->adap, dev); - vp3054_i2c->adap.algo_data = &vp3054_i2c->algo; - vp3054_i2c->client.adapter = &vp3054_i2c->adap; - - vp3054_bit_setscl(dev,1); - vp3054_bit_setsda(dev,1); - - rc = i2c_bit_add_bus(&vp3054_i2c->adap); - if (0 != rc) { - printk("%s: vp3054_i2c register FAILED\n", core->name); - - kfree(dev->card_priv); - dev->card_priv = NULL; - } - - return rc; -} - -void vp3054_i2c_remove(struct cx8802_dev *dev) -{ - struct vp3054_i2c_state *vp3054_i2c = dev->card_priv; - - if (vp3054_i2c == NULL || - dev->core->board != CX88_BOARD_DNTV_LIVE_DVB_T_PRO) - return; - - i2c_bit_del_bus(&vp3054_i2c->adap); - kfree(vp3054_i2c); -} - -EXPORT_SYMBOL(vp3054_i2c_probe); -EXPORT_SYMBOL(vp3054_i2c_remove); diff --git a/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.h b/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.h deleted file mode 100644 index b7a0a04d2423..000000000000 --- a/trunk/drivers/media/video/cx88/cx88-vp3054-i2c.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - - cx88-vp3054-i2c.h -- support for the secondary I2C bus of the - DNTV Live! DVB-T Pro (VP-3054), wired as: - GPIO[0] -> SCL, GPIO[1] -> SDA - - (c) 2005 Chris Pascoe - - 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. - -*/ - -/* ----------------------------------------------------------------------- */ -struct vp3054_i2c_state { - struct i2c_adapter adap; - struct i2c_algo_bit_data algo; - struct i2c_client client; - u32 state; -}; - -/* ----------------------------------------------------------------------- */ -int vp3054_i2c_probe(struct cx8802_dev *dev); -void vp3054_i2c_remove(struct cx8802_dev *dev); diff --git a/trunk/drivers/media/video/cx88/cx88.h b/trunk/drivers/media/video/cx88/cx88.h index e9fd55b57fa6..77beafc5c327 100644 --- a/trunk/drivers/media/video/cx88/cx88.h +++ b/trunk/drivers/media/video/cx88/cx88.h @@ -179,14 +179,6 @@ extern struct sram_channel cx88_sram_channels[]; #define CX88_BOARD_ATI_HDTVWONDER 34 #define CX88_BOARD_WINFAST_DTV1000 35 #define CX88_BOARD_AVERTV_303 36 -#define CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1 37 -#define CX88_BOARD_HAUPPAUGE_NOVASE2_S1 38 -#define CX88_BOARD_KWORLD_DVBS_100 39 -#define CX88_BOARD_HAUPPAUGE_HVR1100 40 -#define CX88_BOARD_HAUPPAUGE_HVR1100LP 41 -#define CX88_BOARD_DNTV_LIVE_DVB_T_PRO 42 -#define CX88_BOARD_KWORLD_DVB_T_CX22702 43 -#define CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL 44 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, @@ -288,9 +280,6 @@ struct cx88_core { unsigned int tda9887_conf; unsigned int has_radio; - /* Supported V4L _STD_ tuner formats */ - unsigned int tuner_formats; - /* config info -- dvb */ struct dvb_pll_desc *pll_desc; unsigned int pll_addr; @@ -312,9 +301,6 @@ struct cx88_core { /* various v4l controls */ u32 freq; - - /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ - struct cx8802_dev *dvbdev; }; struct cx8800_dev; @@ -425,8 +411,6 @@ struct cx8802_dev { struct videobuf_dvb dvb; void* fe_handle; int (*fe_release)(void *handle); - - void *card_priv; /* for switching modulation types */ unsigned char ts_gen_cntrl; @@ -463,6 +447,7 @@ struct cx8802_dev { extern void cx88_print_irqbits(char *name, char *tag, char **strings, u32 bits, u32 mask); +extern void cx88_print_ioctl(char *name, unsigned int cmd); extern int cx88_core_irq(struct cx88_core *core, u32 status); extern void cx88_wakeup(struct cx88_core *core, diff --git a/trunk/drivers/media/video/em28xx/em28xx-cards.c b/trunk/drivers/media/video/em28xx/em28xx-cards.c index 58f7b4194a0d..57779e63f35d 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-cards.c +++ b/trunk/drivers/media/video/em28xx/em28xx-cards.c @@ -30,7 +30,6 @@ #include #include #include -#include #include "msp3400.h" #include "em28xx.h" @@ -262,6 +261,7 @@ void em28xx_card_setup(struct em28xx *dev) /* request some modules */ if (dev->model == EM2820_BOARD_HAUPPAUGE_WINTV_USB_2) { struct tveeprom tv; + struct v4l2_audioout ao; #ifdef CONFIG_MODULES request_module("tveeprom"); request_module("ir-kbd-i2c"); @@ -274,8 +274,12 @@ void em28xx_card_setup(struct em28xx *dev) dev->tuner_type= tv.tuner_type; if (tv.audio_processor == AUDIO_CHIP_MSP34XX) { - dev->i2s_speed=2048000; dev->has_msp34xx=1; + memset (&ao,0,sizeof(ao)); + + ao.index=2; + ao.mode=V4L2_AUDMODE_32BITS; + em28xx_i2c_call_clients(dev, VIDIOC_S_AUDOUT, &ao); } else dev->has_msp34xx=0; } diff --git a/trunk/drivers/media/video/em28xx/em28xx-core.c b/trunk/drivers/media/video/em28xx/em28xx-core.c index dff3893f32fd..0cfe75416ec6 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-core.c +++ b/trunk/drivers/media/video/em28xx/em28xx-core.c @@ -32,7 +32,7 @@ /* #define ENABLE_DEBUG_ISOC_FRAMES */ -static unsigned int core_debug = 0; +static unsigned int core_debug; module_param(core_debug,int,0644); MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); @@ -41,7 +41,7 @@ MODULE_PARM_DESC(core_debug,"enable debug messages [core]"); printk(KERN_INFO "%s %s :"fmt, \ dev->name, __FUNCTION__ , ##arg); } while (0) -static unsigned int reg_debug = 0; +static unsigned int reg_debug; module_param(reg_debug,int,0644); MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); @@ -50,7 +50,7 @@ MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]"); printk(KERN_INFO "%s %s :"fmt, \ dev->name, __FUNCTION__ , ##arg); } while (0) -static unsigned int isoc_debug = 0; +static unsigned int isoc_debug; module_param(isoc_debug,int,0644); MODULE_PARM_DESC(isoc_debug,"enable debug messages [isoc transfers]"); @@ -63,6 +63,59 @@ static int alt = EM28XX_PINOUT; module_param(alt, int, 0644); MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); +/* ------------------------------------------------------------------ */ +/* debug help functions */ + +static const char *v4l1_ioctls[] = { + "0", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT", + "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ", + "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT", + "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", + "SMICROCODE", "GVBIFMT", "SVBIFMT" }; +#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) + +static const char *v4l2_ioctls[] = { + "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT", + "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF", + "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON", + "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD", + "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER", + "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL", + "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43", + "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT", + "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR", + "S_MODULATOR" +}; +#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) + +void em28xx_print_ioctl(char *name, unsigned int cmd) +{ + char *dir; + + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: dir = "--"; break; + case _IOC_READ: dir = "r-"; break; + case _IOC_WRITE: dir = "-w"; break; + case _IOC_READ | _IOC_WRITE: dir = "rw"; break; + default: dir = "??"; break; + } + switch (_IOC_TYPE(cmd)) { + case 'v': + printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n", + name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ? + v4l1_ioctls[_IOC_NR(cmd)] : "???"); + break; + case 'V': + printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n", + name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ? + v4l2_ioctls[_IOC_NR(cmd)] : "???"); + break; + default: + printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n", + name, cmd, dir, _IOC_NR(cmd)); + } +} + /* * em28xx_request_buffers() @@ -73,7 +126,7 @@ u32 em28xx_request_buffers(struct em28xx *dev, u32 count) const size_t imagesize = PAGE_ALIGN(dev->frame_size); /*needs to be page aligned cause the buffers can be mapped individually! */ void *buff = NULL; u32 i; - em28xx_coredbg("requested %i buffers with size %zi", count, imagesize); + em28xx_coredbg("requested %i buffers with size %zd", count, imagesize); if (count > EM28XX_NUM_FRAMES) count = EM28XX_NUM_FRAMES; diff --git a/trunk/drivers/media/video/em28xx/em28xx-i2c.c b/trunk/drivers/media/video/em28xx/em28xx-i2c.c index 0591a705b7a1..d14bcf4ceaea 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-i2c.c +++ b/trunk/drivers/media/video/em28xx/em28xx-i2c.c @@ -28,7 +28,6 @@ #include #include "em28xx.h" -#include #include /* ----------------------------------------------------------- */ @@ -487,7 +486,9 @@ static struct i2c_adapter em28xx_adap_template = { .inc_use = inc_use, .dec_use = dec_use, #endif +#ifdef I2C_CLASS_TV_ANALOG .class = I2C_CLASS_TV_ANALOG, +#endif .name = "em28xx", .id = I2C_HW_B_EM28XX, .algo = &em28xx_algo, diff --git a/trunk/drivers/media/video/em28xx/em28xx-video.c b/trunk/drivers/media/video/em28xx/em28xx-video.c index fdc255918dde..3a56120397ae 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-video.c +++ b/trunk/drivers/media/video/em28xx/em28xx-video.c @@ -32,7 +32,6 @@ #include "em28xx.h" #include -#include #define DRIVER_AUTHOR "Ludovico Cavedon , " \ "Markus Rechberger , " \ @@ -107,31 +106,7 @@ static const unsigned char saa7114_i2c_init[] = { #define TVNORMS ARRAY_SIZE(tvnorms) /* supported controls */ -/* Common to all boards */ static struct v4l2_queryctrl em28xx_qctrl[] = { - { - .id = V4L2_CID_AUDIO_VOLUME, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Volume", - .minimum = 0x0, - .maximum = 0x1f, - .step = 0x1, - .default_value = 0x1f, - .flags = 0, - },{ - .id = V4L2_CID_AUDIO_MUTE, - .type = V4L2_CTRL_TYPE_BOOLEAN, - .name = "Mute", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - .flags = 0, - } -}; - -/* FIXME: These are specific to saa711x - should be moved to its code */ -static struct v4l2_queryctrl saa711x_qctrl[] = { { .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, @@ -159,6 +134,24 @@ static struct v4l2_queryctrl saa711x_qctrl[] = { .step = 0x1, .default_value = 0x10, .flags = 0, + },{ + .id = V4L2_CID_AUDIO_VOLUME, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Volume", + .minimum = 0x0, + .maximum = 0x1f, + .step = 0x1, + .default_value = 0x1f, + .flags = 0, + },{ + .id = V4L2_CID_AUDIO_MUTE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + .flags = 0, },{ .id = V4L2_CID_RED_BALANCE, .type = V4L2_CTRL_TYPE_INTEGER, @@ -186,7 +179,7 @@ static struct v4l2_queryctrl saa711x_qctrl[] = { .step = 0x1, .default_value = 0x20, .flags = 0, - } + } }; static struct usb_driver em28xx_usb_driver; @@ -287,8 +280,6 @@ static void video_mux(struct em28xx *dev, int index) em28xx_videodbg("Setting input index=%d, vmux=%d, amux=%d\n",index,input,dev->ctl_ainput); if (dev->has_msp34xx) { - if (dev->i2s_speed) - em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, &dev->i2s_speed); em28xx_i2c_call_clients(dev, VIDIOC_S_AUDIO, &dev->ctl_ainput); ainput = EM28XX_AUDIO_SRC_TUNER; em28xx_audio_source(dev, ainput); @@ -683,6 +674,7 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) */ static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) { + s32 tmp; switch (ctrl->id) { case V4L2_CID_AUDIO_MUTE: ctrl->value = dev->mute; @@ -690,16 +682,6 @@ static int em28xx_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) case V4L2_CID_AUDIO_VOLUME: ctrl->value = dev->volume; return 0; - default: - return -EINVAL; - } -} - -/*FIXME: should be moved to saa711x */ -static int saa711x_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) -{ - s32 tmp; - switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: if ((tmp = em28xx_brightness_get(dev)) < 0) return -EIO; @@ -749,15 +731,6 @@ static int em28xx_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) case V4L2_CID_AUDIO_VOLUME: dev->volume = ctrl->value; return em28xx_audio_analog_set(dev); - default: - return -EINVAL; - } -} - -/*FIXME: should be moved to saa711x */ -static int saa711x_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) -{ - switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: return em28xx_brightness_set(dev, ctrl->value); case V4L2_CID_CONTRAST: @@ -1021,34 +994,14 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp, case VIDIOC_QUERYCTRL: { struct v4l2_queryctrl *qc = arg; - int i, id=qc->id; - - memset(qc,0,sizeof(*qc)); - qc->id=id; - - if (!dev->has_msp34xx) { - for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { - if (qc->id && qc->id == em28xx_qctrl[i].id) { - memcpy(qc, &(em28xx_qctrl[i]), - sizeof(*qc)); - return 0; - } - } - } - if (dev->decoder == EM28XX_TVP5150) { - em28xx_i2c_call_clients(dev,cmd,qc); - if (qc->type) - return 0; - else - return -EINVAL; - } - for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) { - if (qc->id && qc->id == saa711x_qctrl[i].id) { - memcpy(qc, &(saa711x_qctrl[i]), + u8 i, n; + n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]); + for (i = 0; i < n; i++) + if (qc->id && qc->id == em28xx_qctrl[i].id) { + memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc)); return 0; } - } return -EINVAL; } @@ -1056,64 +1009,29 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp, case VIDIOC_G_CTRL: { struct v4l2_control *ctrl = arg; - int retval=-EINVAL; - if (!dev->has_msp34xx) - retval=em28xx_get_ctrl(dev, ctrl); - if (retval==-EINVAL) { - if (dev->decoder == EM28XX_TVP5150) { - em28xx_i2c_call_clients(dev,cmd,arg); - return 0; - } - return saa711x_get_ctrl(dev, ctrl); - } else return retval; + return em28xx_get_ctrl(dev, ctrl); } + case VIDIOC_S_CTRL_OLD: /* ??? */ case VIDIOC_S_CTRL: { struct v4l2_control *ctrl = arg; - u8 i; - - if (!dev->has_msp34xx){ - for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { - if (ctrl->id == em28xx_qctrl[i].id) { - if (ctrl->value < - em28xx_qctrl[i].minimum - || ctrl->value > - em28xx_qctrl[i].maximum) - return -ERANGE; - return em28xx_set_ctrl(dev, ctrl); - } - } - } + u8 i, n; - if (dev->decoder == EM28XX_TVP5150) { - em28xx_i2c_call_clients(dev,cmd,arg); - return 0; - } else if (!dev->has_msp34xx) { - for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { - if (ctrl->id == em28xx_qctrl[i].id) { - if (ctrl->value < - em28xx_qctrl[i].minimum - || ctrl->value > - em28xx_qctrl[i].maximum) - return -ERANGE; - return em28xx_set_ctrl(dev, ctrl); - } - } - for (i = 0; i < ARRAY_SIZE(saa711x_qctrl); i++) { - if (ctrl->id == saa711x_qctrl[i].id) { - if (ctrl->value < - saa711x_qctrl[i].minimum - || ctrl->value > - saa711x_qctrl[i].maximum) - return -ERANGE; - return saa711x_set_ctrl(dev, ctrl); - } - } - } + n = sizeof(em28xx_qctrl) / sizeof(em28xx_qctrl[0]); + for (i = 0; i < n; i++) + if (ctrl->id == em28xx_qctrl[i].id) { + if (ctrl->value < + em28xx_qctrl[i].minimum + || ctrl->value > + em28xx_qctrl[i].maximum) + return -ERANGE; + + return em28xx_set_ctrl(dev, ctrl); + } return -EINVAL; } @@ -1269,7 +1187,7 @@ static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp, return -ENODEV; if (video_debug > 1) - v4l_print_ioctl(dev->name,cmd); + em28xx_print_ioctl(dev->name,cmd); switch (cmd) { @@ -1646,8 +1564,6 @@ static struct file_operations em28xx_v4l_fops = { .poll = em28xx_v4l2_poll, .mmap = em28xx_v4l2_mmap, .llseek = no_llseek, - .compat_ioctl = v4l_compat_ioctl32, - }; /******************************** usb interface *****************************************/ @@ -1932,12 +1848,9 @@ static void em28xx_usb_disconnect(struct usb_interface *interface) struct em28xx *dev = usb_get_intfdata(interface); usb_set_intfdata(interface, NULL); -/*FIXME: IR should be disconnected */ - if (!dev) return; - down_write(&em28xx_disconnect); down(&dev->lock); diff --git a/trunk/drivers/media/video/em28xx/em28xx.h b/trunk/drivers/media/video/em28xx/em28xx.h index 33de9d846af5..5c7a41ce69f3 100644 --- a/trunk/drivers/media/video/em28xx/em28xx.h +++ b/trunk/drivers/media/video/em28xx/em28xx.h @@ -1,5 +1,5 @@ /* - em28xx.h - driver for Empia EM2800/EM2820/2840 USB video capture devices + em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices Copyright (C) 2005 Markus Rechberger Ludovico Cavedon @@ -216,8 +216,6 @@ struct em28xx { unsigned int has_msp34xx:1; unsigned int has_tda9887:1; - u32 i2s_speed; /* I2S speed for audio digital stream */ - enum em28xx_decoder decoder; int tuner_type; /* type of the tuner */ @@ -295,6 +293,8 @@ void em28xx_set_ir(struct em28xx * dev,struct IR_i2c *ir); /* Provided by em28xx-core.c */ +void em28xx_print_ioctl(char *name, unsigned int cmd); + u32 em28xx_request_buffers(struct em28xx *dev, u32 count); void em28xx_queue_unusedframes(struct em28xx *dev); void em28xx_release_buffers(struct em28xx *dev); diff --git a/trunk/drivers/media/video/bttv-input.c b/trunk/drivers/media/video/ir-kbd-gpio.c similarity index 73% rename from trunk/drivers/media/video/bttv-input.c rename to trunk/drivers/media/video/ir-kbd-gpio.c index 12197f1b2757..de1385e5d05e 100644 --- a/trunk/drivers/media/video/bttv-input.c +++ b/trunk/drivers/media/video/ir-kbd-gpio.c @@ -24,9 +24,11 @@ #include #include #include +#include + +#include #include "bttv.h" -#include "bttvp.h" /* ---------------------------------------------------------------------- */ @@ -154,6 +156,9 @@ static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = { /* ---------------------------------------------------------------------- */ +/* Ricardo Cerqueira */ +/* Weird matching, since the remote has "uncommon" keys */ + static IR_KEYTAB_TYPE ir_codes_conceptronic[IR_KEYTAB_SIZE] = { [ 30 ] = KEY_POWER, // power @@ -274,6 +279,34 @@ static IR_KEYTAB_TYPE ir_codes_nebula[IR_KEYTAB_SIZE] = { [0x36] = KEY_PC }; +struct IR { + struct bttv_sub_device *sub; + struct input_dev *input; + struct ir_input_state ir; + char name[32]; + char phys[32]; + + /* Usual gpio signalling */ + + u32 mask_keycode; + u32 mask_keydown; + u32 mask_keyup; + u32 polling; + u32 last_gpio; + struct work_struct work; + struct timer_list timer; + + /* RC5 gpio */ + u32 rc5_gpio; + struct timer_list timer_end; /* timer_end for code completion */ + struct timer_list timer_keyup; /* timer_end for key release */ + u32 last_rc5; /* last good rc5 code */ + u32 last_bit; /* last raw bit seen */ + u32 code; /* raw code under construction */ + struct timeval base_time; /* time of last seen code */ + int active; /* building raw code */ +}; + static int debug; module_param(debug, int, 0644); /* debug level (0,1,2) */ static int repeat_delay = 500; @@ -281,17 +314,31 @@ module_param(repeat_delay, int, 0644); static int repeat_period = 33; module_param(repeat_period, int, 0644); -#define DEVNAME "bttv-input" +#define DEVNAME "ir-kbd-gpio" +#define dprintk(fmt, arg...) if (debug) \ + printk(KERN_DEBUG DEVNAME ": " fmt , ## arg) + +static void ir_irq(struct bttv_sub_device *sub); +static int ir_probe(struct device *dev); +static int ir_remove(struct device *dev); + +static struct bttv_sub_driver driver = { + .drv = { + .name = DEVNAME, + .probe = ir_probe, + .remove = ir_remove, + }, + .gpio_irq = ir_irq, +}; /* ---------------------------------------------------------------------- */ -static void ir_handle_key(struct bttv *btv) +static void ir_handle_key(struct IR *ir) { - struct bttv_ir *ir = btv->remote; u32 gpio,data; /* read gpio value */ - gpio = bttv_gpio_read(&btv->c); + gpio = bttv_gpio_read(ir->sub->core); if (ir->polling) { if (ir->last_gpio == gpio) return; @@ -300,36 +347,56 @@ static void ir_handle_key(struct bttv *btv) /* extract data */ data = ir_extract_bits(gpio, ir->mask_keycode); - dprintk(KERN_INFO DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n", + dprintk(DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n", gpio, data, ir->polling ? "poll" : "irq", (gpio & ir->mask_keydown) ? " down" : "", (gpio & ir->mask_keyup) ? " up" : ""); - if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || - (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { - ir_input_keydown(ir->dev,&ir->ir,data,data); + if (ir->mask_keydown) { + /* bit set on keydown */ + if (gpio & ir->mask_keydown) { + ir_input_keydown(ir->input, &ir->ir, data, data); + } else { + ir_input_nokey(ir->input, &ir->ir); + } + + } else if (ir->mask_keyup) { + /* bit cleared on keydown */ + if (0 == (gpio & ir->mask_keyup)) { + ir_input_keydown(ir->input, &ir->ir, data, data); + } else { + ir_input_nokey(ir->input, &ir->ir); + } + } else { - ir_input_nokey(ir->dev,&ir->ir); + /* can't disturgissh keydown/up :-/ */ + ir_input_keydown(ir->input, &ir->ir, data, data); + ir_input_nokey(ir->input, &ir->ir); } - } -void bttv_input_irq(struct bttv *btv) +static void ir_irq(struct bttv_sub_device *sub) { - struct bttv_ir *ir = btv->remote; + struct IR *ir = dev_get_drvdata(&sub->dev); if (!ir->polling) - ir_handle_key(btv); + ir_handle_key(ir); +} + +static void ir_timer(unsigned long data) +{ + struct IR *ir = (struct IR*)data; + + schedule_work(&ir->work); } -static void bttv_input_timer(unsigned long data) +static void ir_work(void *data) { - struct bttv *btv = (struct bttv*)data; - struct bttv_ir *ir = btv->remote; + struct IR *ir = data; unsigned long timeout; - ir_handle_key(btv); + ir_handle_key(ir); timeout = jiffies + (ir->polling * HZ / 1000); mod_timer(&ir->timer, timeout); } @@ -368,26 +435,26 @@ static u32 rc5_decode(unsigned int code) rc5 |= 1; break; case 3: - dprintk(KERN_WARNING "bad code: %x\n", org_code); + dprintk("bad code: %x\n", org_code); return 0; } } - dprintk(KERN_WARNING "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " + dprintk("code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " "instr=%x\n", rc5, org_code, RC5_START(rc5), RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); return rc5; } -static int bttv_rc5_irq(struct bttv *btv) +static int ir_rc5_irq(struct bttv_sub_device *sub) { - struct bttv_ir *ir = btv->remote; + struct IR *ir = dev_get_drvdata(&sub->dev); struct timeval tv; u32 gpio; u32 gap; unsigned long current_jiffies, timeout; /* read gpio port */ - gpio = bttv_gpio_read(&btv->c); + gpio = bttv_gpio_read(ir->sub->core); /* remote IRQ? */ if (!(gpio & 0x20)) @@ -426,15 +493,14 @@ static int bttv_rc5_irq(struct bttv *btv) } /* toggle GPIO pin 4 to reset the irq */ - bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); - bttv_gpio_write(&btv->c, gpio | (1 << 4)); + bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4)); + bttv_gpio_write(ir->sub->core, gpio | (1 << 4)); return 1; } - -static void bttv_rc5_timer_end(unsigned long data) +static void ir_rc5_timer_end(unsigned long data) { - struct bttv_ir *ir = (struct bttv_ir *)data; + struct IR *ir = (struct IR *)data; struct timeval tv; unsigned long current_jiffies, timeout; u32 gap; @@ -453,20 +519,20 @@ static void bttv_rc5_timer_end(unsigned long data) /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */ if (gap < 28000) { - dprintk(KERN_WARNING "spurious timer_end\n"); + dprintk("spurious timer_end\n"); return; } ir->active = 0; if (ir->last_bit < 20) { /* ignore spurious codes (caused by light/other remotes) */ - dprintk(KERN_WARNING "short code: %x\n", ir->code); + dprintk("short code: %x\n", ir->code); } else { u32 rc5 = rc5_decode(ir->code); /* two start bits? */ if (RC5_START(rc5) != 3) { - dprintk(KERN_WARNING "rc5 start bits invalid: %u\n", RC5_START(rc5)); + dprintk("rc5 start bits invalid: %u\n", RC5_START(rc5)); /* right address? */ } else if (RC5_ADDR(rc5) == 0x0) { @@ -476,10 +542,10 @@ static void bttv_rc5_timer_end(unsigned long data) /* Good code, decide if repeat/repress */ if (toggle != RC5_TOGGLE(ir->last_rc5) || instr != RC5_INSTR(ir->last_rc5)) { - dprintk(KERN_WARNING "instruction %x, toggle %x\n", instr, + dprintk("instruction %x, toggle %x\n", instr, toggle); - ir_input_nokey(ir->dev, &ir->ir); - ir_input_keydown(ir->dev, &ir->ir, instr, + ir_input_nokey(ir->input, &ir->ir); + ir_input_keydown(ir->input, &ir->ir, instr, instr); } @@ -494,37 +560,34 @@ static void bttv_rc5_timer_end(unsigned long data) } } -static void bttv_rc5_timer_keyup(unsigned long data) +static void ir_rc5_timer_keyup(unsigned long data) { - struct bttv_ir *ir = (struct bttv_ir *)data; + struct IR *ir = (struct IR *)data; - dprintk(KERN_DEBUG "key released\n"); - ir_input_nokey(ir->dev, &ir->ir); + dprintk("key released\n"); + ir_input_nokey(ir->input, &ir->ir); } /* ---------------------------------------------------------------------- */ -int bttv_input_init(struct bttv *btv) +static int ir_probe(struct device *dev) { - struct bttv_ir *ir; - IR_KEYTAB_TYPE *ir_codes = NULL; + struct bttv_sub_device *sub = to_bttv_sub_dev(dev); + struct IR *ir; struct input_dev *input_dev; + IR_KEYTAB_TYPE *ir_codes = NULL; int ir_type = IR_TYPE_OTHER; - if (!btv->has_remote) - return -ENODEV; - - ir = kzalloc(sizeof(*ir),GFP_KERNEL); + ir = kzalloc(sizeof(*ir), GFP_KERNEL); input_dev = input_allocate_device(); if (!ir || !input_dev) { kfree(ir); input_free_device(input_dev); return -ENOMEM; } - memset(ir,0,sizeof(*ir)); /* detect & configure */ - switch (btv->c.type) { + switch (sub->core->type) { case BTTV_BOARD_AVERMEDIA: case BTTV_BOARD_AVPHONE98: case BTTV_BOARD_AVERMEDIA98: @@ -580,12 +643,12 @@ int bttv_input_init(struct bttv *btv) break; case BTTV_BOARD_NEBULA_DIGITV: ir_codes = ir_codes_nebula; - btv->custom_irq = bttv_rc5_irq; + driver.any_irq = ir_rc5_irq; + driver.gpio_irq = NULL; ir->rc5_gpio = 1; break; } if (NULL == ir_codes) { - dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n",btv->c.type); kfree(ir); input_free_device(input_dev); return -ENODEV; @@ -594,92 +657,109 @@ int bttv_input_init(struct bttv *btv) if (ir->rc5_gpio) { u32 gpio; /* enable remote irq */ - bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4); - gpio = bttv_gpio_read(&btv->c); - bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); - bttv_gpio_write(&btv->c, gpio | (1 << 4)); + bttv_gpio_inout(sub->core, (1 << 4), 1 << 4); + gpio = bttv_gpio_read(sub->core); + bttv_gpio_write(sub->core, gpio & ~(1 << 4)); + bttv_gpio_write(sub->core, gpio | (1 << 4)); } else { /* init hardware-specific stuff */ - bttv_gpio_inout(&btv->c, ir->mask_keycode | ir->mask_keydown, 0); + bttv_gpio_inout(sub->core, ir->mask_keycode | ir->mask_keydown, 0); } /* init input device */ - ir->dev = input_dev; - snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)", - btv->c.type); + sub->core->type); snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", - pci_name(btv->c.pci)); + pci_name(sub->core->pci)); ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); input_dev->name = ir->name; input_dev->phys = ir->phys; input_dev->id.bustype = BUS_PCI; input_dev->id.version = 1; - if (btv->c.pci->subsystem_vendor) { - input_dev->id.vendor = btv->c.pci->subsystem_vendor; - input_dev->id.product = btv->c.pci->subsystem_device; + if (sub->core->pci->subsystem_vendor) { + input_dev->id.vendor = sub->core->pci->subsystem_vendor; + input_dev->id.product = sub->core->pci->subsystem_device; } else { - input_dev->id.vendor = btv->c.pci->vendor; - input_dev->id.product = btv->c.pci->device; + input_dev->id.vendor = sub->core->pci->vendor; + input_dev->id.product = sub->core->pci->device; } - input_dev->cdev.dev = &btv->c.pci->dev; + input_dev->cdev.dev = &sub->core->pci->dev; + + ir->input = input_dev; + ir->sub = sub; - btv->remote = ir; if (ir->polling) { + INIT_WORK(&ir->work, ir_work, ir); init_timer(&ir->timer); - ir->timer.function = bttv_input_timer; - ir->timer.data = (unsigned long)btv; - ir->timer.expires = jiffies + HZ; - add_timer(&ir->timer); + ir->timer.function = ir_timer; + ir->timer.data = (unsigned long)ir; + schedule_work(&ir->work); } else if (ir->rc5_gpio) { /* set timer_end for code completion */ init_timer(&ir->timer_end); - ir->timer_end.function = bttv_rc5_timer_end; + ir->timer_end.function = ir_rc5_timer_end; ir->timer_end.data = (unsigned long)ir; init_timer(&ir->timer_keyup); - ir->timer_keyup.function = bttv_rc5_timer_keyup; + ir->timer_keyup.function = ir_rc5_timer_keyup; ir->timer_keyup.data = (unsigned long)ir; } /* all done */ - input_register_device(btv->remote->dev); - printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys); + dev_set_drvdata(dev, ir); + input_register_device(ir->input); /* the remote isn't as bouncy as a keyboard */ - ir->dev->rep[REP_DELAY] = repeat_delay; - ir->dev->rep[REP_PERIOD] = repeat_period; + ir->input->rep[REP_DELAY] = repeat_delay; + ir->input->rep[REP_PERIOD] = repeat_period; return 0; } -void bttv_input_fini(struct bttv *btv) +static int ir_remove(struct device *dev) { - if (btv->remote == NULL) - return; + struct IR *ir = dev_get_drvdata(dev); - if (btv->remote->polling) { - del_timer_sync(&btv->remote->timer); + if (ir->polling) { + del_timer(&ir->timer); flush_scheduled_work(); } - - if (btv->remote->rc5_gpio) { + if (ir->rc5_gpio) { u32 gpio; - del_timer_sync(&btv->remote->timer_end); + del_timer(&ir->timer_end); flush_scheduled_work(); - gpio = bttv_gpio_read(&btv->c); - bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); + gpio = bttv_gpio_read(ir->sub->core); + bttv_gpio_write(ir->sub->core, gpio & ~(1 << 4)); } - input_unregister_device(btv->remote->dev); - kfree(btv->remote); - btv->remote = NULL; + input_unregister_device(ir->input); + kfree(ir); + return 0; +} + +/* ---------------------------------------------------------------------- */ + +MODULE_AUTHOR("Gerd Knorr, Pavel Machek"); +MODULE_DESCRIPTION("input driver for bt8x8 gpio IR remote controls"); +MODULE_LICENSE("GPL"); + +static int ir_init(void) +{ + return bttv_sub_register(&driver, "remote"); } +static void ir_fini(void) +{ + bttv_sub_unregister(&driver); +} + +module_init(ir_init); +module_exit(ir_fini); + /* * Local variables: diff --git a/trunk/drivers/media/video/ir-kbd-i2c.c b/trunk/drivers/media/video/ir-kbd-i2c.c index 58b0e6982822..3cc1d6a6019b 100644 --- a/trunk/drivers/media/video/ir-kbd-i2c.c +++ b/trunk/drivers/media/video/ir-kbd-i2c.c @@ -279,7 +279,7 @@ static int ir_probe(struct i2c_adapter *adap); static struct i2c_driver driver = { .driver = { - .name = "ir-kbd-i2c", + .name = "ir remote kbd driver", }, .id = I2C_DRIVERID_INFRARED, .attach_adapter = ir_probe, @@ -304,20 +304,18 @@ static int ir_attach(struct i2c_adapter *adap, int addr, ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL); input_dev = input_allocate_device(); if (!ir || !input_dev) { - input_free_device(input_dev); kfree(ir); + input_free_device(input_dev); return -ENOMEM; } - memset(ir,0,sizeof(*ir)); ir->c = client_template; ir->input = input_dev; + i2c_set_clientdata(&ir->c, ir); ir->c.adapter = adap; ir->c.addr = addr; - i2c_set_clientdata(&ir->c, ir); - switch(addr) { case 0x64: name = "Pixelview"; @@ -380,15 +378,13 @@ static int ir_attach(struct i2c_adapter *adap, int addr, ir->c.dev.bus_id); /* init + register input device */ - ir_input_init(input_dev,&ir->ir,ir_type,ir->ir_codes); - input_dev->id.bustype = BUS_I2C; - input_dev->name = ir->c.name; - input_dev->phys = ir->phys; + ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); + input_dev->id.bustype = BUS_I2C; + input_dev->name = ir->c.name; + input_dev->phys = ir->phys; /* register event device */ input_register_device(ir->input); - printk(DEVNAME ": %s detected at %s [%s]\n", - ir->input->name,ir->input->phys,adap->name); /* start polling via eventd */ INIT_WORK(&ir->work, ir_work, ir); diff --git a/trunk/drivers/media/video/meye.c b/trunk/drivers/media/video/meye.c index 2869464aee0d..3f2a882bc20a 100644 --- a/trunk/drivers/media/video/meye.c +++ b/trunk/drivers/media/video/meye.c @@ -1754,7 +1754,6 @@ static struct file_operations meye_fops = { .release = meye_release, .mmap = meye_mmap, .ioctl = meye_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .poll = meye_poll, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/video/msp3400-driver.c b/trunk/drivers/media/video/msp3400-driver.c deleted file mode 100644 index aa8c556b6ba1..000000000000 --- a/trunk/drivers/media/video/msp3400-driver.c +++ /dev/null @@ -1,1274 +0,0 @@ -/* - * Programming the mspx4xx sound processor family - * - * (c) 1997-2001 Gerd Knorr - * - * what works and what doesn't: - * - * AM-Mono - * Support for Hauppauge cards added (decoding handled by tuner) added by - * Frederic Crozat - * - * FM-Mono - * should work. The stereo modes are backward compatible to FM-mono, - * therefore FM-Mono should be allways available. - * - * FM-Stereo (B/G, used in germany) - * should work, with autodetect - * - * FM-Stereo (satellite) - * should work, no autodetect (i.e. default is mono, but you can - * switch to stereo -- untested) - * - * NICAM (B/G, L , used in UK, Scandinavia, Spain and France) - * should work, with autodetect. Support for NICAM was added by - * Pekka Pietikainen - * - * TODO: - * - better SAT support - * - * 980623 Thomas Sailer (sailer@ife.ee.ethz.ch) - * using soundcore instead of OSS - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "msp3400.h" - -/* ---------------------------------------------------------------------- */ - -MODULE_DESCRIPTION("device driver for msp34xx TV sound processor"); -MODULE_AUTHOR("Gerd Knorr"); -MODULE_LICENSE("GPL"); - -/* module parameters */ -static int opmode = OPMODE_AUTO; -int debug = 0; /* debug output */ -int once = 0; /* no continous stereo monitoring */ -int amsound = 0; /* hard-wire AM sound at 6.5 Hz (france), - the autoscan seems work well only with FM... */ -int standard = 1; /* Override auto detect of audio standard, if needed. */ -int dolby = 0; - -int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual - (msp34xxg only) 0x00a0-0x03c0 */ - -/* read-only */ -module_param(opmode, int, 0444); - -/* read-write */ -module_param(once, bool, 0644); -module_param(debug, int, 0644); -module_param(stereo_threshold, int, 0644); -module_param(standard, int, 0644); -module_param(amsound, bool, 0644); -module_param(dolby, bool, 0644); - -MODULE_PARM_DESC(opmode, "Forces a MSP3400 opmode. 0=Manual, 1=Autodetect, 2=Autodetect and autoselect"); -MODULE_PARM_DESC(once, "No continuous stereo monitoring"); -MODULE_PARM_DESC(debug, "Enable debug messages [0-3]"); -MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo"); -MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect"); -MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); -MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); - -/* ---------------------------------------------------------------------- */ - -/* control subaddress */ -#define I2C_MSP_CONTROL 0x00 -/* demodulator unit subaddress */ -#define I2C_MSP_DEM 0x10 -/* DSP unit subaddress */ -#define I2C_MSP_DSP 0x12 - -/* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x80 >> 1, 0x88 >> 1, I2C_CLIENT_END }; -I2C_CLIENT_INSMOD; - -/* ----------------------------------------------------------------------- */ -/* functions for talking to the MSP3400C Sound processor */ - -int msp_reset(struct i2c_client *client) -{ - /* reset and read revision code */ - static u8 reset_off[3] = { I2C_MSP_CONTROL, 0x80, 0x00 }; - static u8 reset_on[3] = { I2C_MSP_CONTROL, 0x00, 0x00 }; - static u8 write[3] = { I2C_MSP_DSP + 1, 0x00, 0x1e }; - u8 read[2]; - struct i2c_msg reset[2] = { - { client->addr, I2C_M_IGNORE_NAK, 3, reset_off }, - { client->addr, I2C_M_IGNORE_NAK, 3, reset_on }, - }; - struct i2c_msg test[2] = { - { client->addr, 0, 3, write }, - { client->addr, I2C_M_RD, 2, read }, - }; - - v4l_dbg(3, client, "msp_reset\n"); - if (i2c_transfer(client->adapter, &reset[0], 1) != 1 || - i2c_transfer(client->adapter, &reset[1], 1) != 1 || - i2c_transfer(client->adapter, test, 2) != 2) { - v4l_err(client, "chip reset failed\n"); - return -1; - } - return 0; -} - -static int msp_read(struct i2c_client *client, int dev, int addr) -{ - int err, retval; - u8 write[3]; - u8 read[2]; - struct i2c_msg msgs[2] = { - { client->addr, 0, 3, write }, - { client->addr, I2C_M_RD, 2, read } - }; - - write[0] = dev + 1; - write[1] = addr >> 8; - write[2] = addr & 0xff; - - for (err = 0; err < 3; err++) { - if (i2c_transfer(client->adapter, msgs, 2) == 2) - break; - v4l_warn(client, "I/O error #%d (read 0x%02x/0x%02x)\n", err, - dev, addr); - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(msecs_to_jiffies(10)); - } - if (err == 3) { - v4l_warn(client, "giving up, resetting chip. Sound will go off, sorry folks :-|\n"); - msp_reset(client); - return -1; - } - retval = read[0] << 8 | read[1]; - v4l_dbg(3, client, "msp_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval); - return retval; -} - -int msp_read_dem(struct i2c_client *client, int addr) -{ - return msp_read(client, I2C_MSP_DEM, addr); -} - -int msp_read_dsp(struct i2c_client *client, int addr) -{ - return msp_read(client, I2C_MSP_DSP, addr); -} - -static int msp_write(struct i2c_client *client, int dev, int addr, int val) -{ - int err; - u8 buffer[5]; - - buffer[0] = dev; - buffer[1] = addr >> 8; - buffer[2] = addr & 0xff; - buffer[3] = val >> 8; - buffer[4] = val & 0xff; - - v4l_dbg(3, client, "msp_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val); - for (err = 0; err < 3; err++) { - if (i2c_master_send(client, buffer, 5) == 5) - break; - v4l_warn(client, "I/O error #%d (write 0x%02x/0x%02x)\n", err, - dev, addr); - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(msecs_to_jiffies(10)); - } - if (err == 3) { - v4l_warn(client, "giving up, resetting chip. Sound will go off, sorry folks :-|\n"); - msp_reset(client); - return -1; - } - return 0; -} - -int msp_write_dem(struct i2c_client *client, int addr, int val) -{ - return msp_write(client, I2C_MSP_DEM, addr, val); -} - -int msp_write_dsp(struct i2c_client *client, int addr, int val) -{ - return msp_write(client, I2C_MSP_DSP, addr, val); -} - -/* ----------------------------------------------------------------------- * - * bits 9 8 5 - SCART DSP input Select: - * 0 0 0 - SCART 1 to DSP input (reset position) - * 0 1 0 - MONO to DSP input - * 1 0 0 - SCART 2 to DSP input - * 1 1 1 - Mute DSP input - * - * bits 11 10 6 - SCART 1 Output Select: - * 0 0 0 - undefined (reset position) - * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS) - * 1 0 0 - MONO input to SCART 1 Output - * 1 1 0 - SCART 1 DA to SCART 1 Output - * 0 0 1 - SCART 2 DA to SCART 1 Output - * 0 1 1 - SCART 1 Input to SCART 1 Output - * 1 1 1 - Mute SCART 1 Output - * - * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART): - * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position) - * 0 1 0 - SCART 1 Input to SCART 2 Output - * 1 0 0 - MONO input to SCART 2 Output - * 0 0 1 - SCART 2 DA to SCART 2 Output - * 0 1 1 - SCART 2 Input to SCART 2 Output - * 1 1 0 - Mute SCART 2 Output - * - * Bits 4 to 0 should be zero. - * ----------------------------------------------------------------------- */ - -static int scarts[3][9] = { - /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ - /* SCART DSP Input select */ - { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, - /* SCART1 Output select */ - { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, - /* SCART2 Output select */ - { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, -}; - -static char *scart_names[] = { - "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" -}; - -void msp_set_scart(struct i2c_client *client, int in, int out) -{ - struct msp_state *state = i2c_get_clientdata(client); - - state->in_scart=in; - - if (in >= 1 && in <= 8 && out >= 0 && out <= 2) { - if (-1 == scarts[out][in]) - return; - - state->acb &= ~scarts[out][SCART_MASK]; - state->acb |= scarts[out][in]; - } else - state->acb = 0xf60; /* Mute Input and SCART 1 Output */ - - v4l_dbg(1, client, "scart switch: %s => %d (ACB=0x%04x)\n", - scart_names[in], out, state->acb); - msp_write_dsp(client, 0x13, state->acb); - - /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */ - msp_write_dem(client, 0x40, state->i2s_mode); -} - -void msp_set_mute(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - - v4l_dbg(1, client, "mute audio\n"); - msp_write_dsp(client, 0x0000, 0); - msp_write_dsp(client, 0x0007, 1); - if (state->has_scart2_out_volume) - msp_write_dsp(client, 0x0040, 1); - if (state->has_headphones) - msp_write_dsp(client, 0x0006, 0); -} - -void msp_set_audio(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - int bal = 0, bass, treble, loudness; - int val = 0; - - if (!state->muted) - val = (state->volume * 0x7f / 65535) << 8; - - v4l_dbg(1, client, "mute=%s volume=%d\n", - state->muted ? "on" : "off", state->volume); - - msp_write_dsp(client, 0x0000, val); - msp_write_dsp(client, 0x0007, state->muted ? 0x1 : (val | 0x1)); - if (state->has_scart2_out_volume) - msp_write_dsp(client, 0x0040, state->muted ? 0x1 : (val | 0x1)); - if (state->has_headphones) - msp_write_dsp(client, 0x0006, val); - if (!state->has_sound_processing) - return; - - if (val) - bal = (u8)((state->balance / 256) - 128); - bass = ((state->bass - 32768) * 0x60 / 65535) << 8; - treble = ((state->treble - 32768) * 0x60 / 65535) << 8; - loudness = state->loudness ? ((5 * 4) << 8) : 0; - - v4l_dbg(1, client, "balance=%d bass=%d treble=%d loudness=%d\n", - state->balance, state->bass, state->treble, state->loudness); - - msp_write_dsp(client, 0x0001, bal << 8); - msp_write_dsp(client, 0x0002, bass); - msp_write_dsp(client, 0x0003, treble); - msp_write_dsp(client, 0x0004, loudness); - if (!state->has_headphones) - return; - msp_write_dsp(client, 0x0030, bal << 8); - msp_write_dsp(client, 0x0031, bass); - msp_write_dsp(client, 0x0032, treble); - msp_write_dsp(client, 0x0033, loudness); -} - -int msp_modus(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - - if (state->radio) { - v4l_dbg(1, client, "video mode selected to Radio\n"); - return 0x0003; - } - - if (state->v4l2_std & V4L2_STD_PAL) { - v4l_dbg(1, client, "video mode selected to PAL\n"); - -#if 1 - /* experimental: not sure this works with all chip versions */ - return 0x7003; -#else - /* previous value, try this if it breaks ... */ - return 0x1003; -#endif - } - if (state->v4l2_std & V4L2_STD_NTSC) { - v4l_dbg(1, client, "video mode selected to NTSC\n"); - return 0x2003; - } - if (state->v4l2_std & V4L2_STD_SECAM) { - v4l_dbg(1, client, "video mode selected to SECAM\n"); - return 0x0003; - } - return 0x0003; -} - -/* ------------------------------------------------------------------------ */ - - -static void msp_wake_thread(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - - if (NULL == state->kthread) - return; - msp_set_mute(client); - state->watch_stereo = 0; - state->restart = 1; - wake_up_interruptible(&state->wq); -} - -int msp_sleep(struct msp_state *state, int timeout) -{ - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue(&state->wq, &wait); - if (!kthread_should_stop()) { - if (timeout < 0) { - set_current_state(TASK_INTERRUPTIBLE); - schedule(); - } else { - schedule_timeout_interruptible - (msecs_to_jiffies(timeout)); - } - } - - remove_wait_queue(&state->wq, &wait); - try_to_freeze(); - return state->restart; -} - -/* ------------------------------------------------------------------------ */ - -static int msp_mode_v4l2_to_v4l1(int rxsubchans) -{ - int mode = 0; - - if (rxsubchans & V4L2_TUNER_SUB_STEREO) - mode |= VIDEO_SOUND_STEREO; - if (rxsubchans & V4L2_TUNER_SUB_LANG2) - mode |= VIDEO_SOUND_LANG2; - if (rxsubchans & V4L2_TUNER_SUB_LANG1) - mode |= VIDEO_SOUND_LANG1; - if (mode == 0) - mode |= VIDEO_SOUND_MONO; - return mode; -} - -static int msp_mode_v4l1_to_v4l2(int mode) -{ - if (mode & VIDEO_SOUND_STEREO) - return V4L2_TUNER_MODE_STEREO; - if (mode & VIDEO_SOUND_LANG2) - return V4L2_TUNER_MODE_LANG2; - if (mode & VIDEO_SOUND_LANG1) - return V4L2_TUNER_MODE_LANG1; - return V4L2_TUNER_MODE_MONO; -} - -static void msp_any_detect_stereo(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - - switch (state->opmode) { - case OPMODE_MANUAL: - case OPMODE_AUTODETECT: - autodetect_stereo(client); - break; - case OPMODE_AUTOSELECT: - msp34xxg_detect_stereo(client); - break; - } -} - -static struct v4l2_queryctrl msp_qctrl_std[] = { - { - .id = V4L2_CID_AUDIO_VOLUME, - .name = "Volume", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 58880, - .flags = 0, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_AUDIO_MUTE, - .name = "Mute", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - .flags = 0, - .type = V4L2_CTRL_TYPE_BOOLEAN, - }, -}; - -static struct v4l2_queryctrl msp_qctrl_sound_processing[] = { - { - .id = V4L2_CID_AUDIO_BALANCE, - .name = "Balance", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 32768, - .flags = 0, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_AUDIO_BASS, - .name = "Bass", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_AUDIO_TREBLE, - .name = "Treble", - .minimum = 0, - .maximum = 65535, - .step = 65535/100, - .default_value = 32768, - .type = V4L2_CTRL_TYPE_INTEGER, - },{ - .id = V4L2_CID_AUDIO_LOUDNESS, - .name = "Loudness", - .minimum = 0, - .maximum = 1, - .step = 1, - .default_value = 1, - .flags = 0, - .type = V4L2_CTRL_TYPE_BOOLEAN, - }, -}; - - -static void msp_any_set_audmode(struct i2c_client *client, int audmode) -{ - struct msp_state *state = i2c_get_clientdata(client); - - switch (state->opmode) { - case OPMODE_MANUAL: - case OPMODE_AUTODETECT: - state->watch_stereo = 0; - msp3400c_setstereo(client, audmode); - break; - case OPMODE_AUTOSELECT: - msp34xxg_set_audmode(client, audmode); - break; - } -} - -static int msp_get_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) -{ - struct msp_state *state = i2c_get_clientdata(client); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - ctrl->value = state->volume; - break; - - case V4L2_CID_AUDIO_MUTE: - ctrl->value = state->muted; - break; - - case V4L2_CID_AUDIO_BALANCE: - if (!state->has_sound_processing) - return -EINVAL; - ctrl->value = state->balance; - break; - - case V4L2_CID_AUDIO_BASS: - if (!state->has_sound_processing) - return -EINVAL; - ctrl->value = state->bass; - break; - - case V4L2_CID_AUDIO_TREBLE: - if (!state->has_sound_processing) - return -EINVAL; - ctrl->value = state->treble; - break; - - case V4L2_CID_AUDIO_LOUDNESS: - if (!state->has_sound_processing) - return -EINVAL; - ctrl->value = state->loudness; - break; - - default: - return -EINVAL; - } - return 0; -} - -static int msp_set_ctrl(struct i2c_client *client, struct v4l2_control *ctrl) -{ - struct msp_state *state = i2c_get_clientdata(client); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - state->volume = ctrl->value; - if (state->volume == 0) - state->balance = 32768; - break; - - case V4L2_CID_AUDIO_MUTE: - if (ctrl->value < 0 || ctrl->value >= 2) - return -ERANGE; - state->muted = ctrl->value; - break; - - case V4L2_CID_AUDIO_BASS: - if (!state->has_sound_processing) - return -EINVAL; - state->bass = ctrl->value; - break; - - case V4L2_CID_AUDIO_TREBLE: - if (!state->has_sound_processing) - return -EINVAL; - state->treble = ctrl->value; - break; - - case V4L2_CID_AUDIO_LOUDNESS: - if (!state->has_sound_processing) - return -EINVAL; - state->loudness = ctrl->value; - break; - - case V4L2_CID_AUDIO_BALANCE: - if (!state->has_sound_processing) - return -EINVAL; - state->balance = ctrl->value; - break; - - default: - return -EINVAL; - } - msp_set_audio(client); - return 0; -} - -static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) -{ - struct msp_state *state = i2c_get_clientdata(client); - u16 *sarg = arg; - int scart = 0; - - if (debug >= 2) - v4l_i2c_print_ioctl(client, cmd); - - switch (cmd) { - case AUDC_SET_INPUT: - if (*sarg == state->input) - break; - state->input = *sarg; - switch (*sarg) { - case AUDIO_RADIO: - /* Hauppauge uses IN2 for the radio */ - state->mode = MSP_MODE_FM_RADIO; - scart = SCART_IN2; - break; - case AUDIO_EXTERN_1: - /* IN1 is often used for external input ... */ - state->mode = MSP_MODE_EXTERN; - scart = SCART_IN1; - break; - case AUDIO_EXTERN_2: - /* ... sometimes it is IN2 through ;) */ - state->mode = MSP_MODE_EXTERN; - scart = SCART_IN2; - break; - case AUDIO_TUNER: - state->mode = -1; - break; - default: - if (*sarg & AUDIO_MUTE) - msp_set_scart(client, SCART_MUTE, 0); - break; - } - if (scart) { - state->rxsubchans = V4L2_TUNER_SUB_STEREO; - state->audmode = V4L2_TUNER_MODE_STEREO; - msp_set_scart(client, scart, 0); - msp_write_dsp(client, 0x000d, 0x1900); - if (state->opmode != OPMODE_AUTOSELECT) - msp3400c_setstereo(client, state->audmode); - } - msp_wake_thread(client); - break; - - case AUDC_SET_RADIO: - if (state->radio) - return 0; - state->radio = 1; - v4l_dbg(1, client, "switching to radio mode\n"); - state->watch_stereo = 0; - switch (state->opmode) { - case OPMODE_MANUAL: - /* set msp3400 to FM radio mode */ - msp3400c_setmode(client, MSP_MODE_FM_RADIO); - msp3400c_setcarrier(client, MSP_CARRIER(10.7), - MSP_CARRIER(10.7)); - msp_set_audio(client); - break; - case OPMODE_AUTODETECT: - case OPMODE_AUTOSELECT: - /* the thread will do for us */ - msp_wake_thread(client); - break; - } - break; - - /* --- v4l ioctls --- */ - /* take care: bttv does userspace copying, we'll get a - kernel pointer here... */ - case VIDIOCGAUDIO: - { - struct video_audio *va = arg; - - va->flags |= VIDEO_AUDIO_VOLUME | VIDEO_AUDIO_MUTABLE; - if (state->has_sound_processing) - va->flags |= VIDEO_AUDIO_BALANCE | - VIDEO_AUDIO_BASS | - VIDEO_AUDIO_TREBLE; - if (state->muted) - va->flags |= VIDEO_AUDIO_MUTE; - va->volume = state->volume; - va->balance = state->volume ? state->balance : 32768; - va->bass = state->bass; - va->treble = state->treble; - - if (state->radio) - break; - if (state->opmode == OPMODE_AUTOSELECT) - msp_any_detect_stereo(client); - va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans); - break; - } - - case VIDIOCSAUDIO: - { - struct video_audio *va = arg; - - state->muted = (va->flags & VIDEO_AUDIO_MUTE); - state->volume = va->volume; - state->balance = va->balance; - state->bass = va->bass; - state->treble = va->treble; - msp_set_audio(client); - - if (va->mode != 0 && state->radio == 0) - msp_any_set_audmode(client, msp_mode_v4l1_to_v4l2(va->mode)); - break; - } - - case VIDIOCSCHAN: - { - struct video_channel *vc = arg; - int update = 0; - v4l2_std_id std; - - if (state->radio) - update = 1; - state->radio = 0; - if (vc->norm == VIDEO_MODE_PAL) - std = V4L2_STD_PAL; - else if (vc->norm == VIDEO_MODE_SECAM) - std = V4L2_STD_SECAM; - else - std = V4L2_STD_NTSC; - if (std != state->v4l2_std) { - state->v4l2_std = std; - update = 1; - } - if (update) - msp_wake_thread(client); - break; - } - - case VIDIOCSFREQ: - case VIDIOC_S_FREQUENCY: - { - /* new channel -- kick audio carrier scan */ - msp_wake_thread(client); - break; - } - - /* msp34xx specific */ - case MSP_SET_MATRIX: - { - struct msp_matrix *mspm = arg; - - msp_set_scart(client, mspm->input, mspm->output); - break; - } - - /* --- v4l2 ioctls --- */ - case VIDIOC_S_STD: - { - v4l2_std_id *id = arg; - int update = state->radio || state->v4l2_std != *id; - - state->v4l2_std = *id; - state->radio = 0; - if (update) - msp_wake_thread(client); - return 0; - } - - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *i = arg; - - if (i->index != 0) - return -EINVAL; - - i->type = V4L2_INPUT_TYPE_TUNER; - switch (i->index) { - case AUDIO_RADIO: - strcpy(i->name, "Radio"); - break; - case AUDIO_EXTERN_1: - strcpy(i->name, "Extern 1"); - break; - case AUDIO_EXTERN_2: - strcpy(i->name, "Extern 2"); - break; - case AUDIO_TUNER: - strcpy(i->name, "Television"); - break; - default: - return -EINVAL; - } - return 0; - } - - case VIDIOC_G_AUDIO: - { - struct v4l2_audio *a = arg; - - memset(a, 0, sizeof(*a)); - - switch (a->index) { - case AUDIO_RADIO: - strcpy(a->name, "Radio"); - break; - case AUDIO_EXTERN_1: - strcpy(a->name, "Extern 1"); - break; - case AUDIO_EXTERN_2: - strcpy(a->name, "Extern 2"); - break; - case AUDIO_TUNER: - strcpy(a->name, "Television"); - break; - default: - return -EINVAL; - } - - msp_any_detect_stereo(client); - if (state->audmode == V4L2_TUNER_MODE_STEREO) { - a->capability = V4L2_AUDCAP_STEREO; - } - - break; - } - - case VIDIOC_S_AUDIO: - { - struct v4l2_audio *sarg = arg; - - switch (sarg->index) { - case AUDIO_RADIO: - /* Hauppauge uses IN2 for the radio */ - state->mode = MSP_MODE_FM_RADIO; - scart = SCART_IN2; - break; - case AUDIO_EXTERN_1: - /* IN1 is often used for external input ... */ - state->mode = MSP_MODE_EXTERN; - scart = SCART_IN1; - break; - case AUDIO_EXTERN_2: - /* ... sometimes it is IN2 through ;) */ - state->mode = MSP_MODE_EXTERN; - scart = SCART_IN2; - break; - case AUDIO_TUNER: - state->mode = -1; - break; - } - if (scart) { - state->rxsubchans = V4L2_TUNER_SUB_STEREO; - state->audmode = V4L2_TUNER_MODE_STEREO; - msp_set_scart(client, scart, 0); - msp_write_dsp(client, 0x000d, 0x1900); - } - if (sarg->capability == V4L2_AUDCAP_STEREO) { - state->audmode = V4L2_TUNER_MODE_STEREO; - } else { - state->audmode &= ~V4L2_TUNER_MODE_STEREO; - } - msp_any_set_audmode(client, state->audmode); - msp_wake_thread(client); - break; - } - - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *vt = arg; - - if (state->radio) - break; - if (state->opmode == OPMODE_AUTOSELECT) - msp_any_detect_stereo(client); - vt->audmode = state->audmode; - vt->rxsubchans = state->rxsubchans; - vt->capability = V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; - break; - } - - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; - - if (state->radio) - break; - /* only set audmode */ - if (vt->audmode != -1 && vt->audmode != 0) - msp_any_set_audmode(client, vt->audmode); - break; - } - - case VIDIOC_G_AUDOUT: - { - struct v4l2_audioout *a = (struct v4l2_audioout *)arg; - int idx = a->index; - - memset(a, 0, sizeof(*a)); - - switch (idx) { - case 0: - strcpy(a->name, "Scart1 Out"); - break; - case 1: - strcpy(a->name, "Scart2 Out"); - break; - case 2: - strcpy(a->name, "I2S Out"); - break; - default: - return -EINVAL; - } - break; - - } - - case VIDIOC_S_AUDOUT: - { - struct v4l2_audioout *a = (struct v4l2_audioout *)arg; - - if (a->index < 0 || a->index > 2) - return -EINVAL; - - v4l_dbg(1, client, "Setting audio out on msp34xx to input %i\n", a->index); - msp_set_scart(client, state->in_scart, a->index + 1); - - break; - } - - case VIDIOC_INT_I2S_CLOCK_FREQ: - { - u32 *a = (u32 *)arg; - - v4l_dbg(1, client, "Setting I2S speed to %d\n", *a); - - switch (*a) { - case 1024000: - state->i2s_mode = 0; - break; - case 2048000: - state->i2s_mode = 1; - break; - default: - return -EINVAL; - } - break; - } - - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *qc = arg; - int i; - - for (i = 0; i < ARRAY_SIZE(msp_qctrl_std); i++) - if (qc->id && qc->id == msp_qctrl_std[i].id) { - memcpy(qc, &msp_qctrl_std[i], sizeof(*qc)); - return 0; - } - if (!state->has_sound_processing) - return -EINVAL; - for (i = 0; i < ARRAY_SIZE(msp_qctrl_sound_processing); i++) - if (qc->id && qc->id == msp_qctrl_sound_processing[i].id) { - memcpy(qc, &msp_qctrl_sound_processing[i], sizeof(*qc)); - return 0; - } - return -EINVAL; - } - - case VIDIOC_G_CTRL: - return msp_get_ctrl(client, arg); - - case VIDIOC_S_CTRL: - return msp_set_ctrl(client, arg); - - case VIDIOC_LOG_STATUS: - { - const char *p; - - if (state->opmode == OPMODE_AUTOSELECT) - msp_any_detect_stereo(client); - v4l_info(client, "%s rev1 = 0x%04x rev2 = 0x%04x\n", - client->name, state->rev1, state->rev2); - v4l_info(client, "Audio: volume %d%s\n", - state->volume, state->muted ? " (muted)" : ""); - if (state->has_sound_processing) { - v4l_info(client, "Audio: balance %d bass %d treble %d loudness %s\n", - state->balance, state->bass, state->treble, - state->loudness ? "on" : "off"); - } - switch (state->mode) { - case MSP_MODE_AM_DETECT: p = "AM (for carrier detect)"; break; - case MSP_MODE_FM_RADIO: p = "FM Radio"; break; - case MSP_MODE_FM_TERRA: p = "Terrestial FM-mono + FM-stereo"; break; - case MSP_MODE_FM_SAT: p = "Satellite FM-mono"; break; - case MSP_MODE_FM_NICAM1: p = "NICAM/FM (B/G, D/K)"; break; - case MSP_MODE_FM_NICAM2: p = "NICAM/FM (I)"; break; - case MSP_MODE_AM_NICAM: p = "NICAM/AM (L)"; break; - case MSP_MODE_BTSC: p = "BTSC"; break; - case MSP_MODE_EXTERN: p = "External input"; break; - default: p = "unknown"; break; - } - if (state->opmode == OPMODE_MANUAL) { - v4l_info(client, "Mode: %s (%s%s)\n", p, - (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", - (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); - } else { - v4l_info(client, "Mode: %s\n", p); - v4l_info(client, "Standard: %s (%s%s)\n", - msp_standard_std_name(state->std), - (state->rxsubchans & V4L2_TUNER_SUB_STEREO) ? "stereo" : "mono", - (state->rxsubchans & V4L2_TUNER_SUB_LANG2) ? ", dual" : ""); - } - v4l_info(client, "ACB: 0x%04x\n", state->acb); - break; - } - - default: - /* nothing */ - break; - } - return 0; -} - -static int msp_suspend(struct device * dev, pm_message_t state) -{ - struct i2c_client *client = container_of(dev, struct i2c_client, dev); - - v4l_dbg(1, client, "suspend\n"); - msp_reset(client); - return 0; -} - -static int msp_resume(struct device * dev) -{ - struct i2c_client *client = container_of(dev, struct i2c_client, dev); - - v4l_dbg(1, client, "resume\n"); - msp_wake_thread(client); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static struct i2c_driver i2c_driver; - -static int msp_attach(struct i2c_adapter *adapter, int address, int kind) -{ - struct i2c_client *client; - struct msp_state *state; - int (*thread_func)(void *data) = NULL; - int msp_hard; - int msp_family; - int msp_revision; - int msp_product, msp_prod_hi, msp_prod_lo; - int msp_rom; - - client = kmalloc(sizeof(*client), GFP_KERNEL); - if (client == NULL) - return -ENOMEM; - memset(client, 0, sizeof(*client)); - client->addr = address; - client->adapter = adapter; - client->driver = &i2c_driver; - snprintf(client->name, sizeof(client->name) - 1, "msp3400"); - - if (msp_reset(client) == -1) { - v4l_dbg(1, client, "msp3400 not found\n"); - kfree(client); - return -1; - } - - state = kmalloc(sizeof(*state), GFP_KERNEL); - if (state == NULL) { - kfree(client); - return -ENOMEM; - } - i2c_set_clientdata(client, state); - - memset(state, 0, sizeof(*state)); - state->v4l2_std = V4L2_STD_NTSC; - state->volume = 58880; /* 0db gain */ - state->balance = 32768; /* 0db gain */ - state->bass = 32768; - state->treble = 32768; - state->loudness = 0; - state->input = -1; - state->muted = 0; - state->i2s_mode = 0; - init_waitqueue_head(&state->wq); - - state->rev1 = msp_read_dsp(client, 0x1e); - if (state->rev1 != -1) - state->rev2 = msp_read_dsp(client, 0x1f); - v4l_dbg(1, client, "rev1=0x%04x, rev2=0x%04x\n", state->rev1, state->rev2); - if (state->rev1 == -1 || (state->rev1 == 0 && state->rev2 == 0)) { - v4l_dbg(1, client, "not an msp3400 (cannot read chip version)\n"); - kfree(state); - kfree(client); - return -1; - } - - msp_set_audio(client); - - msp_family = ((state->rev1 >> 4) & 0x0f) + 3; - msp_product = (state->rev2 >> 8) & 0xff; - msp_prod_hi = msp_product / 10; - msp_prod_lo = msp_product % 10; - msp_revision = (state->rev1 & 0x0f) + '@'; - msp_hard = ((state->rev1 >> 8) & 0xff) + '@'; - msp_rom = state->rev2 & 0x1f; - snprintf(client->name, sizeof(client->name), "MSP%d4%02d%c-%c%d", - msp_family, msp_product, - msp_revision, msp_hard, msp_rom); - - /* Has NICAM support: all mspx41x and mspx45x products have NICAM */ - state->has_nicam = msp_prod_hi == 1 || msp_prod_hi == 5; - /* Has radio support: was added with revision G */ - state->has_radio = msp_revision >= 'G'; - /* Has headphones output: not for stripped down products */ - state->has_headphones = msp_prod_lo < 5; - /* Has scart4 input: not in pre D revisions, not in stripped D revs */ - state->has_scart4 = msp_family >= 4 || (msp_revision >= 'D' && msp_prod_lo < 5); - /* Has scart2 and scart3 inputs and scart2 output: not in stripped - down products of the '3' family */ - state->has_scart23_in_scart2_out = msp_family >= 4 || msp_prod_lo < 5; - /* Has scart2 a volume control? Not in pre-D revisions. */ - state->has_scart2_out_volume = msp_revision > 'C' && state->has_scart23_in_scart2_out; - /* Has a configurable i2s out? */ - state->has_i2s_conf = msp_revision >= 'G' && msp_prod_lo < 7; - /* Has subwoofer output: not in pre-D revs and not in stripped down products */ - state->has_subwoofer = msp_revision >= 'D' && msp_prod_lo < 5; - /* Has soundprocessing (bass/treble/balance/loudness/equalizer): not in - stripped down products */ - state->has_sound_processing = msp_prod_lo < 7; - /* Has Virtual Dolby Surround: only in msp34x1 */ - state->has_virtual_dolby_surround = msp_revision == 'G' && msp_prod_lo == 1; - /* Has Virtual Dolby Surround & Dolby Pro Logic: only in msp34x2 */ - state->has_dolby_pro_logic = msp_revision == 'G' && msp_prod_lo == 2; - - state->opmode = opmode; - if (state->opmode == OPMODE_AUTO) { - /* MSP revision G and up have both autodetect and autoselect */ - if (msp_revision >= 'G') - state->opmode = OPMODE_AUTOSELECT; - /* MSP revision D and up have autodetect */ - else if (msp_revision >= 'D') - state->opmode = OPMODE_AUTODETECT; - else - state->opmode = OPMODE_MANUAL; - } - - /* hello world :-) */ - v4l_info(client, "%s found @ 0x%x (%s)\n", client->name, address << 1, adapter->name); - v4l_info(client, "%s ", client->name); - if (state->has_nicam && state->has_radio) - printk("supports nicam and radio, "); - else if (state->has_nicam) - printk("supports nicam, "); - else if (state->has_radio) - printk("supports radio, "); - printk("mode is "); - - /* version-specific initialization */ - switch (state->opmode) { - case OPMODE_MANUAL: - printk("manual"); - thread_func = msp3400c_thread; - break; - case OPMODE_AUTODETECT: - printk("autodetect"); - thread_func = msp3410d_thread; - break; - case OPMODE_AUTOSELECT: - printk("autodetect and autoselect"); - thread_func = msp34xxg_thread; - break; - } - printk("\n"); - - /* startup control thread if needed */ - if (thread_func) { - state->kthread = kthread_run(thread_func, client, "msp34xx"); - - if (state->kthread == NULL) - v4l_warn(client, "kernel_thread() failed\n"); - msp_wake_thread(client); - } - - /* done */ - i2c_attach_client(client); - - return 0; -} - -static int msp_probe(struct i2c_adapter *adapter) -{ - if (adapter->class & I2C_CLASS_TV_ANALOG) - return i2c_probe(adapter, &addr_data, msp_attach); - return 0; -} - -static int msp_detach(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - int err; - - /* shutdown control thread */ - if (state->kthread) { - state->restart = 1; - kthread_stop(state->kthread); - } - msp_reset(client); - - err = i2c_detach_client(client); - if (err) { - return err; - } - - kfree(state); - kfree(client); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -/* i2c implementation */ -static struct i2c_driver i2c_driver = { - .id = I2C_DRIVERID_MSP3400, - .attach_adapter = msp_probe, - .detach_client = msp_detach, - .command = msp_command, - .driver = { - .name = "msp3400", - .suspend = msp_suspend, - .resume = msp_resume, - }, -}; - -static int __init msp3400_init_module(void) -{ - return i2c_add_driver(&i2c_driver); -} - -static void __exit msp3400_cleanup_module(void) -{ - i2c_del_driver(&i2c_driver); -} - -module_init(msp3400_init_module); -module_exit(msp3400_cleanup_module); - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * --------------------------------------------------------------------------- - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/trunk/drivers/media/video/msp3400-kthreads.c b/trunk/drivers/media/video/msp3400-kthreads.c deleted file mode 100644 index 2b59b6847535..000000000000 --- a/trunk/drivers/media/video/msp3400-kthreads.c +++ /dev/null @@ -1,1010 +0,0 @@ -/* - * Programming the mspx4xx sound processor family - * - * (c) 1997-2001 Gerd Knorr - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "msp3400.h" - -/* this one uses the automatic sound standard detection of newer msp34xx - chip versions */ -static struct { - int retval; - int main, second; - char *name; -} msp_stdlist[] = { - { 0x0000, 0, 0, "could not detect sound standard" }, - { 0x0001, 0, 0, "autodetect start" }, - { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72 M Dual FM-Stereo" }, - { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74 B/G Dual FM-Stereo" }, - { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" }, - { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" }, - { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" }, - { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" }, - { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" }, - { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" }, - { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" }, - { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" }, - { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" }, - { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" }, - { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" }, - { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7 FM-Stereo Radio" }, - { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 SAT-Mono" }, - { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20 SAT-Stereo" }, - { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2 SAT ADR" }, - { -1, 0, 0, NULL }, /* EOF */ -}; - -static struct msp3400c_init_data_dem { - int fir1[6]; - int fir2[6]; - int cdo1; - int cdo2; - int ad_cv; - int mode_reg; - int dsp_src; - int dsp_matrix; -} msp3400c_init_data[] = { - { /* AM (for carrier detect / msp3400) */ - {75, 19, 36, 35, 39, 40}, - {75, 19, 36, 35, 39, 40}, - MSP_CARRIER(5.5), MSP_CARRIER(5.5), - 0x00d0, 0x0500, 0x0020, 0x3000 - },{ /* AM (for carrier detect / msp3410) */ - {-1, -1, -8, 2, 59, 126}, - {-1, -1, -8, 2, 59, 126}, - MSP_CARRIER(5.5), MSP_CARRIER(5.5), - 0x00d0, 0x0100, 0x0020, 0x3000 - },{ /* FM Radio */ - {-8, -8, 4, 6, 78, 107}, - {-8, -8, 4, 6, 78, 107}, - MSP_CARRIER(10.7), MSP_CARRIER(10.7), - 0x00d0, 0x0480, 0x0020, 0x3000 - },{ /* Terrestial FM-mono + FM-stereo */ - {3, 18, 27, 48, 66, 72}, - {3, 18, 27, 48, 66, 72}, - MSP_CARRIER(5.5), MSP_CARRIER(5.5), - 0x00d0, 0x0480, 0x0030, 0x3000 - },{ /* Sat FM-mono */ - { 1, 9, 14, 24, 33, 37}, - { 3, 18, 27, 48, 66, 72}, - MSP_CARRIER(6.5), MSP_CARRIER(6.5), - 0x00c6, 0x0480, 0x0000, 0x3000 - },{ /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */ - {-2, -8, -10, 10, 50, 86}, - {3, 18, 27, 48, 66, 72}, - MSP_CARRIER(5.5), MSP_CARRIER(5.5), - 0x00d0, 0x0040, 0x0120, 0x3000 - },{ /* NICAM/FM -- I (6.0/6.552) */ - {2, 4, -6, -4, 40, 94}, - {3, 18, 27, 48, 66, 72}, - MSP_CARRIER(6.0), MSP_CARRIER(6.0), - 0x00d0, 0x0040, 0x0120, 0x3000 - },{ /* NICAM/AM -- L (6.5/5.85) */ - {-2, -8, -10, 10, 50, 86}, - {-4, -12, -9, 23, 79, 126}, - MSP_CARRIER(6.5), MSP_CARRIER(6.5), - 0x00c6, 0x0140, 0x0120, 0x7c03 - }, -}; - -struct msp3400c_carrier_detect { - int cdo; - char *name; -}; - -static struct msp3400c_carrier_detect msp3400c_carrier_detect_main[] = { - /* main carrier */ - { MSP_CARRIER(4.5), "4.5 NTSC" }, - { MSP_CARRIER(5.5), "5.5 PAL B/G" }, - { MSP_CARRIER(6.0), "6.0 PAL I" }, - { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" } -}; - -static struct msp3400c_carrier_detect msp3400c_carrier_detect_55[] = { - /* PAL B/G */ - { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" }, - { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" } -}; - -static struct msp3400c_carrier_detect msp3400c_carrier_detect_65[] = { - /* PAL SAT / SECAM */ - { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" }, - { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" }, - { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" }, - { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" }, - { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" }, - { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" }, -}; - -/* ------------------------------------------------------------------------ */ - -const char *msp_standard_std_name(int std) -{ - int i; - - for (i = 0; msp_stdlist[i].name != NULL; i++) - if (msp_stdlist[i].retval == std) - return msp_stdlist[i].name; - return "unknown"; -} - -void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2) -{ - msp_write_dem(client, 0x0093, cdo1 & 0xfff); - msp_write_dem(client, 0x009b, cdo1 >> 12); - msp_write_dem(client, 0x00a3, cdo2 & 0xfff); - msp_write_dem(client, 0x00ab, cdo2 >> 12); - msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/ -} - -void msp3400c_setmode(struct i2c_client *client, int type) -{ - struct msp_state *state = i2c_get_clientdata(client); - int i; - - v4l_dbg(1, client, "setmode: %d\n", type); - state->mode = type; - state->audmode = V4L2_TUNER_MODE_MONO; - state->rxsubchans = V4L2_TUNER_SUB_MONO; - - msp_write_dem(client, 0x00bb, msp3400c_init_data[type].ad_cv); - - for (i = 5; i >= 0; i--) /* fir 1 */ - msp_write_dem(client, 0x0001, msp3400c_init_data[type].fir1[i]); - - msp_write_dem(client, 0x0005, 0x0004); /* fir 2 */ - msp_write_dem(client, 0x0005, 0x0040); - msp_write_dem(client, 0x0005, 0x0000); - for (i = 5; i >= 0; i--) - msp_write_dem(client, 0x0005, msp3400c_init_data[type].fir2[i]); - - msp_write_dem(client, 0x0083, msp3400c_init_data[type].mode_reg); - - msp3400c_setcarrier(client, msp3400c_init_data[type].cdo1, - msp3400c_init_data[type].cdo2); - - msp_write_dem(client, 0x0056, 0); /*LOAD_REG_1/2*/ - - if (dolby) { - msp_write_dsp(client, 0x0008, 0x0520); /* I2S1 */ - msp_write_dsp(client, 0x0009, 0x0620); /* I2S2 */ - msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src); - } else { - msp_write_dsp(client, 0x0008, msp3400c_init_data[type].dsp_src); - msp_write_dsp(client, 0x0009, msp3400c_init_data[type].dsp_src); - msp_write_dsp(client, 0x000b, msp3400c_init_data[type].dsp_src); - } - msp_write_dsp(client, 0x000a, msp3400c_init_data[type].dsp_src); - msp_write_dsp(client, 0x000e, msp3400c_init_data[type].dsp_matrix); - - if (state->has_nicam) { - /* nicam prescale */ - msp_write_dsp(client, 0x0010, 0x5a00); /* was: 0x3000 */ - } -} - -/* turn on/off nicam + stereo */ -void msp3400c_setstereo(struct i2c_client *client, int mode) -{ - static char *strmode[] = { "mono", "stereo", "lang2", "lang1" }; - struct msp_state *state = i2c_get_clientdata(client); - int nicam = 0; /* channel source: FM/AM or nicam */ - int src = 0; - - if (state->opmode == OPMODE_AUTOSELECT) { - /* this method would break everything, let's make sure - * it's never called - */ - v4l_dbg(1, client, "setstereo called with mode=%d instead of set_source (ignored)\n", - mode); - return; - } - - /* switch demodulator */ - switch (state->mode) { - case MSP_MODE_FM_TERRA: - v4l_dbg(1, client, "FM setstereo: %s\n", strmode[mode]); - msp3400c_setcarrier(client, state->second, state->main); - switch (mode) { - case V4L2_TUNER_MODE_STEREO: - msp_write_dsp(client, 0x000e, 0x3001); - break; - case V4L2_TUNER_MODE_MONO: - case V4L2_TUNER_MODE_LANG1: - case V4L2_TUNER_MODE_LANG2: - msp_write_dsp(client, 0x000e, 0x3000); - break; - } - break; - case MSP_MODE_FM_SAT: - v4l_dbg(1, client, "SAT setstereo: %s\n", strmode[mode]); - switch (mode) { - case V4L2_TUNER_MODE_MONO: - msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); - break; - case V4L2_TUNER_MODE_STEREO: - msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02)); - break; - case V4L2_TUNER_MODE_LANG1: - msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); - break; - case V4L2_TUNER_MODE_LANG2: - msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); - break; - } - break; - case MSP_MODE_FM_NICAM1: - case MSP_MODE_FM_NICAM2: - case MSP_MODE_AM_NICAM: - v4l_dbg(1, client, "NICAM setstereo: %s\n",strmode[mode]); - msp3400c_setcarrier(client,state->second,state->main); - if (state->nicam_on) - nicam=0x0100; - break; - case MSP_MODE_BTSC: - v4l_dbg(1, client, "BTSC setstereo: %s\n",strmode[mode]); - nicam=0x0300; - break; - case MSP_MODE_EXTERN: - v4l_dbg(1, client, "extern setstereo: %s\n",strmode[mode]); - nicam = 0x0200; - break; - case MSP_MODE_FM_RADIO: - v4l_dbg(1, client, "FM-Radio setstereo: %s\n",strmode[mode]); - break; - default: - v4l_dbg(1, client, "mono setstereo\n"); - return; - } - - /* switch audio */ - switch (mode) { - case V4L2_TUNER_MODE_STEREO: - src = 0x0020 | nicam; - break; - case V4L2_TUNER_MODE_MONO: - if (state->mode == MSP_MODE_AM_NICAM) { - v4l_dbg(1, client, "switching to AM mono\n"); - /* AM mono decoding is handled by tuner, not MSP chip */ - /* SCART switching control register */ - msp_set_scart(client, SCART_MONO, 0); - src = 0x0200; - break; - } - case V4L2_TUNER_MODE_LANG1: - src = 0x0000 | nicam; - break; - case V4L2_TUNER_MODE_LANG2: - src = 0x0010 | nicam; - break; - } - v4l_dbg(1, client, "setstereo final source/matrix = 0x%x\n", src); - - if (dolby) { - msp_write_dsp(client, 0x0008, 0x0520); - msp_write_dsp(client, 0x0009, 0x0620); - msp_write_dsp(client, 0x000a, src); - msp_write_dsp(client, 0x000b, src); - } else { - msp_write_dsp(client, 0x0008, src); - msp_write_dsp(client, 0x0009, src); - msp_write_dsp(client, 0x000a, src); - msp_write_dsp(client, 0x000b, src); - msp_write_dsp(client, 0x000c, src); - if (state->has_scart23_in_scart2_out) - msp_write_dsp(client, 0x0041, src); - } -} - -static void msp3400c_print_mode(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - - if (state->main == state->second) { - v4l_dbg(1, client, "mono sound carrier: %d.%03d MHz\n", - state->main / 910000, (state->main / 910) % 1000); - } else { - v4l_dbg(1, client, "main sound carrier: %d.%03d MHz\n", - state->main / 910000, (state->main / 910) % 1000); - } - if (state->mode == MSP_MODE_FM_NICAM1 || state->mode == MSP_MODE_FM_NICAM2) - v4l_dbg(1, client, "NICAM/FM carrier : %d.%03d MHz\n", - state->second / 910000, (state->second/910) % 1000); - if (state->mode == MSP_MODE_AM_NICAM) - v4l_dbg(1, client, "NICAM/AM carrier : %d.%03d MHz\n", - state->second / 910000, (state->second / 910) % 1000); - if (state->mode == MSP_MODE_FM_TERRA && state->main != state->second) { - v4l_dbg(1, client, "FM-stereo carrier : %d.%03d MHz\n", - state->second / 910000, (state->second / 910) % 1000); - } -} - -/* ----------------------------------------------------------------------- */ - -int autodetect_stereo(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - int val; - int rxsubchans = state->rxsubchans; - int newnicam = state->nicam_on; - int update = 0; - - switch (state->mode) { - case MSP_MODE_FM_TERRA: - val = msp_read_dsp(client, 0x18); - if (val > 32767) - val -= 65536; - v4l_dbg(2, client, "stereo detect register: %d\n", val); - if (val > 4096) { - rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; - } else if (val < -4096) { - rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; - } else { - rxsubchans = V4L2_TUNER_SUB_MONO; - } - newnicam = 0; - break; - case MSP_MODE_FM_NICAM1: - case MSP_MODE_FM_NICAM2: - case MSP_MODE_AM_NICAM: - val = msp_read_dem(client, 0x23); - v4l_dbg(2, client, "nicam sync=%d, mode=%d\n", - val & 1, (val & 0x1e) >> 1); - - if (val & 1) { - /* nicam synced */ - switch ((val & 0x1e) >> 1) { - case 0: - case 8: - rxsubchans = V4L2_TUNER_SUB_STEREO; - break; - case 1: - case 9: - rxsubchans = V4L2_TUNER_SUB_MONO - | V4L2_TUNER_SUB_LANG1; - break; - case 2: - case 10: - rxsubchans = V4L2_TUNER_SUB_MONO - | V4L2_TUNER_SUB_LANG1 - | V4L2_TUNER_SUB_LANG2; - break; - default: - rxsubchans = V4L2_TUNER_SUB_MONO; - break; - } - newnicam = 1; - } else { - newnicam = 0; - rxsubchans = V4L2_TUNER_SUB_MONO; - } - break; - case MSP_MODE_BTSC: - val = msp_read_dem(client, 0x200); - v4l_dbg(2, client, "status=0x%x (pri=%s, sec=%s, %s%s%s)\n", - val, - (val & 0x0002) ? "no" : "yes", - (val & 0x0004) ? "no" : "yes", - (val & 0x0040) ? "stereo" : "mono", - (val & 0x0080) ? ", nicam 2nd mono" : "", - (val & 0x0100) ? ", bilingual/SAP" : ""); - rxsubchans = V4L2_TUNER_SUB_MONO; - if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO; - if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1; - break; - } - if (rxsubchans != state->rxsubchans) { - update = 1; - v4l_dbg(1, client, "watch: rxsubchans %d => %d\n", - state->rxsubchans,rxsubchans); - state->rxsubchans = rxsubchans; - } - if (newnicam != state->nicam_on) { - update = 1; - v4l_dbg(1, client, "watch: nicam %d => %d\n", - state->nicam_on,newnicam); - state->nicam_on = newnicam; - } - return update; -} - -/* - * A kernel thread for msp3400 control -- we don't want to block the - * in the ioctl while doing the sound carrier & stereo detect - */ -/* stereo/multilang monitoring */ -static void watch_stereo(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - - if (autodetect_stereo(client)) { - if (state->rxsubchans & V4L2_TUNER_SUB_STEREO) - msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO); - else if (state->rxsubchans & V4L2_TUNER_SUB_LANG1) - msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1); - else - msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); - } - - if (once) - state->watch_stereo = 0; -} - -int msp3400c_thread(void *data) -{ - struct i2c_client *client = data; - struct msp_state *state = i2c_get_clientdata(client); - struct msp3400c_carrier_detect *cd; - int count, max1,max2,val1,val2, val,this; - - - v4l_dbg(1, client, "msp3400 daemon started\n"); - for (;;) { - v4l_dbg(2, client, "msp3400 thread: sleep\n"); - msp_sleep(state, -1); - v4l_dbg(2, client, "msp3400 thread: wakeup\n"); - - restart: - v4l_dbg(1, client, "thread: restart scan\n"); - state->restart = 0; - if (kthread_should_stop()) - break; - - if (state->radio || MSP_MODE_EXTERN == state->mode) { - /* no carrier scan, just unmute */ - v4l_dbg(1, client, "thread: no carrier scan\n"); - msp_set_audio(client); - continue; - } - - /* mute */ - msp_set_mute(client); - msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ ); - val1 = val2 = 0; - max1 = max2 = -1; - state->watch_stereo = 0; - - /* some time for the tuner to sync */ - if (msp_sleep(state,200)) - goto restart; - - /* carrier detect pass #1 -- main carrier */ - cd = msp3400c_carrier_detect_main; - count = ARRAY_SIZE(msp3400c_carrier_detect_main); - - if (amsound && (state->v4l2_std & V4L2_STD_SECAM)) { - /* autodetect doesn't work well with AM ... */ - max1 = 3; - count = 0; - v4l_dbg(1, client, "AM sound override\n"); - } - - for (this = 0; this < count; this++) { - msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); - if (msp_sleep(state,100)) - goto restart; - val = msp_read_dsp(client, 0x1b); - if (val > 32767) - val -= 65536; - if (val1 < val) - val1 = val, max1 = this; - v4l_dbg(1, client, "carrier1 val: %5d / %s\n", val,cd[this].name); - } - - /* carrier detect pass #2 -- second (stereo) carrier */ - switch (max1) { - case 1: /* 5.5 */ - cd = msp3400c_carrier_detect_55; - count = ARRAY_SIZE(msp3400c_carrier_detect_55); - break; - case 3: /* 6.5 */ - cd = msp3400c_carrier_detect_65; - count = ARRAY_SIZE(msp3400c_carrier_detect_65); - break; - case 0: /* 4.5 */ - case 2: /* 6.0 */ - default: - cd = NULL; - count = 0; - break; - } - - if (amsound && (state->v4l2_std & V4L2_STD_SECAM)) { - /* autodetect doesn't work well with AM ... */ - cd = NULL; - count = 0; - max2 = 0; - } - for (this = 0; this < count; this++) { - msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); - if (msp_sleep(state,100)) - goto restart; - val = msp_read_dsp(client, 0x1b); - if (val > 32767) - val -= 65536; - if (val2 < val) - val2 = val, max2 = this; - v4l_dbg(1, client, "carrier2 val: %5d / %s\n", val,cd[this].name); - } - - /* program the msp3400 according to the results */ - state->main = msp3400c_carrier_detect_main[max1].cdo; - switch (max1) { - case 1: /* 5.5 */ - if (max2 == 0) { - /* B/G FM-stereo */ - state->second = msp3400c_carrier_detect_55[max2].cdo; - msp3400c_setmode(client, MSP_MODE_FM_TERRA); - state->nicam_on = 0; - msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); - state->watch_stereo = 1; - } else if (max2 == 1 && state->has_nicam) { - /* B/G NICAM */ - state->second = msp3400c_carrier_detect_55[max2].cdo; - msp3400c_setmode(client, MSP_MODE_FM_NICAM1); - state->nicam_on = 1; - msp3400c_setcarrier(client, state->second, state->main); - state->watch_stereo = 1; - } else { - goto no_second; - } - break; - case 2: /* 6.0 */ - /* PAL I NICAM */ - state->second = MSP_CARRIER(6.552); - msp3400c_setmode(client, MSP_MODE_FM_NICAM2); - state->nicam_on = 1; - msp3400c_setcarrier(client, state->second, state->main); - state->watch_stereo = 1; - break; - case 3: /* 6.5 */ - if (max2 == 1 || max2 == 2) { - /* D/K FM-stereo */ - state->second = msp3400c_carrier_detect_65[max2].cdo; - msp3400c_setmode(client, MSP_MODE_FM_TERRA); - state->nicam_on = 0; - msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); - state->watch_stereo = 1; - } else if (max2 == 0 && (state->v4l2_std & V4L2_STD_SECAM)) { - /* L NICAM or AM-mono */ - state->second = msp3400c_carrier_detect_65[max2].cdo; - msp3400c_setmode(client, MSP_MODE_AM_NICAM); - state->nicam_on = 0; - msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); - msp3400c_setcarrier(client, state->second, state->main); - /* volume prescale for SCART (AM mono input) */ - msp_write_dsp(client, 0x000d, 0x1900); - state->watch_stereo = 1; - } else if (max2 == 0 && state->has_nicam) { - /* D/K NICAM */ - state->second = msp3400c_carrier_detect_65[max2].cdo; - msp3400c_setmode(client, MSP_MODE_FM_NICAM1); - state->nicam_on = 1; - msp3400c_setcarrier(client, state->second, state->main); - state->watch_stereo = 1; - } else { - goto no_second; - } - break; - case 0: /* 4.5 */ - default: - no_second: - state->second = msp3400c_carrier_detect_main[max1].cdo; - msp3400c_setmode(client, MSP_MODE_FM_TERRA); - state->nicam_on = 0; - msp3400c_setcarrier(client, state->second, state->main); - state->rxsubchans = V4L2_TUNER_SUB_MONO; - msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); - break; - } - - /* unmute */ - msp_set_audio(client); - - if (debug) - msp3400c_print_mode(client); - - /* monitor tv audio mode */ - while (state->watch_stereo) { - if (msp_sleep(state,5000)) - goto restart; - watch_stereo(client); - } - } - v4l_dbg(1, client, "thread: exit\n"); - return 0; -} - - -int msp3410d_thread(void *data) -{ - struct i2c_client *client = data; - struct msp_state *state = i2c_get_clientdata(client); - int val, i, std; - - v4l_dbg(1, client, "msp3410 daemon started\n"); - - for (;;) { - v4l_dbg(2, client, "msp3410 thread: sleep\n"); - msp_sleep(state,-1); - v4l_dbg(2, client, "msp3410 thread: wakeup\n"); - - restart: - v4l_dbg(1, client, "thread: restart scan\n"); - state->restart = 0; - if (kthread_should_stop()) - break; - - if (state->mode == MSP_MODE_EXTERN) { - /* no carrier scan needed, just unmute */ - v4l_dbg(1, client, "thread: no carrier scan\n"); - msp_set_audio(client); - continue; - } - - /* put into sane state (and mute) */ - msp_reset(client); - - /* some time for the tuner to sync */ - if (msp_sleep(state,200)) - goto restart; - - /* start autodetect */ - if (state->radio) - std = 0x40; - else - std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1; - state->watch_stereo = 0; - - if (debug) - v4l_dbg(1, client, "setting standard: %s (0x%04x)\n", - msp_standard_std_name(std), std); - - if (std != 1) { - /* programmed some specific mode */ - val = std; - } else { - /* triggered autodetect */ - msp_write_dem(client, 0x20, std); - for (;;) { - if (msp_sleep(state, 100)) - goto restart; - - /* check results */ - val = msp_read_dem(client, 0x7e); - if (val < 0x07ff) - break; - v4l_dbg(1, client, "detection still in progress\n"); - } - } - for (i = 0; msp_stdlist[i].name != NULL; i++) - if (msp_stdlist[i].retval == val) - break; - v4l_dbg(1, client, "current standard: %s (0x%04x)\n", - msp_standard_std_name(val), val); - state->main = msp_stdlist[i].main; - state->second = msp_stdlist[i].second; - state->std = val; - - if (amsound && !state->radio && (state->v4l2_std & V4L2_STD_SECAM) && - (val != 0x0009)) { - /* autodetection has failed, let backup */ - v4l_dbg(1, client, "autodetection failed," - " switching to backup standard: %s (0x%04x)\n", - msp_stdlist[8].name ? msp_stdlist[8].name : "unknown",val); - val = 0x0009; - msp_write_dem(client, 0x20, val); - } - - /* set various prescales */ - msp_write_dsp(client, 0x0d, 0x1900); /* scart */ - msp_write_dsp(client, 0x0e, 0x2403); /* FM */ - msp_write_dsp(client, 0x10, 0x5a00); /* nicam */ - - /* set stereo */ - switch (val) { - case 0x0008: /* B/G NICAM */ - case 0x000a: /* I NICAM */ - if (val == 0x0008) - state->mode = MSP_MODE_FM_NICAM1; - else - state->mode = MSP_MODE_FM_NICAM2; - /* just turn on stereo */ - state->rxsubchans = V4L2_TUNER_SUB_STEREO; - state->nicam_on = 1; - state->watch_stereo = 1; - msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); - break; - case 0x0009: - state->mode = MSP_MODE_AM_NICAM; - state->rxsubchans = V4L2_TUNER_SUB_MONO; - state->nicam_on = 1; - msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO); - state->watch_stereo = 1; - break; - case 0x0020: /* BTSC */ - /* just turn on stereo */ - state->mode = MSP_MODE_BTSC; - state->rxsubchans = V4L2_TUNER_SUB_STEREO; - state->nicam_on = 0; - state->watch_stereo = 1; - msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); - break; - case 0x0040: /* FM radio */ - state->mode = MSP_MODE_FM_RADIO; - state->rxsubchans = V4L2_TUNER_SUB_STEREO; - state->audmode = V4L2_TUNER_MODE_STEREO; - state->nicam_on = 0; - state->watch_stereo = 0; - /* not needed in theory if we have radio, but - short programming enables carrier mute */ - msp3400c_setmode(client, MSP_MODE_FM_RADIO); - msp3400c_setcarrier(client, MSP_CARRIER(10.7), - MSP_CARRIER(10.7)); - /* scart routing */ - msp_set_scart(client,SCART_IN2,0); - /* msp34xx does radio decoding */ - msp_write_dsp(client, 0x08, 0x0020); - msp_write_dsp(client, 0x09, 0x0020); - msp_write_dsp(client, 0x0b, 0x0020); - break; - case 0x0003: - case 0x0004: - case 0x0005: - state->mode = MSP_MODE_FM_TERRA; - state->rxsubchans = V4L2_TUNER_SUB_MONO; - state->audmode = V4L2_TUNER_MODE_MONO; - state->nicam_on = 0; - state->watch_stereo = 1; - break; - } - - /* unmute, restore misc registers */ - msp_set_audio(client); - msp_write_dsp(client, 0x13, state->acb); - if (state->has_i2s_conf) - msp_write_dem(client, 0x40, state->i2s_mode); - - /* monitor tv audio mode */ - while (state->watch_stereo) { - if (msp_sleep(state,5000)) - goto restart; - watch_stereo(client); - } - } - v4l_dbg(1, client, "thread: exit\n"); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -/* msp34xxG + (autoselect no-thread) */ -/* this one uses both automatic standard detection and automatic sound */ -/* select which are available in the newer G versions */ -/* struct msp: only norm, acb and source are really used in this mode */ - -/* set the same 'source' for the loudspeaker, scart and quasi-peak detector - * the value for source is the same as bit 15:8 of DSP registers 0x08, - * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B - * - * this function replaces msp3400c_setstereo - */ -static void msp34xxg_set_source(struct i2c_client *client, int source) -{ - struct msp_state *state = i2c_get_clientdata(client); - - /* fix matrix mode to stereo and let the msp choose what - * to output according to 'source', as recommended - * for MONO (source==0) downmixing set bit[7:0] to 0x30 - */ - int value = (source & 0x07) << 8 | (source == 0 ? 0x30 : 0x20); - - v4l_dbg(1, client, "set source to %d (0x%x)\n", source, value); - /* Loudspeaker Output */ - msp_write_dsp(client, 0x08, value); - /* SCART1 DA Output */ - msp_write_dsp(client, 0x0a, value); - /* Quasi-peak detector */ - msp_write_dsp(client, 0x0c, value); - /* - * set identification threshold. Personally, I - * I set it to a higher value that the default - * of 0x190 to ignore noisy stereo signals. - * this needs tuning. (recommended range 0x00a0-0x03c0) - * 0x7f0 = forced mono mode - */ - /* a2 threshold for stereo/bilingual */ - msp_write_dem(client, 0x22, stereo_threshold); - state->source = source; -} - -/* (re-)initialize the msp34xxg, according to the current norm in state->norm - * return 0 if it worked, -1 if it failed - */ -static int msp34xxg_reset(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - int modus, std; - - if (msp_reset(client)) - return -1; - - /* make sure that input/output is muted (paranoid mode) */ - /* ACB, mute DSP input, mute SCART 1 */ - if (msp_write_dsp(client, 0x13, 0x0f20)) - return -1; - - if (state->has_i2s_conf) - msp_write_dem(client, 0x40, state->i2s_mode); - - /* step-by-step initialisation, as described in the manual */ - modus = msp_modus(client); - if (state->radio) - std = 0x40; - else - std = (state->v4l2_std & V4L2_STD_NTSC) ? 0x20 : 1; - modus &= ~0x03; /* STATUS_CHANGE = 0 */ - modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION = 1 */ - if (msp_write_dem(client, 0x30, modus)) - return -1; - if (msp_write_dem(client, 0x20, std)) - return -1; - - /* write the dsps that may have an influence on - standard/audio autodetection right now */ - msp34xxg_set_source(client, state->source); - - /* AM/FM Prescale [15:8] 75khz deviation */ - if (msp_write_dsp(client, 0x0e, 0x3000)) - return -1; - - /* NICAM Prescale 9db gain (as recommended) */ - if (msp_write_dsp(client, 0x10, 0x5a00)) - return -1; - - return 0; -} - -int msp34xxg_thread(void *data) -{ - struct i2c_client *client = data; - struct msp_state *state = i2c_get_clientdata(client); - int val, std, i; - - v4l_dbg(1, client, "msp34xxg daemon started\n"); - - state->source = 1; /* default */ - for (;;) { - v4l_dbg(2, client, "msp34xxg thread: sleep\n"); - msp_sleep(state, -1); - v4l_dbg(2, client, "msp34xxg thread: wakeup\n"); - - restart: - v4l_dbg(1, client, "thread: restart scan\n"); - state->restart = 0; - if (kthread_should_stop()) - break; - - /* setup the chip*/ - msp34xxg_reset(client); - std = standard; - if (std != 0x01) - goto unmute; - - /* watch autodetect */ - v4l_dbg(1, client, "triggered autodetect, waiting for result\n"); - for (i = 0; i < 10; i++) { - if (msp_sleep(state, 100)) - goto restart; - - /* check results */ - val = msp_read_dem(client, 0x7e); - if (val < 0x07ff) { - std = val; - break; - } - v4l_dbg(2, client, "detection still in progress\n"); - } - if (std == 1) { - v4l_dbg(1, client, "detection still in progress after 10 tries. giving up.\n"); - continue; - } - - unmute: - state->std = std; - v4l_dbg(1, client, "current standard: %s (0x%04x)\n", - msp_standard_std_name(std), std); - - /* unmute: dispatch sound to scart output, set scart volume */ - msp_set_audio(client); - - /* restore ACB */ - if (msp_write_dsp(client, 0x13, state->acb)) - return -1; - - msp_write_dem(client, 0x40, state->i2s_mode); - } - v4l_dbg(1, client, "thread: exit\n"); - return 0; -} - -void msp34xxg_detect_stereo(struct i2c_client *client) -{ - struct msp_state *state = i2c_get_clientdata(client); - - int status = msp_read_dem(client, 0x0200); - int is_bilingual = status & 0x100; - int is_stereo = status & 0x40; - - state->rxsubchans = 0; - if (is_stereo) - state->rxsubchans |= V4L2_TUNER_SUB_STEREO; - else - state->rxsubchans |= V4L2_TUNER_SUB_MONO; - if (is_bilingual) { - state->rxsubchans |= V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; - /* I'm supposed to check whether it's SAP or not - * and set only LANG2/SAP in this case. Yet, the MSP - * does a lot of work to hide this and handle everything - * the same way. I don't want to work around it so unless - * this is a problem, I'll handle SAP just like lang1/lang2. - */ - } - v4l_dbg(1, client, "status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", - status, is_stereo, is_bilingual, state->rxsubchans); -} - -void msp34xxg_set_audmode(struct i2c_client *client, int audmode) -{ - struct msp_state *state = i2c_get_clientdata(client); - int source; - - switch (audmode) { - case V4L2_TUNER_MODE_MONO: - source = 0; /* mono only */ - break; - case V4L2_TUNER_MODE_STEREO: - source = 1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */ - /* problem: that could also mean 2 (scart input) */ - break; - case V4L2_TUNER_MODE_LANG1: - source = 3; /* stereo or A */ - break; - case V4L2_TUNER_MODE_LANG2: - source = 4; /* stereo or B */ - break; - default: - audmode = 0; - source = 1; - break; - } - state->audmode = audmode; - msp34xxg_set_source(client, source); -} - diff --git a/trunk/drivers/media/video/msp3400.c b/trunk/drivers/media/video/msp3400.c new file mode 100644 index 000000000000..183253e2dd91 --- /dev/null +++ b/trunk/drivers/media/video/msp3400.c @@ -0,0 +1,2229 @@ +/* + * programming the msp34* sound processor family + * + * (c) 1997-2001 Gerd Knorr + * + * what works and what doesn't: + * + * AM-Mono + * Support for Hauppauge cards added (decoding handled by tuner) added by + * Frederic Crozat + * + * FM-Mono + * should work. The stereo modes are backward compatible to FM-mono, + * therefore FM-Mono should be allways available. + * + * FM-Stereo (B/G, used in germany) + * should work, with autodetect + * + * FM-Stereo (satellite) + * should work, no autodetect (i.e. default is mono, but you can + * switch to stereo -- untested) + * + * NICAM (B/G, L , used in UK, Scandinavia, Spain and France) + * should work, with autodetect. Support for NICAM was added by + * Pekka Pietikainen + * + * + * TODO: + * - better SAT support + * + * + * 980623 Thomas Sailer (sailer@ife.ee.ethz.ch) + * using soundcore instead of OSS + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "msp3400.h" + +#define msp3400_dbg(fmt, arg...) \ + do { \ + if (debug) \ + printk(KERN_INFO "%s debug %d-%04x: " fmt, \ + client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); \ + } while (0) + +/* Medium volume debug. */ +#define msp3400_dbg_mediumvol(fmt, arg...) \ + do { \ + if (debug >= 2) \ + printk(KERN_INFO "%s debug %d-%04x: " fmt, \ + client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); \ + } while (0) + +/* High volume debug. Use with care. */ +#define msp3400_dbg_highvol(fmt, arg...) \ + do { \ + if (debug >= 16) \ + printk(KERN_INFO "%s debug %d-%04x: " fmt, \ + client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); \ + } while (0) + +#define msp3400_err(fmt, arg...) do { \ + printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) +#define msp3400_warn(fmt, arg...) do { \ + printk(KERN_WARNING "%s %d-%04x: " fmt, client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) +#define msp3400_info(fmt, arg...) do { \ + printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) + +#define OPMODE_AUTO -1 +#define OPMODE_MANUAL 0 +#define OPMODE_SIMPLE 1 /* use short programming (>= msp3410 only) */ +#define OPMODE_SIMPLER 2 /* use shorter programming (>= msp34xxG) */ + +/* insmod parameters */ +static int opmode = OPMODE_AUTO; +static int debug = 0; /* debug output */ +static int once = 0; /* no continous stereo monitoring */ +static int amsound = 0; /* hard-wire AM sound at 6.5 Hz (france), + the autoscan seems work well only with FM... */ +static int standard = 1; /* Override auto detect of audio standard, if needed. */ +static int dolby = 0; + +static int stereo_threshold = 0x190; /* a2 threshold for stereo/bilingual + (msp34xxg only) 0x00a0-0x03c0 */ +#define DFP_COUNT 0x41 +static const int bl_dfp[] = { + 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a, + 0x0b, 0x0d, 0x0e, 0x10 +}; + +#define IS_MSP34XX_G(msp) ((msp)->opmode==2) + +struct msp3400c { + int rev1,rev2; + + int opmode; + int nicam; + int mode; + int norm; + int stereo; + int nicam_on; + int acb; + int in_scart; + int i2s_mode; + int main, second; /* sound carrier */ + int input; + int source; /* see msp34xxg_set_source */ + + /* v4l2 */ + int audmode; + int rxsubchans; + + int muted; + int left, right; /* volume */ + int bass, treble; + + /* shadow register set */ + int dfp_regs[DFP_COUNT]; + + /* thread */ + struct task_struct *kthread; + wait_queue_head_t wq; + int restart:1; + int watch_stereo:1; +}; + +#define MIN(a,b) (((a)>(b))?(b):(a)) +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define HAVE_NICAM(msp) (((msp->rev2>>8) & 0xff) != 00) +#define HAVE_SIMPLE(msp) ((msp->rev1 & 0xff) >= 'D'-'@') +#define HAVE_SIMPLER(msp) ((msp->rev1 & 0xff) >= 'G'-'@') +#define HAVE_RADIO(msp) ((msp->rev1 & 0xff) >= 'G'-'@') + +#define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */ + +/* ---------------------------------------------------------------------- */ + +/* read-only */ +module_param(opmode, int, 0444); + +/* read-write */ +module_param(once, int, 0644); +module_param(debug, int, 0644); +module_param(stereo_threshold, int, 0644); +module_param(standard, int, 0644); +module_param(amsound, int, 0644); +module_param(dolby, int, 0644); + +MODULE_PARM_DESC(opmode, "Forces a MSP3400 opmode. 0=Manual, 1=Simple, 2=Simpler"); +MODULE_PARM_DESC(once, "No continuous stereo monitoring"); +MODULE_PARM_DESC(debug, "Enable debug messages"); +MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo"); +MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect"); +MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan"); +MODULE_PARM_DESC(dolby, "Activates Dolby processsing"); + +/* ---------------------------------------------------------------------- */ + +#define I2C_MSP3400C 0x80 +#define I2C_MSP3400C_ALT 0x88 + +#define I2C_MSP3400C_DEM 0x10 +#define I2C_MSP3400C_DFP 0x12 + +/* Addresses to scan */ +static unsigned short normal_i2c[] = { + I2C_MSP3400C >> 1, + I2C_MSP3400C_ALT >> 1, + I2C_CLIENT_END +}; +I2C_CLIENT_INSMOD; + +MODULE_DESCRIPTION("device driver for msp34xx TV sound processor"); +MODULE_AUTHOR("Gerd Knorr"); +MODULE_LICENSE("GPL"); + +/* ----------------------------------------------------------------------- */ +/* functions for talking to the MSP3400C Sound processor */ + +static int msp3400c_reset(struct i2c_client *client) +{ + /* reset and read revision code */ + static char reset_off[3] = { 0x00, 0x80, 0x00 }; + static char reset_on[3] = { 0x00, 0x00, 0x00 }; + static char write[3] = { I2C_MSP3400C_DFP + 1, 0x00, 0x1e }; + char read[2]; + struct i2c_msg reset[2] = { + { client->addr, I2C_M_IGNORE_NAK, 3, reset_off }, + { client->addr, I2C_M_IGNORE_NAK, 3, reset_on }, + }; + struct i2c_msg test[2] = { + { client->addr, 0, 3, write }, + { client->addr, I2C_M_RD, 2, read }, + }; + + msp3400_dbg_highvol("msp3400c_reset\n"); + if ( (1 != i2c_transfer(client->adapter,&reset[0],1)) || + (1 != i2c_transfer(client->adapter,&reset[1],1)) || + (2 != i2c_transfer(client->adapter,test,2)) ) { + msp3400_err("chip reset failed\n"); + return -1; + } + return 0; +} + +static int msp3400c_read(struct i2c_client *client, int dev, int addr) +{ + int err,retval; + + unsigned char write[3]; + unsigned char read[2]; + struct i2c_msg msgs[2] = { + { client->addr, 0, 3, write }, + { client->addr, I2C_M_RD, 2, read } + }; + + write[0] = dev+1; + write[1] = addr >> 8; + write[2] = addr & 0xff; + + for (err = 0; err < 3;) { + if (2 == i2c_transfer(client->adapter,msgs,2)) + break; + err++; + msp3400_warn("I/O error #%d (read 0x%02x/0x%02x)\n", err, + dev, addr); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(msecs_to_jiffies(10)); + } + if (3 == err) { + msp3400_warn("giving up, resetting chip. Sound will go off, sorry folks :-|\n"); + msp3400c_reset(client); + return -1; + } + retval = read[0] << 8 | read[1]; + msp3400_dbg_highvol("msp3400c_read(0x%x, 0x%x): 0x%x\n", dev, addr, retval); + return retval; +} + +static int msp3400c_write(struct i2c_client *client, int dev, int addr, int val) +{ + int err; + unsigned char buffer[5]; + + buffer[0] = dev; + buffer[1] = addr >> 8; + buffer[2] = addr & 0xff; + buffer[3] = val >> 8; + buffer[4] = val & 0xff; + + msp3400_dbg_highvol("msp3400c_write(0x%x, 0x%x, 0x%x)\n", dev, addr, val); + for (err = 0; err < 3;) { + if (5 == i2c_master_send(client, buffer, 5)) + break; + err++; + msp3400_warn("I/O error #%d (write 0x%02x/0x%02x)\n", err, + dev, addr); + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(msecs_to_jiffies(10)); + } + if (3 == err) { + msp3400_warn("giving up, reseting chip. Sound will go off, sorry folks :-|\n"); + msp3400c_reset(client); + return -1; + } + return 0; +} + +/* ------------------------------------------------------------------------ */ + +/* This macro is allowed for *constants* only, gcc must calculate it + at compile time. Remember -- no floats in kernel mode */ +#define MSP_CARRIER(freq) ((int)((float)(freq/18.432)*(1<<24))) + +#define MSP_MODE_AM_DETECT 0 +#define MSP_MODE_FM_RADIO 2 +#define MSP_MODE_FM_TERRA 3 +#define MSP_MODE_FM_SAT 4 +#define MSP_MODE_FM_NICAM1 5 +#define MSP_MODE_FM_NICAM2 6 +#define MSP_MODE_AM_NICAM 7 +#define MSP_MODE_BTSC 8 +#define MSP_MODE_EXTERN 9 + +static struct MSP_INIT_DATA_DEM { + int fir1[6]; + int fir2[6]; + int cdo1; + int cdo2; + int ad_cv; + int mode_reg; + int dfp_src; + int dfp_matrix; +} msp_init_data[] = { + { /* AM (for carrier detect / msp3400) */ + {75, 19, 36, 35, 39, 40}, + {75, 19, 36, 35, 39, 40}, + MSP_CARRIER(5.5), MSP_CARRIER(5.5), + 0x00d0, 0x0500, 0x0020, 0x3000 + },{ /* AM (for carrier detect / msp3410) */ + {-1, -1, -8, 2, 59, 126}, + {-1, -1, -8, 2, 59, 126}, + MSP_CARRIER(5.5), MSP_CARRIER(5.5), + 0x00d0, 0x0100, 0x0020, 0x3000 + },{ /* FM Radio */ + {-8, -8, 4, 6, 78, 107}, + {-8, -8, 4, 6, 78, 107}, + MSP_CARRIER(10.7), MSP_CARRIER(10.7), + 0x00d0, 0x0480, 0x0020, 0x3000 + },{ /* Terrestial FM-mono + FM-stereo */ + {3, 18, 27, 48, 66, 72}, + {3, 18, 27, 48, 66, 72}, + MSP_CARRIER(5.5), MSP_CARRIER(5.5), + 0x00d0, 0x0480, 0x0030, 0x3000 + },{ /* Sat FM-mono */ + { 1, 9, 14, 24, 33, 37}, + { 3, 18, 27, 48, 66, 72}, + MSP_CARRIER(6.5), MSP_CARRIER(6.5), + 0x00c6, 0x0480, 0x0000, 0x3000 + },{ /* NICAM/FM -- B/G (5.5/5.85), D/K (6.5/5.85) */ + {-2, -8, -10, 10, 50, 86}, + {3, 18, 27, 48, 66, 72}, + MSP_CARRIER(5.5), MSP_CARRIER(5.5), + 0x00d0, 0x0040, 0x0120, 0x3000 + },{ /* NICAM/FM -- I (6.0/6.552) */ + {2, 4, -6, -4, 40, 94}, + {3, 18, 27, 48, 66, 72}, + MSP_CARRIER(6.0), MSP_CARRIER(6.0), + 0x00d0, 0x0040, 0x0120, 0x3000 + },{ /* NICAM/AM -- L (6.5/5.85) */ + {-2, -8, -10, 10, 50, 86}, + {-4, -12, -9, 23, 79, 126}, + MSP_CARRIER(6.5), MSP_CARRIER(6.5), + 0x00c6, 0x0140, 0x0120, 0x7c03 + }, +}; + +struct CARRIER_DETECT { + int cdo; + char *name; +}; + +static struct CARRIER_DETECT carrier_detect_main[] = { + /* main carrier */ + { MSP_CARRIER(4.5), "4.5 NTSC" }, + { MSP_CARRIER(5.5), "5.5 PAL B/G" }, + { MSP_CARRIER(6.0), "6.0 PAL I" }, + { MSP_CARRIER(6.5), "6.5 PAL D/K + SAT + SECAM" } +}; + +static struct CARRIER_DETECT carrier_detect_55[] = { + /* PAL B/G */ + { MSP_CARRIER(5.7421875), "5.742 PAL B/G FM-stereo" }, + { MSP_CARRIER(5.85), "5.85 PAL B/G NICAM" } +}; + +static struct CARRIER_DETECT carrier_detect_65[] = { + /* PAL SAT / SECAM */ + { MSP_CARRIER(5.85), "5.85 PAL D/K + SECAM NICAM" }, + { MSP_CARRIER(6.2578125), "6.25 PAL D/K1 FM-stereo" }, + { MSP_CARRIER(6.7421875), "6.74 PAL D/K2 FM-stereo" }, + { MSP_CARRIER(7.02), "7.02 PAL SAT FM-stereo s/b" }, + { MSP_CARRIER(7.20), "7.20 PAL SAT FM-stereo s" }, + { MSP_CARRIER(7.38), "7.38 PAL SAT FM-stereo b" }, +}; + +#define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT)) + +/* ----------------------------------------------------------------------- * + * bits 9 8 5 - SCART DSP input Select: + * 0 0 0 - SCART 1 to DSP input (reset position) + * 0 1 0 - MONO to DSP input + * 1 0 0 - SCART 2 to DSP input + * 1 1 1 - Mute DSP input + * + * bits 11 10 6 - SCART 1 Output Select: + * 0 0 0 - undefined (reset position) + * 0 1 0 - SCART 2 Input to SCART 1 Output (for devices with 2 SCARTS) + * 1 0 0 - MONO input to SCART 1 Output + * 1 1 0 - SCART 1 DA to SCART 1 Output + * 0 0 1 - SCART 2 DA to SCART 1 Output + * 0 1 1 - SCART 1 Input to SCART 1 Output + * 1 1 1 - Mute SCART 1 Output + * + * bits 13 12 7 - SCART 2 Output Select (for devices with 2 Output SCART): + * 0 0 0 - SCART 1 DA to SCART 2 Output (reset position) + * 0 1 0 - SCART 1 Input to SCART 2 Output + * 1 0 0 - MONO input to SCART 2 Output + * 0 0 1 - SCART 2 DA to SCART 2 Output + * 0 1 1 - SCART 2 Input to SCART 2 Output + * 1 1 0 - Mute SCART 2 Output + * + * Bits 4 to 0 should be zero. + * ----------------------------------------------------------------------- */ + +static int scarts[3][9] = { + /* MASK IN1 IN2 IN1_DA IN2_DA IN3 IN4 MONO MUTE */ + /* SCART DSP Input select */ + { 0x0320, 0x0000, 0x0200, -1, -1, 0x0300, 0x0020, 0x0100, 0x0320 }, + /* SCART1 Output select */ + { 0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 }, + /* SCART2 Output select */ + { 0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 }, +}; + +static char *scart_names[] = { + "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute" +}; + +static void msp3400c_set_scart(struct i2c_client *client, int in, int out) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + + msp->in_scart=in; + + if (in >= 1 && in <= 8 && out >= 0 && out <= 2) { + if (-1 == scarts[out][in]) + return; + + msp->acb &= ~scarts[out][SCART_MASK]; + msp->acb |= scarts[out][in]; + } else + msp->acb = 0xf60; /* Mute Input and SCART 1 Output */ + + msp3400_dbg("scart switch: %s => %d (ACB=0x%04x)\n", + scart_names[in], out, msp->acb); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x13, msp->acb); + + /* Sets I2S speed 0 = 1.024 Mbps, 1 = 2.048 Mbps */ + msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); +} + +/* ------------------------------------------------------------------------ */ + +static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2) +{ + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff); + msp3400c_write(client,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12); + msp3400c_write(client,I2C_MSP3400C_DEM, 0x00a3, cdo2 & 0xfff); + msp3400c_write(client,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12); + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/ +} + +static void msp3400c_setvolume(struct i2c_client *client, + int muted, int left, int right) + { + int vol = 0, val = 0, balance = 0; + + if (!muted) { + /* 0x7f instead if 0x73 here has sound quality issues, + * probably due to overmodulation + clipping ... */ + vol = (left > right) ? left : right; + val = (vol * 0x73 / 65535) << 8; + } + if (vol > 0) { + balance = ((right - left) * 127) / vol; + } + + msp3400_dbg("setvolume: mute=%s %d:%d v=0x%02x b=0x%02x\n", + muted ? "on" : "off", left, right, val >> 8, balance); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, + muted ? 0x1 : (val | 0x1)); + msp3400c_write(client, I2C_MSP3400C_DFP, 0x0001, balance << 8); +} + +static void msp3400c_setbass(struct i2c_client *client, int bass) +{ + int val = ((bass-32768) * 0x60 / 65535) << 8; + + msp3400_dbg("setbass: %d 0x%02x\n", bass, val >> 8); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */ +} + +static void msp3400c_settreble(struct i2c_client *client, int treble) +{ + int val = ((treble-32768) * 0x60 / 65535) << 8; + + msp3400_dbg("settreble: %d 0x%02x\n",treble, val>>8); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */ +} + +static void msp3400c_setmode(struct i2c_client *client, int type) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + int i; + + msp3400_dbg("setmode: %d\n",type); + msp->mode = type; + msp->audmode = V4L2_TUNER_MODE_MONO; + msp->rxsubchans = V4L2_TUNER_SUB_MONO; + + msp3400c_write(client,I2C_MSP3400C_DEM, 0x00bb, /* ad_cv */ + msp_init_data[type].ad_cv); + + for (i = 5; i >= 0; i--) /* fir 1 */ + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0001, + msp_init_data[type].fir1[i]); + + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0004); /* fir 2 */ + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0040); + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0000); + for (i = 5; i >= 0; i--) + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, + msp_init_data[type].fir2[i]); + + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0083, /* MODE_REG */ + msp_init_data[type].mode_reg); + + msp3400c_setcarrier(client, msp_init_data[type].cdo1, + msp_init_data[type].cdo2); + + msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/ + + if (dolby) { + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008, + 0x0520); /* I2S1 */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009, + 0x0620); /* I2S2 */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b, + msp_init_data[type].dfp_src); + } else { + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008, + msp_init_data[type].dfp_src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009, + msp_init_data[type].dfp_src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b, + msp_init_data[type].dfp_src); + } + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a, + msp_init_data[type].dfp_src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, + msp_init_data[type].dfp_matrix); + + if (HAVE_NICAM(msp)) { + /* nicam prescale */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0010, 0x5a00); /* was: 0x3000 */ + } +} + +/* given a bitmask of VIDEO_SOUND_XXX returns the "best" in the bitmask */ +static int best_video_sound(int rxsubchans) +{ + if (rxsubchans & V4L2_TUNER_SUB_STEREO) + return V4L2_TUNER_MODE_STEREO; + if (rxsubchans & V4L2_TUNER_SUB_LANG1) + return V4L2_TUNER_MODE_LANG1; + if (rxsubchans & V4L2_TUNER_SUB_LANG2) + return V4L2_TUNER_MODE_LANG2; + return V4L2_TUNER_MODE_MONO; +} + +/* turn on/off nicam + stereo */ +static void msp3400c_setstereo(struct i2c_client *client, int mode) +{ + static char *strmode[] = { "0", "mono", "stereo", "3", + "lang1", "5", "6", "7", "lang2" + }; + struct msp3400c *msp = i2c_get_clientdata(client); + int nicam = 0; /* channel source: FM/AM or nicam */ + int src = 0; + + if (IS_MSP34XX_G(msp)) { + /* this method would break everything, let's make sure + * it's never called + */ + msp3400_dbg + ("DEBUG WARNING setstereo called with mode=%d instead of set_source (ignored)\n", + mode); + return; + } + + /* switch demodulator */ + switch (msp->mode) { + case MSP_MODE_FM_TERRA: + msp3400_dbg("FM setstereo: %s\n", strmode[mode]); + msp3400c_setcarrier(client,msp->second,msp->main); + switch (mode) { + case V4L2_TUNER_MODE_STEREO: + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001); + break; + case V4L2_TUNER_MODE_MONO: + case V4L2_TUNER_MODE_LANG1: + case V4L2_TUNER_MODE_LANG2: + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3000); + break; + } + break; + case MSP_MODE_FM_SAT: + msp3400_dbg("SAT setstereo: %s\n", strmode[mode]); + switch (mode) { + case V4L2_TUNER_MODE_MONO: + msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5)); + break; + case V4L2_TUNER_MODE_STEREO: + msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02)); + break; + case V4L2_TUNER_MODE_LANG1: + msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); + break; + case V4L2_TUNER_MODE_LANG2: + msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02)); + break; + } + break; + case MSP_MODE_FM_NICAM1: + case MSP_MODE_FM_NICAM2: + case MSP_MODE_AM_NICAM: + msp3400_dbg("NICAM setstereo: %s\n",strmode[mode]); + msp3400c_setcarrier(client,msp->second,msp->main); + if (msp->nicam_on) + nicam=0x0100; + break; + case MSP_MODE_BTSC: + msp3400_dbg("BTSC setstereo: %s\n",strmode[mode]); + nicam=0x0300; + break; + case MSP_MODE_EXTERN: + msp3400_dbg("extern setstereo: %s\n",strmode[mode]); + nicam = 0x0200; + break; + case MSP_MODE_FM_RADIO: + msp3400_dbg("FM-Radio setstereo: %s\n",strmode[mode]); + break; + default: + msp3400_dbg("mono setstereo\n"); + return; + } + + /* switch audio */ + switch (best_video_sound(mode)) { + case V4L2_TUNER_MODE_STEREO: + src = 0x0020 | nicam; + break; + case V4L2_TUNER_MODE_MONO: + if (msp->mode == MSP_MODE_AM_NICAM) { + msp3400_dbg("switching to AM mono\n"); + /* AM mono decoding is handled by tuner, not MSP chip */ + /* SCART switching control register */ + msp3400c_set_scart(client,SCART_MONO,0); + src = 0x0200; + break; + } + case V4L2_TUNER_MODE_LANG1: + src = 0x0000 | nicam; + break; + case V4L2_TUNER_MODE_LANG2: + src = 0x0010 | nicam; + break; + } + msp3400_dbg("setstereo final source/matrix = 0x%x\n", src); + + if (dolby) { + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src); + } else { + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src); + } +} + +static void +msp3400c_print_mode(struct i2c_client *client) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + + if (msp->main == msp->second) { + msp3400_dbg("mono sound carrier: %d.%03d MHz\n", + msp->main/910000,(msp->main/910)%1000); + } else { + msp3400_dbg("main sound carrier: %d.%03d MHz\n", + msp->main/910000,(msp->main/910)%1000); + } + if (msp->mode == MSP_MODE_FM_NICAM1 || msp->mode == MSP_MODE_FM_NICAM2) + msp3400_dbg("NICAM/FM carrier : %d.%03d MHz\n", + msp->second/910000,(msp->second/910)%1000); + if (msp->mode == MSP_MODE_AM_NICAM) + msp3400_dbg("NICAM/AM carrier : %d.%03d MHz\n", + msp->second/910000,(msp->second/910)%1000); + if (msp->mode == MSP_MODE_FM_TERRA && + msp->main != msp->second) { + msp3400_dbg("FM-stereo carrier : %d.%03d MHz\n", + msp->second/910000,(msp->second/910)%1000); + } +} + +#define MSP3400_MAX 4 +static struct i2c_client *msps[MSP3400_MAX]; +static void msp3400c_restore_dfp(struct i2c_client *client) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + int i; + + for (i = 0; i < DFP_COUNT; i++) { + if (-1 == msp->dfp_regs[i]) + continue; + msp3400c_write(client, I2C_MSP3400C_DFP, i, msp->dfp_regs[i]); + } +} + +/* if the dfp_regs is set, set what's in there. Otherwise, set the default value */ +static int msp3400c_write_dfp_with_default(struct i2c_client *client, + int addr, int default_value) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + int value = default_value; + if (addr < DFP_COUNT && -1 != msp->dfp_regs[addr]) + value = msp->dfp_regs[addr]; + return msp3400c_write(client, I2C_MSP3400C_DFP, addr, value); +} + +/* ----------------------------------------------------------------------- */ + +struct REGISTER_DUMP { + int addr; + char *name; +}; + +struct REGISTER_DUMP d1[] = { + {0x007e, "autodetect"}, + {0x0023, "C_AD_BITS "}, + {0x0038, "ADD_BITS "}, + {0x003e, "CIB_BITS "}, + {0x0057, "ERROR_RATE"}, +}; + +static int autodetect_stereo(struct i2c_client *client) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + int val; + int rxsubchans = msp->rxsubchans; + int newnicam = msp->nicam_on; + int update = 0; + + switch (msp->mode) { + case MSP_MODE_FM_TERRA: + val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18); + if (val > 32767) + val -= 65536; + msp3400_dbg("stereo detect register: %d\n",val); + if (val > 4096) { + rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; + } else if (val < -4096) { + rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; + } else { + rxsubchans = V4L2_TUNER_SUB_MONO; + } + newnicam = 0; + break; + case MSP_MODE_FM_NICAM1: + case MSP_MODE_FM_NICAM2: + case MSP_MODE_AM_NICAM: + val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23); + msp3400_dbg("nicam sync=%d, mode=%d\n", + val & 1, (val & 0x1e) >> 1); + + if (val & 1) { + /* nicam synced */ + switch ((val & 0x1e) >> 1) { + case 0: + case 8: + rxsubchans = V4L2_TUNER_SUB_STEREO; + break; + case 1: + case 9: + rxsubchans = V4L2_TUNER_SUB_MONO + | V4L2_TUNER_SUB_LANG1; + break; + case 2: + case 10: + rxsubchans = V4L2_TUNER_SUB_MONO + | V4L2_TUNER_SUB_LANG1 + | V4L2_TUNER_SUB_LANG2; + break; + default: + rxsubchans = V4L2_TUNER_SUB_MONO; + break; + } + newnicam=1; + } else { + newnicam = 0; + rxsubchans = V4L2_TUNER_SUB_MONO; + } + break; + case MSP_MODE_BTSC: + val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200); + msp3400_dbg("status=0x%x (pri=%s, sec=%s, %s%s%s)\n", + val, + (val & 0x0002) ? "no" : "yes", + (val & 0x0004) ? "no" : "yes", + (val & 0x0040) ? "stereo" : "mono", + (val & 0x0080) ? ", nicam 2nd mono" : "", + (val & 0x0100) ? ", bilingual/SAP" : ""); + rxsubchans = V4L2_TUNER_SUB_MONO; + if (val & 0x0040) rxsubchans |= V4L2_TUNER_SUB_STEREO; + if (val & 0x0100) rxsubchans |= V4L2_TUNER_SUB_LANG1; + break; + } + if (rxsubchans != msp->rxsubchans) { + update = 1; + msp3400_dbg("watch: rxsubchans %d => %d\n", + msp->rxsubchans,rxsubchans); + msp->rxsubchans = rxsubchans; + } + if (newnicam != msp->nicam_on) { + update = 1; + msp3400_dbg("watch: nicam %d => %d\n", + msp->nicam_on,newnicam); + msp->nicam_on = newnicam; + } + return update; +} + +/* + * A kernel thread for msp3400 control -- we don't want to block the + * in the ioctl while doing the sound carrier & stereo detect + */ + +static int msp34xx_sleep(struct msp3400c *msp, int timeout) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(&msp->wq, &wait); + if (!kthread_should_stop()) { + if (timeout < 0) { + set_current_state(TASK_INTERRUPTIBLE); + schedule(); + } else { + schedule_timeout_interruptible + (msecs_to_jiffies(timeout)); + } + } + + remove_wait_queue(&msp->wq, &wait); + try_to_freeze(); + return msp->restart; +} + +/* stereo/multilang monitoring */ +static void watch_stereo(struct i2c_client *client) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + + if (autodetect_stereo(client)) { + if (msp->stereo & V4L2_TUNER_MODE_STEREO) + msp3400c_setstereo(client, V4L2_TUNER_MODE_STEREO); + else if (msp->stereo & VIDEO_SOUND_LANG1) + msp3400c_setstereo(client, V4L2_TUNER_MODE_LANG1); + else + msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); + } + + if (once) + msp->watch_stereo = 0; +} + + +static int msp3400c_thread(void *data) +{ + struct i2c_client *client = data; + struct msp3400c *msp = i2c_get_clientdata(client); + struct CARRIER_DETECT *cd; + int count, max1,max2,val1,val2, val,this; + + + msp3400_info("msp3400 daemon started\n"); + for (;;) { + msp3400_dbg_mediumvol("msp3400 thread: sleep\n"); + msp34xx_sleep(msp,-1); + msp3400_dbg_mediumvol("msp3400 thread: wakeup\n"); + + restart: + msp3400_dbg("thread: restart scan\n"); + msp->restart = 0; + if (kthread_should_stop()) + break; + + if (VIDEO_MODE_RADIO == msp->norm || + MSP_MODE_EXTERN == msp->mode) { + /* no carrier scan, just unmute */ + msp3400_info("thread: no carrier scan\n"); + msp3400c_setvolume(client, msp->muted, msp->left, msp->right); + continue; + } + + /* mute */ + msp3400c_setvolume(client, msp->muted, 0, 0); + msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ ); + val1 = val2 = 0; + max1 = max2 = -1; + msp->watch_stereo = 0; + + /* some time for the tuner to sync */ + if (msp34xx_sleep(msp,200)) + goto restart; + + /* carrier detect pass #1 -- main carrier */ + cd = carrier_detect_main; + count = CARRIER_COUNT(carrier_detect_main); + + if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { + /* autodetect doesn't work well with AM ... */ + max1 = 3; + count = 0; + msp3400_dbg("AM sound override\n"); + } + + for (this = 0; this < count; this++) { + msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); + if (msp34xx_sleep(msp,100)) + goto restart; + val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b); + if (val > 32767) + val -= 65536; + if (val1 < val) + val1 = val, max1 = this; + msp3400_dbg("carrier1 val: %5d / %s\n", val,cd[this].name); + } + + /* carrier detect pass #2 -- second (stereo) carrier */ + switch (max1) { + case 1: /* 5.5 */ + cd = carrier_detect_55; + count = CARRIER_COUNT(carrier_detect_55); + break; + case 3: /* 6.5 */ + cd = carrier_detect_65; + count = CARRIER_COUNT(carrier_detect_65); + break; + case 0: /* 4.5 */ + case 2: /* 6.0 */ + default: + cd = NULL; + count = 0; + break; + } + + if (amsound && (msp->norm == VIDEO_MODE_SECAM)) { + /* autodetect doesn't work well with AM ... */ + cd = NULL; + count = 0; + max2 = 0; + } + for (this = 0; this < count; this++) { + msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo); + if (msp34xx_sleep(msp,100)) + goto restart; + val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b); + if (val > 32767) + val -= 65536; + if (val2 < val) + val2 = val, max2 = this; + msp3400_dbg("carrier2 val: %5d / %s\n", val,cd[this].name); + } + + /* programm the msp3400 according to the results */ + msp->main = carrier_detect_main[max1].cdo; + switch (max1) { + case 1: /* 5.5 */ + if (max2 == 0) { + /* B/G FM-stereo */ + msp->second = carrier_detect_55[max2].cdo; + msp3400c_setmode(client, MSP_MODE_FM_TERRA); + msp->nicam_on = 0; + msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); + msp->watch_stereo = 1; + } else if (max2 == 1 && HAVE_NICAM(msp)) { + /* B/G NICAM */ + msp->second = carrier_detect_55[max2].cdo; + msp3400c_setmode(client, MSP_MODE_FM_NICAM1); + msp->nicam_on = 1; + msp3400c_setcarrier(client, msp->second, msp->main); + msp->watch_stereo = 1; + } else { + goto no_second; + } + break; + case 2: /* 6.0 */ + /* PAL I NICAM */ + msp->second = MSP_CARRIER(6.552); + msp3400c_setmode(client, MSP_MODE_FM_NICAM2); + msp->nicam_on = 1; + msp3400c_setcarrier(client, msp->second, msp->main); + msp->watch_stereo = 1; + break; + case 3: /* 6.5 */ + if (max2 == 1 || max2 == 2) { + /* D/K FM-stereo */ + msp->second = carrier_detect_65[max2].cdo; + msp3400c_setmode(client, MSP_MODE_FM_TERRA); + msp->nicam_on = 0; + msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); + msp->watch_stereo = 1; + } else if (max2 == 0 && + msp->norm == VIDEO_MODE_SECAM) { + /* L NICAM or AM-mono */ + msp->second = carrier_detect_65[max2].cdo; + msp3400c_setmode(client, MSP_MODE_AM_NICAM); + msp->nicam_on = 0; + msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); + msp3400c_setcarrier(client, msp->second, msp->main); + /* volume prescale for SCART (AM mono input) */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900); + msp->watch_stereo = 1; + } else if (max2 == 0 && HAVE_NICAM(msp)) { + /* D/K NICAM */ + msp->second = carrier_detect_65[max2].cdo; + msp3400c_setmode(client, MSP_MODE_FM_NICAM1); + msp->nicam_on = 1; + msp3400c_setcarrier(client, msp->second, msp->main); + msp->watch_stereo = 1; + } else { + goto no_second; + } + break; + case 0: /* 4.5 */ + default: + no_second: + msp->second = carrier_detect_main[max1].cdo; + msp3400c_setmode(client, MSP_MODE_FM_TERRA); + msp->nicam_on = 0; + msp3400c_setcarrier(client, msp->second, msp->main); + msp->rxsubchans = V4L2_TUNER_SUB_MONO; + msp3400c_setstereo(client, V4L2_TUNER_MODE_MONO); + break; + } + + /* unmute */ + msp3400c_setvolume(client, msp->muted, msp->left, msp->right); + msp3400c_restore_dfp(client); + + if (debug) + msp3400c_print_mode(client); + + /* monitor tv audio mode */ + while (msp->watch_stereo) { + if (msp34xx_sleep(msp,5000)) + goto restart; + watch_stereo(client); + } + } + msp3400_dbg("thread: exit\n"); + return 0; +} + +/* ----------------------------------------------------------------------- */ +/* this one uses the automatic sound standard detection of newer */ +/* msp34xx chip versions */ + +static struct MODES { + int retval; + int main, second; + char *name; +} modelist[] = { + { 0x0000, 0, 0, "ERROR" }, + { 0x0001, 0, 0, "autodetect start" }, + { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72 M Dual FM-Stereo" }, + { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74 B/G Dual FM-Stereo" }, + { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25 D/K1 Dual FM-Stereo" }, + { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74 D/K2 Dual FM-Stereo" }, + { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 D/K FM-Mono (HDEV3)" }, + { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85 B/G NICAM FM" }, + { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 L NICAM AM" }, + { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55 I NICAM FM" }, + { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM" }, + { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85 D/K NICAM FM (HDEV2)" }, + { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Stereo" }, + { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M BTSC-Mono + SAP" }, + { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5 M EIA-J Japan Stereo" }, + { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7 FM-Stereo Radio" }, + { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5 SAT-Mono" }, + { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20 SAT-Stereo" }, + { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2 SAT ADR" }, + { -1, 0, 0, NULL }, /* EOF */ +}; + +static inline const char *msp34xx_standard_mode_name(int mode) +{ + int i; + for (i = 0; modelist[i].name != NULL; i++) + if (modelist[i].retval == mode) + return modelist[i].name; + return "unknown"; +} + +static int msp34xx_modus(struct i2c_client *client, int norm) +{ + switch (norm) { + case VIDEO_MODE_PAL: + msp3400_dbg("video mode selected to PAL\n"); + +#if 1 + /* experimental: not sure this works with all chip versions */ + return 0x7003; +#else + /* previous value, try this if it breaks ... */ + return 0x1003; +#endif + case VIDEO_MODE_NTSC: /* BTSC */ + msp3400_dbg("video mode selected to NTSC\n"); + return 0x2003; + case VIDEO_MODE_SECAM: + msp3400_dbg("video mode selected to SECAM\n"); + return 0x0003; + case VIDEO_MODE_RADIO: + msp3400_dbg("video mode selected to Radio\n"); + return 0x0003; + case VIDEO_MODE_AUTO: + msp3400_dbg("video mode selected to Auto\n"); + return 0x2003; + default: + return 0x0003; + } +} + +static int msp34xx_standard(int norm) +{ + switch (norm) { + case VIDEO_MODE_PAL: + return 1; + case VIDEO_MODE_NTSC: /* BTSC */ + return 0x0020; + case VIDEO_MODE_SECAM: + return 1; + case VIDEO_MODE_RADIO: + return 0x0040; + default: + return 1; + } +} + +static int msp3410d_thread(void *data) +{ + struct i2c_client *client = data; + struct msp3400c *msp = i2c_get_clientdata(client); + int mode,val,i,std; + + msp3400_info("msp3410 daemon started\n"); + + for (;;) { + msp3400_dbg_mediumvol("msp3410 thread: sleep\n"); + msp34xx_sleep(msp,-1); + msp3400_dbg_mediumvol("msp3410 thread: wakeup\n"); + + restart: + msp3400_dbg("thread: restart scan\n"); + msp->restart = 0; + if (kthread_should_stop()) + break; + + if (msp->mode == MSP_MODE_EXTERN) { + /* no carrier scan needed, just unmute */ + msp3400_dbg("thread: no carrier scan\n"); + msp3400c_setvolume(client, msp->muted, msp->left, msp->right); + continue; + } + + /* put into sane state (and mute) */ + msp3400c_reset(client); + + /* some time for the tuner to sync */ + if (msp34xx_sleep(msp,200)) + goto restart; + + /* start autodetect */ + mode = msp34xx_modus(client, msp->norm); + std = msp34xx_standard(msp->norm); + msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode); + msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std); + msp->watch_stereo = 0; + + if (debug) + msp3400_dbg("setting mode: %s (0x%04x)\n", + msp34xx_standard_mode_name(std) ,std); + + if (std != 1) { + /* programmed some specific mode */ + val = std; + } else { + /* triggered autodetect */ + for (;;) { + if (msp34xx_sleep(msp,100)) + goto restart; + + /* check results */ + val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); + if (val < 0x07ff) + break; + msp3400_dbg("detection still in progress\n"); + } + } + for (i = 0; modelist[i].name != NULL; i++) + if (modelist[i].retval == val) + break; + msp3400_dbg("current mode: %s (0x%04x)\n", + modelist[i].name ? modelist[i].name : "unknown", + val); + msp->main = modelist[i].main; + msp->second = modelist[i].second; + + if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) { + /* autodetection has failed, let backup */ + msp3400_dbg("autodetection failed," + " switching to backup mode: %s (0x%04x)\n", + modelist[8].name ? modelist[8].name : "unknown",val); + val = 0x0009; + msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, val); + } + + /* set various prescales */ + msp3400c_write(client, I2C_MSP3400C_DFP, 0x0d, 0x1900); /* scart */ + msp3400c_write(client, I2C_MSP3400C_DFP, 0x0e, 0x2403); /* FM */ + msp3400c_write(client, I2C_MSP3400C_DFP, 0x10, 0x5a00); /* nicam */ + + /* set stereo */ + switch (val) { + case 0x0008: /* B/G NICAM */ + case 0x000a: /* I NICAM */ + if (val == 0x0008) + msp->mode = MSP_MODE_FM_NICAM1; + else + msp->mode = MSP_MODE_FM_NICAM2; + /* just turn on stereo */ + msp->rxsubchans = V4L2_TUNER_SUB_STEREO; + msp->nicam_on = 1; + msp->watch_stereo = 1; + msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); + break; + case 0x0009: + msp->mode = MSP_MODE_AM_NICAM; + msp->rxsubchans = V4L2_TUNER_SUB_MONO; + msp->nicam_on = 1; + msp3400c_setstereo(client,V4L2_TUNER_MODE_MONO); + msp->watch_stereo = 1; + break; + case 0x0020: /* BTSC */ + /* just turn on stereo */ + msp->mode = MSP_MODE_BTSC; + msp->rxsubchans = V4L2_TUNER_SUB_STEREO; + msp->nicam_on = 0; + msp->watch_stereo = 1; + msp3400c_setstereo(client,V4L2_TUNER_MODE_STEREO); + break; + case 0x0040: /* FM radio */ + msp->mode = MSP_MODE_FM_RADIO; + msp->rxsubchans = V4L2_TUNER_SUB_STEREO; + msp->audmode = V4L2_TUNER_MODE_STEREO; + msp->nicam_on = 0; + msp->watch_stereo = 0; + /* not needed in theory if HAVE_RADIO(), but + short programming enables carrier mute */ + msp3400c_setmode(client,MSP_MODE_FM_RADIO); + msp3400c_setcarrier(client, MSP_CARRIER(10.7), + MSP_CARRIER(10.7)); + /* scart routing */ + msp3400c_set_scart(client,SCART_IN2,0); + /* msp34xx does radio decoding */ + msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0020); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0020); + msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0020); + break; + case 0x0003: + case 0x0004: + case 0x0005: + msp->mode = MSP_MODE_FM_TERRA; + msp->rxsubchans = V4L2_TUNER_SUB_MONO; + msp->audmode = V4L2_TUNER_MODE_MONO; + msp->nicam_on = 0; + msp->watch_stereo = 1; + break; + } + + /* unmute, restore misc registers */ + msp3400c_setbass(client, msp->bass); + msp3400c_settreble(client, msp->treble); + msp3400c_setvolume(client, msp->muted, msp->left, msp->right); + msp3400c_write(client, I2C_MSP3400C_DFP, 0x13, msp->acb); + msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); + msp3400c_restore_dfp(client); + + /* monitor tv audio mode */ + while (msp->watch_stereo) { + if (msp34xx_sleep(msp,5000)) + goto restart; + watch_stereo(client); + } + } + msp3400_dbg("thread: exit\n"); + return 0; +} + +/* ----------------------------------------------------------------------- */ +/* msp34xxG + (simpler no-thread) */ +/* this one uses both automatic standard detection and automatic sound */ +/* select which are available in the newer G versions */ +/* struct msp: only norm, acb and source are really used in this mode */ + +static void msp34xxg_set_source(struct i2c_client *client, int source); + +/* (re-)initialize the msp34xxg, according to the current norm in msp->norm + * return 0 if it worked, -1 if it failed + */ +static int msp34xxg_reset(struct i2c_client *client) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + int modus,std; + + if (msp3400c_reset(client)) + return -1; + + /* make sure that input/output is muted (paranoid mode) */ + if (msp3400c_write(client, + I2C_MSP3400C_DFP, + 0x13, /* ACB */ + 0x0f20 /* mute DSP input, mute SCART 1 */)) + return -1; + + msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); + + /* step-by-step initialisation, as described in the manual */ + modus = msp34xx_modus(client, msp->norm); + std = msp34xx_standard(msp->norm); + modus &= ~0x03; /* STATUS_CHANGE=0 */ + modus |= 0x01; /* AUTOMATIC_SOUND_DETECTION=1 */ + if (msp3400c_write(client, + I2C_MSP3400C_DEM, + 0x30/*MODUS*/, + modus)) + return -1; + if (msp3400c_write(client, + I2C_MSP3400C_DEM, + 0x20/*standard*/, + std)) + return -1; + + /* write the dfps that may have an influence on + standard/audio autodetection right now */ + msp34xxg_set_source(client, msp->source); + + if (msp3400c_write_dfp_with_default(client, 0x0e, /* AM/FM Prescale */ + 0x3000 + /* default: [15:8] 75khz deviation */ + )) + return -1; + + if (msp3400c_write_dfp_with_default(client, 0x10, /* NICAM Prescale */ + 0x5a00 + /* default: 9db gain (as recommended) */ + )) + return -1; + + return 0; +} + +static int msp34xxg_thread(void *data) +{ + struct i2c_client *client = data; + struct msp3400c *msp = i2c_get_clientdata(client); + int val, std, i; + + msp3400_info("msp34xxg daemon started\n"); + + msp->source = 1; /* default */ + for (;;) { + msp3400_dbg_mediumvol("msp34xxg thread: sleep\n"); + msp34xx_sleep(msp,-1); + msp3400_dbg_mediumvol("msp34xxg thread: wakeup\n"); + + restart: + msp3400_dbg("thread: restart scan\n"); + msp->restart = 0; + if (kthread_should_stop()) + break; + + /* setup the chip*/ + msp34xxg_reset(client); + std = standard; + if (std != 0x01) + goto unmute; + + /* watch autodetect */ + msp3400_dbg("triggered autodetect, waiting for result\n"); + for (i = 0; i < 10; i++) { + if (msp34xx_sleep(msp,100)) + goto restart; + + /* check results */ + val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e); + if (val < 0x07ff) { + std = val; + break; + } + msp3400_dbg("detection still in progress\n"); + } + if (0x01 == std) { + msp3400_dbg("detection still in progress after 10 tries. giving up.\n"); + continue; + } + + unmute: + msp3400_dbg("current mode: %s (0x%04x)\n", + msp34xx_standard_mode_name(std), std); + + /* unmute: dispatch sound to scart output, set scart volume */ + msp3400_dbg("unmute\n"); + + msp3400c_setbass(client, msp->bass); + msp3400c_settreble(client, msp->treble); + msp3400c_setvolume(client, msp->muted, msp->left, msp->right); + + /* restore ACB */ + if (msp3400c_write(client, + I2C_MSP3400C_DFP, + 0x13, /* ACB */ + msp->acb)) + return -1; + + msp3400c_write(client,I2C_MSP3400C_DEM, 0x40, msp->i2s_mode); + } + msp3400_dbg("thread: exit\n"); + return 0; +} + +/* set the same 'source' for the loudspeaker, scart and quasi-peak detector + * the value for source is the same as bit 15:8 of DFP registers 0x08, + * 0x0a and 0x0c: 0=mono, 1=stereo or A|B, 2=SCART, 3=stereo or A, 4=stereo or B + * + * this function replaces msp3400c_setstereo + */ +static void msp34xxg_set_source(struct i2c_client *client, int source) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + + /* fix matrix mode to stereo and let the msp choose what + * to output according to 'source', as recommended + * for MONO (source==0) downmixing set bit[7:0] to 0x30 + */ + int value = (source&0x07)<<8|(source==0 ? 0x30:0x20); + msp3400_dbg("set source to %d (0x%x)\n", source, value); + msp3400c_write(client, + I2C_MSP3400C_DFP, + 0x08, /* Loudspeaker Output */ + value); + msp3400c_write(client, + I2C_MSP3400C_DFP, + 0x0a, /* SCART1 DA Output */ + value); + msp3400c_write(client, + I2C_MSP3400C_DFP, + 0x0c, /* Quasi-peak detector */ + value); + /* + * set identification threshold. Personally, I + * I set it to a higher value that the default + * of 0x190 to ignore noisy stereo signals. + * this needs tuning. (recommended range 0x00a0-0x03c0) + * 0x7f0 = forced mono mode + */ + msp3400c_write(client, + I2C_MSP3400C_DEM, + 0x22, /* a2 threshold for stereo/bilingual */ + stereo_threshold); + msp->source=source; +} + +static void msp34xxg_detect_stereo(struct i2c_client *client) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + + int status = msp3400c_read(client, + I2C_MSP3400C_DEM, + 0x0200 /* STATUS */); + int is_bilingual = status&0x100; + int is_stereo = status&0x40; + + msp->rxsubchans = 0; + if (is_stereo) + msp->rxsubchans |= V4L2_TUNER_SUB_STEREO; + else + msp->rxsubchans |= V4L2_TUNER_SUB_MONO; + if (is_bilingual) { + msp->rxsubchans |= V4L2_TUNER_SUB_LANG1|V4L2_TUNER_SUB_LANG2; + /* I'm supposed to check whether it's SAP or not + * and set only LANG2/SAP in this case. Yet, the MSP + * does a lot of work to hide this and handle everything + * the same way. I don't want to work around it so unless + * this is a problem, I'll handle SAP just like lang1/lang2. + */ + } + msp3400_dbg("status=0x%x, stereo=%d, bilingual=%d -> rxsubchans=%d\n", + status, is_stereo, is_bilingual, msp->rxsubchans); +} + +static void msp34xxg_set_audmode(struct i2c_client *client, int audmode) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + int source; + + switch (audmode) { + case V4L2_TUNER_MODE_MONO: + source=0; /* mono only */ + break; + case V4L2_TUNER_MODE_STEREO: + source=1; /* stereo or A|B, see comment in msp34xxg_get_v4l2_stereo() */ + /* problem: that could also mean 2 (scart input) */ + break; + case V4L2_TUNER_MODE_LANG1: + source=3; /* stereo or A */ + break; + case V4L2_TUNER_MODE_LANG2: + source=4; /* stereo or B */ + break; + default: + audmode = 0; + source = 1; + break; + } + msp->audmode = audmode; + msp34xxg_set_source(client, source); +} + + +/* ----------------------------------------------------------------------- */ + +static int msp_attach(struct i2c_adapter *adap, int addr, int kind); +static int msp_detach(struct i2c_client *client); +static int msp_probe(struct i2c_adapter *adap); +static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg); + +static int msp_suspend(struct device * dev, pm_message_t state); +static int msp_resume(struct device * dev); + +static void msp_wake_thread(struct i2c_client *client); + +static struct i2c_driver driver = { + .id = I2C_DRIVERID_MSP3400, + .attach_adapter = msp_probe, + .detach_client = msp_detach, + .command = msp_command, + .driver = { + .name = "i2c msp3400 driver", + .suspend = msp_suspend, + .resume = msp_resume, + }, +}; + +static struct i2c_client client_template = +{ + .name = "(unset)", + .driver = &driver, +}; + +static int msp_attach(struct i2c_adapter *adap, int addr, int kind) +{ + struct msp3400c *msp; + struct i2c_client *client = &client_template; + int (*thread_func)(void *data) = NULL; + int i; + + client_template.adapter = adap; + client_template.addr = addr; + + if (-1 == msp3400c_reset(&client_template)) { + msp3400_dbg("no chip found\n"); + return -1; + } + + if (NULL == (client = kmalloc(sizeof(struct i2c_client),GFP_KERNEL))) + return -ENOMEM; + memcpy(client,&client_template,sizeof(struct i2c_client)); + if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) { + kfree(client); + return -ENOMEM; + } + + memset(msp,0,sizeof(struct msp3400c)); + msp->norm = VIDEO_MODE_NTSC; + msp->left = 58880; /* 0db gain */ + msp->right = 58880; /* 0db gain */ + msp->bass = 32768; + msp->treble = 32768; + msp->input = -1; + msp->muted = 0; + msp->i2s_mode = 0; + for (i = 0; i < DFP_COUNT; i++) + msp->dfp_regs[i] = -1; + + i2c_set_clientdata(client, msp); + init_waitqueue_head(&msp->wq); + + if (-1 == msp3400c_reset(client)) { + kfree(msp); + kfree(client); + msp3400_dbg("no chip found\n"); + return -1; + } + + msp->rev1 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1e); + if (-1 != msp->rev1) + msp->rev2 = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1f); + if ((-1 == msp->rev1) || (0 == msp->rev1 && 0 == msp->rev2)) { + kfree(msp); + kfree(client); + msp3400_dbg("error while reading chip version\n"); + return -1; + } + msp3400_dbg("rev1=0x%04x, rev2=0x%04x\n", msp->rev1, msp->rev2); + + msp3400c_setvolume(client, msp->muted, msp->left, msp->right); + + snprintf(client->name, sizeof(client->name), "MSP%c4%02d%c-%c%d", + ((msp->rev1>>4)&0x0f) + '3', + (msp->rev2>>8)&0xff, (msp->rev1&0x0f)+'@', + ((msp->rev1>>8)&0xff)+'@', msp->rev2&0x1f); + + msp->opmode = opmode; + if (OPMODE_AUTO == msp->opmode) { + if (HAVE_SIMPLER(msp)) + msp->opmode = OPMODE_SIMPLER; + else if (HAVE_SIMPLE(msp)) + msp->opmode = OPMODE_SIMPLE; + else + msp->opmode = OPMODE_MANUAL; + } + + /* hello world :-) */ + msp3400_info("chip=%s", client->name); + if (HAVE_NICAM(msp)) + printk(" +nicam"); + if (HAVE_SIMPLE(msp)) + printk(" +simple"); + if (HAVE_SIMPLER(msp)) + printk(" +simpler"); + if (HAVE_RADIO(msp)) + printk(" +radio"); + + /* version-specific initialization */ + switch (msp->opmode) { + case OPMODE_MANUAL: + printk(" mode=manual"); + thread_func = msp3400c_thread; + break; + case OPMODE_SIMPLE: + printk(" mode=simple"); + thread_func = msp3410d_thread; + break; + case OPMODE_SIMPLER: + printk(" mode=simpler"); + thread_func = msp34xxg_thread; + break; + } + printk("\n"); + + /* startup control thread if needed */ + if (thread_func) { + msp->kthread = kthread_run(thread_func, client, "msp34xx"); + + if (NULL == msp->kthread) + msp3400_warn("kernel_thread() failed\n"); + msp_wake_thread(client); + } + + /* done */ + i2c_attach_client(client); + + /* update our own array */ + for (i = 0; i < MSP3400_MAX; i++) { + if (NULL == msps[i]) { + msps[i] = client; + break; + } + } + + return 0; +} + +static int msp_detach(struct i2c_client *client) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + int i; + + /* shutdown control thread */ + if (msp->kthread) { + msp->restart = 1; + kthread_stop(msp->kthread); + } + msp3400c_reset(client); + + /* update our own array */ + for (i = 0; i < MSP3400_MAX; i++) { + if (client == msps[i]) { + msps[i] = NULL; + break; + } + } + + i2c_detach_client(client); + + kfree(msp); + kfree(client); + return 0; +} + +static int msp_probe(struct i2c_adapter *adap) +{ + if (adap->class & I2C_CLASS_TV_ANALOG) + return i2c_probe(adap, &addr_data, msp_attach); + return 0; +} + +static void msp_wake_thread(struct i2c_client *client) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + + if (NULL == msp->kthread) + return; + msp3400c_setvolume(client,msp->muted,0,0); + msp->watch_stereo = 0; + msp->restart = 1; + wake_up_interruptible(&msp->wq); +} + +/* ----------------------------------------------------------------------- */ + +static int mode_v4l2_to_v4l1(int rxsubchans) +{ + int mode = 0; + + if (rxsubchans & V4L2_TUNER_SUB_STEREO) + mode |= VIDEO_SOUND_STEREO; + if (rxsubchans & V4L2_TUNER_SUB_LANG2) + mode |= VIDEO_SOUND_LANG2; + if (rxsubchans & V4L2_TUNER_SUB_LANG1) + mode |= VIDEO_SOUND_LANG1; + if (0 == mode) + mode |= VIDEO_SOUND_MONO; + return mode; +} + +static int mode_v4l1_to_v4l2(int mode) +{ + if (mode & VIDEO_SOUND_STEREO) + return V4L2_TUNER_MODE_STEREO; + if (mode & VIDEO_SOUND_LANG2) + return V4L2_TUNER_MODE_LANG2; + if (mode & VIDEO_SOUND_LANG1) + return V4L2_TUNER_MODE_LANG1; + return V4L2_TUNER_MODE_MONO; +} + +static void msp_any_detect_stereo(struct i2c_client *client) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + + switch (msp->opmode) { + case OPMODE_MANUAL: + case OPMODE_SIMPLE: + autodetect_stereo(client); + break; + case OPMODE_SIMPLER: + msp34xxg_detect_stereo(client); + break; + } +} + +static void msp_any_set_audmode(struct i2c_client *client, int audmode) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + + switch (msp->opmode) { + case OPMODE_MANUAL: + case OPMODE_SIMPLE: + msp->watch_stereo = 0; + msp3400c_setstereo(client, audmode); + break; + case OPMODE_SIMPLER: + msp34xxg_set_audmode(client, audmode); + break; + } +} + + +static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg) +{ + struct msp3400c *msp = i2c_get_clientdata(client); + __u16 *sarg = arg; + int scart = 0; + + switch (cmd) { + + case AUDC_SET_INPUT: + msp3400_dbg("AUDC_SET_INPUT(%d)\n",*sarg); + + if (*sarg == msp->input) + break; + msp->input = *sarg; + switch (*sarg) { + case AUDIO_RADIO: + /* Hauppauge uses IN2 for the radio */ + msp->mode = MSP_MODE_FM_RADIO; + scart = SCART_IN2; + break; + case AUDIO_EXTERN_1: + /* IN1 is often used for external input ... */ + msp->mode = MSP_MODE_EXTERN; + scart = SCART_IN1; + break; + case AUDIO_EXTERN_2: + /* ... sometimes it is IN2 through ;) */ + msp->mode = MSP_MODE_EXTERN; + scart = SCART_IN2; + break; + case AUDIO_TUNER: + msp->mode = -1; + break; + default: + if (*sarg & AUDIO_MUTE) + msp3400c_set_scart(client,SCART_MUTE,0); + break; + } + if (scart) { + msp->rxsubchans = V4L2_TUNER_SUB_STEREO; + msp->audmode = V4L2_TUNER_MODE_STEREO; + msp3400c_set_scart(client,scart,0); + msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); + if (msp->opmode != OPMODE_SIMPLER) + msp3400c_setstereo(client, msp->audmode); + } + msp_wake_thread(client); + break; + + case AUDC_SET_RADIO: + msp3400_dbg("AUDC_SET_RADIO\n"); + msp->norm = VIDEO_MODE_RADIO; + msp3400_dbg("switching to radio mode\n"); + msp->watch_stereo = 0; + switch (msp->opmode) { + case OPMODE_MANUAL: + /* set msp3400 to FM radio mode */ + msp3400c_setmode(client,MSP_MODE_FM_RADIO); + msp3400c_setcarrier(client, MSP_CARRIER(10.7), + MSP_CARRIER(10.7)); + msp3400c_setvolume(client, msp->muted, msp->left, msp->right); + break; + case OPMODE_SIMPLE: + case OPMODE_SIMPLER: + /* the thread will do for us */ + msp_wake_thread(client); + break; + } + break; + /* work-in-progress: hook to control the DFP registers */ + case MSP_SET_DFPREG: + { + struct msp_dfpreg *r = arg; + int i; + + if (r->reg < 0 || r->reg >= DFP_COUNT) + return -EINVAL; + for (i = 0; i < sizeof(bl_dfp) / sizeof(int); i++) + if (r->reg == bl_dfp[i]) + return -EINVAL; + msp->dfp_regs[r->reg] = r->value; + msp3400c_write(client, I2C_MSP3400C_DFP, r->reg, r->value); + return 0; + } + case MSP_GET_DFPREG: + { + struct msp_dfpreg *r = arg; + + if (r->reg < 0 || r->reg >= DFP_COUNT) + return -EINVAL; + r->value = msp3400c_read(client, I2C_MSP3400C_DFP, r->reg); + return 0; + } + + /* --- v4l ioctls --- */ + /* take care: bttv does userspace copying, we'll get a + kernel pointer here... */ + case VIDIOCGAUDIO: + { + struct video_audio *va = arg; + + msp3400_dbg("VIDIOCGAUDIO\n"); + va->flags |= VIDEO_AUDIO_VOLUME | + VIDEO_AUDIO_BASS | + VIDEO_AUDIO_TREBLE | + VIDEO_AUDIO_MUTABLE; + if (msp->muted) + va->flags |= VIDEO_AUDIO_MUTE; + + if (msp->muted) + va->flags |= VIDEO_AUDIO_MUTE; + va->volume = MAX(msp->left, msp->right); + va->balance = (32768 * MIN(msp->left, msp->right)) / + (va->volume ? va->volume : 1); + va->balance = (msp->left < msp->right) ? + (65535 - va->balance) : va->balance; + if (0 == va->volume) + va->balance = 32768; + va->bass = msp->bass; + va->treble = msp->treble; + + msp_any_detect_stereo(client); + va->mode = mode_v4l2_to_v4l1(msp->rxsubchans); + break; + } + case VIDIOCSAUDIO: + { + struct video_audio *va = arg; + + msp3400_dbg("VIDIOCSAUDIO\n"); + msp->muted = (va->flags & VIDEO_AUDIO_MUTE); + msp->left = (MIN(65536 - va->balance, 32768) * + va->volume) / 32768; + msp->right = (MIN(va->balance, 32768) * va->volume) / 32768; + msp->bass = va->bass; + msp->treble = va->treble; + msp3400_dbg("VIDIOCSAUDIO setting va->volume to %d\n", + va->volume); + msp3400_dbg("VIDIOCSAUDIO setting va->balance to %d\n", + va->balance); + msp3400_dbg("VIDIOCSAUDIO setting va->flags to %d\n", + va->flags); + msp3400_dbg("VIDIOCSAUDIO setting msp->left to %d\n", + msp->left); + msp3400_dbg("VIDIOCSAUDIO setting msp->right to %d\n", + msp->right); + msp3400_dbg("VIDIOCSAUDIO setting msp->bass to %d\n", + msp->bass); + msp3400_dbg("VIDIOCSAUDIO setting msp->treble to %d\n", + msp->treble); + msp3400_dbg("VIDIOCSAUDIO setting msp->mode to %d\n", + msp->mode); + msp3400c_setvolume(client, msp->muted, msp->left, msp->right); + msp3400c_setbass(client, msp->bass); + msp3400c_settreble(client, msp->treble); + + if (va->mode != 0 && msp->norm != VIDEO_MODE_RADIO) + msp_any_set_audmode(client,mode_v4l1_to_v4l2(va->mode)); + break; + } + + case VIDIOCSCHAN: + { + struct video_channel *vc = arg; + + msp3400_dbg("VIDIOCSCHAN (norm=%d)\n",vc->norm); + msp->norm = vc->norm; + msp_wake_thread(client); + break; + } + + case VIDIOCSFREQ: + case VIDIOC_S_FREQUENCY: + { + /* new channel -- kick audio carrier scan */ + msp3400_dbg("VIDIOCSFREQ\n"); + msp_wake_thread(client); + break; + } + + /* msp34xx specific */ + case MSP_SET_MATRIX: + { + struct msp_matrix *mspm = arg; + + msp3400_dbg("MSP_SET_MATRIX\n"); + msp3400c_set_scart(client, mspm->input, mspm->output); + break; + } + + /* --- v4l2 ioctls --- */ + case VIDIOC_S_STD: + { + v4l2_std_id *id = arg; + + /*FIXME: use V4L2 mode flags on msp3400 instead of V4L1*/ + if (*id & V4L2_STD_PAL) { + msp->norm=VIDEO_MODE_PAL; + } else if (*id & V4L2_STD_SECAM) { + msp->norm=VIDEO_MODE_SECAM; + } else { + msp->norm=VIDEO_MODE_NTSC; + } + + msp_wake_thread(client); + return 0; + } + + case VIDIOC_ENUMINPUT: + { + struct v4l2_input *i = arg; + + if (i->index != 0) + return -EINVAL; + + i->type = V4L2_INPUT_TYPE_TUNER; + switch (i->index) { + case AUDIO_RADIO: + strcpy(i->name,"Radio"); + break; + case AUDIO_EXTERN_1: + strcpy(i->name,"Extern 1"); + break; + case AUDIO_EXTERN_2: + strcpy(i->name,"Extern 2"); + break; + case AUDIO_TUNER: + strcpy(i->name,"Television"); + break; + default: + return -EINVAL; + } + return 0; + } + + case VIDIOC_G_AUDIO: + { + struct v4l2_audio *a = arg; + + memset(a,0,sizeof(*a)); + + switch (a->index) { + case AUDIO_RADIO: + strcpy(a->name,"Radio"); + break; + case AUDIO_EXTERN_1: + strcpy(a->name,"Extern 1"); + break; + case AUDIO_EXTERN_2: + strcpy(a->name,"Extern 2"); + break; + case AUDIO_TUNER: + strcpy(a->name,"Television"); + break; + default: + return -EINVAL; + } + + msp_any_detect_stereo(client); + if (msp->audmode == V4L2_TUNER_MODE_STEREO) { + a->capability=V4L2_AUDCAP_STEREO; + } + + break; + } + case VIDIOC_S_AUDIO: + { + struct v4l2_audio *sarg = arg; + + switch (sarg->index) { + case AUDIO_RADIO: + /* Hauppauge uses IN2 for the radio */ + msp->mode = MSP_MODE_FM_RADIO; + scart = SCART_IN2; + break; + case AUDIO_EXTERN_1: + /* IN1 is often used for external input ... */ + msp->mode = MSP_MODE_EXTERN; + scart = SCART_IN1; + break; + case AUDIO_EXTERN_2: + /* ... sometimes it is IN2 through ;) */ + msp->mode = MSP_MODE_EXTERN; + scart = SCART_IN2; + break; + case AUDIO_TUNER: + msp->mode = -1; + break; + } + if (scart) { + msp->rxsubchans = V4L2_TUNER_SUB_STEREO; + msp->audmode = V4L2_TUNER_MODE_STEREO; + msp3400c_set_scart(client,scart,0); + msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900); + } + if (sarg->capability==V4L2_AUDCAP_STEREO) { + msp->audmode = V4L2_TUNER_MODE_STEREO; + } else { + msp->audmode &= ~V4L2_TUNER_MODE_STEREO; + } + msp_any_set_audmode(client, msp->audmode); + msp_wake_thread(client); + break; + } + case VIDIOC_G_TUNER: + { + struct v4l2_tuner *vt = arg; + + msp_any_detect_stereo(client); + vt->audmode = msp->audmode; + vt->rxsubchans = msp->rxsubchans; + vt->capability = V4L2_TUNER_CAP_STEREO | + V4L2_TUNER_CAP_LANG1| + V4L2_TUNER_CAP_LANG2; + break; + } + case VIDIOC_S_TUNER: + { + struct v4l2_tuner *vt=(struct v4l2_tuner *)arg; + + /* only set audmode */ + if (vt->audmode != -1 && vt->audmode != 0) + msp_any_set_audmode(client, vt->audmode); + break; + } + + case VIDIOC_G_AUDOUT: + { + struct v4l2_audioout *a=(struct v4l2_audioout *)arg; + int idx=a->index; + + memset(a,0,sizeof(*a)); + + switch (idx) { + case 0: + strcpy(a->name,"Scart1 Out"); + break; + case 1: + strcpy(a->name,"Scart2 Out"); + break; + case 2: + strcpy(a->name,"I2S Out"); + break; + default: + return -EINVAL; + } + break; + + } + case VIDIOC_S_AUDOUT: + { + struct v4l2_audioout *a=(struct v4l2_audioout *)arg; + + if (a->index<0||a->index>2) + return -EINVAL; + + if (a->index==2) { + if (a->mode == V4L2_AUDMODE_32BITS) + msp->i2s_mode=1; + else + msp->i2s_mode=0; + } + msp3400_dbg("Setting audio out on msp34xx to input %i, mode %i\n", + a->index,msp->i2s_mode); + msp3400c_set_scart(client,msp->in_scart,a->index+1); + + break; + } + + default: + /* nothing */ + break; + } + return 0; +} + +static int msp_suspend(struct device * dev, pm_message_t state) +{ + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + + msp3400_dbg("msp34xx: suspend\n"); + msp3400c_reset(client); + return 0; +} + +static int msp_resume(struct device * dev) +{ + struct i2c_client *client = container_of(dev, struct i2c_client, dev); + + msp3400_dbg("msp34xx: resume\n"); + msp_wake_thread(client); + return 0; +} + +/* ----------------------------------------------------------------------- */ + +static int __init msp3400_init_module(void) +{ + return i2c_add_driver(&driver); +} + +static void __exit msp3400_cleanup_module(void) +{ + i2c_del_driver(&driver); +} + +module_init(msp3400_init_module); +module_exit(msp3400_cleanup_module); + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/trunk/drivers/media/video/msp3400.h b/trunk/drivers/media/video/msp3400.h index 8a05cf500a8c..2d9ff40f0b09 100644 --- a/trunk/drivers/media/video/msp3400.h +++ b/trunk/drivers/media/video/msp3400.h @@ -6,28 +6,22 @@ /* ---------------------------------------------------------------------- */ +struct msp_dfpreg { + int reg; + int value; +}; + struct msp_matrix { int input; int output; }; +#define MSP_SET_DFPREG _IOW('m',15,struct msp_dfpreg) +#define MSP_GET_DFPREG _IOW('m',16,struct msp_dfpreg) + /* ioctl for MSP_SET_MATRIX will have to be registered */ #define MSP_SET_MATRIX _IOW('m',17,struct msp_matrix) -/* This macro is allowed for *constants* only, gcc must calculate it - at compile time. Remember -- no floats in kernel mode */ -#define MSP_CARRIER(freq) ((int)((float)(freq / 18.432) * (1 << 24))) - -#define MSP_MODE_AM_DETECT 0 -#define MSP_MODE_FM_RADIO 2 -#define MSP_MODE_FM_TERRA 3 -#define MSP_MODE_FM_SAT 4 -#define MSP_MODE_FM_NICAM1 5 -#define MSP_MODE_FM_NICAM2 6 -#define MSP_MODE_AM_NICAM 7 -#define MSP_MODE_BTSC 8 -#define MSP_MODE_EXTERN 9 - #define SCART_MASK 0 #define SCART_IN1 1 #define SCART_IN2 2 @@ -42,84 +36,4 @@ struct msp_matrix { #define SCART1_OUT 1 #define SCART2_OUT 2 -#define OPMODE_AUTO -1 -#define OPMODE_MANUAL 0 -#define OPMODE_AUTODETECT 1 /* use autodetect (>= msp3410 only) */ -#define OPMODE_AUTOSELECT 2 /* use autodetect & autoselect (>= msp34xxG) */ - -/* module parameters */ -extern int debug; -extern int once; -extern int amsound; -extern int standard; -extern int dolby; -extern int stereo_threshold; - -struct msp_state { - int rev1, rev2; - u8 has_nicam; - u8 has_radio; - u8 has_headphones; - u8 has_ntsc_jp_d_k3; - u8 has_scart4; - u8 has_scart23_in_scart2_out; - u8 has_scart2_out_volume; - u8 has_i2s_conf; - u8 has_subwoofer; - u8 has_sound_processing; - u8 has_virtual_dolby_surround; - u8 has_dolby_pro_logic; - - int radio; - int opmode; - int std; - int mode; - v4l2_std_id v4l2_std; - int nicam_on; - int acb; - int in_scart; - int i2s_mode; - int main, second; /* sound carrier */ - int input; - int source; /* see msp34xxg_set_source */ - - /* v4l2 */ - int audmode; - int rxsubchans; - - int volume, muted; - int balance, loudness; - int bass, treble; - - /* thread */ - struct task_struct *kthread; - wait_queue_head_t wq; - int restart:1; - int watch_stereo:1; -}; - -/* msp3400-driver.c */ -int msp_write_dem(struct i2c_client *client, int addr, int val); -int msp_write_dsp(struct i2c_client *client, int addr, int val); -int msp_read_dem(struct i2c_client *client, int addr); -int msp_read_dsp(struct i2c_client *client, int addr); -int msp_reset(struct i2c_client *client); -void msp_set_scart(struct i2c_client *client, int in, int out); -void msp_set_mute(struct i2c_client *client); -void msp_set_audio(struct i2c_client *client); -int msp_modus(struct i2c_client *client); -int msp_sleep(struct msp_state *state, int timeout); - -/* msp3400-kthreads.c */ -const char *msp_standard_std_name(int std); -void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2); -void msp3400c_setmode(struct i2c_client *client, int type); -void msp3400c_setstereo(struct i2c_client *client, int mode); -int autodetect_stereo(struct i2c_client *client); -int msp3400c_thread(void *data); -int msp3410d_thread(void *data); -int msp34xxg_thread(void *data); -void msp34xxg_detect_stereo(struct i2c_client *client); -void msp34xxg_set_audmode(struct i2c_client *client, int audmode); - #endif /* MSP3400_H */ diff --git a/trunk/drivers/media/video/mt20xx.c b/trunk/drivers/media/video/mt20xx.c index 2c19c9588c02..2180018f06de 100644 --- a/trunk/drivers/media/video/mt20xx.c +++ b/trunk/drivers/media/video/mt20xx.c @@ -20,9 +20,6 @@ module_param(tv_antenna, int, 0644); static unsigned int radio_antenna = 0; module_param(radio_antenna, int, 0644); -/* from tuner-core.c */ -extern int debug; - /* ---------------------------------------------------------------------- */ #define MT2032 0x04 @@ -404,7 +401,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned div2a=(lo2/8)-1; div2b=lo2-(div2a+1)*8; - if (debug > 1) { + if (tuner_debug > 1) { tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2); tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n", num1,num2,div1a,div1b,div2a,div2b); @@ -420,7 +417,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned buf[5]=div2a; if(num2!=0) buf[5]=buf[5]|0x40; - if (debug > 1) { + if (tuner_debug > 1) { int i; tuner_dbg("bufs is: "); for(i=0;i<6;i++) @@ -497,18 +494,11 @@ int microtune_init(struct i2c_client *c) t->tv_freq = NULL; t->radio_freq = NULL; t->standby = NULL; - if (t->std & V4L2_STD_525_60) { - tuner_dbg("pinnacle ntsc\n"); - t->radio_if2 = 41300 * 1000; - } else { - tuner_dbg("pinnacle pal\n"); - t->radio_if2 = 33300 * 1000; - } name = "unknown"; i2c_master_send(c,buf,1); i2c_master_recv(c,buf,21); - if (debug) { + if (tuner_debug) { int i; tuner_dbg("MT20xx hexdump:"); for(i=0;i<21;i++) { diff --git a/trunk/drivers/media/video/mxb.c b/trunk/drivers/media/video/mxb.c index 91681aa6c657..d04793fb80fc 100644 --- a/trunk/drivers/media/video/mxb.c +++ b/trunk/drivers/media/video/mxb.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "mxb.h" #include "tea6415c.h" diff --git a/trunk/drivers/media/video/pms.c b/trunk/drivers/media/video/pms.c index 9e6448639480..2504207b2e3d 100644 --- a/trunk/drivers/media/video/pms.c +++ b/trunk/drivers/media/video/pms.c @@ -883,7 +883,6 @@ static struct file_operations pms_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = pms_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .read = pms_read, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/video/saa5249.c b/trunk/drivers/media/video/saa5249.c index 73b4f0e2abf0..a51c7bd96618 100644 --- a/trunk/drivers/media/video/saa5249.c +++ b/trunk/drivers/media/video/saa5249.c @@ -702,7 +702,6 @@ static struct file_operations saa_fops = { .open = saa5249_open, .release = saa5249_release, .ioctl = saa5249_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/video/saa6588.c b/trunk/drivers/media/video/saa6588.c index e70b17ef36e9..d60a783e0473 100644 --- a/trunk/drivers/media/video/saa6588.c +++ b/trunk/drivers/media/video/saa6588.c @@ -427,8 +427,18 @@ static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind) static int saa6588_probe(struct i2c_adapter *adap) { +#ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, saa6588_attach); +#else + switch (adap->id) { + case I2C_HW_B_BT848: + case I2C_HW_B_RIVA: + case I2C_HW_SAA7134: + return i2c_probe(adap, &addr_data, saa6588_attach); + break; + } +#endif return 0; } @@ -486,7 +496,7 @@ static int saa6588_command(struct i2c_client *client, unsigned int cmd, static struct i2c_driver driver = { .driver = { - .name = "saa6588", + .name = "i2c saa6588 driver", }, .id = -1, /* FIXME */ .attach_adapter = saa6588_probe, diff --git a/trunk/drivers/media/video/saa7115.c b/trunk/drivers/media/video/saa7115.c index 4a4bc69fb0e9..29e28c742cd4 100644 --- a/trunk/drivers/media/video/saa7115.c +++ b/trunk/drivers/media/video/saa7115.c @@ -39,18 +39,31 @@ #include #include #include -#include -#include MODULE_DESCRIPTION("Philips SAA7114/SAA7115 video decoder driver"); MODULE_AUTHOR("Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, Hans Verkuil"); MODULE_LICENSE("GPL"); static int debug = 0; -module_param(debug, bool, 0644); +module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Debug level (0-1)"); +#define saa7115_dbg(fmt,arg...) \ + do { \ + if (debug) \ + printk(KERN_INFO "%s debug %d-%04x: " fmt, \ + client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); \ + } while (0) + +#define saa7115_err(fmt, arg...) do { \ + printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) +#define saa7115_info(fmt, arg...) do { \ + printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) + static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END }; @@ -60,13 +73,12 @@ struct saa7115_state { v4l2_std_id std; int input; int enable; - int radio; int bright; int contrast; int hue; int sat; enum v4l2_chip_ident ident; - u32 audclk_freq; + enum v4l2_audio_clock_freq audclk_freq; }; /* ----------------------------------------------------------------------- */ @@ -457,6 +469,80 @@ static const unsigned char saa7115_init_misc[] = { 0x00, 0x00 }; +/* ============== SAA7715 AUDIO settings ============= */ + +/* 48.0 kHz */ +static const unsigned char saa7115_cfg_48_audio[] = { + 0x34, 0xce, + 0x35, 0xfb, + 0x36, 0x30, + 0x00, 0x00 +}; + +/* 44.1 kHz */ +static const unsigned char saa7115_cfg_441_audio[] = { + 0x34, 0xf2, + 0x35, 0x00, + 0x36, 0x2d, + 0x00, 0x00 +}; + +/* 32.0 kHz */ +static const unsigned char saa7115_cfg_32_audio[] = { + 0x34, 0xdf, + 0x35, 0xa7, + 0x36, 0x20, + 0x00, 0x00 +}; + +/* 48.0 kHz 60hz */ +static const unsigned char saa7115_cfg_60hz_48_audio[] = { + 0x30, 0xcd, + 0x31, 0x20, + 0x32, 0x03, + 0x00, 0x00 +}; + +/* 48.0 kHz 50hz */ +static const unsigned char saa7115_cfg_50hz_48_audio[] = { + 0x30, 0x00, + 0x31, 0xc0, + 0x32, 0x03, + 0x00, 0x00 +}; + +/* 44.1 kHz 60hz */ +static const unsigned char saa7115_cfg_60hz_441_audio[] = { + 0x30, 0xbc, + 0x31, 0xdf, + 0x32, 0x02, + 0x00, 0x00 +}; + +/* 44.1 kHz 50hz */ +static const unsigned char saa7115_cfg_50hz_441_audio[] = { + 0x30, 0x00, + 0x31, 0x72, + 0x32, 0x03, + 0x00, 0x00 +}; + +/* 32.0 kHz 60hz */ +static const unsigned char saa7115_cfg_60hz_32_audio[] = { + 0x30, 0xde, + 0x31, 0x15, + 0x32, 0x02, + 0x00, 0x00 +}; + +/* 32.0 kHz 50hz */ +static const unsigned char saa7115_cfg_50hz_32_audio[] = { + 0x30, 0x00, + 0x31, 0x80, + 0x32, 0x02, + 0x00, 0x00 +}; + static int saa7115_odd_parity(u8 c) { c ^= (c >> 4); @@ -541,38 +627,40 @@ static int saa7115_decode_wss(u8 * p) } -static int saa7115_set_audio_clock_freq(struct i2c_client *client, u32 freq) +static int saa7115_set_audio_clock_freq(struct i2c_client *client, enum v4l2_audio_clock_freq freq) { struct saa7115_state *state = i2c_get_clientdata(client); - u32 acpf; - u32 acni; - u32 hz; - u64 f; - - v4l_dbg(1, client, "set audio clock freq: %d\n", freq); - /* sanity check */ - if (freq < 32000 || freq > 48000) - return -EINVAL; - - /* hz is the refresh rate times 100 */ - hz = (state->std & V4L2_STD_525_60) ? 5994 : 5000; - /* acpf = (256 * freq) / field_frequency == (256 * 100 * freq) / hz */ - acpf = (25600 * freq) / hz; - /* acni = (256 * freq * 2^23) / crystal_frequency = - (freq * 2^(8+23)) / crystal_frequency = - (freq << 31) / 32.11 MHz */ - f = freq; - f = f << 31; - do_div(f, 32110000); - acni = f; - - saa7115_write(client, 0x30, acpf & 0xff); - saa7115_write(client, 0x31, (acpf >> 8) & 0xff); - saa7115_write(client, 0x32, (acpf >> 16) & 0x03); - saa7115_write(client, 0x34, acni & 0xff); - saa7115_write(client, 0x35, (acni >> 8) & 0xff); - saa7115_write(client, 0x36, (acni >> 16) & 0x3f); + saa7115_dbg("set audio clock freq: %d\n", freq); + switch (freq) { + case V4L2_AUDCLK_32_KHZ: + saa7115_writeregs(client, saa7115_cfg_32_audio); + if (state->std & V4L2_STD_525_60) { + saa7115_writeregs(client, saa7115_cfg_60hz_32_audio); + } else { + saa7115_writeregs(client, saa7115_cfg_50hz_32_audio); + } + break; + case V4L2_AUDCLK_441_KHZ: + saa7115_writeregs(client, saa7115_cfg_441_audio); + if (state->std & V4L2_STD_525_60) { + saa7115_writeregs(client, saa7115_cfg_60hz_441_audio); + } else { + saa7115_writeregs(client, saa7115_cfg_50hz_441_audio); + } + break; + case V4L2_AUDCLK_48_KHZ: + saa7115_writeregs(client, saa7115_cfg_48_audio); + if (state->std & V4L2_STD_525_60) { + saa7115_writeregs(client, saa7115_cfg_60hz_48_audio); + } else { + saa7115_writeregs(client, saa7115_cfg_50hz_48_audio); + } + break; + default: + saa7115_dbg("invalid audio setting %d\n", freq); + return -EINVAL; + } state->audclk_freq = freq; return 0; } @@ -584,7 +672,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: if (ctrl->value < 0 || ctrl->value > 255) { - v4l_err(client, "invalid brightness setting %d\n", ctrl->value); + saa7115_err("invalid brightness setting %d\n", ctrl->value); return -ERANGE; } @@ -594,7 +682,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c case V4L2_CID_CONTRAST: if (ctrl->value < 0 || ctrl->value > 127) { - v4l_err(client, "invalid contrast setting %d\n", ctrl->value); + saa7115_err("invalid contrast setting %d\n", ctrl->value); return -ERANGE; } @@ -604,7 +692,7 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c case V4L2_CID_SATURATION: if (ctrl->value < 0 || ctrl->value > 127) { - v4l_err(client, "invalid saturation setting %d\n", ctrl->value); + saa7115_err("invalid saturation setting %d\n", ctrl->value); return -ERANGE; } @@ -614,16 +702,13 @@ static int saa7115_set_v4lctrl(struct i2c_client *client, struct v4l2_control *c case V4L2_CID_HUE: if (ctrl->value < -127 || ctrl->value > 127) { - v4l_err(client, "invalid hue setting %d\n", ctrl->value); + saa7115_err("invalid hue setting %d\n", ctrl->value); return -ERANGE; } state->hue = ctrl->value; saa7115_write(client, 0x0d, state->hue); break; - - default: - return -EINVAL; } return 0; @@ -658,22 +743,12 @@ static void saa7115_set_v4lstd(struct i2c_client *client, v4l2_std_id std) struct saa7115_state *state = i2c_get_clientdata(client); int taskb = saa7115_read(client, 0x80) & 0x10; - /* Prevent unnecessary standard changes. During a standard - change the I-Port is temporarily disabled. Any devices - reading from that port can get confused. - Note that VIDIOC_S_STD is also used to switch from - radio to TV mode, so if a VIDIOC_S_STD is broadcast to - all I2C devices then you do not want to have an unwanted - side-effect here. */ - if (std == state->std) - return; - // This works for NTSC-M, SECAM-L and the 50Hz PAL variants. if (std & V4L2_STD_525_60) { - v4l_dbg(1, client, "decoder set standard 60 Hz\n"); + saa7115_dbg("decoder set standard 60 Hz\n"); saa7115_writeregs(client, saa7115_cfg_60hz_video); } else { - v4l_dbg(1, client, "decoder set standard 50 Hz\n"); + saa7115_dbg("decoder set standard 50 Hz\n"); saa7115_writeregs(client, saa7115_cfg_50hz_video); } @@ -698,17 +773,24 @@ static v4l2_std_id saa7115_get_v4lstd(struct i2c_client *client) static void saa7115_log_status(struct i2c_client *client) { struct saa7115_state *state = i2c_get_clientdata(client); + char *audfreq = "undefined"; int reg1e, reg1f; int signalOk; int vcr; - v4l_info(client, "Audio frequency: %d Hz\n", state->audclk_freq); + switch (state->audclk_freq) { + case V4L2_AUDCLK_32_KHZ: audfreq = "32 kHz"; break; + case V4L2_AUDCLK_441_KHZ: audfreq = "44.1 kHz"; break; + case V4L2_AUDCLK_48_KHZ: audfreq = "48 kHz"; break; + } + + saa7115_info("Audio frequency: %s\n", audfreq); if (client->name[6] == '4') { /* status for the saa7114 */ reg1f = saa7115_read(client, 0x1f); signalOk = (reg1f & 0xc1) == 0x81; - v4l_info(client, "Video signal: %s\n", signalOk ? "ok" : "bad"); - v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz"); + saa7115_info("Video signal: %s\n", signalOk ? "ok" : "bad"); + saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz"); return; } @@ -719,26 +801,21 @@ static void saa7115_log_status(struct i2c_client *client) signalOk = (reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80; vcr = !(reg1f & 0x10); - if (state->input >= 6) { - v4l_info(client, "Input: S-Video %d\n", state->input - 6); - } else { - v4l_info(client, "Input: Composite %d\n", state->input); - } - v4l_info(client, "Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad"); - v4l_info(client, "Frequency: %s\n", (reg1f & 0x20) ? "60 Hz" : "50 Hz"); + saa7115_info("Video signal: %s\n", signalOk ? (vcr ? "VCR" : "broadcast/DVD") : "bad"); + saa7115_info("Frequency: %s\n", (reg1f & 0x20) ? "60Hz" : "50Hz"); switch (reg1e & 0x03) { case 1: - v4l_info(client, "Detected format: NTSC\n"); + saa7115_info("Detected format: NTSC\n"); break; case 2: - v4l_info(client, "Detected format: PAL\n"); + saa7115_info("Detected format: PAL\n"); break; case 3: - v4l_info(client, "Detected format: SECAM\n"); + saa7115_info("Detected format: SECAM\n"); break; default: - v4l_info(client, "Detected format: BW/No color\n"); + saa7115_info("Detected format: BW/No color\n"); break; } } @@ -863,7 +940,7 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt pix = &(fmt->fmt.pix); - v4l_dbg(1, client, "decoder set size\n"); + saa7115_dbg("decoder set size\n"); /* FIXME need better bounds checking here */ if ((pix->width < 1) || (pix->width > 1440)) @@ -889,7 +966,7 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt HPSC = HPSC ? HPSC : 1; HFSC = (int)((1024 * 720) / (HPSC * pix->width)); - v4l_dbg(1, client, "Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC); + saa7115_dbg("Hpsc: 0x%05x, Hfsc: 0x%05x\n", HPSC, HFSC); /* FIXME hardcodes to "Task B" * write H prescaler integer */ saa7115_write(client, 0xd0, (u8) (HPSC & 0x3f)); @@ -903,10 +980,10 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt saa7115_write(client, 0xDD, (u8) ((HFSC >> 9) & 0xff)); } else { if (is_50hz) { - v4l_dbg(1, client, "Setting full 50hz width\n"); + saa7115_dbg("Setting full 50hz width\n"); saa7115_writeregs(client, saa7115_cfg_50hz_fullres_x); } else { - v4l_dbg(1, client, "Setting full 60hz width\n"); + saa7115_dbg("Setting full 60hz width\n"); saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); } } @@ -915,7 +992,7 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt if (pix->height != Vsrc) { VSCY = (int)((1024 * Vsrc) / pix->height); - v4l_dbg(1, client, "Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY); + saa7115_dbg("Vsrc: %d, Vscy: 0x%05x\n", Vsrc, VSCY); /* Correct Contrast and Luminance */ saa7115_write(client, 0xd5, (u8) (64 * 1024 / VSCY)); @@ -929,10 +1006,10 @@ static int saa7115_set_v4lfmt(struct i2c_client *client, struct v4l2_format *fmt saa7115_write(client, 0xe3, (u8) ((VSCY >> 8) & 0xff)); } else { if (is_50hz) { - v4l_dbg(1, client, "Setting full 50Hz height\n"); + saa7115_dbg("Setting full 50Hz height\n"); saa7115_writeregs(client, saa7115_cfg_50hz_fullres_y); } else { - v4l_dbg(1, client, "Setting full 60hz height\n"); + saa7115_dbg("Setting full 60hz height\n"); saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); } } @@ -1012,48 +1089,6 @@ static void saa7115_decode_vbi_line(struct i2c_client *client, /* ============ SAA7115 AUDIO settings (end) ============= */ -static struct v4l2_queryctrl saa7115_qctrl[] = { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 128, - .flags = 0, - }, { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 64, - .flags = 0, - }, { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 64, - .flags = 0, - }, { - .id = V4L2_CID_HUE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Hue", - .minimum = -128, - .maximum = 127, - .step = 1, - .default_value = 0, - .flags = 0, - }, -}; - -/* ----------------------------------------------------------------------- */ - static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct saa7115_state *state = i2c_get_clientdata(client); @@ -1068,18 +1103,16 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar return saa7115_get_v4lfmt(client, (struct v4l2_format *)arg); case VIDIOC_INT_AUDIO_CLOCK_FREQ: - return saa7115_set_audio_clock_freq(client, *(u32 *)arg); + return saa7115_set_audio_clock_freq(client, *(enum v4l2_audio_clock_freq *)arg); case VIDIOC_G_TUNER: { struct v4l2_tuner *vt = arg; int status; - if (state->radio) - break; status = saa7115_read(client, 0x1f); - v4l_dbg(1, client, "status: 0x%02x\n", status); + saa7115_dbg("status: 0x%02x\n", status); vt->signal = ((status & (1 << 6)) == 0) ? 0xffff : 0x0; break; } @@ -1094,38 +1127,20 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar case VIDIOC_S_CTRL: return saa7115_set_v4lctrl(client, (struct v4l2_control *)arg); - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *qc = arg; - int i; - - for (i = 0; i < ARRAY_SIZE(saa7115_qctrl); i++) - if (qc->id && qc->id == saa7115_qctrl[i].id) { - memcpy(qc, &saa7115_qctrl[i], sizeof(*qc)); - return 0; - } - return -EINVAL; - } - case VIDIOC_G_STD: *(v4l2_std_id *)arg = saa7115_get_v4lstd(client); break; case VIDIOC_S_STD: - state->radio = 0; saa7115_set_v4lstd(client, *(v4l2_std_id *)arg); break; - case AUDC_SET_RADIO: - state->radio = 1; - break; - case VIDIOC_G_INPUT: *(int *)arg = state->input; break; case VIDIOC_S_INPUT: - v4l_dbg(1, client, "decoder set input %d\n", *iarg); + saa7115_dbg("decoder set input %d\n", *iarg); /* inputs from 0-9 are available */ if (*iarg < 0 || *iarg > 9) { return -EINVAL; @@ -1133,7 +1148,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar if (state->input == *iarg) break; - v4l_dbg(1, client, "now setting %s input\n", + saa7115_dbg("now setting %s input\n", *iarg >= 6 ? "S-Video" : "Composite"); state->input = *iarg; @@ -1150,7 +1165,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar case VIDIOC_STREAMON: case VIDIOC_STREAMOFF: - v4l_dbg(1, client, "%s output\n", + saa7115_dbg("%s output\n", (cmd == VIDIOC_STREAMON) ? "enable" : "disable"); if (state->enable != (cmd == VIDIOC_STREAMON)) { @@ -1164,7 +1179,7 @@ static int saa7115_command(struct i2c_client *client, unsigned int cmd, void *ar break; case VIDIOC_INT_RESET: - v4l_dbg(1, client, "decoder RESET\n"); + saa7115_dbg("decoder RESET\n"); saa7115_writeregs(client, saa7115_cfg_reset_scaler); break; @@ -1258,19 +1273,19 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) client->driver = &i2c_driver_saa7115; snprintf(client->name, sizeof(client->name) - 1, "saa7115"); - v4l_dbg(1, client, "detecting saa7115 client on address 0x%x\n", address << 1); + saa7115_dbg("detecting saa7115 client on address 0x%x\n", address << 1); saa7115_write(client, 0, 5); chip_id = saa7115_read(client, 0) & 0x0f; if (chip_id != 4 && chip_id != 5) { - v4l_dbg(1, client, "saa7115 not found\n"); + saa7115_dbg("saa7115 not found\n"); kfree(client); return 0; } if (chip_id == 4) { snprintf(client->name, sizeof(client->name) - 1, "saa7114"); } - v4l_info(client, "saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name); + saa7115_info("saa711%d found @ 0x%x (%s)\n", chip_id, address << 1, adapter->name); state = kmalloc(sizeof(struct saa7115_state), GFP_KERNEL); i2c_set_clientdata(client, state); @@ -1282,15 +1297,14 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) state->std = V4L2_STD_NTSC; state->input = -1; state->enable = 1; - state->radio = 0; state->bright = 128; state->contrast = 64; state->hue = 0; state->sat = 64; state->ident = (chip_id == 4) ? V4L2_IDENT_SAA7114 : V4L2_IDENT_SAA7115; - state->audclk_freq = 48000; + state->audclk_freq = V4L2_AUDCLK_48_KHZ; - v4l_dbg(1, client, "writing init values\n"); + saa7115_dbg("writing init values\n"); /* init to 60hz/48khz */ saa7115_writeregs(client, saa7115_init_auto_input); @@ -1298,12 +1312,13 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) saa7115_writeregs(client, saa7115_cfg_60hz_fullres_x); saa7115_writeregs(client, saa7115_cfg_60hz_fullres_y); saa7115_writeregs(client, saa7115_cfg_60hz_video); - saa7115_set_audio_clock_freq(client, state->audclk_freq); + saa7115_writeregs(client, saa7115_cfg_48_audio); + saa7115_writeregs(client, saa7115_cfg_60hz_48_audio); saa7115_writeregs(client, saa7115_cfg_reset_scaler); i2c_attach_client(client); - v4l_dbg(1, client, "status: (1E) 0x%02x, (1F) 0x%02x\n", + saa7115_dbg("status: (1E) 0x%02x, (1F) 0x%02x\n", saa7115_read(client, 0x1e), saa7115_read(client, 0x1f)); return 0; @@ -1311,7 +1326,11 @@ static int saa7115_attach(struct i2c_adapter *adapter, int address, int kind) static int saa7115_probe(struct i2c_adapter *adapter) { +#ifdef I2C_CLASS_TV_ANALOG if (adapter->class & I2C_CLASS_TV_ANALOG) +#else + if (adapter->id == I2C_HW_B_BT848) +#endif return i2c_probe(adapter, &addr_data, &saa7115_attach); return 0; } diff --git a/trunk/drivers/media/video/saa711x.c b/trunk/drivers/media/video/saa711x.c index f39a7be08588..8008537391b5 100644 --- a/trunk/drivers/media/video/saa711x.c +++ b/trunk/drivers/media/video/saa711x.c @@ -567,7 +567,9 @@ static struct i2c_driver i2c_driver_saa711x = { .driver = { .name = "saa711x", }, + .id = I2C_DRIVERID_SAA711X, + .attach_adapter = saa711x_attach_adapter, .detach_client = saa711x_detach_client, .command = saa711x_command, diff --git a/trunk/drivers/media/video/saa7127.c b/trunk/drivers/media/video/saa7127.c index 2009c1bc4720..bca6ed0e2752 100644 --- a/trunk/drivers/media/video/saa7127.c +++ b/trunk/drivers/media/video/saa7127.c @@ -66,6 +66,30 @@ module_param(test_image, int, 0644); MODULE_PARM_DESC(debug, "debug level (0-2)"); MODULE_PARM_DESC(test_image, "test_image (0-1)"); +#define saa7127_dbg(fmt, arg...) \ + do { \ + if (debug >= 1) \ + printk(KERN_INFO "%s debug %d-%04x: " fmt, \ + client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); \ + } while (0) + +/* High volume debug. Use with care. */ +#define saa7127_dbg_highvol(fmt, arg...) \ + do { \ + if (debug == 2) \ + printk(KERN_INFO "%s debug %d-%04x: " fmt, \ + client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); \ + } while (0) + +#define saa7127_err(fmt, arg...) do { \ + printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) +#define saa7127_info(fmt, arg...) do { \ + printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) + static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END }; @@ -312,7 +336,7 @@ static int saa7127_write(struct i2c_client *client, u8 reg, u8 val) if (i2c_smbus_write_byte_data(client, reg, val) == 0) return 0; } - v4l_err(client, "I2C Write Problem\n"); + saa7127_err("I2C Write Problem\n"); return -1; } @@ -338,7 +362,7 @@ static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_dat if (enable && (data->field != 0 || data->line != 16)) return -EINVAL; if (state->vps_enable != enable) { - v4l_dbg(1, client, "Turn VPS Signal %s\n", enable ? "on" : "off"); + saa7127_dbg("Turn VPS Signal %s\n", enable ? "on" : "off"); saa7127_write(client, 0x54, enable << 7); state->vps_enable = enable; } @@ -350,7 +374,7 @@ static int saa7127_set_vps(struct i2c_client *client, struct v4l2_sliced_vbi_dat state->vps_data[2] = data->data[11]; state->vps_data[3] = data->data[12]; state->vps_data[4] = data->data[13]; - v4l_dbg(1, client, "Set VPS data %02x %02x %02x %02x %02x\n", + saa7127_dbg("Set VPS data %02x %02x %02x %02x %02x\n", state->vps_data[0], state->vps_data[1], state->vps_data[2], state->vps_data[3], state->vps_data[4]); @@ -373,7 +397,7 @@ static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data if (enable && (data->field != 0 || data->line != 21)) return -EINVAL; if (state->cc_enable != enable) { - v4l_dbg(1, client, "Turn CC %s\n", enable ? "on" : "off"); + saa7127_dbg("Turn CC %s\n", enable ? "on" : "off"); saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, (state->xds_enable << 7) | (enable << 6) | 0x11); state->cc_enable = enable; @@ -381,7 +405,7 @@ static int saa7127_set_cc(struct i2c_client *client, struct v4l2_sliced_vbi_data if (!enable) return 0; - v4l_dbg(2, client, "CC data: %04x\n", cc); + saa7127_dbg_highvol("CC data: %04x\n", cc); saa7127_write(client, SAA7127_REG_LINE_21_ODD_0, cc & 0xff); saa7127_write(client, SAA7127_REG_LINE_21_ODD_1, cc >> 8); state->cc_data = cc; @@ -399,7 +423,7 @@ static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_dat if (enable && (data->field != 1 || data->line != 21)) return -EINVAL; if (state->xds_enable != enable) { - v4l_dbg(1, client, "Turn XDS %s\n", enable ? "on" : "off"); + saa7127_dbg("Turn XDS %s\n", enable ? "on" : "off"); saa7127_write(client, SAA7127_REG_CLOSED_CAPTION, (enable << 7) | (state->cc_enable << 6) | 0x11); state->xds_enable = enable; @@ -407,7 +431,7 @@ static int saa7127_set_xds(struct i2c_client *client, struct v4l2_sliced_vbi_dat if (!enable) return 0; - v4l_dbg(2, client, "XDS data: %04x\n", xds); + saa7127_dbg_highvol("XDS data: %04x\n", xds); saa7127_write(client, SAA7127_REG_LINE_21_EVEN_0, xds & 0xff); saa7127_write(client, SAA7127_REG_LINE_21_EVEN_1, xds >> 8); state->xds_data = xds; @@ -424,7 +448,7 @@ static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_dat if (enable && (data->field != 0 || data->line != 23)) return -EINVAL; if (state->wss_enable != enable) { - v4l_dbg(1, client, "Turn WSS %s\n", enable ? "on" : "off"); + saa7127_dbg("Turn WSS %s\n", enable ? "on" : "off"); saa7127_write(client, 0x27, enable << 7); state->wss_enable = enable; } @@ -433,7 +457,7 @@ static int saa7127_set_wss(struct i2c_client *client, struct v4l2_sliced_vbi_dat saa7127_write(client, 0x26, data->data[0]); saa7127_write(client, 0x27, 0x80 | (data->data[1] & 0x3f)); - v4l_dbg(1, client, "WSS mode: %s\n", wss_strs[data->data[0] & 0xf]); + saa7127_dbg("WSS mode: %s\n", wss_strs[data->data[0] & 0xf]); state->wss_mode = (data->data[1] & 0x3f) << 8 | data->data[0]; return 0; } @@ -445,11 +469,11 @@ static int saa7127_set_video_enable(struct i2c_client *client, int enable) struct saa7127_state *state = i2c_get_clientdata(client); if (enable) { - v4l_dbg(1, client, "Enable Video Output\n"); + saa7127_dbg("Enable Video Output\n"); saa7127_write(client, 0x2d, state->reg_2d); saa7127_write(client, 0x61, state->reg_61); } else { - v4l_dbg(1, client, "Disable Video Output\n"); + saa7127_dbg("Disable Video Output\n"); saa7127_write(client, 0x2d, (state->reg_2d & 0xf0)); saa7127_write(client, 0x61, (state->reg_61 | 0xc0)); } @@ -465,11 +489,11 @@ static int saa7127_set_std(struct i2c_client *client, v4l2_std_id std) const struct i2c_reg_value *inittab; if (std & V4L2_STD_525_60) { - v4l_dbg(1, client, "Selecting 60 Hz video Standard\n"); + saa7127_dbg("Selecting 60 Hz video Standard\n"); inittab = saa7127_init_config_60hz; state->reg_61 = SAA7127_60HZ_DAC_CONTROL; } else { - v4l_dbg(1, client, "Selecting 50 Hz video Standard\n"); + saa7127_dbg("Selecting 50 Hz video Standard\n"); inittab = saa7127_init_config_50hz; state->reg_61 = SAA7127_50HZ_DAC_CONTROL; } @@ -520,7 +544,7 @@ static int saa7127_set_output_type(struct i2c_client *client, int output) default: return -EINVAL; } - v4l_dbg(1, client, "Selecting %s output type\n", output_strs[output]); + saa7127_dbg("Selecting %s output type\n", output_strs[output]); /* Configure Encoder */ saa7127_write(client, 0x2d, state->reg_2d); @@ -537,12 +561,12 @@ static int saa7127_set_input_type(struct i2c_client *client, int input) switch (input) { case SAA7127_INPUT_TYPE_NORMAL: /* avia */ - v4l_dbg(1, client, "Selecting Normal Encoder Input\n"); + saa7127_dbg("Selecting Normal Encoder Input\n"); state->reg_3a_cb = 0; break; case SAA7127_INPUT_TYPE_TEST_IMAGE: /* color bar */ - v4l_dbg(1, client, "Selecting Color Bar generator\n"); + saa7127_dbg("Selecting Color Bar generator\n"); state->reg_3a_cb = 0x80; break; @@ -609,14 +633,14 @@ static int saa7127_command(struct i2c_client *client, break; case VIDIOC_LOG_STATUS: - v4l_info(client, "Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz"); - v4l_info(client, "Input: %s\n", state->input_type ? "color bars" : "normal"); - v4l_info(client, "Output: %s\n", state->video_enable ? + saa7127_info("Standard: %s\n", (state->std & V4L2_STD_525_60) ? "60 Hz" : "50 Hz"); + saa7127_info("Input: %s\n", state->input_type ? "color bars" : "normal"); + saa7127_info("Output: %s\n", state->video_enable ? output_strs[state->output_type] : "disabled"); - v4l_info(client, "WSS: %s\n", state->wss_enable ? + saa7127_info("WSS: %s\n", state->wss_enable ? wss_strs[state->wss_mode] : "disabled"); - v4l_info(client, "VPS: %s\n", state->vps_enable ? "enabled" : "disabled"); - v4l_info(client, "CC: %s\n", state->cc_enable ? "enabled" : "disabled"); + saa7127_info("VPS: %s\n", state->vps_enable ? "enabled" : "disabled"); + saa7127_info("CC: %s\n", state->cc_enable ? "enabled" : "disabled"); break; #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -699,7 +723,7 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind) client->driver = &i2c_driver_saa7127; snprintf(client->name, sizeof(client->name) - 1, "saa7127"); - v4l_dbg(1, client, "detecting saa7127 client on address 0x%x\n", address << 1); + saa7127_dbg("detecting saa7127 client on address 0x%x\n", address << 1); /* First test register 0: Bits 5-7 are a version ID (should be 0), and bit 2 should also be 0. @@ -708,7 +732,7 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind) 0x1d after a reset and not expected to ever change. */ if ((saa7127_read(client, 0) & 0xe4) != 0 || (saa7127_read(client, 0x29) & 0x3f) != 0x1d) { - v4l_dbg(1, client, "saa7127 not found\n"); + saa7127_dbg("saa7127 not found\n"); kfree(client); return 0; } @@ -724,7 +748,7 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind) /* Configure Encoder */ - v4l_dbg(1, client, "Configuring encoder\n"); + saa7127_dbg("Configuring encoder\n"); saa7127_write_inittab(client, saa7127_init_config_common); saa7127_set_std(client, V4L2_STD_NTSC); saa7127_set_output_type(client, SAA7127_OUTPUT_TYPE_BOTH); @@ -745,12 +769,12 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind) read_result = saa7127_read(client, SAA7129_REG_FADE_KEY_COL2); saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, 0xaa); if (saa7127_read(client, SAA7129_REG_FADE_KEY_COL2) == 0xaa) { - v4l_info(client, "saa7129 found @ 0x%x (%s)\n", address << 1, adapter->name); + saa7127_info("saa7129 found @ 0x%x (%s)\n", address << 1, adapter->name); saa7127_write(client, SAA7129_REG_FADE_KEY_COL2, read_result); saa7127_write_inittab(client, saa7129_init_config_extra); state->ident = V4L2_IDENT_SAA7129; } else { - v4l_info(client, "saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name); + saa7127_info("saa7127 found @ 0x%x (%s)\n", address << 1, adapter->name); state->ident = V4L2_IDENT_SAA7127; } @@ -763,7 +787,11 @@ static int saa7127_attach(struct i2c_adapter *adapter, int address, int kind) static int saa7127_probe(struct i2c_adapter *adapter) { +#ifdef I2C_CLASS_TV_ANALOG if (adapter->class & I2C_CLASS_TV_ANALOG) +#else + if (adapter->id == I2C_HW_B_BT848) +#endif return i2c_probe(adapter, &addr_data, saa7127_attach); return 0; } diff --git a/trunk/drivers/media/video/saa7134/saa6752hs.c b/trunk/drivers/media/video/saa7134/saa6752hs.c index ad73c4a60f2b..4615a982ac64 100644 --- a/trunk/drivers/media/video/saa7134/saa6752hs.c +++ b/trunk/drivers/media/video/saa7134/saa6752hs.c @@ -9,8 +9,7 @@ #include #include #include -#include -#include +#include #include #include @@ -510,6 +509,7 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) { struct saa6752hs_state *h; + printk("saa6752hs: chip found @ 0x%x\n", addr<<1); if (NULL == (h = kmalloc(sizeof(*h), GFP_KERNEL))) return -ENOMEM; @@ -525,8 +525,6 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind) i2c_set_clientdata(&h->client, h); i2c_attach_client(&h->client); - v4l_info(&h->client,"saa6752hs: chip found @ 0x%x\n", addr<<1); - return 0; } @@ -600,7 +598,7 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) static struct i2c_driver driver = { .driver = { - .name = "saa6752hs", + .name = "i2c saa6752hs MPEG encoder", }, .id = I2C_DRIVERID_SAA6752HS, .attach_adapter = saa6752hs_probe, diff --git a/trunk/drivers/media/video/saa7134/saa7134-alsa.c b/trunk/drivers/media/video/saa7134/saa7134-alsa.c index a7a6ab9298a9..ade05f75fdb0 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-alsa.c +++ b/trunk/drivers/media/video/saa7134/saa7134-alsa.c @@ -20,13 +20,13 @@ * */ +#include #include #include #include #include #include #include -#include #include #include #include diff --git a/trunk/drivers/media/video/saa7134/saa7134-cards.c b/trunk/drivers/media/video/saa7134/saa7134-cards.c index 77e5be98e4c6..672fb205959f 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-cards.c +++ b/trunk/drivers/media/video/saa7134/saa7134-cards.c @@ -25,7 +25,6 @@ #include "saa7134-reg.h" #include "saa7134.h" -#include /* commly used strings */ static char name_mute[] = "mute"; @@ -2556,69 +2555,6 @@ struct saa7134_board saa7134_boards[] = { .amux = LINE1, }, }, - [SAA7134_BOARD_CINERGY250PCI] = { - /* remote-control does not work. The signal about a - key press comes in via gpio, but the key code - doesn't. Neither does it have an i2c remote control - interface. */ - .name = "Terratec Cinergy 250 PCI TV", - .audio_clock = 0x00187de7, - .tuner_type = TUNER_PHILIPS_TDA8290, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .gpiomask = 0x80200000, - .inputs = {{ - .name = name_tv, - .vmux = 1, - .amux = TV, - .tv = 1, - },{ - .name = name_svideo, /* NOT tested */ - .vmux = 8, - .amux = LINE1, - }}, - .radio = { - .name = name_radio, - .amux = LINE1, - .gpio = 0x0200000, - }, - }, - [SAA7134_BOARD_FLYDVB_TRIO] = { - /* LifeView LR319 FlyDVB Trio */ - /* Peter Missel */ - .name = "LifeView FlyDVB Trio", - .audio_clock = 0x00200000, - .tuner_type = TUNER_PHILIPS_TDA8290, - .radio_type = UNSET, - .tuner_addr = ADDR_UNSET, - .radio_addr = ADDR_UNSET, - .gpiomask = 0x00200000, - .inputs = {{ - .name = name_tv, /* Analog broadcast/cable TV */ - .vmux = 1, - .amux = TV, - .gpio = 0x200000, /* GPIO21=High for TV input */ - .tv = 1, - },{ - .name = name_svideo, /* S-Video signal on S-Video input */ - .vmux = 8, - .amux = LINE2, - },{ - .name = name_comp1, /* Composite signal on S-Video input */ - .vmux = 0, - .amux = LINE2, - },{ - .name = name_comp2, /* Composite input */ - .vmux = 3, - .amux = LINE2, - }}, - .radio = { - .name = name_radio, - .amux = TV, - .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */ - }, - }, }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -2955,12 +2891,6 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x1421, .subdevice = 0x0350, /* PCI version */ .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, - },{ - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, - .subvendor = 0x1421, - .subdevice = 0x0351, /* PCI version, new revision */ - .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7133, @@ -3071,18 +3001,6 @@ struct pci_device_id saa7134_pci_tbl[] = { .subvendor = 0x1462, .subdevice = 0x6231, .driver_data = SAA7134_BOARD_MSI_TVATANYWHERE_PLUS, - },{ - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, - .subvendor = 0x153b, - .subdevice = 0x1160, - .driver_data = SAA7134_BOARD_CINERGY250PCI, - },{ - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA 7131E */ - .subvendor = 0x5168, - .subdevice = 0x0319, - .driver_data = SAA7134_BOARD_FLYDVB_TRIO, },{ /* --- boards without eeprom + subsystem ID --- */ .vendor = PCI_VENDOR_ID_PHILIPS, @@ -3172,7 +3090,6 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_AVERMEDIA_GO_007_FM: /* case SAA7134_BOARD_SABRENT_SBTTVFM: */ /* not finished yet */ case SAA7134_BOARD_VIDEOMATE_TV_PVR: - case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: case SAA7134_BOARD_VIDEOMATE_DVBT_300: case SAA7134_BOARD_VIDEOMATE_DVBT_200: diff --git a/trunk/drivers/media/video/saa7134/saa7134-core.c b/trunk/drivers/media/video/saa7134/saa7134-core.c index accbc32725cf..23d8747338ed 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-core.c +++ b/trunk/drivers/media/video/saa7134/saa7134-core.c @@ -95,6 +95,77 @@ int (*dmasound_exit)(struct saa7134_dev *dev); #define dprintk(fmt, arg...) if (core_debug) \ printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg) +/* ------------------------------------------------------------------ */ +/* debug help functions */ + +static const char *v4l1_ioctls[] = { + "0", "GCAP", "GCHAN", "SCHAN", "GTUNER", "STUNER", "GPICT", "SPICT", + "CCAPTURE", "GWIN", "SWIN", "GFBUF", "SFBUF", "KEY", "GFREQ", + "SFREQ", "GAUDIO", "SAUDIO", "SYNC", "MCAPTURE", "GMBUF", "GUNIT", + "GCAPTURE", "SCAPTURE", "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", + "SMICROCODE", "GVBIFMT", "SVBIFMT" }; +#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) + +static const char *v4l2_ioctls[] = { + "QUERYCAP", "1", "ENUM_PIXFMT", "ENUM_FBUFFMT", "G_FMT", "S_FMT", + "G_COMP", "S_COMP", "REQBUFS", "QUERYBUF", "G_FBUF", "S_FBUF", + "G_WIN", "S_WIN", "PREVIEW", "QBUF", "16", "DQBUF", "STREAMON", + "STREAMOFF", "G_PERF", "G_PARM", "S_PARM", "G_STD", "S_STD", + "ENUMSTD", "ENUMINPUT", "G_CTRL", "S_CTRL", "G_TUNER", "S_TUNER", + "G_FREQ", "S_FREQ", "G_AUDIO", "S_AUDIO", "35", "QUERYCTRL", + "QUERYMENU", "G_INPUT", "S_INPUT", "ENUMCVT", "41", "42", "43", + "44", "45", "G_OUTPUT", "S_OUTPUT", "ENUMOUTPUT", "G_AUDOUT", + "S_AUDOUT", "ENUMFX", "G_EFFECT", "S_EFFECT", "G_MODULATOR", + "S_MODULATOR" +}; +#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) + +static const char *osspcm_ioctls[] = { + "RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT", + "CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS", + "GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER", + "GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO", + "SETDUPLEX", "GETODELAY" +}; +#define OSSPCM_IOCTLS ARRAY_SIZE(v4l2_ioctls) + +void saa7134_print_ioctl(char *name, unsigned int cmd) +{ + char *dir; + + switch (_IOC_DIR(cmd)) { + case _IOC_NONE: dir = "--"; break; + case _IOC_READ: dir = "r-"; break; + case _IOC_WRITE: dir = "-w"; break; + case _IOC_READ | _IOC_WRITE: dir = "rw"; break; + default: dir = "??"; break; + } + switch (_IOC_TYPE(cmd)) { + case 'v': + printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l1, %s, VIDIOC%s)\n", + name, cmd, dir, (_IOC_NR(cmd) < V4L1_IOCTLS) ? + v4l1_ioctls[_IOC_NR(cmd)] : "???"); + break; + case 'V': + printk(KERN_DEBUG "%s: ioctl 0x%08x (v4l2, %s, VIDIOC_%s)\n", + name, cmd, dir, (_IOC_NR(cmd) < V4L2_IOCTLS) ? + v4l2_ioctls[_IOC_NR(cmd)] : "???"); + break; + case 'P': + printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n", + name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ? + osspcm_ioctls[_IOC_NR(cmd)] : "???"); + break; + case 'M': + printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n", + name, cmd, dir, _IOC_NR(cmd)); + break; + default: + printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n", + name, cmd, dir, _IOC_NR(cmd)); + } +} + void saa7134_track_gpio(struct saa7134_dev *dev, char *msg) { unsigned long mode,status; @@ -140,7 +211,7 @@ static int pending_call(struct notifier_block *self, unsigned long state, return NOTIFY_DONE; } -static int pending_registered=0; +static int pending_registered; static struct notifier_block pending_notifier = { .notifier_call = pending_call, }; @@ -539,38 +610,11 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) card_has_mpeg(dev)) saa7134_irq_ts_done(dev,status); - if (report & SAA7134_IRQ_REPORT_GPIO16) { - switch (dev->has_remote) { - case SAA7134_REMOTE_GPIO: - if (dev->remote->mask_keydown & 0x10000) { - saa7134_input_irq(dev); - } - break; - - case SAA7134_REMOTE_I2C: - break; /* FIXME: invoke I2C get_key() */ + if ((report & (SAA7134_IRQ_REPORT_GPIO16 | + SAA7134_IRQ_REPORT_GPIO18)) && + dev->remote) + saa7134_input_irq(dev); - default: /* GPIO16 not used by IR remote */ - break; - } - } - - if (report & SAA7134_IRQ_REPORT_GPIO18) { - switch (dev->has_remote) { - case SAA7134_REMOTE_GPIO: - if ((dev->remote->mask_keydown & 0x40000) || - (dev->remote->mask_keyup & 0x40000)) { - saa7134_input_irq(dev); - } - break; - - case SAA7134_REMOTE_I2C: - break; /* FIXME: invoke I2C get_key() */ - - default: /* GPIO18 not used by IR remote */ - break; - } - } } if (10 == loop) { @@ -580,16 +624,13 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) printk(KERN_WARNING "%s/irq: looping -- " "clearing PE (parity error!) enable bit\n",dev->name); saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE); - } else if (report & SAA7134_IRQ_REPORT_GPIO16) { - /* disable gpio16 IRQ */ + } else if (report & (SAA7134_IRQ_REPORT_GPIO16 | + SAA7134_IRQ_REPORT_GPIO18)) { + /* disable gpio IRQs */ printk(KERN_WARNING "%s/irq: looping -- " - "clearing GPIO16 enable bit\n",dev->name); - saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO16); - } else if (report & SAA7134_IRQ_REPORT_GPIO18) { - /* disable gpio18 IRQs */ - printk(KERN_WARNING "%s/irq: looping -- " - "clearing GPIO18 enable bit\n",dev->name); - saa_clearl(SAA7134_IRQ2, SAA7134_IRQ2_INTE_GPIO18); + "clearing GPIO enable bits\n",dev->name); + saa_clearl(SAA7134_IRQ2, (SAA7134_IRQ2_INTE_GPIO16 | + SAA7134_IRQ2_INTE_GPIO18)); } else { /* disable all irqs */ printk(KERN_WARNING "%s/irq: looping -- " @@ -670,14 +711,10 @@ static int saa7134_hwinit2(struct saa7134_dev *dev) SAA7134_IRQ2_INTE_PE | SAA7134_IRQ2_INTE_AR; - if (dev->has_remote == SAA7134_REMOTE_GPIO) { - if (dev->remote->mask_keydown & 0x10000) - irq2_mask |= SAA7134_IRQ2_INTE_GPIO16; - else if (dev->remote->mask_keydown & 0x40000) - irq2_mask |= SAA7134_IRQ2_INTE_GPIO18; - else if (dev->remote->mask_keyup & 0x40000) - irq2_mask |= SAA7134_IRQ2_INTE_GPIO18A; - } + if (dev->has_remote == SAA7134_REMOTE_GPIO) + irq2_mask |= (SAA7134_IRQ2_INTE_GPIO18 | + SAA7134_IRQ2_INTE_GPIO18A | + SAA7134_IRQ2_INTE_GPIO16 ); saa_writel(SAA7134_IRQ1, 0); saa_writel(SAA7134_IRQ2, irq2_mask); @@ -1119,7 +1156,7 @@ static int saa7134_init(void) printk(KERN_INFO "saa7130/34: snapshot date %04d-%02d-%02d\n", SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); #endif - return pci_register_driver(&saa7134_pci_driver); + return pci_module_init(&saa7134_pci_driver); } static void saa7134_fini(void) @@ -1136,6 +1173,7 @@ module_exit(saa7134_fini); /* ----------------------------------------------------------- */ +EXPORT_SYMBOL(saa7134_print_ioctl); EXPORT_SYMBOL(saa7134_i2c_call_clients); EXPORT_SYMBOL(saa7134_devlist); EXPORT_SYMBOL(saa7134_boards); diff --git a/trunk/drivers/media/video/saa7134/saa7134-dvb.c b/trunk/drivers/media/video/saa7134/saa7134-dvb.c index 399f9952596c..e016480c3468 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-dvb.c +++ b/trunk/drivers/media/video/saa7134/saa7134-dvb.c @@ -31,7 +31,6 @@ #include "saa7134-reg.h" #include "saa7134.h" -#include #ifdef HAVE_MT352 # include "mt352.h" diff --git a/trunk/drivers/media/video/saa7134/saa7134-empress.c b/trunk/drivers/media/video/saa7134/saa7134-empress.c index bd4c389d4c37..575f3e835f91 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-empress.c +++ b/trunk/drivers/media/video/saa7134/saa7134-empress.c @@ -29,7 +29,6 @@ #include "saa7134.h" #include -#include /* ------------------------------------------------------------------ */ @@ -164,7 +163,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file, struct saa7134_dev *dev = file->private_data; if (debug > 1) - v4l_print_ioctl(dev->name,cmd); + saa7134_print_ioctl(dev->name,cmd); switch (cmd) { case VIDIOC_QUERYCAP: { diff --git a/trunk/drivers/media/video/saa7134/saa7134-i2c.c b/trunk/drivers/media/video/saa7134/saa7134-i2c.c index 6162550c4136..1792d03d621d 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-i2c.c +++ b/trunk/drivers/media/video/saa7134/saa7134-i2c.c @@ -30,7 +30,6 @@ #include "saa7134-reg.h" #include "saa7134.h" -#include /* ----------------------------------------------------------- */ @@ -391,7 +390,9 @@ static struct i2c_algorithm saa7134_algo = { static struct i2c_adapter saa7134_adap_template = { .owner = THIS_MODULE, +#ifdef I2C_CLASS_TV_ANALOG .class = I2C_CLASS_TV_ANALOG, +#endif .name = "saa7134", .id = I2C_HW_SAA7134, .algo = &saa7134_algo, diff --git a/trunk/drivers/media/video/saa7134/saa7134-input.c b/trunk/drivers/media/video/saa7134/saa7134-input.c index 82d28cbf289f..ab75ca5ac356 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-input.c +++ b/trunk/drivers/media/video/saa7134/saa7134-input.c @@ -56,22 +56,22 @@ static IR_KEYTAB_TYPE flyvideo_codes[IR_KEYTAB_SIZE] = { [ 12 ] = KEY_KP8, [ 13 ] = KEY_KP9, - [ 14 ] = KEY_MODE, // Air/Cable + [ 14 ] = KEY_TUNER, // Air/Cable [ 17 ] = KEY_VIDEO, // Video [ 21 ] = KEY_AUDIO, // Audio - [ 0 ] = KEY_POWER, // Power - [ 24 ] = KEY_TUNER, // AV Source + [ 0 ] = KEY_POWER, // Pover [ 2 ] = KEY_ZOOM, // Fullscreen - [ 26 ] = KEY_LANGUAGE, // Stereo [ 27 ] = KEY_MUTE, // Mute - [ 20 ] = KEY_VOLUMEUP, // Volume + - [ 23 ] = KEY_VOLUMEDOWN, // Volume - + [ 20 ] = KEY_VOLUMEUP, + [ 23 ] = KEY_VOLUMEDOWN, [ 18 ] = KEY_CHANNELUP, // Channel + [ 19 ] = KEY_CHANNELDOWN, // Channel - - [ 6 ] = KEY_AGAIN, // Recall - [ 16 ] = KEY_ENTER, // Enter -}; + [ 6 ] = KEY_AGAIN, // Recal + [ 16 ] = KEY_KPENTER, // Enter + [ 26 ] = KEY_F22, // Stereo + [ 24 ] = KEY_EDIT, // AV Source +}; static IR_KEYTAB_TYPE cinergy_codes[IR_KEYTAB_SIZE] = { [ 0 ] = KEY_KP0, @@ -543,22 +543,12 @@ static int build_key(struct saa7134_dev *dev) dprintk("build_key gpio=0x%x mask=0x%x data=%d\n", gpio, ir->mask_keycode, data); - if (ir->polling) { - if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || - (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { - ir_input_keydown(ir->dev, &ir->ir, data, data); - } else { - ir_input_nokey(ir->dev, &ir->ir); - } - } - else { /* IRQ driven mode - handle key press and release in one go */ - if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || - (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { - ir_input_keydown(ir->dev, &ir->ir, data, data); - ir_input_nokey(ir->dev, &ir->ir); - } + if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) || + (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) { + ir_input_keydown(ir->dev, &ir->ir, data, data); + } else { + ir_input_nokey(ir->dev, &ir->ir); } - return 0; } @@ -696,7 +686,6 @@ int saa7134_input_init1(struct saa7134_dev *dev) polling = 50; // ms break; case SAA7134_BOARD_VIDEOMATE_TV_PVR: - case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: case SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII: ir_codes = videomate_tv_pvr_codes; mask_keycode = 0x00003F; diff --git a/trunk/drivers/media/video/saa7134/saa7134-oss.c b/trunk/drivers/media/video/saa7134/saa7134-oss.c index 7448e386a804..8badd2a9cb2f 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-oss.c +++ b/trunk/drivers/media/video/saa7134/saa7134-oss.c @@ -373,42 +373,6 @@ static ssize_t dsp_write(struct file *file, const char __user *buffer, return -EINVAL; } -static const char *osspcm_ioctls[] = { - "RESET", "SYNC", "SPEED", "STEREO", "GETBLKSIZE", "SETFMT", - "CHANNELS", "?", "POST", "SUBDIVIDE", "SETFRAGMENT", "GETFMTS", - "GETOSPACE", "GETISPACE", "NONBLOCK", "GETCAPS", "GET/SETTRIGGER", - "GETIPTR", "GETOPTR", "MAPINBUF", "MAPOUTBUF", "SETSYNCRO", - "SETDUPLEX", "GETODELAY" -}; -#define OSSPCM_IOCTLS ARRAY_SIZE(osspcm_ioctls) - -static void saa7134_oss_print_ioctl(char *name, unsigned int cmd) -{ - char *dir; - - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: dir = "--"; break; - case _IOC_READ: dir = "r-"; break; - case _IOC_WRITE: dir = "-w"; break; - case _IOC_READ | _IOC_WRITE: dir = "rw"; break; - default: dir = "??"; break; - } - switch (_IOC_TYPE(cmd)) { - case 'P': - printk(KERN_DEBUG "%s: ioctl 0x%08x (oss dsp, %s, SNDCTL_DSP_%s)\n", - name, cmd, dir, (_IOC_NR(cmd) < OSSPCM_IOCTLS) ? - osspcm_ioctls[_IOC_NR(cmd)] : "???"); - break; - case 'M': - printk(KERN_DEBUG "%s: ioctl 0x%08x (oss mixer, %s, #%d)\n", - name, cmd, dir, _IOC_NR(cmd)); - break; - default: - printk(KERN_DEBUG "%s: ioctl 0x%08x (???, %s, #%d)\n", - name, cmd, dir, _IOC_NR(cmd)); - } -} - static int dsp_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { @@ -418,7 +382,7 @@ static int dsp_ioctl(struct inode *inode, struct file *file, int val = 0; if (debug > 1) - saa7134_oss_print_ioctl(dev->name,cmd); + saa7134_print_ioctl(dev->name,cmd); switch (cmd) { case OSS_GETVERSION: return put_user(SOUND_VERSION, p); @@ -714,7 +678,7 @@ static int mixer_ioctl(struct inode *inode, struct file *file, int __user *p = argp; if (debug > 1) - saa7134_oss_print_ioctl(dev->name,cmd); + saa7134_print_ioctl(dev->name,cmd); switch (cmd) { case OSS_GETVERSION: return put_user(SOUND_VERSION, p); diff --git a/trunk/drivers/media/video/saa7134/saa7134-video.c b/trunk/drivers/media/video/saa7134/saa7134-video.c index adfa8fe49a11..45c852df13ed 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-video.c +++ b/trunk/drivers/media/video/saa7134/saa7134-video.c @@ -29,7 +29,6 @@ #include "saa7134-reg.h" #include "saa7134.h" -#include /* Include V4L1 specific functions. Should be removed soon */ #include @@ -1690,7 +1689,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, int err; if (video_debug > 1) - v4l_print_ioctl(dev->name,cmd); + saa7134_print_ioctl(dev->name,cmd); switch (cmd) { case VIDIOC_S_CTRL: @@ -2143,7 +2142,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, struct saa7134_dev *dev = fh->dev; if (video_debug > 1) - v4l_print_ioctl(dev->name,cmd); + saa7134_print_ioctl(dev->name,cmd); switch (cmd) { case VIDIOC_QUERYCAP: { @@ -2263,7 +2262,6 @@ static struct file_operations video_fops = .poll = video_poll, .mmap = video_mmap, .ioctl = video_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; @@ -2273,7 +2271,6 @@ static struct file_operations radio_fops = .open = video_open, .release = video_release, .ioctl = radio_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/video/saa7134/saa7134.h b/trunk/drivers/media/video/saa7134/saa7134.h index e70eae8d29bb..add49db1ad41 100644 --- a/trunk/drivers/media/video/saa7134/saa7134.h +++ b/trunk/drivers/media/video/saa7134/saa7134.h @@ -37,9 +37,6 @@ #include #include #include -#include -#include -#include #include #ifndef TRUE @@ -50,6 +47,10 @@ #endif #define UNSET (-1U) +#include +#include +#include + /* ----------------------------------------------------------- */ /* enums */ @@ -208,8 +209,6 @@ struct saa7134_format { #define SAA7134_BOARD_ASUSTEK_DIGIMATRIX_TV 80 #define SAA7134_BOARD_PHILIPS_TIGER 81 #define SAA7134_BOARD_MSI_TVATANYWHERE_PLUS 82 -#define SAA7134_BOARD_CINERGY250PCI 83 -#define SAA7134_BOARD_FLYDVB_TRIO 84 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 @@ -547,6 +546,7 @@ struct saa7134_dev { extern struct list_head saa7134_devlist; +void saa7134_print_ioctl(char *name, unsigned int cmd); void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); #define SAA7134_PGTABLE_SIZE 4096 diff --git a/trunk/drivers/media/video/stradis.c b/trunk/drivers/media/video/stradis.c index 6ee54a45411f..d4497dbae05c 100644 --- a/trunk/drivers/media/video/stradis.c +++ b/trunk/drivers/media/video/stradis.c @@ -1974,7 +1974,6 @@ static struct file_operations saa_fops = .open = saa_open, .release = saa_release, .ioctl = saa_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .read = saa_read, .llseek = no_llseek, .write = saa_write, diff --git a/trunk/drivers/media/video/tda7432.c b/trunk/drivers/media/video/tda7432.c index 99261f15e66e..549c9929f107 100644 --- a/trunk/drivers/media/video/tda7432.c +++ b/trunk/drivers/media/video/tda7432.c @@ -50,7 +50,6 @@ #include "bttv.h" #include -#include #ifndef VIDEO_AUDIO_BALANCE # define VIDEO_AUDIO_BALANCE 32 @@ -91,6 +90,9 @@ struct tda7432 { static struct i2c_driver driver; static struct i2c_client client_template; +#define dprintk if (debug) printk +#define d2printk if (debug > 1) printk + /* The TDA7432 is made by STS-Thompson * http://www.st.com * http://us.st.com/stonline/books/pdf/docs/4056.pdf @@ -227,12 +229,12 @@ static struct i2c_client client_template; static int tda7432_write(struct i2c_client *client, int subaddr, int val) { unsigned char buffer[2]; - v4l_dbg(2,client,"In tda7432_write\n"); - v4l_dbg(1,client,"Writing %d 0x%x\n", subaddr, val); + d2printk("tda7432: In tda7432_write\n"); + dprintk("tda7432: Writing %d 0x%x\n", subaddr, val); buffer[0] = subaddr; buffer[1] = val; if (2 != i2c_master_send(client,buffer,2)) { - v4l_err(client,"I/O error, trying (write %d 0x%x)\n", + printk(KERN_WARNING "tda7432: I/O error, trying (write %d 0x%x)\n", subaddr, val); return -1; } @@ -245,9 +247,9 @@ static int tda7432_set(struct i2c_client *client) { struct tda7432 *t = i2c_get_clientdata(client); unsigned char buf[16]; - v4l_dbg(2,client,"In tda7432_set\n"); + d2printk("tda7432: In tda7432_set\n"); - v4l_dbg(1,client, + dprintk(KERN_INFO "tda7432: 7432_set(0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x)\n", t->input,t->volume,t->bass,t->treble,t->lf,t->lr,t->rf,t->rr,t->loud); buf[0] = TDA7432_IN; @@ -261,7 +263,7 @@ static int tda7432_set(struct i2c_client *client) buf[8] = t->rr; buf[9] = t->loud; if (10 != i2c_master_send(client,buf,10)) { - v4l_err(client,"I/O error, trying tda7432_set\n"); + printk(KERN_WARNING "tda7432: I/O error, trying tda7432_set\n"); return -1; } @@ -271,7 +273,7 @@ static int tda7432_set(struct i2c_client *client) static void do_tda7432_init(struct i2c_client *client) { struct tda7432 *t = i2c_get_clientdata(client); - v4l_dbg(2,client,"In tda7432_init\n"); + d2printk("tda7432: In tda7432_init\n"); t->input = TDA7432_STEREO_IN | /* Main (stereo) input */ TDA7432_BASS_SYM | /* Symmetric bass cut */ @@ -299,6 +301,7 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind) { struct tda7432 *t; struct i2c_client *client; + d2printk("tda7432: In tda7432_attach\n"); t = kmalloc(sizeof *t,GFP_KERNEL); if (!t) @@ -312,16 +315,21 @@ static int tda7432_attach(struct i2c_adapter *adap, int addr, int kind) i2c_set_clientdata(client, t); do_tda7432_init(client); - i2c_attach_client(client); + printk(KERN_INFO "tda7432: init\n"); - v4l_info(client, "chip found @ 0x%x (%s)\n", addr << 1, adap->name); + i2c_attach_client(client); return 0; } static int tda7432_probe(struct i2c_adapter *adap) { +#ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tda7432_attach); +#else + if (adap->id == I2C_HW_B_BT848) + return i2c_probe(adap, &addr_data, tda7432_attach); +#endif return 0; } @@ -340,9 +348,7 @@ static int tda7432_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct tda7432 *t = i2c_get_clientdata(client); - v4l_dbg(2,client,"In tda7432_command\n"); - if (debug>1) - v4l_i2c_print_ioctl(client,cmd); + d2printk("tda7432: In tda7432_command\n"); switch (cmd) { /* --- v4l ioctls --- */ @@ -353,6 +359,7 @@ static int tda7432_command(struct i2c_client *client, case VIDIOCGAUDIO: { struct video_audio *va = arg; + dprintk("tda7432: VIDIOCGAUDIO\n"); va->flags |= VIDEO_AUDIO_VOLUME | VIDEO_AUDIO_BASS | @@ -407,6 +414,7 @@ static int tda7432_command(struct i2c_client *client, case VIDIOCSAUDIO: { struct video_audio *va = arg; + dprintk("tda7432: VIDEOCSAUDIO\n"); if(va->flags & VIDEO_AUDIO_VOLUME){ if(!maxvol){ /* max +20db */ @@ -482,6 +490,11 @@ static int tda7432_command(struct i2c_client *client, } /* end of VIDEOCSAUDIO case */ + default: /* Not VIDEOCGAUDIO or VIDEOCSAUDIO */ + + /* nothing */ + d2printk("tda7432: Default\n"); + } /* end of (cmd) switch */ return 0; @@ -489,7 +502,7 @@ static int tda7432_command(struct i2c_client *client, static struct i2c_driver driver = { .driver = { - .name = "tda7432", + .name = "i2c tda7432 driver", }, .id = I2C_DRIVERID_TDA7432, .attach_adapter = tda7432_probe, @@ -506,7 +519,7 @@ static struct i2c_client client_template = static int __init tda7432_init(void) { if ( (loudness < 0) || (loudness > 15) ) { - printk(KERN_ERR "loudness parameter must be between 0 and 15\n"); + printk(KERN_ERR "tda7432: loudness parameter must be between 0 and 15\n"); return -EINVAL; } diff --git a/trunk/drivers/media/video/tda8290.c b/trunk/drivers/media/video/tda8290.c index 2498b76df429..61d94ddaff41 100644 --- a/trunk/drivers/media/video/tda8290.c +++ b/trunk/drivers/media/video/tda8290.c @@ -398,8 +398,14 @@ static int tda8290_tune(struct i2c_client *c, u16 ifc, unsigned int freq) return 0; } + /*---------------------------------------------------------------------*/ +#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) +#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) +#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H) +#define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK) + static void set_audio(struct tuner *t) { char* mode; diff --git a/trunk/drivers/media/video/tda9875.c b/trunk/drivers/media/video/tda9875.c index 299393bf900a..9c3ecf7a0fed 100644 --- a/trunk/drivers/media/video/tda9875.c +++ b/trunk/drivers/media/video/tda9875.c @@ -257,8 +257,13 @@ static int tda9875_attach(struct i2c_adapter *adap, int addr, int kind) static int tda9875_probe(struct i2c_adapter *adap) { +#ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tda9875_attach); +#else + if (adap->id == I2C_HW_B_BT848) + return i2c_probe(adap, &addr_data, tda9875_attach); +#endif return 0; } @@ -368,7 +373,7 @@ static int tda9875_command(struct i2c_client *client, static struct i2c_driver driver = { .driver = { - .name = "tda9875", + .name = "i2c tda9875 driver", }, .id = I2C_DRIVERID_TDA9875, .attach_adapter = tda9875_probe, diff --git a/trunk/drivers/media/video/tda9887.c b/trunk/drivers/media/video/tda9887.c index 9cf47dc65579..7165a1b9625a 100644 --- a/trunk/drivers/media/video/tda9887.c +++ b/trunk/drivers/media/video/tda9887.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include @@ -57,6 +57,7 @@ struct tda9887 { v4l2_std_id std; enum tuner_mode mode; unsigned int config; + unsigned int pinnacle_id; unsigned int using_v4l2; unsigned int radio_mode; unsigned char data[4]; @@ -114,9 +115,6 @@ static struct i2c_client client_template; #define cAudioGain0 0x00 // bit c7 #define cAudioGain6 0x80 // bit c7 -#define cTopMask 0x1f // bit c0:4 -#define cTopPalSecamDefault 0x14 // bit c0:4 -#define cTopNtscRadioDefault 0x10 // bit c0:4 //// third reg (e) #define cAudioIF_4_5 0x00 // bit e0:1 @@ -148,15 +146,13 @@ static struct i2c_client client_template; static struct tvnorm tvnorms[] = { { - .std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N, - .name = "PAL-BGHN", + .std = V4L2_STD_PAL_BG, + .name = "PAL-BG", .b = ( cNegativeFmTV | cQSS ), .c = ( cDeemphasisON | - cDeemphasis50 | - cTopPalSecamDefault), - .e = ( cGating_36 | - cAudioIF_5_5 | + cDeemphasis50 ), + .e = ( cAudioIF_5_5 | cVideoIF_38_90 ), },{ .std = V4L2_STD_PAL_I, @@ -164,10 +160,8 @@ static struct tvnorm tvnorms[] = { .b = ( cNegativeFmTV | cQSS ), .c = ( cDeemphasisON | - cDeemphasis50 | - cTopPalSecamDefault), - .e = ( cGating_36 | - cAudioIF_6_0 | + cDeemphasis50 ), + .e = ( cAudioIF_6_0 | cVideoIF_38_90 ), },{ .std = V4L2_STD_PAL_DK, @@ -175,80 +169,52 @@ static struct tvnorm tvnorms[] = { .b = ( cNegativeFmTV | cQSS ), .c = ( cDeemphasisON | - cDeemphasis50 | - cTopPalSecamDefault), - .e = ( cGating_36 | - cAudioIF_6_5 | - cVideoIF_38_90 ), + cDeemphasis50 ), + .e = ( cAudioIF_6_5 | + cVideoIF_38_00 ), },{ - .std = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc, - .name = "PAL-M/Nc", + .std = V4L2_STD_PAL_M | V4L2_STD_PAL_N, + .name = "PAL-M/N", .b = ( cNegativeFmTV | cQSS ), .c = ( cDeemphasisON | - cDeemphasis75 | - cTopNtscRadioDefault), - .e = ( cGating_36 | - cAudioIF_4_5 | + cDeemphasis75 ), + .e = ( cAudioIF_4_5 | cVideoIF_45_75 ), - },{ - .std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, - .name = "SECAM-BGH", - .b = ( cPositiveAmTV | - cQSS ), - .c = ( cTopPalSecamDefault), - .e = ( cGating_36 | - cAudioIF_5_5 | - cVideoIF_38_90 ), },{ .std = V4L2_STD_SECAM_L, .name = "SECAM-L", .b = ( cPositiveAmTV | cQSS ), - .c = ( cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_6_5 | cVideoIF_38_90 ), - },{ - .std = V4L2_STD_SECAM_LC, - .name = "SECAM-L'", - .b = ( cOutputPort2Inactive | - cPositiveAmTV | - cQSS ), - .c = ( cTopPalSecamDefault), - .e = ( cGating_36 | - cAudioIF_6_5 | - cVideoIF_33_90 ), },{ .std = V4L2_STD_SECAM_DK, .name = "SECAM-DK", .b = ( cNegativeFmTV | cQSS ), .c = ( cDeemphasisON | - cDeemphasis50 | - cTopPalSecamDefault), - .e = ( cGating_36 | - cAudioIF_6_5 | - cVideoIF_38_90 ), + cDeemphasis50 ), + .e = ( cAudioIF_6_5 | + cVideoIF_38_00 ), },{ .std = V4L2_STD_NTSC_M, .name = "NTSC-M", .b = ( cNegativeFmTV | cQSS ), .c = ( cDeemphasisON | - cDeemphasis75 | - cTopNtscRadioDefault), + cDeemphasis75 ), .e = ( cGating_36 | cAudioIF_4_5 | cVideoIF_45_75 ), },{ .std = V4L2_STD_NTSC_M_JP, - .name = "NTSC-M-JP", + .name = "NTSC-JP", .b = ( cNegativeFmTV | cQSS ), .c = ( cDeemphasisON | - cDeemphasis50 | - cTopNtscRadioDefault), + cDeemphasis50 ), .e = ( cGating_36 | cAudioIF_4_5 | cVideoIF_58_75 ), @@ -260,10 +226,8 @@ static struct tvnorm radio_stereo = { .b = ( cFmRadio | cQSS ), .c = ( cDeemphasisOFF | - cAudioGain6 | - cTopNtscRadioDefault), - .e = ( cTunerGainLow | - cAudioIF_5_5 | + cAudioGain6 ), + .e = ( cAudioIF_5_5 | cRadioIF_38_90 ), }; @@ -272,10 +236,8 @@ static struct tvnorm radio_mono = { .b = ( cFmRadio | cQSS ), .c = ( cDeemphasisON | - cDeemphasis75 | - cTopNtscRadioDefault), - .e = ( cTunerGainLow | - cAudioIF_5_5 | + cDeemphasis50), + .e = ( cAudioIF_5_5 | cRadioIF_38_90 ), }; @@ -438,8 +400,7 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) static unsigned int port1 = UNSET; static unsigned int port2 = UNSET; static unsigned int qss = UNSET; -static unsigned int adjust = UNSET; - +static unsigned int adjust = 0x10; module_param(port1, int, 0644); module_param(port2, int, 0644); module_param(qss, int, 0644); @@ -467,10 +428,8 @@ static int tda9887_set_insmod(struct tda9887 *t, char *buf) buf[1] &= ~cQSS; } - if (adjust >= 0x00 && adjust < 0x20) { - buf[2] &= ~cTopMask; + if (adjust >= 0x00 && adjust < 0x20) buf[2] |= adjust; - } return 0; } @@ -506,10 +465,6 @@ static int tda9887_set_config(struct tda9887 *t, char *buf) break; } } - if (t->config & TDA9887_TOP_SET) { - buf[2] &= ~cTopMask; - buf[2] |= (t->config >> 8) & cTopMask; - } if ((t->config & TDA9887_INTERCARRIER_NTSC) && (t->std & V4L2_STD_NTSC)) buf[1] &= ~cQSS; return 0; @@ -517,13 +472,38 @@ static int tda9887_set_config(struct tda9887 *t, char *buf) /* ---------------------------------------------------------------------- */ -static char pal[] = "--"; -static char secam[] = "--"; -static char ntsc[] = "-"; +static int tda9887_set_pinnacle(struct tda9887 *t, char *buf) +{ + unsigned int bCarrierMode = UNSET; + + if (t->std & V4L2_STD_625_50) { + if ((1 == t->pinnacle_id) || (7 == t->pinnacle_id)) { + bCarrierMode = cIntercarrier; + } else { + bCarrierMode = cQSS; + } + } + if (t->std & V4L2_STD_525_60) { + if ((5 == t->pinnacle_id) || (6 == t->pinnacle_id)) { + bCarrierMode = cIntercarrier; + } else { + bCarrierMode = cQSS; + } + } + + if (bCarrierMode != UNSET) { + buf[1] &= ~0x04; + buf[1] |= bCarrierMode; + } + return 0; +} + +/* ---------------------------------------------------------------------- */ +static char pal[] = "-"; module_param_string(pal, pal, sizeof(pal), 0644); +static char secam[] = "-"; module_param_string(secam, secam, sizeof(secam), 0644); -module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); static int tda9887_fixup_std(struct tda9887 *t) { @@ -534,17 +514,8 @@ static int tda9887_fixup_std(struct tda9887 *t) case 'B': case 'g': case 'G': - case 'h': - case 'H': - case 'n': - case 'N': - if (pal[1] == 'c' || pal[1] == 'C') { - tda9887_dbg("insmod fixup: PAL => PAL-Nc\n"); - t->std = V4L2_STD_PAL_Nc; - } else { - tda9887_dbg("insmod fixup: PAL => PAL-BGHN\n"); - t->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N; - } + tda9887_dbg("insmod fixup: PAL => PAL-BG\n"); + t->std = V4L2_STD_PAL_BG; break; case 'i': case 'I': @@ -558,11 +529,6 @@ static int tda9887_fixup_std(struct tda9887 *t) tda9887_dbg("insmod fixup: PAL => PAL-DK\n"); t->std = V4L2_STD_PAL_DK; break; - case 'm': - case 'M': - tda9887_dbg("insmod fixup: PAL => PAL-M\n"); - t->std = V4L2_STD_PAL_M; - break; case '-': /* default parameter, do nothing */ break; @@ -573,15 +539,6 @@ static int tda9887_fixup_std(struct tda9887 *t) } if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { switch (secam[0]) { - case 'b': - case 'B': - case 'g': - case 'G': - case 'h': - case 'H': - tda9887_dbg("insmod fixup: SECAM => SECAM-BGH\n"); - t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; - break; case 'd': case 'D': case 'k': @@ -591,13 +548,8 @@ static int tda9887_fixup_std(struct tda9887 *t) break; case 'l': case 'L': - if (secam[1] == 'c' || secam[1] == 'C') { - tda9887_dbg("insmod fixup: SECAM => SECAM-L'\n"); - t->std = V4L2_STD_SECAM_LC; - } else { - tda9887_dbg("insmod fixup: SECAM => SECAM-L\n"); - t->std = V4L2_STD_SECAM_L; - } + tda9887_dbg("insmod fixup: SECAM => SECAM-L\n"); + t->std = V4L2_STD_SECAM_L; break; case '-': /* default parameter, do nothing */ @@ -607,26 +559,6 @@ static int tda9887_fixup_std(struct tda9887 *t) break; } } - if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { - switch (ntsc[0]) { - case 'm': - case 'M': - tda9887_dbg("insmod fixup: NTSC => NTSC-M\n"); - t->std = V4L2_STD_NTSC_M; - break; - case 'j': - case 'J': - tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); - t->std = V4L2_STD_NTSC_M_JP; - break; - case '-': - /* default parameter, do nothing */ - break; - default: - tda9887_info("ntsc= argument not recognised\n"); - break; - } - } return 0; } @@ -649,22 +581,12 @@ static int tda9887_configure(struct tda9887 *t) memset(t->data,0,sizeof(t->data)); tda9887_set_tvnorm(t,t->data); - /* A note on the port settings: - These settings tend to depend on the specifics of the board. - By default they are set to inactive (bit value 1) by this driver, - overwriting any changes made by the tvnorm. This means that it - is the responsibility of the module using the tda9887 to set - these values in case of changes in the tvnorm. - In many cases port 2 should be made active (0) when selecting - SECAM-L, and port 2 should remain inactive (1) for SECAM-L'. - - For the other standards the tda9887 application note says that - the ports should be set to active (0), but, again, that may - differ depending on the precise hardware configuration. - */ t->data[1] |= cOutputPort1Inactive; t->data[1] |= cOutputPort2Inactive; + if (UNSET != t->pinnacle_id) { + tda9887_set_pinnacle(t,t->data); + } tda9887_set_config(t,t->data); tda9887_set_insmod(t,t->data); @@ -672,6 +594,7 @@ static int tda9887_configure(struct tda9887 *t) t->data[1] |= cForcedMuteAudioON; } + tda9887_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1],t->data[2],t->data[3]); if (debug > 1) @@ -702,6 +625,7 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) t->client = client_template; t->std = 0; + t->pinnacle_id = UNSET; t->radio_mode = V4L2_TUNER_MODE_STEREO; tda9887_info("chip found @ 0x%x (%s)\n", addr<<1, adap->name); @@ -714,8 +638,18 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) static int tda9887_probe(struct i2c_adapter *adap) { +#ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tda9887_attach); +#else + switch (adap->id) { + case I2C_HW_B_BT848: + case I2C_HW_B_RIVA: + case I2C_HW_SAA7134: + return i2c_probe(adap, &addr_data, tda9887_attach); + break; + } +#endif return 0; } @@ -755,6 +689,14 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) tda9887_configure(t); break; } + case AUDC_CONFIG_PINNACLE: + { + int *i = arg; + + t->pinnacle_id = *i; + tda9887_configure(t); + break; + } case TDA9887_SET_CONFIG: { int *i = arg; @@ -845,7 +787,7 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg) } case VIDIOC_LOG_STATUS: { - tda9887_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n", t->data[1], t->data[2], t->data[3]); + tda9887_info("Data bytes: b=%02x c=%02x e=%02x\n", t->data[1], t->data[2], t->data[3]); break; } default: @@ -882,7 +824,7 @@ static struct i2c_driver driver = { .detach_client = tda9887_detach, .command = tda9887_command, .driver = { - .name = "tda9887", + .name = "i2c tda9887 driver", .suspend = tda9887_suspend, .resume = tda9887_resume, }, diff --git a/trunk/drivers/media/video/tea5767.c b/trunk/drivers/media/video/tea5767.c index 261b7a3c0417..a9375ef05de1 100644 --- a/trunk/drivers/media/video/tea5767.c +++ b/trunk/drivers/media/video/tea5767.c @@ -17,9 +17,6 @@ #define PREFIX "TEA5767 " -/* from tuner-core.c */ -extern int debug; - /*****************************************************************************/ /****************************** @@ -249,7 +246,7 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq) if (5 != (rc = i2c_master_send(c, buffer, 5))) tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); - if (debug) { + if (tuner_debug) { if (5 != (rc = i2c_master_recv(c, buffer, 5))) tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); else @@ -267,7 +264,7 @@ static int tea5767_signal(struct i2c_client *c) if (5 != (rc = i2c_master_recv(c, buffer, 5))) tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); - return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8); + return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << (13 - 4)); } static int tea5767_stereo(struct i2c_client *c) diff --git a/trunk/drivers/media/video/tuner-core.c b/trunk/drivers/media/video/tuner-core.c index 57bc585a6955..c13c7b95ef35 100644 --- a/trunk/drivers/media/video/tuner-core.c +++ b/trunk/drivers/media/video/tuner-core.c @@ -20,9 +20,10 @@ #include #include -#include #include +#include "msp3400.h" + #define UNSET (-1U) /* standard i2c insmod options */ @@ -37,30 +38,21 @@ I2C_CLIENT_INSMOD; /* insmod options used at init time => read/only */ static unsigned int addr = 0; +module_param(addr, int, 0444); + static unsigned int no_autodetect = 0; +module_param(no_autodetect, int, 0444); + static unsigned int show_i2c = 0; +module_param(show_i2c, int, 0444); /* insmod options used at runtime => read/write */ -static unsigned int tuner_debug = 0; -int debug = 0; +unsigned int tuner_debug = 0; +module_param(tuner_debug, int, 0644); static unsigned int tv_range[2] = { 44, 958 }; static unsigned int radio_range[2] = { 65, 108 }; -static char pal[] = "--"; -static char secam[] = "--"; -static char ntsc[] = "-"; - -module_param(addr, int, 0444); -module_param(no_autodetect, int, 0444); -module_param(show_i2c, int, 0444); -/* Note: tuner_debug is deprecated and will be removed in 2.6.17 */ -module_param(tuner_debug, int, 0444); -module_param(debug, int, 0644); - -module_param_string(pal, pal, sizeof(pal), 0644); -module_param_string(secam, secam, sizeof(secam), 0644); -module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); module_param_array(tv_range, int, NULL, 0644); module_param_array(radio_range, int, NULL, 0644); @@ -257,6 +249,11 @@ static inline int check_mode(struct tuner *t, char *cmd) return 0; } +static char pal[] = "-"; +module_param_string(pal, pal, sizeof(pal), 0644); +static char secam[] = "--"; +module_param_string(secam, secam, sizeof(secam), 0644); + /* get more precise norm info from insmod option */ static int tuner_fixup_std(struct tuner *t) { @@ -288,13 +285,8 @@ static int tuner_fixup_std(struct tuner *t) break; case 'N': case 'n': - if (pal[1] == 'c' || pal[1] == 'C') { - tuner_dbg("insmod fixup: PAL => PAL-Nc\n"); - t->std = V4L2_STD_PAL_Nc; - } else { - tuner_dbg ("insmod fixup: PAL => PAL-N\n"); - t->std = V4L2_STD_PAL_N; - } + tuner_dbg ("insmod fixup: PAL => PAL-N\n"); + t->std = V4L2_STD_PAL_N; break; case '-': /* default parameter, do nothing */ @@ -306,15 +298,6 @@ static int tuner_fixup_std(struct tuner *t) } if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { switch (secam[0]) { - case 'b': - case 'B': - case 'g': - case 'G': - case 'h': - case 'H': - tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n"); - t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; - break; case 'd': case 'D': case 'k': @@ -341,60 +324,9 @@ static int tuner_fixup_std(struct tuner *t) } } - if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { - switch (ntsc[0]) { - case 'm': - case 'M': - tuner_dbg("insmod fixup: NTSC => NTSC-M\n"); - t->std = V4L2_STD_NTSC_M; - break; - case 'j': - case 'J': - tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); - t->std = V4L2_STD_NTSC_M_JP; - break; - case '-': - /* default parameter, do nothing */ - break; - default: - tuner_info("ntsc= argument not recognised\n"); - break; - } - } return 0; } -static void tuner_status(struct i2c_client *client) -{ - struct tuner *t = i2c_get_clientdata(client); - unsigned long freq, freq_fraction; - const char *p; - - switch (t->mode) { - case V4L2_TUNER_RADIO: p = "radio"; break; - case V4L2_TUNER_ANALOG_TV: p = "analog TV"; break; - case V4L2_TUNER_DIGITAL_TV: p = "digital TV"; break; - default: p = "undefined"; break; - } - if (t->mode == V4L2_TUNER_RADIO) { - freq = t->freq / 16000; - freq_fraction = (t->freq % 16000) * 100 / 16000; - } else { - freq = t->freq / 16; - freq_fraction = (t->freq % 16) * 100 / 16; - } - tuner_info("Tuner mode: %s\n", p); - tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction); - tuner_info("Standard: 0x%08llx\n", t->std); - if (t->mode == V4L2_TUNER_RADIO) { - if (t->has_signal) { - tuner_info("Signal strength: %d\n", t->has_signal(client)); - } - if (t->is_stereo) { - tuner_info("Stereo: %s\n", t->is_stereo(client) ? "yes" : "no"); - } - } -} /* ---------------------------------------------------------------------- */ /* static var Used only in tuner_attach and tuner_probe */ @@ -420,11 +352,6 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) t->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */ t->audmode = V4L2_TUNER_MODE_STEREO; t->mode_mask = T_UNINITIALIZED; - if (tuner_debug) { - debug = tuner_debug; - printk(KERN_ERR "tuner: tuner_debug is deprecated and will be removed in 2.6.17.\n"); - printk(KERN_ERR "tuner: use the debug option instead.\n"); - } if (show_i2c) { unsigned char buffer[16]; @@ -551,9 +478,7 @@ static inline int check_v4l2(struct tuner *t) static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct tuner *t = i2c_get_clientdata(client); - - if (debug>1) - v4l_i2c_print_ioctl(&(t->i2c),cmd); + unsigned int *iarg = (int *)arg; switch (cmd) { /* --- configuration --- */ @@ -576,6 +501,18 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) t->standby (client); break; } + case AUDC_CONFIG_PINNACLE: + switch (*iarg) { + case 2: + tuner_dbg("pinnacle pal\n"); + t->radio_if2 = 33300 * 1000; + break; + case 3: + tuner_dbg("pinnacle ntsc\n"); + t->radio_if2 = 41300 * 1000; + break; + } + break; case VIDIOCSAUDIO: if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) return 0; @@ -585,6 +522,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) /* Should be implemented, since bttv calls it */ tuner_dbg("VIDIOCSAUDIO not implemented.\n"); + break; + case MSP_SET_MATRIX: + case TDA9887_SET_CONFIG: break; /* --- v4l ioctls --- */ /* take care: bttv does userspace copying, we'll get a @@ -768,8 +708,10 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) } break; } - case VIDIOC_LOG_STATUS: - tuner_status(client); + default: + tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp='%c',nr=%d,sz=%d)\n", + cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd), + _IOC_NR(cmd), _IOC_SIZE(cmd)); break; } @@ -805,10 +747,10 @@ static struct i2c_driver driver = { .detach_client = tuner_detach, .command = tuner_command, .driver = { - .name = "tuner", - .suspend = tuner_suspend, - .resume = tuner_resume, - }, + .name = "tuner", + .suspend = tuner_suspend, + .resume = tuner_resume, + }, }; static struct i2c_client client_template = { .name = "(tuner unset)", diff --git a/trunk/drivers/media/video/tuner-simple.c b/trunk/drivers/media/video/tuner-simple.c index e5fb74365836..e0c9fdb9914a 100644 --- a/trunk/drivers/media/video/tuner-simple.c +++ b/trunk/drivers/media/video/tuner-simple.c @@ -8,10 +8,6 @@ #include #include -static int offset = 0; -module_param(offset, int, 0666); -MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner"); - /* ---------------------------------------------------------------------- */ /* tv standard selection for Temic 4046 FM5 @@ -79,20 +75,24 @@ MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner"); #define TUNER_PLL_LOCKED 0x40 #define TUNER_STEREO_MK3 0x04 -#define TUNER_MAX_RANGES 3 - /* ---------------------------------------------------------------------- */ struct tunertype { char *name; - - int count; - struct { - unsigned short thresh; - unsigned char cb; - } ranges[TUNER_MAX_RANGES]; + unsigned char Vendor; + unsigned char Type; + + unsigned short thresh1; /* band switch VHF_LO <=> VHF_HI */ + unsigned short thresh2; /* band switch VHF_HI <=> UHF */ + unsigned char VHF_L; + unsigned char VHF_H; + unsigned char UHF; unsigned char config; + unsigned short IFPCoff; /* 622.4=16*38.90 MHz PAL, + 732 =16*45.75 NTSCi, + 940 =16*58.75 NTSC-Japan + 704 =16*44 ATSC */ }; /* @@ -102,696 +102,158 @@ struct tunertype */ static struct tunertype tuners[] = { /* 0-9 */ - [TUNER_TEMIC_PAL] = { /* TEMIC PAL */ - .name = "Temic PAL (4002 FH5)", - .count = 3, - .ranges = { - { 16 * 140.25 /*MHz*/, 0x02, }, - { 16 * 463.25 /*MHz*/, 0x04, }, - { 16 * 999.99 , 0x01, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */ - .name = "Philips PAL_I (FI1246 and compatibles)", - .count = 3, - .ranges = { - { 16 * 140.25 /*MHz*/, 0xa0, }, - { 16 * 463.25 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */ - .name = "Philips NTSC (FI1236,FM1236 and compatibles)", - .count = 3, - .ranges = { - { 16 * 157.25 /*MHz*/, 0xa0, }, - { 16 * 451.25 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */ - .name = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", - .count = 3, - .ranges = { - { 16 * 168.25 /*MHz*/, 0xa7, }, - { 16 * 447.25 /*MHz*/, 0x97, }, - { 16 * 999.99 , 0x37, }, - }, - .config = 0x8e, - }, - [TUNER_ABSENT] = { /* Tuner Absent */ - .name = "NoTuner", - .count = 1, - .ranges = { - { 0, 0x00, }, - }, - .config = 0x00, - }, - [TUNER_PHILIPS_PAL] = { /* Philips PAL */ - .name = "Philips PAL_BG (FI1216 and compatibles)", - .count = 3, - .ranges = { - { 16 * 168.25 /*MHz*/, 0xa0, }, - { 16 * 447.25 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */ - .name = "Temic NTSC (4032 FY5)", - .count = 3, - .ranges = { - { 16 * 157.25 /*MHz*/, 0x02, }, - { 16 * 463.25 /*MHz*/, 0x04, }, - { 16 * 999.99 , 0x01, }, - }, - .config = 0x8e, - }, - [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */ - .name = "Temic PAL_I (4062 FY5)", - .count = 3, - .ranges = { - { 16 * 170.00 /*MHz*/, 0x02, }, - { 16 * 450.00 /*MHz*/, 0x04, }, - { 16 * 999.99 , 0x01, }, - }, - .config = 0x8e, - }, - [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */ - .name = "Temic NTSC (4036 FY5)", - .count = 3, - .ranges = { - { 16 * 157.25 /*MHz*/, 0xa0, }, - { 16 * 463.25 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */ - .name = "Alps HSBH1", - .count = 3, - .ranges = { - { 16 * 137.25 /*MHz*/, 0x01, }, - { 16 * 385.25 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0x8e, - }, + { "Temic PAL (4002 FH5)", TEMIC, PAL, + 16*140.25,16*463.25,0x02,0x04,0x01,0x8e,623}, + { "Philips PAL_I (FI1246 and compatibles)", Philips, PAL_I, + 16*140.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, + { "Philips NTSC (FI1236,FM1236 and compatibles)", Philips, NTSC, + 16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,732}, + { "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)", Philips, SECAM, + 16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,623}, + { "NoTuner", NoTuner, NOTUNER, + 0,0,0x00,0x00,0x00,0x00,0x00}, + { "Philips PAL_BG (FI1216 and compatibles)", Philips, PAL, + 16*168.25,16*447.25,0xA0,0x90,0x30,0x8e,623}, + { "Temic NTSC (4032 FY5)", TEMIC, NTSC, + 16*157.25,16*463.25,0x02,0x04,0x01,0x8e,732}, + { "Temic PAL_I (4062 FY5)", TEMIC, PAL_I, + 16*170.00,16*450.00,0x02,0x04,0x01,0x8e,623}, + { "Temic NTSC (4036 FY5)", TEMIC, NTSC, + 16*157.25,16*463.25,0xa0,0x90,0x30,0x8e,732}, + { "Alps HSBH1", TEMIC, NTSC, + 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, /* 10-19 */ - [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */ - .name = "Alps TSBE1", - .count = 3, - .ranges = { - { 16 * 137.25 /*MHz*/, 0x01, }, - { 16 * 385.25 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0x8e, - }, - [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */ - .name = "Alps TSBB5", - .count = 3, - .ranges = { - { 16 * 133.25 /*MHz*/, 0x01, }, - { 16 * 351.25 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0x8e, - }, - [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */ - .name = "Alps TSBE5", - .count = 3, - .ranges = { - { 16 * 133.25 /*MHz*/, 0x01, }, - { 16 * 351.25 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0x8e, - }, - [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */ - .name = "Alps TSBC5", - .count = 3, - .ranges = { - { 16 * 133.25 /*MHz*/, 0x01, }, - { 16 * 351.25 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0x8e, - }, - [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */ - .name = "Temic PAL_BG (4006FH5)", - .count = 3, - .ranges = { - { 16 * 170.00 /*MHz*/, 0xa0, }, - { 16 * 450.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */ - .name = "Alps TSCH6", - .count = 3, - .ranges = { - { 16 * 137.25 /*MHz*/, 0x14, }, - { 16 * 385.25 /*MHz*/, 0x12, }, - { 16 * 999.99 , 0x11, }, - }, - .config = 0x8e, - }, - [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */ - .name = "Temic PAL_DK (4016 FY5)", - .count = 3, - .ranges = { - { 16 * 168.25 /*MHz*/, 0xa0, }, - { 16 * 456.25 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */ - .name = "Philips NTSC_M (MK2)", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0xa0, }, - { 16 * 454.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */ - .name = "Temic PAL_I (4066 FY5)", - .count = 3, - .ranges = { - { 16 * 169.00 /*MHz*/, 0xa0, }, - { 16 * 454.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */ - .name = "Temic PAL* auto (4006 FN5)", - .count = 3, - .ranges = { - { 16 * 169.00 /*MHz*/, 0xa0, }, - { 16 * 454.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, + { "Alps TSBE1", TEMIC, PAL, + 16*137.25,16*385.25,0x01,0x02,0x08,0x8e,732}, + { "Alps TSBB5", Alps, PAL_I, /* tested (UK UHF) with Modulartech MM205 */ + 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,632}, + { "Alps TSBE5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ + 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,622}, + { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */ + 16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608}, + { "Temic PAL_BG (4006FH5)", TEMIC, PAL, + 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, + { "Alps TSCH6", Alps, NTSC, + 16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732}, + { "Temic PAL_DK (4016 FY5)", TEMIC, PAL, + 16*168.25,16*456.25,0xa0,0x90,0x30,0x8e,623}, + { "Philips NTSC_M (MK2)", Philips, NTSC, + 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, + { "Temic PAL_I (4066 FY5)", TEMIC, PAL_I, + 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, + { "Temic PAL* auto (4006 FN5)", TEMIC, PAL, + 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, /* 20-29 */ - [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */ - .name = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", - .count = 3, - .ranges = { - { 16 * 141.00 /*MHz*/, 0xa0, }, - { 16 * 464.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */ - .name = "Temic NTSC (4039 FR5)", - .count = 3, - .ranges = { - { 16 * 158.00 /*MHz*/, 0xa0, }, - { 16 * 453.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */ - .name = "Temic PAL/SECAM multi (4046 FM5)", - .count = 3, - .ranges = { - { 16 * 169.00 /*MHz*/, 0xa0, }, - { 16 * 454.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */ - .name = "Philips PAL_DK (FI1256 and compatibles)", - .count = 3, - .ranges = { - { 16 * 170.00 /*MHz*/, 0xa0, }, - { 16 * 450.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */ - .name = "Philips PAL/SECAM multi (FQ1216ME)", - .count = 3, - .ranges = { - { 16 * 170.00 /*MHz*/, 0xa0, }, - { 16 * 450.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */ - .name = "LG PAL_I+FM (TAPC-I001D)", - .count = 3, - .ranges = { - { 16 * 170.00 /*MHz*/, 0xa0, }, - { 16 * 450.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */ - .name = "LG PAL_I (TAPC-I701D)", - .count = 3, - .ranges = { - { 16 * 170.00 /*MHz*/, 0xa0, }, - { 16 * 450.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */ - .name = "LG NTSC+FM (TPI8NSR01F)", - .count = 3, - .ranges = { - { 16 * 210.00 /*MHz*/, 0xa0, }, - { 16 * 497.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */ - .name = "LG PAL_BG+FM (TPI8PSB01D)", - .count = 3, - .ranges = { - { 16 * 170.00 /*MHz*/, 0xa0, }, - { 16 * 450.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_LG_PAL] = { /* LGINNOTEK PAL */ - .name = "LG PAL_BG (TPI8PSB11D)", - .count = 3, - .ranges = { - { 16 * 170.00 /*MHz*/, 0xa0, }, - { 16 * 450.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, + { "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)", TEMIC, PAL, + 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, + { "Temic NTSC (4039 FR5)", TEMIC, NTSC, + 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, + { "Temic PAL/SECAM multi (4046 FM5)", TEMIC, PAL, + 16*169.00, 16*454.00, 0xa0,0x90,0x30,0x8e,623}, + { "Philips PAL_DK (FI1256 and compatibles)", Philips, PAL, + 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, + { "Philips PAL/SECAM multi (FQ1216ME)", Philips, PAL, + 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, + { "LG PAL_I+FM (TAPC-I001D)", LGINNOTEK, PAL_I, + 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, + { "LG PAL_I (TAPC-I701D)", LGINNOTEK, PAL_I, + 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, + { "LG NTSC+FM (TPI8NSR01F)", LGINNOTEK, NTSC, + 16*210.00,16*497.00,0xa0,0x90,0x30,0x8e,732}, + { "LG PAL_BG+FM (TPI8PSB01D)", LGINNOTEK, PAL, + 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, + { "LG PAL_BG (TPI8PSB11D)", LGINNOTEK, PAL, + 16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, /* 30-39 */ - [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */ - .name = "Temic PAL* auto + FM (4009 FN5)", - .count = 3, - .ranges = { - { 16 * 141.00 /*MHz*/, 0xa0, }, - { 16 * 464.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */ - .name = "SHARP NTSC_JP (2U5JF5540)", - .count = 3, - .ranges = { - { 16 * 137.25 /*MHz*/, 0x01, }, - { 16 * 317.25 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0x8e, - }, - [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */ - .name = "Samsung PAL TCPM9091PD27", - .count = 3, - .ranges = { - { 16 * 169 /*MHz*/, 0xa0, }, - { 16 * 464 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_MT2032] = { /* Microtune PAL|NTSC */ - .name = "MT20xx universal", + { "Temic PAL* auto + FM (4009 FN5)", TEMIC, PAL, + 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, + { "SHARP NTSC_JP (2U5JF5540)", SHARP, NTSC, /* 940=16*58.75 NTSC@Japan */ + 16*137.25,16*317.25,0x01,0x02,0x08,0x8e,940 }, + { "Samsung PAL TCPM9091PD27", Samsung, PAL, /* from sourceforge v3tv */ + 16*169,16*464,0xA0,0x90,0x30,0x8e,623}, + { "MT20xx universal", Microtune, PAL|NTSC, /* see mt20xx.c for details */ }, - [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */ - .name = "Temic PAL_BG (4106 FH5)", - .count = 3, - .ranges = { - { 16 * 141.00 /*MHz*/, 0xa0, }, - { 16 * 464.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */ - .name = "Temic PAL_DK/SECAM_L (4012 FY5)", - .count = 3, - .ranges = { - { 16 * 140.25 /*MHz*/, 0x02, }, - { 16 * 463.25 /*MHz*/, 0x04, }, - { 16 * 999.99 , 0x01, }, - }, - .config = 0x8e, - }, - [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */ - .name = "Temic NTSC (4136 FY5)", - .count = 3, - .ranges = { - { 16 * 158.00 /*MHz*/, 0xa0, }, - { 16 * 453.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */ - .name = "LG PAL (newer TAPC series)", - .count = 3, - .ranges = { - { 16 * 170.00 /*MHz*/, 0x01, }, - { 16 * 450.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */ - .name = "Philips PAL/SECAM multi (FM1216ME MK3)", - .count = 3, - .ranges = { - { 16 * 158.00 /*MHz*/, 0x01, }, - { 16 * 442.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x04, }, - }, - .config = 0x8e, - }, - [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */ - .name = "LG NTSC (newer TAPC series)", - .count = 3, - .ranges = { - { 16 * 170.00 /*MHz*/, 0x01, }, - { 16 * 450.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0x8e, - }, + { "Temic PAL_BG (4106 FH5)", TEMIC, PAL, + 16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623}, + { "Temic PAL_DK/SECAM_L (4012 FY5)", TEMIC, PAL, + 16*140.25, 16*463.25, 0x02,0x04,0x01,0x8e,623}, + { "Temic NTSC (4136 FY5)", TEMIC, NTSC, + 16*158.00, 16*453.00, 0xa0,0x90,0x30,0x8e,732}, + { "LG PAL (newer TAPC series)", LGINNOTEK, PAL, + 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,623}, + { "Philips PAL/SECAM multi (FM1216ME MK3)", Philips, PAL, + 16*158.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, + { "LG NTSC (newer TAPC series)", LGINNOTEK, NTSC, + 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,732}, /* 40-49 */ - [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */ - .name = "HITACHI V7-J180AT", - .count = 3, - .ranges = { - { 16 * 170.00 /*MHz*/, 0x01, }, - { 16 * 450.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */ - .name = "Philips PAL_MK (FI1216 MK)", - .count = 3, - .ranges = { - { 16 * 140.25 /*MHz*/, 0x01, }, - { 16 * 463.25 /*MHz*/, 0xc2, }, - { 16 * 999.99 , 0xcf, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_ATSC] = { /* Philips ATSC */ - .name = "Philips 1236D ATSC/NTSC dual in", - .count = 3, - .ranges = { - { 16 * 157.25 /*MHz*/, 0xa0, }, - { 16 * 454.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */ - .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0x01, }, - { 16 * 442.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x04, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */ - .name = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0x01, }, - { 16 * 442.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x04, }, - }, - .config = 0x8e, - }, - [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */ - .name = "Microtune 4049 FM5", - .count = 3, - .ranges = { - { 16 * 141.00 /*MHz*/, 0xa0, }, - { 16 * 464.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */ - .name = "Panasonic VP27s/ENGE4324D", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0x01, }, - { 16 * 454.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0xce, - }, - [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */ - .name = "LG NTSC (TAPE series)", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0x01, }, - { 16 * 442.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x04, }, - }, - .config = 0x8e, - }, - [TUNER_TNF_8831BGFF] = { /* Philips PAL */ - .name = "Tenna TNF 8831 BGFF)", - .count = 3, - .ranges = { - { 16 * 161.25 /*MHz*/, 0xa0, }, - { 16 * 463.25 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */ - .name = "Microtune 4042 FI5 ATSC/NTSC dual in", - .count = 3, - .ranges = { - { 16 * 162.00 /*MHz*/, 0xa2, }, - { 16 * 457.00 /*MHz*/, 0x94, }, - { 16 * 999.99 , 0x31, }, - }, - .config = 0x8e, - }, + { "HITACHI V7-J180AT", HITACHI, NTSC, + 16*170.00, 16*450.00, 0x01,0x02,0x08,0x8e,940 }, + { "Philips PAL_MK (FI1216 MK)", Philips, PAL, + 16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623}, + { "Philips 1236D ATSC/NTSC daul in", Philips, ATSC, + 16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732}, + { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC, + 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, + { "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)", Philips, NTSC, + 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732}, + { "Microtune 4049 FM5", Microtune, PAL, + 16*141.00,16*464.00,0xa0,0x90,0x30,0x8e,623}, + { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC, + 16*160.00,16*454.00,0x01,0x02,0x08,0xce,940}, + { "LG NTSC (TAPE series)", LGINNOTEK, NTSC, + 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, + { "Tenna TNF 8831 BGFF)", Philips, PAL, + 16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623}, + { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC, + 16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732}, /* 50-59 */ - [TUNER_TCL_2002N] = { /* TCL NTSC */ - .name = "TCL 2002N", - .count = 3, - .ranges = { - { 16 * 172.00 /*MHz*/, 0x01, }, - { 16 * 448.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */ - .name = "Philips PAL/SECAM_D (FM 1256 I-H3)", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0x01, }, - { 16 * 442.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x04, }, - }, - .config = 0x8e, - }, - [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */ - .name = "Thomson DTT 7610 (ATSC/NTSC)", - .count = 3, - .ranges = { - { 16 * 157.25 /*MHz*/, 0x39, }, - { 16 * 454.00 /*MHz*/, 0x3a, }, - { 16 * 999.99 , 0x3c, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */ - .name = "Philips FQ1286", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0x41, }, - { 16 * 454.00 /*MHz*/, 0x42, }, - { 16 * 999.99 , 0x04, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */ - .name = "tda8290+75", + { "TCL 2002N", TCL, NTSC, + 16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732}, + { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL, + 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 }, + { "Thomson DDT 7610 (ATSC/NTSC)", THOMSON, ATSC, + 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, + { "Philips FQ1286", Philips, NTSC, + 16*160.00,16*454.00,0x41,0x42,0x04,0x8e,940}, /* UHF band untested */ + { "tda8290+75", Philips, PAL|NTSC, /* see tda8290.c for details */ }, - [TUNER_TCL_2002MB] = { /* TCL PAL */ - .name = "TCL 2002MB", - .count = 3, - .ranges = { - { 16 * 170.00 /*MHz*/, 0x01, }, - { 16 * 450.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0xce, - }, - [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */ - .name = "Philips PAL/SECAM multi (FQ1216AME MK4)", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0x01, }, - { 16 * 442.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x04, }, - }, - .config = 0xce, - }, - [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */ - .name = "Philips FQ1236A MK4", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0x01, }, - { 16 * 442.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x04, }, - }, - .config = 0x8e, - }, - [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */ - .name = "Ymec TVision TVF-8531MF/8831MF/8731MF", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0xa0, }, - { 16 * 454.00 /*MHz*/, 0x90, }, - { 16 * 999.99 , 0x30, }, - }, - .config = 0x8e, - }, - [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */ - .name = "Ymec TVision TVF-5533MF", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0x01, }, - { 16 * 454.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x04, }, - }, - .config = 0x8e, - }, + { "TCL 2002MB", TCL, PAL, + 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, + { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, + 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, + { "Philips FQ1236A MK4", Philips, NTSC, + 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, + { "Ymec TVision TVF-8531MF/8831MF/8731MF", Philips, NTSC, + 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, + { "Ymec TVision TVF-5533MF", Philips, NTSC, + 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, /* 60-69 */ - [TUNER_THOMSON_DTT761X] = { /* THOMSON ATSC */ - /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ - .name = "Thomson DTT 761X (ATSC/NTSC)", - .count = 3, - .ranges = { - { 16 * 145.25 /*MHz*/, 0x39, }, - { 16 * 415.25 /*MHz*/, 0x3a, }, - { 16 * 999.99 , 0x3c, }, - }, - .config = 0x8e, - }, - [TUNER_TENA_9533_DI] = { /* Philips PAL */ - .name = "Tena TNF9533-D/IF/TNF9533-B/DF", - .count = 3, - .ranges = { - { 16 * 160.25 /*MHz*/, 0x01, }, - { 16 * 464.25 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x04, }, - }, - .config = 0x8e, - }, - [TUNER_TEA5767] = { /* Philips RADIO */ - .name = "Philips TEA5767HN FM Radio", + { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, + 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, + { "Tena TNF9533-D/IF/TNF9533-B/DF", Philips, PAL, + 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, + { "Philips TEA5767HN FM Radio", Philips, RADIO, /* see tea5767.c for details */}, - [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */ - .name = "Philips FMD1216ME MK3 Hybrid Tuner", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0x51, }, - { 16 * 442.00 /*MHz*/, 0x52, }, - { 16 * 999.99 , 0x54, }, - }, - .config = 0x86, - }, - [TUNER_LG_TDVS_H062F] = { /* LGINNOTEK ATSC */ - .name = "LG TDVS-H062F/TUA6034", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0x01 }, - { 16 * 455.00 /*MHz*/, 0x02 }, - { 16 * 999.99 , 0x04 }, - }, - .config = 0x8e, - }, - [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */ - .name = "Ymec TVF66T5-B/DFF", - .count = 3, - .ranges = { - { 16 * 160.25 /*MHz*/, 0x01, }, - { 16 * 464.25 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0x8e, - }, - [TUNER_LG_NTSC_TALN_MINI] = { /* LGINNOTEK NTSC */ - .name = "LG NTSC (TALN mini series)", - .count = 3, - .ranges = { - { 16 * 137.25 /*MHz*/, 0x01, }, - { 16 * 373.25 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x08, }, - }, - .config = 0x8e, - }, - [TUNER_PHILIPS_TD1316] = { /* Philips PAL */ - .name = "Philips TD1316 Hybrid Tuner", - .count = 3, - .ranges = { - { 16 * 160.00 /*MHz*/, 0xa1, }, - { 16 * 442.00 /*MHz*/, 0xa2, }, - { 16 * 999.99 , 0xa4, }, - }, - .config = 0xc8, - }, - [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */ - .name = "Philips TUV1236D ATSC/NTSC dual in", - .count = 3, - .ranges = { - { 16 * 157.25 /*MHz*/, 0x01, }, - { 16 * 454.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x04, }, - }, - .config = 0xce, - }, - [TUNER_TNF_5335MF] = { /* Philips NTSC */ - .name = "Tena TNF 5335 MF", - .count = 3, - .ranges = { - { 16 * 157.25 /*MHz*/, 0x01, }, - { 16 * 454.00 /*MHz*/, 0x02, }, - { 16 * 999.99 , 0x04, }, - }, - .config = 0x8e, - }, + { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, + 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, + { "LG TDVS-H062F/TUA6034", LGINNOTEK, ATSC, + 16*160.00,16*455.00,0x01,0x02,0x04,0x8e,732}, + { "Ymec TVF66T5-B/DFF", Philips, PAL, + 16*160.25,16*464.25,0x01,0x02,0x08,0x8e,623}, + { "LG NTSC (TALN mini series)", LGINNOTEK, NTSC, + 16*137.25,16*373.25,0x01,0x02,0x08,0x8e,732 }, + { "Philips TD1316 Hybrid Tuner", Philips, PAL, + 16*160.00,16*442.00,0xa1,0xa2,0xa4,0xc8,623 }, + { "Philips TUV1236D ATSC/NTSC dual in", Philips, ATSC, + 16*157.25,16*454.00,0x01,0x02,0x04,0xce,732 }, + { "Tena TNF 5335 MF", Philips, NTSC, + 16*157.25,16*454.00,0x01,0x02,0x04,0x8e,732 }, }; unsigned const int tuner_count = ARRAY_SIZE(tuners); @@ -843,19 +305,20 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) u16 div; struct tunertype *tun; unsigned char buffer[4]; - int rc, IFPCoff, i; + int rc; tun = &tuners[t->type]; - for (i = 0; i < tun->count; i++) { - if (freq > tun->ranges[i].thresh) - continue; - break; + if (freq < tun->thresh1) { + config = tun->VHF_L; + tuner_dbg("tv: VHF lowrange\n"); + } else if (freq < tun->thresh2) { + config = tun->VHF_H; + tuner_dbg("tv: VHF high range\n"); + } else { + config = tun->UHF; + tuner_dbg("tv: UHF range\n"); } - config = tun->ranges[i].cb; - /* i == 0 -> VHF_LO */ - /* i == 1 -> VHF_HI */ - /* i == 2 -> UHF */ - tuner_dbg("tv: range %d\n",i); + /* tv norm specific stuff for multi-norm tuners */ switch (t->type) { @@ -957,37 +420,7 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq) * frequency in case (wanted frequency < current frequency). */ - /* IFPCoff = Video Intermediate Frequency - Vif: - 940 =16*58.75 NTSC/J (Japan) - 732 =16*45.75 M/N STD - 704 =16*44 ATSC (at DVB code) - 632 =16*39.50 I U.K. - 622.4=16*38.90 B/G D/K I, L STD - 592 =16*37.00 D China - 590 =16.36.875 B Australia - 543.2=16*33.95 L' STD - 171.2=16*10.70 FM Radio (at set_radio_freq) - */ - - if (t->std == V4L2_STD_NTSC_M_JP) { - IFPCoff = 940; - } else if ((t->std & V4L2_STD_MN) && - !(t->std & ~V4L2_STD_MN)) { - IFPCoff = 732; - } else if (t->std == V4L2_STD_SECAM_LC) { - IFPCoff = 543; - } else { - IFPCoff = 623; - } - - div=freq + IFPCoff + offset; - - tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n", - freq / 16, freq % 16 * 100 / 16, - IFPCoff / 16, IFPCoff % 16 * 100 / 16, - offset / 16, offset % 16 * 100 / 16, - div); - + div=freq + tun->IFPCoff; if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) { buffer[0] = tun->config; buffer[1] = config; diff --git a/trunk/drivers/media/video/tvaudio.c b/trunk/drivers/media/video/tvaudio.c index b582943a0d3e..0292c5abf14a 100644 --- a/trunk/drivers/media/video/tvaudio.c +++ b/trunk/drivers/media/video/tvaudio.c @@ -31,7 +31,6 @@ #include #include -#include #include "tvaudio.h" @@ -47,6 +46,17 @@ MODULE_LICENSE("GPL"); #define UNSET (-1U) +#define tvaudio_info(fmt, arg...) do {\ + printk(KERN_INFO "tvaudio %d-%04x: " fmt, \ + chip->c.adapter->nr, chip->c.addr , ##arg); } while (0) +#define tvaudio_warn(fmt, arg...) do {\ + printk(KERN_WARNING "tvaudio %d-%04x: " fmt, \ + chip->c.adapter->nr, chip->c.addr , ##arg); } while (0) +#define tvaudio_dbg(fmt, arg...) do {\ + if (debug) \ + printk(KERN_INFO "tvaudio %d-%04x: " fmt, \ + chip->c.adapter->nr, chip->c.addr , ##arg); } while (0) + /* ---------------------------------------------------------------------- */ /* our structs */ @@ -121,7 +131,7 @@ struct CHIPSTATE { /* current settings */ __u16 left,right,treble,bass,mode; int prevmode; - int radio; + int norm; /* thread */ pid_t tpid; @@ -132,6 +142,8 @@ struct CHIPSTATE { int watch_stereo; }; +#define VIDEO_MODE_RADIO 16 /* norm magic for radio mode */ + /* ---------------------------------------------------------------------- */ /* i2c addresses */ @@ -159,23 +171,23 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) unsigned char buffer[2]; if (-1 == subaddr) { - v4l_dbg(1, &chip->c, "%s: chip_write: 0x%x\n", + tvaudio_dbg("%s: chip_write: 0x%x\n", chip->c.name, val); chip->shadow.bytes[1] = val; buffer[0] = val; if (1 != i2c_master_send(&chip->c,buffer,1)) { - v4l_warn(&chip->c, "%s: I/O error (write 0x%x)\n", + tvaudio_warn("%s: I/O error (write 0x%x)\n", chip->c.name, val); return -1; } } else { - v4l_dbg(1, &chip->c, "%s: chip_write: reg%d=0x%x\n", + tvaudio_dbg("%s: chip_write: reg%d=0x%x\n", chip->c.name, subaddr, val); chip->shadow.bytes[subaddr+1] = val; buffer[0] = subaddr; buffer[1] = val; if (2 != i2c_master_send(&chip->c,buffer,2)) { - v4l_warn(&chip->c, "%s: I/O error (write reg%d=0x%x)\n", + tvaudio_warn("%s: I/O error (write reg%d=0x%x)\n", chip->c.name, subaddr, val); return -1; } @@ -200,11 +212,11 @@ static int chip_read(struct CHIPSTATE *chip) unsigned char buffer; if (1 != i2c_master_recv(&chip->c,&buffer,1)) { - v4l_warn(&chip->c, "%s: I/O error (read)\n", + tvaudio_warn("%s: I/O error (read)\n", chip->c.name); return -1; } - v4l_dbg(1, &chip->c, "%s: chip_read: 0x%x\n",chip->c.name, buffer); + tvaudio_dbg("%s: chip_read: 0x%x\n",chip->c.name, buffer); return buffer; } @@ -219,10 +231,10 @@ static int chip_read2(struct CHIPSTATE *chip, int subaddr) write[0] = subaddr; if (2 != i2c_transfer(chip->c.adapter,msgs,2)) { - v4l_warn(&chip->c, "%s: I/O error (read2)\n", chip->c.name); + tvaudio_warn("%s: I/O error (read2)\n", chip->c.name); return -1; } - v4l_dbg(1, &chip->c, "%s: chip_read2: reg%d=0x%x\n", + tvaudio_dbg("%s: chip_read2: reg%d=0x%x\n", chip->c.name, subaddr,read[0]); return read[0]; } @@ -235,7 +247,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) return 0; /* update our shadow register set; print bytes if (debug > 0) */ - v4l_dbg(1, &chip->c, "%s: chip_cmd(%s): reg=%d, data:", + tvaudio_dbg("%s: chip_cmd(%s): reg=%d, data:", chip->c.name, name,cmd->bytes[0]); for (i = 1; i < cmd->count; i++) { if (debug) @@ -247,7 +259,7 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) /* send data to the chip */ if (cmd->count != i2c_master_send(&chip->c,cmd->bytes,cmd->count)) { - v4l_warn(&chip->c, "%s: I/O error (%s)\n", chip->c.name, name); + tvaudio_warn("%s: I/O error (%s)\n", chip->c.name, name); return -1; } return 0; @@ -274,7 +286,7 @@ static int chip_thread(void *data) daemonize("%s", chip->c.name); allow_signal(SIGTERM); - v4l_dbg(1, &chip->c, "%s: thread started\n", chip->c.name); + tvaudio_dbg("%s: thread started\n", chip->c.name); for (;;) { add_wait_queue(&chip->wq, &wait); @@ -286,10 +298,10 @@ static int chip_thread(void *data) try_to_freeze(); if (chip->done || signal_pending(current)) break; - v4l_dbg(1, &chip->c, "%s: thread wakeup\n", chip->c.name); + tvaudio_dbg("%s: thread wakeup\n", chip->c.name); /* don't do anything for radio or if mode != auto */ - if (chip->radio || chip->mode != 0) + if (chip->norm == VIDEO_MODE_RADIO || chip->mode != 0) continue; /* have a look what's going on */ @@ -299,7 +311,7 @@ static int chip_thread(void *data) mod_timer(&chip->wt, jiffies+2*HZ); } - v4l_dbg(1, &chip->c, "%s: thread exiting\n", chip->c.name); + tvaudio_dbg("%s: thread exiting\n", chip->c.name); complete_and_exit(&chip->texit, 0); return 0; } @@ -312,7 +324,7 @@ static void generic_checkmode(struct CHIPSTATE *chip) if (mode == chip->prevmode) return; - v4l_dbg(1, &chip->c, "%s: thread checkmode\n", chip->c.name); + tvaudio_dbg("%s: thread checkmode\n", chip->c.name); chip->prevmode = mode; if (mode & VIDEO_SOUND_STEREO) @@ -359,7 +371,7 @@ static int tda9840_getmode(struct CHIPSTATE *chip) if (val & TDA9840_ST_STEREO) mode |= VIDEO_SOUND_STEREO; - v4l_dbg(1, &chip->c, "tda9840_getmode(): raw chip read: %d, return: %d\n", + tvaudio_dbg ("tda9840_getmode(): raw chip read: %d, return: %d\n", val, mode); return mode; } @@ -655,7 +667,7 @@ static int tda9873_getmode(struct CHIPSTATE *chip) mode |= VIDEO_SOUND_STEREO; if (val & TDA9873_DUAL) mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; - v4l_dbg(1, &chip->c, "tda9873_getmode(): raw chip read: %d, return: %d\n", + tvaudio_dbg ("tda9873_getmode(): raw chip read: %d, return: %d\n", val, mode); return mode; } @@ -666,12 +678,12 @@ static void tda9873_setmode(struct CHIPSTATE *chip, int mode) /* int adj_data = chip->shadow.bytes[TDA9873_AD+1] ; */ if ((sw_data & TDA9873_INP_MASK) != TDA9873_INTERNAL) { - v4l_dbg(1, &chip->c, "tda9873_setmode(): external input\n"); + tvaudio_dbg("tda9873_setmode(): external input\n"); return; } - v4l_dbg(1, &chip->c, "tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]); - v4l_dbg(1, &chip->c, "tda9873_setmode(): sw_data = %d\n", sw_data); + tvaudio_dbg("tda9873_setmode(): chip->shadow.bytes[%d] = %d\n", TDA9873_SW+1, chip->shadow.bytes[TDA9873_SW+1]); + tvaudio_dbg("tda9873_setmode(): sw_data = %d\n", sw_data); switch (mode) { case VIDEO_SOUND_MONO: @@ -692,7 +704,7 @@ static void tda9873_setmode(struct CHIPSTATE *chip, int mode) } chip_write(chip, TDA9873_SW, sw_data); - v4l_dbg(1, &chip->c, "tda9873_setmode(): req. mode %d; chip_write: %d\n", + tvaudio_dbg("tda9873_setmode(): req. mode %d; chip_write: %d\n", mode, sw_data); } @@ -831,7 +843,7 @@ static int tda9874a_setup(struct CHIPSTATE *chip) chip_write(chip, TDA9874A_SDACOSR, (tda9874a_mode) ? 0x81:0x80); chip_write(chip, TDA9874A_AOSR, 0x00); /* or 0x10 */ } - v4l_dbg(1, &chip->c, "tda9874a_setup(): %s [0x%02X].\n", + tvaudio_dbg("tda9874a_setup(): %s [0x%02X].\n", tda9874a_modelist[tda9874a_STD].name,tda9874a_STD); return 1; } @@ -874,7 +886,7 @@ static int tda9874a_getmode(struct CHIPSTATE *chip) mode |= VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2; } - v4l_dbg(1, &chip->c, "tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n", + tvaudio_dbg("tda9874a_getmode(): DSR=0x%X, NSR=0x%X, NECR=0x%X, return: %d.\n", dsr, nsr, necr, mode); return mode; } @@ -920,7 +932,7 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode) chip_write(chip, TDA9874A_AOSR, aosr); chip_write(chip, TDA9874A_MDACOSR, mdacosr); - v4l_dbg(1, &chip->c, "tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n", + tvaudio_dbg("tda9874a_setmode(): req. mode %d; AOSR=0x%X, MDACOSR=0x%X.\n", mode, aosr, mdacosr); } else { /* dic == 0x07 */ @@ -955,7 +967,7 @@ static void tda9874a_setmode(struct CHIPSTATE *chip, int mode) chip_write(chip, TDA9874A_FMMR, fmmr); chip_write(chip, TDA9874A_AOSR, aosr); - v4l_dbg(1, &chip->c, "tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n", + tvaudio_dbg("tda9874a_setmode(): req. mode %d; FMMR=0x%X, AOSR=0x%X.\n", mode, fmmr, aosr); } } @@ -969,10 +981,10 @@ static int tda9874a_checkit(struct CHIPSTATE *chip) if(-1 == (sic = chip_read2(chip,TDA9874A_SIC))) return 0; - v4l_dbg(1, &chip->c, "tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic); + tvaudio_dbg("tda9874a_checkit(): DIC=0x%X, SIC=0x%X.\n", dic, sic); if((dic == 0x11)||(dic == 0x07)) { - v4l_info(&chip->c, "found tda9874%s.\n", (dic == 0x11) ? "a":"h"); + tvaudio_info("found tda9874%s.\n", (dic == 0x11) ? "a":"h"); tda9874a_dic = dic; /* remember device id. */ return 1; } @@ -1184,7 +1196,7 @@ static int ta8874z_getmode(struct CHIPSTATE *chip) }else if (!(val & TA8874Z_B0)){ mode |= VIDEO_SOUND_STEREO; } - /* v4l_dbg(1, &chip->c, "ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode); */ + /* tvaudio_dbg ("ta8874z_getmode(): raw chip read: 0x%02x, return: 0x%02x\n", val, mode); */ return mode; } @@ -1197,7 +1209,7 @@ static void ta8874z_setmode(struct CHIPSTATE *chip, int mode) { int update = 1; audiocmd *t = NULL; - v4l_dbg(1, &chip->c, "ta8874z_setmode(): mode: 0x%02x\n", mode); + tvaudio_dbg("ta8874z_setmode(): mode: 0x%02x\n", mode); switch(mode){ case VIDEO_SOUND_MONO: @@ -1478,7 +1490,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) i2c_set_clientdata(&chip->c, chip); /* find description for the chip */ - v4l_dbg(1, &chip->c, "chip found @ 0x%x\n", addr<<1); + tvaudio_dbg("chip found @ 0x%x\n", addr<<1); for (desc = chiplist; desc->name != NULL; desc++) { if (0 == *(desc->insmodopt)) continue; @@ -1490,12 +1502,12 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) break; } if (desc->name == NULL) { - v4l_dbg(1, &chip->c, "no matching chip description found\n"); + tvaudio_dbg("no matching chip description found\n"); return -EIO; } - v4l_info(&chip->c, "%s found @ 0x%x (%s)\n", desc->name, addr<<1, adap->name); + tvaudio_info("%s found @ 0x%x (%s)\n", desc->name, addr<<1, adap->name); if (desc->flags) { - v4l_dbg(1, &chip->c, "matches:%s%s%s.\n", + tvaudio_dbg("matches:%s%s%s.\n", (desc->flags & CHIP_HAS_VOLUME) ? " volume" : "", (desc->flags & CHIP_HAS_BASSTREBLE) ? " bass/treble" : "", (desc->flags & CHIP_HAS_INPUTSEL) ? " audiomux" : ""); @@ -1538,7 +1550,7 @@ static int chip_attach(struct i2c_adapter *adap, int addr, int kind) init_completion(&chip->texit); chip->tpid = kernel_thread(chip_thread,(void *)chip,0); if (chip->tpid < 0) - v4l_warn(&chip->c, "%s: kernel_thread() failed\n", + tvaudio_warn("%s: kernel_thread() failed\n", chip->c.name); wake_up_interruptible(&chip->wq); } @@ -1551,8 +1563,17 @@ static int chip_probe(struct i2c_adapter *adap) because dedicated drivers are used */ if ((adap->id == I2C_HW_SAA7146)) return 0; +#ifdef I2C_CLASS_TV_ANALOG if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, chip_attach); +#else + switch (adap->id) { + case I2C_HW_B_BT848: + case I2C_HW_B_RIVA: + case I2C_HW_SAA7134: + return i2c_probe(adap, &addr_data, chip_attach); + } +#endif return 0; } @@ -1583,7 +1604,7 @@ static int chip_command(struct i2c_client *client, struct CHIPSTATE *chip = i2c_get_clientdata(client); struct CHIPDESC *desc = chiplist + chip->type; - v4l_dbg(1, &chip->c, "%s: chip_command 0x%x\n", chip->c.name, cmd); + tvaudio_dbg("%s: chip_command 0x%x\n", chip->c.name, cmd); switch (cmd) { case AUDC_SET_INPUT: @@ -1596,7 +1617,7 @@ static int chip_command(struct i2c_client *client, break; case AUDC_SET_RADIO: - chip->radio = 1; + chip->norm = VIDEO_MODE_RADIO; chip->watch_stereo = 0; /* del_timer(&chip->wt); */ break; @@ -1622,7 +1643,7 @@ static int chip_command(struct i2c_client *client, va->bass = chip->bass; va->treble = chip->treble; } - if (!chip->radio) { + if (chip->norm != VIDEO_MODE_RADIO) { if (desc->getmode) va->mode = desc->getmode(chip); else @@ -1657,80 +1678,15 @@ static int chip_command(struct i2c_client *client, } break; } - - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *vt = arg; - int mode = 0; - - switch (vt->audmode) { - case V4L2_TUNER_MODE_MONO: - mode = VIDEO_SOUND_MONO; - break; - case V4L2_TUNER_MODE_STEREO: - mode = VIDEO_SOUND_STEREO; - break; - case V4L2_TUNER_MODE_LANG1: - mode = VIDEO_SOUND_LANG1; - break; - case V4L2_TUNER_MODE_LANG2: - mode = VIDEO_SOUND_LANG2; - break; - default: - break; - } - - if (desc->setmode && mode) { - chip->watch_stereo = 0; - /* del_timer(&chip->wt); */ - chip->mode = mode; - desc->setmode(chip, mode); - } - break; - } - - case VIDIOC_G_TUNER: + case VIDIOCSCHAN: { - struct v4l2_tuner *vt = arg; - int mode = VIDEO_SOUND_MONO; - - if (chip->radio) - break; - vt->audmode = 0; - vt->rxsubchans = 0; - vt->capability = V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; + struct video_channel *vc = arg; - if (desc->getmode) - mode = desc->getmode(chip); - - if (mode & VIDEO_SOUND_MONO) - vt->rxsubchans |= V4L2_TUNER_SUB_MONO; - if (mode & VIDEO_SOUND_STEREO) - vt->rxsubchans |= V4L2_TUNER_SUB_STEREO; - if (mode & VIDEO_SOUND_LANG1) - vt->rxsubchans |= V4L2_TUNER_SUB_LANG1 | - V4L2_TUNER_SUB_LANG2; - - mode = chip->mode; - if (mode & VIDEO_SOUND_MONO) - vt->audmode = V4L2_TUNER_MODE_MONO; - if (mode & VIDEO_SOUND_STEREO) - vt->audmode = V4L2_TUNER_MODE_STEREO; - if (mode & VIDEO_SOUND_LANG1) - vt->audmode = V4L2_TUNER_MODE_LANG1; - if (mode & VIDEO_SOUND_LANG2) - vt->audmode = V4L2_TUNER_MODE_LANG2; + chip->norm = vc->norm; break; } - - case VIDIOCSCHAN: - case VIDIOC_S_STD: - chip->radio = 0; - break; - case VIDIOCSFREQ: - case VIDIOC_S_FREQUENCY: + { chip->mode = 0; /* automatic */ if (desc->checkmode) { desc->setmode(chip,VIDEO_SOUND_MONO); @@ -1739,14 +1695,15 @@ static int chip_command(struct i2c_client *client, mod_timer(&chip->wt, jiffies+2*HZ); /* the thread will call checkmode() later */ } - break; + } } return 0; } + static struct i2c_driver driver = { .driver = { - .name = "tvaudio", + .name = "generic i2c audio driver", }, .id = I2C_DRIVERID_TVAUDIO, .attach_adapter = chip_probe, diff --git a/trunk/drivers/media/video/tveeprom.c b/trunk/drivers/media/video/tveeprom.c index fd0acc5da667..8ac4cb82a459 100644 --- a/trunk/drivers/media/video/tveeprom.c +++ b/trunk/drivers/media/video/tveeprom.c @@ -40,7 +40,6 @@ #include #include -#include #include MODULE_DESCRIPTION("i2c Hauppauge eeprom decoder driver"); @@ -53,19 +52,21 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); #define STRM(array,i) (i < sizeof(array)/sizeof(char*) ? array[i] : "unknown") -#define tveeprom_info(fmt, arg...) \ - v4l_printk(KERN_INFO, "tveeprom", c->adapter, c->addr, fmt , ## arg) -#define tveeprom_warn(fmt, arg...) \ - v4l_printk(KERN_WARNING, "tveeprom", c->adapter, c->addr, fmt , ## arg) -#define tveeprom_dbg(fmt, arg...) do { \ +#define tveeprom_info(fmt, arg...) do {\ + printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ + c->adapter->nr, c->addr , ##arg); } while (0) +#define tveeprom_warn(fmt, arg...) do {\ + printk(KERN_WARNING "tveeprom %d-%04x: " fmt, \ + c->adapter->nr, c->addr , ##arg); } while (0) +#define tveeprom_dbg(fmt, arg...) do {\ if (debug) \ - v4l_printk(KERN_DEBUG, "tveeprom", c->adapter, c->addr, fmt , ## arg); \ - } while (0) + printk(KERN_INFO "tveeprom %d-%04x: " fmt, \ + c->adapter->nr, c->addr , ##arg); } while (0) + + +/* ----------------------------------------------------------------------- */ +/* some hauppauge specific stuff */ -/* - * The Hauppauge eeprom uses an 8bit field to determine which - * tuner formats the tuner supports. - */ static struct HAUPPAUGE_TUNER_FMT { int id; @@ -73,14 +74,14 @@ static struct HAUPPAUGE_TUNER_FMT } hauppauge_tuner_fmt[] = { - { V4L2_STD_UNKNOWN," UNKNOWN" }, - { V4L2_STD_UNKNOWN," FM" }, - { V4L2_STD_PAL_BG, " PAL(B/G)" }, - { V4L2_STD_NTSC_M, " NTSC(M)" }, - { V4L2_STD_PAL_I, " PAL(I)" }, - { V4L2_STD_SECAM_L," SECAM(L/L')" }, - { V4L2_STD_PAL_DK, " PAL(D/D1/K)" }, - { V4L2_STD_ATSC, " ATSC/DVB Digital" }, + { 0x00000000, " unknown1" }, + { 0x00000000, " unknown2" }, + { 0x00000007, " PAL(B/G)" }, + { 0x00001000, " NTSC(M)" }, + { 0x00000010, " PAL(I)" }, + { 0x00400000, " SECAM(L/L')" }, + { 0x00000e00, " PAL(D/K)" }, + { 0x03000000, " ATSC/DVB Digital" }, }; /* This is the full list of possible tuners. Many thanks to Hauppauge for @@ -386,7 +387,7 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, if ((eeprom_data[0] == 0x1a) && (eeprom_data[1] == 0xeb) && (eeprom_data[2] == 0x67) && (eeprom_data[3] == 0x95)) start=0xa0; /* Generic em28xx offset */ - else if (((eeprom_data[0] & 0xe1) == 0x01) && + else if (((eeprom_data[0] & 0xf0) == 0x10) && (eeprom_data[1] == 0x00) && (eeprom_data[2] == 0x00) && (eeprom_data[8] == 0x84)) diff --git a/trunk/drivers/media/video/tvmixer.c b/trunk/drivers/media/video/tvmixer.c index 9e86caeb96a7..e837f9f7fed6 100644 --- a/trunk/drivers/media/video/tvmixer.c +++ b/trunk/drivers/media/video/tvmixer.c @@ -227,9 +227,13 @@ static int tvmixer_release(struct inode *inode, struct file *file) } static struct i2c_driver driver = { +#ifdef I2C_PEC .driver = { - .name = "tvmixer", + .name = "tv card mixer driver", }, +#else + .name = "tv card mixer driver", +#endif .id = I2C_DRIVERID_TVMIXER, .detach_adapter = tvmixer_adapters, .attach_adapter = tvmixer_adapters, @@ -263,8 +267,22 @@ static int tvmixer_clients(struct i2c_client *client) struct video_audio va; int i,minor; +#ifdef I2C_CLASS_TV_ANALOG if (!(client->adapter->class & I2C_CLASS_TV_ANALOG)) return -1; +#else + /* TV card ??? */ + switch (client->adapter->id) { + case I2C_HW_SMBUS_VOODOO3: + case I2C_HW_B_BT848: + case I2C_HW_B_RIVA: + /* ok, have a look ... */ + break; + default: + /* ignore that one */ + return -1; + } +#endif /* unregister ?? */ for (i = 0; i < DEV_MAX; i++) { diff --git a/trunk/drivers/media/video/tvp5150.c b/trunk/drivers/media/video/tvp5150.c index c35b8042eee5..a60442ea4f94 100644 --- a/trunk/drivers/media/video/tvp5150.c +++ b/trunk/drivers/media/video/tvp5150.c @@ -9,7 +9,6 @@ #include #include #include -#include #include "tvp5150_reg.h" @@ -29,38 +28,33 @@ static int debug = 0; module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); -#define tvp5150_info(fmt, arg...) do { \ - printk(KERN_INFO "%s %d-%04x: " fmt, c->driver->driver.name, \ - i2c_adapter_id(c->adapter), c->addr , ## arg); } while (0) -#define tvp5150_dbg(num, fmt, arg...) \ +#define dprintk(num, format, args...) \ do { \ if (debug >= num) \ - printk(KERN_DEBUG "%s debug %d-%04x: " fmt,\ - c->driver->driver.name, \ - i2c_adapter_id(c->adapter), \ - c->addr , ## arg); } while (0) + printk(format, ##args); \ + } while (0) /* supported controls */ static struct v4l2_queryctrl tvp5150_qctrl[] = { { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 0, - .flags = 0, - }, { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 255, - .step = 0x1, - .default_value = 0x10, - .flags = 0, - }, { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = 0, + .flags = 0, + }, { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 255, + .step = 0x1, + .default_value = 0x10, + .flags = 0, + }, { .id = V4L2_CID_SATURATION, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Saturation", @@ -69,16 +63,16 @@ static struct v4l2_queryctrl tvp5150_qctrl[] = { .step = 0x1, .default_value = 0x10, .flags = 0, - }, { - .id = V4L2_CID_HUE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Hue", - .minimum = -128, - .maximum = 127, - .step = 0x1, - .default_value = 0x10, - .flags = 0, - } + }, { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = -128, + .maximum = 127, + .step = 0x1, + .default_value = 0x10, + .flags = 0, + } }; struct tvp5150 { @@ -100,14 +94,12 @@ static inline int tvp5150_read(struct i2c_client *c, unsigned char addr) buffer[0] = addr; if (1 != (rc = i2c_master_send(c, buffer, 1))) - tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc); + dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc); msleep(10); if (1 != (rc = i2c_master_recv(c, buffer, 1))) - tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 1)\n", rc); - - tvp5150_dbg(2, "tvp5150: read 0x%02x = 0x%02x\n", addr, buffer[0]); + dprintk(0, "i2c i/o error: rc == %d (should be 1)\n", rc); return (buffer[0]); } @@ -117,12 +109,13 @@ static inline void tvp5150_write(struct i2c_client *c, unsigned char addr, { unsigned char buffer[2]; int rc; +/* struct tvp5150 *core = i2c_get_clientdata(c); */ buffer[0] = addr; buffer[1] = value; - tvp5150_dbg(2, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]); + dprintk(1, "tvp5150: writing 0x%02x 0x%02x\n", buffer[0], buffer[1]); if (2 != (rc = i2c_master_send(c, buffer, 2))) - tvp5150_dbg(0, "i2c i/o error: rc == %d (should be 2)\n", rc); + dprintk(0, "i2c i/o error: rc == %d (should be 2)\n", rc); } static void dump_reg(struct i2c_client *c) @@ -444,346 +437,48 @@ enum tvp5150_input { static inline void tvp5150_selmux(struct i2c_client *c, enum tvp5150_input input) { - int opmode=0; - struct tvp5150 *decoder = i2c_get_clientdata(c); if (!decoder->enable) input |= TVP5150_BLACK_SCREEN; - switch (input) { - case TVP5150_ANALOG_CH0: - case TVP5150_ANALOG_CH1: - opmode=0x30; /* TV Mode */ - break; - default: - opmode=0; /* Auto Mode */ - break; - } - - tvp5150_write(c, TVP5150_OP_MODE_CTL, opmode); tvp5150_write(c, TVP5150_VD_IN_SRC_SEL_1, input); }; -struct i2c_reg_value { - unsigned char reg; - unsigned char value; -}; - -/* Default values as sugested at TVP5150AM1 datasheet */ -static const struct i2c_reg_value tvp5150_init_default[] = { - { /* 0x00 */ - TVP5150_VD_IN_SRC_SEL_1,0x00 - }, - { /* 0x01 */ - TVP5150_ANAL_CHL_CTL,0x15 - }, - { /* 0x02 */ - TVP5150_OP_MODE_CTL,0x00 - }, - { /* 0x03 */ - TVP5150_MISC_CTL,0x01 - }, - { /* 0x06 */ - TVP5150_COLOR_KIL_THSH_CTL,0x10 - }, - { /* 0x07 */ - TVP5150_LUMA_PROC_CTL_1,0x60 - }, - { /* 0x08 */ - TVP5150_LUMA_PROC_CTL_2,0x00 - }, - { /* 0x09 */ - TVP5150_BRIGHT_CTL,0x80 - }, - { /* 0x0a */ - TVP5150_SATURATION_CTL,0x80 - }, - { /* 0x0b */ - TVP5150_HUE_CTL,0x00 - }, - { /* 0x0c */ - TVP5150_CONTRAST_CTL,0x80 - }, - { /* 0x0d */ - TVP5150_DATA_RATE_SEL,0x47 - }, - { /* 0x0e */ - TVP5150_LUMA_PROC_CTL_3,0x00 - }, - { /* 0x0f */ - TVP5150_CONF_SHARED_PIN,0x08 - }, - { /* 0x11 */ - TVP5150_ACT_VD_CROP_ST_MSB,0x00 - }, - { /* 0x12 */ - TVP5150_ACT_VD_CROP_ST_LSB,0x00 - }, - { /* 0x13 */ - TVP5150_ACT_VD_CROP_STP_MSB,0x00 - }, - { /* 0x14 */ - TVP5150_ACT_VD_CROP_STP_LSB,0x00 - }, - { /* 0x15 */ - TVP5150_GENLOCK,0x01 - }, - { /* 0x16 */ - TVP5150_HORIZ_SYNC_START,0x80 - }, - { /* 0x18 */ - TVP5150_VERT_BLANKING_START,0x00 - }, - { /* 0x19 */ - TVP5150_VERT_BLANKING_STOP,0x00 - }, - { /* 0x1a */ - TVP5150_CHROMA_PROC_CTL_1,0x0c - }, - { /* 0x1b */ - TVP5150_CHROMA_PROC_CTL_2,0x14 - }, - { /* 0x1c */ - TVP5150_INT_RESET_REG_B,0x00 - }, - { /* 0x1d */ - TVP5150_INT_ENABLE_REG_B,0x00 - }, - { /* 0x1e */ - TVP5150_INTT_CONFIG_REG_B,0x00 - }, - { /* 0x28 */ - TVP5150_VIDEO_STD,0x00 - }, - { /* 0x2e */ - TVP5150_MACROVISION_ON_CTR,0x0f - }, - { /* 0x2f */ - TVP5150_MACROVISION_OFF_CTR,0x01 - }, - { /* 0xbb */ - TVP5150_TELETEXT_FIL_ENA,0x00 - }, - { /* 0xc0 */ - TVP5150_INT_STATUS_REG_A,0x00 - }, - { /* 0xc1 */ - TVP5150_INT_ENABLE_REG_A,0x00 - }, - { /* 0xc2 */ - TVP5150_INT_CONF,0x04 - }, - { /* 0xc8 */ - TVP5150_FIFO_INT_THRESHOLD,0x80 - }, - { /* 0xc9 */ - TVP5150_FIFO_RESET,0x00 - }, - { /* 0xca */ - TVP5150_LINE_NUMBER_INT,0x00 - }, - { /* 0xcb */ - TVP5150_PIX_ALIGN_REG_LOW,0x4e - }, - { /* 0xcc */ - TVP5150_PIX_ALIGN_REG_HIGH,0x00 - }, - { /* 0xcd */ - TVP5150_FIFO_OUT_CTRL,0x01 - }, - { /* 0xcf */ - TVP5150_FULL_FIELD_ENA_1,0x00 - }, - { /* 0xd0 */ - TVP5150_FULL_FIELD_ENA_2,0x00 - }, - { /* 0xfc */ - TVP5150_FULL_FIELD_MODE_REG,0x7f - }, - { /* end of data */ - 0xff,0xff - } -}; - -/* Default values as sugested at TVP5150AM1 datasheet */ -static const struct i2c_reg_value tvp5150_init_enable[] = { - { - TVP5150_CONF_SHARED_PIN, 2 - },{ /* Automatic offset and AGC enabled */ - TVP5150_ANAL_CHL_CTL, 0x15 - },{ /* Activate YCrCb output 0x9 or 0xd ? */ - TVP5150_MISC_CTL, 0x6f - },{ /* Activates video std autodetection for all standards */ - TVP5150_AUTOSW_MSK, 0x0 - },{ /* Default format: 0x47. For 4:2:2: 0x40 */ - TVP5150_DATA_RATE_SEL, 0x47 - },{ - TVP5150_CHROMA_PROC_CTL_1, 0x0c - },{ - TVP5150_CHROMA_PROC_CTL_2, 0x54 - },{ /* Non documented, but initialized on WinTV USB2 */ - 0x27, 0x20 - },{ - 0xff,0xff - } -}; - -struct i2c_vbi_ram_value { - u16 reg; - unsigned char values[26]; -}; - -struct i2c_vbi_ram_value vbi_ram_default[] = -{ - {0x010, /* WST SECAM 6 */ - { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x26, 0xe6, 0xb4, 0x0e, 0x0, 0x0, 0x0, 0x10, 0x0 } - }, - {0x030, /* WST PAL B 6 */ - { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x2b, 0xa6, 0x72, 0x10, 0x0, 0x0, 0x0, 0x10, 0x0 } - }, - {0x050, /* WST PAL C 6 */ - { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0xa6, 0x98, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 } - }, - {0x070, /* WST NTSC 6 */ - { 0xaa, 0xaa, 0xff, 0xff , 0x27, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 } - }, - {0x090, /* NABTS, NTSC 6 */ - { 0xaa, 0xaa, 0xff, 0xff , 0xe7, 0x2e, 0x20, 0x22, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x15, 0x0 } - }, - {0x0b0, /* NABTS, NTSC-J 6 */ - { 0xaa, 0xaa, 0xff, 0xff , 0xa7, 0x2e, 0x20, 0x23, 0x69, 0x93, 0x0d, 0x0, 0x0, 0x0, 0x10, 0x0 } - }, - {0x0d0, /* CC, PAL/SECAM 6 */ - { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0xa6, 0x7b, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 } - }, - {0x0f0, /* CC, NTSC 6 */ - { 0xaa, 0x2a, 0xff, 0x3f , 0x04, 0x51, 0x6e, 0x02, 0x69, 0x8c, 0x09, 0x0, 0x0, 0x0, 0x27, 0x0 } - }, - {0x110, /* WSS, PAL/SECAM 6 */ - { 0x5b, 0x55, 0xc5, 0xff , 0x0, 0x71, 0x6e, 0x42, 0xa6, 0xcd, 0x0f, 0x0, 0x0, 0x0, 0x3a, 0x0 } - }, - {0x130, /* WSS, NTSC C */ - { 0x38, 0x00, 0x3f, 0x00 , 0x0, 0x71, 0x6e, 0x43, 0x69, 0x7c, 0x08, 0x0, 0x0, 0x0, 0x39, 0x0 } - }, - {0x150, /* VITC, PAL/SECAM 6 */ - { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0xa6, 0x85, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 } - }, - {0x170, /* VITC, NTSC 6 */ - { 0x0, 0x0, 0x0, 0x0 , 0x0, 0x8f, 0x6d, 0x49, 0x69, 0x94, 0x08, 0x0, 0x0, 0x0, 0x4c, 0x0 } - }, - { (u16)-1 } -}; - -static int tvp5150_write_inittab(struct i2c_client *c, - const struct i2c_reg_value *regs) -{ - while (regs->reg != 0xff) { - tvp5150_write(c, regs->reg, regs->value); - regs++; - } - return 0; -} - -static int tvp5150_vdp_init(struct i2c_client *c, - const struct i2c_vbi_ram_value *regs) -{ - unsigned int i; - - /* Disable Full Field */ - tvp5150_write(c, TVP5150_FULL_FIELD_ENA_1, 0); - - /* Before programming, Line mode should be at 0xff */ - for (i=TVP5150_FULL_FIELD_ENA_2; i<=TVP5150_LINE_MODE_REG_44; i++) - tvp5150_write(c, i, 0xff); - - /* Load Ram Table */ - while (regs->reg != (u16)-1 ) { - tvp5150_write(c, TVP5150_CONF_RAM_ADDR_HIGH,regs->reg>>8); - tvp5150_write(c, TVP5150_CONF_RAM_ADDR_LOW,regs->reg); - - for (i=0;i<16;i++) - tvp5150_write(c, TVP5150_VDP_CONF_RAM_DATA,regs->values[i]); - - regs++; - } - return 0; -} - -static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std) +static inline void tvp5150_reset(struct i2c_client *c) { struct tvp5150 *decoder = i2c_get_clientdata(c); - int fmt=0; - - decoder->norm=std; - - /* First tests should be against specific std */ - - if (std == V4L2_STD_ALL) { - fmt=0; /* Autodetect mode */ - } else if (std & V4L2_STD_NTSC_443) { - fmt=0xa; - } else if (std & V4L2_STD_PAL_M) { - fmt=0x6; - } else if (std & (V4L2_STD_PAL_N| V4L2_STD_PAL_Nc)) { - fmt=0x8; - } else { - /* Then, test against generic ones */ - if (std & V4L2_STD_NTSC) { - fmt=0x2; - } else if (std & V4L2_STD_PAL) { - fmt=0x4; - } else if (std & V4L2_STD_SECAM) { - fmt=0xc; - } - } - tvp5150_dbg(1,"Set video std register to %d.\n",fmt); - tvp5150_write(c, TVP5150_VIDEO_STD, fmt); + tvp5150_write(c, TVP5150_CONF_SHARED_PIN, 2); - return 0; -} + /* Automatic offset and AGC enabled */ + tvp5150_write(c, TVP5150_ANAL_CHL_CTL, 0x15); -static inline void tvp5150_reset(struct i2c_client *c) -{ - u8 type, ver_656, msb_id, lsb_id, msb_rom, lsb_rom; - struct tvp5150 *decoder = i2c_get_clientdata(c); + /* Normal Operation */ +// tvp5150_write(c, TVP5150_OP_MODE_CTL, 0x00); - type=tvp5150_read(c,TVP5150_AUTOSW_MSK); - msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID); - lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID); - msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER); - lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER); - - if (type==0xdc) { - ver_656=tvp5150_read(c,TVP5150_REV_SELECT); - tvp5150_info("tvp%02x%02xam1 detected 656 version is %d.\n",msb_id, lsb_id,ver_656); - } else if (type==0xfc) { - tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id); - } else { - tvp5150_info("unknown tvp%02x%02x chip detected(%d).\n",msb_id,lsb_id,type); - } - tvp5150_info("Rom ver is %d.%d\n",msb_rom,lsb_rom); + /* Activate YCrCb output 0x9 or 0xd ? */ + tvp5150_write(c, TVP5150_MISC_CTL, 0x6f); - /* Initializes TVP5150 to its default values */ - tvp5150_write_inittab(c, tvp5150_init_default); + /* Activates video std autodetection for all standards */ + tvp5150_write(c, TVP5150_AUTOSW_MSK, 0x0); - /* Initializes VDP registers */ - tvp5150_vdp_init(c, vbi_ram_default); + /* Default format: 0x47, 4:2:2: 0x40 */ + tvp5150_write(c, TVP5150_DATA_RATE_SEL, 0x47); - /* Selects decoder input */ tvp5150_selmux(c, decoder->input); - /* Initializes TVP5150 to stream enabled values */ - tvp5150_write_inittab(c, tvp5150_init_enable); + tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_1, 0x0c); + tvp5150_write(c, TVP5150_CHROMA_PROC_CTL_2, 0x54); + + tvp5150_write(c, 0x27, 0x20); /* ?????????? */ + + tvp5150_write(c, TVP5150_VIDEO_STD, 0x0); /* Auto switch */ - /* Initialize image preferences */ tvp5150_write(c, TVP5150_BRIGHT_CTL, decoder->bright >> 8); tvp5150_write(c, TVP5150_CONTRAST_CTL, decoder->contrast >> 8); tvp5150_write(c, TVP5150_SATURATION_CTL, decoder->contrast >> 8); tvp5150_write(c, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8); - - tvp5150_set_std(c, decoder->norm); }; static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) @@ -803,8 +498,9 @@ static int tvp5150_get_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) case V4L2_CID_HUE: ctrl->value = tvp5150_read(c, TVP5150_HUE_CTL); return 0; + default: + return -EINVAL; } - return -EINVAL; } static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) @@ -824,59 +520,28 @@ static int tvp5150_set_ctrl(struct i2c_client *c, struct v4l2_control *ctrl) case V4L2_CID_HUE: tvp5150_write(c, TVP5150_HUE_CTL, ctrl->value); return 0; + default: + return -EINVAL; } - return -EINVAL; } /**************************************************************************** I2C Command ****************************************************************************/ -static int tvp5150_command(struct i2c_client *c, +static int tvp5150_command(struct i2c_client *client, unsigned int cmd, void *arg) { - struct tvp5150 *decoder = i2c_get_clientdata(c); + struct tvp5150 *decoder = i2c_get_clientdata(client); switch (cmd) { case 0: - case VIDIOC_INT_RESET: case DECODER_INIT: - tvp5150_reset(c); - break; - case VIDIOC_S_STD: - if (decoder->norm == *(v4l2_std_id *)arg) - break; - return tvp5150_set_std(c, *(v4l2_std_id *)arg); - case VIDIOC_G_STD: - *(v4l2_std_id *)arg = decoder->norm; - break; - -#ifdef CONFIG_VIDEO_ADV_DEBUG - case VIDIOC_INT_G_REGISTER: - { - struct v4l2_register *reg = arg; - - if (reg->i2c_id != I2C_DRIVERID_TVP5150) - return -EINVAL; - reg->val = tvp5150_read(c, reg->reg & 0xff); - break; - } - - case VIDIOC_INT_S_REGISTER: - { - struct v4l2_register *reg = arg; - - if (reg->i2c_id != I2C_DRIVERID_TVP5150) - return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - tvp5150_write(c, reg->reg & 0xff, reg->val & 0xff); + tvp5150_reset(client); break; - } -#endif case DECODER_DUMP: - dump_reg(c); + dump_reg(client); break; case DECODER_GET_CAPABILITIES: @@ -935,7 +600,7 @@ static int tvp5150_command(struct i2c_client *c, } decoder->input = *iarg; - tvp5150_selmux(c, decoder->input); + tvp5150_selmux(client, decoder->input); break; } @@ -955,18 +620,19 @@ static int tvp5150_command(struct i2c_client *c, decoder->enable = (*iarg != 0); - tvp5150_selmux(c, decoder->input); + tvp5150_selmux(client, decoder->input); break; } case VIDIOC_QUERYCTRL: { struct v4l2_queryctrl *qc = arg; - int i; + u8 i, n; - tvp5150_dbg(1, "VIDIOC_QUERYCTRL called\n"); + dprintk(1, KERN_DEBUG "VIDIOC_QUERYCTRL"); - for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++) + n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]); + for (i = 0; i < n; i++) if (qc->id && qc->id == tvp5150_qctrl[i].id) { memcpy(qc, &(tvp5150_qctrl[i]), sizeof(*qc)); @@ -978,14 +644,16 @@ static int tvp5150_command(struct i2c_client *c, case VIDIOC_G_CTRL: { struct v4l2_control *ctrl = arg; - tvp5150_dbg(1, "VIDIOC_G_CTRL called\n"); + dprintk(1, KERN_DEBUG "VIDIOC_G_CTRL"); - return tvp5150_get_ctrl(c, ctrl); + return tvp5150_get_ctrl(client, ctrl); } + case VIDIOC_S_CTRL_OLD: /* ??? */ case VIDIOC_S_CTRL: { struct v4l2_control *ctrl = arg; u8 i, n; + dprintk(1, KERN_DEBUG "VIDIOC_S_CTRL"); n = sizeof(tvp5150_qctrl) / sizeof(tvp5150_qctrl[0]); for (i = 0; i < n; i++) if (ctrl->id == tvp5150_qctrl[i].id) { @@ -994,10 +662,11 @@ static int tvp5150_command(struct i2c_client *c, || ctrl->value > tvp5150_qctrl[i].maximum) return -ERANGE; - tvp5150_dbg(1, - "VIDIOC_S_CTRL: id=%d, value=%d\n", + dprintk(1, + KERN_DEBUG + "VIDIOC_S_CTRL: id=%d, value=%d", ctrl->id, ctrl->value); - return tvp5150_set_ctrl(c, ctrl); + return tvp5150_set_ctrl(client, ctrl); } return -EINVAL; } @@ -1008,25 +677,25 @@ static int tvp5150_command(struct i2c_client *c, if (decoder->bright != pic->brightness) { /* We want 0 to 255 we get 0-65535 */ decoder->bright = pic->brightness; - tvp5150_write(c, TVP5150_BRIGHT_CTL, + tvp5150_write(client, TVP5150_BRIGHT_CTL, decoder->bright >> 8); } if (decoder->contrast != pic->contrast) { /* We want 0 to 255 we get 0-65535 */ decoder->contrast = pic->contrast; - tvp5150_write(c, TVP5150_CONTRAST_CTL, + tvp5150_write(client, TVP5150_CONTRAST_CTL, decoder->contrast >> 8); } if (decoder->sat != pic->colour) { /* We want 0 to 255 we get 0-65535 */ decoder->sat = pic->colour; - tvp5150_write(c, TVP5150_SATURATION_CTL, + tvp5150_write(client, TVP5150_SATURATION_CTL, decoder->contrast >> 8); } if (decoder->hue != pic->hue) { /* We want -128 to 127 we get 0-65535 */ decoder->hue = pic->hue; - tvp5150_write(c, TVP5150_HUE_CTL, + tvp5150_write(client, TVP5150_HUE_CTL, (decoder->hue - 32768) >> 8); } break; @@ -1051,12 +720,12 @@ static struct i2c_client client_template = { static int tvp5150_detect_client(struct i2c_adapter *adapter, int address, int kind) { - struct i2c_client *c; + struct i2c_client *client; struct tvp5150 *core; int rv; - if (debug) - printk( KERN_INFO + dprintk(1, + KERN_INFO "tvp5150.c: detecting tvp5150 client on address 0x%x\n", address << 1); @@ -1069,22 +738,22 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter, I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) return 0; - c = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (c == 0) + client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (client == 0) return -ENOMEM; - memcpy(c, &client_template, sizeof(struct i2c_client)); + memcpy(client, &client_template, sizeof(struct i2c_client)); core = kmalloc(sizeof(struct tvp5150), GFP_KERNEL); if (core == 0) { - kfree(c); + kfree(client); return -ENOMEM; } memset(core, 0, sizeof(struct tvp5150)); - i2c_set_clientdata(c, core); + i2c_set_clientdata(client, core); - rv = i2c_attach_client(c); + rv = i2c_attach_client(client); - core->norm = V4L2_STD_ALL; + core->norm = VIDEO_MODE_AUTO; core->input = 2; core->enable = 1; core->bright = 32768; @@ -1093,41 +762,37 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter, core->sat = 32768; if (rv) { - kfree(c); + kfree(client); kfree(core); return rv; } if (debug > 1) - dump_reg(c); + dump_reg(client); return 0; } static int tvp5150_attach_adapter(struct i2c_adapter *adapter) { - if (debug) - printk( KERN_INFO + dprintk(1, + KERN_INFO "tvp5150.c: starting probe for adapter %s (0x%x)\n", adapter->name, adapter->id); return i2c_probe(adapter, &addr_data, &tvp5150_detect_client); } -static int tvp5150_detach_client(struct i2c_client *c) +static int tvp5150_detach_client(struct i2c_client *client) { - struct tvp5150 *decoder = i2c_get_clientdata(c); + struct tvp5150 *decoder = i2c_get_clientdata(client); int err; - tvp5150_dbg(1, - "tvp5150.c: removing tvp5150 adapter on address 0x%x\n", - c->addr << 1); - - err = i2c_detach_client(c); + err = i2c_detach_client(client); if (err) { return err; } kfree(decoder); - kfree(c); + kfree(client); return 0; } @@ -1138,7 +803,9 @@ static struct i2c_driver driver = { .driver = { .name = "tvp5150", }, - .id = I2C_DRIVERID_TVP5150, + + /* FIXME */ + .id = I2C_DRIVERID_SAA7110, .attach_adapter = tvp5150_attach_adapter, .detach_client = tvp5150_detach_client, diff --git a/trunk/drivers/media/video/v4l1-compat.c b/trunk/drivers/media/video/v4l1-compat.c index 2ab5b4093800..4134549d11a8 100644 --- a/trunk/drivers/media/video/v4l1-compat.c +++ b/trunk/drivers/media/video/v4l1-compat.c @@ -951,10 +951,6 @@ v4l_compat_translate_ioctl(struct inode *inode, dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err); break; } - if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) { - err = -EINVAL; - break; - } memset(fmt, 0, sizeof(*fmt)); fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line; fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate; @@ -970,11 +966,6 @@ v4l_compat_translate_ioctl(struct inode *inode, { struct vbi_format *fmt = arg; - if (VIDEO_PALETTE_RAW != fmt->sample_format) { - err = -EINVAL; - break; - } - fmt2 = kmalloc(sizeof(*fmt2),GFP_KERNEL); memset(fmt2, 0, sizeof(*fmt2)); @@ -995,7 +986,7 @@ v4l_compat_translate_ioctl(struct inode *inode, if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line || fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate || - fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY || + VIDEO_PALETTE_RAW != fmt->sample_format || fmt2->fmt.vbi.start[0] != fmt->start[0] || fmt2->fmt.vbi.count[0] != fmt->count[0] || fmt2->fmt.vbi.start[1] != fmt->start[1] || diff --git a/trunk/drivers/media/video/v4l2-common.c b/trunk/drivers/media/video/v4l2-common.c index 5dbd7c1b362a..597b8db35a13 100644 --- a/trunk/drivers/media/video/v4l2-common.c +++ b/trunk/drivers/media/video/v4l2-common.c @@ -58,8 +58,6 @@ #include #include #include -#include -#include #ifdef CONFIG_KMOD #include @@ -192,174 +190,57 @@ char *v4l2_type_names[] = { [V4L2_BUF_TYPE_VBI_OUTPUT] = "vbi-out", }; -/* ------------------------------------------------------------------ */ -/* debug help functions */ - -#ifdef HAVE_V4L1 -static const char *v4l1_ioctls[] = { - [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", - [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", - [_IOC_NR(VIDIOCSCHAN)] = "VIDIOCSCHAN", - [_IOC_NR(VIDIOCGTUNER)] = "VIDIOCGTUNER", - [_IOC_NR(VIDIOCSTUNER)] = "VIDIOCSTUNER", - [_IOC_NR(VIDIOCGPICT)] = "VIDIOCGPICT", - [_IOC_NR(VIDIOCSPICT)] = "VIDIOCSPICT", - [_IOC_NR(VIDIOCCAPTURE)] = "VIDIOCCAPTURE", - [_IOC_NR(VIDIOCGWIN)] = "VIDIOCGWIN", - [_IOC_NR(VIDIOCSWIN)] = "VIDIOCSWIN", - [_IOC_NR(VIDIOCGFBUF)] = "VIDIOCGFBUF", - [_IOC_NR(VIDIOCSFBUF)] = "VIDIOCSFBUF", - [_IOC_NR(VIDIOCKEY)] = "VIDIOCKEY", - [_IOC_NR(VIDIOCGFREQ)] = "VIDIOCGFREQ", - [_IOC_NR(VIDIOCSFREQ)] = "VIDIOCSFREQ", - [_IOC_NR(VIDIOCGAUDIO)] = "VIDIOCGAUDIO", - [_IOC_NR(VIDIOCSAUDIO)] = "VIDIOCSAUDIO", - [_IOC_NR(VIDIOCSYNC)] = "VIDIOCSYNC", - [_IOC_NR(VIDIOCMCAPTURE)] = "VIDIOCMCAPTURE", - [_IOC_NR(VIDIOCGMBUF)] = "VIDIOCGMBUF", - [_IOC_NR(VIDIOCGUNIT)] = "VIDIOCGUNIT", - [_IOC_NR(VIDIOCGCAPTURE)] = "VIDIOCGCAPTURE", - [_IOC_NR(VIDIOCSCAPTURE)] = "VIDIOCSCAPTURE", - [_IOC_NR(VIDIOCSPLAYMODE)] = "VIDIOCSPLAYMODE", - [_IOC_NR(VIDIOCSWRITEMODE)] = "VIDIOCSWRITEMODE", - [_IOC_NR(VIDIOCGPLAYINFO)] = "VIDIOCGPLAYINFO", - [_IOC_NR(VIDIOCSMICROCODE)] = "VIDIOCSMICROCODE", - [_IOC_NR(VIDIOCGVBIFMT)] = "VIDIOCGVBIFMT", - [_IOC_NR(VIDIOCSVBIFMT)] = "VIDIOCSVBIFMT" -}; -#define V4L1_IOCTLS ARRAY_SIZE(v4l1_ioctls) -#endif - -static const char *v4l2_ioctls[] = { - [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", - [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", - [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", - [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", - [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", - [_IOC_NR(VIDIOC_G_MPEGCOMP)] = "VIDIOC_G_MPEGCOMP", - [_IOC_NR(VIDIOC_S_MPEGCOMP)] = "VIDIOC_S_MPEGCOMP", - [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", - [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", - [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", - [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", - [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", - [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", - [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", - [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", - [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", - [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", - [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", - [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", - [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", - [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", - [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", - [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", - [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", - [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", - [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", - [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", - [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", - [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", - [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", - [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", - [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", - [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", - [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", - [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", - [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", - [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", - [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", - [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", - [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", - [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", - [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", - [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", - [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", - [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", - [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", - [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", - [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", - [_IOC_NR(VIDIOC_ENUMAUDIO)] = "VIDIOC_ENUMAUDIO", - [_IOC_NR(VIDIOC_ENUMAUDOUT)] = "VIDIOC_ENUMAUDOUT", - [_IOC_NR(VIDIOC_G_PRIORITY)] = "VIDIOC_G_PRIORITY", - [_IOC_NR(VIDIOC_S_PRIORITY)] = "VIDIOC_S_PRIORITY", -#if 1 - [_IOC_NR(VIDIOC_G_SLICED_VBI_CAP)] = "VIDIOC_G_SLICED_VBI_CAP", +char *v4l2_ioctl_names[256] = { +#if __GNUC__ >= 3 + [0 ... 255] = "UNKNOWN", #endif - [_IOC_NR(VIDIOC_LOG_STATUS)] = "VIDIOC_LOG_STATUS" + [_IOC_NR(VIDIOC_QUERYCAP)] = "VIDIOC_QUERYCAP", + [_IOC_NR(VIDIOC_RESERVED)] = "VIDIOC_RESERVED", + [_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT", + [_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT", + [_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT", + [_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS", + [_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF", + [_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF", + [_IOC_NR(VIDIOC_S_FBUF)] = "VIDIOC_S_FBUF", + [_IOC_NR(VIDIOC_OVERLAY)] = "VIDIOC_OVERLAY", + [_IOC_NR(VIDIOC_QBUF)] = "VIDIOC_QBUF", + [_IOC_NR(VIDIOC_DQBUF)] = "VIDIOC_DQBUF", + [_IOC_NR(VIDIOC_STREAMON)] = "VIDIOC_STREAMON", + [_IOC_NR(VIDIOC_STREAMOFF)] = "VIDIOC_STREAMOFF", + [_IOC_NR(VIDIOC_G_PARM)] = "VIDIOC_G_PARM", + [_IOC_NR(VIDIOC_S_PARM)] = "VIDIOC_S_PARM", + [_IOC_NR(VIDIOC_G_STD)] = "VIDIOC_G_STD", + [_IOC_NR(VIDIOC_S_STD)] = "VIDIOC_S_STD", + [_IOC_NR(VIDIOC_ENUMSTD)] = "VIDIOC_ENUMSTD", + [_IOC_NR(VIDIOC_ENUMINPUT)] = "VIDIOC_ENUMINPUT", + [_IOC_NR(VIDIOC_G_CTRL)] = "VIDIOC_G_CTRL", + [_IOC_NR(VIDIOC_S_CTRL)] = "VIDIOC_S_CTRL", + [_IOC_NR(VIDIOC_G_TUNER)] = "VIDIOC_G_TUNER", + [_IOC_NR(VIDIOC_S_TUNER)] = "VIDIOC_S_TUNER", + [_IOC_NR(VIDIOC_G_AUDIO)] = "VIDIOC_G_AUDIO", + [_IOC_NR(VIDIOC_S_AUDIO)] = "VIDIOC_S_AUDIO", + [_IOC_NR(VIDIOC_QUERYCTRL)] = "VIDIOC_QUERYCTRL", + [_IOC_NR(VIDIOC_QUERYMENU)] = "VIDIOC_QUERYMENU", + [_IOC_NR(VIDIOC_G_INPUT)] = "VIDIOC_G_INPUT", + [_IOC_NR(VIDIOC_S_INPUT)] = "VIDIOC_S_INPUT", + [_IOC_NR(VIDIOC_G_OUTPUT)] = "VIDIOC_G_OUTPUT", + [_IOC_NR(VIDIOC_S_OUTPUT)] = "VIDIOC_S_OUTPUT", + [_IOC_NR(VIDIOC_ENUMOUTPUT)] = "VIDIOC_ENUMOUTPUT", + [_IOC_NR(VIDIOC_G_AUDOUT)] = "VIDIOC_G_AUDOUT", + [_IOC_NR(VIDIOC_S_AUDOUT)] = "VIDIOC_S_AUDOUT", + [_IOC_NR(VIDIOC_G_MODULATOR)] = "VIDIOC_G_MODULATOR", + [_IOC_NR(VIDIOC_S_MODULATOR)] = "VIDIOC_S_MODULATOR", + [_IOC_NR(VIDIOC_G_FREQUENCY)] = "VIDIOC_G_FREQUENCY", + [_IOC_NR(VIDIOC_S_FREQUENCY)] = "VIDIOC_S_FREQUENCY", + [_IOC_NR(VIDIOC_CROPCAP)] = "VIDIOC_CROPCAP", + [_IOC_NR(VIDIOC_G_CROP)] = "VIDIOC_G_CROP", + [_IOC_NR(VIDIOC_S_CROP)] = "VIDIOC_S_CROP", + [_IOC_NR(VIDIOC_G_JPEGCOMP)] = "VIDIOC_G_JPEGCOMP", + [_IOC_NR(VIDIOC_S_JPEGCOMP)] = "VIDIOC_S_JPEGCOMP", + [_IOC_NR(VIDIOC_QUERYSTD)] = "VIDIOC_QUERYSTD", + [_IOC_NR(VIDIOC_TRY_FMT)] = "VIDIOC_TRY_FMT", }; -#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) - -static const char *v4l2_int_ioctls[] = { -#ifdef HAVE_VIDEO_DECODER - [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", - [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", - [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", - [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT", - [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT", - [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT", - [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE", - [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO", - [_IOC_NR(DECODER_INIT)] = "DECODER_INIT", - [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS", - [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP", -#endif - [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", - [_IOC_NR(AUDC_SET_INPUT)] = "AUDC_SET_INPUT", - - [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", - [_IOC_NR(TUNER_SET_STANDBY)] = "TUNER_SET_STANDBY", - [_IOC_NR(TDA9887_SET_CONFIG)] = "TDA9887_SET_CONFIG", - - [_IOC_NR(VIDIOC_INT_S_REGISTER)] = "VIDIOC_INT_S_REGISTER", - [_IOC_NR(VIDIOC_INT_G_REGISTER)] = "VIDIOC_INT_G_REGISTER", - [_IOC_NR(VIDIOC_INT_RESET)] = "VIDIOC_INT_RESET", - [_IOC_NR(VIDIOC_INT_AUDIO_CLOCK_FREQ)] = "VIDIOC_INT_AUDIO_CLOCK_FREQ", - [_IOC_NR(VIDIOC_INT_DECODE_VBI_LINE)] = "VIDIOC_INT_DECODE_VBI_LINE", - [_IOC_NR(VIDIOC_INT_S_VBI_DATA)] = "VIDIOC_INT_S_VBI_DATA", - [_IOC_NR(VIDIOC_INT_G_VBI_DATA)] = "VIDIOC_INT_G_VBI_DATA", - [_IOC_NR(VIDIOC_INT_G_CHIP_IDENT)] = "VIDIOC_INT_G_CHIP_IDENT", - [_IOC_NR(VIDIOC_INT_I2S_CLOCK_FREQ)] = "VIDIOC_INT_I2S_CLOCK_FREQ" -}; -#define V4L2_INT_IOCTLS ARRAY_SIZE(v4l2_int_ioctls) - -/* Common ioctl debug function. This function can be used by - external ioctl messages as well as internal V4L ioctl */ -void v4l_printk_ioctl(unsigned int cmd) -{ - char *dir; - - switch (_IOC_DIR(cmd)) { - case _IOC_NONE: dir = "--"; break; - case _IOC_READ: dir = "r-"; break; - case _IOC_WRITE: dir = "-w"; break; - case _IOC_READ | _IOC_WRITE: dir = "rw"; break; - default: dir = "*ERR*"; break; - } - switch (_IOC_TYPE(cmd)) { - case 'd': - printk("v4l2_int ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? - v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; -#ifdef HAVE_V4L1 - case 'v': - printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L1_IOCTLS) ? - v4l1_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; -#endif - case 'V': - printk("v4l2 ioctl %s, dir=%s (0x%08x)\n", - (_IOC_NR(cmd) < V4L2_IOCTLS) ? - v4l2_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); - break; - - default: - printk("unknown ioctl '%c', dir=%s, #%d (0x%08x)\n", - _IOC_TYPE(cmd), dir, _IOC_NR(cmd), cmd); - } -} /* ----------------------------------------------------------------- */ @@ -374,7 +255,7 @@ EXPORT_SYMBOL(v4l2_prio_check); EXPORT_SYMBOL(v4l2_field_names); EXPORT_SYMBOL(v4l2_type_names); -EXPORT_SYMBOL(v4l_printk_ioctl); +EXPORT_SYMBOL(v4l2_ioctl_names); /* * Local variables: diff --git a/trunk/drivers/media/video/videodev.c b/trunk/drivers/media/video/videodev.c index 9a9902c56ae7..6de5b0094b82 100644 --- a/trunk/drivers/media/video/videodev.c +++ b/trunk/drivers/media/video/videodev.c @@ -68,8 +68,7 @@ static void video_release(struct class_device *cd) { struct video_device *vfd = container_of(cd, struct video_device, class_dev); -#if 1 - /* needed until all drivers are fixed */ +#if 1 /* needed until all drivers are fixed */ if (!vfd->release) return; #endif @@ -339,14 +338,13 @@ int video_register_device(struct video_device *vfd, int type, int nr) if (vfd->dev) vfd->class_dev.dev = vfd->dev; vfd->class_dev.class = &video_class; - vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); + vfd->class_dev.devt = MKDEV(VIDEO_MAJOR, vfd->minor); strlcpy(vfd->class_dev.class_id, vfd->devfs_name + 4, BUS_ID_SIZE); class_device_register(&vfd->class_dev); class_device_create_file(&vfd->class_dev, - &class_device_attr_name); + &class_device_attr_name); -#if 1 - /* needed until all drivers are fixed */ +#if 1 /* needed until all drivers are fixed */ if (!vfd->release) printk(KERN_WARNING "videodev: \"%s\" has no release callback. " "Please fix your driver for proper sysfs support, see " diff --git a/trunk/drivers/media/video/w9966.c b/trunk/drivers/media/video/w9966.c index b7b0afffd214..c318ba32fbaf 100644 --- a/trunk/drivers/media/video/w9966.c +++ b/trunk/drivers/media/video/w9966.c @@ -187,7 +187,6 @@ static struct file_operations w9966_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = w9966_v4l_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .read = w9966_v4l_read, .llseek = no_llseek, }; diff --git a/trunk/drivers/media/video/wm8775.c b/trunk/drivers/media/video/wm8775.c index c2e6d2e9f5f1..bbfd55cd9948 100644 --- a/trunk/drivers/media/video/wm8775.c +++ b/trunk/drivers/media/video/wm8775.c @@ -25,6 +25,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + #include #include #include @@ -32,12 +33,20 @@ #include #include #include -#include +#include MODULE_DESCRIPTION("wm8775 driver"); MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); MODULE_LICENSE("GPL"); +#define wm8775_err(fmt, arg...) do { \ + printk(KERN_ERR "%s %d-%04x: " fmt, client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) +#define wm8775_info(fmt, arg...) do { \ + printk(KERN_INFO "%s %d-%04x: " fmt, client->driver->driver.name, \ + i2c_adapter_id(client->adapter), client->addr , ## arg); } while (0) + + static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END }; @@ -61,7 +70,7 @@ static int wm8775_write(struct i2c_client *client, int reg, u16 val) int i; if (reg < 0 || reg >= TOT_REGS) { - v4l_err(client, "Invalid register R%d\n", reg); + wm8775_err("Invalid register R%d\n", reg); return -1; } @@ -71,7 +80,7 @@ static int wm8775_write(struct i2c_client *client, int reg, u16 val) return 0; } } - v4l_err(client, "I2C: cannot write %03x to register R%d\n", val, reg); + wm8775_err("I2C: cannot write %03x to register R%d\n", val, reg); return -1; } @@ -79,53 +88,38 @@ static int wm8775_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct wm8775_state *state = i2c_get_clientdata(client); - struct v4l2_audio *input = arg; - struct v4l2_control *ctrl = arg; + int *input = arg; switch (cmd) { - case VIDIOC_S_AUDIO: - /* There are 4 inputs and one output. Zero or more inputs - are multiplexed together to the output. Hence there are - 16 combinations. - If only one input is active (the normal case) then the - input values 1, 2, 4 or 8 should be used. */ - if (input->index > 15) { - v4l_err(client, "Invalid input %d.\n", input->index); - return -EINVAL; - } - state->input = input->index; - if (state->muted) - break; + case AUDC_SET_INPUT: wm8775_write(client, R21, 0x0c0); wm8775_write(client, R14, 0x1d4); wm8775_write(client, R15, 0x1d4); - wm8775_write(client, R21, 0x100 + state->input); - break; - - case VIDIOC_G_AUDIO: - memset(input, 0, sizeof(*input)); - input->index = state->input; - break; - - case VIDIOC_G_CTRL: - if (ctrl->id != V4L2_CID_AUDIO_MUTE) - return -EINVAL; - ctrl->value = state->muted; - break; - case VIDIOC_S_CTRL: - if (ctrl->id != V4L2_CID_AUDIO_MUTE) - return -EINVAL; - state->muted = ctrl->value; - wm8775_write(client, R21, 0x0c0); - wm8775_write(client, R14, 0x1d4); - wm8775_write(client, R15, 0x1d4); - if (!state->muted) + if (*input == AUDIO_RADIO) { + wm8775_write(client, R21, 0x108); + state->input = 8; + state->muted = 0; + break; + } + if (*input == AUDIO_MUTE) { + state->muted = 1; + break; + } + if (*input == AUDIO_UNMUTE) { wm8775_write(client, R21, 0x100 + state->input); + state->muted = 0; + break; + } + /* All other inputs... */ + wm8775_write(client, R21, 0x102); + state->input = 2; + state->muted = 0; break; case VIDIOC_LOG_STATUS: - v4l_info(client, "Input: %d%s\n", state->input, + wm8775_info("Input: %s%s\n", + state->input == 8 ? "radio" : "default", state->muted ? " (muted)" : ""); break; @@ -176,7 +170,7 @@ static int wm8775_attach(struct i2c_adapter *adapter, int address, int kind) client->driver = &i2c_driver; snprintf(client->name, sizeof(client->name) - 1, "wm8775"); - v4l_info(client, "chip found @ 0x%x (%s)\n", address << 1, adapter->name); + wm8775_info("chip found @ 0x%x (%s)\n", address << 1, adapter->name); state = kmalloc(sizeof(struct wm8775_state), GFP_KERNEL); if (state == NULL) { @@ -212,7 +206,11 @@ static int wm8775_attach(struct i2c_adapter *adapter, int address, int kind) static int wm8775_probe(struct i2c_adapter *adapter) { +#ifdef I2C_CLASS_TV_ANALOG if (adapter->class & I2C_CLASS_TV_ANALOG) +#else + if (adapter->id == I2C_HW_B_BT848) +#endif return i2c_probe(adapter, &addr_data, wm8775_attach); return 0; } @@ -237,10 +235,12 @@ static struct i2c_driver i2c_driver = { .driver = { .name = "wm8775", }, - .id = I2C_DRIVERID_WM8775, + + .id = I2C_DRIVERID_WM8775, + .attach_adapter = wm8775_probe, - .detach_client = wm8775_detach, - .command = wm8775_command, + .detach_client = wm8775_detach, + .command = wm8775_command, }; diff --git a/trunk/drivers/media/video/zoran_driver.c b/trunk/drivers/media/video/zoran_driver.c index 15283f44e79f..4034f1b45366 100644 --- a/trunk/drivers/media/video/zoran_driver.c +++ b/trunk/drivers/media/video/zoran_driver.c @@ -4678,7 +4678,6 @@ static struct file_operations zoran_fops = { .open = zoran_open, .release = zoran_close, .ioctl = zoran_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, .read = zoran_read, .write = zoran_write, diff --git a/trunk/drivers/media/video/zr36120.c b/trunk/drivers/media/video/zr36120.c index d4c633b8a7f5..07286816d7df 100644 --- a/trunk/drivers/media/video/zr36120.c +++ b/trunk/drivers/media/video/zr36120.c @@ -1490,7 +1490,6 @@ static struct video_device zr36120_template= .write = zoran_write, .poll = zoran_poll, .ioctl = zoran_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .mmap = zoran_mmap, .minor = -1, }; diff --git a/trunk/drivers/message/i2o/i2o_block.c b/trunk/drivers/message/i2o/i2o_block.c index b09fb6307153..5b1febed3133 100644 --- a/trunk/drivers/message/i2o/i2o_block.c +++ b/trunk/drivers/message/i2o/i2o_block.c @@ -662,13 +662,6 @@ static int i2o_block_release(struct inode *inode, struct file *file) return 0; } -static int i2o_block_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - i2o_block_biosparam(get_capacity(bdev->bd_disk), - &geo->cylinders, &geo->heads, &geo->sectors); - return 0; -} - /** * i2o_block_ioctl - Issue device specific ioctl calls. * @cmd: ioctl command @@ -683,6 +676,7 @@ static int i2o_block_ioctl(struct inode *inode, struct file *file, { struct gendisk *disk = inode->i_bdev->bd_disk; struct i2o_block_device *dev = disk->private_data; + void __user *argp = (void __user *)arg; /* Anyone capable of this syscall can do *real bad* things */ @@ -690,6 +684,15 @@ static int i2o_block_ioctl(struct inode *inode, struct file *file, return -EPERM; switch (cmd) { + case HDIO_GETGEO: + { + struct hd_geometry g; + i2o_block_biosparam(get_capacity(disk), + &g.cylinders, &g.heads, &g.sectors); + g.start = get_start_sect(inode->i_bdev); + return copy_to_user(argp, &g, sizeof(g)) ? -EFAULT : 0; + } + case BLKI2OGRSTRAT: return put_user(dev->rcache, (int __user *)arg); case BLKI2OGWSTRAT: @@ -959,7 +962,6 @@ static struct block_device_operations i2o_block_fops = { .open = i2o_block_open, .release = i2o_block_release, .ioctl = i2o_block_ioctl, - .getgeo = i2o_block_getgeo, .media_changed = i2o_block_media_changed }; diff --git a/trunk/drivers/mfd/ucb1x00-core.c b/trunk/drivers/mfd/ucb1x00-core.c index b42e0fbab59b..e335d54c4659 100644 --- a/trunk/drivers/mfd/ucb1x00-core.c +++ b/trunk/drivers/mfd/ucb1x00-core.c @@ -27,6 +27,7 @@ #include #include +#include #include "ucb1x00.h" @@ -506,14 +507,14 @@ static int ucb1x00_probe(struct mcp *mcp) goto err_free; } - ret = request_irq(ucb->irq, ucb1x00_irq, SA_TRIGGER_RISING, - "UCB1x00", ucb); + ret = request_irq(ucb->irq, ucb1x00_irq, 0, "UCB1x00", ucb); if (ret) { printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", ucb->irq, ret); goto err_free; } + set_irq_type(ucb->irq, IRQT_RISING); mcp_set_drvdata(mcp, ucb); ret = class_device_register(&ucb->cdev); diff --git a/trunk/drivers/mfd/ucb1x00-ts.c b/trunk/drivers/mfd/ucb1x00-ts.c index 79fd062ccb34..551061c2eadf 100644 --- a/trunk/drivers/mfd/ucb1x00-ts.c +++ b/trunk/drivers/mfd/ucb1x00-ts.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/mmc/mmc.c b/trunk/drivers/mmc/mmc.c index bfca5c176e88..6696f71363b9 100644 --- a/trunk/drivers/mmc/mmc.c +++ b/trunk/drivers/mmc/mmc.c @@ -495,7 +495,6 @@ static void mmc_decode_cid(struct mmc_card *card) case 2: /* MMC v2.0 - v2.2 */ case 3: /* MMC v3.1 - v3.3 */ - case 4: /* MMC v4 */ card->cid.manfid = UNSTUFF_BITS(resp, 120, 8); card->cid.oemid = UNSTUFF_BITS(resp, 104, 16); card->cid.prod_name[0] = UNSTUFF_BITS(resp, 96, 8); diff --git a/trunk/drivers/mmc/mmc_block.c b/trunk/drivers/mmc/mmc_block.c index f2c42b13945d..198561d21710 100644 --- a/trunk/drivers/mmc/mmc_block.c +++ b/trunk/drivers/mmc/mmc_block.c @@ -113,18 +113,31 @@ static int mmc_blk_release(struct inode *inode, struct file *filp) } static int -mmc_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo) +mmc_blk_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { - geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16); - geo->heads = 4; - geo->sectors = 16; - return 0; + struct block_device *bdev = inode->i_bdev; + + if (cmd == HDIO_GETGEO) { + struct hd_geometry geo; + + memset(&geo, 0, sizeof(struct hd_geometry)); + + geo.cylinders = get_capacity(bdev->bd_disk) / (4 * 16); + geo.heads = 4; + geo.sectors = 16; + geo.start = get_start_sect(bdev); + + return copy_to_user((void __user *)arg, &geo, sizeof(geo)) + ? -EFAULT : 0; + } + + return -ENOTTY; } static struct block_device_operations mmc_bdops = { .open = mmc_blk_open, .release = mmc_blk_release, - .getgeo = mmc_blk_getgeo, + .ioctl = mmc_blk_ioctl, .owner = THIS_MODULE, }; @@ -187,13 +200,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) brq.data.flags |= MMC_DATA_WRITE; brq.data.blocks = 1; } - - if (brq.data.blocks > 1) { - brq.data.flags |= MMC_DATA_MULTI; - brq.mrq.stop = &brq.stop; - } else { - brq.mrq.stop = NULL; - } + brq.mrq.stop = brq.data.blocks > 1 ? &brq.stop : NULL; brq.data.sg = mq->sg; brq.data.sg_len = blk_rq_map_sg(req->q, req, brq.data.sg); diff --git a/trunk/drivers/mmc/wbsd.c b/trunk/drivers/mmc/wbsd.c index f25757625361..4f13bd2ccf9a 100644 --- a/trunk/drivers/mmc/wbsd.c +++ b/trunk/drivers/mmc/wbsd.c @@ -90,7 +90,7 @@ static int dma = 2; * Basic functions */ -static inline void wbsd_unlock_config(struct wbsd_host *host) +static inline void wbsd_unlock_config(struct wbsd_host* host) { BUG_ON(host->config == 0); @@ -98,14 +98,14 @@ static inline void wbsd_unlock_config(struct wbsd_host *host) outb(host->unlock_code, host->config); } -static inline void wbsd_lock_config(struct wbsd_host *host) +static inline void wbsd_lock_config(struct wbsd_host* host) { BUG_ON(host->config == 0); outb(LOCK_CODE, host->config); } -static inline void wbsd_write_config(struct wbsd_host *host, u8 reg, u8 value) +static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value) { BUG_ON(host->config == 0); @@ -113,7 +113,7 @@ static inline void wbsd_write_config(struct wbsd_host *host, u8 reg, u8 value) outb(value, host->config + 1); } -static inline u8 wbsd_read_config(struct wbsd_host *host, u8 reg) +static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg) { BUG_ON(host->config == 0); @@ -121,13 +121,13 @@ static inline u8 wbsd_read_config(struct wbsd_host *host, u8 reg) return inb(host->config + 1); } -static inline void wbsd_write_index(struct wbsd_host *host, u8 index, u8 value) +static inline void wbsd_write_index(struct wbsd_host* host, u8 index, u8 value) { outb(index, host->base + WBSD_IDXR); outb(value, host->base + WBSD_DATAR); } -static inline u8 wbsd_read_index(struct wbsd_host *host, u8 index) +static inline u8 wbsd_read_index(struct wbsd_host* host, u8 index) { outb(index, host->base + WBSD_IDXR); return inb(host->base + WBSD_DATAR); @@ -137,7 +137,7 @@ static inline u8 wbsd_read_index(struct wbsd_host *host, u8 index) * Common routines */ -static void wbsd_init_device(struct wbsd_host *host) +static void wbsd_init_device(struct wbsd_host* host) { u8 setup, ier; @@ -197,7 +197,7 @@ static void wbsd_init_device(struct wbsd_host *host) inb(host->base + WBSD_ISR); } -static void wbsd_reset(struct wbsd_host *host) +static void wbsd_reset(struct wbsd_host* host) { u8 setup; @@ -211,13 +211,14 @@ static void wbsd_reset(struct wbsd_host *host) wbsd_write_index(host, WBSD_IDX_SETUP, setup); } -static void wbsd_request_end(struct wbsd_host *host, struct mmc_request *mrq) +static void wbsd_request_end(struct wbsd_host* host, struct mmc_request* mrq) { unsigned long dmaflags; DBGF("Ending request, cmd (%x)\n", mrq->cmd->opcode); - if (host->dma >= 0) { + if (host->dma >= 0) + { /* * Release ISA DMA controller. */ @@ -246,7 +247,7 @@ static void wbsd_request_end(struct wbsd_host *host, struct mmc_request *mrq) * Scatter/gather functions */ -static inline void wbsd_init_sg(struct wbsd_host *host, struct mmc_data *data) +static inline void wbsd_init_sg(struct wbsd_host* host, struct mmc_data* data) { /* * Get info. about SG list from data structure. @@ -258,7 +259,7 @@ static inline void wbsd_init_sg(struct wbsd_host *host, struct mmc_data *data) host->remain = host->cur_sg->length; } -static inline int wbsd_next_sg(struct wbsd_host *host) +static inline int wbsd_next_sg(struct wbsd_host* host) { /* * Skip to next SG entry. @@ -269,32 +270,33 @@ static inline int wbsd_next_sg(struct wbsd_host *host) /* * Any entries left? */ - if (host->num_sg > 0) { - host->offset = 0; - host->remain = host->cur_sg->length; - } + if (host->num_sg > 0) + { + host->offset = 0; + host->remain = host->cur_sg->length; + } return host->num_sg; } -static inline char *wbsd_kmap_sg(struct wbsd_host *host) +static inline char* wbsd_kmap_sg(struct wbsd_host* host) { host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) + host->cur_sg->offset; return host->mapped_sg; } -static inline void wbsd_kunmap_sg(struct wbsd_host *host) +static inline void wbsd_kunmap_sg(struct wbsd_host* host) { kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ); } -static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) +static inline void wbsd_sg_to_dma(struct wbsd_host* host, struct mmc_data* data) { unsigned int len, i, size; - struct scatterlist *sg; - char *dmabuf = host->dma_buffer; - char *sgbuf; + struct scatterlist* sg; + char* dmabuf = host->dma_buffer; + char* sgbuf; size = host->size; @@ -306,7 +308,8 @@ static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) * be the entire list though so make sure that * we do not transfer too much. */ - for (i = 0; i < len; i++) { + for (i = 0;i < len;i++) + { sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset; if (size < sg[i].length) memcpy(dmabuf, sgbuf, size); @@ -334,12 +337,12 @@ static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data) host->size -= size; } -static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) +static inline void wbsd_dma_to_sg(struct wbsd_host* host, struct mmc_data* data) { unsigned int len, i, size; - struct scatterlist *sg; - char *dmabuf = host->dma_buffer; - char *sgbuf; + struct scatterlist* sg; + char* dmabuf = host->dma_buffer; + char* sgbuf; size = host->size; @@ -351,7 +354,8 @@ static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) * be the entire list though so make sure that * we do not transfer too much. */ - for (i = 0; i < len; i++) { + for (i = 0;i < len;i++) + { sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset; if (size < sg[i].length) memcpy(sgbuf, dmabuf, size); @@ -383,38 +387,46 @@ static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data) * Command handling */ -static inline void wbsd_get_short_reply(struct wbsd_host *host, - struct mmc_command *cmd) +static inline void wbsd_get_short_reply(struct wbsd_host* host, + struct mmc_command* cmd) { /* * Correct response type? */ - if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_SHORT) { + if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_SHORT) + { cmd->error = MMC_ERR_INVALID; return; } - cmd->resp[0] = wbsd_read_index(host, WBSD_IDX_RESP12) << 24; - cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP13) << 16; - cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP14) << 8; - cmd->resp[0] |= wbsd_read_index(host, WBSD_IDX_RESP15) << 0; - cmd->resp[1] = wbsd_read_index(host, WBSD_IDX_RESP16) << 24; + cmd->resp[0] = + wbsd_read_index(host, WBSD_IDX_RESP12) << 24; + cmd->resp[0] |= + wbsd_read_index(host, WBSD_IDX_RESP13) << 16; + cmd->resp[0] |= + wbsd_read_index(host, WBSD_IDX_RESP14) << 8; + cmd->resp[0] |= + wbsd_read_index(host, WBSD_IDX_RESP15) << 0; + cmd->resp[1] = + wbsd_read_index(host, WBSD_IDX_RESP16) << 24; } -static inline void wbsd_get_long_reply(struct wbsd_host *host, - struct mmc_command *cmd) +static inline void wbsd_get_long_reply(struct wbsd_host* host, + struct mmc_command* cmd) { int i; /* * Correct response type? */ - if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_LONG) { + if (wbsd_read_index(host, WBSD_IDX_RSPLEN) != WBSD_RSP_LONG) + { cmd->error = MMC_ERR_INVALID; return; } - for (i = 0; i < 4; i++) { + for (i = 0;i < 4;i++) + { cmd->resp[i] = wbsd_read_index(host, WBSD_IDX_RESP1 + i * 4) << 24; cmd->resp[i] |= @@ -426,7 +438,7 @@ static inline void wbsd_get_long_reply(struct wbsd_host *host, } } -static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) +static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) { int i; u8 status, isr; @@ -444,7 +456,7 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) * Send the command (CRC calculated by host). */ outb(cmd->opcode, host->base + WBSD_CMDR); - for (i = 3; i >= 0; i--) + for (i = 3;i >= 0;i--) outb((cmd->arg >> (i * 8)) & 0xff, host->base + WBSD_CMDR); cmd->error = MMC_ERR_NONE; @@ -459,7 +471,8 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) /* * Do we expect a reply? */ - if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE) { + if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE) + { /* * Read back status. */ @@ -475,7 +488,8 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) else if ((cmd->flags & MMC_RSP_CRC) && (isr & WBSD_INT_CRC)) cmd->error = MMC_ERR_BADCRC; /* All ok */ - else { + else + { if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) wbsd_get_short_reply(host, cmd); else @@ -490,10 +504,10 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) * Data functions */ -static void wbsd_empty_fifo(struct wbsd_host *host) +static void wbsd_empty_fifo(struct wbsd_host* host) { - struct mmc_data *data = host->mrq->cmd->data; - char *buffer; + struct mmc_data* data = host->mrq->cmd->data; + char* buffer; int i, fsr, fifo; /* @@ -508,7 +522,8 @@ static void wbsd_empty_fifo(struct wbsd_host *host) * Drain the fifo. This has a tendency to loop longer * than the FIFO length (usually one block). */ - while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_EMPTY)) { + while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_EMPTY)) + { /* * The size field in the FSR is broken so we have to * do some guessing. @@ -520,7 +535,8 @@ static void wbsd_empty_fifo(struct wbsd_host *host) else fifo = 1; - for (i = 0; i < fifo; i++) { + for (i = 0;i < fifo;i++) + { *buffer = inb(host->base + WBSD_DFR); buffer++; host->offset++; @@ -531,7 +547,8 @@ static void wbsd_empty_fifo(struct wbsd_host *host) /* * Transfer done? */ - if (data->bytes_xfered == host->size) { + if (data->bytes_xfered == host->size) + { wbsd_kunmap_sg(host); return; } @@ -539,13 +556,15 @@ static void wbsd_empty_fifo(struct wbsd_host *host) /* * End of scatter list entry? */ - if (host->remain == 0) { + if (host->remain == 0) + { wbsd_kunmap_sg(host); /* * Get next entry. Check if last. */ - if (!wbsd_next_sg(host)) { + if (!wbsd_next_sg(host)) + { /* * We should never reach this point. * It means that we're trying to @@ -575,10 +594,10 @@ static void wbsd_empty_fifo(struct wbsd_host *host) tasklet_schedule(&host->fifo_tasklet); } -static void wbsd_fill_fifo(struct wbsd_host *host) +static void wbsd_fill_fifo(struct wbsd_host* host) { - struct mmc_data *data = host->mrq->cmd->data; - char *buffer; + struct mmc_data* data = host->mrq->cmd->data; + char* buffer; int i, fsr, fifo; /* @@ -594,7 +613,8 @@ static void wbsd_fill_fifo(struct wbsd_host *host) * Fill the fifo. This has a tendency to loop longer * than the FIFO length (usually one block). */ - while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_FULL)) { + while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_FULL)) + { /* * The size field in the FSR is broken so we have to * do some guessing. @@ -606,7 +626,8 @@ static void wbsd_fill_fifo(struct wbsd_host *host) else fifo = 15; - for (i = 16; i > fifo; i--) { + for (i = 16;i > fifo;i--) + { outb(*buffer, host->base + WBSD_DFR); buffer++; host->offset++; @@ -617,7 +638,8 @@ static void wbsd_fill_fifo(struct wbsd_host *host) /* * Transfer done? */ - if (data->bytes_xfered == host->size) { + if (data->bytes_xfered == host->size) + { wbsd_kunmap_sg(host); return; } @@ -625,13 +647,15 @@ static void wbsd_fill_fifo(struct wbsd_host *host) /* * End of scatter list entry? */ - if (host->remain == 0) { + if (host->remain == 0) + { wbsd_kunmap_sg(host); /* * Get next entry. Check if last. */ - if (!wbsd_next_sg(host)) { + if (!wbsd_next_sg(host)) + { /* * We should never reach this point. * It means that we're trying to @@ -660,7 +684,7 @@ static void wbsd_fill_fifo(struct wbsd_host *host) tasklet_schedule(&host->fifo_tasklet); } -static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) +static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) { u16 blksize; u8 setup; @@ -682,10 +706,8 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) */ if (data->timeout_ns > 127000000) wbsd_write_index(host, WBSD_IDX_TAAC, 127); - else { - wbsd_write_index(host, WBSD_IDX_TAAC, - data->timeout_ns / 1000000); - } + else + wbsd_write_index(host, WBSD_IDX_TAAC, data->timeout_ns/1000000); if (data->timeout_clks > 255) wbsd_write_index(host, WBSD_IDX_NSAC, 255); @@ -700,18 +722,23 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) * Space for CRC must be included in the size. * Two bytes are needed for each data line. */ - if (host->bus_width == MMC_BUS_WIDTH_1) { + if (host->bus_width == MMC_BUS_WIDTH_1) + { blksize = (1 << data->blksz_bits) + 2; wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0); wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); - } else if (host->bus_width == MMC_BUS_WIDTH_4) { + } + else if (host->bus_width == MMC_BUS_WIDTH_4) + { blksize = (1 << data->blksz_bits) + 2 * 4; - wbsd_write_index(host, WBSD_IDX_PBSMSB, - ((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH); + wbsd_write_index(host, WBSD_IDX_PBSMSB, ((blksize >> 4) & 0xF0) + | WBSD_DATA_WIDTH); wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF); - } else { + } + else + { data->error = MMC_ERR_INVALID; return; } @@ -728,12 +755,14 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) /* * DMA transfer? */ - if (host->dma >= 0) { + if (host->dma >= 0) + { /* * The buffer for DMA is only 64 kB. */ BUG_ON(host->size > 0x10000); - if (host->size > 0x10000) { + if (host->size > 0x10000) + { data->error = MMC_ERR_INVALID; return; } @@ -765,7 +794,9 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) * Enable DMA on the host. */ wbsd_write_index(host, WBSD_IDX_DMA, WBSD_DMA_ENABLE); - } else { + } + else + { /* * This flag is used to keep printk * output to a minimum. @@ -786,10 +817,13 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) * Set up FIFO threshold levels (and fill * buffer if doing a write). */ - if (data->flags & MMC_DATA_READ) { + if (data->flags & MMC_DATA_READ) + { wbsd_write_index(host, WBSD_IDX_FIFOEN, WBSD_FIFOEN_FULL | 8); - } else { + } + else + { wbsd_write_index(host, WBSD_IDX_FIFOEN, WBSD_FIFOEN_EMPTY | 8); wbsd_fill_fifo(host); @@ -799,7 +833,7 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data) data->error = MMC_ERR_NONE; } -static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) +static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) { unsigned long dmaflags; int count; @@ -817,14 +851,16 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) * Wait for the controller to leave data * transfer state. */ - do { + do + { status = wbsd_read_index(host, WBSD_IDX_STATUS); } while (status & (WBSD_BLOCK_READ | WBSD_BLOCK_WRITE)); /* * DMA transfer? */ - if (host->dma >= 0) { + if (host->dma >= 0) + { /* * Disable DMA on the host. */ @@ -842,13 +878,16 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) /* * Any leftover data? */ - if (count) { + if (count) + { printk(KERN_ERR "%s: Incomplete DMA transfer. " "%d bytes left.\n", mmc_hostname(host->mmc), count); data->error = MMC_ERR_FAILED; - } else { + } + else + { /* * Transfer data from DMA buffer to * SG list. @@ -871,10 +910,10 @@ static void wbsd_finish_data(struct wbsd_host *host, struct mmc_data *data) * * \*****************************************************************************/ -static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) +static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) { - struct wbsd_host *host = mmc_priv(mmc); - struct mmc_command *cmd; + struct wbsd_host* host = mmc_priv(mmc); + struct mmc_command* cmd; /* * Disable tasklets to avoid a deadlock. @@ -891,7 +930,8 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) * If there is no card in the slot then * timeout immediatly. */ - if (!(host->flags & WBSD_FCARD_PRESENT)) { + if (!(host->flags & WBSD_FCARD_PRESENT)) + { cmd->error = MMC_ERR_TIMEOUT; goto done; } @@ -899,7 +939,8 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) /* * Does the request include data? */ - if (cmd->data) { + if (cmd->data) + { wbsd_prepare_data(host, cmd->data); if (cmd->data->error != MMC_ERR_NONE) @@ -913,7 +954,8 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) * will be finished after the data has * transfered. */ - if (cmd->data && (cmd->error == MMC_ERR_NONE)) { + if (cmd->data && (cmd->error == MMC_ERR_NONE)) + { /* * Dirty fix for hardware bug. */ @@ -931,14 +973,14 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq) spin_unlock_bh(&host->lock); } -static void wbsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) { - struct wbsd_host *host = mmc_priv(mmc); + struct wbsd_host* host = mmc_priv(mmc); u8 clk, setup, pwr; DBGF("clock %uHz busmode %u powermode %u cs %u Vdd %u width %u\n", - ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, - ios->vdd, ios->bus_width); + ios->clock, ios->bus_mode, ios->power_mode, ios->chip_select, + ios->vdd, ios->bus_width); spin_lock_bh(&host->lock); @@ -962,7 +1004,8 @@ static void wbsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * Only write to the clock register when * there is an actual change. */ - if (clk != host->clk) { + if (clk != host->clk) + { wbsd_write_index(host, WBSD_IDX_CLK, clk); host->clk = clk; } @@ -970,7 +1013,8 @@ static void wbsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) /* * Power up card. */ - if (ios->power_mode != MMC_POWER_OFF) { + if (ios->power_mode != MMC_POWER_OFF) + { pwr = inb(host->base + WBSD_CSR); pwr &= ~WBSD_POWER_N; outb(pwr, host->base + WBSD_CSR); @@ -982,19 +1026,23 @@ static void wbsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * that needs to be disabled. */ setup = wbsd_read_index(host, WBSD_IDX_SETUP); - if (ios->chip_select == MMC_CS_HIGH) { + if (ios->chip_select == MMC_CS_HIGH) + { BUG_ON(ios->bus_width != MMC_BUS_WIDTH_1); setup |= WBSD_DAT3_H; host->flags |= WBSD_FIGNORE_DETECT; - } else { - if (setup & WBSD_DAT3_H) { + } + else + { + if (setup & WBSD_DAT3_H) + { setup &= ~WBSD_DAT3_H; /* * We cannot resume card detection immediatly * because of capacitance and delays in the chip. */ - mod_timer(&host->ignore_timer, jiffies + HZ / 100); + mod_timer(&host->ignore_timer, jiffies + HZ/100); } } wbsd_write_index(host, WBSD_IDX_SETUP, setup); @@ -1008,9 +1056,9 @@ static void wbsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) spin_unlock_bh(&host->lock); } -static int wbsd_get_ro(struct mmc_host *mmc) +static int wbsd_get_ro(struct mmc_host* mmc) { - struct wbsd_host *host = mmc_priv(mmc); + struct wbsd_host* host = mmc_priv(mmc); u8 csr; spin_lock_bh(&host->lock); @@ -1048,7 +1096,7 @@ static struct mmc_host_ops wbsd_ops = { static void wbsd_reset_ignore(unsigned long data) { - struct wbsd_host *host = (struct wbsd_host *)data; + struct wbsd_host *host = (struct wbsd_host*)data; BUG_ON(host == NULL); @@ -1071,7 +1119,7 @@ static void wbsd_reset_ignore(unsigned long data) * Tasklets */ -static inline struct mmc_data *wbsd_get_data(struct wbsd_host *host) +static inline struct mmc_data* wbsd_get_data(struct wbsd_host* host) { WARN_ON(!host->mrq); if (!host->mrq) @@ -1090,13 +1138,14 @@ static inline struct mmc_data *wbsd_get_data(struct wbsd_host *host) static void wbsd_tasklet_card(unsigned long param) { - struct wbsd_host *host = (struct wbsd_host *)param; + struct wbsd_host* host = (struct wbsd_host*)param; u8 csr; int delay = -1; spin_lock(&host->lock); - if (host->flags & WBSD_FIGNORE_DETECT) { + if (host->flags & WBSD_FIGNORE_DETECT) + { spin_unlock(&host->lock); return; } @@ -1104,18 +1153,23 @@ static void wbsd_tasklet_card(unsigned long param) csr = inb(host->base + WBSD_CSR); WARN_ON(csr == 0xff); - if (csr & WBSD_CARDPRESENT) { - if (!(host->flags & WBSD_FCARD_PRESENT)) { + if (csr & WBSD_CARDPRESENT) + { + if (!(host->flags & WBSD_FCARD_PRESENT)) + { DBG("Card inserted\n"); host->flags |= WBSD_FCARD_PRESENT; delay = 500; } - } else if (host->flags & WBSD_FCARD_PRESENT) { + } + else if (host->flags & WBSD_FCARD_PRESENT) + { DBG("Card removed\n"); host->flags &= ~WBSD_FCARD_PRESENT; - if (host->mrq) { + if (host->mrq) + { printk(KERN_ERR "%s: Card removed during transfer!\n", mmc_hostname(host->mmc)); wbsd_reset(host); @@ -1139,8 +1193,8 @@ static void wbsd_tasklet_card(unsigned long param) static void wbsd_tasklet_fifo(unsigned long param) { - struct wbsd_host *host = (struct wbsd_host *)param; - struct mmc_data *data; + struct wbsd_host* host = (struct wbsd_host*)param; + struct mmc_data* data; spin_lock(&host->lock); @@ -1159,7 +1213,8 @@ static void wbsd_tasklet_fifo(unsigned long param) /* * Done? */ - if (host->size == data->bytes_xfered) { + if (host->size == data->bytes_xfered) + { wbsd_write_index(host, WBSD_IDX_FIFOEN, 0); tasklet_schedule(&host->finish_tasklet); } @@ -1170,8 +1225,8 @@ static void wbsd_tasklet_fifo(unsigned long param) static void wbsd_tasklet_crc(unsigned long param) { - struct wbsd_host *host = (struct wbsd_host *)param; - struct mmc_data *data; + struct wbsd_host* host = (struct wbsd_host*)param; + struct mmc_data* data; spin_lock(&host->lock); @@ -1194,8 +1249,8 @@ static void wbsd_tasklet_crc(unsigned long param) static void wbsd_tasklet_timeout(unsigned long param) { - struct wbsd_host *host = (struct wbsd_host *)param; - struct mmc_data *data; + struct wbsd_host* host = (struct wbsd_host*)param; + struct mmc_data* data; spin_lock(&host->lock); @@ -1218,8 +1273,8 @@ static void wbsd_tasklet_timeout(unsigned long param) static void wbsd_tasklet_finish(unsigned long param) { - struct wbsd_host *host = (struct wbsd_host *)param; - struct mmc_data *data; + struct wbsd_host* host = (struct wbsd_host*)param; + struct mmc_data* data; spin_lock(&host->lock); @@ -1239,13 +1294,14 @@ static void wbsd_tasklet_finish(unsigned long param) static void wbsd_tasklet_block(unsigned long param) { - struct wbsd_host *host = (struct wbsd_host *)param; - struct mmc_data *data; + struct wbsd_host* host = (struct wbsd_host*)param; + struct mmc_data* data; spin_lock(&host->lock); if ((wbsd_read_index(host, WBSD_IDX_CRCSTATUS) & WBSD_CRC_MASK) != - WBSD_CRC_OK) { + WBSD_CRC_OK) + { data = wbsd_get_data(host); if (!data) goto end; @@ -1267,7 +1323,7 @@ static void wbsd_tasklet_block(unsigned long param) static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs) { - struct wbsd_host *host = dev_id; + struct wbsd_host* host = dev_id; int isr; isr = inb(host->base + WBSD_ISR); @@ -1309,10 +1365,10 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs) * Allocate/free MMC structure. */ -static int __devinit wbsd_alloc_mmc(struct device *dev) +static int __devinit wbsd_alloc_mmc(struct device* dev) { - struct mmc_host *mmc; - struct wbsd_host *host; + struct mmc_host* mmc; + struct wbsd_host* host; /* * Allocate MMC structure. @@ -1332,7 +1388,7 @@ static int __devinit wbsd_alloc_mmc(struct device *dev) mmc->ops = &wbsd_ops; mmc->f_min = 375000; mmc->f_max = 24000000; - mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; mmc->caps = MMC_CAP_4_BIT_DATA; spin_lock_init(&host->lock); @@ -1368,10 +1424,10 @@ static int __devinit wbsd_alloc_mmc(struct device *dev) return 0; } -static void __devexit wbsd_free_mmc(struct device *dev) +static void __devexit wbsd_free_mmc(struct device* dev) { - struct mmc_host *mmc; - struct wbsd_host *host; + struct mmc_host* mmc; + struct wbsd_host* host; mmc = dev_get_drvdata(dev); if (!mmc) @@ -1391,7 +1447,7 @@ static void __devexit wbsd_free_mmc(struct device *dev) * Scan for known chip id:s */ -static int __devinit wbsd_scan(struct wbsd_host *host) +static int __devinit wbsd_scan(struct wbsd_host* host) { int i, j, k; int id; @@ -1421,14 +1477,16 @@ static int __devinit wbsd_scan(struct wbsd_host *host) wbsd_lock_config(host); for (k = 0; k < ARRAY_SIZE(valid_ids); k++) { - if (id == valid_ids[k]) { + if (id == valid_ids[k]) + { host->chip_id = id; return 0; } } - if (id != 0xFFFF) { + if (id != 0xFFFF) + { DBG("Unknown hardware (id %x) found at %x\n", id, config_ports[i]); } @@ -1447,7 +1505,7 @@ static int __devinit wbsd_scan(struct wbsd_host *host) * Allocate/free io port ranges */ -static int __devinit wbsd_request_region(struct wbsd_host *host, int base) +static int __devinit wbsd_request_region(struct wbsd_host* host, int base) { if (io & 0x7) return -EINVAL; @@ -1460,7 +1518,7 @@ static int __devinit wbsd_request_region(struct wbsd_host *host, int base) return 0; } -static void __devexit wbsd_release_regions(struct wbsd_host *host) +static void __devexit wbsd_release_regions(struct wbsd_host* host) { if (host->base) release_region(host->base, 8); @@ -1477,7 +1535,7 @@ static void __devexit wbsd_release_regions(struct wbsd_host *host) * Allocate/free DMA port and buffer */ -static void __devinit wbsd_request_dma(struct wbsd_host *host, int dma) +static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma) { if (dma < 0) return; @@ -1521,8 +1579,8 @@ static void __devinit wbsd_request_dma(struct wbsd_host *host, int dma) */ BUG_ON(1); - dma_unmap_single(host->mmc->dev, host->dma_addr, - WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); + dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, + DMA_BIDIRECTIONAL); host->dma_addr = (dma_addr_t)NULL; kfree(host->dma_buffer); @@ -1536,12 +1594,11 @@ static void __devinit wbsd_request_dma(struct wbsd_host *host, int dma) "Falling back on FIFO.\n", dma); } -static void __devexit wbsd_release_dma(struct wbsd_host *host) +static void __devexit wbsd_release_dma(struct wbsd_host* host) { - if (host->dma_addr) { - dma_unmap_single(host->mmc->dev, host->dma_addr, - WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); - } + if (host->dma_addr) + dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, + DMA_BIDIRECTIONAL); kfree(host->dma_buffer); if (host->dma >= 0) free_dma(host->dma); @@ -1555,7 +1612,7 @@ static void __devexit wbsd_release_dma(struct wbsd_host *host) * Allocate/free IRQ. */ -static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq) +static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq) { int ret; @@ -1572,23 +1629,17 @@ static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq) /* * Set up tasklets. */ - tasklet_init(&host->card_tasklet, wbsd_tasklet_card, - (unsigned long)host); - tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, - (unsigned long)host); - tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, - (unsigned long)host); - tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, - (unsigned long)host); - tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, - (unsigned long)host); - tasklet_init(&host->block_tasklet, wbsd_tasklet_block, - (unsigned long)host); + tasklet_init(&host->card_tasklet, wbsd_tasklet_card, (unsigned long)host); + tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, (unsigned long)host); + tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, (unsigned long)host); + tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host); + tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host); + tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host); return 0; } -static void __devexit wbsd_release_irq(struct wbsd_host *host) +static void __devexit wbsd_release_irq(struct wbsd_host* host) { if (!host->irq) return; @@ -1609,7 +1660,7 @@ static void __devexit wbsd_release_irq(struct wbsd_host *host) * Allocate all resources for the host. */ -static int __devinit wbsd_request_resources(struct wbsd_host *host, +static int __devinit wbsd_request_resources(struct wbsd_host* host, int base, int irq, int dma) { int ret; @@ -1640,7 +1691,7 @@ static int __devinit wbsd_request_resources(struct wbsd_host *host, * Release all resources for the host. */ -static void __devexit wbsd_release_resources(struct wbsd_host *host) +static void __devexit wbsd_release_resources(struct wbsd_host* host) { wbsd_release_dma(host); wbsd_release_irq(host); @@ -1651,7 +1702,7 @@ static void __devexit wbsd_release_resources(struct wbsd_host *host) * Configure the resources the chip should use. */ -static void wbsd_chip_config(struct wbsd_host *host) +static void wbsd_chip_config(struct wbsd_host* host) { wbsd_unlock_config(host); @@ -1695,7 +1746,7 @@ static void wbsd_chip_config(struct wbsd_host *host) * Check that configured resources are correct. */ -static int wbsd_chip_validate(struct wbsd_host *host) +static int wbsd_chip_validate(struct wbsd_host* host) { int base, irq, dma; @@ -1735,7 +1786,7 @@ static int wbsd_chip_validate(struct wbsd_host *host) * Powers down the SD function */ -static void wbsd_chip_poweroff(struct wbsd_host *host) +static void wbsd_chip_poweroff(struct wbsd_host* host) { wbsd_unlock_config(host); @@ -1751,11 +1802,11 @@ static void wbsd_chip_poweroff(struct wbsd_host *host) * * \*****************************************************************************/ -static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma, +static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, int pnp) { - struct wbsd_host *host = NULL; - struct mmc_host *mmc = NULL; + struct wbsd_host* host = NULL; + struct mmc_host* mmc = NULL; int ret; ret = wbsd_alloc_mmc(dev); @@ -1769,12 +1820,16 @@ static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma, * Scan for hardware. */ ret = wbsd_scan(host); - if (ret) { - if (pnp && (ret == -ENODEV)) { + if (ret) + { + if (pnp && (ret == -ENODEV)) + { printk(KERN_WARNING DRIVER_NAME ": Unable to confirm device presence. You may " "experience lock-ups.\n"); - } else { + } + else + { wbsd_free_mmc(dev); return ret; } @@ -1784,7 +1839,8 @@ static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma, * Request resources. */ ret = wbsd_request_resources(host, io, irq, dma); - if (ret) { + if (ret) + { wbsd_release_resources(host); wbsd_free_mmc(dev); return ret; @@ -1793,15 +1849,18 @@ static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma, /* * See if chip needs to be configured. */ - if (pnp) { - if ((host->config != 0) && !wbsd_chip_validate(host)) { + if (pnp) + { + if ((host->config != 0) && !wbsd_chip_validate(host)) + { printk(KERN_WARNING DRIVER_NAME ": PnP active but chip not configured! " "You probably have a buggy BIOS. " "Configuring chip manually.\n"); wbsd_chip_config(host); } - } else + } + else wbsd_chip_config(host); /* @@ -1809,7 +1868,8 @@ static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma, * Not tested. */ #ifdef CONFIG_PM - if (host->config) { + if (host->config) + { wbsd_unlock_config(host); wbsd_write_config(host, WBSD_CONF_PME, 0xA0); wbsd_lock_config(host); @@ -1842,10 +1902,10 @@ static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma, return 0; } -static void __devexit wbsd_shutdown(struct device *dev, int pnp) +static void __devexit wbsd_shutdown(struct device* dev, int pnp) { - struct mmc_host *mmc = dev_get_drvdata(dev); - struct wbsd_host *host; + struct mmc_host* mmc = dev_get_drvdata(dev); + struct wbsd_host* host; if (!mmc) return; @@ -1869,12 +1929,12 @@ static void __devexit wbsd_shutdown(struct device *dev, int pnp) * Non-PnP */ -static int __devinit wbsd_probe(struct platform_device *dev) +static int __devinit wbsd_probe(struct platform_device* dev) { return wbsd_init(&dev->dev, io, irq, dma, 0); } -static int __devexit wbsd_remove(struct platform_device *dev) +static int __devexit wbsd_remove(struct platform_device* dev) { wbsd_shutdown(&dev->dev, 0); @@ -1888,7 +1948,7 @@ static int __devexit wbsd_remove(struct platform_device *dev) #ifdef CONFIG_PNP static int __devinit -wbsd_pnp_probe(struct pnp_dev *pnpdev, const struct pnp_device_id *dev_id) +wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id) { int io, irq, dma; @@ -1907,7 +1967,7 @@ wbsd_pnp_probe(struct pnp_dev *pnpdev, const struct pnp_device_id *dev_id) return wbsd_init(&pnpdev->dev, io, irq, dma, 1); } -static void __devexit wbsd_pnp_remove(struct pnp_dev *dev) +static void __devexit wbsd_pnp_remove(struct pnp_dev * dev) { wbsd_shutdown(&dev->dev, 1); } @@ -1920,54 +1980,37 @@ static void __devexit wbsd_pnp_remove(struct pnp_dev *dev) #ifdef CONFIG_PM -static int wbsd_suspend(struct wbsd_host *host, pm_message_t state) -{ - BUG_ON(host == NULL); - - return mmc_suspend_host(host->mmc, state); -} - -static int wbsd_resume(struct wbsd_host *host) -{ - BUG_ON(host == NULL); - - wbsd_init_device(host); - - return mmc_resume_host(host->mmc); -} - -static int wbsd_platform_suspend(struct platform_device *dev, - pm_message_t state) +static int wbsd_suspend(struct platform_device *dev, pm_message_t state) { struct mmc_host *mmc = platform_get_drvdata(dev); struct wbsd_host *host; int ret; - if (mmc == NULL) + if (!mmc) return 0; - DBGF("Suspending...\n"); - - host = mmc_priv(mmc); + DBG("Suspending...\n"); - ret = wbsd_suspend(host, state); - if (ret) + ret = mmc_suspend_host(mmc, state); + if (!ret) return ret; + host = mmc_priv(mmc); + wbsd_chip_poweroff(host); return 0; } -static int wbsd_platform_resume(struct platform_device *dev) +static int wbsd_resume(struct platform_device *dev) { struct mmc_host *mmc = platform_get_drvdata(dev); struct wbsd_host *host; - if (mmc == NULL) + if (!mmc) return 0; - DBGF("Resuming...\n"); + DBG("Resuming...\n"); host = mmc_priv(mmc); @@ -1978,68 +2021,15 @@ static int wbsd_platform_resume(struct platform_device *dev) */ mdelay(5); - return wbsd_resume(host); -} - -#ifdef CONFIG_PNP - -static int wbsd_pnp_suspend(struct pnp_dev *pnp_dev, pm_message_t state) -{ - struct mmc_host *mmc = dev_get_drvdata(&pnp_dev->dev); - struct wbsd_host *host; - - if (mmc == NULL) - return 0; - - DBGF("Suspending...\n"); - - host = mmc_priv(mmc); - - return wbsd_suspend(host, state); -} - -static int wbsd_pnp_resume(struct pnp_dev *pnp_dev) -{ - struct mmc_host *mmc = dev_get_drvdata(&pnp_dev->dev); - struct wbsd_host *host; - - if (mmc == NULL) - return 0; - - DBGF("Resuming...\n"); - - host = mmc_priv(mmc); - - /* - * See if chip needs to be configured. - */ - if (host->config != 0) { - if (!wbsd_chip_validate(host)) { - printk(KERN_WARNING DRIVER_NAME - ": PnP active but chip not configured! " - "You probably have a buggy BIOS. " - "Configuring chip manually.\n"); - wbsd_chip_config(host); - } - } - - /* - * Allow device to initialise itself properly. - */ - mdelay(5); + wbsd_init_device(host); - return wbsd_resume(host); + return mmc_resume_host(mmc); } -#endif /* CONFIG_PNP */ - #else /* CONFIG_PM */ -#define wbsd_platform_suspend NULL -#define wbsd_platform_resume NULL - -#define wbsd_pnp_suspend NULL -#define wbsd_pnp_resume NULL +#define wbsd_suspend NULL +#define wbsd_resume NULL #endif /* CONFIG_PM */ @@ -2049,8 +2039,8 @@ static struct platform_driver wbsd_driver = { .probe = wbsd_probe, .remove = __devexit_p(wbsd_remove), - .suspend = wbsd_platform_suspend, - .resume = wbsd_platform_resume, + .suspend = wbsd_suspend, + .resume = wbsd_resume, .driver = { .name = DRIVER_NAME, }, @@ -2063,9 +2053,6 @@ static struct pnp_driver wbsd_pnp_driver = { .id_table = pnp_dev_table, .probe = wbsd_pnp_probe, .remove = __devexit_p(wbsd_pnp_remove), - - .suspend = wbsd_pnp_suspend, - .resume = wbsd_pnp_resume, }; #endif /* CONFIG_PNP */ @@ -2085,26 +2072,31 @@ static int __init wbsd_drv_init(void) #ifdef CONFIG_PNP - if (!nopnp) { + if (!nopnp) + { result = pnp_register_driver(&wbsd_pnp_driver); if (result < 0) return result; } + #endif /* CONFIG_PNP */ - if (nopnp) { + if (nopnp) + { result = platform_driver_register(&wbsd_driver); if (result < 0) return result; wbsd_device = platform_device_alloc(DRIVER_NAME, -1); - if (!wbsd_device) { + if (!wbsd_device) + { platform_driver_unregister(&wbsd_driver); return -ENOMEM; } result = platform_device_add(wbsd_device); - if (result) { + if (result) + { platform_device_put(wbsd_device); platform_driver_unregister(&wbsd_driver); return result; @@ -2123,7 +2115,8 @@ static void __exit wbsd_drv_exit(void) #endif /* CONFIG_PNP */ - if (nopnp) { + if (nopnp) + { platform_device_unregister(wbsd_device); platform_driver_unregister(&wbsd_driver); diff --git a/trunk/drivers/mtd/maps/Kconfig b/trunk/drivers/mtd/maps/Kconfig index b9b77cf39a18..7abd7fee0dda 100644 --- a/trunk/drivers/mtd/maps/Kconfig +++ b/trunk/drivers/mtd/maps/Kconfig @@ -473,14 +473,6 @@ config MTD_IXP2000 IXDP425 and Coyote. If you have an IXP2000 based board and would like to use the flash chips on it, say 'Y'. -config MTD_EPXA10DB - tristate "CFI Flash device mapped on Epxa10db" - depends on MTD_CFI && MTD_PARTITIONS && ARCH_CAMELOT - help - This enables support for the flash devices on the Altera - Excalibur XA10 Development Board. If you are building a kernel - for on of these boards then you should say 'Y' otherwise say 'N'. - config MTD_FORTUNET tristate "CFI Flash device mapped on the FortuNet board" depends on MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET diff --git a/trunk/drivers/mtd/maps/Makefile b/trunk/drivers/mtd/maps/Makefile index 2f7e254912f0..ab71f172eb77 100644 --- a/trunk/drivers/mtd/maps/Makefile +++ b/trunk/drivers/mtd/maps/Makefile @@ -15,7 +15,6 @@ obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o obj-$(CONFIG_MTD_CSTM_MIPS_IXX) += cstm_mips_ixx.o obj-$(CONFIG_MTD_DC21285) += dc21285.o obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o -obj-$(CONFIG_MTD_EPXA10DB) += epxa10db-flash.o obj-$(CONFIG_MTD_IQ80310) += iq80310.o obj-$(CONFIG_MTD_L440GX) += l440gx.o obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o diff --git a/trunk/drivers/mtd/maps/epxa10db-flash.c b/trunk/drivers/mtd/maps/epxa10db-flash.c deleted file mode 100644 index 265b079fe934..000000000000 --- a/trunk/drivers/mtd/maps/epxa10db-flash.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Flash memory access on EPXA based devices - * - * (C) 2000 Nicolas Pitre - * Copyright (C) 2001 Altera Corporation - * Copyright (C) 2001 Red Hat, Inc. - * - * $Id: epxa10db-flash.c,v 1.15 2005/11/07 11:14:27 gleixner Exp $ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#ifdef CONFIG_EPXA10DB -#define BOARD_NAME "EPXA10DB" -#else -#define BOARD_NAME "EPXA1DB" -#endif - -static int nr_parts = 0; -static struct mtd_partition *parts; - -static struct mtd_info *mymtd; - -static int epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts); - - -static struct map_info epxa_map = { - .name = "EPXA flash", - .size = FLASH_SIZE, - .bankwidth = 2, - .phys = FLASH_START, -}; - -static const char *probes[] = { "RedBoot", "afs", NULL }; - -static int __init epxa_mtd_init(void) -{ - int i; - - printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START); - - epxa_map.virt = ioremap(FLASH_START, FLASH_SIZE); - if (!epxa_map.virt) { - printk("Failed to ioremap %s flash\n",BOARD_NAME); - return -EIO; - } - simple_map_init(&epxa_map); - - mymtd = do_map_probe("cfi_probe", &epxa_map); - if (!mymtd) { - iounmap((void *)epxa_map.virt); - return -ENXIO; - } - - mymtd->owner = THIS_MODULE; - - /* Unlock the flash device. */ - if(mymtd->unlock){ - for (i=0; inumeraseregions;i++){ - int j; - for(j=0;jeraseregions[i].numblocks;j++){ - mymtd->unlock(mymtd,mymtd->eraseregions[i].offset + j * mymtd->eraseregions[i].erasesize,mymtd->eraseregions[i].erasesize); - } - } - } - -#ifdef CONFIG_MTD_PARTITIONS - nr_parts = parse_mtd_partitions(mymtd, probes, &parts, 0); - - if (nr_parts > 0) { - add_mtd_partitions(mymtd, parts, nr_parts); - return 0; - } -#endif - /* No recognised partitioning schemes found - use defaults */ - nr_parts = epxa_default_partitions(mymtd, &parts); - if (nr_parts > 0) { - add_mtd_partitions(mymtd, parts, nr_parts); - return 0; - } - - /* If all else fails... */ - add_mtd_device(mymtd); - return 0; -} - -static void __exit epxa_mtd_cleanup(void) -{ - if (mymtd) { - if (nr_parts) - del_mtd_partitions(mymtd); - else - del_mtd_device(mymtd); - map_destroy(mymtd); - } - if (epxa_map.virt) { - iounmap((void *)epxa_map.virt); - epxa_map.virt = 0; - } -} - - -/* - * This will do for now, once we decide which bootldr we're finally - * going to use then we'll remove this function and do it properly - * - * Partions are currently (as offsets from base of flash): - * 0x00000000 - 0x003FFFFF - bootloader (!) - * 0x00400000 - 0x00FFFFFF - Flashdisk - */ - -static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts) -{ - struct mtd_partition *parts; - int ret, i; - int npartitions = 0; - char *names; - const char *name = "jffs"; - - printk("Using default partitions for %s\n",BOARD_NAME); - npartitions=1; - parts = kmalloc(npartitions*sizeof(*parts)+strlen(name), GFP_KERNEL); - memzero(parts,npartitions*sizeof(*parts)+strlen(name)); - if (!parts) { - ret = -ENOMEM; - goto out; - } - i=0; - names = (char *)&parts[npartitions]; - parts[i].name = names; - names += strlen(name) + 1; - strcpy(parts[i].name, name); - -#ifdef CONFIG_EPXA10DB - parts[i].size = FLASH_SIZE-0x00400000; - parts[i].offset = 0x00400000; -#else - parts[i].size = FLASH_SIZE-0x00180000; - parts[i].offset = 0x00180000; -#endif - - out: - *pparts = parts; - return npartitions; -} - - -module_init(epxa_mtd_init); -module_exit(epxa_mtd_cleanup); - -MODULE_AUTHOR("Clive Davies"); -MODULE_DESCRIPTION("Altera epxa mtd flash map"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/mtd/mtd_blkdevs.c b/trunk/drivers/mtd/mtd_blkdevs.c index 7f3ff500b68e..339cb1218eaa 100644 --- a/trunk/drivers/mtd/mtd_blkdevs.c +++ b/trunk/drivers/mtd/mtd_blkdevs.c @@ -194,14 +194,6 @@ static int blktrans_release(struct inode *i, struct file *f) return ret; } -static int blktrans_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct mtd_blktrans_dev *dev = bdev->bd_disk->private_data; - - if (dev->tr->getgeo) - return dev->tr->getgeo(dev, geo); - return -ENOTTY; -} static int blktrans_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -215,6 +207,22 @@ static int blktrans_ioctl(struct inode *inode, struct file *file, return tr->flush(dev); /* The core code did the work, we had nothing to do. */ return 0; + + case HDIO_GETGEO: + if (tr->getgeo) { + struct hd_geometry g; + int ret; + + memset(&g, 0, sizeof(g)); + ret = tr->getgeo(dev, &g); + if (ret) + return ret; + + g.start = get_start_sect(inode->i_bdev); + if (copy_to_user((void __user *)arg, &g, sizeof(g))) + return -EFAULT; + return 0; + } /* else */ default: return -ENOTTY; } @@ -225,7 +233,6 @@ struct block_device_operations mtd_blktrans_ops = { .open = blktrans_open, .release = blktrans_release, .ioctl = blktrans_ioctl, - .getgeo = blktrans_getgeo, }; int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) diff --git a/trunk/drivers/mtd/onenand/generic.c b/trunk/drivers/mtd/onenand/generic.c index af06a80f44de..45c077d0f063 100644 --- a/trunk/drivers/mtd/onenand/generic.c +++ b/trunk/drivers/mtd/onenand/generic.c @@ -14,7 +14,6 @@ #include #include -#include #include #include #include diff --git a/trunk/drivers/mtd/rfd_ftl.c b/trunk/drivers/mtd/rfd_ftl.c index a3e00a4635a5..20ce212638fc 100644 --- a/trunk/drivers/mtd/rfd_ftl.c +++ b/trunk/drivers/mtd/rfd_ftl.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/net/3c503.c b/trunk/drivers/net/3c503.c index dcc98afa65d7..5c5eebdb6914 100644 --- a/trunk/drivers/net/3c503.c +++ b/trunk/drivers/net/3c503.c @@ -148,6 +148,14 @@ el2_pio_probe(struct net_device *dev) return -ENODEV; } +static void cleanup_card(struct net_device *dev) +{ + /* NB: el2_close() handles free_irq */ + release_region(dev->base_addr, EL2_IO_EXTENT); + if (ei_status.mem) + iounmap(ei_status.mem); +} + #ifndef MODULE struct net_device * __init el2_probe(int unit) { @@ -718,14 +726,6 @@ init_module(void) return -ENXIO; } -static void cleanup_card(struct net_device *dev) -{ - /* NB: el2_close() handles free_irq */ - release_region(dev->base_addr, EL2_IO_EXTENT); - if (ei_status.mem) - iounmap(ei_status.mem); -} - void cleanup_module(void) { diff --git a/trunk/drivers/net/3c527.h b/trunk/drivers/net/3c527.h index 53b5b071df08..c10f009ce9b6 100644 --- a/trunk/drivers/net/3c527.h +++ b/trunk/drivers/net/3c527.h @@ -32,43 +32,43 @@ struct mc32_mailbox { - u16 mbox; - u16 data[1]; -} __attribute((packed)); + u16 mbox __attribute((packed)); + u16 data[1] __attribute((packed)); +}; struct skb_header { - u8 status; - u8 control; - u16 next; /* Do not change! */ - u16 length; - u32 data; -} __attribute((packed)); + u8 status __attribute((packed)); + u8 control __attribute((packed)); + u16 next __attribute((packed)); /* Do not change! */ + u16 length __attribute((packed)); + u32 data __attribute((packed)); +}; struct mc32_stats { /* RX Errors */ - u32 rx_crc_errors; - u32 rx_alignment_errors; - u32 rx_overrun_errors; - u32 rx_tooshort_errors; - u32 rx_toolong_errors; - u32 rx_outofresource_errors; + u32 rx_crc_errors __attribute((packed)); + u32 rx_alignment_errors __attribute((packed)); + u32 rx_overrun_errors __attribute((packed)); + u32 rx_tooshort_errors __attribute((packed)); + u32 rx_toolong_errors __attribute((packed)); + u32 rx_outofresource_errors __attribute((packed)); - u32 rx_discarded; /* via card pattern match filter */ + u32 rx_discarded __attribute((packed)); /* via card pattern match filter */ /* TX Errors */ - u32 tx_max_collisions; - u32 tx_carrier_errors; - u32 tx_underrun_errors; - u32 tx_cts_errors; - u32 tx_timeout_errors; + u32 tx_max_collisions __attribute((packed)); + u32 tx_carrier_errors __attribute((packed)); + u32 tx_underrun_errors __attribute((packed)); + u32 tx_cts_errors __attribute((packed)); + u32 tx_timeout_errors __attribute((packed)) ; /* various cruft */ - u32 dataA[6]; - u16 dataB[5]; - u32 dataC[14]; -} __attribute((packed)); + u32 dataA[6] __attribute((packed)); + u16 dataB[5] __attribute((packed)); + u32 dataC[14] __attribute((packed)); +}; #define STATUS_MASK 0x0F #define COMPLETED (1<<7) diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 733bc25b2bf9..e2fa29b612cd 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -129,7 +129,7 @@ config NET_SB1000 If you don't have this card, of course say N. -source "drivers/net/arcnet/Kconfig" + source "drivers/net/arcnet/Kconfig" source "drivers/net/phy/Kconfig" @@ -844,7 +844,7 @@ config SMC9194 config DM9000 tristate "DM9000 support" - depends on (ARM || MIPS) && NET_ETHERNET + depends on ARM && NET_ETHERNET select CRC32 select MII ---help--- @@ -1374,7 +1374,7 @@ config FORCEDETH config CS89x0 tristate "CS89x0 support" - depends on NET_PCI && (ISA || ARCH_IXDP2X01 || ARCH_PNX010X) + depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105 ---help--- Support for CS89x0 chipset based Ethernet cards. If you have a network (Ethernet) card of this type, say Y and read the diff --git a/trunk/drivers/net/ac3200.c b/trunk/drivers/net/ac3200.c index 7952dc6d77e3..8a0af5453e21 100644 --- a/trunk/drivers/net/ac3200.c +++ b/trunk/drivers/net/ac3200.c @@ -123,6 +123,14 @@ static int __init do_ac3200_probe(struct net_device *dev) return -ENODEV; } +static void cleanup_card(struct net_device *dev) +{ + /* Someday free_irq may be in ac_close_card() */ + free_irq(dev->irq, dev); + release_region(dev->base_addr, AC_IO_EXTENT); + iounmap(ei_status.mem); +} + #ifndef MODULE struct net_device * __init ac3200_probe(int unit) { @@ -398,14 +406,6 @@ init_module(void) return -ENXIO; } -static void cleanup_card(struct net_device *dev) -{ - /* Someday free_irq may be in ac_close_card() */ - free_irq(dev->irq, dev); - release_region(dev->base_addr, AC_IO_EXTENT); - iounmap(ei_status.mem); -} - void cleanup_module(void) { diff --git a/trunk/drivers/net/arm/Kconfig b/trunk/drivers/net/arm/Kconfig index 470364deded0..625184b65e38 100644 --- a/trunk/drivers/net/arm/Kconfig +++ b/trunk/drivers/net/arm/Kconfig @@ -31,16 +31,3 @@ config ARM_ETHERH help If you have an Acorn system with one of these network cards, you should say Y to this option if you wish to use it with Linux. - -config ARM_ETHER00 - tristate "Altera Ether00 support" - depends on NET_ETHERNET && ARM && ARCH_CAMELOT - help - This is the driver for Altera's ether00 ethernet mac IP core. Say - Y here if you want to build support for this into the kernel. It - is also available as a module (say M here) that can be inserted/ - removed from the kernel at the same time as the PLD is configured. - If this driver is running on an epxa10 development board then it - will generate a suitable hw address based on the board serial - number (MTD support is required for this). Otherwise you will - need to set a suitable hw address using ifconfig. diff --git a/trunk/drivers/net/arm/Makefile b/trunk/drivers/net/arm/Makefile index b0d706834d89..bc263edf06a7 100644 --- a/trunk/drivers/net/arm/Makefile +++ b/trunk/drivers/net/arm/Makefile @@ -4,7 +4,6 @@ # obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o -obj-$(CONFIG_ARM_ETHER00) += ether00.o obj-$(CONFIG_ARM_ETHERH) += etherh.o obj-$(CONFIG_ARM_ETHER3) += ether3.o obj-$(CONFIG_ARM_ETHER1) += ether1.o diff --git a/trunk/drivers/net/arm/ether00.c b/trunk/drivers/net/arm/ether00.c deleted file mode 100644 index 4f1f4e31bda5..000000000000 --- a/trunk/drivers/net/arm/ether00.c +++ /dev/null @@ -1,1017 +0,0 @@ -/* - * drivers/net/ether00.c - * - * 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 - */ - -/* includes */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -MODULE_AUTHOR("Clive Davies"); -MODULE_DESCRIPTION("Altera Ether00 IP core driver"); -MODULE_LICENSE("GPL"); - -#define PKT_BUF_SZ 1540 /* Size of each rx buffer */ -#define ETH_NR 4 /* Number of MACs this driver supports */ - -#define DEBUG(x) - -#define __dma_va(x) (unsigned int)((unsigned int)priv->dma_data+(((unsigned int)(x))&(EXC_SPSRAM_BLOCK0_SIZE-1))) -#define __dma_pa(x) (unsigned int)(EXC_SPSRAM_BLOCK0_BASE+(((unsigned int)(x))-(unsigned int)priv->dma_data)) - -#define ETHER00_BASE 0 -#define ETHER00_TYPE -#define ETHER00_NAME "ether00" -#define MAC_REG_SIZE 0x400 /* size of MAC register area */ - - - -/* typedefs */ - -/* The definition of the driver control structure */ - -#define RX_NUM_BUFF 10 -#define RX_NUM_FDESC 10 -#define TX_NUM_FDESC 10 - -struct tx_fda_ent{ - FDA_DESC fd; - BUF_DESC bd; - BUF_DESC pad; -}; -struct rx_fda_ent{ - FDA_DESC fd; - BUF_DESC bd; - BUF_DESC pad; -}; -struct rx_blist_ent{ - FDA_DESC fd; - BUF_DESC bd; - BUF_DESC pad; -}; -struct net_priv -{ - struct net_device_stats stats; - struct sk_buff* skb; - void* dma_data; - struct rx_blist_ent* rx_blist_vp; - struct rx_fda_ent* rx_fda_ptr; - struct tx_fda_ent* tx_fdalist_vp; - struct tq_struct tq_memupdate; - unsigned char memupdate_scheduled; - unsigned char rx_disabled; - unsigned char queue_stopped; - spinlock_t rx_lock; -}; - -static const char vendor_id[2]={0x07,0xed}; - -#ifdef ETHER00_DEBUG - -/* Dump (most) registers for debugging puposes */ - -static void dump_regs(struct net_device *dev){ - struct net_priv* priv=dev->priv; - unsigned int* i; - - printk("\n RX free descriptor area:\n"); - - for(i=(unsigned int*)priv->rx_fda_ptr; - i<((unsigned int*)(priv->rx_fda_ptr+RX_NUM_FDESC));){ - printk("%#8x %#8x %#8x %#8x\n",*i,*(i+1),*(i+2),*(i+3)); - i+=4; - } - - printk("\n RX buffer list:\n"); - - for(i=(unsigned int*)priv->rx_blist_vp; - i<((unsigned int*)(priv->rx_blist_vp+RX_NUM_BUFF));){ - printk("%#8x %#8x %#8x %#8x\n",*i,*(i+1),*(i+2),*(i+3)); - i+=4; - } - - printk("\n TX frame descriptor list:\n"); - - for(i=(unsigned int*)priv->tx_fdalist_vp; - i<((unsigned int*)(priv->tx_fdalist_vp+TX_NUM_FDESC));){ - printk("%#8x %#8x %#8x %#8x\n",*i,*(i+1),*(i+2),*(i+3)); - i+=4; - } - - printk("\ndma ctl=%#x\n",readw(ETHER_DMA_CTL(dev->base_addr))); - printk("txfrmptr=%#x\n",readw(ETHER_TXFRMPTR(dev->base_addr))); - printk("txthrsh=%#x\n",readw(ETHER_TXTHRSH(dev->base_addr))); - printk("txpollctr=%#x\n",readw(ETHER_TXPOLLCTR(dev->base_addr))); - printk("blfrmptr=%#x\n",readw(ETHER_BLFRMPTR(dev->base_addr))); - printk("rxfragsize=%#x\n",readw(ETHER_RXFRAGSIZE(dev->base_addr))); - printk("tx_int_en=%#x\n",readw(ETHER_INT_EN(dev->base_addr))); - printk("fda_bas=%#x\n",readw(ETHER_FDA_BAS(dev->base_addr))); - printk("fda_lim=%#x\n",readw(ETHER_FDA_LIM(dev->base_addr))); - printk("int_src=%#x\n",readw(ETHER_INT_SRC(dev->base_addr))); - printk("pausecnt=%#x\n",readw(ETHER_PAUSECNT(dev->base_addr))); - printk("rempaucnt=%#x\n",readw(ETHER_REMPAUCNT(dev->base_addr))); - printk("txconfrmstat=%#x\n",readw(ETHER_TXCONFRMSTAT(dev->base_addr))); - printk("mac_ctl=%#x\n",readw(ETHER_MAC_CTL(dev->base_addr))); - printk("arc_ctl=%#x\n",readw(ETHER_ARC_CTL(dev->base_addr))); - printk("tx_ctl=%#x\n",readw(ETHER_TX_CTL(dev->base_addr))); -} -#endif /* ETHER00_DEBUG */ - - -static int ether00_write_phy(struct net_device *dev, short address, short value) -{ - volatile int count = 1024; - writew(value,ETHER_MD_DATA(dev->base_addr)); - writew( ETHER_MD_CA_BUSY_MSK | - ETHER_MD_CA_WR_MSK | - (address & ETHER_MD_CA_ADDR_MSK), - ETHER_MD_CA(dev->base_addr)); - - /* Wait for the command to complete */ - while((readw(ETHER_MD_CA(dev->base_addr)) & ETHER_MD_CA_BUSY_MSK)&&count){ - count--; - } - if (!count){ - printk("Write to phy failed, addr=%#x, data=%#x\n",address, value); - return -EIO; - } - return 0; -} - -static int ether00_read_phy(struct net_device *dev, short address) -{ - volatile int count = 1024; - writew( ETHER_MD_CA_BUSY_MSK | - (address & ETHER_MD_CA_ADDR_MSK), - ETHER_MD_CA(dev->base_addr)); - - /* Wait for the command to complete */ - while((readw(ETHER_MD_CA(dev->base_addr)) & ETHER_MD_CA_BUSY_MSK)&&count){ - count--; - } - if (!count){ - printk(KERN_WARNING "Read from phy timed out\n"); - return -EIO; - } - return readw(ETHER_MD_DATA(dev->base_addr)); -} - -static void ether00_phy_int(int irq_num, void* dev_id, struct pt_regs* regs) -{ - struct net_device* dev=dev_id; - int irq_status; - - irq_status=ether00_read_phy(dev, PHY_IRQ_CONTROL); - - if(irq_status & PHY_IRQ_CONTROL_ANEG_COMP_INT_MSK){ - /* - * Autonegotiation complete on epxa10db. The mac doesn't - * twig if we're in full duplex so we need to check the - * phy status register and configure the mac accordingly - */ - if(ether00_read_phy(dev, PHY_STATUS)&(PHY_STATUS_10T_F_MSK|PHY_STATUS_100_X_F_MSK)){ - int tmp; - tmp=readl(ETHER_MAC_CTL(dev->base_addr)); - writel(tmp|ETHER_MAC_CTL_FULLDUP_MSK,ETHER_MAC_CTL(dev->base_addr)); - } - } - - if(irq_status&PHY_IRQ_CONTROL_LS_CHG_INT_MSK){ - - if(ether00_read_phy(dev, PHY_STATUS)& PHY_STATUS_LINK_MSK){ - /* Link is up */ - netif_carrier_on(dev); - //printk("Carrier on\n"); - }else{ - netif_carrier_off(dev); - //printk("Carrier off\n"); - - } - } - -} - -static void setup_blist_entry(struct sk_buff* skb,struct rx_blist_ent* blist_ent_ptr){ - /* Make the buffer consistent with the cache as the mac is going to write - * directly into it*/ - blist_ent_ptr->fd.FDSystem=(unsigned int)skb; - blist_ent_ptr->bd.BuffData=(char*)__pa(skb->data); - consistent_sync(skb->data,PKT_BUF_SZ,PCI_DMA_FROMDEVICE); - /* align IP on 16 Byte (DMA_CTL set to skip 2 bytes) */ - skb_reserve(skb,2); - blist_ent_ptr->bd.BuffLength=PKT_BUF_SZ-2; - blist_ent_ptr->fd.FDLength=1; - blist_ent_ptr->fd.FDCtl=FDCTL_COWNSFD_MSK; - blist_ent_ptr->bd.BDCtl=BDCTL_COWNSBD_MSK; -} - - -static int ether00_mem_init(struct net_device* dev) -{ - struct net_priv* priv=dev->priv; - struct tx_fda_ent *tx_fd_ptr,*tx_end_ptr; - struct rx_blist_ent* blist_ent_ptr; - int i; - - /* - * Grab a block of on chip SRAM to contain the control stuctures for - * the ethernet MAC. This uncached becuase it needs to be accesses by both - * bus masters (cpu + mac). However, it shouldn't matter too much in terms - * of speed as its on chip memory - */ - priv->dma_data=ioremap_nocache(EXC_SPSRAM_BLOCK0_BASE,EXC_SPSRAM_BLOCK0_SIZE ); - if (!priv->dma_data) - return -ENOMEM; - - priv->rx_fda_ptr=(struct rx_fda_ent*)priv->dma_data; - /* - * Now share it out amongst the Frame descriptors and the buffer list - */ - priv->rx_blist_vp=(struct rx_blist_ent*)((unsigned int)priv->dma_data+RX_NUM_FDESC*sizeof(struct rx_fda_ent)); - - /* - *Initalise the FDA list - */ - /* set ownership to the controller */ - memset(priv->rx_fda_ptr,0x80,RX_NUM_FDESC*sizeof(struct rx_fda_ent)); - - /* - *Initialise the buffer list - */ - blist_ent_ptr=priv->rx_blist_vp; - i=0; - while(blist_ent_ptr<(priv->rx_blist_vp+RX_NUM_BUFF)){ - struct sk_buff *skb; - blist_ent_ptr->fd.FDLength=1; - skb=dev_alloc_skb(PKT_BUF_SZ); - if(skb){ - setup_blist_entry(skb,blist_ent_ptr); - blist_ent_ptr->fd.FDNext=(FDA_DESC*)__dma_pa(blist_ent_ptr+1); - blist_ent_ptr->bd.BDStat=i++; - blist_ent_ptr++; - } - else - { - printk("Failed to initalise buffer list\n"); - } - - } - blist_ent_ptr--; - blist_ent_ptr->fd.FDNext=(FDA_DESC*)__dma_pa(priv->rx_blist_vp); - - priv->tx_fdalist_vp=(struct tx_fda_ent*)(priv->rx_blist_vp+RX_NUM_BUFF); - - /* Initialise the buffers to be a circular list. The mac will then go poll - * the list until it finds a frame ready to transmit */ - tx_end_ptr=priv->tx_fdalist_vp+TX_NUM_FDESC; - for(tx_fd_ptr=priv->tx_fdalist_vp;tx_fd_ptrfd.FDNext=(FDA_DESC*)__dma_pa((tx_fd_ptr+1)); - tx_fd_ptr->fd.FDCtl=1; - tx_fd_ptr->fd.FDStat=0; - tx_fd_ptr->fd.FDLength=1; - - } - /* Change the last FDNext pointer to make a circular list */ - tx_fd_ptr--; - tx_fd_ptr->fd.FDNext=(FDA_DESC*)__dma_pa(priv->tx_fdalist_vp); - - /* Point the device at the chain of Rx and Tx Buffers */ - writel((unsigned int)__dma_pa(priv->rx_fda_ptr),ETHER_FDA_BAS(dev->base_addr)); - writel((RX_NUM_FDESC-1)*sizeof(struct rx_fda_ent),ETHER_FDA_LIM(dev->base_addr)); - writel((unsigned int)__dma_pa(priv->rx_blist_vp),ETHER_BLFRMPTR(dev->base_addr)); - - writel((unsigned int)__dma_pa(priv->tx_fdalist_vp),ETHER_TXFRMPTR(dev->base_addr)); - - return 0; -} - - -void ether00_mem_update(void* dev_id) -{ - struct net_device* dev=dev_id; - struct net_priv* priv=dev->priv; - struct sk_buff* skb; - struct tx_fda_ent *fda_ptr=priv->tx_fdalist_vp; - struct rx_blist_ent* blist_ent_ptr; - unsigned long flags; - - priv->tq_memupdate.sync=0; - //priv->tq_memupdate.list= - priv->memupdate_scheduled=0; - - /* Transmit interrupt */ - while(fda_ptr<(priv->tx_fdalist_vp+TX_NUM_FDESC)){ - if(!(FDCTL_COWNSFD_MSK&fda_ptr->fd.FDCtl) && (ETHER_TX_STAT_COMP_MSK&fda_ptr->fd.FDStat)){ - priv->stats.tx_packets++; - priv->stats.tx_bytes+=fda_ptr->bd.BuffLength; - skb=(struct sk_buff*)fda_ptr->fd.FDSystem; - //printk("%d:txcln:fda=%#x skb=%#x\n",jiffies,fda_ptr,skb); - dev_kfree_skb(skb); - fda_ptr->fd.FDSystem=0; - fda_ptr->fd.FDStat=0; - fda_ptr->fd.FDCtl=0; - } - fda_ptr++; - } - /* Fill in any missing buffers from the received queue */ - spin_lock_irqsave(&priv->rx_lock,flags); - blist_ent_ptr=priv->rx_blist_vp; - while(blist_ent_ptr<(priv->rx_blist_vp+RX_NUM_BUFF)){ - /* fd.FDSystem of 0 indicates we failed to allocate the buffer in the ISR */ - if(!blist_ent_ptr->fd.FDSystem){ - struct sk_buff *skb; - skb=dev_alloc_skb(PKT_BUF_SZ); - blist_ent_ptr->fd.FDSystem=(unsigned int)skb; - if(skb){ - setup_blist_entry(skb,blist_ent_ptr); - } - else - { - break; - } - } - blist_ent_ptr++; - } - spin_unlock_irqrestore(&priv->rx_lock,flags); - if(priv->queue_stopped){ - //printk("%d:cln:start q\n",jiffies); - netif_start_queue(dev); - } - if(priv->rx_disabled){ - //printk("%d:enable_irq\n",jiffies); - priv->rx_disabled=0; - writel(ETHER_RX_CTL_RXEN_MSK,ETHER_RX_CTL(dev->base_addr)); - - } -} - - -static void ether00_int( int irq_num, void* dev_id, struct pt_regs* regs) -{ - struct net_device* dev=dev_id; - struct net_priv* priv=dev->priv; - - unsigned int interruptValue; - - interruptValue=readl(ETHER_INT_SRC(dev->base_addr)); - - //printk("INT_SRC=%x\n",interruptValue); - - if(!(readl(ETHER_INT_SRC(dev->base_addr)) & ETHER_INT_SRC_IRQ_MSK)) - { - return; /* Interrupt wasn't caused by us!! */ - } - - if(readl(ETHER_INT_SRC(dev->base_addr))& - (ETHER_INT_SRC_INTMACRX_MSK | - ETHER_INT_SRC_FDAEX_MSK | - ETHER_INT_SRC_BLEX_MSK)) { - struct rx_blist_ent* blist_ent_ptr; - struct rx_fda_ent* fda_ent_ptr; - struct sk_buff* skb; - - fda_ent_ptr=priv->rx_fda_ptr; - spin_lock(&priv->rx_lock); - while(fda_ent_ptr<(priv->rx_fda_ptr+RX_NUM_FDESC)){ - int result; - - if(!(fda_ent_ptr->fd.FDCtl&FDCTL_COWNSFD_MSK)) - { - /* This frame is ready for processing */ - /*find the corresponding buffer in the bufferlist */ - blist_ent_ptr=priv->rx_blist_vp+fda_ent_ptr->bd.BDStat; - skb=(struct sk_buff*)blist_ent_ptr->fd.FDSystem; - - /* Pass this skb up the stack */ - skb->dev=dev; - skb_put(skb,fda_ent_ptr->fd.FDLength); - skb->protocol=eth_type_trans(skb,dev); - skb->ip_summed=CHECKSUM_UNNECESSARY; - result=netif_rx(skb); - /* Update statistics */ - priv->stats.rx_packets++; - priv->stats.rx_bytes+=fda_ent_ptr->fd.FDLength; - - /* Free the FDA entry */ - fda_ent_ptr->bd.BDStat=0xff; - fda_ent_ptr->fd.FDCtl=FDCTL_COWNSFD_MSK; - - /* Allocate a new skb and point the bd entry to it */ - blist_ent_ptr->fd.FDSystem=0; - skb=dev_alloc_skb(PKT_BUF_SZ); - //printk("allocskb=%#x\n",skb); - if(skb){ - setup_blist_entry(skb,blist_ent_ptr); - - } - else if(!priv->memupdate_scheduled){ - int tmp; - /* There are no buffers at the moment, so schedule */ - /* the background task to sort this out */ - schedule_task(&priv->tq_memupdate); - priv->memupdate_scheduled=1; - printk(KERN_DEBUG "%s:No buffers",dev->name); - /* If this interrupt was due to a lack of buffers then - * we'd better stop the receiver too */ - if(interruptValueÐER_INT_SRC_BLEX_MSK){ - priv->rx_disabled=1; - tmp=readl(ETHER_INT_SRC(dev->base_addr)); - writel(tmp&~ETHER_RX_CTL_RXEN_MSK,ETHER_RX_CTL(dev->base_addr)); - printk(KERN_DEBUG "%s:Halting rx",dev->name); - } - - } - - } - fda_ent_ptr++; - } - spin_unlock(&priv->rx_lock); - - /* Clear the interrupts */ - writel(ETHER_INT_SRC_INTMACRX_MSK | ETHER_INT_SRC_FDAEX_MSK - | ETHER_INT_SRC_BLEX_MSK,ETHER_INT_SRC(dev->base_addr)); - - } - - if(readl(ETHER_INT_SRC(dev->base_addr))ÐER_INT_SRC_INTMACTX_MSK){ - - if(!priv->memupdate_scheduled){ - schedule_task(&priv->tq_memupdate); - priv->memupdate_scheduled=1; - } - /* Clear the interrupt */ - writel(ETHER_INT_SRC_INTMACTX_MSK,ETHER_INT_SRC(dev->base_addr)); - } - - if (readl(ETHER_INT_SRC(dev->base_addr)) & (ETHER_INT_SRC_SWINT_MSK| - ETHER_INT_SRC_INTEARNOT_MSK| - ETHER_INT_SRC_INTLINK_MSK| - ETHER_INT_SRC_INTEXBD_MSK| - ETHER_INT_SRC_INTTXCTLCMP_MSK)) - { - /* - * Not using any of these so they shouldn't happen - * - * In the cased of INTEXBD - if you allocate more - * than 28 decsriptors you may need to think about this - */ - printk("Not using this interrupt\n"); - } - - if (readl(ETHER_INT_SRC(dev->base_addr)) & - (ETHER_INT_SRC_INTSBUS_MSK | - ETHER_INT_SRC_INTNRABT_MSK - |ETHER_INT_SRC_DMPARERR_MSK)) - { - /* - * Hardware errors, we can either ignore them and hope they go away - *or reset the device, I'll try the first for now to see if they happen - */ - printk("Hardware error\n"); - } -} - -static void ether00_setup_ethernet_address(struct net_device* dev) -{ - int tmp; - - dev->addr_len=6; - writew(0,ETHER_ARC_ADR(dev->base_addr)); - writel((dev->dev_addr[0]<<24) | - (dev->dev_addr[1]<<16) | - (dev->dev_addr[2]<<8) | - dev->dev_addr[3], - ETHER_ARC_DATA(dev->base_addr)); - - writew(4,ETHER_ARC_ADR(dev->base_addr)); - tmp=readl(ETHER_ARC_DATA(dev->base_addr)); - tmp&=0xffff; - tmp|=(dev->dev_addr[4]<<24) | (dev->dev_addr[5]<<16); - writel(tmp, ETHER_ARC_DATA(dev->base_addr)); - /* Enable this entry in the ARC */ - - writel(1,ETHER_ARC_ENA(dev->base_addr)); - - return; -} - - -static void ether00_reset(struct net_device *dev) -{ - /* reset the controller */ - writew(ETHER_MAC_CTL_RESET_MSK,ETHER_MAC_CTL(dev->base_addr)); - - /* - * Make sure we're not going to send anything - */ - - writew(ETHER_TX_CTL_TXHALT_MSK,ETHER_TX_CTL(dev->base_addr)); - - /* - * Make sure we're not going to receive anything - */ - writew(ETHER_RX_CTL_RXHALT_MSK,ETHER_RX_CTL(dev->base_addr)); - - /* - * Disable Interrupts for now, and set the burst size to 8 bytes - */ - - writel(ETHER_DMA_CTL_INTMASK_MSK | - ((8 << ETHER_DMA_CTL_DMBURST_OFST) & ETHER_DMA_CTL_DMBURST_MSK) - |(2<base_addr)); - - - /* - * Set TxThrsh - start transmitting a packet after 1514 - * bytes or when a packet is complete, whichever comes first - */ - writew(1514,ETHER_TXTHRSH(dev->base_addr)); - - /* - * Set TxPollCtr. Each cycle is - * 61.44 microseconds with a 33 MHz bus - */ - writew(1,ETHER_TXPOLLCTR(dev->base_addr)); - - /* - * Set Rx_Ctl - Turn off reception and let RxData turn it - * on later - */ - writew(ETHER_RX_CTL_RXHALT_MSK,ETHER_RX_CTL(dev->base_addr)); - -} - - -static void ether00_set_multicast(struct net_device* dev) -{ - int count=dev->mc_count; - - /* Set promiscuous mode if it's asked for. */ - - if (dev->flags&IFF_PROMISC){ - - writew( ETHER_ARC_CTL_COMPEN_MSK | - ETHER_ARC_CTL_BROADACC_MSK | - ETHER_ARC_CTL_GROUPACC_MSK | - ETHER_ARC_CTL_STATIONACC_MSK, - ETHER_ARC_CTL(dev->base_addr)); - return; - } - - /* - * Get all multicast packets if required, or if there are too - * many addresses to fit in hardware - */ - if (dev->flags & IFF_ALLMULTI){ - writew( ETHER_ARC_CTL_COMPEN_MSK | - ETHER_ARC_CTL_GROUPACC_MSK | - ETHER_ARC_CTL_BROADACC_MSK, - ETHER_ARC_CTL(dev->base_addr)); - return; - } - if (dev->mc_count > (ETHER_ARC_SIZE - 1)){ - - printk(KERN_WARNING "Too many multicast addresses for hardware to filter - receiving all multicast packets\n"); - writew( ETHER_ARC_CTL_COMPEN_MSK | - ETHER_ARC_CTL_GROUPACC_MSK | - ETHER_ARC_CTL_BROADACC_MSK, - ETHER_ARC_CTL(dev->base_addr)); - return; - } - - if(dev->mc_count){ - struct dev_mc_list *mc_list_ent=dev->mc_list; - unsigned int temp,i; - DEBUG(printk("mc_count=%d mc_list=%#x\n",dev-> mc_count, dev->mc_list)); - DEBUG(printk("mc addr=%02#x%02x%02x%02x%02x%02x\n", - mc_list_ent->dmi_addr[5], - mc_list_ent->dmi_addr[4], - mc_list_ent->dmi_addr[3], - mc_list_ent->dmi_addr[2], - mc_list_ent->dmi_addr[1], - mc_list_ent->dmi_addr[0]);) - - /* - * The first 6 bytes are the MAC address, so - * don't change them! - */ - writew(4,ETHER_ARC_ADR(dev->base_addr)); - temp=readl(ETHER_ARC_DATA(dev->base_addr)); - temp&=0xffff0000; - - /* Disable the current multicast stuff */ - writel(1,ETHER_ARC_ENA(dev->base_addr)); - - for(;;){ - temp|=mc_list_ent->dmi_addr[1] | - mc_list_ent->dmi_addr[0]<<8; - writel(temp,ETHER_ARC_DATA(dev->base_addr)); - - i=readl(ETHER_ARC_ADR(dev->base_addr)); - writew(i+4,ETHER_ARC_ADR(dev->base_addr)); - - temp=mc_list_ent->dmi_addr[5]| - mc_list_ent->dmi_addr[4]<<8 | - mc_list_ent->dmi_addr[3]<<16 | - mc_list_ent->dmi_addr[2]<<24; - writel(temp,ETHER_ARC_DATA(dev->base_addr)); - - count--; - if(!mc_list_ent->next || !count){ - break; - } - DEBUG(printk("mc_list_next=%#x\n",mc_list_ent->next);) - mc_list_ent=mc_list_ent->next; - - - i=readl(ETHER_ARC_ADR(dev->base_addr)); - writel(i+4,ETHER_ARC_ADR(dev->base_addr)); - - temp=mc_list_ent->dmi_addr[3]| - mc_list_ent->dmi_addr[2]<<8 | - mc_list_ent->dmi_addr[1]<<16 | - mc_list_ent->dmi_addr[0]<<24; - writel(temp,ETHER_ARC_DATA(dev->base_addr)); - - i=readl(ETHER_ARC_ADR(dev->base_addr)); - writel(i+4,ETHER_ARC_ADR(dev->base_addr)); - - temp=mc_list_ent->dmi_addr[4]<<16 | - mc_list_ent->dmi_addr[5]<<24; - - writel(temp,ETHER_ARC_DATA(dev->base_addr)); - - count--; - if(!mc_list_ent->next || !count){ - break; - } - mc_list_ent=mc_list_ent->next; - } - - - if(count) - printk(KERN_WARNING "Multicast list size error\n"); - - - writew( ETHER_ARC_CTL_BROADACC_MSK| - ETHER_ARC_CTL_COMPEN_MSK, - ETHER_ARC_CTL(dev->base_addr)); - - } - - /* enable the active ARC enties */ - writew((1<<(count+2))-1,ETHER_ARC_ENA(dev->base_addr)); -} - - -static int ether00_open(struct net_device* dev) -{ - int result,tmp; - struct net_priv* priv; - - if (!is_valid_ether_addr(dev->dev_addr)) - return -EINVAL; - - /* Install interrupt handlers */ - result=request_irq(dev->irq,ether00_int,0,"ether00",dev); - if(result) - goto open_err1; - - result=request_irq(2,ether00_phy_int,0,"ether00_phy",dev); - if(result) - goto open_err2; - - ether00_reset(dev); - result=ether00_mem_init(dev); - if(result) - goto open_err3; - - - ether00_setup_ethernet_address(dev); - - ether00_set_multicast(dev); - - result=ether00_write_phy(dev,PHY_CONTROL, PHY_CONTROL_ANEGEN_MSK | PHY_CONTROL_RANEG_MSK); - if(result) - goto open_err4; - result=ether00_write_phy(dev,PHY_IRQ_CONTROL, PHY_IRQ_CONTROL_LS_CHG_IE_MSK | - PHY_IRQ_CONTROL_ANEG_COMP_IE_MSK); - if(result) - goto open_err4; - - /* Start the device enable interrupts */ - writew(ETHER_RX_CTL_RXEN_MSK -// | ETHER_RX_CTL_STRIPCRC_MSK - | ETHER_RX_CTL_ENGOOD_MSK - | ETHER_RX_CTL_ENRXPAR_MSK| ETHER_RX_CTL_ENLONGERR_MSK - | ETHER_RX_CTL_ENOVER_MSK| ETHER_RX_CTL_ENCRCERR_MSK, - ETHER_RX_CTL(dev->base_addr)); - - writew(ETHER_TX_CTL_TXEN_MSK| - ETHER_TX_CTL_ENEXDEFER_MSK| - ETHER_TX_CTL_ENLCARR_MSK| - ETHER_TX_CTL_ENEXCOLL_MSK| - ETHER_TX_CTL_ENLATECOLL_MSK| - ETHER_TX_CTL_ENTXPAR_MSK| - ETHER_TX_CTL_ENCOMP_MSK, - ETHER_TX_CTL(dev->base_addr)); - - tmp=readl(ETHER_DMA_CTL(dev->base_addr)); - writel(tmp&~ETHER_DMA_CTL_INTMASK_MSK,ETHER_DMA_CTL(dev->base_addr)); - - return 0; - - open_err4: - ether00_reset(dev); - open_err3: - free_irq(2,dev); - open_err2: - free_irq(dev->irq,dev); - open_err1: - return result; - -} - - -static int ether00_tx(struct sk_buff* skb, struct net_device* dev) -{ - struct net_priv *priv=dev->priv; - struct tx_fda_ent *fda_ptr; - int i; - - - /* - * Find an empty slot in which to stick the frame - */ - fda_ptr=(struct tx_fda_ent*)__dma_va(readl(ETHER_TXFRMPTR(dev->base_addr))); - i=0; - while(ifd.FDStat||(fda_ptr->fd.FDCtl & FDCTL_COWNSFD_MSK)){ - fda_ptr =(struct tx_fda_ent*) __dma_va((struct tx_fda_ent*)fda_ptr->fd.FDNext); - } - else { - break; - } - i++; - } - - /* Write the skb data from the cache*/ - consistent_sync(skb->data,skb->len,PCI_DMA_TODEVICE); - fda_ptr->bd.BuffData=(char*)__pa(skb->data); - fda_ptr->bd.BuffLength=(unsigned short)skb->len; - /* Save the pointer to the skb for freeing later */ - fda_ptr->fd.FDSystem=(unsigned int)skb; - fda_ptr->fd.FDStat=0; - /* Pass ownership of the buffers to the controller */ - fda_ptr->fd.FDCtl=1; - fda_ptr->fd.FDCtl|=FDCTL_COWNSFD_MSK; - - /* If the next buffer in the list is full, stop the queue */ - fda_ptr=(struct tx_fda_ent*)__dma_va(fda_ptr->fd.FDNext); - if ((fda_ptr->fd.FDStat)||(fda_ptr->fd.FDCtl & FDCTL_COWNSFD_MSK)){ - netif_stop_queue(dev); - priv->queue_stopped=1; - } - - return 0; -} - -static struct net_device_stats *ether00_stats(struct net_device* dev) -{ - struct net_priv *priv=dev->priv; - return &priv->stats; -} - - -static int ether00_stop(struct net_device* dev) -{ - struct net_priv *priv=dev->priv; - int tmp; - - /* Stop/disable the device. */ - tmp=readw(ETHER_RX_CTL(dev->base_addr)); - tmp&=~(ETHER_RX_CTL_RXEN_MSK | ETHER_RX_CTL_ENGOOD_MSK); - tmp|=ETHER_RX_CTL_RXHALT_MSK; - writew(tmp,ETHER_RX_CTL(dev->base_addr)); - - tmp=readl(ETHER_TX_CTL(dev->base_addr)); - tmp&=~ETHER_TX_CTL_TXEN_MSK; - tmp|=ETHER_TX_CTL_TXHALT_MSK; - writel(tmp,ETHER_TX_CTL(dev->base_addr)); - - /* Free up system resources */ - free_irq(dev->irq,dev); - free_irq(2,dev); - iounmap(priv->dma_data); - - return 0; -} - - -static void ether00_get_ethernet_address(struct net_device* dev) -{ - struct mtd_info *mymtd=NULL; - int i; - size_t retlen; - - /* - * For the Epxa10 dev board (camelot), the ethernet MAC - * address is of the form 00:aa:aa:00:xx:xx where - * 00:aa:aa is the Altera vendor ID and xx:xx is the - * last 2 bytes of the board serial number, as programmed - * into the OTP area of the flash device on EBI1. If this - * isn't an expa10 dev board, or there's no mtd support to - * read the serial number from flash then we'll force the - * use to set their own mac address using ifconfig. - */ - -#ifdef CONFIG_ARCH_CAMELOT -#ifdef CONFIG_MTD - /* get the mtd_info structure for the first mtd device*/ - for(i=0;iname,"EPXA10DB flash")) - break; - } - - if(!mymtd || !mymtd->read_user_prot_reg){ - printk(KERN_WARNING "%s: Failed to read MAC address from flash\n",dev->name); - }else{ - mymtd->read_user_prot_reg(mymtd,2,1,&retlen,&dev->dev_addr[5]); - mymtd->read_user_prot_reg(mymtd,3,1,&retlen,&dev->dev_addr[4]); - dev->dev_addr[3]=0; - dev->dev_addr[2]=vendor_id[1]; - dev->dev_addr[1]=vendor_id[0]; - dev->dev_addr[0]=0; - } -#else - printk(KERN_WARNING "%s: MTD support required to read MAC address from EPXA10 dev board\n", dev->name); -#endif -#endif - - if (!is_valid_ether_addr(dev->dev_addr)) - printk("%s: Invalid ethernet MAC address. Please set using " - "ifconfig\n", dev->name); - -} - -/* - * Keep a mapping of dev_info addresses -> port lines to use when - * removing ports dev==NULL indicates unused entry - */ - - -static struct net_device* dev_list[ETH_NR]; - -static int ether00_add_device(struct pldhs_dev_info* dev_info,void* dev_ps_data) -{ - struct net_device *dev; - struct net_priv *priv; - void *map_addr; - int result; - int i; - - i=0; - while(dev_list[i] && i < ETH_NR) - i++; - - if(i==ETH_NR){ - printk(KERN_WARNING "ether00: Maximum number of ports reached\n"); - return 0; - } - - - if (!request_mem_region(dev_info->base_addr, MAC_REG_SIZE, "ether00")) - return -EBUSY; - - dev = alloc_etherdev(sizeof(struct net_priv)); - if(!dev) { - result = -ENOMEM; - goto out_release; - } - priv = dev->priv; - - priv->tq_memupdate.routine=ether00_mem_update; - priv->tq_memupdate.data=(void*) dev; - - spin_lock_init(&priv->rx_lock); - - map_addr=ioremap_nocache(dev_info->base_addr,SZ_4K); - if(!map_addr){ - result = -ENOMEM; - out_kfree; - } - - dev->open=ether00_open; - dev->stop=ether00_stop; - dev->set_multicast_list=ether00_set_multicast; - dev->hard_start_xmit=ether00_tx; - dev->get_stats=ether00_stats; - - ether00_get_ethernet_address(dev); - - SET_MODULE_OWNER(dev); - - dev->base_addr=(unsigned int)map_addr; - dev->irq=dev_info->irq; - dev->features=NETIF_F_DYNALLOC | NETIF_F_HW_CSUM; - - result=register_netdev(dev); - if(result){ - printk("Ether00: Error %i registering driver\n",result); - goto out_unmap; - } - printk("registered ether00 device at %#x\n",dev_info->base_addr); - - dev_list[i]=dev; - - return result; - - out_unmap: - iounmap(map_addr); - out_kfree: - free_netdev(dev); - out_release: - release_mem_region(dev_info->base_addr, MAC_REG_SIZE); - return result; -} - - -static int ether00_remove_devices(void) -{ - int i; - - for(i=0;ibase_addr); - release_mem_region(dev_list[i]->base_addr, MAC_REG_SIZE); - free_netdev(dev_list[i]); - dev_list[i]=0; - } - } - return 0; -} - -static struct pld_hotswap_ops ether00_pldhs_ops={ - .name = ETHER00_NAME, - .add_device = ether00_add_device, - .remove_devices = ether00_remove_devices, -}; - - -static void __exit ether00_cleanup_module(void) -{ - int result; - result=ether00_remove_devices(); - if(result) - printk(KERN_WARNING "ether00: failed to remove all devices\n"); - - pldhs_unregister_driver(ETHER00_NAME); -} -module_exit(ether00_cleanup_module); - - -static int __init ether00_mod_init(void) -{ - printk("mod init\n"); - return pldhs_register_driver(ðer00_pldhs_ops); - -} - -module_init(ether00_mod_init); - diff --git a/trunk/drivers/net/bonding/bonding.h b/trunk/drivers/net/bonding/bonding.h index f20bb85c1ea5..015c7f1d1bc0 100644 --- a/trunk/drivers/net/bonding/bonding.h +++ b/trunk/drivers/net/bonding/bonding.h @@ -205,7 +205,7 @@ struct bonding { * * Caller must hold bond lock for read */ -static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev) +extern inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev) { struct slave *slave = NULL; int i; @@ -219,7 +219,7 @@ static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct n return slave; } -static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) +extern inline struct bonding *bond_get_bond_by_slave(struct slave *slave) { if (!slave || !slave->dev->master) { return NULL; @@ -228,13 +228,13 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) return (struct bonding *)slave->dev->master->priv; } -static inline void bond_set_slave_inactive_flags(struct slave *slave) +extern inline void bond_set_slave_inactive_flags(struct slave *slave) { slave->state = BOND_STATE_BACKUP; slave->dev->flags |= IFF_NOARP; } -static inline void bond_set_slave_active_flags(struct slave *slave) +extern inline void bond_set_slave_active_flags(struct slave *slave) { slave->state = BOND_STATE_ACTIVE; slave->dev->flags &= ~IFF_NOARP; diff --git a/trunk/drivers/net/cs89x0.c b/trunk/drivers/net/cs89x0.c index 907c01009746..a6078ad9b654 100644 --- a/trunk/drivers/net/cs89x0.c +++ b/trunk/drivers/net/cs89x0.c @@ -175,7 +175,7 @@ static unsigned int cs8900_irq_map[] = {1,0,0,0}; #include static unsigned int netcard_portlist[] __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; -#elif defined(CONFIG_ARCH_PNX010X) +#elif defined(CONFIG_ARCH_PNX0105) #include #include #define CIRRUS_DEFAULT_BASE IO_ADDRESS(EXT_STATIC2_s0_BASE + 0x200000) /* = Physical address 0x48200000 */ @@ -338,86 +338,30 @@ struct net_device * __init cs89x0_probe(int unit) } #endif -#if defined(CONFIG_ARCH_IXDP2X01) static int -readword(unsigned long base_addr, int portno) +readreg(struct net_device *dev, int portno) { - return (u16)__raw_readl(base_addr + (portno << 1)); + outw(portno, dev->base_addr + ADD_PORT); + return inw(dev->base_addr + DATA_PORT); } static void -writeword(unsigned long base_addr, int portno, int value) +writereg(struct net_device *dev, int portno, int value) { - __raw_writel((u16)value, base_addr + (portno << 1)); -} -#else -#if defined(CONFIG_ARCH_PNX010X) -static int -readword(unsigned long base_addr, int portno) -{ - return inw(base_addr + (portno << 1)); -} - -static void -writeword(unsigned long base_addr, int portno, int value) -{ - outw(value, base_addr + (portno << 1)); -} -#else -static int -readword(unsigned long base_addr, int portno) -{ - return inw(base_addr + portno); -} - -static void -writeword(unsigned long base_addr, int portno, int value) -{ - outw(value, base_addr + portno); -} -#endif -#endif - -static void -readwords(unsigned long base_addr, int portno, void *buf, int length) -{ - u8 *buf8 = (u8 *)buf; - - do { - u32 tmp32; - - tmp32 = readword(base_addr, portno); - *buf8++ = (u8)tmp32; - *buf8++ = (u8)(tmp32 >> 8); - } while (--length); -} - -static void -writewords(unsigned long base_addr, int portno, void *buf, int length) -{ - u8 *buf8 = (u8 *)buf; - - do { - u32 tmp32; - - tmp32 = *buf8++; - tmp32 |= (*buf8++) << 8; - writeword(base_addr, portno, tmp32); - } while (--length); + outw(portno, dev->base_addr + ADD_PORT); + outw(value, dev->base_addr + DATA_PORT); } static int -readreg(struct net_device *dev, int regno) +readword(struct net_device *dev, int portno) { - writeword(dev->base_addr, ADD_PORT, regno); - return readword(dev->base_addr, DATA_PORT); + return inw(dev->base_addr + portno); } static void -writereg(struct net_device *dev, int regno, int value) +writeword(struct net_device *dev, int portno, int value) { - writeword(dev->base_addr, ADD_PORT, regno); - writeword(dev->base_addr, DATA_PORT, value); + outw(value, dev->base_addr + portno); } static int __init @@ -512,7 +456,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) #endif } -#ifdef CONFIG_ARCH_PNX010X +#ifdef CONFIG_ARCH_PNX0105 initialize_ebi(); /* Map GPIO registers for the pins connected to the CS8900a. */ @@ -547,8 +491,8 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) #ifdef CONFIG_SH_HICOSH4 /* truely reset the chip */ - writeword(ioaddr, ADD_PORT, 0x0114); - writeword(ioaddr, DATA_PORT, 0x0040); + outw(0x0114, ioaddr + ADD_PORT); + outw(0x0040, ioaddr + DATA_PORT); #endif /* if they give us an odd I/O address, then do ONE write to @@ -559,24 +503,24 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) if (net_debug > 1) printk(KERN_INFO "%s: odd ioaddr 0x%x\n", dev->name, ioaddr); if ((ioaddr & 2) != 2) - if ((readword(ioaddr & ~3, ADD_PORT) & ADD_MASK) != ADD_SIG) { + if ((inw((ioaddr & ~3)+ ADD_PORT) & ADD_MASK) != ADD_SIG) { printk(KERN_ERR "%s: bad signature 0x%x\n", - dev->name, readword(ioaddr & ~3, ADD_PORT)); + dev->name, inw((ioaddr & ~3)+ ADD_PORT)); retval = -ENODEV; goto out2; } } - printk(KERN_DEBUG "PP_addr at %x[%x]: 0x%x\n", - ioaddr, ADD_PORT, readword(ioaddr, ADD_PORT)); + printk(KERN_DEBUG "PP_addr at %x: 0x%x\n", + ioaddr + ADD_PORT, inw(ioaddr + ADD_PORT)); ioaddr &= ~3; - writeword(ioaddr, ADD_PORT, PP_ChipID); + outw(PP_ChipID, ioaddr + ADD_PORT); - tmp = readword(ioaddr, DATA_PORT); + tmp = inw(ioaddr + DATA_PORT); if (tmp != CHIP_EISA_ID_SIG) { - printk(KERN_DEBUG "%s: incorrect signature at %x[%x]: 0x%x!=" + printk(KERN_DEBUG "%s: incorrect signature at %x: 0x%x!=" CHIP_EISA_ID_SIG_STR "\n", - dev->name, ioaddr, DATA_PORT, tmp); + dev->name, ioaddr + DATA_PORT, tmp); retval = -ENODEV; goto out2; } @@ -780,7 +724,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) } else { i = lp->isa_config & INT_NO_MASK; if (lp->chip_type == CS8900) { -#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX010X) +#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105) i = cs8900_irq_map[0]; #else /* Translate the IRQ using the IRQ mapping table. */ @@ -846,7 +790,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) goto out3; return 0; out3: - writeword(dev->base_addr, ADD_PORT, PP_ChipID); + outw(PP_ChipID, dev->base_addr + ADD_PORT); out2: release_region(ioaddr & ~3, NETCARD_IO_EXTENT); out1: @@ -1026,11 +970,11 @@ void __init reset_chip(struct net_device *dev) #ifndef CONFIG_ARCH_IXDP2X01 if (lp->chip_type != CS8900) { /* Hardware problem requires PNP registers to be reconfigured after a reset */ - writeword(ioaddr, ADD_PORT, PP_CS8920_ISAINT); + outw(PP_CS8920_ISAINT, ioaddr + ADD_PORT); outb(dev->irq, ioaddr + DATA_PORT); outb(0, ioaddr + DATA_PORT + 1); - writeword(ioaddr, ADD_PORT, PP_CS8920_ISAMemB); + outw(PP_CS8920_ISAMemB, ioaddr + ADD_PORT); outb((dev->mem_start >> 16) & 0xff, ioaddr + DATA_PORT); outb((dev->mem_start >> 8) & 0xff, ioaddr + DATA_PORT + 1); } @@ -1160,8 +1104,8 @@ send_test_pkt(struct net_device *dev) memcpy(test_packet, dev->dev_addr, ETH_ALEN); memcpy(test_packet+ETH_ALEN, dev->dev_addr, ETH_ALEN); - writeword(dev->base_addr, TX_CMD_PORT, TX_AFTER_ALL); - writeword(dev->base_addr, TX_LEN_PORT, ETH_ZLEN); + writeword(dev, TX_CMD_PORT, TX_AFTER_ALL); + writeword(dev, TX_LEN_PORT, ETH_ZLEN); /* Test to see if the chip has allocated memory for the packet */ while (jiffies - timenow < 5) @@ -1171,7 +1115,7 @@ send_test_pkt(struct net_device *dev) return 0; /* this shouldn't happen */ /* Write the contents of the packet */ - writewords(dev->base_addr, TX_FRAME_PORT,test_packet,(ETH_ZLEN+1) >>1); + outsw(dev->base_addr + TX_FRAME_PORT,test_packet,(ETH_ZLEN+1) >>1); if (net_debug > 1) printk("Sending test packet "); /* wait a couple of jiffies for packet to be received */ @@ -1256,7 +1200,7 @@ net_open(struct net_device *dev) int i; int ret; -#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX010X) /* uses irq#1, so this won't work */ +#if !defined(CONFIG_SH_HICOSH4) && !defined(CONFIG_ARCH_PNX0105) /* uses irq#1, so this won't work */ if (dev->irq < 2) { /* Allow interrupts to be generated by the chip */ /* Cirrus' release had this: */ @@ -1287,7 +1231,7 @@ net_open(struct net_device *dev) else #endif { -#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX010X) +#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX0105) if (((1 << dev->irq) & lp->irq_map) == 0) { printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n", dev->name, dev->irq, lp->irq_map); @@ -1372,7 +1316,7 @@ net_open(struct net_device *dev) case A_CNF_MEDIA_10B_2: result = lp->adapter_cnf & A_CNF_10B_2; break; default: result = lp->adapter_cnf & (A_CNF_10B_T | A_CNF_AUI | A_CNF_10B_2); } -#ifdef CONFIG_ARCH_PNX010X +#ifdef CONFIG_ARCH_PNX0105 result = A_CNF_10B_T; #endif if (!result) { @@ -1513,8 +1457,8 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); /* initiate a transmit sequence */ - writeword(dev->base_addr, TX_CMD_PORT, lp->send_cmd); - writeword(dev->base_addr, TX_LEN_PORT, skb->len); + writeword(dev, TX_CMD_PORT, lp->send_cmd); + writeword(dev, TX_LEN_PORT, skb->len); /* Test to see if the chip has allocated memory for the packet */ if ((readreg(dev, PP_BusST) & READY_FOR_TX_NOW) == 0) { @@ -1528,7 +1472,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev) return 1; } /* Write the contents of the packet */ - writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1); + outsw(dev->base_addr + TX_FRAME_PORT,skb->data,(skb->len+1) >>1); spin_unlock_irq(&lp->lock); lp->stats.tx_bytes += skb->len; dev->trans_start = jiffies; @@ -1568,7 +1512,7 @@ static irqreturn_t net_interrupt(int irq, void *dev_id, struct pt_regs * regs) course, if you're on a slow machine, and packets are arriving faster than you can read them off, you're screwed. Hasta la vista, baby! */ - while ((status = readword(dev->base_addr, ISQ_PORT))) { + while ((status = readword(dev, ISQ_PORT))) { if (net_debug > 4)printk("%s: event=%04x\n", dev->name, status); handled = 1; switch(status & ISQ_EVENT_MASK) { @@ -1662,8 +1606,8 @@ net_rx(struct net_device *dev) int status, length; int ioaddr = dev->base_addr; - status = readword(ioaddr, RX_FRAME_PORT); - length = readword(ioaddr, RX_FRAME_PORT); + status = inw(ioaddr + RX_FRAME_PORT); + length = inw(ioaddr + RX_FRAME_PORT); if ((status & RX_OK) == 0) { count_rx_errors(status, lp); @@ -1682,9 +1626,9 @@ net_rx(struct net_device *dev) skb_reserve(skb, 2); /* longword align L3 header */ skb->dev = dev; - readwords(ioaddr, RX_FRAME_PORT, skb_put(skb, length), length >> 1); + insw(ioaddr + RX_FRAME_PORT, skb_put(skb, length), length >> 1); if (length & 1) - skb->data[length-1] = readword(ioaddr, RX_FRAME_PORT); + skb->data[length-1] = inw(ioaddr + RX_FRAME_PORT); if (net_debug > 3) { printk( "%s: received %d byte packet of type %x\n", @@ -1957,7 +1901,7 @@ void cleanup_module(void) { unregister_netdev(dev_cs89x0); - writeword(dev_cs89x0->base_addr, ADD_PORT, PP_ChipID); + outw(PP_ChipID, dev_cs89x0->base_addr + ADD_PORT); release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT); free_netdev(dev_cs89x0); } diff --git a/trunk/drivers/net/cs89x0.h b/trunk/drivers/net/cs89x0.h index bd954aaa636f..decea264f121 100644 --- a/trunk/drivers/net/cs89x0.h +++ b/trunk/drivers/net/cs89x0.h @@ -16,6 +16,13 @@ #include +#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105) +/* IXDP2401/IXDP2801 uses dword-aligned register addressing */ +#define CS89x0_PORT(reg) ((reg) * 2) +#else +#define CS89x0_PORT(reg) (reg) +#endif + #define PP_ChipID 0x0000 /* offset 0h -> Corp -ID */ /* offset 2h -> Model/Product Number */ /* offset 3h -> Chip Revision Number */ @@ -325,16 +332,16 @@ #define RAM_SIZE 0x1000 /* The card has 4k bytes or RAM */ #define PKT_START PP_TxFrame /* Start of packet RAM */ -#define RX_FRAME_PORT 0x0000 +#define RX_FRAME_PORT CS89x0_PORT(0x0000) #define TX_FRAME_PORT RX_FRAME_PORT -#define TX_CMD_PORT 0x0004 +#define TX_CMD_PORT CS89x0_PORT(0x0004) #define TX_NOW 0x0000 /* Tx packet after 5 bytes copied */ #define TX_AFTER_381 0x0040 /* Tx packet after 381 bytes copied */ #define TX_AFTER_ALL 0x00c0 /* Tx packet after all bytes copied */ -#define TX_LEN_PORT 0x0006 -#define ISQ_PORT 0x0008 -#define ADD_PORT 0x000A -#define DATA_PORT 0x000C +#define TX_LEN_PORT CS89x0_PORT(0x0006) +#define ISQ_PORT CS89x0_PORT(0x0008) +#define ADD_PORT CS89x0_PORT(0x000A) +#define DATA_PORT CS89x0_PORT(0x000C) #define EEPROM_WRITE_EN 0x00F0 #define EEPROM_WRITE_DIS 0x0000 diff --git a/trunk/drivers/net/e1000/e1000_param.c b/trunk/drivers/net/e1000/e1000_param.c index ccbbe5ad8e0f..38695d5b4637 100644 --- a/trunk/drivers/net/e1000/e1000_param.c +++ b/trunk/drivers/net/e1000/e1000_param.c @@ -545,7 +545,7 @@ e1000_check_fiber_options(struct e1000_adapter *adapter) static void __devinit e1000_check_copper_options(struct e1000_adapter *adapter) { - int speed, dplx, an; + int speed, dplx; int bd = adapter->bd_number; { /* Speed */ @@ -641,12 +641,8 @@ e1000_check_copper_options(struct e1000_adapter *adapter) .p = an_list }} }; - if (num_AutoNeg > bd) { - an = AutoNeg[bd]; - e1000_validate_option(&an, &opt, adapter); - } else { - an = opt.def; - } + int an = AutoNeg[bd]; + e1000_validate_option(&an, &opt, adapter); adapter->hw.autoneg_advertised = an; } diff --git a/trunk/drivers/net/e2100.c b/trunk/drivers/net/e2100.c index e5c5cd2a2712..f5a4dd7d8564 100644 --- a/trunk/drivers/net/e2100.c +++ b/trunk/drivers/net/e2100.c @@ -140,6 +140,13 @@ static int __init do_e2100_probe(struct net_device *dev) return -ENODEV; } +static void cleanup_card(struct net_device *dev) +{ + /* NB: e21_close() handles free_irq */ + iounmap(ei_status.mem); + release_region(dev->base_addr, E21_IO_EXTENT); +} + #ifndef MODULE struct net_device * __init e2100_probe(int unit) { @@ -456,13 +463,6 @@ init_module(void) return -ENXIO; } -static void cleanup_card(struct net_device *dev) -{ - /* NB: e21_close() handles free_irq */ - iounmap(ei_status.mem); - release_region(dev->base_addr, E21_IO_EXTENT); -} - void cleanup_module(void) { diff --git a/trunk/drivers/net/es3210.c b/trunk/drivers/net/es3210.c index 6b0ab1eac3fb..50f8e23bb9e5 100644 --- a/trunk/drivers/net/es3210.c +++ b/trunk/drivers/net/es3210.c @@ -155,6 +155,13 @@ static int __init do_es_probe(struct net_device *dev) return -ENODEV; } +static void cleanup_card(struct net_device *dev) +{ + free_irq(dev->irq, dev); + release_region(dev->base_addr, ES_IO_EXTENT); + iounmap(ei_status.mem); +} + #ifndef MODULE struct net_device * __init es_probe(int unit) { @@ -449,13 +456,6 @@ init_module(void) return -ENXIO; } -static void cleanup_card(struct net_device *dev) -{ - free_irq(dev->irq, dev); - release_region(dev->base_addr, ES_IO_EXTENT); - iounmap(ei_status.mem); -} - void cleanup_module(void) { diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index 3682ec61e8a8..c39344adecce 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -101,7 +101,6 @@ * 0.46: 20 Oct 2005: Add irq optimization modes. * 0.47: 26 Oct 2005: Add phyaddr 0 in phy scan. * 0.48: 24 Dec 2005: Disable TSO, bugfix for pci_map_single - * 0.49: 10 Dec 2005: Fix tso for large buffers. * * Known bugs: * We suspect that on some hardware no TX done interrupts are generated. @@ -113,7 +112,7 @@ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * superfluous timer interrupts from the nic. */ -#define FORCEDETH_VERSION "0.49" +#define FORCEDETH_VERSION "0.48" #define DRV_NAME "forcedeth" #include @@ -350,8 +349,6 @@ typedef union _ring_type { #define NV_TX2_VALID (1<<31) #define NV_TX2_TSO (1<<28) #define NV_TX2_TSO_SHIFT 14 -#define NV_TX2_TSO_MAX_SHIFT 14 -#define NV_TX2_TSO_MAX_SIZE (1<tx_ring.ex[i].FlagLen = 0; np->tx_skbuff[i] = NULL; - np->tx_dma[i] = 0; } } @@ -950,27 +945,30 @@ static int nv_init_ring(struct net_device *dev) return nv_alloc_rx(dev); } -static int nv_release_txskb(struct net_device *dev, unsigned int skbnr) +static void nv_release_txskb(struct net_device *dev, unsigned int skbnr) { struct fe_priv *np = netdev_priv(dev); - - dprintk(KERN_INFO "%s: nv_release_txskb for skbnr %d\n", - dev->name, skbnr); - - if (np->tx_dma[skbnr]) { - pci_unmap_page(np->pci_dev, np->tx_dma[skbnr], - np->tx_dma_len[skbnr], - PCI_DMA_TODEVICE); - np->tx_dma[skbnr] = 0; - } - - if (np->tx_skbuff[skbnr]) { - dev_kfree_skb_irq(np->tx_skbuff[skbnr]); - np->tx_skbuff[skbnr] = NULL; - return 1; - } else { - return 0; + struct sk_buff *skb = np->tx_skbuff[skbnr]; + unsigned int j, entry, fragments; + + dprintk(KERN_INFO "%s: nv_release_txskb for skbnr %d, skb %p\n", + dev->name, skbnr, np->tx_skbuff[skbnr]); + + entry = skbnr; + if ((fragments = skb_shinfo(skb)->nr_frags) != 0) { + for (j = fragments; j >= 1; j--) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[j-1]; + pci_unmap_page(np->pci_dev, np->tx_dma[entry], + frag->size, + PCI_DMA_TODEVICE); + entry = (entry - 1) % TX_RING; + } } + pci_unmap_single(np->pci_dev, np->tx_dma[entry], + skb->len - skb->data_len, + PCI_DMA_TODEVICE); + dev_kfree_skb_irq(skb); + np->tx_skbuff[skbnr] = NULL; } static void nv_drain_tx(struct net_device *dev) @@ -983,8 +981,10 @@ static void nv_drain_tx(struct net_device *dev) np->tx_ring.orig[i].FlagLen = 0; else np->tx_ring.ex[i].FlagLen = 0; - if (nv_release_txskb(dev, i)) + if (np->tx_skbuff[i]) { + nv_release_txskb(dev, i); np->stats.tx_dropped++; + } } } @@ -1021,105 +1021,68 @@ static void drain_ring(struct net_device *dev) static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); - u32 tx_flags = 0; u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET); unsigned int fragments = skb_shinfo(skb)->nr_frags; - unsigned int nr = (np->next_tx - 1) % TX_RING; - unsigned int start_nr = np->next_tx % TX_RING; + unsigned int nr = (np->next_tx + fragments) % TX_RING; unsigned int i; - u32 offset = 0; - u32 bcnt; - u32 size = skb->len-skb->data_len; - u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); - - /* add fragments to entries count */ - for (i = 0; i < fragments; i++) { - entries += (skb_shinfo(skb)->frags[i].size >> NV_TX2_TSO_MAX_SHIFT) + - ((skb_shinfo(skb)->frags[i].size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0); - } spin_lock_irq(&np->lock); - if ((np->next_tx - np->nic_tx + entries - 1) > TX_LIMIT_STOP) { + if ((np->next_tx - np->nic_tx + fragments) > TX_LIMIT_STOP) { spin_unlock_irq(&np->lock); netif_stop_queue(dev); return NETDEV_TX_BUSY; } - /* setup the header buffer */ - do { - bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size; - nr = (nr + 1) % TX_RING; - - np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data + offset, bcnt, - PCI_DMA_TODEVICE); - np->tx_dma_len[nr] = bcnt; - - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); - np->tx_ring.orig[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags); - } else { - np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32; - np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF; - np->tx_ring.ex[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags); - } - tx_flags = np->tx_flags; - offset += bcnt; - size -= bcnt; - } while(size); - - /* setup the fragments */ - for (i = 0; i < fragments; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - u32 size = frag->size; - offset = 0; - - do { - bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size; - nr = (nr + 1) % TX_RING; - - np->tx_dma[nr] = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt, - PCI_DMA_TODEVICE); - np->tx_dma_len[nr] = bcnt; + np->tx_skbuff[nr] = skb; + + if (fragments) { + dprintk(KERN_DEBUG "%s: nv_start_xmit: buffer contains %d fragments\n", dev->name, fragments); + /* setup descriptors in reverse order */ + for (i = fragments; i >= 1; i--) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1]; + np->tx_dma[nr] = pci_map_page(np->pci_dev, frag->page, frag->page_offset, frag->size, + PCI_DMA_TODEVICE); if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); - np->tx_ring.orig[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags); + np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra); } else { np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32; np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF; - np->tx_ring.ex[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags); + np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra); } - offset += bcnt; - size -= bcnt; - } while (size); - } + + nr = (nr - 1) % TX_RING; - /* set last fragment flag */ - if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - np->tx_ring.orig[nr].FlagLen |= cpu_to_le32(tx_flags_extra); - } else { - np->tx_ring.ex[nr].FlagLen |= cpu_to_le32(tx_flags_extra); + if (np->desc_ver == DESC_VER_1) + tx_flags_extra &= ~NV_TX_LASTPACKET; + else + tx_flags_extra &= ~NV_TX2_LASTPACKET; + } } - np->tx_skbuff[nr] = skb; - #ifdef NETIF_F_TSO if (skb_shinfo(skb)->tso_size) - tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT); + tx_flags_extra |= NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT); else #endif - tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0); + tx_flags_extra |= (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0); - /* set tx flags */ + np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len-skb->data_len, + PCI_DMA_TODEVICE); + if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { - np->tx_ring.orig[start_nr].FlagLen |= cpu_to_le32(tx_flags | tx_flags_extra); + np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); + np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra); } else { - np->tx_ring.ex[start_nr].FlagLen |= cpu_to_le32(tx_flags | tx_flags_extra); + np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32; + np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF; + np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra); } - dprintk(KERN_DEBUG "%s: nv_start_xmit: packet %d (entries %d) queued for transmission. tx_flags_extra: %x\n", - dev->name, np->next_tx, entries, tx_flags_extra); + dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission. tx_flags_extra: %x\n", + dev->name, np->next_tx, tx_flags_extra); { int j; for (j=0; j<64; j++) { @@ -1130,7 +1093,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) dprintk("\n"); } - np->next_tx += entries; + np->next_tx += 1 + fragments; dev->trans_start = jiffies; spin_unlock_irq(&np->lock); @@ -1177,6 +1140,7 @@ static void nv_tx_done(struct net_device *dev) np->stats.tx_packets++; np->stats.tx_bytes += skb->len; } + nv_release_txskb(dev, i); } } else { if (Flags & NV_TX2_LASTPACKET) { @@ -1192,9 +1156,9 @@ static void nv_tx_done(struct net_device *dev) np->stats.tx_packets++; np->stats.tx_bytes += skb->len; } + nv_release_txskb(dev, i); } } - nv_release_txskb(dev, i); np->nic_tx++; } if (np->next_tx - np->nic_tx < TX_LIMIT_START) @@ -2492,7 +2456,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG; #ifdef NETIF_F_TSO - dev->features |= NETIF_F_TSO; + /* disabled dev->features |= NETIF_F_TSO; */ #endif } diff --git a/trunk/drivers/net/gianfar.h b/trunk/drivers/net/gianfar.h index cb9d66ac3ab9..94a91da84fbb 100644 --- a/trunk/drivers/net/gianfar.h +++ b/trunk/drivers/net/gianfar.h @@ -718,14 +718,14 @@ struct gfar_private { uint32_t msg_enable; }; -static inline u32 gfar_read(volatile unsigned *addr) +extern inline u32 gfar_read(volatile unsigned *addr) { u32 val; val = in_be32(addr); return val; } -static inline void gfar_write(volatile unsigned *addr, u32 val) +extern inline void gfar_write(volatile unsigned *addr, u32 val) { out_be32(addr, val); } diff --git a/trunk/drivers/net/hamradio/mkiss.c b/trunk/drivers/net/hamradio/mkiss.c index 41b3d83c2ab8..3e9accf137e7 100644 --- a/trunk/drivers/net/hamradio/mkiss.c +++ b/trunk/drivers/net/hamradio/mkiss.c @@ -524,7 +524,6 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) ax->dev->trans_start = jiffies; ax->xleft = count - actual; ax->xhead = ax->xbuff + actual; - spin_unlock_bh(&ax->buflock); } /* Encapsulate an AX.25 packet and kick it into a TTY queue. */ diff --git a/trunk/drivers/net/hp-plus.c b/trunk/drivers/net/hp-plus.c index 74e167e7dea7..0abf5dd08b4c 100644 --- a/trunk/drivers/net/hp-plus.c +++ b/trunk/drivers/net/hp-plus.c @@ -138,6 +138,12 @@ static int __init do_hpp_probe(struct net_device *dev) return -ENODEV; } +static void cleanup_card(struct net_device *dev) +{ + /* NB: hpp_close() handles free_irq */ + release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT); +} + #ifndef MODULE struct net_device * __init hp_plus_probe(int unit) { @@ -467,12 +473,6 @@ init_module(void) return -ENXIO; } -static void cleanup_card(struct net_device *dev) -{ - /* NB: hpp_close() handles free_irq */ - release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT); -} - void cleanup_module(void) { diff --git a/trunk/drivers/net/hp.c b/trunk/drivers/net/hp.c index cf9fb3698a6b..59cf841b14ab 100644 --- a/trunk/drivers/net/hp.c +++ b/trunk/drivers/net/hp.c @@ -102,6 +102,12 @@ static int __init do_hp_probe(struct net_device *dev) return -ENODEV; } +static void cleanup_card(struct net_device *dev) +{ + free_irq(dev->irq, dev); + release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT); +} + #ifndef MODULE struct net_device * __init hp_probe(int unit) { @@ -438,12 +444,6 @@ init_module(void) return -ENXIO; } -static void cleanup_card(struct net_device *dev) -{ - free_irq(dev->irq, dev); - release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT); -} - void cleanup_module(void) { diff --git a/trunk/drivers/net/ibm_emac/ibm_emac.h b/trunk/drivers/net/ibm_emac/ibm_emac.h index c2dae6092c4c..644edbff4f94 100644 --- a/trunk/drivers/net/ibm_emac/ibm_emac.h +++ b/trunk/drivers/net/ibm_emac/ibm_emac.h @@ -110,7 +110,6 @@ struct emac_regs { #define EMAC_MR1_TFS_2K 0x00080000 #define EMAC_MR1_TR0_MULT 0x00008000 #define EMAC_MR1_JPSM 0x00000000 -#define EMAC_MR1_MWSW_001 0x00000000 #define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR0_MULT) #else #define EMAC_MR1_RFS_4K 0x00180000 @@ -131,7 +130,7 @@ struct emac_regs { (freq) <= 83 ? EMAC_MR1_OBCI_83 : \ (freq) <= 100 ? EMAC_MR1_OBCI_100 : EMAC_MR1_OBCI_100P) #define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR | \ - EMAC_MR1_OBCI(opb)) + EMAC_MR1_MWSW_001 | EMAC_MR1_OBCI(opb)) #endif /* EMACx_TMR0 */ diff --git a/trunk/drivers/net/ibm_emac/ibm_emac_core.c b/trunk/drivers/net/ibm_emac/ibm_emac_core.c index 591c5864ffb1..1da8a66f91e1 100644 --- a/trunk/drivers/net/ibm_emac/ibm_emac_core.c +++ b/trunk/drivers/net/ibm_emac/ibm_emac_core.c @@ -408,7 +408,7 @@ static int emac_configure(struct ocp_enet_private *dev) /* Mode register */ r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST; if (dev->phy.duplex == DUPLEX_FULL) - r |= EMAC_MR1_FDE | EMAC_MR1_MWSW_001; + r |= EMAC_MR1_FDE; dev->stop_timeout = STOP_TIMEOUT_10; switch (dev->phy.speed) { case SPEED_1000: diff --git a/trunk/drivers/net/irda/vlsi_ir.h b/trunk/drivers/net/irda/vlsi_ir.h index a82a4ba8de4f..741aecc655df 100644 --- a/trunk/drivers/net/irda/vlsi_ir.h +++ b/trunk/drivers/net/irda/vlsi_ir.h @@ -577,8 +577,8 @@ struct ring_descr_hw { struct { u8 addr_res[3]; volatile u8 status; /* descriptor status */ - } __attribute__((packed)) rd_s; - } __attribute((packed)) rd_u; + } rd_s __attribute__((packed)); + } rd_u __attribute((packed)); } __attribute__ ((packed)); #define rd_addr rd_u.addr diff --git a/trunk/drivers/net/lance.c b/trunk/drivers/net/lance.c index d1d714faa6ce..1d75ca0bb939 100644 --- a/trunk/drivers/net/lance.c +++ b/trunk/drivers/net/lance.c @@ -309,6 +309,17 @@ static void lance_tx_timeout (struct net_device *dev); +static void cleanup_card(struct net_device *dev) +{ + struct lance_private *lp = dev->priv; + if (dev->dma != 4) + free_dma(dev->dma); + release_region(dev->base_addr, LANCE_TOTAL_SIZE); + kfree(lp->tx_bounce_buffs); + kfree((void*)lp->rx_buffs); + kfree(lp); +} + #ifdef MODULE #define MAX_CARDS 8 /* Max number of interfaces (cards) per module */ @@ -356,17 +367,6 @@ int init_module(void) return -ENXIO; } -static void cleanup_card(struct net_device *dev) -{ - struct lance_private *lp = dev->priv; - if (dev->dma != 4) - free_dma(dev->dma); - release_region(dev->base_addr, LANCE_TOTAL_SIZE); - kfree(lp->tx_bounce_buffs); - kfree((void*)lp->rx_buffs); - kfree(lp); -} - void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/lne390.c b/trunk/drivers/net/lne390.c index 646e89fc3562..309d254842cf 100644 --- a/trunk/drivers/net/lne390.c +++ b/trunk/drivers/net/lne390.c @@ -145,6 +145,13 @@ static int __init do_lne390_probe(struct net_device *dev) return -ENODEV; } +static void cleanup_card(struct net_device *dev) +{ + free_irq(dev->irq, dev); + release_region(dev->base_addr, LNE390_IO_EXTENT); + iounmap(ei_status.mem); +} + #ifndef MODULE struct net_device * __init lne390_probe(int unit) { @@ -433,13 +440,6 @@ int init_module(void) return -ENXIO; } -static void cleanup_card(struct net_device *dev) -{ - free_irq(dev->irq, dev); - release_region(dev->base_addr, LNE390_IO_EXTENT); - iounmap(ei_status.mem); -} - void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/mv643xx_eth.c b/trunk/drivers/net/mv643xx_eth.c index 22c3a37bba5a..3cb9b3fe0cf1 100644 --- a/trunk/drivers/net/mv643xx_eth.c +++ b/trunk/drivers/net/mv643xx_eth.c @@ -6,7 +6,7 @@ * Copyright (C) 2002 rabeeh@galileo.co.il * * Copyright (C) 2003 PMC-Sierra, Inc., - * written by Manish Lachwani + * written by Manish Lachwani (lachwani@pmc-sierra.com) * * Copyright (C) 2003 Ralf Baechle * diff --git a/trunk/drivers/net/ne.c b/trunk/drivers/net/ne.c index 94f782d51f0f..0de8fdd2aa86 100644 --- a/trunk/drivers/net/ne.c +++ b/trunk/drivers/net/ne.c @@ -212,6 +212,15 @@ static int __init do_ne_probe(struct net_device *dev) return -ENODEV; } +static void cleanup_card(struct net_device *dev) +{ + struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; + if (idev) + pnp_device_detach(idev); + free_irq(dev->irq, dev); + release_region(dev->base_addr, NE_IO_EXTENT); +} + #ifndef MODULE struct net_device * __init ne_probe(int unit) { @@ -850,15 +859,6 @@ int init_module(void) return -ENODEV; } -static void cleanup_card(struct net_device *dev) -{ - struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; - if (idev) - pnp_device_detach(idev); - free_irq(dev->irq, dev); - release_region(dev->base_addr, NE_IO_EXTENT); -} - void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/ne2.c b/trunk/drivers/net/ne2.c index e6df375a1d4b..6d62ada85de6 100644 --- a/trunk/drivers/net/ne2.c +++ b/trunk/drivers/net/ne2.c @@ -278,6 +278,14 @@ static int __init do_ne2_probe(struct net_device *dev) return -ENODEV; } +static void cleanup_card(struct net_device *dev) +{ + mca_mark_as_unused(ei_status.priv); + mca_set_adapter_procfn( ei_status.priv, NULL, NULL); + free_irq(dev->irq, dev); + release_region(dev->base_addr, NE_IO_EXTENT); +} + #ifndef MODULE struct net_device * __init ne2_probe(int unit) { @@ -804,14 +812,6 @@ int init_module(void) return -ENXIO; } -static void cleanup_card(struct net_device *dev) -{ - mca_mark_as_unused(ei_status.priv); - mca_set_adapter_procfn( ei_status.priv, NULL, NULL); - free_irq(dev->irq, dev); - release_region(dev->base_addr, NE_IO_EXTENT); -} - void cleanup_module(void) { int this_dev; diff --git a/trunk/drivers/net/sk98lin/skge.c b/trunk/drivers/net/sk98lin/skge.c index 197edd74fbb5..9a76ac180b11 100644 --- a/trunk/drivers/net/sk98lin/skge.c +++ b/trunk/drivers/net/sk98lin/skge.c @@ -282,22 +282,26 @@ SK_U32 Val) /* pointer to store the read value */ * Description: * This function initialize the PCI resources and IO * - * Returns: - * 0 - indicate everything worked ok. - * != 0 - error indication + * Returns: N/A + * */ -static __devinit int SkGeInitPCI(SK_AC *pAC) +int SkGeInitPCI(SK_AC *pAC) { struct SK_NET_DEVICE *dev = pAC->dev[0]; struct pci_dev *pdev = pAC->PciDev; int retval; + if (pci_enable_device(pdev) != 0) { + return 1; + } + dev->mem_start = pci_resource_start (pdev, 0); pci_set_master(pdev); - retval = pci_request_regions(pdev, "sk98lin"); - if (retval) - goto out; + if (pci_request_regions(pdev, "sk98lin") != 0) { + retval = 2; + goto out_disable; + } #ifdef SK_BIG_ENDIAN /* @@ -316,8 +320,9 @@ static __devinit int SkGeInitPCI(SK_AC *pAC) * Remap the regs into kernel space. */ pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000); - if (!pAC->IoBase) { - retval = -EIO; + + if (!pAC->IoBase){ + retval = 3; goto out_release; } @@ -325,7 +330,8 @@ static __devinit int SkGeInitPCI(SK_AC *pAC) out_release: pci_release_regions(pdev); - out: + out_disable: + pci_disable_device(pdev); return retval; } @@ -486,7 +492,7 @@ module_param_array(AutoSizing, charp, NULL, 0); * 0, if everything is ok * !=0, on error */ -static int __devinit SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC) +static int __init SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC) { short i; unsigned long Flags; @@ -523,7 +529,7 @@ SK_BOOL DualNet; if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) { printk("HWInit (0) failed.\n"); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - return -EIO; + return(-EAGAIN); } SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA); SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA); @@ -545,7 +551,7 @@ SK_BOOL DualNet; if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) { printk("sk98lin: HWInit (1) failed.\n"); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - return -EIO; + return(-EAGAIN); } SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO); SkEventInit(pAC, pAC->IoBase, SK_INIT_IO); @@ -577,20 +583,20 @@ SK_BOOL DualNet; } else { printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n", pAC->GIni.GIMacsFound); - return -EIO; + return -EAGAIN; } if (Ret) { printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n", dev->irq); - return Ret; + return -EAGAIN; } pAC->AllocFlag |= SK_ALLOC_IRQ; /* Alloc memory for this board (Mem for RxD/TxD) : */ if(!BoardAllocMem(pAC)) { printk("No memory for descriptor rings.\n"); - return -ENOMEM; + return(-EAGAIN); } BoardInitMem(pAC); @@ -606,7 +612,7 @@ SK_BOOL DualNet; DualNet)) { BoardFreeMem(pAC); printk("sk98lin: SkGeInitAssignRamToQueues failed.\n"); - return -EIO; + return(-EAGAIN); } return (0); @@ -627,7 +633,8 @@ SK_BOOL DualNet; * SK_TRUE, if all memory could be allocated * SK_FALSE, if not */ -static __devinit SK_BOOL BoardAllocMem(SK_AC *pAC) +static SK_BOOL BoardAllocMem( +SK_AC *pAC) { caddr_t pDescrMem; /* pointer to descriptor memory area */ size_t AllocLength; /* length of complete descriptor area */ @@ -720,7 +727,8 @@ size_t AllocLength; /* length of complete descriptor area */ * * Returns: N/A */ -static __devinit void BoardInitMem(SK_AC *pAC) +static void BoardInitMem( +SK_AC *pAC) /* pointer to adapter context */ { int i; /* loop counter */ int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/ @@ -4768,47 +4776,32 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, struct net_device *dev = NULL; static int boards_found = 0; int error = -ENODEV; - int using_dac = 0; char DeviceStr[80]; if (pci_enable_device(pdev)) goto out; /* Configure DMA attributes. */ - if (sizeof(dma_addr_t) > sizeof(u32) && - !(error = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) { - using_dac = 1; - error = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); - if (error < 0) { - printk(KERN_ERR "sk98lin %s unable to obtain 64 bit DMA " - "for consistent allocations\n", pci_name(pdev)); - goto out_disable_device; - } - } else { - error = pci_set_dma_mask(pdev, DMA_32BIT_MASK); - if (error) { - printk(KERN_ERR "sk98lin %s no usable DMA configuration\n", - pci_name(pdev)); - goto out_disable_device; - } - } + if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) && + pci_set_dma_mask(pdev, DMA_32BIT_MASK)) + goto out_disable_device; + - error = -ENOMEM; - dev = alloc_etherdev(sizeof(DEV_NET)); - if (!dev) { - printk(KERN_ERR "sk98lin: unable to allocate etherdev " + if ((dev = alloc_etherdev(sizeof(DEV_NET))) == NULL) { + printk(KERN_ERR "Unable to allocate etherdev " "structure!\n"); goto out_disable_device; } pNet = netdev_priv(dev); - pNet->pAC = kzalloc(sizeof(SK_AC), GFP_KERNEL); + pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL); if (!pNet->pAC) { - printk(KERN_ERR "sk98lin: unable to allocate adapter " + printk(KERN_ERR "Unable to allocate adapter " "structure!\n"); goto out_free_netdev; } + memset(pNet->pAC, 0, sizeof(SK_AC)); pAC = pNet->pAC; pAC->PciDev = pdev; @@ -4817,7 +4810,6 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, pAC->CheckQueue = SK_FALSE; dev->irq = pdev->irq; - error = SkGeInitPCI(pAC); if (error) { printk(KERN_ERR "sk98lin: PCI setup failed: %i\n", error); @@ -4852,25 +4844,19 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, #endif } - if (using_dac) - dev->features |= NETIF_F_HIGHDMA; - pAC->Index = boards_found++; - error = SkGeBoardInit(dev, pAC); - if (error) + if (SkGeBoardInit(dev, pAC)) goto out_free_netdev; /* Read Adapter name from VPD */ if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) { - error = -EIO; printk(KERN_ERR "sk98lin: Could not read VPD data.\n"); goto out_free_resources; } /* Register net device */ - error = register_netdev(dev); - if (error) { + if (register_netdev(dev)) { printk(KERN_ERR "sk98lin: Could not register device.\n"); goto out_free_resources; } @@ -4897,17 +4883,15 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, boards_found++; - pci_set_drvdata(pdev, dev); - /* More then one port found */ if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { - dev = alloc_etherdev(sizeof(DEV_NET)); - if (!dev) { - printk(KERN_ERR "sk98lin: unable to allocate etherdev " + if ((dev = alloc_etherdev(sizeof(DEV_NET))) == 0) { + printk(KERN_ERR "Unable to allocate etherdev " "structure!\n"); - goto single_port; + goto out; } + pAC->dev[1] = dev; pNet = netdev_priv(dev); pNet->PortNr = 1; pNet->NetNr = 1; @@ -4936,28 +4920,20 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, #endif } - if (using_dac) - dev->features |= NETIF_F_HIGHDMA; - - error = register_netdev(dev); - if (error) { - printk(KERN_ERR "sk98lin: Could not register device" - " for second port. (%d)\n", error); + if (register_netdev(dev)) { + printk(KERN_ERR "sk98lin: Could not register device for seconf port.\n"); free_netdev(dev); - goto single_port; + pAC->dev[1] = pAC->dev[0]; + } else { + memcpy(&dev->dev_addr, + &pAC->Addr.Net[1].CurrentMacAddress, 6); + memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); + + printk("%s: %s\n", dev->name, DeviceStr); + printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); } - - pAC->dev[1] = dev; - memcpy(&dev->dev_addr, - &pAC->Addr.Net[1].CurrentMacAddress, 6); - memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); - - printk("%s: %s\n", dev->name, DeviceStr); - printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); } -single_port: - /* Save the hardware revision */ pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) + (pAC->GIni.GIPciHwRev & 0x0F); @@ -4969,6 +4945,7 @@ static int __devinit skge_probe_one(struct pci_dev *pdev, memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA)); memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA)); + pci_set_drvdata(pdev, dev); return 0; out_free_resources: diff --git a/trunk/drivers/net/smc-ultra.c b/trunk/drivers/net/smc-ultra.c index 3db30cd0625e..ba8593ac3f8a 100644 --- a/trunk/drivers/net/smc-ultra.c +++ b/trunk/drivers/net/smc-ultra.c @@ -168,6 +168,18 @@ static int __init do_ultra_probe(struct net_device *dev) return -ENODEV; } +static void cleanup_card(struct net_device *dev) +{ + /* NB: ultra_close_card() does free_irq */ +#ifdef __ISAPNP__ + struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; + if (idev) + pnp_device_detach(idev); +#endif + release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT); + iounmap(ei_status.mem); +} + #ifndef MODULE struct net_device * __init ultra_probe(int unit) { @@ -582,18 +594,6 @@ init_module(void) return -ENXIO; } -static void cleanup_card(struct net_device *dev) -{ - /* NB: ultra_close_card() does free_irq */ -#ifdef __ISAPNP__ - struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; - if (idev) - pnp_device_detach(idev); -#endif - release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT); - iounmap(ei_status.mem); -} - void cleanup_module(void) { diff --git a/trunk/drivers/net/smc91x.c b/trunk/drivers/net/smc91x.c index 7ec08127c9d6..28bf2e69eb5e 100644 --- a/trunk/drivers/net/smc91x.c +++ b/trunk/drivers/net/smc91x.c @@ -88,6 +88,7 @@ static const char version[] = #include #include +#include #include "smc91x.h" @@ -2006,10 +2007,12 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) } /* Grab the IRQ */ - retval = request_irq(dev->irq, &smc_interrupt, SMC_IRQ_FLAGS, dev->name, dev); + retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev); if (retval) goto err_out; + set_irq_type(dev->irq, SMC_IRQ_TRIGGER_TYPE); + #ifdef SMC_USE_PXA_DMA { int dma = pxa_request_dma(dev->name, DMA_PRIO_LOW, diff --git a/trunk/drivers/net/smc91x.h b/trunk/drivers/net/smc91x.h index e0efd1964e72..5c2824be4ee6 100644 --- a/trunk/drivers/net/smc91x.h +++ b/trunk/drivers/net/smc91x.h @@ -90,7 +90,7 @@ __l--; \ } \ } while (0) -#define SMC_IRQ_FLAGS (0) +#define set_irq_type(irq, type) #elif defined(CONFIG_SA1100_PLEB) /* We can only do 16-bit reads and writes in the static memory space. */ @@ -109,7 +109,7 @@ #define SMC_outw(v, a, r) writew(v, (a) + (r)) #define SMC_outsw(a, r, p, l) writesw((a) + (r), p, l) -#define SMC_IRQ_FLAGS (0) +#define set_irq_type(irq, type) do {} while (0) #elif defined(CONFIG_SA1100_ASSABET) @@ -185,11 +185,11 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #include #include -#define SMC_IRQ_FLAGS (( \ +#define SMC_IRQ_TRIGGER_TYPE (( \ machine_is_omap_h2() \ || machine_is_omap_h3() \ || (machine_is_omap_innovator() && !cpu_is_omap1510()) \ - ) ? SA_TRIGGER_FALLING : SA_TRIGGER_RISING) + ) ? IRQT_FALLING : IRQT_RISING) #elif defined(CONFIG_SH_SH4202_MICRODEV) @@ -209,7 +209,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define SMC_insw(a, r, p, l) insw((a) + (r) - 0xa0000000, p, l) #define SMC_outsw(a, r, p, l) outsw((a) + (r) - 0xa0000000, p, l) -#define SMC_IRQ_FLAGS (0) +#define set_irq_type(irq, type) do {} while(0) #elif defined(CONFIG_ISA) @@ -237,7 +237,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define SMC_insw(a, r, p, l) insw(((u32)a) + (r), p, l) #define SMC_outsw(a, r, p, l) outsw(((u32)a) + (r), p, l) -#define SMC_IRQ_FLAGS (0) +#define set_irq_type(irq, type) do {} while(0) #define RPC_LSA_DEFAULT RPC_LED_TX_RX #define RPC_LSB_DEFAULT RPC_LED_100_10 @@ -319,7 +319,7 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l) au_writew(*_p++ , _a); \ } while(0) -#define SMC_IRQ_FLAGS (0) +#define set_irq_type(irq, type) do {} while (0) #else @@ -342,8 +342,8 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l) #endif -#ifndef SMC_IRQ_FLAGS -#define SMC_IRQ_FLAGS SA_TRIGGER_RISING +#ifndef SMC_IRQ_TRIGGER_TYPE +#define SMC_IRQ_TRIGGER_TYPE IRQT_RISING #endif #ifdef SMC_USE_PXA_DMA diff --git a/trunk/drivers/net/tulip/tulip_core.c b/trunk/drivers/net/tulip/tulip_core.c index c67c91251d04..125ed00e95a5 100644 --- a/trunk/drivers/net/tulip/tulip_core.c +++ b/trunk/drivers/net/tulip/tulip_core.c @@ -1564,7 +1564,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, dev->dev_addr, 6); } #endif -#if defined(__i386__) || defined(__x86_64__) /* Patch up x86 BIOS bug. */ +#if defined(__i386__) /* Patch up x86 BIOS bug. */ if (last_irq) irq = last_irq; #endif diff --git a/trunk/drivers/net/wan/sdla.c b/trunk/drivers/net/wan/sdla.c index 22e794071cf4..036adc4f8ba7 100644 --- a/trunk/drivers/net/wan/sdla.c +++ b/trunk/drivers/net/wan/sdla.c @@ -329,9 +329,9 @@ static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr) struct _dlci_stat { - short dlci; - char flags; -} __attribute__((packed)); + short dlci __attribute__((packed)); + char flags __attribute__((packed)); +}; struct _frad_stat { diff --git a/trunk/drivers/net/wd.c b/trunk/drivers/net/wd.c index 7caa8dc88a58..b03feae459fc 100644 --- a/trunk/drivers/net/wd.c +++ b/trunk/drivers/net/wd.c @@ -127,6 +127,13 @@ static int __init do_wd_probe(struct net_device *dev) return -ENODEV; } +static void cleanup_card(struct net_device *dev) +{ + free_irq(dev->irq, dev); + release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT); + iounmap(ei_status.mem); +} + #ifndef MODULE struct net_device * __init wd_probe(int unit) { @@ -531,13 +538,6 @@ init_module(void) return -ENXIO; } -static void cleanup_card(struct net_device *dev) -{ - free_irq(dev->irq, dev); - release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT); - iounmap(ei_status.mem); -} - void cleanup_module(void) { diff --git a/trunk/drivers/net/wireless/ipw2100.c b/trunk/drivers/net/wireless/ipw2100.c index cf05661fb1bd..44cd3fcd1572 100644 --- a/trunk/drivers/net/wireless/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2100.c @@ -7153,7 +7153,7 @@ static int ipw2100_wx_get_range(struct net_device *dev, /* Set the Wireless Extension versions */ range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 18; + range->we_version_source = 16; // range->retry_capa; /* What retry options are supported */ // range->retry_flags; /* How to decode max/min retry limit */ @@ -7184,9 +7184,6 @@ static int ipw2100_wx_get_range(struct net_device *dev, IW_EVENT_CAPA_MASK(SIOCGIWAP)); range->event_capa[1] = IW_EVENT_CAPA_K_1; - range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - IPW_DEBUG_WX("GET Range\n"); return 0; diff --git a/trunk/drivers/oprofile/buffer_sync.c b/trunk/drivers/oprofile/buffer_sync.c index b2e8e49c8659..531b07313141 100644 --- a/trunk/drivers/oprofile/buffer_sync.c +++ b/trunk/drivers/oprofile/buffer_sync.c @@ -43,16 +43,13 @@ static void process_task_mortuary(void); * list for processing. Only after two full buffer syncs * does the task eventually get freed, because by then * we are sure we will not reference it again. - * Can be invoked from softirq via RCU callback due to - * call_rcu() of the task struct, hence the _irqsave. */ static int task_free_notify(struct notifier_block * self, unsigned long val, void * data) { - unsigned long flags; struct task_struct * task = data; - spin_lock_irqsave(&task_mortuary, flags); + spin_lock(&task_mortuary); list_add(&task->tasks, &dying_tasks); - spin_unlock_irqrestore(&task_mortuary, flags); + spin_unlock(&task_mortuary); return NOTIFY_OK; } @@ -434,22 +431,25 @@ static void increment_tail(struct oprofile_cpu_buffer * b) */ static void process_task_mortuary(void) { - unsigned long flags; - LIST_HEAD(local_dead_tasks); + struct list_head * pos; + struct list_head * pos2; struct task_struct * task; - struct task_struct * ttask; - spin_lock_irqsave(&task_mortuary, flags); + spin_lock(&task_mortuary); - list_splice_init(&dead_tasks, &local_dead_tasks); - list_splice_init(&dying_tasks, &dead_tasks); - - spin_unlock_irqrestore(&task_mortuary, flags); - - list_for_each_entry_safe(task, ttask, &local_dead_tasks, tasks) { + list_for_each_safe(pos, pos2, &dead_tasks) { + task = list_entry(pos, struct task_struct, tasks); list_del(&task->tasks); free_task(task); } + + list_for_each_safe(pos, pos2, &dying_tasks) { + task = list_entry(pos, struct task_struct, tasks); + list_del(&task->tasks); + list_add_tail(&task->tasks, &dead_tasks); + } + + spin_unlock(&task_mortuary); } diff --git a/trunk/drivers/oprofile/cpu_buffer.c b/trunk/drivers/oprofile/cpu_buffer.c index 78193e4bbdb5..026f671ea558 100644 --- a/trunk/drivers/oprofile/cpu_buffer.c +++ b/trunk/drivers/oprofile/cpu_buffer.c @@ -52,8 +52,7 @@ int alloc_cpu_buffers(void) for_each_online_cpu(i) { struct oprofile_cpu_buffer * b = &cpu_buffer[i]; - b->buffer = vmalloc_node(sizeof(struct op_sample) * buffer_size, - cpu_to_node(i)); + b->buffer = vmalloc(sizeof(struct op_sample) * buffer_size); if (!b->buffer) goto fail; diff --git a/trunk/drivers/parport/Kconfig b/trunk/drivers/parport/Kconfig index a665951b1586..b8241561da45 100644 --- a/trunk/drivers/parport/Kconfig +++ b/trunk/drivers/parport/Kconfig @@ -34,7 +34,7 @@ config PARPORT config PARPORT_PC tristate "PC-style hardware" - depends on PARPORT && (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV + depends on PARPORT && (!SPARC64 || PCI) && !SPARC32 && !M32R ---help--- You should say Y here if you have a PC-style parallel port. All IBM PC compatible computers and some Alphas have PC-style diff --git a/trunk/drivers/parport/parport_pc.c b/trunk/drivers/parport/parport_pc.c index 9302b8fd7461..18e85ccdae67 100644 --- a/trunk/drivers/parport/parport_pc.c +++ b/trunk/drivers/parport/parport_pc.c @@ -2371,10 +2371,8 @@ void parport_pc_unregister_port (struct parport *p) spin_lock(&ports_lock); list_del_init(&priv->list); spin_unlock(&ports_lock); -#if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA) if (p->dma != PARPORT_DMA_NONE) free_dma(p->dma); -#endif if (p->irq != PARPORT_IRQ_NONE) free_irq(p->irq, p); release_region(p->base, 3); @@ -2382,11 +2380,13 @@ void parport_pc_unregister_port (struct parport *p) release_region(p->base + 3, p->size - 3); if (p->modes & PARPORT_MODE_ECP) release_region(p->base_hi, 3); -#if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA) +#ifdef CONFIG_PARPORT_PC_FIFO +#ifdef HAS_DMA if (priv->dma_buf) pci_free_consistent(priv->dev, PAGE_SIZE, priv->dma_buf, priv->dma_handle); +#endif #endif kfree (p->private_data); parport_put_port(p); diff --git a/trunk/drivers/pci/hotplug/pciehp.h b/trunk/drivers/pci/hotplug/pciehp.h index 0aac6a61337d..6a61b9f286e1 100644 --- a/trunk/drivers/pci/hotplug/pciehp.h +++ b/trunk/drivers/pci/hotplug/pciehp.h @@ -32,7 +32,6 @@ #include #include #include -#include /* signal_pending() */ #include #include "pci_hotplug.h" diff --git a/trunk/drivers/pci/hotplug/pciehp_hpc.c b/trunk/drivers/pci/hotplug/pciehp_hpc.c index ac1e495c314e..0b8b26beb163 100644 --- a/trunk/drivers/pci/hotplug/pciehp_hpc.c +++ b/trunk/drivers/pci/hotplug/pciehp_hpc.c @@ -30,9 +30,6 @@ #include #include #include -#include -#include -#include #include #include diff --git a/trunk/drivers/rapidio/rio-scan.c b/trunk/drivers/rapidio/rio-scan.c index 94e30fe4b8f3..4f7ed4bd3be9 100644 --- a/trunk/drivers/rapidio/rio-scan.c +++ b/trunk/drivers/rapidio/rio-scan.c @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include "rio.h" diff --git a/trunk/drivers/rapidio/rio-sysfs.c b/trunk/drivers/rapidio/rio-sysfs.c index bef9316e95df..30a11436e241 100644 --- a/trunk/drivers/rapidio/rio-sysfs.c +++ b/trunk/drivers/rapidio/rio-sysfs.c @@ -15,7 +15,6 @@ #include #include #include -#include /* for capable() */ #include "rio.h" diff --git a/trunk/drivers/rapidio/rio.c b/trunk/drivers/rapidio/rio.c index 5e382470faa2..3ca1011ceaac 100644 --- a/trunk/drivers/rapidio/rio.c +++ b/trunk/drivers/rapidio/rio.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "rio.h" diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index 2472fa1a1be1..f779f674dfa0 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -1724,34 +1723,12 @@ dasd_release(struct inode *inp, struct file *filp) return 0; } -/* - * Return disk geometry. - */ -static int -dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - struct dasd_device *device; - - device = bdev->bd_disk->private_data; - if (!device) - return -ENODEV; - - if (!device->discipline || - !device->discipline->fill_geometry) - return -EINVAL; - - device->discipline->fill_geometry(device, geo); - geo->start = get_start_sect(bdev) >> device->s2b_shift; - return 0; -} - struct block_device_operations dasd_device_operations = { .owner = THIS_MODULE, .open = dasd_open, .release = dasd_release, .ioctl = dasd_ioctl, - .getgeo = dasd_getgeo, }; diff --git a/trunk/drivers/s390/block/dasd_ioctl.c b/trunk/drivers/s390/block/dasd_ioctl.c index 8e4dcd58599e..044b75371990 100644 --- a/trunk/drivers/s390/block/dasd_ioctl.c +++ b/trunk/drivers/s390/block/dasd_ioctl.c @@ -485,6 +485,33 @@ dasd_ioctl_set_ro(struct block_device *bdev, int no, long args) return rc; } +/* + * Return disk geometry. + */ +static int +dasd_ioctl_getgeo(struct block_device *bdev, int no, long args) +{ + struct hd_geometry geo = { 0, }; + struct dasd_device *device; + + device = bdev->bd_disk->private_data; + if (device == NULL) + return -ENODEV; + + if (device == NULL || device->discipline == NULL || + device->discipline->fill_geometry == NULL) + return -EINVAL; + + geo = (struct hd_geometry) {}; + device->discipline->fill_geometry(device, &geo); + geo.start = get_start_sect(bdev) >> device->s2b_shift; + if (copy_to_user((struct hd_geometry __user *) args, &geo, + sizeof (struct hd_geometry))) + return -EFAULT; + + return 0; +} + /* * List of static ioctls. */ @@ -501,6 +528,7 @@ static struct { int no; dasd_ioctl_fn_t fn; } dasd_ioctls[] = { BIODASDPRRST, dasd_ioctl_reset_profile }, { BLKROSET, dasd_ioctl_set_ro }, { DASDAPIVER, dasd_ioctl_api_version }, + { HDIO_GETGEO, dasd_ioctl_getgeo }, { -1, NULL } }; diff --git a/trunk/drivers/s390/block/xpram.c b/trunk/drivers/s390/block/xpram.c index 54ecd548c318..bf3a67c3cc5e 100644 --- a/trunk/drivers/s390/block/xpram.c +++ b/trunk/drivers/s390/block/xpram.c @@ -328,27 +328,31 @@ static int xpram_make_request(request_queue_t *q, struct bio *bio) return 0; } -static int xpram_getgeo(struct block_device *bdev, struct hd_geometry *geo) +static int xpram_ioctl (struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { + struct hd_geometry __user *geo; unsigned long size; - + if (cmd != HDIO_GETGEO) + return -EINVAL; /* * get geometry: we have to fake one... trim the size to a * multiple of 64 (32k): tell we have 16 sectors, 4 heads, * whatever cylinders. Tell also that data starts at sector. 4. */ + geo = (struct hd_geometry __user *) arg; size = (xpram_pages * 8) & ~0x3f; - geo->cylinders = size >> 6; - geo->heads = 4; - geo->sectors = 16; - geo->start = 4; + put_user(size >> 6, &geo->cylinders); + put_user(4, &geo->heads); + put_user(16, &geo->sectors); + put_user(4, &geo->start); return 0; } static struct block_device_operations xpram_devops = { .owner = THIS_MODULE, - .getgeo = xpram_getgeo, + .ioctl = xpram_ioctl, }; /* diff --git a/trunk/drivers/scsi/mac53c94.c b/trunk/drivers/scsi/mac53c94.c index 311a4122bd70..932dcf0366eb 100644 --- a/trunk/drivers/scsi/mac53c94.c +++ b/trunk/drivers/scsi/mac53c94.c @@ -432,12 +432,11 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat struct Scsi_Host *host; void *dma_cmd_space; unsigned char *clkprop; - int proplen, rc = -ENODEV; + int proplen; if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) { - printk(KERN_ERR "mac53c94: expected 2 addrs and intrs" - " (got %d/%d)\n", - macio_resource_count(mdev), macio_irq_count(mdev)); + printk(KERN_ERR "mac53c94: expected 2 addrs and intrs (got %d/%d)\n", + node->n_addrs, node->n_intrs); return -ENODEV; } @@ -449,7 +448,6 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat host = scsi_host_alloc(&mac53c94_template, sizeof(struct fsc_state)); if (host == NULL) { printk(KERN_ERR "mac53c94: couldn't register host"); - rc = -ENOMEM; goto out_release; } @@ -488,7 +486,6 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat if (dma_cmd_space == 0) { printk(KERN_ERR "mac53c94: couldn't allocate dma " "command space for %s\n", node->full_name); - rc = -ENOMEM; goto out_free; } state->dma_cmds = (struct dbdma_cmd *)DBDMA_ALIGN(dma_cmd_space); @@ -498,21 +495,18 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat mac53c94_init(state); - if (request_irq(state->intr, do_mac53c94_interrupt, 0, "53C94",state)) { + if (request_irq(state->intr, do_mac53c94_interrupt, 0, "53C94", state)) { printk(KERN_ERR "mac53C94: can't get irq %d for %s\n", state->intr, node->full_name); goto out_free_dma; } - rc = scsi_add_host(host, &mdev->ofdev.dev); - if (rc != 0) - goto out_release_irq; - + /* XXX FIXME: handle failure */ + scsi_add_host(host, &mdev->ofdev.dev); scsi_scan_host(host); + return 0; - out_release_irq: - free_irq(state->intr, state); out_free_dma: kfree(state->dma_cmd_space); out_free: @@ -524,7 +518,7 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat out_release: macio_release_resources(mdev); - return rc; + return -ENODEV; } static int mac53c94_remove(struct macio_dev *mdev) diff --git a/trunk/drivers/scsi/mesh.c b/trunk/drivers/scsi/mesh.c index d6d2125f9044..bdccf73cf9fe 100644 --- a/trunk/drivers/scsi/mesh.c +++ b/trunk/drivers/scsi/mesh.c @@ -1869,8 +1869,7 @@ static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match) if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) { printk(KERN_ERR "mesh: expected 2 addrs and 2 intrs" - " (got %d,%d)\n", macio_resource_count(mdev), - macio_irq_count(mdev)); + " (got %d,%d)\n", mesh->n_addrs, mesh->n_intrs); return -ENODEV; } diff --git a/trunk/drivers/scsi/sata_nv.c b/trunk/drivers/scsi/sata_nv.c index bbbb55eeb73a..c0cf52cb975a 100644 --- a/trunk/drivers/scsi/sata_nv.c +++ b/trunk/drivers/scsi/sata_nv.c @@ -29,12 +29,6 @@ * NV-specific details such as register offsets, SATA phy location, * hotplug info, etc. * - * 0.10 - * - Fixed spurious interrupts issue seen with the Maxtor 6H500F0 500GB - * drive. Also made the check_hotplug() callbacks return whether there - * was a hotplug interrupt or not. This was not the source of the - * spurious interrupts, but is the right thing to do anyway. - * * 0.09 * - Fixed bug introduced by 0.08's MCP51 and MCP55 support. * @@ -130,10 +124,10 @@ static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void nv_host_stop (struct ata_host_set *host_set); static void nv_enable_hotplug(struct ata_probe_ent *probe_ent); static void nv_disable_hotplug(struct ata_host_set *host_set); -static int nv_check_hotplug(struct ata_host_set *host_set); +static void nv_check_hotplug(struct ata_host_set *host_set); static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent); static void nv_disable_hotplug_ck804(struct ata_host_set *host_set); -static int nv_check_hotplug_ck804(struct ata_host_set *host_set); +static void nv_check_hotplug_ck804(struct ata_host_set *host_set); enum nv_host_type { @@ -182,7 +176,7 @@ struct nv_host_desc enum nv_host_type host_type; void (*enable_hotplug)(struct ata_probe_ent *probe_ent); void (*disable_hotplug)(struct ata_host_set *host_set); - int (*check_hotplug)(struct ata_host_set *host_set); + void (*check_hotplug)(struct ata_host_set *host_set); }; static struct nv_host_desc nv_device_tbl[] = { @@ -315,16 +309,12 @@ static irqreturn_t nv_interrupt (int irq, void *dev_instance, qc = ata_qc_from_tag(ap, ap->active_tag); if (qc && (!(qc->tf.ctl & ATA_NIEN))) handled += ata_host_intr(ap, qc); - else - // No request pending? Clear interrupt status - // anyway, in case there's one pending. - ap->ops->check_status(ap); } } if (host->host_desc->check_hotplug) - handled += host->host_desc->check_hotplug(host_set); + host->host_desc->check_hotplug(host_set); spin_unlock_irqrestore(&host_set->lock, flags); @@ -507,7 +497,7 @@ static void nv_disable_hotplug(struct ata_host_set *host_set) outb(intr_mask, host_set->ports[0]->ioaddr.scr_addr + NV_INT_ENABLE); } -static int nv_check_hotplug(struct ata_host_set *host_set) +static void nv_check_hotplug(struct ata_host_set *host_set) { u8 intr_status; @@ -532,11 +522,7 @@ static int nv_check_hotplug(struct ata_host_set *host_set) if (intr_status & NV_INT_STATUS_SDEV_REMOVED) printk(KERN_WARNING "nv_sata: " "Secondary device removed\n"); - - return 1; } - - return 0; } static void nv_enable_hotplug_ck804(struct ata_probe_ent *probe_ent) @@ -574,7 +560,7 @@ static void nv_disable_hotplug_ck804(struct ata_host_set *host_set) pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval); } -static int nv_check_hotplug_ck804(struct ata_host_set *host_set) +static void nv_check_hotplug_ck804(struct ata_host_set *host_set) { u8 intr_status; @@ -599,11 +585,7 @@ static int nv_check_hotplug_ck804(struct ata_host_set *host_set) if (intr_status & NV_INT_STATUS_SDEV_REMOVED) printk(KERN_WARNING "nv_sata: " "Secondary device removed\n"); - - return 1; } - - return 0; } static int __init nv_init(void) diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index ee5f4dfdab14..180676d7115a 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -69,6 +69,7 @@ #include "scsi_logging.h" static void scsi_done(struct scsi_cmnd *cmd); +static int scsi_retry_command(struct scsi_cmnd *cmd); /* * Definitions and constants. @@ -751,7 +752,7 @@ static void scsi_done(struct scsi_cmnd *cmd) * isn't running --- used by scsi_times_out */ void __scsi_done(struct scsi_cmnd *cmd) { - struct request *rq = cmd->request; + unsigned long flags; /* * Set the serial numbers back to zero @@ -762,14 +763,71 @@ void __scsi_done(struct scsi_cmnd *cmd) if (cmd->result) atomic_inc(&cmd->device->ioerr_cnt); - BUG_ON(!rq); - /* - * The uptodate/nbytes values don't matter, as we allow partial - * completes and thus will check this in the softirq callback + * Next, enqueue the command into the done queue. + * It is a per-CPU queue, so we just disable local interrupts + * and need no spinlock. */ - rq->completion_data = cmd; - blk_complete_request(rq); + local_irq_save(flags); + list_add_tail(&cmd->eh_entry, &__get_cpu_var(scsi_done_q)); + raise_softirq_irqoff(SCSI_SOFTIRQ); + local_irq_restore(flags); +} + +/** + * scsi_softirq - Perform post-interrupt processing of finished SCSI commands. + * + * This is the consumer of the done queue. + * + * This is called with all interrupts enabled. This should reduce + * interrupt latency, stack depth, and reentrancy of the low-level + * drivers. + */ +static void scsi_softirq(struct softirq_action *h) +{ + int disposition; + LIST_HEAD(local_q); + + local_irq_disable(); + list_splice_init(&__get_cpu_var(scsi_done_q), &local_q); + local_irq_enable(); + + while (!list_empty(&local_q)) { + struct scsi_cmnd *cmd = list_entry(local_q.next, + struct scsi_cmnd, eh_entry); + /* The longest time any command should be outstanding is the + * per command timeout multiplied by the number of retries. + * + * For a typical command, this is 2.5 minutes */ + unsigned long wait_for + = cmd->allowed * cmd->timeout_per_command; + list_del_init(&cmd->eh_entry); + + disposition = scsi_decide_disposition(cmd); + if (disposition != SUCCESS && + time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) { + sdev_printk(KERN_ERR, cmd->device, + "timing out command, waited %lus\n", + wait_for/HZ); + disposition = SUCCESS; + } + + scsi_log_completion(cmd, disposition); + switch (disposition) { + case SUCCESS: + scsi_finish_command(cmd); + break; + case NEEDS_RETRY: + scsi_retry_command(cmd); + break; + case ADD_TO_MLQUEUE: + scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY); + break; + default: + if (!scsi_eh_scmd_add(cmd, 0)) + scsi_finish_command(cmd); + } + } } /* @@ -782,7 +840,7 @@ void __scsi_done(struct scsi_cmnd *cmd) * level drivers should not become re-entrant as a result of * this. */ -int scsi_retry_command(struct scsi_cmnd *cmd) +static int scsi_retry_command(struct scsi_cmnd *cmd) { /* * Restore the SCSI command state. @@ -1215,6 +1273,38 @@ int scsi_device_cancel(struct scsi_device *sdev, int recovery) } EXPORT_SYMBOL(scsi_device_cancel); +#ifdef CONFIG_HOTPLUG_CPU +static int scsi_cpu_notify(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + int cpu = (unsigned long)hcpu; + + switch(action) { + case CPU_DEAD: + /* Drain scsi_done_q. */ + local_irq_disable(); + list_splice_init(&per_cpu(scsi_done_q, cpu), + &__get_cpu_var(scsi_done_q)); + raise_softirq_irqoff(SCSI_SOFTIRQ); + local_irq_enable(); + break; + default: + break; + } + return NOTIFY_OK; +} + +static struct notifier_block __devinitdata scsi_cpu_nb = { + .notifier_call = scsi_cpu_notify, +}; + +#define register_scsi_cpu() register_cpu_notifier(&scsi_cpu_nb) +#define unregister_scsi_cpu() unregister_cpu_notifier(&scsi_cpu_nb) +#else +#define register_scsi_cpu() +#define unregister_scsi_cpu() +#endif /* CONFIG_HOTPLUG_CPU */ + MODULE_DESCRIPTION("SCSI core"); MODULE_LICENSE("GPL"); @@ -1248,6 +1338,8 @@ static int __init init_scsi(void) INIT_LIST_HEAD(&per_cpu(scsi_done_q, i)); devfs_mk_dir("scsi"); + open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL); + register_scsi_cpu(); printk(KERN_NOTICE "SCSI subsystem initialized\n"); return 0; @@ -1275,6 +1367,7 @@ static void __exit exit_scsi(void) devfs_remove("scsi"); scsi_exit_procfs(); scsi_exit_queue(); + unregister_scsi_cpu(); } subsys_initcall(init_scsi); diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 00c9bf383e23..ba93d6e66d48 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -1493,41 +1493,6 @@ static void scsi_kill_request(struct request *req, request_queue_t *q) __scsi_done(cmd); } -static void scsi_softirq_done(struct request *rq) -{ - struct scsi_cmnd *cmd = rq->completion_data; - unsigned long wait_for = cmd->allowed * cmd->timeout_per_command; - int disposition; - - INIT_LIST_HEAD(&cmd->eh_entry); - - disposition = scsi_decide_disposition(cmd); - if (disposition != SUCCESS && - time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) { - sdev_printk(KERN_ERR, cmd->device, - "timing out command, waited %lus\n", - wait_for/HZ); - disposition = SUCCESS; - } - - scsi_log_completion(cmd, disposition); - - switch (disposition) { - case SUCCESS: - scsi_finish_command(cmd); - break; - case NEEDS_RETRY: - scsi_retry_command(cmd); - break; - case ADD_TO_MLQUEUE: - scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY); - break; - default: - if (!scsi_eh_scmd_add(cmd, 0)) - scsi_finish_command(cmd); - } -} - /* * Function: scsi_request_fn() * @@ -1702,7 +1667,6 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); blk_queue_segment_boundary(q, shost->dma_boundary); blk_queue_issue_flush_fn(q, scsi_issue_flush_fn); - blk_queue_softirq_done(q, scsi_softirq_done); if (!shost->use_clustering) clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); diff --git a/trunk/drivers/scsi/scsi_priv.h b/trunk/drivers/scsi/scsi_priv.h index 14a6198cb8d2..f04e7e11f57a 100644 --- a/trunk/drivers/scsi/scsi_priv.h +++ b/trunk/drivers/scsi/scsi_priv.h @@ -44,7 +44,6 @@ extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd, struct scsi_request *sreq); extern void __scsi_release_request(struct scsi_request *sreq); extern void __scsi_done(struct scsi_cmnd *cmd); -extern int scsi_retry_command(struct scsi_cmnd *cmd); #ifdef CONFIG_SCSI_LOGGING void scsi_log_send(struct scsi_cmnd *cmd); void scsi_log_completion(struct scsi_cmnd *cmd, int disposition); diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 4c5127ed379c..32d4d8d7b9f3 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -527,7 +527,7 @@ static int sd_release(struct inode *inode, struct file *filp) return 0; } -static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo) +static int sd_hdio_getgeo(struct block_device *bdev, struct hd_geometry __user *loc) { struct scsi_disk *sdkp = scsi_disk(bdev->bd_disk); struct scsi_device *sdp = sdkp->device; @@ -545,9 +545,15 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo) else scsicam_bios_param(bdev, sdkp->capacity, diskinfo); - geo->heads = diskinfo[0]; - geo->sectors = diskinfo[1]; - geo->cylinders = diskinfo[2]; + if (put_user(diskinfo[0], &loc->heads)) + return -EFAULT; + if (put_user(diskinfo[1], &loc->sectors)) + return -EFAULT; + if (put_user(diskinfo[2], &loc->cylinders)) + return -EFAULT; + if (put_user((unsigned)get_start_sect(bdev), + (unsigned long __user *)&loc->start)) + return -EFAULT; return 0; } @@ -587,6 +593,12 @@ static int sd_ioctl(struct inode * inode, struct file * filp, if (!scsi_block_when_processing_errors(sdp) || !error) return error; + if (cmd == HDIO_GETGEO) { + if (!arg) + return -EINVAL; + return sd_hdio_getgeo(bdev, p); + } + /* * Send SCSI addressing ioctls directly to mid level, send other * ioctls to block level and then onto mid level if they can't be @@ -788,7 +800,6 @@ static struct block_device_operations sd_fops = { .open = sd_open, .release = sd_release, .ioctl = sd_ioctl, - .getgeo = sd_getgeo, #ifdef CONFIG_COMPAT .compat_ioctl = sd_compat_ioctl, #endif diff --git a/trunk/drivers/scsi/sg.c b/trunk/drivers/scsi/sg.c index 78aad9582bcf..221e96e2620a 100644 --- a/trunk/drivers/scsi/sg.c +++ b/trunk/drivers/scsi/sg.c @@ -2493,7 +2493,7 @@ sg_page_malloc(int rqSz, int lowDma, int *retSzp) } if (resp) { if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) - memset(page_address(resp), 0, resSz); + memset(resp, 0, resSz); if (retSzp) *retSzp = resSz; } diff --git a/trunk/drivers/serial/8250.c b/trunk/drivers/serial/8250.c index e8454611cb65..1891cf5bdeef 100644 --- a/trunk/drivers/serial/8250.c +++ b/trunk/drivers/serial/8250.c @@ -54,8 +54,6 @@ */ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; -static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS; - /* * Debugging. */ @@ -2120,7 +2118,7 @@ static void __init serial8250_isa_init_ports(void) return; first = 0; - for (i = 0; i < nr_uarts; i++) { + for (i = 0; i < UART_NR; i++) { struct uart_8250_port *up = &serial8250_ports[i]; up->port.line = i; @@ -2139,7 +2137,7 @@ static void __init serial8250_isa_init_ports(void) } for (i = 0, up = serial8250_ports; - i < ARRAY_SIZE(old_serial_port) && i < nr_uarts; + i < ARRAY_SIZE(old_serial_port) && i < UART_NR; i++, up++) { up->port.iobase = old_serial_port[i].port; up->port.irq = irq_canonicalize(old_serial_port[i].irq); @@ -2161,7 +2159,7 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) serial8250_isa_init_ports(); - for (i = 0; i < nr_uarts; i++) { + for (i = 0; i < UART_NR; i++) { struct uart_8250_port *up = &serial8250_ports[i]; up->port.dev = dev; @@ -2264,7 +2262,7 @@ static int serial8250_console_setup(struct console *co, char *options) * if so, search for the first available port that does have * console support. */ - if (co->index >= nr_uarts) + if (co->index >= UART_NR) co->index = 0; port = &serial8250_ports[co->index].port; if (!port->iobase && !port->membase) @@ -2300,7 +2298,7 @@ static int __init find_port(struct uart_port *p) int line; struct uart_port *port; - for (line = 0; line < nr_uarts; line++) { + for (line = 0; line < UART_NR; line++) { port = &serial8250_ports[line].port; if (uart_match_port(p, port)) return line; @@ -2422,7 +2420,7 @@ static int __devexit serial8250_remove(struct platform_device *dev) { int i; - for (i = 0; i < nr_uarts; i++) { + for (i = 0; i < UART_NR; i++) { struct uart_8250_port *up = &serial8250_ports[i]; if (up->port.dev == &dev->dev) @@ -2489,7 +2487,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * /* * First, find a port entry which matches. */ - for (i = 0; i < nr_uarts; i++) + for (i = 0; i < UART_NR; i++) if (uart_match_port(&serial8250_ports[i].port, port)) return &serial8250_ports[i]; @@ -2498,7 +2496,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * * free entry. We look for one which hasn't been previously * used (indicated by zero iobase). */ - for (i = 0; i < nr_uarts; i++) + for (i = 0; i < UART_NR; i++) if (serial8250_ports[i].port.type == PORT_UNKNOWN && serial8250_ports[i].port.iobase == 0) return &serial8250_ports[i]; @@ -2507,7 +2505,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * * That also failed. Last resort is to find any entry which * doesn't have a real port associated with it. */ - for (i = 0; i < nr_uarts; i++) + for (i = 0; i < UART_NR; i++) if (serial8250_ports[i].port.type == PORT_UNKNOWN) return &serial8250_ports[i]; @@ -2592,11 +2590,8 @@ static int __init serial8250_init(void) { int ret, i; - if (nr_uarts > UART_NR) - nr_uarts = UART_NR; - printk(KERN_INFO "Serial: 8250/16550 driver $Revision: 1.90 $ " - "%d ports, IRQ sharing %sabled\n", nr_uarts, + "%d ports, IRQ sharing %sabled\n", (int) UART_NR, share_irqs ? "en" : "dis"); for (i = 0; i < NR_IRQS; i++) @@ -2656,9 +2651,6 @@ module_param(share_irqs, uint, 0644); MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices" " (unsafe)"); -module_param(nr_uarts, uint, 0644); -MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")"); - #ifdef CONFIG_SERIAL_8250_RSA module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); diff --git a/trunk/drivers/serial/Kconfig b/trunk/drivers/serial/Kconfig index 3fd5b999fdac..47ea8338c03c 100644 --- a/trunk/drivers/serial/Kconfig +++ b/trunk/drivers/serial/Kconfig @@ -95,16 +95,6 @@ config SERIAL_8250_NR_UARTS PCI enumeration and any ports that may be added at run-time via hot-plug, or any ISA multi-port serial cards. -config SERIAL_8250_RUNTIME_UARTS - int "Number of 8250/16550 serial ports to register at runtime" - depends on SERIAL_8250 - default "4" - help - Set this to the maximum number of serial ports you want - the kernel to register at boot time. This can be overriden - with the module parameter "nr_uarts", or boot-time parameter - 8250.nr_uarts - config SERIAL_8250_EXTENDED bool "Extended 8250/16550 serial driver options" depends on SERIAL_8250 @@ -369,29 +359,6 @@ config SERIAL_21285_CONSOLE your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) -config SERIAL_UART00 - bool "Excalibur serial port (uart00) support" - depends on ARM && ARCH_CAMELOT - select SERIAL_CORE - help - Say Y here if you want to use the hard logic uart on Excalibur. This - driver also supports soft logic implementations of this uart core. - -config SERIAL_UART00_CONSOLE - bool "Support for console on Excalibur serial port" - depends on SERIAL_UART00 - select SERIAL_CORE_CONSOLE - help - Say Y here if you want to support a serial console on an Excalibur - hard logic uart or uart00 IP core. - - 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=ttyS1". (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_MPSC bool "Marvell MPSC serial port support" depends on PPC32 && MV64X60 diff --git a/trunk/drivers/serial/Makefile b/trunk/drivers/serial/Makefile index d7c7c7180e33..137148bba4fa 100644 --- a/trunk/drivers/serial/Makefile +++ b/trunk/drivers/serial/Makefile @@ -29,7 +29,6 @@ obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o obj-$(CONFIG_SERIAL_PXA) += pxa.o obj-$(CONFIG_SERIAL_SA1100) += sa1100.o obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o -obj-$(CONFIG_SERIAL_UART00) += uart00.o obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o diff --git a/trunk/drivers/serial/cpm_uart/cpm_uart_core.c b/trunk/drivers/serial/cpm_uart/cpm_uart_core.c index 16af5626c243..987d22b53c22 100644 --- a/trunk/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/trunk/drivers/serial/cpm_uart/cpm_uart_core.c @@ -608,7 +608,7 @@ static int cpm_uart_tx_pump(struct uart_port *port) p = cpm2cpu_addr(bdp->cbd_bufaddr); - *p++ = port->x_char; + *p++ = xmit->buf[xmit->tail]; bdp->cbd_datlen = 1; bdp->cbd_sc |= BD_SC_READY; /* Get next BD. */ diff --git a/trunk/drivers/serial/pmac_zilog.c b/trunk/drivers/serial/pmac_zilog.c index ea24129eb6b9..5ddd8ab1f108 100644 --- a/trunk/drivers/serial/pmac_zilog.c +++ b/trunk/drivers/serial/pmac_zilog.c @@ -1431,14 +1431,11 @@ static int __init pmz_init_port(struct uart_pmac_port *uap) char name[1]; } *slots; int len; - struct resource r_ports, r_rxdma, r_txdma; /* * Request & map chip registers */ - if (of_address_to_resource(np, 0, &r_ports)) - return -ENODEV; - uap->port.mapbase = r_ports.start; + uap->port.mapbase = np->addrs[0].address; uap->port.membase = ioremap(uap->port.mapbase, 0x1000); uap->control_reg = uap->port.membase; @@ -1448,20 +1445,16 @@ static int __init pmz_init_port(struct uart_pmac_port *uap) * Request & map DBDMA registers */ #ifdef HAS_DBDMA - if (of_address_to_resource(np, 1, &r_txdma) == 0 && - of_address_to_resource(np, 2, &r_rxdma) == 0) + if (np->n_addrs >= 3 && np->n_intrs >= 3) uap->flags |= PMACZILOG_FLAG_HAS_DMA; -#else - memset(&r_txdma, 0, sizeof(struct resource)); - memset(&r_rxdma, 0, sizeof(struct resource)); #endif if (ZS_HAS_DMA(uap)) { - uap->tx_dma_regs = ioremap(r_txdma.start, 0x100); + uap->tx_dma_regs = ioremap(np->addrs[np->n_addrs - 2].address, 0x1000); if (uap->tx_dma_regs == NULL) { uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; goto no_dma; } - uap->rx_dma_regs = ioremap(r_rxdma.start, 0x100); + uap->rx_dma_regs = ioremap(np->addrs[np->n_addrs - 1].address, 0x1000); if (uap->rx_dma_regs == NULL) { iounmap(uap->tx_dma_regs); uap->tx_dma_regs = NULL; diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index 9589509fc5bd..34c576dfad8d 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/drivers/serial/serial_core.c @@ -1440,7 +1440,6 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) * modem is ready for us. */ spin_lock_irq(&port->lock); - port->ops->enable_ms(port); mctrl = port->ops->get_mctrl(port); spin_unlock_irq(&port->lock); if (mctrl & TIOCM_CAR) diff --git a/trunk/drivers/serial/uart00.c b/trunk/drivers/serial/uart00.c deleted file mode 100644 index 47b504ff38b2..000000000000 --- a/trunk/drivers/serial/uart00.c +++ /dev/null @@ -1,782 +0,0 @@ -/* - * linux/drivers/serial/uart00.c - * - * Driver for UART00 serial ports - * - * Based on drivers/char/serial_amba.c, by ARM Limited & - * Deep Blue Solutions Ltd. - * Copyright 2001 Altera Corporation - * - * Update for 2.6.4 by Dirk Behme - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This 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 - * - * $Id: uart00.c,v 1.35 2002/07/28 10:03:28 rmk Exp $ - * - */ -#include - -#if defined(CONFIG_SERIAL_UART00_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#define UART00_TYPE (volatile unsigned int*) -#include -#include - -#define UART_NR 2 - -#define SERIAL_UART00_NAME "ttyUA" -#define SERIAL_UART00_MAJOR 204 -#define SERIAL_UART00_MINOR 16 /* Temporary - will change in future */ -#define SERIAL_UART00_NR UART_NR -#define UART_PORT_SIZE 0x50 - -#define UART00_ISR_PASS_LIMIT 256 - -/* - * Access macros for the UART00 UARTs - */ -#define UART_GET_INT_STATUS(p) inl(UART_ISR((p)->membase)) -#define UART_PUT_IES(p, c) outl(c,UART_IES((p)->membase)) -#define UART_GET_IES(p) inl(UART_IES((p)->membase)) -#define UART_PUT_IEC(p, c) outl(c,UART_IEC((p)->membase)) -#define UART_GET_IEC(p) inl(UART_IEC((p)->membase)) -#define UART_PUT_CHAR(p, c) outl(c,UART_TD((p)->membase)) -#define UART_GET_CHAR(p) inl(UART_RD((p)->membase)) -#define UART_GET_RSR(p) inl(UART_RSR((p)->membase)) -#define UART_GET_RDS(p) inl(UART_RDS((p)->membase)) -#define UART_GET_MSR(p) inl(UART_MSR((p)->membase)) -#define UART_GET_MCR(p) inl(UART_MCR((p)->membase)) -#define UART_PUT_MCR(p, c) outl(c,UART_MCR((p)->membase)) -#define UART_GET_MC(p) inl(UART_MC((p)->membase)) -#define UART_PUT_MC(p, c) outl(c,UART_MC((p)->membase)) -#define UART_GET_TSR(p) inl(UART_TSR((p)->membase)) -#define UART_GET_DIV_HI(p) inl(UART_DIV_HI((p)->membase)) -#define UART_PUT_DIV_HI(p,c) outl(c,UART_DIV_HI((p)->membase)) -#define UART_GET_DIV_LO(p) inl(UART_DIV_LO((p)->membase)) -#define UART_PUT_DIV_LO(p,c) outl(c,UART_DIV_LO((p)->membase)) -#define UART_RX_DATA(s) ((s) & UART_RSR_RX_LEVEL_MSK) -#define UART_TX_READY(s) (((s) & UART_TSR_TX_LEVEL_MSK) < 15) -//#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & UART00_UARTFR_TMSK) == 0) - -static void uart00_stop_tx(struct uart_port *port) -{ - UART_PUT_IEC(port, UART_IEC_TIE_MSK); -} - -static void uart00_stop_rx(struct uart_port *port) -{ - UART_PUT_IEC(port, UART_IEC_RE_MSK); -} - -static void uart00_enable_ms(struct uart_port *port) -{ - UART_PUT_IES(port, UART_IES_ME_MSK); -} - -static void -uart00_rx_chars(struct uart_port *port, struct pt_regs *regs) -{ - struct tty_struct *tty = port->info->tty; - unsigned int status, ch, rds, flg, ignored = 0; - - status = UART_GET_RSR(port); - while (UART_RX_DATA(status)) { - /* - * We need to read rds before reading the - * character from the fifo - */ - rds = UART_GET_RDS(port); - ch = UART_GET_CHAR(port); - port->icount.rx++; - - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - goto ignore_char; - - flg = TTY_NORMAL; - - /* - * Note that the error handling code is - * out of the main execution path - */ - if (rds & (UART_RDS_BI_MSK |UART_RDS_FE_MSK| - UART_RDS_PE_MSK |UART_RDS_PE_MSK)) - goto handle_error; - if (uart_handle_sysrq_char(port, ch, regs)) - goto ignore_char; - - error_return: - tty_insert_flip_char(tty, ch, flg); - - ignore_char: - status = UART_GET_RSR(port); - } - out: - tty_flip_buffer_push(tty); - return; - - handle_error: - if (rds & UART_RDS_BI_MSK) { - status &= ~(UART_RDS_FE_MSK | UART_RDS_PE_MSK); - port->icount.brk++; - if (uart_handle_break(port)) - goto ignore_char; - } else if (rds & UART_RDS_PE_MSK) - port->icount.parity++; - else if (rds & UART_RDS_FE_MSK) - port->icount.frame++; - if (rds & UART_RDS_OE_MSK) - port->icount.overrun++; - - if (rds & port->ignore_status_mask) { - if (++ignored > 100) - goto out; - goto ignore_char; - } - rds &= port->read_status_mask; - - if (rds & UART_RDS_BI_MSK) - flg = TTY_BREAK; - else if (rds & UART_RDS_PE_MSK) - flg = TTY_PARITY; - else if (rds & UART_RDS_FE_MSK) - flg = TTY_FRAME; - - if (rds & UART_RDS_OE_MSK) { - /* - * CHECK: does overrun affect the current character? - * ASSUMPTION: it does not. - */ - tty_insert_flip_char(tty, ch, flg); - ch = 0; - flg = TTY_OVERRUN; - } -#ifdef SUPPORT_SYSRQ - port->sysrq = 0; -#endif - goto error_return; -} - -static void uart00_tx_chars(struct uart_port *port) -{ - struct circ_buf *xmit = &port->info->xmit; - int count; - - if (port->x_char) { - while ((UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK) == 15) - barrier(); - UART_PUT_CHAR(port, port->x_char); - port->icount.tx++; - port->x_char = 0; - return; - } - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - uart00_stop_tx(port); - return; - } - - count = port->fifosize >> 1; - do { - while ((UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK) == 15) - barrier(); - UART_PUT_CHAR(port, xmit->buf[xmit->tail]); - xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); - port->icount.tx++; - if (uart_circ_empty(xmit)) - break; - } while (--count > 0); - - if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) - uart_write_wakeup(port); - - if (uart_circ_empty(xmit)) - uart00_stop_tx(port); -} - -static void uart00_start_tx(struct uart_port *port) -{ - UART_PUT_IES(port, UART_IES_TIE_MSK); - uart00_tx_chars(port); -} - -static void uart00_modem_status(struct uart_port *port) -{ - unsigned int status; - - status = UART_GET_MSR(port); - - if (!(status & (UART_MSR_DCTS_MSK | UART_MSR_DDSR_MSK | - UART_MSR_TERI_MSK | UART_MSR_DDCD_MSK))) - return; - - if (status & UART_MSR_DDCD_MSK) - uart_handle_dcd_change(port, status & UART_MSR_DCD_MSK); - - if (status & UART_MSR_DDSR_MSK) - port->icount.dsr++; - - if (status & UART_MSR_DCTS_MSK) - uart_handle_cts_change(port, status & UART_MSR_CTS_MSK); - - wake_up_interruptible(&port->info->delta_msr_wait); -} - -static irqreturn_t uart00_int(int irq, void *dev_id, struct pt_regs *regs) -{ - struct uart_port *port = dev_id; - unsigned int status, pass_counter = 0; - - status = UART_GET_INT_STATUS(port); - do { - if (status & UART_ISR_RI_MSK) - uart00_rx_chars(port, regs); - if (status & UART_ISR_MI_MSK) - uart00_modem_status(port); - if (status & (UART_ISR_TI_MSK | UART_ISR_TII_MSK)) - uart00_tx_chars(port); - if (pass_counter++ > UART00_ISR_PASS_LIMIT) - break; - - status = UART_GET_INT_STATUS(port); - } while (status); - - return IRQ_HANDLED; -} - -static unsigned int uart00_tx_empty(struct uart_port *port) -{ - return UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK? 0 : TIOCSER_TEMT; -} - -static unsigned int uart00_get_mctrl(struct uart_port *port) -{ - unsigned int result = 0; - unsigned int status; - - status = UART_GET_MSR(port); - if (status & UART_MSR_DCD_MSK) - result |= TIOCM_CAR; - if (status & UART_MSR_DSR_MSK) - result |= TIOCM_DSR; - if (status & UART_MSR_CTS_MSK) - result |= TIOCM_CTS; - if (status & UART_MSR_RI_MSK) - result |= TIOCM_RI; - - return result; -} - -static void uart00_set_mctrl_null(struct uart_port *port, unsigned int mctrl) -{ -} - -static void uart00_break_ctl(struct uart_port *port, int break_state) -{ - unsigned long flags; - unsigned int mcr; - - spin_lock_irqsave(&port->lock, flags); - mcr = UART_GET_MCR(port); - if (break_state == -1) - mcr |= UART_MCR_BR_MSK; - else - mcr &= ~UART_MCR_BR_MSK; - UART_PUT_MCR(port, mcr); - spin_unlock_irqrestore(&port->lock, flags); -} - -static void -uart00_set_termios(struct uart_port *port, struct termios *termios, - struct termios *old) -{ - unsigned int uart_mc, old_ies, baud, quot; - unsigned long flags; - - /* - * We don't support CREAD (yet) - */ - termios->c_cflag |= CREAD; - - /* - * 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); - - /* byte size and parity */ - switch (termios->c_cflag & CSIZE) { - case CS5: - uart_mc = UART_MC_CLS_CHARLEN_5; - break; - case CS6: - uart_mc = UART_MC_CLS_CHARLEN_6; - break; - case CS7: - uart_mc = UART_MC_CLS_CHARLEN_7; - break; - default: // CS8 - uart_mc = UART_MC_CLS_CHARLEN_8; - break; - } - if (termios->c_cflag & CSTOPB) - uart_mc|= UART_MC_ST_TWO; - if (termios->c_cflag & PARENB) { - uart_mc |= UART_MC_PE_MSK; - if (!(termios->c_cflag & PARODD)) - uart_mc |= UART_MC_EP_MSK; - } - - spin_lock_irqsave(&port->lock, flags); - - /* - * Update the per-port timeout. - */ - uart_update_timeout(port, termios->c_cflag, baud); - - port->read_status_mask = UART_RDS_OE_MSK; - if (termios->c_iflag & INPCK) - port->read_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK; - if (termios->c_iflag & (BRKINT | PARMRK)) - port->read_status_mask |= UART_RDS_BI_MSK; - - /* - * Characters to ignore - */ - port->ignore_status_mask = 0; - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK; - if (termios->c_iflag & IGNBRK) { - port->ignore_status_mask |= UART_RDS_BI_MSK; - /* - * If we're ignoring parity and break indicators, - * ignore overruns to (for real raw support). - */ - if (termios->c_iflag & IGNPAR) - port->ignore_status_mask |= UART_RDS_OE_MSK; - } - - /* first, disable everything */ - old_ies = UART_GET_IES(port); - - if (UART_ENABLE_MS(port, termios->c_cflag)) - old_ies |= UART_IES_ME_MSK; - - /* Set baud rate */ - UART_PUT_DIV_LO(port, (quot & 0xff)); - UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8)); - - UART_PUT_MC(port, uart_mc); - UART_PUT_IES(port, old_ies); - - spin_unlock_irqrestore(&port->lock, flags); -} - -static int uart00_startup(struct uart_port *port) -{ - int result; - - /* - * Allocate the IRQ - */ - result = request_irq(port->irq, uart00_int, 0, "uart00", port); - if (result) { - printk(KERN_ERR "Request of irq %d failed\n", port->irq); - return result; - } - - /* - * Finally, enable interrupts. Use the TII interrupt to minimise - * the number of interrupts generated. If higher performance is - * needed, consider using the TI interrupt with a suitable FIFO - * threshold - */ - UART_PUT_IES(port, UART_IES_RE_MSK | UART_IES_TIE_MSK); - - return 0; -} - -static void uart00_shutdown(struct uart_port *port) -{ - /* - * disable all interrupts, disable the port - */ - UART_PUT_IEC(port, 0xff); - - /* disable break condition and fifos */ - UART_PUT_MCR(port, UART_GET_MCR(port) &~UART_MCR_BR_MSK); - - /* - * Free the interrupt - */ - free_irq(port->irq, port); -} - -static const char *uart00_type(struct uart_port *port) -{ - return port->type == PORT_UART00 ? "Altera UART00" : NULL; -} - -/* - * Release the memory region(s) being used by 'port' - */ -static void uart00_release_port(struct uart_port *port) -{ - release_mem_region(port->mapbase, UART_PORT_SIZE); - -#ifdef CONFIG_ARCH_CAMELOT - if (port->membase != (void*)IO_ADDRESS(EXC_UART00_BASE)) { - iounmap(port->membase); - } -#endif -} - -/* - * Request the memory region(s) being used by 'port' - */ -static int uart00_request_port(struct uart_port *port) -{ - return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_uart00") - != NULL ? 0 : -EBUSY; -} - -/* - * Configure/autoconfigure the port. - */ -static void uart00_config_port(struct uart_port *port, int flags) -{ - - /* - * Map the io memory if this is a soft uart - */ - if (!port->membase) - port->membase = ioremap_nocache(port->mapbase,SZ_4K); - - if (!port->membase) - printk(KERN_ERR "serial00: cannot map io memory\n"); - else - port->type = PORT_UART00; - -} - -/* - * verify the new serial_struct (for TIOCSSERIAL). - */ -static int uart00_verify_port(struct uart_port *port, struct serial_struct *ser) -{ - int ret = 0; - if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00) - ret = -EINVAL; - if (ser->irq < 0 || ser->irq >= NR_IRQS) - ret = -EINVAL; - if (ser->baud_base < 9600) - ret = -EINVAL; - return ret; -} - -static struct uart_ops uart00_pops = { - .tx_empty = uart00_tx_empty, - .set_mctrl = uart00_set_mctrl_null, - .get_mctrl = uart00_get_mctrl, - .stop_tx = uart00_stop_tx, - .start_tx = uart00_start_tx, - .stop_rx = uart00_stop_rx, - .enable_ms = uart00_enable_ms, - .break_ctl = uart00_break_ctl, - .startup = uart00_startup, - .shutdown = uart00_shutdown, - .set_termios = uart00_set_termios, - .type = uart00_type, - .release_port = uart00_release_port, - .request_port = uart00_request_port, - .config_port = uart00_config_port, - .verify_port = uart00_verify_port, -}; - - -#ifdef CONFIG_ARCH_CAMELOT -static struct uart_port epxa10db_port = { - .membase = (void*)IO_ADDRESS(EXC_UART00_BASE), - .mapbase = EXC_UART00_BASE, - .iotype = SERIAL_IO_MEM, - .irq = IRQ_UART, - .uartclk = EXC_AHB2_CLK_FREQUENCY, - .fifosize = 16, - .ops = &uart00_pops, - .flags = ASYNC_BOOT_AUTOCONF, -}; -#endif - - -#ifdef CONFIG_SERIAL_UART00_CONSOLE -static void uart00_console_write(struct console *co, const char *s, unsigned count) -{ -#ifdef CONFIG_ARCH_CAMELOT - struct uart_port *port = &epxa10db_port; - unsigned int status, old_ies; - int i; - - /* - * First save the CR then disable the interrupts - */ - old_ies = UART_GET_IES(port); - UART_PUT_IEC(port,0xff); - - /* - * Now, do each character - */ - for (i = 0; i < count; i++) { - do { - status = UART_GET_TSR(port); - } while (!UART_TX_READY(status)); - UART_PUT_CHAR(port, s[i]); - if (s[i] == '\n') { - do { - status = UART_GET_TSR(port); - } while (!UART_TX_READY(status)); - UART_PUT_CHAR(port, '\r'); - } - } - - /* - * Finally, wait for transmitter to become empty - * and restore the IES - */ - do { - status = UART_GET_TSR(port); - } while (status & UART_TSR_TX_LEVEL_MSK); - UART_PUT_IES(port, old_ies); -#endif -} - -static void __init -uart00_console_get_options(struct uart_port *port, int *baud, - int *parity, int *bits) -{ - unsigned int uart_mc, quot; - - uart_mc = UART_GET_MC(port); - - *parity = 'n'; - if (uart_mc & UART_MC_PE_MSK) { - if (uart_mc & UART_MC_EP_MSK) - *parity = 'e'; - else - *parity = 'o'; - } - - switch (uart_mc & UART_MC_CLS_MSK) { - case UART_MC_CLS_CHARLEN_5: - *bits = 5; - break; - case UART_MC_CLS_CHARLEN_6: - *bits = 6; - break; - case UART_MC_CLS_CHARLEN_7: - *bits = 7; - break; - case UART_MC_CLS_CHARLEN_8: - *bits = 8; - break; - } - quot = UART_GET_DIV_LO(port) | (UART_GET_DIV_HI(port) << 8); - *baud = port->uartclk / (16 *quot ); -} - -static int __init uart00_console_setup(struct console *co, char *options) -{ - struct uart_port *port; - int baud = 115200; - int bits = 8; - int parity = 'n'; - int flow = 'n'; - -#ifdef CONFIG_ARCH_CAMELOT - port = &epxa10db_port; ; -#else - return -ENODEV; -#endif - if (options) - uart_parse_options(options, &baud, &parity, &bits, &flow); - else - uart00_console_get_options(port, &baud, &parity, &bits); - - return uart_set_options(port, co, baud, parity, bits, flow); -} - -extern struct uart_driver uart00_reg; -static struct console uart00_console = { - .name = SERIAL_UART00_NAME, - .write = uart00_console_write, - .device = uart_console_device, - .setup = uart00_console_setup, - .flags = CON_PRINTBUFFER, - .index = 0, - .data = &uart00_reg, -}; - -static int __init uart00_console_init(void) -{ - register_console(&uart00_console); - return 0; -} -console_initcall(uart00_console_init); - -#define UART00_CONSOLE &uart00_console -#else -#define UART00_CONSOLE NULL -#endif - -static struct uart_driver uart00_reg = { - .owner = NULL, - .driver_name = SERIAL_UART00_NAME, - .dev_name = SERIAL_UART00_NAME, - .major = SERIAL_UART00_MAJOR, - .minor = SERIAL_UART00_MINOR, - .nr = UART_NR, - .cons = UART00_CONSOLE, -}; - -struct dev_port_entry{ - unsigned int base_addr; - struct uart_port *port; -}; - -#ifdef CONFIG_PLD_HOTSWAP - -static struct dev_port_entry dev_port_map[UART_NR]; - -/* - * Keep a mapping of dev_info addresses -> port lines to use when - * removing ports dev==NULL indicates unused entry - */ - -struct uart00_ps_data{ - unsigned int clk; - unsigned int fifosize; -}; - -int uart00_add_device(struct pldhs_dev_info* dev_info, void* dev_ps_data) -{ - struct uart00_ps_data* dev_ps=dev_ps_data; - struct uart_port * port; - int i,result; - - i=0; - while(dev_port_map[i].port) - i++; - - if(i==UART_NR){ - printk(KERN_WARNING "uart00: Maximum number of ports reached\n"); - return 0; - } - - port=kmalloc(sizeof(struct uart_port),GFP_KERNEL); - if(!port) - return -ENOMEM; - - printk("clk=%d fifo=%d\n",dev_ps->clk,dev_ps->fifosize); - port->membase=0; - port->mapbase=dev_info->base_addr; - port->iotype=SERIAL_IO_MEM; - port->irq=dev_info->irq; - port->uartclk=dev_ps->clk; - port->fifosize=dev_ps->fifosize; - port->ops=&uart00_pops; - port->line=i; - port->flags=ASYNC_BOOT_AUTOCONF; - - result=uart_add_one_port(&uart00_reg, port); - if(result){ - printk("uart_add_one_port returned %d\n",result); - return result; - } - dev_port_map[i].base_addr=dev_info->base_addr; - dev_port_map[i].port=port; - printk("uart00: added device at %x as ttyUA%d\n",dev_port_map[i].base_addr,i); - return 0; - -} - -int uart00_remove_devices(void) -{ - int i,result; - - - result=0; - for(i=1;id_inode->i_sem); - list_for_each_entry(dev, &bus->d_subdirs, d_u.d_child) + list_for_each_entry(dev, &bus->d_subdirs, d_child) if (dev->d_inode) update_dev(dev); @@ -203,7 +203,7 @@ static void update_sb(struct super_block *sb) down(&root->d_inode->i_sem); - list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) { + list_for_each_entry(bus, &root->d_subdirs, d_child) { if (bus->d_inode) { switch (S_IFMT & bus->d_inode->i_mode) { case S_IFDIR: @@ -319,7 +319,7 @@ static int usbfs_empty (struct dentry *dentry) spin_lock(&dcache_lock); list_for_each(list, &dentry->d_subdirs) { - struct dentry *de = list_entry(list, struct dentry, d_u.d_child); + struct dentry *de = list_entry(list, struct dentry, d_child); if (usbfs_positive(de)) { spin_unlock(&dcache_lock); return 0; diff --git a/trunk/drivers/usb/host/ohci-au1xxx.c b/trunk/drivers/usb/host/ohci-au1xxx.c index 77cd6ac07e3c..d9cf3b327d96 100644 --- a/trunk/drivers/usb/host/ohci-au1xxx.c +++ b/trunk/drivers/usb/host/ohci-au1xxx.c @@ -19,7 +19,6 @@ */ #include -#include #include diff --git a/trunk/drivers/usb/host/ohci-lh7a404.c b/trunk/drivers/usb/host/ohci-lh7a404.c index 0020ed7a39d0..3959ccc88332 100644 --- a/trunk/drivers/usb/host/ohci-lh7a404.c +++ b/trunk/drivers/usb/host/ohci-lh7a404.c @@ -17,7 +17,6 @@ */ #include -#include #include diff --git a/trunk/drivers/usb/host/ohci-ppc-soc.c b/trunk/drivers/usb/host/ohci-ppc-soc.c index b2a8dfa48870..2ec6a78bd65e 100644 --- a/trunk/drivers/usb/host/ohci-ppc-soc.c +++ b/trunk/drivers/usb/host/ohci-ppc-soc.c @@ -15,7 +15,6 @@ */ #include -#include /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ diff --git a/trunk/drivers/usb/media/dsbr100.c b/trunk/drivers/usb/media/dsbr100.c index 25646804d5be..6a5700e9d428 100644 --- a/trunk/drivers/usb/media/dsbr100.c +++ b/trunk/drivers/usb/media/dsbr100.c @@ -127,7 +127,6 @@ static struct file_operations usb_dsbr100_fops = { .open = usb_dsbr100_open, .release = usb_dsbr100_close, .ioctl = usb_dsbr100_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/usb/media/ov511.c b/trunk/drivers/usb/media/ov511.c index 8af665bbe330..3a0e8ce67ebe 100644 --- a/trunk/drivers/usb/media/ov511.c +++ b/trunk/drivers/usb/media/ov511.c @@ -4774,7 +4774,6 @@ static struct file_operations ov511_fops = { .read = ov51x_v4l1_read, .mmap = ov51x_v4l1_mmap, .ioctl = ov51x_v4l1_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/usb/media/pwc/pwc-if.c b/trunk/drivers/usb/media/pwc/pwc-if.c index 4f9b0dc6fd7b..09ca6128ac20 100644 --- a/trunk/drivers/usb/media/pwc/pwc-if.c +++ b/trunk/drivers/usb/media/pwc/pwc-if.c @@ -154,7 +154,6 @@ static struct file_operations pwc_fops = { .poll = pwc_video_poll, .mmap = pwc_video_mmap, .ioctl = pwc_video_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; static struct video_device pwc_template = { diff --git a/trunk/drivers/usb/media/se401.c b/trunk/drivers/usb/media/se401.c index 2ba562285fda..b2ae29af5940 100644 --- a/trunk/drivers/usb/media/se401.c +++ b/trunk/drivers/usb/media/se401.c @@ -1193,7 +1193,6 @@ static struct file_operations se401_fops = { .read = se401_read, .mmap = se401_mmap, .ioctl = se401_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; static struct video_device se401_template = { diff --git a/trunk/drivers/usb/media/stv680.c b/trunk/drivers/usb/media/stv680.c index b497a6a0a206..774038b352cd 100644 --- a/trunk/drivers/usb/media/stv680.c +++ b/trunk/drivers/usb/media/stv680.c @@ -1343,7 +1343,6 @@ static struct file_operations stv680_fops = { .read = stv680_read, .mmap = stv680_mmap, .ioctl = stv680_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; static struct video_device stv680_template = { diff --git a/trunk/drivers/usb/media/usbvideo.c b/trunk/drivers/usb/media/usbvideo.c index 63a72e550a1b..4bd113325ef9 100644 --- a/trunk/drivers/usb/media/usbvideo.c +++ b/trunk/drivers/usb/media/usbvideo.c @@ -953,7 +953,6 @@ static struct file_operations usbvideo_fops = { .read = usbvideo_v4l_read, .mmap = usbvideo_v4l_mmap, .ioctl = usbvideo_v4l_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; static const struct video_device usbvideo_template = { diff --git a/trunk/drivers/usb/media/vicam.c b/trunk/drivers/usb/media/vicam.c index 5df144073871..1c73155c8d77 100644 --- a/trunk/drivers/usb/media/vicam.c +++ b/trunk/drivers/usb/media/vicam.c @@ -1236,7 +1236,6 @@ static struct file_operations vicam_fops = { .read = vicam_read, .mmap = vicam_mmap, .ioctl = vicam_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; diff --git a/trunk/drivers/usb/media/w9968cf.c b/trunk/drivers/usb/media/w9968cf.c index bff9434c8e55..3605a6f3067b 100644 --- a/trunk/drivers/usb/media/w9968cf.c +++ b/trunk/drivers/usb/media/w9968cf.c @@ -3490,7 +3490,6 @@ static struct file_operations w9968cf_fops = { .release = w9968cf_release, .read = w9968cf_read, .ioctl = w9968cf_ioctl, - .compat_ioctl = v4l_compat_ioctl32, .mmap = w9968cf_mmap, .llseek = no_llseek, }; diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index 3f04427c9026..cc8e3bf5001b 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -1151,7 +1151,7 @@ config FB_VOODOO1 config FB_CYBLA tristate "Cyberblade/i1 support" - depends on FB && PCI && X86_32 && !64BIT + depends on FB && PCI select FB_CFB_IMAGEBLIT select VIDEO_SELECT ---help--- diff --git a/trunk/drivers/video/console/Kconfig b/trunk/drivers/video/console/Kconfig index 6ee449858a5c..a5d09e159cd1 100644 --- a/trunk/drivers/video/console/Kconfig +++ b/trunk/drivers/video/console/Kconfig @@ -6,7 +6,7 @@ menu "Console display driver support" config VGA_CONSOLE bool "VGA text console" if EMBEDDED || !X86 - depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !ARCH_VERSATILE + depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !ARCH_VERSATILE default y help Saying Y here will allow you to use Linux in text mode through a diff --git a/trunk/drivers/video/console/vgacon.c b/trunk/drivers/video/console/vgacon.c index 12d9329d1408..167de397e4b4 100644 --- a/trunk/drivers/video/console/vgacon.c +++ b/trunk/drivers/video/console/vgacon.c @@ -56,8 +56,6 @@ static DEFINE_SPINLOCK(vga_lock); static int cursor_size_lastfrom; static int cursor_size_lastto; -static u32 vgacon_xres; -static u32 vgacon_yres; static struct vgastate state; #define BLANK 0x0020 @@ -71,7 +69,7 @@ static struct vgastate state; * appear. */ #undef TRIDENT_GLITCH -#define VGA_FONTWIDTH 8 /* VGA does not support fontwidths != 8 */ + /* * Interface used by the world */ @@ -327,10 +325,6 @@ static const char __init *vgacon_startup(void) vga_scan_lines = vga_video_font_height * vga_video_num_lines; } - - vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH; - vgacon_yres = vga_scan_lines; - return display_desc; } @@ -509,18 +503,10 @@ static int vgacon_doresize(struct vc_data *c, { unsigned long flags; unsigned int scanlines = height * c->vc_font.height; - u8 scanlines_lo, r7, vsync_end, mode, max_scan; + u8 scanlines_lo, r7, vsync_end, mode; spin_lock_irqsave(&vga_lock, flags); - outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg); - max_scan = inb_p(vga_video_port_val); - - if (max_scan & 0x80) - scanlines <<= 1; - - vgacon_xres = width * VGA_FONTWIDTH; - vgacon_yres = height * c->vc_font.height; outb_p(VGA_CRTC_MODE, vga_video_port_reg); mode = inb_p(vga_video_port_val); @@ -565,10 +551,6 @@ static int vgacon_doresize(struct vc_data *c, static int vgacon_switch(struct vc_data *c) { - int x = c->vc_cols * VGA_FONTWIDTH; - int y = c->vc_rows * c->vc_font.height; - int rows = ORIG_VIDEO_LINES * vga_default_font_height/ - c->vc_font.height; /* * We need to save screen size here as it's the only way * we can spot the screen has been resized and we need to @@ -584,11 +566,10 @@ static int vgacon_switch(struct vc_data *c) scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - - if ((vgacon_xres != x || vgacon_yres != y) && - (!(vga_video_num_columns % 2) && - vga_video_num_columns <= ORIG_VIDEO_COLS && - vga_video_num_lines <= rows)) + if (!(vga_video_num_columns % 2) && + vga_video_num_columns <= ORIG_VIDEO_COLS && + vga_video_num_lines <= (ORIG_VIDEO_LINES * + vga_default_font_height) / c->vc_font.height) vgacon_doresize(c, c->vc_cols, c->vc_rows); } @@ -1012,8 +993,7 @@ static int vgacon_font_set(struct vc_data *c, struct console_font *font, unsigne if (vga_video_type < VIDEO_TYPE_EGAM) return -EINVAL; - if (font->width != VGA_FONTWIDTH || - (charcount != 256 && charcount != 512)) + if (font->width != 8 || (charcount != 256 && charcount != 512)) return -EINVAL; rc = vgacon_do_font_op(&state, font->data, 1, charcount == 512); @@ -1030,7 +1010,7 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font) if (vga_video_type < VIDEO_TYPE_EGAM) return -EINVAL; - font->width = VGA_FONTWIDTH; + font->width = 8; font->height = c->vc_font.height; font->charcount = vga_512_chars ? 512 : 256; if (!font->data) diff --git a/trunk/drivers/video/controlfb.c b/trunk/drivers/video/controlfb.c index 03798e9c882d..403d17377f8d 100644 --- a/trunk/drivers/video/controlfb.c +++ b/trunk/drivers/video/controlfb.c @@ -133,6 +133,12 @@ static int controlfb_mmap(struct fb_info *info, struct file *file, static int controlfb_set_par (struct fb_info *info); static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info); +/* + * inititialization + */ +int control_init(void); +void control_setup(char *); + /******************** Prototypes for internal functions **********************/ static void set_control_clock(unsigned char *params); @@ -544,46 +550,9 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro /* - * Parse user speficied options (`video=controlfb:') + * Called from fbmem.c for probing & initializing */ -static void __init control_setup(char *options) -{ - char *this_opt; - - if (!options || !*options) - return; - - while ((this_opt = strsep(&options, ",")) != NULL) { - if (!strncmp(this_opt, "vmode:", 6)) { - int vmode = simple_strtoul(this_opt+6, NULL, 0); - if (vmode > 0 && vmode <= VMODE_MAX && - control_mac_modes[vmode - 1].m[1] >= 0) - default_vmode = vmode; - } else if (!strncmp(this_opt, "cmode:", 6)) { - int depth = simple_strtoul(this_opt+6, NULL, 0); - switch (depth) { - case CMODE_8: - case CMODE_16: - case CMODE_32: - default_cmode = depth; - break; - case 8: - default_cmode = CMODE_8; - break; - case 15: - case 16: - default_cmode = CMODE_16; - break; - case 24: - case 32: - default_cmode = CMODE_32; - break; - } - } - } -} - -static int __init control_init(void) +int __init control_init(void) { struct device_node *dp; char *option = NULL; @@ -682,16 +651,15 @@ static void __init find_vram_size(struct fb_info_control *p) static int __init control_of_init(struct device_node *dp) { struct fb_info_control *p; - struct resource fb_res, reg_res; + unsigned long addr; + int i; if (control_fb) { printk(KERN_ERR "controlfb: only one control is supported\n"); return -ENXIO; } - - if (of_pci_address_to_resource(dp, 2, &fb_res) || - of_pci_address_to_resource(dp, 1, ®_res)) { - printk(KERN_ERR "can't get 2 addresses for control\n"); + if(dp->n_addrs != 2) { + printk(KERN_ERR "expecting 2 address for control (got %d)", dp->n_addrs); return -ENXIO; } p = kmalloc(sizeof(*p), GFP_KERNEL); @@ -701,12 +669,18 @@ static int __init control_of_init(struct device_node *dp) memset(p, 0, sizeof(*p)); /* Map in frame buffer and registers */ - p->fb_orig_base = fb_res.start; - p->fb_orig_size = fb_res.end - fb_res.start + 1; - /* use the big-endian aperture (??) */ - p->frame_buffer_phys = fb_res.start + 0x800000; - p->control_regs_phys = reg_res.start; - p->control_regs_size = reg_res.end - reg_res.start + 1; + for (i = 0; i < dp->n_addrs; ++i) { + addr = dp->addrs[i].address; + if (dp->addrs[i].size >= 0x800000) { + p->fb_orig_base = addr; + p->fb_orig_size = dp->addrs[i].size; + /* use the big-endian aperture (??) */ + p->frame_buffer_phys = addr + 0x800000; + } else { + p->control_regs_phys = addr; + p->control_regs_size = dp->addrs[i].size; + } + } if (!p->fb_orig_base || !request_mem_region(p->fb_orig_base,p->fb_orig_size,"controlfb")) { @@ -1085,3 +1059,43 @@ static void control_cleanup(void) } +/* + * Parse user speficied options (`video=controlfb:') + */ +void __init control_setup(char *options) +{ + char *this_opt; + + if (!options || !*options) + return; + + while ((this_opt = strsep(&options, ",")) != NULL) { + if (!strncmp(this_opt, "vmode:", 6)) { + int vmode = simple_strtoul(this_opt+6, NULL, 0); + if (vmode > 0 && vmode <= VMODE_MAX && + control_mac_modes[vmode - 1].m[1] >= 0) + default_vmode = vmode; + } else if (!strncmp(this_opt, "cmode:", 6)) { + int depth = simple_strtoul(this_opt+6, NULL, 0); + switch (depth) { + case CMODE_8: + case CMODE_16: + case CMODE_32: + default_cmode = depth; + break; + case 8: + default_cmode = CMODE_8; + break; + case 15: + case 16: + default_cmode = CMODE_16; + break; + case 24: + case 32: + default_cmode = CMODE_32; + break; + } + } + } +} + diff --git a/trunk/drivers/video/cyblafb.c b/trunk/drivers/video/cyblafb.c index e9f5dee67e3c..03fbe83d71a8 100644 --- a/trunk/drivers/video/cyblafb.c +++ b/trunk/drivers/video/cyblafb.c @@ -7,12 +7,11 @@ * tridentfb.c by Jani Monoses * see files above for further credits * + * TODO: + * */ #define CYBLAFB_DEBUG 0 -#define CYBLAFB_KD_GRAPHICS_QUIRK 1 - -#define CYBLAFB_PIXMAPSIZE 8192 #include #include @@ -23,7 +22,7 @@ #include #include