diff --git a/[refs] b/[refs] index a7d6256b210d..1077b7daf59a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 47c2a3aa4475d27073dd3c7e183fcc13f495c8f5 +refs/heads/master: 740e518efcd84ce5e53ecf3c4c9be08cf8f3747c diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile index 66e1cf733571..5a2882d275ba 100644 --- a/trunk/Documentation/DocBook/Makefile +++ b/trunk/Documentation/DocBook/Makefile @@ -10,8 +10,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ procfs-guide.xml writing_usb_driver.xml \ kernel-api.xml journal-api.xml lsm.xml usb.xml \ - gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ - genericirq.xml + gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml ### # The build process is as follows (targets): diff --git a/trunk/Documentation/DocBook/genericirq.tmpl b/trunk/Documentation/DocBook/genericirq.tmpl deleted file mode 100644 index 0f4a4b6321e4..000000000000 --- a/trunk/Documentation/DocBook/genericirq.tmpl +++ /dev/null @@ -1,474 +0,0 @@ - - - - - - Linux generic IRQ handling - - - - Thomas - Gleixner - -
- tglx@linutronix.de -
-
-
- - Ingo - Molnar - -
- mingo@elte.hu -
-
-
-
- - - 2005-2006 - Thomas Gleixner - - - 2005-2006 - Ingo Molnar - - - - - This documentation is free software; you can redistribute - it and/or modify it under the terms of the GNU General Public - License version 2 as published by the Free Software Foundation. - - - - This program is distributed in the hope that it will be - useful, but WITHOUT ANY WARRANTY; without even the implied - warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, - MA 02111-1307 USA - - - - For more details see the file COPYING in the source - distribution of Linux. - - -
- - - - - Introduction - - The generic interrupt handling layer is designed to provide a - complete abstraction of interrupt handling for device drivers. - It is able to handle all the different types of interrupt controller - hardware. Device drivers use generic API functions to request, enable, - disable and free interrupts. The drivers do not have to know anything - about interrupt hardware details, so they can be used on different - platforms without code changes. - - - This documentation is provided to developers who want to implement - an interrupt subsystem based for their architecture, with the help - of the generic IRQ handling layer. - - - - - Rationale - - The original implementation of interrupt handling in Linux is using - the __do_IRQ() super-handler, which is able to deal with every - type of interrupt logic. - - - Originally, Russell King identified different types of handlers to - build a quite universal set for the ARM interrupt handler - implementation in Linux 2.5/2.6. He distinguished between: - - Level type - Edge type - Simple type - - In the SMP world of the __do_IRQ() super-handler another type - was identified: - - Per CPU type - - - - This split implementation of highlevel IRQ handlers allows us to - optimize the flow of the interrupt handling for each specific - interrupt type. This reduces complexity in that particular codepath - and allows the optimized handling of a given type. - - - The original general IRQ implementation used hw_interrupt_type - structures and their ->ack(), ->end() [etc.] callbacks to - differentiate the flow control in the super-handler. This leads to - a mix of flow logic and lowlevel hardware logic, and it also leads - to unnecessary code duplication: for example in i386, there is a - ioapic_level_irq and a ioapic_edge_irq irq-type which share many - of the lowlevel details but have different flow handling. - - - A more natural abstraction is the clean separation of the - 'irq flow' and the 'chip details'. - - - Analysing a couple of architecture's IRQ subsystem implementations - reveals that most of them can use a generic set of 'irq flow' - methods and only need to add the chip level specific code. - The separation is also valuable for (sub)architectures - which need specific quirks in the irq flow itself but not in the - chip-details - and thus provides a more transparent IRQ subsystem - design. - - - Each interrupt descriptor is assigned its own highlevel flow - handler, which is normally one of the generic - implementations. (This highlevel flow handler implementation also - makes it simple to provide demultiplexing handlers which can be - found in embedded platforms on various architectures.) - - - The separation makes the generic interrupt handling layer more - flexible and extensible. For example, an (sub)architecture can - use a generic irq-flow implementation for 'level type' interrupts - and add a (sub)architecture specific 'edge type' implementation. - - - To make the transition to the new model easier and prevent the - breakage of existing implementations, the __do_IRQ() super-handler - is still available. This leads to a kind of duality for the time - being. Over time the new model should be used in more and more - architectures, as it enables smaller and cleaner IRQ subsystems. - - - - Known Bugs And Assumptions - - None (knock on wood). - - - - - Abstraction layers - - There are three main levels of abstraction in the interrupt code: - - Highlevel driver API - Highlevel IRQ flow handlers - Chiplevel hardware encapsulation - - - - Interrupt control flow - - Each interrupt is described by an interrupt descriptor structure - irq_desc. The interrupt is referenced by an 'unsigned int' numeric - value which selects the corresponding interrupt decription structure - in the descriptor structures array. - The descriptor structure contains status information and pointers - to the interrupt flow method and the interrupt chip structure - which are assigned to this interrupt. - - - Whenever an interrupt triggers, the lowlevel arch code calls into - the generic interrupt code by calling desc->handle_irq(). - This highlevel IRQ handling function only uses desc->chip primitives - referenced by the assigned chip descriptor structure. - - - - Highlevel Driver API - - The highlevel Driver API consists of following functions: - - request_irq() - free_irq() - disable_irq() - enable_irq() - disable_irq_nosync() (SMP only) - synchronize_irq() (SMP only) - set_irq_type() - set_irq_wake() - set_irq_data() - set_irq_chip() - set_irq_chip_data() - - See the autogenerated function documentation for details. - - - - Highlevel IRQ flow handlers - - The generic layer provides a set of pre-defined irq-flow methods: - - handle_level_irq - handle_edge_irq - handle_simple_irq - handle_percpu_irq - - The interrupt flow handlers (either predefined or architecture - specific) are assigned to specific interrupts by the architecture - either during bootup or during device initialization. - - - Default flow implementations - - Helper functions - - The helper functions call the chip primitives and - are used by the default flow implementations. - The following helper functions are implemented (simplified excerpt): - -default_enable(irq) -{ - desc->chip->unmask(irq); -} - -default_disable(irq) -{ - if (!delay_disable(irq)) - desc->chip->mask(irq); -} - -default_ack(irq) -{ - chip->ack(irq); -} - -default_mask_ack(irq) -{ - if (chip->mask_ack) { - chip->mask_ack(irq); - } else { - chip->mask(irq); - chip->ack(irq); - } -} - -noop(irq) -{ -} - - - - - - - Default flow handler implementations - - Default Level IRQ flow handler - - handle_level_irq provides a generic implementation - for level-triggered interrupts. - - - The following control flow is implemented (simplified excerpt): - -desc->chip->start(); -handle_IRQ_event(desc->action); -desc->chip->end(); - - - - - Default Edge IRQ flow handler - - handle_edge_irq provides a generic implementation - for edge-triggered interrupts. - - - The following control flow is implemented (simplified excerpt): - -if (desc->status & running) { - desc->chip->hold(); - desc->status |= pending | masked; - return; -} -desc->chip->start(); -desc->status |= running; -do { - if (desc->status & masked) - desc->chip->enable(); - desc-status &= ~pending; - handle_IRQ_event(desc->action); -} while (status & pending); -desc-status &= ~running; -desc->chip->end(); - - - - - Default simple IRQ flow handler - - handle_simple_irq provides a generic implementation - for simple interrupts. - - - Note: The simple flow handler does not call any - handler/chip primitives. - - - The following control flow is implemented (simplified excerpt): - -handle_IRQ_event(desc->action); - - - - - Default per CPU flow handler - - handle_percpu_irq provides a generic implementation - for per CPU interrupts. - - - Per CPU interrupts are only available on SMP and - the handler provides a simplified version without - locking. - - - The following control flow is implemented (simplified excerpt): - -desc->chip->start(); -handle_IRQ_event(desc->action); -desc->chip->end(); - - - - - - Quirks and optimizations - - The generic functions are intended for 'clean' architectures and chips, - which have no platform-specific IRQ handling quirks. If an architecture - needs to implement quirks on the 'flow' level then it can do so by - overriding the highlevel irq-flow handler. - - - - Delayed interrupt disable - - This per interrupt selectable feature, which was introduced by Russell - King in the ARM interrupt implementation, does not mask an interrupt - at the hardware level when disable_irq() is called. The interrupt is - kept enabled and is masked in the flow handler when an interrupt event - happens. This prevents losing edge interrupts on hardware which does - not store an edge interrupt event while the interrupt is disabled at - the hardware level. When an interrupt arrives while the IRQ_DISABLED - flag is set, then the interrupt is masked at the hardware level and - the IRQ_PENDING bit is set. When the interrupt is re-enabled by - enable_irq() the pending bit is checked and if it is set, the - interrupt is resent either via hardware or by a software resend - mechanism. (It's necessary to enable CONFIG_HARDIRQS_SW_RESEND when - you want to use the delayed interrupt disable feature and your - hardware is not capable of retriggering an interrupt.) - The delayed interrupt disable can be runtime enabled, per interrupt, - by setting the IRQ_DELAYED_DISABLE flag in the irq_desc status field. - - - - - Chiplevel hardware encapsulation - - The chip level hardware descriptor structure irq_chip - contains all the direct chip relevant functions, which - can be utilized by the irq flow implementations. - - ack() - mask_ack() - Optional, recommended for performance - mask() - unmask() - retrigger() - Optional - set_type() - Optional - set_wake() - Optional - - These primitives are strictly intended to mean what they say: ack means - ACK, masking means masking of an IRQ line, etc. It is up to the flow - handler(s) to use these basic units of lowlevel functionality. - - - - - - __do_IRQ entry point - - The original implementation __do_IRQ() is an alternative entry - point for all types of interrupts. - - - This handler turned out to be not suitable for all - interrupt hardware and was therefore reimplemented with split - functionality for egde/level/simple/percpu interrupts. This is not - only a functional optimization. It also shortens code paths for - interrupts. - - - To make use of the split implementation, replace the call to - __do_IRQ by a call to desc->chip->handle_irq() and associate - the appropriate handler function to desc->chip->handle_irq(). - In most cases the generic handler implementations should - be sufficient. - - - - - Locking on SMP - - The locking of chip registers is up to the architecture that - defines the chip primitives. There is a chip->lock field that can be used - for serialization, but the generic layer does not touch it. The per-irq - structure is protected via desc->lock, by the generic layer. - - - - Structures - - This chapter contains the autogenerated documentation of the structures which are - used in the generic IRQ layer. - -!Iinclude/linux/irq.h - - - - Public Functions Provided - - This chapter contains the autogenerated documentation of the kernel API functions - which are exported. - -!Ekernel/irq/manage.c -!Ekernel/irq/chip.c - - - - Internal Functions Provided - - This chapter contains the autogenerated documentation of the internal functions. - -!Ikernel/irq/handle.c -!Ikernel/irq/chip.c - - - - Credits - - The following people have contributed to this document: - - Thomas Gleixnertglx@linutronix.de - Ingo Molnarmingo@elte.hu - - - -
diff --git a/trunk/Documentation/IRQ.txt b/trunk/Documentation/IRQ.txt deleted file mode 100644 index 1011e7175021..000000000000 --- a/trunk/Documentation/IRQ.txt +++ /dev/null @@ -1,22 +0,0 @@ -What is an IRQ? - -An IRQ is an interrupt request from a device. -Currently they can come in over a pin, or over a packet. -Several devices may be connected to the same pin thus -sharing an IRQ. - -An IRQ number is a kernel identifier used to talk about a hardware -interrupt source. Typically this is an index into the global irq_desc -array, but except for what linux/interrupt.h implements the details -are architecture specific. - -An IRQ number is an enumeration of the possible interrupt sources on a -machine. Typically what is enumerated is the number of input pins on -all of the interrupt controller in the system. In the case of ISA -what is enumerated are the 16 input pins on the two i8259 interrupt -controllers. - -Architectures can assign additional meaning to the IRQ numbers, and -are encouraged to in the case where there is any manual configuration -of the hardware involved. The ISA IRQs are a classic example of -assigning this kind of additional meaning. diff --git a/trunk/Documentation/RCU/torture.txt b/trunk/Documentation/RCU/torture.txt index a4948591607d..e4c38152f7f7 100644 --- a/trunk/Documentation/RCU/torture.txt +++ b/trunk/Documentation/RCU/torture.txt @@ -7,7 +7,7 @@ The CONFIG_RCU_TORTURE_TEST config option is available for all RCU implementations. It creates an rcutorture kernel module that can be loaded to run a torture test. The test periodically outputs status messages via printk(), which can be examined via the dmesg -command (perhaps grepping for "torture"). The test is started +command (perhaps grepping for "rcutorture"). The test is started when the module is loaded, and stops when the module is unloaded. However, actually setting this config option to "y" results in the system @@ -35,19 +35,6 @@ stat_interval The number of seconds between output of torture be printed -only- when the module is unloaded, and this is the default. -shuffle_interval - The number of seconds to keep the test threads affinitied - to a particular subset of the CPUs. Used in conjunction - with test_no_idle_hz. - -test_no_idle_hz Whether or not to test the ability of RCU to operate in - a kernel that disables the scheduling-clock interrupt to - idle CPUs. Boolean parameter, "1" to test, "0" otherwise. - -torture_type The type of RCU to test: "rcu" for the rcu_read_lock() - API, "rcu_bh" for the rcu_read_lock_bh() API, and "srcu" - for the "srcu_read_lock()" API. - verbose Enable debug printk()s. Default is disabled. @@ -55,14 +42,14 @@ OUTPUT The statistics output is as follows: - rcu-torture: --- Start of test: nreaders=16 stat_interval=0 verbose=0 - rcu-torture: rtc: 0000000000000000 ver: 1916 tfle: 0 rta: 1916 rtaf: 0 rtf: 1915 - rcu-torture: Reader Pipe: 1466408 9747 0 0 0 0 0 0 0 0 0 - rcu-torture: Reader Batch: 1464477 11678 0 0 0 0 0 0 0 0 - rcu-torture: Free-Block Circulation: 1915 1915 1915 1915 1915 1915 1915 1915 1915 1915 0 - rcu-torture: --- End of test + rcutorture: --- Start of test: nreaders=16 stat_interval=0 verbose=0 + rcutorture: rtc: 0000000000000000 ver: 1916 tfle: 0 rta: 1916 rtaf: 0 rtf: 1915 + rcutorture: Reader Pipe: 1466408 9747 0 0 0 0 0 0 0 0 0 + rcutorture: Reader Batch: 1464477 11678 0 0 0 0 0 0 0 0 + rcutorture: Free-Block Circulation: 1915 1915 1915 1915 1915 1915 1915 1915 1915 1915 0 + rcutorture: --- End of test -The command "dmesg | grep torture:" will extract this information on +The command "dmesg | grep rcutorture:" will extract this information on most systems. On more esoteric configurations, it may be necessary to use other commands to access the output of the printk()s used by the RCU torture test. The printk()s use KERN_ALERT, so they should @@ -128,9 +115,8 @@ The following script may be used to torture RCU: modprobe rcutorture sleep 100 rmmod rcutorture - dmesg | grep torture: + dmesg | grep rcutorture: The output can be manually inspected for the error flag of "!!!". One could of course create a more elaborate script that automatically -checked for such errors. The "rmmod" command forces a "SUCCESS" or -"FAILURE" indication to be printk()ed. +checked for such errors. diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 033ac91da07a..027285d0c26c 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -177,16 +177,6 @@ Who: Jean Delvare --------------------------- -What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports - (temporary transition config option provided until then) - The transition config option will also be removed at the same time. -When: before 2.6.19 -Why: Unused symbols are both increasing the size of the kernel binary - and are often a sign of "wrong API" -Who: Arjan van de Ven - ---------------------------- - What: remove EXPORT_SYMBOL(tasklist_lock) When: August 2006 Files: kernel/fork.c diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 0d189c93eeaf..2e352a605fcf 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -1669,10 +1669,6 @@ running once the system is up. usbhid.mousepoll= [USBHID] The interval which mice are to be polled at. - vdso= [IA-32] - vdso=1: enable VDSO (default) - vdso=0: disable VDSO mapping - video= [FB] Frame buffer configuration See Documentation/fb/modedb.txt. diff --git a/trunk/Documentation/keys-request-key.txt b/trunk/Documentation/keys-request-key.txt index c1f64fdf84cb..22488d791168 100644 --- a/trunk/Documentation/keys-request-key.txt +++ b/trunk/Documentation/keys-request-key.txt @@ -3,23 +3,16 @@ =================== The key request service is part of the key retention service (refer to -Documentation/keys.txt). This document explains more fully how the requesting -algorithm works. +Documentation/keys.txt). This document explains more fully how that the +requesting algorithm works. The process starts by either the kernel requesting a service by calling -request_key*(): +request_key(): struct key *request_key(const struct key_type *type, const char *description, const char *callout_string); -or: - - struct key *request_key_with_auxdata(const struct key_type *type, - const char *description, - const char *callout_string, - void *aux); - Or by userspace invoking the request_key system call: key_serial_t request_key(const char *type, @@ -27,26 +20,16 @@ Or by userspace invoking the request_key system call: const char *callout_info, key_serial_t dest_keyring); -The main difference between the access points is that the in-kernel interface -does not need to link the key to a keyring to prevent it from being immediately -destroyed. The kernel interface returns a pointer directly to the key, and -it's up to the caller to destroy the key. - -The request_key_with_auxdata() call is like the in-kernel request_key() call, -except that it permits auxiliary data to be passed to the upcaller (the default -is NULL). This is only useful for those key types that define their own upcall -mechanism rather than using /sbin/request-key. +The main difference between the two access points is that the in-kernel +interface does not need to link the key to a keyring to prevent it from being +immediately destroyed. The kernel interface returns a pointer directly to the +key, and it's up to the caller to destroy the key. The userspace interface links the key to a keyring associated with the process to prevent the key from going away, and returns the serial number of the key to the caller. -The following example assumes that the key types involved don't define their -own upcall mechanisms. If they do, then those should be substituted for the -forking and execution of /sbin/request-key. - - =========== THE PROCESS =========== @@ -57,8 +40,8 @@ A request proceeds in the following manner: interface]. (2) request_key() searches the process's subscribed keyrings to see if there's - a suitable key there. If there is, it returns the key. If there isn't, - and callout_info is not set, an error is returned. Otherwise the process + a suitable key there. If there is, it returns the key. If there isn't, and + callout_info is not set, an error is returned. Otherwise the process proceeds to the next step. (3) request_key() sees that A doesn't have the desired key yet, so it creates @@ -79,7 +62,7 @@ A request proceeds in the following manner: instantiation. (7) 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 + 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. This will permit it to then search the keyrings of process A with the @@ -96,11 +79,10 @@ A request proceeds in the following manner: (10) 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 specified by auth key X will still be process A, as it was in auth key -V. +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 +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 /sbin/request-key at the appropriate places because (a) execve will discard two @@ -136,17 +118,17 @@ A search of any particular keyring proceeds in the following fashion: (2) It considers all the non-keyring keys within that keyring and, if any key matches the criteria specified, calls key_permission(SEARCH) on it to see - if the key is allowed to be found. If it is, that key is returned; if + if the key is allowed to be found. If it is, that key is returned; if not, the search continues, and the error code is retained if of higher priority than the one currently set. (3) It then considers all the keyring-type keys in the keyring it's currently - searching. It calls key_permission(SEARCH) on each keyring, and if this + searching. It calls key_permission(SEARCH) on each keyring, and if this grants permission, it recurses, executing steps (2) and (3) on that keyring. The process stops immediately a valid key is found with permission granted to -use it. Any error from a previous match attempt is discarded and the key is +use it. Any error from a previous match attempt is discarded and the key is returned. When search_process_keyrings() is invoked, it performs the following searches @@ -171,7 +153,7 @@ The moment one succeeds, all pending errors are discarded and the found key is returned. Only if all these fail does the whole thing fail with the highest priority -error. Note that several errors may have come from LSM. +error. Note that several errors may have come from LSM. The error priority is: diff --git a/trunk/Documentation/keys.txt b/trunk/Documentation/keys.txt index e373f0212843..61c0fad2fe2f 100644 --- a/trunk/Documentation/keys.txt +++ b/trunk/Documentation/keys.txt @@ -780,17 +780,6 @@ payload contents" for more information. See also Documentation/keys-request-key.txt. -(*) To search for a key, passing auxiliary data to the upcaller, call: - - struct key *request_key_with_auxdata(const struct key_type *type, - const char *description, - const char *callout_string, - void *aux); - - This is identical to request_key(), except that the auxiliary data is - passed to the key_type->request_key() op if it exists. - - (*) When it is no longer required, the key should be released using: void key_put(struct key *key); @@ -1042,24 +1031,6 @@ The structure has a number of fields, some of which are mandatory: as might happen when the userspace buffer is accessed. - (*) int (*request_key)(struct key *key, struct key *authkey, const char *op, - void *aux); - - This method is optional. If provided, request_key() and - request_key_with_auxdata() will invoke this function rather than - upcalling to /sbin/request-key to operate upon a key of this type. - - The aux parameter is as passed to request_key_with_auxdata() or is NULL - otherwise. Also passed are the key to be operated upon, the - authorisation key for this operation and the operation type (currently - only "create"). - - This function should return only when the upcall is complete. Upon return - the authorisation key will be revoked, and the target key will be - negatively instantiated if it is still uninstantiated. The error will be - returned to the caller of request_key*(). - - ============================ REQUEST-KEY CALLBACK SERVICE ============================ diff --git a/trunk/Documentation/pi-futex.txt b/trunk/Documentation/pi-futex.txt deleted file mode 100644 index 5d61dacd21f6..000000000000 --- a/trunk/Documentation/pi-futex.txt +++ /dev/null @@ -1,121 +0,0 @@ -Lightweight PI-futexes ----------------------- - -We are calling them lightweight for 3 reasons: - - - in the user-space fastpath a PI-enabled futex involves no kernel work - (or any other PI complexity) at all. No registration, no extra kernel - calls - just pure fast atomic ops in userspace. - - - even in the slowpath, the system call and scheduling pattern is very - similar to normal futexes. - - - the in-kernel PI implementation is streamlined around the mutex - abstraction, with strict rules that keep the implementation - relatively simple: only a single owner may own a lock (i.e. no - read-write lock support), only the owner may unlock a lock, no - recursive locking, etc. - -Priority Inheritance - why? ---------------------------- - -The short reply: user-space PI helps achieving/improving determinism for -user-space applications. In the best-case, it can help achieve -determinism and well-bound latencies. Even in the worst-case, PI will -improve the statistical distribution of locking related application -delays. - -The longer reply: ------------------ - -Firstly, sharing locks between multiple tasks is a common programming -technique that often cannot be replaced with lockless algorithms. As we -can see it in the kernel [which is a quite complex program in itself], -lockless structures are rather the exception than the norm - the current -ratio of lockless vs. locky code for shared data structures is somewhere -between 1:10 and 1:100. Lockless is hard, and the complexity of lockless -algorithms often endangers to ability to do robust reviews of said code. -I.e. critical RT apps often choose lock structures to protect critical -data structures, instead of lockless algorithms. Furthermore, there are -cases (like shared hardware, or other resource limits) where lockless -access is mathematically impossible. - -Media players (such as Jack) are an example of reasonable application -design with multiple tasks (with multiple priority levels) sharing -short-held locks: for example, a highprio audio playback thread is -combined with medium-prio construct-audio-data threads and low-prio -display-colory-stuff threads. Add video and decoding to the mix and -we've got even more priority levels. - -So once we accept that synchronization objects (locks) are an -unavoidable fact of life, and once we accept that multi-task userspace -apps have a very fair expectation of being able to use locks, we've got -to think about how to offer the option of a deterministic locking -implementation to user-space. - -Most of the technical counter-arguments against doing priority -inheritance only apply to kernel-space locks. But user-space locks are -different, there we cannot disable interrupts or make the task -non-preemptible in a critical section, so the 'use spinlocks' argument -does not apply (user-space spinlocks have the same priority inversion -problems as other user-space locking constructs). Fact is, pretty much -the only technique that currently enables good determinism for userspace -locks (such as futex-based pthread mutexes) is priority inheritance: - -Currently (without PI), if a high-prio and a low-prio task shares a lock -[this is a quite common scenario for most non-trivial RT applications], -even if all critical sections are coded carefully to be deterministic -(i.e. all critical sections are short in duration and only execute a -limited number of instructions), the kernel cannot guarantee any -deterministic execution of the high-prio task: any medium-priority task -could preempt the low-prio task while it holds the shared lock and -executes the critical section, and could delay it indefinitely. - -Implementation: ---------------- - -As mentioned before, the userspace fastpath of PI-enabled pthread -mutexes involves no kernel work at all - they behave quite similarly to -normal futex-based locks: a 0 value means unlocked, and a value==TID -means locked. (This is the same method as used by list-based robust -futexes.) Userspace uses atomic ops to lock/unlock these mutexes without -entering the kernel. - -To handle the slowpath, we have added two new futex ops: - - FUTEX_LOCK_PI - FUTEX_UNLOCK_PI - -If the lock-acquire fastpath fails, [i.e. an atomic transition from 0 to -TID fails], then FUTEX_LOCK_PI is called. The kernel does all the -remaining work: if there is no futex-queue attached to the futex address -yet then the code looks up the task that owns the futex [it has put its -own TID into the futex value], and attaches a 'PI state' structure to -the futex-queue. The pi_state includes an rt-mutex, which is a PI-aware, -kernel-based synchronization object. The 'other' task is made the owner -of the rt-mutex, and the FUTEX_WAITERS bit is atomically set in the -futex value. Then this task tries to lock the rt-mutex, on which it -blocks. Once it returns, it has the mutex acquired, and it sets the -futex value to its own TID and returns. Userspace has no other work to -perform - it now owns the lock, and futex value contains -FUTEX_WAITERS|TID. - -If the unlock side fastpath succeeds, [i.e. userspace manages to do a -TID -> 0 atomic transition of the futex value], then no kernel work is -triggered. - -If the unlock fastpath fails (because the FUTEX_WAITERS bit is set), -then FUTEX_UNLOCK_PI is called, and the kernel unlocks the futex on the -behalf of userspace - and it also unlocks the attached -pi_state->rt_mutex and thus wakes up any potential waiters. - -Note that under this approach, contrary to previous PI-futex approaches, -there is no prior 'registration' of a PI-futex. [which is not quite -possible anyway, due to existing ABI properties of pthread mutexes.] - -Also, under this scheme, 'robustness' and 'PI' are two orthogonal -properties of futexes, and all four combinations are possible: futex, -robust-futex, PI-futex, robust+PI-futex. - -More details about priority inheritance can be found in -Documentation/rtmutex.txt. diff --git a/trunk/Documentation/robust-futexes.txt b/trunk/Documentation/robust-futexes.txt index 76e8064b8c3a..df82d75245a0 100644 --- a/trunk/Documentation/robust-futexes.txt +++ b/trunk/Documentation/robust-futexes.txt @@ -95,7 +95,7 @@ comparison. If the thread has registered a list, then normally the list is empty. If the thread/process crashed or terminated in some incorrect way then the list might be non-empty: in this case the kernel carefully walks the list [not trusting it], and marks all locks that are owned by -this thread with the FUTEX_OWNER_DIED bit, and wakes up one waiter (if +this thread with the FUTEX_OWNER_DEAD bit, and wakes up one waiter (if any). The list is guaranteed to be private and per-thread at do_exit() time, diff --git a/trunk/Documentation/rt-mutex-design.txt b/trunk/Documentation/rt-mutex-design.txt deleted file mode 100644 index c472ffacc2f6..000000000000 --- a/trunk/Documentation/rt-mutex-design.txt +++ /dev/null @@ -1,781 +0,0 @@ -# -# Copyright (c) 2006 Steven Rostedt -# Licensed under the GNU Free Documentation License, Version 1.2 -# - -RT-mutex implementation design ------------------------------- - -This document tries to describe the design of the rtmutex.c implementation. -It doesn't describe the reasons why rtmutex.c exists. For that please see -Documentation/rt-mutex.txt. Although this document does explain problems -that happen without this code, but that is in the concept to understand -what the code actually is doing. - -The goal of this document is to help others understand the priority -inheritance (PI) algorithm that is used, as well as reasons for the -decisions that were made to implement PI in the manner that was done. - - -Unbounded Priority Inversion ----------------------------- - -Priority inversion is when a lower priority process executes while a higher -priority process wants to run. This happens for several reasons, and -most of the time it can't be helped. Anytime a high priority process wants -to use a resource that a lower priority process has (a mutex for example), -the high priority process must wait until the lower priority process is done -with the resource. This is a priority inversion. What we want to prevent -is something called unbounded priority inversion. That is when the high -priority process is prevented from running by a lower priority process for -an undetermined amount of time. - -The classic example of unbounded priority inversion is were you have three -processes, let's call them processes A, B, and C, where A is the highest -priority process, C is the lowest, and B is in between. A tries to grab a lock -that C owns and must wait and lets C run to release the lock. But in the -meantime, B executes, and since B is of a higher priority than C, it preempts C, -but by doing so, it is in fact preempting A which is a higher priority process. -Now there's no way of knowing how long A will be sleeping waiting for C -to release the lock, because for all we know, B is a CPU hog and will -never give C a chance to release the lock. This is called unbounded priority -inversion. - -Here's a little ASCII art to show the problem. - - grab lock L1 (owned by C) - | -A ---+ - C preempted by B - | -C +----+ - -B +--------> - B now keeps A from running. - - -Priority Inheritance (PI) -------------------------- - -There are several ways to solve this issue, but other ways are out of scope -for this document. Here we only discuss PI. - -PI is where a process inherits the priority of another process if the other -process blocks on a lock owned by the current process. To make this easier -to understand, let's use the previous example, with processes A, B, and C again. - -This time, when A blocks on the lock owned by C, C would inherit the priority -of A. So now if B becomes runnable, it would not preempt C, since C now has -the high priority of A. As soon as C releases the lock, it loses its -inherited priority, and A then can continue with the resource that C had. - -Terminology ------------ - -Here I explain some terminology that is used in this document to help describe -the design that is used to implement PI. - -PI chain - The PI chain is an ordered series of locks and processes that cause - processes to inherit priorities from a previous process that is - blocked on one of its locks. This is described in more detail - later in this document. - -mutex - In this document, to differentiate from locks that implement - PI and spin locks that are used in the PI code, from now on - the PI locks will be called a mutex. - -lock - In this document from now on, I will use the term lock when - referring to spin locks that are used to protect parts of the PI - algorithm. These locks disable preemption for UP (when - CONFIG_PREEMPT is enabled) and on SMP prevents multiple CPUs from - entering critical sections simultaneously. - -spin lock - Same as lock above. - -waiter - A waiter is a struct that is stored on the stack of a blocked - process. Since the scope of the waiter is within the code for - a process being blocked on the mutex, it is fine to allocate - the waiter on the process's stack (local variable). This - structure holds a pointer to the task, as well as the mutex that - the task is blocked on. It also has the plist node structures to - place the task in the waiter_list of a mutex as well as the - pi_list of a mutex owner task (described below). - - waiter is sometimes used in reference to the task that is waiting - on a mutex. This is the same as waiter->task. - -waiters - A list of processes that are blocked on a mutex. - -top waiter - The highest priority process waiting on a specific mutex. - -top pi waiter - The highest priority process waiting on one of the mutexes - that a specific process owns. - -Note: task and process are used interchangeably in this document, mostly to - differentiate between two processes that are being described together. - - -PI chain --------- - -The PI chain is a list of processes and mutexes that may cause priority -inheritance to take place. Multiple chains may converge, but a chain -would never diverge, since a process can't be blocked on more than one -mutex at a time. - -Example: - - Process: A, B, C, D, E - Mutexes: L1, L2, L3, L4 - - A owns: L1 - B blocked on L1 - B owns L2 - C blocked on L2 - C owns L3 - D blocked on L3 - D owns L4 - E blocked on L4 - -The chain would be: - - E->L4->D->L3->C->L2->B->L1->A - -To show where two chains merge, we could add another process F and -another mutex L5 where B owns L5 and F is blocked on mutex L5. - -The chain for F would be: - - F->L5->B->L1->A - -Since a process may own more than one mutex, but never be blocked on more than -one, the chains merge. - -Here we show both chains: - - E->L4->D->L3->C->L2-+ - | - +->B->L1->A - | - F->L5-+ - -For PI to work, the processes at the right end of these chains (or we may -also call it the Top of the chain) must be equal to or higher in priority -than the processes to the left or below in the chain. - -Also since a mutex may have more than one process blocked on it, we can -have multiple chains merge at mutexes. If we add another process G that is -blocked on mutex L2: - - G->L2->B->L1->A - -And once again, to show how this can grow I will show the merging chains -again. - - E->L4->D->L3->C-+ - +->L2-+ - | | - G-+ +->B->L1->A - | - F->L5-+ - - -Plist ------ - -Before I go further and talk about how the PI chain is stored through lists -on both mutexes and processes, I'll explain the plist. This is similar to -the struct list_head functionality that is already in the kernel. -The implementation of plist is out of scope for this document, but it is -very important to understand what it does. - -There are a few differences between plist and list, the most important one -being that plist is a priority sorted linked list. This means that the -priorities of the plist are sorted, such that it takes O(1) to retrieve the -highest priority item in the list. Obviously this is useful to store processes -based on their priorities. - -Another difference, which is important for implementation, is that, unlike -list, the head of the list is a different element than the nodes of a list. -So the head of the list is declared as struct plist_head and nodes that will -be added to the list are declared as struct plist_node. - - -Mutex Waiter List ------------------ - -Every mutex keeps track of all the waiters that are blocked on itself. The mutex -has a plist to store these waiters by priority. This list is protected by -a spin lock that is located in the struct of the mutex. This lock is called -wait_lock. Since the modification of the waiter list is never done in -interrupt context, the wait_lock can be taken without disabling interrupts. - - -Task PI List ------------- - -To keep track of the PI chains, each process has its own PI list. This is -a list of all top waiters of the mutexes that are owned by the process. -Note that this list only holds the top waiters and not all waiters that are -blocked on mutexes owned by the process. - -The top of the task's PI list is always the highest priority task that -is waiting on a mutex that is owned by the task. So if the task has -inherited a priority, it will always be the priority of the task that is -at the top of this list. - -This list is stored in the task structure of a process as a plist called -pi_list. This list is protected by a spin lock also in the task structure, -called pi_lock. This lock may also be taken in interrupt context, so when -locking the pi_lock, interrupts must be disabled. - - -Depth of the PI Chain ---------------------- - -The maximum depth of the PI chain is not dynamic, and could actually be -defined. But is very complex to figure it out, since it depends on all -the nesting of mutexes. Let's look at the example where we have 3 mutexes, -L1, L2, and L3, and four separate functions func1, func2, func3 and func4. -The following shows a locking order of L1->L2->L3, but may not actually -be directly nested that way. - -void func1(void) -{ - mutex_lock(L1); - - /* do anything */ - - mutex_unlock(L1); -} - -void func2(void) -{ - mutex_lock(L1); - mutex_lock(L2); - - /* do something */ - - mutex_unlock(L2); - mutex_unlock(L1); -} - -void func3(void) -{ - mutex_lock(L2); - mutex_lock(L3); - - /* do something else */ - - mutex_unlock(L3); - mutex_unlock(L2); -} - -void func4(void) -{ - mutex_lock(L3); - - /* do something again */ - - mutex_unlock(L3); -} - -Now we add 4 processes that run each of these functions separately. -Processes A, B, C, and D which run functions func1, func2, func3 and func4 -respectively, and such that D runs first and A last. With D being preempted -in func4 in the "do something again" area, we have a locking that follows: - -D owns L3 - C blocked on L3 - C owns L2 - B blocked on L2 - B owns L1 - A blocked on L1 - -And thus we have the chain A->L1->B->L2->C->L3->D. - -This gives us a PI depth of 4 (four processes), but looking at any of the -functions individually, it seems as though they only have at most a locking -depth of two. So, although the locking depth is defined at compile time, -it still is very difficult to find the possibilities of that depth. - -Now since mutexes can be defined by user-land applications, we don't want a DOS -type of application that nests large amounts of mutexes to create a large -PI chain, and have the code holding spin locks while looking at a large -amount of data. So to prevent this, the implementation not only implements -a maximum lock depth, but also only holds at most two different locks at a -time, as it walks the PI chain. More about this below. - - -Mutex owner and flags ---------------------- - -The mutex structure contains a pointer to the owner of the mutex. If the -mutex is not owned, this owner is set to NULL. Since all architectures -have the task structure on at least a four byte alignment (and if this is -not true, the rtmutex.c code will be broken!), this allows for the two -least significant bits to be used as flags. This part is also described -in Documentation/rt-mutex.txt, but will also be briefly described here. - -Bit 0 is used as the "Pending Owner" flag. This is described later. -Bit 1 is used as the "Has Waiters" flags. This is also described later - in more detail, but is set whenever there are waiters on a mutex. - - -cmpxchg Tricks --------------- - -Some architectures implement an atomic cmpxchg (Compare and Exchange). This -is used (when applicable) to keep the fast path of grabbing and releasing -mutexes short. - -cmpxchg is basically the following function performed atomically: - -unsigned long _cmpxchg(unsigned long *A, unsigned long *B, unsigned long *C) -{ - unsigned long T = *A; - if (*A == *B) { - *A = *C; - } - return T; -} -#define cmpxchg(a,b,c) _cmpxchg(&a,&b,&c) - -This is really nice to have, since it allows you to only update a variable -if the variable is what you expect it to be. You know if it succeeded if -the return value (the old value of A) is equal to B. - -The macro rt_mutex_cmpxchg is used to try to lock and unlock mutexes. If -the architecture does not support CMPXCHG, then this macro is simply set -to fail every time. But if CMPXCHG is supported, then this will -help out extremely to keep the fast path short. - -The use of rt_mutex_cmpxchg with the flags in the owner field help optimize -the system for architectures that support it. This will also be explained -later in this document. - - -Priority adjustments --------------------- - -The implementation of the PI code in rtmutex.c has several places that a -process must adjust its priority. With the help of the pi_list of a -process this is rather easy to know what needs to be adjusted. - -The functions implementing the task adjustments are rt_mutex_adjust_prio, -__rt_mutex_adjust_prio (same as the former, but expects the task pi_lock -to already be taken), rt_mutex_get_prio, and rt_mutex_setprio. - -rt_mutex_getprio and rt_mutex_setprio are only used in __rt_mutex_adjust_prio. - -rt_mutex_getprio returns the priority that the task should have. Either the -task's own normal priority, or if a process of a higher priority is waiting on -a mutex owned by the task, then that higher priority should be returned. -Since the pi_list of a task holds an order by priority list of all the top -waiters of all the mutexes that the task owns, rt_mutex_getprio simply needs -to compare the top pi waiter to its own normal priority, and return the higher -priority back. - -(Note: if looking at the code, you will notice that the lower number of - prio is returned. This is because the prio field in the task structure - is an inverse order of the actual priority. So a "prio" of 5 is - of higher priority than a "prio" of 10.) - -__rt_mutex_adjust_prio examines the result of rt_mutex_getprio, and if the -result does not equal the task's current priority, then rt_mutex_setprio -is called to adjust the priority of the task to the new priority. -Note that rt_mutex_setprio is defined in kernel/sched.c to implement the -actual change in priority. - -It is interesting to note that __rt_mutex_adjust_prio can either increase -or decrease the priority of the task. In the case that a higher priority -process has just blocked on a mutex owned by the task, __rt_mutex_adjust_prio -would increase/boost the task's priority. But if a higher priority task -were for some reason to leave the mutex (timeout or signal), this same function -would decrease/unboost the priority of the task. That is because the pi_list -always contains the highest priority task that is waiting on a mutex owned -by the task, so we only need to compare the priority of that top pi waiter -to the normal priority of the given task. - - -High level overview of the PI chain walk ----------------------------------------- - -The PI chain walk is implemented by the function rt_mutex_adjust_prio_chain. - -The implementation has gone through several iterations, and has ended up -with what we believe is the best. It walks the PI chain by only grabbing -at most two locks at a time, and is very efficient. - -The rt_mutex_adjust_prio_chain can be used either to boost or lower process -priorities. - -rt_mutex_adjust_prio_chain is called with a task to be checked for PI -(de)boosting (the owner of a mutex that a process is blocking on), a flag to -check for deadlocking, the mutex that the task owns, and a pointer to a waiter -that is the process's waiter struct that is blocked on the mutex (although this -parameter may be NULL for deboosting). - -For this explanation, I will not mention deadlock detection. This explanation -will try to stay at a high level. - -When this function is called, there are no locks held. That also means -that the state of the owner and lock can change when entered into this function. - -Before this function is called, the task has already had rt_mutex_adjust_prio -performed on it. This means that the task is set to the priority that it -should be at, but the plist nodes of the task's waiter have not been updated -with the new priorities, and that this task may not be in the proper locations -in the pi_lists and wait_lists that the task is blocked on. This function -solves all that. - -A loop is entered, where task is the owner to be checked for PI changes that -was passed by parameter (for the first iteration). The pi_lock of this task is -taken to prevent any more changes to the pi_list of the task. This also -prevents new tasks from completing the blocking on a mutex that is owned by this -task. - -If the task is not blocked on a mutex then the loop is exited. We are at -the top of the PI chain. - -A check is now done to see if the original waiter (the process that is blocked -on the current mutex) is the top pi waiter of the task. That is, is this -waiter on the top of the task's pi_list. If it is not, it either means that -there is another process higher in priority that is blocked on one of the -mutexes that the task owns, or that the waiter has just woken up via a signal -or timeout and has left the PI chain. In either case, the loop is exited, since -we don't need to do any more changes to the priority of the current task, or any -task that owns a mutex that this current task is waiting on. A priority chain -walk is only needed when a new top pi waiter is made to a task. - -The next check sees if the task's waiter plist node has the priority equal to -the priority the task is set at. If they are equal, then we are done with -the loop. Remember that the function started with the priority of the -task adjusted, but the plist nodes that hold the task in other processes -pi_lists have not been adjusted. - -Next, we look at the mutex that the task is blocked on. The mutex's wait_lock -is taken. This is done by a spin_trylock, because the locking order of the -pi_lock and wait_lock goes in the opposite direction. If we fail to grab the -lock, the pi_lock is released, and we restart the loop. - -Now that we have both the pi_lock of the task as well as the wait_lock of -the mutex the task is blocked on, we update the task's waiter's plist node -that is located on the mutex's wait_list. - -Now we release the pi_lock of the task. - -Next the owner of the mutex has its pi_lock taken, so we can update the -task's entry in the owner's pi_list. If the task is the highest priority -process on the mutex's wait_list, then we remove the previous top waiter -from the owner's pi_list, and replace it with the task. - -Note: It is possible that the task was the current top waiter on the mutex, - in which case the task is not yet on the pi_list of the waiter. This - is OK, since plist_del does nothing if the plist node is not on any - list. - -If the task was not the top waiter of the mutex, but it was before we -did the priority updates, that means we are deboosting/lowering the -task. In this case, the task is removed from the pi_list of the owner, -and the new top waiter is added. - -Lastly, we unlock both the pi_lock of the task, as well as the mutex's -wait_lock, and continue the loop again. On the next iteration of the -loop, the previous owner of the mutex will be the task that will be -processed. - -Note: One might think that the owner of this mutex might have changed - since we just grab the mutex's wait_lock. And one could be right. - The important thing to remember is that the owner could not have - become the task that is being processed in the PI chain, since - we have taken that task's pi_lock at the beginning of the loop. - So as long as there is an owner of this mutex that is not the same - process as the tasked being worked on, we are OK. - - Looking closely at the code, one might be confused. The check for the - end of the PI chain is when the task isn't blocked on anything or the - task's waiter structure "task" element is NULL. This check is - protected only by the task's pi_lock. But the code to unlock the mutex - sets the task's waiter structure "task" element to NULL with only - the protection of the mutex's wait_lock, which was not taken yet. - Isn't this a race condition if the task becomes the new owner? - - The answer is No! The trick is the spin_trylock of the mutex's - wait_lock. If we fail that lock, we release the pi_lock of the - task and continue the loop, doing the end of PI chain check again. - - In the code to release the lock, the wait_lock of the mutex is held - the entire time, and it is not let go when we grab the pi_lock of the - new owner of the mutex. So if the switch of a new owner were to happen - after the check for end of the PI chain and the grabbing of the - wait_lock, the unlocking code would spin on the new owner's pi_lock - but never give up the wait_lock. So the PI chain loop is guaranteed to - fail the spin_trylock on the wait_lock, release the pi_lock, and - try again. - - If you don't quite understand the above, that's OK. You don't have to, - unless you really want to make a proof out of it ;) - - -Pending Owners and Lock stealing --------------------------------- - -One of the flags in the owner field of the mutex structure is "Pending Owner". -What this means is that an owner was chosen by the process releasing the -mutex, but that owner has yet to wake up and actually take the mutex. - -Why is this important? Why can't we just give the mutex to another process -and be done with it? - -The PI code is to help with real-time processes, and to let the highest -priority process run as long as possible with little latencies and delays. -If a high priority process owns a mutex that a lower priority process is -blocked on, when the mutex is released it would be given to the lower priority -process. What if the higher priority process wants to take that mutex again. -The high priority process would fail to take that mutex that it just gave up -and it would need to boost the lower priority process to run with full -latency of that critical section (since the low priority process just entered -it). - -There's no reason a high priority process that gives up a mutex should be -penalized if it tries to take that mutex again. If the new owner of the -mutex has not woken up yet, there's no reason that the higher priority process -could not take that mutex away. - -To solve this, we introduced Pending Ownership and Lock Stealing. When a -new process is given a mutex that it was blocked on, it is only given -pending ownership. This means that it's the new owner, unless a higher -priority process comes in and tries to grab that mutex. If a higher priority -process does come along and wants that mutex, we let the higher priority -process "steal" the mutex from the pending owner (only if it is still pending) -and continue with the mutex. - - -Taking of a mutex (The walk through) ------------------------------------- - -OK, now let's take a look at the detailed walk through of what happens when -taking a mutex. - -The first thing that is tried is the fast taking of the mutex. This is -done when we have CMPXCHG enabled (otherwise the fast taking automatically -fails). Only when the owner field of the mutex is NULL can the lock be -taken with the CMPXCHG and nothing else needs to be done. - -If there is contention on the lock, whether it is owned or pending owner -we go about the slow path (rt_mutex_slowlock). - -The slow path function is where the task's waiter structure is created on -the stack. This is because the waiter structure is only needed for the -scope of this function. The waiter structure holds the nodes to store -the task on the wait_list of the mutex, and if need be, the pi_list of -the owner. - -The wait_lock of the mutex is taken since the slow path of unlocking the -mutex also takes this lock. - -We then call try_to_take_rt_mutex. This is where the architecture that -does not implement CMPXCHG would always grab the lock (if there's no -contention). - -try_to_take_rt_mutex is used every time the task tries to grab a mutex in the -slow path. The first thing that is done here is an atomic setting of -the "Has Waiters" flag of the mutex's owner field. Yes, this could really -be false, because if the the mutex has no owner, there are no waiters and -the current task also won't have any waiters. But we don't have the lock -yet, so we assume we are going to be a waiter. The reason for this is to -play nice for those architectures that do have CMPXCHG. By setting this flag -now, the owner of the mutex can't release the mutex without going into the -slow unlock path, and it would then need to grab the wait_lock, which this -code currently holds. So setting the "Has Waiters" flag forces the owner -to synchronize with this code. - -Now that we know that we can't have any races with the owner releasing the -mutex, we check to see if we can take the ownership. This is done if the -mutex doesn't have a owner, or if we can steal the mutex from a pending -owner. Let's look at the situations we have here. - - 1) Has owner that is pending - ---------------------------- - - The mutex has a owner, but it hasn't woken up and the mutex flag - "Pending Owner" is set. The first check is to see if the owner isn't the - current task. This is because this function is also used for the pending - owner to grab the mutex. When a pending owner wakes up, it checks to see - if it can take the mutex, and this is done if the owner is already set to - itself. If so, we succeed and leave the function, clearing the "Pending - Owner" bit. - - If the pending owner is not current, we check to see if the current priority is - higher than the pending owner. If not, we fail the function and return. - - There's also something special about a pending owner. That is a pending owner - is never blocked on a mutex. So there is no PI chain to worry about. It also - means that if the mutex doesn't have any waiters, there's no accounting needed - to update the pending owner's pi_list, since we only worry about processes - blocked on the current mutex. - - If there are waiters on this mutex, and we just stole the ownership, we need - to take the top waiter, remove it from the pi_list of the pending owner, and - add it to the current pi_list. Note that at this moment, the pending owner - is no longer on the list of waiters. This is fine, since the pending owner - would add itself back when it realizes that it had the ownership stolen - from itself. When the pending owner tries to grab the mutex, it will fail - in try_to_take_rt_mutex if the owner field points to another process. - - 2) No owner - ----------- - - If there is no owner (or we successfully stole the lock), we set the owner - of the mutex to current, and set the flag of "Has Waiters" if the current - mutex actually has waiters, or we clear the flag if it doesn't. See, it was - OK that we set that flag early, since now it is cleared. - - 3) Failed to grab ownership - --------------------------- - - The most interesting case is when we fail to take ownership. This means that - there exists an owner, or there's a pending owner with equal or higher - priority than the current task. - -We'll continue on the failed case. - -If the mutex has a timeout, we set up a timer to go off to break us out -of this mutex if we failed to get it after a specified amount of time. - -Now we enter a loop that will continue to try to take ownership of the mutex, or -fail from a timeout or signal. - -Once again we try to take the mutex. This will usually fail the first time -in the loop, since it had just failed to get the mutex. But the second time -in the loop, this would likely succeed, since the task would likely be -the pending owner. - -If the mutex is TASK_INTERRUPTIBLE a check for signals and timeout is done -here. - -The waiter structure has a "task" field that points to the task that is blocked -on the mutex. This field can be NULL the first time it goes through the loop -or if the task is a pending owner and had it's mutex stolen. If the "task" -field is NULL then we need to set up the accounting for it. - -Task blocks on mutex --------------------- - -The accounting of a mutex and process is done with the waiter structure of -the process. The "task" field is set to the process, and the "lock" field -to the mutex. The plist nodes are initialized to the processes current -priority. - -Since the wait_lock was taken at the entry of the slow lock, we can safely -add the waiter to the wait_list. If the current process is the highest -priority process currently waiting on this mutex, then we remove the -previous top waiter process (if it exists) from the pi_list of the owner, -and add the current process to that list. Since the pi_list of the owner -has changed, we call rt_mutex_adjust_prio on the owner to see if the owner -should adjust its priority accordingly. - -If the owner is also blocked on a lock, and had its pi_list changed -(or deadlock checking is on), we unlock the wait_lock of the mutex and go ahead -and run rt_mutex_adjust_prio_chain on the owner, as described earlier. - -Now all locks are released, and if the current process is still blocked on a -mutex (waiter "task" field is not NULL), then we go to sleep (call schedule). - -Waking up in the loop ---------------------- - -The schedule can then wake up for a few reasons. - 1) we were given pending ownership of the mutex. - 2) we received a signal and was TASK_INTERRUPTIBLE - 3) we had a timeout and was TASK_INTERRUPTIBLE - -In any of these cases, we continue the loop and once again try to grab the -ownership of the mutex. If we succeed, we exit the loop, otherwise we continue -and on signal and timeout, will exit the loop, or if we had the mutex stolen -we just simply add ourselves back on the lists and go back to sleep. - -Note: For various reasons, because of timeout and signals, the steal mutex - algorithm needs to be careful. This is because the current process is - still on the wait_list. And because of dynamic changing of priorities, - especially on SCHED_OTHER tasks, the current process can be the - highest priority task on the wait_list. - -Failed to get mutex on Timeout or Signal ----------------------------------------- - -If a timeout or signal occurred, the waiter's "task" field would not be -NULL and the task needs to be taken off the wait_list of the mutex and perhaps -pi_list of the owner. If this process was a high priority process, then -the rt_mutex_adjust_prio_chain needs to be executed again on the owner, -but this time it will be lowering the priorities. - - -Unlocking the Mutex -------------------- - -The unlocking of a mutex also has a fast path for those architectures with -CMPXCHG. Since the taking of a mutex on contention always sets the -"Has Waiters" flag of the mutex's owner, we use this to know if we need to -take the slow path when unlocking the mutex. If the mutex doesn't have any -waiters, the owner field of the mutex would equal the current process and -the mutex can be unlocked by just replacing the owner field with NULL. - -If the owner field has the "Has Waiters" bit set (or CMPXCHG is not available), -the slow unlock path is taken. - -The first thing done in the slow unlock path is to take the wait_lock of the -mutex. This synchronizes the locking and unlocking of the mutex. - -A check is made to see if the mutex has waiters or not. On architectures that -do not have CMPXCHG, this is the location that the owner of the mutex will -determine if a waiter needs to be awoken or not. On architectures that -do have CMPXCHG, that check is done in the fast path, but it is still needed -in the slow path too. If a waiter of a mutex woke up because of a signal -or timeout between the time the owner failed the fast path CMPXCHG check and -the grabbing of the wait_lock, the mutex may not have any waiters, thus the -owner still needs to make this check. If there are no waiters than the mutex -owner field is set to NULL, the wait_lock is released and nothing more is -needed. - -If there are waiters, then we need to wake one up and give that waiter -pending ownership. - -On the wake up code, the pi_lock of the current owner is taken. The top -waiter of the lock is found and removed from the wait_list of the mutex -as well as the pi_list of the current owner. The task field of the new -pending owner's waiter structure is set to NULL, and the owner field of the -mutex is set to the new owner with the "Pending Owner" bit set, as well -as the "Has Waiters" bit if there still are other processes blocked on the -mutex. - -The pi_lock of the previous owner is released, and the new pending owner's -pi_lock is taken. Remember that this is the trick to prevent the race -condition in rt_mutex_adjust_prio_chain from adding itself as a waiter -on the mutex. - -We now clear the "pi_blocked_on" field of the new pending owner, and if -the mutex still has waiters pending, we add the new top waiter to the pi_list -of the pending owner. - -Finally we unlock the pi_lock of the pending owner and wake it up. - - -Contact -------- - -For updates on this document, please email Steven Rostedt - - -Credits -------- - -Author: Steven Rostedt - -Reviewers: Ingo Molnar, Thomas Gleixner, Thomas Duetsch, and Randy Dunlap - -Updates -------- - -This document was originally written for 2.6.17-rc3-mm1 diff --git a/trunk/Documentation/rt-mutex.txt b/trunk/Documentation/rt-mutex.txt deleted file mode 100644 index 243393d882ee..000000000000 --- a/trunk/Documentation/rt-mutex.txt +++ /dev/null @@ -1,79 +0,0 @@ -RT-mutex subsystem with PI support ----------------------------------- - -RT-mutexes with priority inheritance are used to support PI-futexes, -which enable pthread_mutex_t priority inheritance attributes -(PTHREAD_PRIO_INHERIT). [See Documentation/pi-futex.txt for more details -about PI-futexes.] - -This technology was developed in the -rt tree and streamlined for -pthread_mutex support. - -Basic principles: ------------------ - -RT-mutexes extend the semantics of simple mutexes by the priority -inheritance protocol. - -A low priority owner of a rt-mutex inherits the priority of a higher -priority waiter until the rt-mutex is released. If the temporarily -boosted owner blocks on a rt-mutex itself it propagates the priority -boosting to the owner of the other rt_mutex it gets blocked on. The -priority boosting is immediately removed once the rt_mutex has been -unlocked. - -This approach allows us to shorten the block of high-prio tasks on -mutexes which protect shared resources. Priority inheritance is not a -magic bullet for poorly designed applications, but it allows -well-designed applications to use userspace locks in critical parts of -an high priority thread, without losing determinism. - -The enqueueing of the waiters into the rtmutex waiter list is done in -priority order. For same priorities FIFO order is chosen. For each -rtmutex, only the top priority waiter is enqueued into the owner's -priority waiters list. This list too queues in priority order. Whenever -the top priority waiter of a task changes (for example it timed out or -got a signal), the priority of the owner task is readjusted. [The -priority enqueueing is handled by "plists", see include/linux/plist.h -for more details.] - -RT-mutexes are optimized for fastpath operations and have no internal -locking overhead when locking an uncontended mutex or unlocking a mutex -without waiters. The optimized fastpath operations require cmpxchg -support. [If that is not available then the rt-mutex internal spinlock -is used] - -The state of the rt-mutex is tracked via the owner field of the rt-mutex -structure: - -rt_mutex->owner holds the task_struct pointer of the owner. Bit 0 and 1 -are used to keep track of the "owner is pending" and "rtmutex has -waiters" state. - - owner bit1 bit0 - NULL 0 0 mutex is free (fast acquire possible) - NULL 0 1 invalid state - NULL 1 0 Transitional state* - NULL 1 1 invalid state - taskpointer 0 0 mutex is held (fast release possible) - taskpointer 0 1 task is pending owner - taskpointer 1 0 mutex is held and has waiters - taskpointer 1 1 task is pending owner and mutex has waiters - -Pending-ownership handling is a performance optimization: -pending-ownership is assigned to the first (highest priority) waiter of -the mutex, when the mutex is released. The thread is woken up and once -it starts executing it can acquire the mutex. Until the mutex is taken -by it (bit 0 is cleared) a competing higher priority thread can "steal" -the mutex which puts the woken up thread back on the waiters list. - -The pending-ownership optimization is especially important for the -uninterrupted workflow of high-prio tasks which repeatedly -takes/releases locks that have lower-prio waiters. Without this -optimization the higher-prio thread would ping-pong to the lower-prio -task [because at unlock time we always assign a new owner]. - -(*) The "mutex has waiters" bit gets set to take the lock. If the lock -doesn't already have an owner, this bit is quickly cleared if there are -no waiters. So this is a transitional state to synchronize with looking -at the owner field of the mutex and the mutex owner releasing the lock. diff --git a/trunk/Documentation/video4linux/README.pvrusb2 b/trunk/Documentation/video4linux/README.pvrusb2 deleted file mode 100644 index c73a32c34528..000000000000 --- a/trunk/Documentation/video4linux/README.pvrusb2 +++ /dev/null @@ -1,212 +0,0 @@ - -$Id$ -Mike Isely - - pvrusb2 driver - -Background: - - This driver is intended for the "Hauppauge WinTV PVR USB 2.0", which - is a USB 2.0 hosted TV Tuner. This driver is a work in progress. - Its history started with the reverse-engineering effort by Björn - Danielsson whose web page can be found here: - - http://pvrusb2.dax.nu/ - - From there Aurelien Alleaume began an effort to - create a video4linux compatible driver. I began with Aurelien's - last known snapshot and evolved the driver to the state it is in - here. - - More information on this driver can be found at: - - http://www.isely.net/pvrusb2.html - - - This driver has a strong separation of layers. They are very - roughly: - - 1a. Low level wire-protocol implementation with the device. - - 1b. I2C adaptor implementation and corresponding I2C client drivers - implemented elsewhere in V4L. - - 1c. High level hardware driver implementation which coordinates all - activities that ensure correct operation of the device. - - 2. A "context" layer which manages instancing of driver, setup, - tear-down, arbitration, and interaction with high level - interfaces appropriately as devices are hotplugged in the - system. - - 3. High level interfaces which glue the driver to various published - Linux APIs (V4L, sysfs, maybe DVB in the future). - - The most important shearing layer is between the top 2 layers. A - lot of work went into the driver to ensure that any kind of - conceivable API can be laid on top of the core driver. (Yes, the - driver internally leverages V4L to do its work but that really has - nothing to do with the API published by the driver to the outside - world.) The architecture allows for different APIs to - simultaneously access the driver. I have a strong sense of fairness - about APIs and also feel that it is a good design principle to keep - implementation and interface isolated from each other. Thus while - right now the V4L high level interface is the most complete, the - sysfs high level interface will work equally well for similar - functions, and there's no reason I see right now why it shouldn't be - possible to produce a DVB high level interface that can sit right - alongside V4L. - - NOTE: Complete documentation on the pvrusb2 driver is contained in - the html files within the doc directory; these are exactly the same - as what is on the web site at the time. Browse those files - (especially the FAQ) before asking questions. - - -Building - - To build these modules essentially amounts to just running "Make", - but you need the kernel source tree nearby and you will likely also - want to set a few controlling environment variables first in order - to link things up with that source tree. Please see the Makefile - here for comments that explain how to do that. - - -Source file list / functional overview: - - (Note: The term "module" used below generally refers to loosely - defined functional units within the pvrusb2 driver and bears no - relation to the Linux kernel's concept of a loadable module.) - - pvrusb2-audio.[ch] - This is glue logic that resides between this - driver and the msp3400.ko I2C client driver (which is found - elsewhere in V4L). - - pvrusb2-context.[ch] - This module implements the context for an - instance of the driver. Everything else eventually ties back to - or is otherwise instanced within the data structures implemented - here. Hotplugging is ultimately coordinated here. All high level - interfaces tie into the driver through this module. This module - helps arbitrate each interface's access to the actual driver core, - and is designed to allow concurrent access through multiple - instances of multiple interfaces (thus you can for example change - the tuner's frequency through sysfs while simultaneously streaming - video through V4L out to an instance of mplayer). - - pvrusb2-debug.h - This header defines a printk() wrapper and a mask - of debugging bit definitions for the various kinds of debug - messages that can be enabled within the driver. - - pvrusb2-debugifc.[ch] - This module implements a crude command line - oriented debug interface into the driver. Aside from being part - of the process for implementing manual firmware extraction (see - the pvrusb2 web site mentioned earlier), probably I'm the only one - who has ever used this. It is mainly a debugging aid. - - pvrusb2-eeprom.[ch] - This is glue logic that resides between this - driver the tveeprom.ko module, which is itself implemented - elsewhere in V4L. - - pvrusb2-encoder.[ch] - This module implements all protocol needed to - interact with the Conexant mpeg2 encoder chip within the pvrusb2 - device. It is a crude echo of corresponding logic in ivtv, - however the design goals (strict isolation) and physical layer - (proxy through USB instead of PCI) are enough different that this - implementation had to be completely different. - - pvrusb2-hdw-internal.h - This header defines the core data structure - in the driver used to track ALL internal state related to control - of the hardware. Nobody outside of the core hardware-handling - modules should have any business using this header. All external - access to the driver should be through one of the high level - interfaces (e.g. V4L, sysfs, etc), and in fact even those high - level interfaces are restricted to the API defined in - pvrusb2-hdw.h and NOT this header. - - pvrusb2-hdw.h - This header defines the full internal API for - controlling the hardware. High level interfaces (e.g. V4L, sysfs) - will work through here. - - pvrusb2-hdw.c - This module implements all the various bits of logic - that handle overall control of a specific pvrusb2 device. - (Policy, instantiation, and arbitration of pvrusb2 devices fall - within the jurisdiction of pvrusb-context not here). - - pvrusb2-i2c-chips-*.c - These modules implement the glue logic to - tie together and configure various I2C modules as they attach to - the I2C bus. There are two versions of this file. The "v4l2" - version is intended to be used in-tree alongside V4L, where we - implement just the logic that makes sense for a pure V4L - environment. The "all" version is intended for use outside of - V4L, where we might encounter other possibly "challenging" modules - from ivtv or older kernel snapshots (or even the support modules - in the standalone snapshot). - - pvrusb2-i2c-cmd-v4l1.[ch] - This module implements generic V4L1 - compatible commands to the I2C modules. It is here where state - changes inside the pvrusb2 driver are translated into V4L1 - commands that are in turn send to the various I2C modules. - - pvrusb2-i2c-cmd-v4l2.[ch] - This module implements generic V4L2 - compatible commands to the I2C modules. It is here where state - changes inside the pvrusb2 driver are translated into V4L2 - commands that are in turn send to the various I2C modules. - - pvrusb2-i2c-core.[ch] - This module provides an implementation of a - kernel-friendly I2C adaptor driver, through which other external - I2C client drivers (e.g. msp3400, tuner, lirc) may connect and - operate corresponding chips within the the pvrusb2 device. It is - through here that other V4L modules can reach into this driver to - operate specific pieces (and those modules are in turn driven by - glue logic which is coordinated by pvrusb2-hdw, doled out by - pvrusb2-context, and then ultimately made available to users - through one of the high level interfaces). - - pvrusb2-io.[ch] - This module implements a very low level ring of - transfer buffers, required in order to stream data from the - device. This module is *very* low level. It only operates the - buffers and makes no attempt to define any policy or mechanism for - how such buffers might be used. - - pvrusb2-ioread.[ch] - This module layers on top of pvrusb2-io.[ch] - to provide a streaming API usable by a read() system call style of - I/O. Right now this is the only layer on top of pvrusb2-io.[ch], - however the underlying architecture here was intended to allow for - other styles of I/O to be implemented with additonal modules, like - mmap()'ed buffers or something even more exotic. - - pvrusb2-main.c - This is the top level of the driver. Module level - and USB core entry points are here. This is our "main". - - pvrusb2-sysfs.[ch] - This is the high level interface which ties the - pvrusb2 driver into sysfs. Through this interface you can do - everything with the driver except actually stream data. - - pvrusb2-tuner.[ch] - This is glue logic that resides between this - driver and the tuner.ko I2C client driver (which is found - elsewhere in V4L). - - pvrusb2-util.h - This header defines some common macros used - throughout the driver. These macros are not really specific to - the driver, but they had to go somewhere. - - pvrusb2-v4l2.[ch] - This is the high level interface which ties the - pvrusb2 driver into video4linux. It is through here that V4L - applications can open and operate the driver in the usual V4L - ways. Note that **ALL** V4L functionality is published only - through here and nowhere else. - - pvrusb2-video-*.[ch] - This is glue logic that resides between this - driver and the saa711x.ko I2C client driver (which is found - elsewhere in V4L). Note that saa711x.ko used to be known as - saa7115.ko in ivtv. There are two versions of this; one is - selected depending on the particular saa711[5x].ko that is found. - - pvrusb2.h - This header contains compile time tunable parameters - (and at the moment the driver has very little that needs to be - tuned). - - - -Mike Isely - isely@pobox.com - diff --git a/trunk/Documentation/watchdog/pcwd-watchdog.txt b/trunk/Documentation/watchdog/pcwd-watchdog.txt index d9ee6336c1d4..12187a33e310 100644 --- a/trunk/Documentation/watchdog/pcwd-watchdog.txt +++ b/trunk/Documentation/watchdog/pcwd-watchdog.txt @@ -22,9 +22,78 @@ to run the program with an "&" to run it in the background!) If you want to write a program to be compatible with the PC Watchdog - driver, simply use of modify the watchdog test program: - Documentation/watchdog/src/watchdog-test.c - + driver, simply do the following: + +-- Snippet of code -- +/* + * Watchdog Driver Test Program + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int fd; + +/* + * This function simply sends an IOCTL to the driver, which in turn ticks + * the PC Watchdog card to reset its internal timer so it doesn't trigger + * a computer reset. + */ +void keep_alive(void) +{ + int dummy; + + ioctl(fd, WDIOC_KEEPALIVE, &dummy); +} + +/* + * The main program. Run the program with "-d" to disable the card, + * or "-e" to enable the card. + */ +int main(int argc, char *argv[]) +{ + fd = open("/dev/watchdog", O_WRONLY); + + if (fd == -1) { + fprintf(stderr, "Watchdog device not enabled.\n"); + fflush(stderr); + exit(-1); + } + + if (argc > 1) { + if (!strncasecmp(argv[1], "-d", 2)) { + ioctl(fd, WDIOC_SETOPTIONS, WDIOS_DISABLECARD); + fprintf(stderr, "Watchdog card disabled.\n"); + fflush(stderr); + exit(0); + } else if (!strncasecmp(argv[1], "-e", 2)) { + ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD); + fprintf(stderr, "Watchdog card enabled.\n"); + fflush(stderr); + exit(0); + } else { + fprintf(stderr, "-d to disable, -e to enable.\n"); + fprintf(stderr, "run by itself to tick the card.\n"); + fflush(stderr); + exit(0); + } + } else { + fprintf(stderr, "Watchdog Ticking Away!\n"); + fflush(stderr); + } + + while(1) { + keep_alive(); + sleep(1); + } +} +-- End snippet -- Other IOCTL functions include: diff --git a/trunk/Documentation/watchdog/src/watchdog-simple.c b/trunk/Documentation/watchdog/src/watchdog-simple.c deleted file mode 100644 index 85cf17c48669..000000000000 --- a/trunk/Documentation/watchdog/src/watchdog-simple.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include - -int main(int argc, const char *argv[]) { - int fd = open("/dev/watchdog", O_WRONLY); - if (fd == -1) { - perror("watchdog"); - exit(1); - } - while (1) { - write(fd, "\0", 1); - fsync(fd); - sleep(10); - } -} diff --git a/trunk/Documentation/watchdog/src/watchdog-test.c b/trunk/Documentation/watchdog/src/watchdog-test.c deleted file mode 100644 index 65f6c19cb865..000000000000 --- a/trunk/Documentation/watchdog/src/watchdog-test.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Watchdog Driver Test Program - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -int fd; - -/* - * This function simply sends an IOCTL to the driver, which in turn ticks - * the PC Watchdog card to reset its internal timer so it doesn't trigger - * a computer reset. - */ -void keep_alive(void) -{ - int dummy; - - ioctl(fd, WDIOC_KEEPALIVE, &dummy); -} - -/* - * The main program. Run the program with "-d" to disable the card, - * or "-e" to enable the card. - */ -int main(int argc, char *argv[]) -{ - fd = open("/dev/watchdog", O_WRONLY); - - if (fd == -1) { - fprintf(stderr, "Watchdog device not enabled.\n"); - fflush(stderr); - exit(-1); - } - - if (argc > 1) { - if (!strncasecmp(argv[1], "-d", 2)) { - ioctl(fd, WDIOC_SETOPTIONS, WDIOS_DISABLECARD); - fprintf(stderr, "Watchdog card disabled.\n"); - fflush(stderr); - exit(0); - } else if (!strncasecmp(argv[1], "-e", 2)) { - ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD); - fprintf(stderr, "Watchdog card enabled.\n"); - fflush(stderr); - exit(0); - } else { - fprintf(stderr, "-d to disable, -e to enable.\n"); - fprintf(stderr, "run by itself to tick the card.\n"); - fflush(stderr); - exit(0); - } - } else { - fprintf(stderr, "Watchdog Ticking Away!\n"); - fflush(stderr); - } - - while(1) { - keep_alive(); - sleep(1); - } -} diff --git a/trunk/Documentation/watchdog/watchdog-api.txt b/trunk/Documentation/watchdog/watchdog-api.txt index 958ff3d48be3..21ed51173662 100644 --- a/trunk/Documentation/watchdog/watchdog-api.txt +++ b/trunk/Documentation/watchdog/watchdog-api.txt @@ -34,7 +34,22 @@ activates as soon as /dev/watchdog is opened and will reboot unless the watchdog is pinged within a certain time, this time is called the timeout or margin. The simplest way to ping the watchdog is to write some data to the device. So a very simple watchdog daemon would look -like this source file: see Documentation/watchdog/src/watchdog-simple.c +like this: + +#include +#include + +int main(int argc, const char *argv[]) { + int fd=open("/dev/watchdog",O_WRONLY); + if (fd==-1) { + perror("watchdog"); + exit(1); + } + while(1) { + write(fd, "\0", 1); + sleep(10); + } +} A more advanced driver could for example check that a HTTP server is still responding before doing the write call to ping the watchdog. @@ -95,40 +110,7 @@ current timeout using the GETTIMEOUT ioctl. ioctl(fd, WDIOC_GETTIMEOUT, &timeout); printf("The timeout was is %d seconds\n", timeout); -Pretimeouts: - -Some watchdog timers can be set to have a trigger go off before the -actual time they will reset the system. This can be done with an NMI, -interrupt, or other mechanism. This allows Linux to record useful -information (like panic information and kernel coredumps) before it -resets. - - pretimeout = 10; - ioctl(fd, WDIOC_SETPRETIMEOUT, &pretimeout); - -Note that the pretimeout is the number of seconds before the time -when the timeout will go off. It is not the number of seconds until -the pretimeout. So, for instance, if you set the timeout to 60 seconds -and the pretimeout to 10 seconds, the pretimout will go of in 50 -seconds. Setting a pretimeout to zero disables it. - -There is also a get function for getting the pretimeout: - - ioctl(fd, WDIOC_GETPRETIMEOUT, &timeout); - printf("The pretimeout was is %d seconds\n", timeout); - -Not all watchdog drivers will support a pretimeout. - -Get the number of seconds before reboot: - -Some watchdog drivers have the ability to report the remaining time -before the system will reboot. The WDIOC_GETTIMELEFT is the ioctl -that returns the number of seconds before reboot. - - ioctl(fd, WDIOC_GETTIMELEFT, &timeleft); - printf("The timeout was is %d seconds\n", timeleft); - -Environmental monitoring: +Envinronmental monitoring: All watchdog drivers are required return more information about the system, some do temperature, fan and power level monitoring, some can tell you @@ -187,10 +169,6 @@ The watchdog saw a keepalive ping since it was last queried. WDIOF_SETTIMEOUT Can set/get the timeout -The watchdog can do pretimeouts. - - WDIOF_PRETIMEOUT Pretimeout (in seconds), get/set - For those drivers that return any bits set in the option field, the GETSTATUS and GETBOOTSTATUS ioctls can be used to ask for the current diff --git a/trunk/Documentation/watchdog/watchdog.txt b/trunk/Documentation/watchdog/watchdog.txt index 4b1ff69cc19a..dffda29c8799 100644 --- a/trunk/Documentation/watchdog/watchdog.txt +++ b/trunk/Documentation/watchdog/watchdog.txt @@ -65,7 +65,28 @@ The external event interfaces on the WDT boards are not currently supported. Minor numbers are however allocated for it. -Example Watchdog Driver: see Documentation/watchdog/src/watchdog-simple.c +Example Watchdog Driver +----------------------- + +#include +#include +#include + +int main(int argc, const char *argv[]) +{ + int fd=open("/dev/watchdog",O_WRONLY); + if(fd==-1) + { + perror("watchdog"); + exit(1); + } + while(1) + { + write(fd,"\0",1); + fsync(fd); + sleep(10); + } +} Contact Information diff --git a/trunk/arch/alpha/kernel/irq.c b/trunk/arch/alpha/kernel/irq.c index 63af36cf7f6e..da677f829f76 100644 --- a/trunk/arch/alpha/kernel/irq.c +++ b/trunk/arch/alpha/kernel/irq.c @@ -49,15 +49,15 @@ select_smp_affinity(unsigned int irq) static int last_cpu; int cpu = last_cpu + 1; - if (!irq_desc[irq].chip->set_affinity || irq_user_affinity[irq]) + if (!irq_desc[irq].handler->set_affinity || irq_user_affinity[irq]) return 1; while (!cpu_possible(cpu)) cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); last_cpu = cpu; - irq_desc[irq].affinity = cpumask_of_cpu(cpu); - irq_desc[irq].chip->set_affinity(irq, cpumask_of_cpu(cpu)); + irq_affinity[irq] = cpumask_of_cpu(cpu); + irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu)); return 0; } #endif /* CONFIG_SMP */ @@ -93,7 +93,7 @@ show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq]); #endif - seq_printf(p, " %14s", irq_desc[irq].chip->typename); + seq_printf(p, " %14s", irq_desc[irq].handler->typename); seq_printf(p, " %c%s", (action->flags & SA_INTERRUPT)?'+':' ', action->name); diff --git a/trunk/arch/alpha/kernel/irq_alpha.c b/trunk/arch/alpha/kernel/irq_alpha.c index f20f2dff9c43..9d34ce26e5ef 100644 --- a/trunk/arch/alpha/kernel/irq_alpha.c +++ b/trunk/arch/alpha/kernel/irq_alpha.c @@ -233,7 +233,7 @@ void __init init_rtc_irq(void) { irq_desc[RTC_IRQ].status = IRQ_DISABLED; - irq_desc[RTC_IRQ].chip = &rtc_irq_type; + irq_desc[RTC_IRQ].handler = &rtc_irq_type; setup_irq(RTC_IRQ, &timer_irqaction); } diff --git a/trunk/arch/alpha/kernel/irq_i8259.c b/trunk/arch/alpha/kernel/irq_i8259.c index ac893bd48036..b188683b83fd 100644 --- a/trunk/arch/alpha/kernel/irq_i8259.c +++ b/trunk/arch/alpha/kernel/irq_i8259.c @@ -109,7 +109,7 @@ init_i8259a_irqs(void) for (i = 0; i < 16; i++) { irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].chip = &i8259a_irq_type; + irq_desc[i].handler = &i8259a_irq_type; } setup_irq(2, &cascade); diff --git a/trunk/arch/alpha/kernel/irq_pyxis.c b/trunk/arch/alpha/kernel/irq_pyxis.c index 3b581415bab0..146a20b9e3d5 100644 --- a/trunk/arch/alpha/kernel/irq_pyxis.c +++ b/trunk/arch/alpha/kernel/irq_pyxis.c @@ -120,7 +120,7 @@ init_pyxis_irqs(unsigned long ignore_mask) if ((ignore_mask >> i) & 1) continue; irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = &pyxis_irq_type; + irq_desc[i].handler = &pyxis_irq_type; } setup_irq(16+7, &isa_cascade_irqaction); diff --git a/trunk/arch/alpha/kernel/irq_srm.c b/trunk/arch/alpha/kernel/irq_srm.c index 8e4d121f84cc..0a87e466918c 100644 --- a/trunk/arch/alpha/kernel/irq_srm.c +++ b/trunk/arch/alpha/kernel/irq_srm.c @@ -67,7 +67,7 @@ init_srm_irqs(long max, unsigned long ignore_mask) if (i < 64 && ((ignore_mask >> i) & 1)) continue; irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = &srm_irq_type; + irq_desc[i].handler = &srm_irq_type; } } diff --git a/trunk/arch/alpha/kernel/setup.c b/trunk/arch/alpha/kernel/setup.c index 254c507a608c..558b83368559 100644 --- a/trunk/arch/alpha/kernel/setup.c +++ b/trunk/arch/alpha/kernel/setup.c @@ -481,7 +481,7 @@ register_cpus(void) struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); if (!p) return -ENOMEM; - register_cpu(p, i); + register_cpu(p, i, NULL); } return 0; } diff --git a/trunk/arch/alpha/kernel/sys_alcor.c b/trunk/arch/alpha/kernel/sys_alcor.c index 1a1a2c7a3d94..d7f0e97fe56f 100644 --- a/trunk/arch/alpha/kernel/sys_alcor.c +++ b/trunk/arch/alpha/kernel/sys_alcor.c @@ -144,7 +144,7 @@ alcor_init_irq(void) if (i >= 16+20 && i <= 16+30) continue; irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = &alcor_irq_type; + irq_desc[i].handler = &alcor_irq_type; } i8259a_irq_type.ack = alcor_isa_mask_and_ack_irq; diff --git a/trunk/arch/alpha/kernel/sys_cabriolet.c b/trunk/arch/alpha/kernel/sys_cabriolet.c index 8c9e443d93ad..8e3374d34c95 100644 --- a/trunk/arch/alpha/kernel/sys_cabriolet.c +++ b/trunk/arch/alpha/kernel/sys_cabriolet.c @@ -124,7 +124,7 @@ common_init_irq(void (*srm_dev_int)(unsigned long v, struct pt_regs *r)) for (i = 16; i < 35; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = &cabriolet_irq_type; + irq_desc[i].handler = &cabriolet_irq_type; } } diff --git a/trunk/arch/alpha/kernel/sys_dp264.c b/trunk/arch/alpha/kernel/sys_dp264.c index b28c8f1c6e10..d5da6b1b28ee 100644 --- a/trunk/arch/alpha/kernel/sys_dp264.c +++ b/trunk/arch/alpha/kernel/sys_dp264.c @@ -300,7 +300,7 @@ init_tsunami_irqs(struct hw_interrupt_type * ops, int imin, int imax) long i; for (i = imin; i <= imax; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = ops; + irq_desc[i].handler = ops; } } diff --git a/trunk/arch/alpha/kernel/sys_eb64p.c b/trunk/arch/alpha/kernel/sys_eb64p.c index aeb8e0277905..61a79c354f0b 100644 --- a/trunk/arch/alpha/kernel/sys_eb64p.c +++ b/trunk/arch/alpha/kernel/sys_eb64p.c @@ -137,7 +137,7 @@ eb64p_init_irq(void) for (i = 16; i < 32; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = &eb64p_irq_type; + irq_desc[i].handler = &eb64p_irq_type; } common_init_isa_dma(); diff --git a/trunk/arch/alpha/kernel/sys_eiger.c b/trunk/arch/alpha/kernel/sys_eiger.c index 64a785baf53a..bd6e5f0e43c7 100644 --- a/trunk/arch/alpha/kernel/sys_eiger.c +++ b/trunk/arch/alpha/kernel/sys_eiger.c @@ -154,7 +154,7 @@ eiger_init_irq(void) for (i = 16; i < 128; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = &eiger_irq_type; + irq_desc[i].handler = &eiger_irq_type; } } diff --git a/trunk/arch/alpha/kernel/sys_jensen.c b/trunk/arch/alpha/kernel/sys_jensen.c index 0148e095638f..fcabb7c96a16 100644 --- a/trunk/arch/alpha/kernel/sys_jensen.c +++ b/trunk/arch/alpha/kernel/sys_jensen.c @@ -206,11 +206,11 @@ jensen_init_irq(void) { init_i8259a_irqs(); - irq_desc[1].chip = &jensen_local_irq_type; - irq_desc[4].chip = &jensen_local_irq_type; - irq_desc[3].chip = &jensen_local_irq_type; - irq_desc[7].chip = &jensen_local_irq_type; - irq_desc[9].chip = &jensen_local_irq_type; + irq_desc[1].handler = &jensen_local_irq_type; + irq_desc[4].handler = &jensen_local_irq_type; + irq_desc[3].handler = &jensen_local_irq_type; + irq_desc[7].handler = &jensen_local_irq_type; + irq_desc[9].handler = &jensen_local_irq_type; common_init_isa_dma(); } diff --git a/trunk/arch/alpha/kernel/sys_marvel.c b/trunk/arch/alpha/kernel/sys_marvel.c index 36d215954376..e32fee505220 100644 --- a/trunk/arch/alpha/kernel/sys_marvel.c +++ b/trunk/arch/alpha/kernel/sys_marvel.c @@ -303,7 +303,7 @@ init_io7_irqs(struct io7 *io7, /* Set up the lsi irqs. */ for (i = 0; i < 128; ++i) { irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[base + i].chip = lsi_ops; + irq_desc[base + i].handler = lsi_ops; } /* Disable the implemented irqs in hardware. */ @@ -317,7 +317,7 @@ init_io7_irqs(struct io7 *io7, /* Set up the msi irqs. */ for (i = 128; i < (128 + 512); ++i) { irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[base + i].chip = msi_ops; + irq_desc[base + i].handler = msi_ops; } for (i = 0; i < 16; ++i) @@ -335,7 +335,7 @@ marvel_init_irq(void) /* Reserve the legacy irqs. */ for (i = 0; i < 16; ++i) { irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].chip = &marvel_legacy_irq_type; + irq_desc[i].handler = &marvel_legacy_irq_type; } /* Init the io7 irqs. */ diff --git a/trunk/arch/alpha/kernel/sys_mikasa.c b/trunk/arch/alpha/kernel/sys_mikasa.c index b741600e3761..d78a0daa6168 100644 --- a/trunk/arch/alpha/kernel/sys_mikasa.c +++ b/trunk/arch/alpha/kernel/sys_mikasa.c @@ -117,7 +117,7 @@ mikasa_init_irq(void) for (i = 16; i < 32; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = &mikasa_irq_type; + irq_desc[i].handler = &mikasa_irq_type; } init_i8259a_irqs(); diff --git a/trunk/arch/alpha/kernel/sys_noritake.c b/trunk/arch/alpha/kernel/sys_noritake.c index 55db02d318d7..65061f5d7410 100644 --- a/trunk/arch/alpha/kernel/sys_noritake.c +++ b/trunk/arch/alpha/kernel/sys_noritake.c @@ -139,7 +139,7 @@ noritake_init_irq(void) for (i = 16; i < 48; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = &noritake_irq_type; + irq_desc[i].handler = &noritake_irq_type; } init_i8259a_irqs(); diff --git a/trunk/arch/alpha/kernel/sys_rawhide.c b/trunk/arch/alpha/kernel/sys_rawhide.c index 949607e3d6fb..05888a02a604 100644 --- a/trunk/arch/alpha/kernel/sys_rawhide.c +++ b/trunk/arch/alpha/kernel/sys_rawhide.c @@ -180,7 +180,7 @@ rawhide_init_irq(void) for (i = 16; i < 128; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = &rawhide_irq_type; + irq_desc[i].handler = &rawhide_irq_type; } init_i8259a_irqs(); diff --git a/trunk/arch/alpha/kernel/sys_rx164.c b/trunk/arch/alpha/kernel/sys_rx164.c index 6ae506052635..58404243057b 100644 --- a/trunk/arch/alpha/kernel/sys_rx164.c +++ b/trunk/arch/alpha/kernel/sys_rx164.c @@ -117,7 +117,7 @@ rx164_init_irq(void) rx164_update_irq_hw(0); for (i = 16; i < 40; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = &rx164_irq_type; + irq_desc[i].handler = &rx164_irq_type; } init_i8259a_irqs(); diff --git a/trunk/arch/alpha/kernel/sys_sable.c b/trunk/arch/alpha/kernel/sys_sable.c index 24dea40c9bfe..a7ff84474ace 100644 --- a/trunk/arch/alpha/kernel/sys_sable.c +++ b/trunk/arch/alpha/kernel/sys_sable.c @@ -537,7 +537,7 @@ sable_lynx_init_irq(int nr_irqs) for (i = 0; i < nr_irqs; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = &sable_lynx_irq_type; + irq_desc[i].handler = &sable_lynx_irq_type; } common_init_isa_dma(); diff --git a/trunk/arch/alpha/kernel/sys_takara.c b/trunk/arch/alpha/kernel/sys_takara.c index 2c75cd1fd81a..7955bdfc2db0 100644 --- a/trunk/arch/alpha/kernel/sys_takara.c +++ b/trunk/arch/alpha/kernel/sys_takara.c @@ -154,7 +154,7 @@ takara_init_irq(void) for (i = 16; i < 128; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = &takara_irq_type; + irq_desc[i].handler = &takara_irq_type; } common_init_isa_dma(); diff --git a/trunk/arch/alpha/kernel/sys_titan.c b/trunk/arch/alpha/kernel/sys_titan.c index 13f3ed8ed7ac..2551fb49ae09 100644 --- a/trunk/arch/alpha/kernel/sys_titan.c +++ b/trunk/arch/alpha/kernel/sys_titan.c @@ -189,7 +189,7 @@ init_titan_irqs(struct hw_interrupt_type * ops, int imin, int imax) long i; for (i = imin; i <= imax; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].chip = ops; + irq_desc[i].handler = ops; } } diff --git a/trunk/arch/alpha/kernel/sys_wildfire.c b/trunk/arch/alpha/kernel/sys_wildfire.c index 22c5798fe083..1553f470246e 100644 --- a/trunk/arch/alpha/kernel/sys_wildfire.c +++ b/trunk/arch/alpha/kernel/sys_wildfire.c @@ -199,14 +199,14 @@ wildfire_init_irq_per_pca(int qbbno, int pcano) if (i == 2) continue; irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i+irq_bias].chip = &wildfire_irq_type; + irq_desc[i+irq_bias].handler = &wildfire_irq_type; } irq_desc[36+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[36+irq_bias].chip = &wildfire_irq_type; + irq_desc[36+irq_bias].handler = &wildfire_irq_type; for (i = 40; i < 64; ++i) { irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i+irq_bias].chip = &wildfire_irq_type; + irq_desc[i+irq_bias].handler = &wildfire_irq_type; } setup_irq(32+irq_bias, &isa_enable); diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index f123c7c9fc98..3d1a3fb7d5fc 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -188,27 +188,23 @@ config ARCH_IMX config ARCH_IOP3XX bool "IOP3xx-based" - depends on MMU select PCI help Support for Intel's IOP3XX (XScale) family of processors. config ARCH_IXP4XX bool "IXP4xx-based" - depends on MMU help Support for Intel's IXP4XX (XScale) family of processors. config ARCH_IXP2000 bool "IXP2400/2800-based" - depends on MMU select PCI help Support for Intel's IXP2400/2800 (XScale) family of processors. config ARCH_IXP23XX bool "IXP23XX-based" - depends on MMU select PCI help Support for Intel's IXP23xx (XScale) family of processors. @@ -233,7 +229,6 @@ config ARCH_PNX4008 config ARCH_PXA bool "PXA2xx-based" - depends on MMU select ARCH_MTD_XIP help Support for Intel's PXA2XX processor line. @@ -344,10 +339,6 @@ config XSCALE_PMU depends on CPU_XSCALE && !XSCALE_PMU_TIMER default y -if !MMU -source "arch/arm/Kconfig-nommu" -endif - endmenu source "arch/arm/common/Kconfig" diff --git a/trunk/arch/arm/kernel/Makefile b/trunk/arch/arm/kernel/Makefile index 7cffbaef064b..a601b8b55f35 100644 --- a/trunk/arch/arm/kernel/Makefile +++ b/trunk/arch/arm/kernel/Makefile @@ -22,9 +22,6 @@ obj-$(CONFIG_PCI) += bios32.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o -obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o -AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 - obj-$(CONFIG_IWMMXT) += iwmmxt.o AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt diff --git a/trunk/arch/arm/kernel/armksyms.c b/trunk/arch/arm/kernel/armksyms.c index da69e660574b..c49b5d4d7fca 100644 --- a/trunk/arch/arm/kernel/armksyms.c +++ b/trunk/arch/arm/kernel/armksyms.c @@ -109,13 +109,11 @@ EXPORT_SYMBOL(memchr); EXPORT_SYMBOL(__memzero); /* user mem (segment) */ -EXPORT_SYMBOL(__strnlen_user); -EXPORT_SYMBOL(__strncpy_from_user); - -#ifdef CONFIG_MMU -EXPORT_SYMBOL(__copy_from_user); -EXPORT_SYMBOL(__copy_to_user); -EXPORT_SYMBOL(__clear_user); +EXPORT_SYMBOL(__arch_copy_from_user); +EXPORT_SYMBOL(__arch_copy_to_user); +EXPORT_SYMBOL(__arch_clear_user); +EXPORT_SYMBOL(__arch_strnlen_user); +EXPORT_SYMBOL(__arch_strncpy_from_user); EXPORT_SYMBOL(__get_user_1); EXPORT_SYMBOL(__get_user_2); @@ -125,7 +123,6 @@ EXPORT_SYMBOL(__put_user_1); EXPORT_SYMBOL(__put_user_2); EXPORT_SYMBOL(__put_user_4); EXPORT_SYMBOL(__put_user_8); -#endif /* crypto hash */ EXPORT_SYMBOL(sha_transform); diff --git a/trunk/arch/arm/kernel/asm-offsets.c b/trunk/arch/arm/kernel/asm-offsets.c index 447ede5143a8..396efba9bacd 100644 --- a/trunk/arch/arm/kernel/asm-offsets.c +++ b/trunk/arch/arm/kernel/asm-offsets.c @@ -59,9 +59,6 @@ int main(void) DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate)); #ifdef CONFIG_IWMMXT DEFINE(TI_IWMMXT_STATE, offsetof(struct thread_info, fpstate.iwmmxt)); -#endif -#ifdef CONFIG_CRUNCH - DEFINE(TI_CRUNCH_STATE, offsetof(struct thread_info, crunchstate)); #endif BLANK(); DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0)); diff --git a/trunk/arch/arm/kernel/crunch-bits.S b/trunk/arch/arm/kernel/crunch-bits.S deleted file mode 100644 index a26886758c67..000000000000 --- a/trunk/arch/arm/kernel/crunch-bits.S +++ /dev/null @@ -1,305 +0,0 @@ -/* - * arch/arm/kernel/crunch-bits.S - * Cirrus MaverickCrunch context switching and handling - * - * Copyright (C) 2006 Lennert Buytenhek - * - * Shamelessly stolen from the iWMMXt code by Nicolas Pitre, which is - * Copyright (c) 2003-2004, MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include - -/* - * We can't use hex constants here due to a bug in gas. - */ -#define CRUNCH_MVDX0 0 -#define CRUNCH_MVDX1 8 -#define CRUNCH_MVDX2 16 -#define CRUNCH_MVDX3 24 -#define CRUNCH_MVDX4 32 -#define CRUNCH_MVDX5 40 -#define CRUNCH_MVDX6 48 -#define CRUNCH_MVDX7 56 -#define CRUNCH_MVDX8 64 -#define CRUNCH_MVDX9 72 -#define CRUNCH_MVDX10 80 -#define CRUNCH_MVDX11 88 -#define CRUNCH_MVDX12 96 -#define CRUNCH_MVDX13 104 -#define CRUNCH_MVDX14 112 -#define CRUNCH_MVDX15 120 -#define CRUNCH_MVAX0L 128 -#define CRUNCH_MVAX0M 132 -#define CRUNCH_MVAX0H 136 -#define CRUNCH_MVAX1L 140 -#define CRUNCH_MVAX1M 144 -#define CRUNCH_MVAX1H 148 -#define CRUNCH_MVAX2L 152 -#define CRUNCH_MVAX2M 156 -#define CRUNCH_MVAX2H 160 -#define CRUNCH_MVAX3L 164 -#define CRUNCH_MVAX3M 168 -#define CRUNCH_MVAX3H 172 -#define CRUNCH_DSPSC 176 - -#define CRUNCH_SIZE 184 - - .text - -/* - * Lazy switching of crunch coprocessor context - * - * r10 = struct thread_info pointer - * r9 = ret_from_exception - * lr = undefined instr exit - * - * called from prefetch exception handler with interrupts disabled - */ -ENTRY(crunch_task_enable) - ldr r8, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr - - ldr r1, [r8, #0x80] - tst r1, #0x00800000 @ access to crunch enabled? - movne pc, lr @ if so no business here - mov r3, #0xaa @ unlock syscon swlock - str r3, [r8, #0xc0] - orr r1, r1, #0x00800000 @ enable access to crunch - str r1, [r8, #0x80] - - ldr r3, =crunch_owner - add r0, r10, #TI_CRUNCH_STATE @ get task crunch save area - ldr r2, [sp, #60] @ current task pc value - ldr r1, [r3] @ get current crunch owner - str r0, [r3] @ this task now owns crunch - sub r2, r2, #4 @ adjust pc back - str r2, [sp, #60] - - ldr r2, [r8, #0x80] - mov r2, r2 @ flush out enable (@@@) - - teq r1, #0 @ test for last ownership - mov lr, r9 @ normal exit from exception - beq crunch_load @ no owner, skip save - -crunch_save: - cfstr64 mvdx0, [r1, #CRUNCH_MVDX0] @ save 64b registers - cfstr64 mvdx1, [r1, #CRUNCH_MVDX1] - cfstr64 mvdx2, [r1, #CRUNCH_MVDX2] - cfstr64 mvdx3, [r1, #CRUNCH_MVDX3] - cfstr64 mvdx4, [r1, #CRUNCH_MVDX4] - cfstr64 mvdx5, [r1, #CRUNCH_MVDX5] - cfstr64 mvdx6, [r1, #CRUNCH_MVDX6] - cfstr64 mvdx7, [r1, #CRUNCH_MVDX7] - cfstr64 mvdx8, [r1, #CRUNCH_MVDX8] - cfstr64 mvdx9, [r1, #CRUNCH_MVDX9] - cfstr64 mvdx10, [r1, #CRUNCH_MVDX10] - cfstr64 mvdx11, [r1, #CRUNCH_MVDX11] - cfstr64 mvdx12, [r1, #CRUNCH_MVDX12] - cfstr64 mvdx13, [r1, #CRUNCH_MVDX13] - cfstr64 mvdx14, [r1, #CRUNCH_MVDX14] - cfstr64 mvdx15, [r1, #CRUNCH_MVDX15] - -#ifdef __ARMEB__ -#error fix me for ARMEB -#endif - - cfmv32al mvfx0, mvax0 @ save 72b accumulators - cfstr32 mvfx0, [r1, #CRUNCH_MVAX0L] - cfmv32am mvfx0, mvax0 - cfstr32 mvfx0, [r1, #CRUNCH_MVAX0M] - cfmv32ah mvfx0, mvax0 - cfstr32 mvfx0, [r1, #CRUNCH_MVAX0H] - cfmv32al mvfx0, mvax1 - cfstr32 mvfx0, [r1, #CRUNCH_MVAX1L] - cfmv32am mvfx0, mvax1 - cfstr32 mvfx0, [r1, #CRUNCH_MVAX1M] - cfmv32ah mvfx0, mvax1 - cfstr32 mvfx0, [r1, #CRUNCH_MVAX1H] - cfmv32al mvfx0, mvax2 - cfstr32 mvfx0, [r1, #CRUNCH_MVAX2L] - cfmv32am mvfx0, mvax2 - cfstr32 mvfx0, [r1, #CRUNCH_MVAX2M] - cfmv32ah mvfx0, mvax2 - cfstr32 mvfx0, [r1, #CRUNCH_MVAX2H] - cfmv32al mvfx0, mvax3 - cfstr32 mvfx0, [r1, #CRUNCH_MVAX3L] - cfmv32am mvfx0, mvax3 - cfstr32 mvfx0, [r1, #CRUNCH_MVAX3M] - cfmv32ah mvfx0, mvax3 - cfstr32 mvfx0, [r1, #CRUNCH_MVAX3H] - - cfmv32sc mvdx0, dspsc @ save status word - cfstr64 mvdx0, [r1, #CRUNCH_DSPSC] - - teq r0, #0 @ anything to load? - cfldr64eq mvdx0, [r1, #CRUNCH_MVDX0] @ mvdx0 was clobbered - moveq pc, lr - -crunch_load: - cfldr64 mvdx0, [r0, #CRUNCH_DSPSC] @ load status word - cfmvsc32 dspsc, mvdx0 - - cfldr32 mvfx0, [r0, #CRUNCH_MVAX0L] @ load 72b accumulators - cfmval32 mvax0, mvfx0 - cfldr32 mvfx0, [r0, #CRUNCH_MVAX0M] - cfmvam32 mvax0, mvfx0 - cfldr32 mvfx0, [r0, #CRUNCH_MVAX0H] - cfmvah32 mvax0, mvfx0 - cfldr32 mvfx0, [r0, #CRUNCH_MVAX1L] - cfmval32 mvax1, mvfx0 - cfldr32 mvfx0, [r0, #CRUNCH_MVAX1M] - cfmvam32 mvax1, mvfx0 - cfldr32 mvfx0, [r0, #CRUNCH_MVAX1H] - cfmvah32 mvax1, mvfx0 - cfldr32 mvfx0, [r0, #CRUNCH_MVAX2L] - cfmval32 mvax2, mvfx0 - cfldr32 mvfx0, [r0, #CRUNCH_MVAX2M] - cfmvam32 mvax2, mvfx0 - cfldr32 mvfx0, [r0, #CRUNCH_MVAX2H] - cfmvah32 mvax2, mvfx0 - cfldr32 mvfx0, [r0, #CRUNCH_MVAX3L] - cfmval32 mvax3, mvfx0 - cfldr32 mvfx0, [r0, #CRUNCH_MVAX3M] - cfmvam32 mvax3, mvfx0 - cfldr32 mvfx0, [r0, #CRUNCH_MVAX3H] - cfmvah32 mvax3, mvfx0 - - cfldr64 mvdx0, [r0, #CRUNCH_MVDX0] @ load 64b registers - cfldr64 mvdx1, [r0, #CRUNCH_MVDX1] - cfldr64 mvdx2, [r0, #CRUNCH_MVDX2] - cfldr64 mvdx3, [r0, #CRUNCH_MVDX3] - cfldr64 mvdx4, [r0, #CRUNCH_MVDX4] - cfldr64 mvdx5, [r0, #CRUNCH_MVDX5] - cfldr64 mvdx6, [r0, #CRUNCH_MVDX6] - cfldr64 mvdx7, [r0, #CRUNCH_MVDX7] - cfldr64 mvdx8, [r0, #CRUNCH_MVDX8] - cfldr64 mvdx9, [r0, #CRUNCH_MVDX9] - cfldr64 mvdx10, [r0, #CRUNCH_MVDX10] - cfldr64 mvdx11, [r0, #CRUNCH_MVDX11] - cfldr64 mvdx12, [r0, #CRUNCH_MVDX12] - cfldr64 mvdx13, [r0, #CRUNCH_MVDX13] - cfldr64 mvdx14, [r0, #CRUNCH_MVDX14] - cfldr64 mvdx15, [r0, #CRUNCH_MVDX15] - - mov pc, lr - -/* - * Back up crunch regs to save area and disable access to them - * (mainly for gdb or sleep mode usage) - * - * r0 = struct thread_info pointer of target task or NULL for any - */ -ENTRY(crunch_task_disable) - stmfd sp!, {r4, r5, lr} - - mrs ip, cpsr - orr r2, ip, #PSR_I_BIT @ disable interrupts - msr cpsr_c, r2 - - ldr r4, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr - - ldr r3, =crunch_owner - add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area - ldr r1, [r3] @ get current crunch owner - teq r1, #0 @ any current owner? - beq 1f @ no: quit - teq r0, #0 @ any owner? - teqne r1, r2 @ or specified one? - bne 1f @ no: quit - - ldr r5, [r4, #0x80] @ enable access to crunch - mov r2, #0xaa - str r2, [r4, #0xc0] - orr r5, r5, #0x00800000 - str r5, [r4, #0x80] - - mov r0, #0 @ nothing to load - str r0, [r3] @ no more current owner - ldr r2, [r4, #0x80] @ flush out enable (@@@) - mov r2, r2 - bl crunch_save - - mov r2, #0xaa @ disable access to crunch - str r2, [r4, #0xc0] - bic r5, r5, #0x00800000 - str r5, [r4, #0x80] - ldr r5, [r4, #0x80] @ flush out enable (@@@) - mov r5, r5 - -1: msr cpsr_c, ip @ restore interrupt mode - ldmfd sp!, {r4, r5, pc} - -/* - * Copy crunch state to given memory address - * - * r0 = struct thread_info pointer of target task - * r1 = memory address where to store crunch state - * - * this is called mainly in the creation of signal stack frames - */ -ENTRY(crunch_task_copy) - mrs ip, cpsr - orr r2, ip, #PSR_I_BIT @ disable interrupts - msr cpsr_c, r2 - - ldr r3, =crunch_owner - add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area - ldr r3, [r3] @ get current crunch owner - teq r2, r3 @ does this task own it... - beq 1f - - @ current crunch values are in the task save area - msr cpsr_c, ip @ restore interrupt mode - mov r0, r1 - mov r1, r2 - mov r2, #CRUNCH_SIZE - b memcpy - -1: @ this task owns crunch regs -- grab a copy from there - mov r0, #0 @ nothing to load - mov r3, lr @ preserve return address - bl crunch_save - msr cpsr_c, ip @ restore interrupt mode - mov pc, r3 - -/* - * Restore crunch state from given memory address - * - * r0 = struct thread_info pointer of target task - * r1 = memory address where to get crunch state from - * - * this is used to restore crunch state when unwinding a signal stack frame - */ -ENTRY(crunch_task_restore) - mrs ip, cpsr - orr r2, ip, #PSR_I_BIT @ disable interrupts - msr cpsr_c, r2 - - ldr r3, =crunch_owner - add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area - ldr r3, [r3] @ get current crunch owner - teq r2, r3 @ does this task own it... - beq 1f - - @ this task doesn't own crunch regs -- use its save area - msr cpsr_c, ip @ restore interrupt mode - mov r0, r2 - mov r2, #CRUNCH_SIZE - b memcpy - -1: @ this task owns crunch regs -- load them directly - mov r0, r1 - mov r1, #0 @ nothing to save - mov r3, lr @ preserve return address - bl crunch_load - msr cpsr_c, ip @ restore interrupt mode - mov pc, r3 diff --git a/trunk/arch/arm/kernel/crunch.c b/trunk/arch/arm/kernel/crunch.c deleted file mode 100644 index 748175921f9b..000000000000 --- a/trunk/arch/arm/kernel/crunch.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * arch/arm/kernel/crunch.c - * Cirrus MaverickCrunch context switching and handling - * - * Copyright (C) 2006 Lennert Buytenhek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct crunch_state *crunch_owner; - -void crunch_task_release(struct thread_info *thread) -{ - local_irq_disable(); - if (crunch_owner == &thread->crunchstate) - crunch_owner = NULL; - local_irq_enable(); -} - -static int crunch_enabled(u32 devcfg) -{ - return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE); -} - -static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) -{ - struct thread_info *thread = (struct thread_info *)t; - struct crunch_state *crunch_state; - u32 devcfg; - - crunch_state = &thread->crunchstate; - - switch (cmd) { - case THREAD_NOTIFY_FLUSH: - memset(crunch_state, 0, sizeof(*crunch_state)); - - /* - * FALLTHROUGH: Ensure we don't try to overwrite our newly - * initialised state information on the first fault. - */ - - case THREAD_NOTIFY_RELEASE: - crunch_task_release(thread); - break; - - case THREAD_NOTIFY_SWITCH: - devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); - if (crunch_enabled(devcfg) || crunch_owner == crunch_state) { - devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; - __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); - __raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG); - } - break; - } - - return NOTIFY_DONE; -} - -static struct notifier_block crunch_notifier_block = { - .notifier_call = crunch_do, -}; - -static int __init crunch_init(void) -{ - thread_register_notifier(&crunch_notifier_block); - - return 0; -} - -late_initcall(crunch_init); diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index 6423a38839b8..86c92523a346 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -492,15 +492,9 @@ call_fpe: b do_fpe @ CP#1 (FPE) b do_fpe @ CP#2 (FPE) mov pc, lr @ CP#3 -#ifdef CONFIG_CRUNCH - b crunch_task_enable @ CP#4 (MaverickCrunch) - b crunch_task_enable @ CP#5 (MaverickCrunch) - b crunch_task_enable @ CP#6 (MaverickCrunch) -#else mov pc, lr @ CP#4 mov pc, lr @ CP#5 mov pc, lr @ CP#6 -#endif mov pc, lr @ CP#7 mov pc, lr @ CP#8 mov pc, lr @ CP#9 diff --git a/trunk/arch/arm/kernel/ptrace.c b/trunk/arch/arm/kernel/ptrace.c index c40bdc770054..a1d1b2906e8d 100644 --- a/trunk/arch/arm/kernel/ptrace.c +++ b/trunk/arch/arm/kernel/ptrace.c @@ -634,32 +634,6 @@ static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp) #endif -#ifdef CONFIG_CRUNCH -/* - * Get the child Crunch state. - */ -static int ptrace_getcrunchregs(struct task_struct *tsk, void __user *ufp) -{ - struct thread_info *thread = task_thread_info(tsk); - - crunch_task_disable(thread); /* force it to ram */ - return copy_to_user(ufp, &thread->crunchstate, CRUNCH_SIZE) - ? -EFAULT : 0; -} - -/* - * Set the child Crunch state. - */ -static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp) -{ - struct thread_info *thread = task_thread_info(tsk); - - crunch_task_release(thread); /* force a reload */ - return copy_from_user(&thread->crunchstate, ufp, CRUNCH_SIZE) - ? -EFAULT : 0; -} -#endif - long arch_ptrace(struct task_struct *child, long request, long addr, long data) { unsigned long tmp; @@ -791,16 +765,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) child->ptrace_message = data; break; -#ifdef CONFIG_CRUNCH - case PTRACE_GETCRUNCHREGS: - ret = ptrace_getcrunchregs(child, (void __user *)data); - break; - - case PTRACE_SETCRUNCHREGS: - ret = ptrace_setcrunchregs(child, (void __user *)data); - break; -#endif - default: ret = ptrace_request(child, request, addr, data); break; diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index 093ccba0503c..d69412728854 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -119,9 +119,24 @@ DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data); * Standard memory resources */ static struct resource mem_res[] = { - { "Video RAM", 0, 0, IORESOURCE_MEM }, - { "Kernel text", 0, 0, IORESOURCE_MEM }, - { "Kernel data", 0, 0, IORESOURCE_MEM } + { + .name = "Video RAM", + .start = 0, + .end = 0, + .flags = IORESOURCE_MEM + }, + { + .name = "Kernel text", + .start = 0, + .end = 0, + .flags = IORESOURCE_MEM + }, + { + .name = "Kernel data", + .start = 0, + .end = 0, + .flags = IORESOURCE_MEM + } }; #define video_ram mem_res[0] @@ -129,9 +144,24 @@ static struct resource mem_res[] = { #define kernel_data mem_res[2] static struct resource io_res[] = { - { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY }, - { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY }, - { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY } + { + .name = "reserved", + .start = 0x3bc, + .end = 0x3be, + .flags = IORESOURCE_IO | IORESOURCE_BUSY + }, + { + .name = "reserved", + .start = 0x378, + .end = 0x37f, + .flags = IORESOURCE_IO | IORESOURCE_BUSY + }, + { + .name = "reserved", + .start = 0x278, + .end = 0x27f, + .flags = IORESOURCE_IO | IORESOURCE_BUSY + } }; #define lp0 io_res[0] @@ -808,7 +838,7 @@ static int __init topology_init(void) int cpu; for_each_possible_cpu(cpu) - register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu); + register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL); return 0; } diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c index 83a8d3c95eb3..1ce05ec086c6 100644 --- a/trunk/arch/arm/kernel/signal.c +++ b/trunk/arch/arm/kernel/signal.c @@ -132,37 +132,6 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, return ret; } -#ifdef CONFIG_CRUNCH -static int preserve_crunch_context(struct crunch_sigframe *frame) -{ - char kbuf[sizeof(*frame) + 8]; - struct crunch_sigframe *kframe; - - /* the crunch context must be 64 bit aligned */ - kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7); - kframe->magic = CRUNCH_MAGIC; - kframe->size = CRUNCH_STORAGE_SIZE; - crunch_task_copy(current_thread_info(), &kframe->storage); - return __copy_to_user(frame, kframe, sizeof(*frame)); -} - -static int restore_crunch_context(struct crunch_sigframe *frame) -{ - char kbuf[sizeof(*frame) + 8]; - struct crunch_sigframe *kframe; - - /* the crunch context must be 64 bit aligned */ - kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7); - if (__copy_from_user(kframe, frame, sizeof(*frame))) - return -1; - if (kframe->magic != CRUNCH_MAGIC || - kframe->size != CRUNCH_STORAGE_SIZE) - return -1; - crunch_task_restore(current_thread_info(), &kframe->storage); - return 0; -} -#endif - #ifdef CONFIG_IWMMXT static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) @@ -245,10 +214,6 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) err |= !valid_user_regs(regs); aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; -#ifdef CONFIG_CRUNCH - if (err == 0) - err |= restore_crunch_context(&aux->crunch); -#endif #ifdef CONFIG_IWMMXT if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) err |= restore_iwmmxt_context(&aux->iwmmxt); @@ -368,10 +333,6 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; -#ifdef CONFIG_CRUNCH - if (err == 0) - err |= preserve_crunch_context(&aux->crunch); -#endif #ifdef CONFIG_IWMMXT if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) err |= preserve_iwmmxt_context(&aux->iwmmxt); diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S index 2df9688a7028..2b254e88595c 100644 --- a/trunk/arch/arm/kernel/vmlinux.lds.S +++ b/trunk/arch/arm/kernel/vmlinux.lds.S @@ -80,10 +80,6 @@ SECTIONS *(.exit.text) *(.exit.data) *(.exitcall.exit) -#ifndef CONFIG_MMU - *(.fixup) - *(__ex_table) -#endif } .text : { /* Real text segment */ @@ -91,9 +87,7 @@ SECTIONS *(.text) SCHED_TEXT LOCK_TEXT -#ifdef CONFIG_MMU *(.fixup) -#endif *(.gnu.warning) *(.rodata) *(.rodata.*) @@ -148,9 +142,7 @@ SECTIONS */ . = ALIGN(32); __start___ex_table = .; -#ifdef CONFIG_MMU *(__ex_table) -#endif __stop___ex_table = .; /* diff --git a/trunk/arch/arm/lib/Makefile b/trunk/arch/arm/lib/Makefile index 30351cd4560d..7b726b627ea5 100644 --- a/trunk/arch/arm/lib/Makefile +++ b/trunk/arch/arm/lib/Makefile @@ -6,31 +6,28 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ csumpartialcopy.o csumpartialcopyuser.o clearbit.o \ - delay.o findbit.o memchr.o memcpy.o \ + copy_page.o delay.o findbit.o memchr.o memcpy.o \ memmove.o memset.o memzero.o setbit.o \ strncpy_from_user.o strnlen_user.o \ strchr.o strrchr.o \ testchangebit.o testclearbit.o testsetbit.o \ + getuser.o putuser.o clear_user.o \ ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ ucmpdi2.o lib1funcs.o div64.o sha1.o \ io-readsb.o io-writesb.o io-readsl.o io-writesl.o -mmu-y := clear_user.o copy_page.o getuser.o putuser.o - # the code in uaccess.S is not preemption safe and # probably faster on ARMv3 only ifeq ($(CONFIG_PREEMPT),y) - mmu-y += copy_from_user.o copy_to_user.o + lib-y += copy_from_user.o copy_to_user.o else ifneq ($(CONFIG_CPU_32v3),y) - mmu-y += copy_from_user.o copy_to_user.o + lib-y += copy_from_user.o copy_to_user.o else - mmu-y += uaccess.o + lib-y += uaccess.o endif endif -lib-$(CONFIG_MMU) += $(mmu-y) - ifeq ($(CONFIG_CPU_32v3),y) lib-y += io-readsw-armv3.o io-writesw-armv3.o else diff --git a/trunk/arch/arm/lib/backtrace.S b/trunk/arch/arm/lib/backtrace.S index 91f993f2e9db..058b80d72aa1 100644 --- a/trunk/arch/arm/lib/backtrace.S +++ b/trunk/arch/arm/lib/backtrace.S @@ -97,13 +97,16 @@ ENTRY(c_backtrace) b 1007f /* - * Fixup for LDMDB. Note that this must not be in the fixup section. + * Fixup for LDMDB */ + .section .fixup,"ax" + .align 0 1007: ldr r0, =.Lbad mov r1, frame bl printk ldmfd sp!, {r4 - r8, pc} .ltorg + .previous .section __ex_table,"a" .align 3 diff --git a/trunk/arch/arm/lib/clear_user.S b/trunk/arch/arm/lib/clear_user.S index ecb28dcdaf7b..ea435ae2e4a5 100644 --- a/trunk/arch/arm/lib/clear_user.S +++ b/trunk/arch/arm/lib/clear_user.S @@ -12,13 +12,13 @@ .text -/* Prototype: int __clear_user(void *addr, size_t sz) +/* Prototype: int __arch_clear_user(void *addr, size_t sz) * Purpose : clear some user memory * Params : addr - user memory address to clear * : sz - number of bytes to clear * Returns : number of bytes NOT cleared */ -ENTRY(__clear_user) +ENTRY(__arch_clear_user) stmfd sp!, {r1, lr} mov r2, #0 cmp r1, #4 diff --git a/trunk/arch/arm/lib/copy_from_user.S b/trunk/arch/arm/lib/copy_from_user.S index 6b7363ce749c..7497393a0e81 100644 --- a/trunk/arch/arm/lib/copy_from_user.S +++ b/trunk/arch/arm/lib/copy_from_user.S @@ -16,7 +16,7 @@ /* * Prototype: * - * size_t __copy_from_user(void *to, const void *from, size_t n) + * size_t __arch_copy_from_user(void *to, const void *from, size_t n) * * Purpose: * @@ -83,7 +83,7 @@ .text -ENTRY(__copy_from_user) +ENTRY(__arch_copy_from_user) #include "copy_template.S" diff --git a/trunk/arch/arm/lib/copy_to_user.S b/trunk/arch/arm/lib/copy_to_user.S index 5224d94688d9..4a6d8ea14022 100644 --- a/trunk/arch/arm/lib/copy_to_user.S +++ b/trunk/arch/arm/lib/copy_to_user.S @@ -16,7 +16,7 @@ /* * Prototype: * - * size_t __copy_to_user(void *to, const void *from, size_t n) + * size_t __arch_copy_to_user(void *to, const void *from, size_t n) * * Purpose: * @@ -86,7 +86,7 @@ .text -ENTRY(__copy_to_user) +ENTRY(__arch_copy_to_user) #include "copy_template.S" diff --git a/trunk/arch/arm/lib/strncpy_from_user.S b/trunk/arch/arm/lib/strncpy_from_user.S index 36e3741a3772..35649f04fcac 100644 --- a/trunk/arch/arm/lib/strncpy_from_user.S +++ b/trunk/arch/arm/lib/strncpy_from_user.S @@ -20,7 +20,7 @@ * returns the number of characters copied (strlen of copied string), * -EFAULT on exception, or "len" if we fill the whole buffer */ -ENTRY(__strncpy_from_user) +ENTRY(__arch_strncpy_from_user) mov ip, r1 1: subs r2, r2, #1 USER( ldrplbt r3, [r1], #1) diff --git a/trunk/arch/arm/lib/strnlen_user.S b/trunk/arch/arm/lib/strnlen_user.S index 18d8fa4f925a..3668a15991ef 100644 --- a/trunk/arch/arm/lib/strnlen_user.S +++ b/trunk/arch/arm/lib/strnlen_user.S @@ -14,13 +14,13 @@ .text .align 5 -/* Prototype: unsigned long __strnlen_user(const char *str, long n) +/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n) * Purpose : get length of a string in user memory * Params : str - address of string in user memory * Returns : length of string *including terminator* * or zero on exception, or n + 1 if too long */ -ENTRY(__strnlen_user) +ENTRY(__arch_strnlen_user) mov r2, r0 1: USER( ldrbt r3, [r0], #1) diff --git a/trunk/arch/arm/lib/uaccess.S b/trunk/arch/arm/lib/uaccess.S index b48bd6d5fd83..1f1545d737be 100644 --- a/trunk/arch/arm/lib/uaccess.S +++ b/trunk/arch/arm/lib/uaccess.S @@ -19,7 +19,7 @@ #define PAGE_SHIFT 12 -/* Prototype: int __copy_to_user(void *to, const char *from, size_t n) +/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n) * Purpose : copy a block to user memory from kernel memory * Params : to - user memory * : from - kernel memory @@ -39,7 +39,7 @@ USER( strgtbt r3, [r0], #1) @ May fault sub r2, r2, ip b .Lc2u_dest_aligned -ENTRY(__copy_to_user) +ENTRY(__arch_copy_to_user) stmfd sp!, {r2, r4 - r7, lr} cmp r2, #4 blt .Lc2u_not_enough @@ -283,7 +283,7 @@ USER( strgtbt r3, [r0], #1) @ May fault 9001: ldmfd sp!, {r0, r4 - r7, pc} .previous -/* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n); +/* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n); * Purpose : copy a block from user memory to kernel memory * Params : to - kernel memory * : from - user memory @@ -302,7 +302,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault sub r2, r2, ip b .Lcfu_dest_aligned -ENTRY(__copy_from_user) +ENTRY(__arch_copy_from_user) stmfd sp!, {r0, r2, r4 - r7, lr} cmp r2, #4 blt .Lcfu_not_enough diff --git a/trunk/arch/arm/mach-ep93xx/Kconfig b/trunk/arch/arm/mach-ep93xx/Kconfig index e15e4c54a253..cec5a21ca4e3 100644 --- a/trunk/arch/arm/mach-ep93xx/Kconfig +++ b/trunk/arch/arm/mach-ep93xx/Kconfig @@ -2,19 +2,8 @@ if ARCH_EP93XX menu "Cirrus EP93xx Implementation Options" -config CRUNCH - bool "Support for MaverickCrunch" - help - Enable kernel support for MaverickCrunch. - comment "EP93xx Platforms" -config MACH_EDB9315 - bool "Support Cirrus Logic EDB9315" - help - Say 'Y' here if you want your kernel to support the Cirrus - Logic EDB9315 Evaluation Board. - config MACH_GESBC9312 bool "Support Glomation GESBC-9312-sx" help diff --git a/trunk/arch/arm/mach-ep93xx/Makefile b/trunk/arch/arm/mach-ep93xx/Makefile index dfa7e2e8a18b..05a48a21038e 100644 --- a/trunk/arch/arm/mach-ep93xx/Makefile +++ b/trunk/arch/arm/mach-ep93xx/Makefile @@ -6,6 +6,5 @@ obj-m := obj-n := obj- := -obj-$(CONFIG_MACH_EDB9315) += edb9315.o obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o obj-$(CONFIG_MACH_TS72XX) += ts72xx.o diff --git a/trunk/arch/arm/mach-ep93xx/edb9315.c b/trunk/arch/arm/mach-ep93xx/edb9315.c deleted file mode 100644 index ef7482faad81..000000000000 --- a/trunk/arch/arm/mach-ep93xx/edb9315.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * arch/arm/mach-ep93xx/edb9315.c - * Cirrus Logic EDB9315 support. - * - * Copyright (C) 2006 Lennert Buytenhek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or (at - * your option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct physmap_flash_data edb9315_flash_data = { - .width = 4, -}; - -static struct resource edb9315_flash_resource = { - .start = 0x60000000, - .end = 0x61ffffff, - .flags = IORESOURCE_MEM, -}; - -static struct platform_device edb9315_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &edb9315_flash_data, - }, - .num_resources = 1, - .resource = &edb9315_flash_resource, -}; - -static void __init edb9315_init_machine(void) -{ - ep93xx_init_devices(); - platform_device_register(&edb9315_flash); -} - -MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board") - /* Maintainer: Lennert Buytenhek */ - .phys_io = EP93XX_APB_PHYS_BASE, - .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, - .boot_params = 0x00000100, - .map_io = ep93xx_map_io, - .init_irq = ep93xx_init_irq, - .timer = &ep93xx_timer, - .init_machine = edb9315_init_machine, -MACHINE_END diff --git a/trunk/arch/arm/mach-ep93xx/gesbc9312.c b/trunk/arch/arm/mach-ep93xx/gesbc9312.c index 2c28d66d260e..47cc6c8b7c79 100644 --- a/trunk/arch/arm/mach-ep93xx/gesbc9312.c +++ b/trunk/arch/arm/mach-ep93xx/gesbc9312.c @@ -30,7 +30,7 @@ static struct physmap_flash_data gesbc9312_flash_data = { static struct resource gesbc9312_flash_resource = { .start = 0x60000000, - .end = 0x607fffff, + .end = 0x60800000, .flags = IORESOURCE_MEM, }; diff --git a/trunk/arch/arm/mach-ep93xx/ts72xx.c b/trunk/arch/arm/mach-ep93xx/ts72xx.c index 0b3b875b1875..6e5a56cd5ae8 100644 --- a/trunk/arch/arm/mach-ep93xx/ts72xx.c +++ b/trunk/arch/arm/mach-ep93xx/ts72xx.c @@ -118,7 +118,7 @@ static struct physmap_flash_data ts72xx_flash_data = { static struct resource ts72xx_flash_resource = { .start = TS72XX_NOR_PHYS_BASE, - .end = TS72XX_NOR_PHYS_BASE + 0x00ffffff, + .end = TS72XX_NOR_PHYS_BASE + 0x01000000, .flags = IORESOURCE_MEM, }; diff --git a/trunk/arch/arm/mach-ixp23xx/espresso.c b/trunk/arch/arm/mach-ixp23xx/espresso.c index 357351fbb1e2..dc5e489c70bc 100644 --- a/trunk/arch/arm/mach-ixp23xx/espresso.c +++ b/trunk/arch/arm/mach-ixp23xx/espresso.c @@ -59,7 +59,7 @@ static struct physmap_flash_data espresso_flash_data = { static struct resource espresso_flash_resource = { .start = 0x90000000, - .end = 0x91ffffff, + .end = 0x92000000, .flags = IORESOURCE_MEM, }; diff --git a/trunk/arch/arm/mach-ixp23xx/ixdp2351.c b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c index e0886871cc77..535b334ee045 100644 --- a/trunk/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c @@ -304,7 +304,7 @@ static struct physmap_flash_data ixdp2351_flash_data = { static struct resource ixdp2351_flash_resource = { .start = 0x90000000, - .end = 0x93ffffff, + .end = 0x94000000, .flags = IORESOURCE_MEM, }; diff --git a/trunk/arch/arm/mach-ixp23xx/roadrunner.c b/trunk/arch/arm/mach-ixp23xx/roadrunner.c index 92ad18f41251..b9f5d13fcfe1 100644 --- a/trunk/arch/arm/mach-ixp23xx/roadrunner.c +++ b/trunk/arch/arm/mach-ixp23xx/roadrunner.c @@ -143,7 +143,7 @@ static struct physmap_flash_data roadrunner_flash_data = { static struct resource roadrunner_flash_resource = { .start = 0x90000000, - .end = 0x93ffffff, + .end = 0x94000000, .flags = IORESOURCE_MEM, }; diff --git a/trunk/arch/arm/mach-pxa/irq.c b/trunk/arch/arm/mach-pxa/irq.c index d9635ff4b10c..539b596005fc 100644 --- a/trunk/arch/arm/mach-pxa/irq.c +++ b/trunk/arch/arm/mach-pxa/irq.c @@ -88,8 +88,8 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) if (type == IRQT_PROBE) { /* Don't mess with enabled GPIOs using preconfigured edges or - GPIOs set to alternate function or to output during probe */ - if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx] | GPDR(gpio)) & + GPIOs set to alternate function during probe */ + if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) & GPIO_bit(gpio)) return 0; if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2))) diff --git a/trunk/arch/arm/mach-s3c2410/s3c244x.c b/trunk/arch/arm/mach-s3c2410/s3c244x.c index 9a2258270de9..838bc525e836 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c244x.c +++ b/trunk/arch/arm/mach-s3c2410/s3c244x.c @@ -69,7 +69,6 @@ void __init s3c244x_map_io(struct map_desc *mach_desc, int size) s3c_device_i2c.name = "s3c2440-i2c"; s3c_device_nand.name = "s3c2440-nand"; - s3c_device_usbgadget.name = "s3c2440-usbgadget"; } void __init s3c244x_init_clocks(int xtal) diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index c4bca753165b..ecf5e232a6fc 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -15,8 +15,8 @@ config CPU_ARM610 select CPU_32v3 select CPU_CACHE_V3 select CPU_CACHE_VIVT - select CPU_COPY_V3 if MMU - select CPU_TLB_V3 if MMU + select CPU_COPY_V3 + select CPU_TLB_V3 help The ARM610 is the successor to the ARM3 processor and was produced by VLSI Technology Inc. @@ -31,8 +31,8 @@ config CPU_ARM710 select CPU_32v3 select CPU_CACHE_V3 select CPU_CACHE_VIVT - select CPU_COPY_V3 if MMU - select CPU_TLB_V3 if MMU + select CPU_COPY_V3 + select CPU_TLB_V3 help A 32-bit RISC microprocessor based on the ARM7 processor core designed by Advanced RISC Machines Ltd. The ARM710 is the @@ -50,8 +50,8 @@ config CPU_ARM720T select CPU_ABRT_LV4T select CPU_CACHE_V4 select CPU_CACHE_VIVT - select CPU_COPY_V4WT if MMU - select CPU_TLB_V4WT if MMU + select CPU_COPY_V4WT + select CPU_TLB_V4WT help A 32-bit RISC processor with 8kByte Cache, Write Buffer and MMU built around an ARM7TDMI core. @@ -68,8 +68,8 @@ config CPU_ARM920T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB if MMU - select CPU_TLB_V4WBI if MMU + select CPU_COPY_V4WB + select CPU_TLB_V4WBI help The ARM920T is licensed to be produced by numerous vendors, and is used in the Maverick EP9312 and the Samsung S3C2410. @@ -89,8 +89,8 @@ config CPU_ARM922T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB if MMU - select CPU_TLB_V4WBI if MMU + select CPU_COPY_V4WB + select CPU_TLB_V4WBI help The ARM922T is a version of the ARM920T, but with smaller instruction and data caches. It is used in Altera's @@ -108,8 +108,8 @@ config CPU_ARM925T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB if MMU - select CPU_TLB_V4WBI if MMU + select CPU_COPY_V4WB + select CPU_TLB_V4WBI help The ARM925T is a mix between the ARM920T and ARM926T, but with different instruction and data caches. It is used in TI's OMAP @@ -126,8 +126,8 @@ config CPU_ARM926T select CPU_32v5 select CPU_ABRT_EV5TJ select CPU_CACHE_VIVT - select CPU_COPY_V4WB if MMU - select CPU_TLB_V4WBI if MMU + select CPU_COPY_V4WB + select CPU_TLB_V4WBI help This is a variant of the ARM920. It has slightly different instruction sequences for cache and TLB operations. Curiously, @@ -144,8 +144,8 @@ config CPU_ARM1020 select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB if MMU - select CPU_TLB_V4WBI if MMU + select CPU_COPY_V4WB + select CPU_TLB_V4WBI help The ARM1020 is the 32K cached version of the ARM10 processor, with an addition of a floating-point unit. @@ -161,8 +161,8 @@ config CPU_ARM1020E select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB if MMU - select CPU_TLB_V4WBI if MMU + select CPU_COPY_V4WB + select CPU_TLB_V4WBI depends on n # ARM1022E @@ -172,8 +172,8 @@ config CPU_ARM1022 select CPU_32v5 select CPU_ABRT_EV4T select CPU_CACHE_VIVT - select CPU_COPY_V4WB if MMU # can probably do better - select CPU_TLB_V4WBI if MMU + select CPU_COPY_V4WB # can probably do better + select CPU_TLB_V4WBI help The ARM1022E is an implementation of the ARMv5TE architecture based upon the ARM10 integer core with a 16KiB L1 Harvard cache, @@ -189,8 +189,8 @@ config CPU_ARM1026 select CPU_32v5 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10 select CPU_CACHE_VIVT - select CPU_COPY_V4WB if MMU # can probably do better - select CPU_TLB_V4WBI if MMU + select CPU_COPY_V4WB # can probably do better + select CPU_TLB_V4WBI help The ARM1026EJ-S is an implementation of the ARMv5TEJ architecture based upon the ARM10 integer core. @@ -207,8 +207,8 @@ config CPU_SA110 select CPU_ABRT_EV4 select CPU_CACHE_V4WB select CPU_CACHE_VIVT - select CPU_COPY_V4WB if MMU - select CPU_TLB_V4WB if MMU + select CPU_COPY_V4WB + select CPU_TLB_V4WB help The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and is available at five speeds ranging from 100 MHz to 233 MHz. @@ -227,7 +227,7 @@ config CPU_SA1100 select CPU_ABRT_EV4 select CPU_CACHE_V4WB select CPU_CACHE_VIVT - select CPU_TLB_V4WB if MMU + select CPU_TLB_V4WB # XScale config CPU_XSCALE @@ -237,7 +237,7 @@ config CPU_XSCALE select CPU_32v5 select CPU_ABRT_EV5T select CPU_CACHE_VIVT - select CPU_TLB_V4WBI if MMU + select CPU_TLB_V4WBI # XScale Core Version 3 config CPU_XSC3 @@ -247,7 +247,7 @@ config CPU_XSC3 select CPU_32v5 select CPU_ABRT_EV5T select CPU_CACHE_VIVT - select CPU_TLB_V4WBI if MMU + select CPU_TLB_V4WBI select IO_36 # ARMv6 @@ -258,8 +258,8 @@ config CPU_V6 select CPU_ABRT_EV6 select CPU_CACHE_V6 select CPU_CACHE_VIPT - select CPU_COPY_V6 if MMU - select CPU_TLB_V6 if MMU + select CPU_COPY_V6 + select CPU_TLB_V6 # ARMv6k config CPU_32v6K @@ -277,17 +277,17 @@ config CPU_32v6K # This defines the compiler instruction set which depends on the machine type. config CPU_32v3 bool - select TLS_REG_EMUL if SMP || !MMU + select TLS_REG_EMUL if SMP select NEEDS_SYSCALL_FOR_CMPXCHG if SMP config CPU_32v4 bool - select TLS_REG_EMUL if SMP || !MMU + select TLS_REG_EMUL if SMP select NEEDS_SYSCALL_FOR_CMPXCHG if SMP config CPU_32v5 bool - select TLS_REG_EMUL if SMP || !MMU + select TLS_REG_EMUL if SMP select NEEDS_SYSCALL_FOR_CMPXCHG if SMP config CPU_32v6 @@ -334,7 +334,6 @@ config CPU_CACHE_VIVT config CPU_CACHE_VIPT bool -if MMU # The copy-page model config CPU_COPY_V3 bool @@ -373,8 +372,6 @@ config CPU_TLB_V4WBI config CPU_TLB_V6 bool -endif - # # CPU supports 36-bit I/O # diff --git a/trunk/arch/arm/mm/Makefile b/trunk/arch/arm/mm/Makefile index 21a2770226ee..07a538505784 100644 --- a/trunk/arch/arm/mm/Makefile +++ b/trunk/arch/arm/mm/Makefile @@ -2,16 +2,10 @@ # Makefile for the linux arm-specific parts of the memory manager. # -obj-y := consistent.o extable.o fault.o init.o \ - iomap.o - -obj-$(CONFIG_MMU) += fault-armv.o flush.o ioremap.o mmap.o \ +obj-y := consistent.o extable.o fault-armv.o \ + fault.o flush.o init.o ioremap.o mmap.o \ mm-armv.o -ifneq ($(CONFIG_MMU),y) -obj-y += nommu.o -endif - obj-$(CONFIG_MODULES) += proc-syms.o obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index 989fd681c822..9ea1f87a7079 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -26,6 +26,8 @@ #include #include +#define TABLE_SIZE (2 * PTRS_PER_PTE * sizeof(pte_t)) + DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; diff --git a/trunk/arch/arm/mm/iomap.c b/trunk/arch/arm/mm/iomap.c deleted file mode 100644 index 62066f3020c8..000000000000 --- a/trunk/arch/arm/mm/iomap.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * linux/arch/arm/mm/iomap.c - * - * Map IO port and PCI memory spaces so that {read,write}[bwl] can - * be used to access this memory. - */ -#include -#include -#include - -#include - -#ifdef __io -void __iomem *ioport_map(unsigned long port, unsigned int nr) -{ - return __io(port); -} -EXPORT_SYMBOL(ioport_map); - -void ioport_unmap(void __iomem *addr) -{ -} -EXPORT_SYMBOL(ioport_unmap); -#endif - -#ifdef CONFIG_PCI -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 (maxlen && len > maxlen) - len = maxlen; - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) { - if (flags & IORESOURCE_CACHEABLE) - return ioremap(start, len); - return ioremap_nocache(start, len); - } - return NULL; -} -EXPORT_SYMBOL(pci_iomap); - -void pci_iounmap(struct pci_dev *dev, void __iomem *addr) -{ - if ((unsigned long)addr >= VMALLOC_START && - (unsigned long)addr < VMALLOC_END) - iounmap(addr); -} -EXPORT_SYMBOL(pci_iounmap); -#endif diff --git a/trunk/arch/arm/mm/ioremap.c b/trunk/arch/arm/mm/ioremap.c index 7691cfdba567..c1f7180c7bed 100644 --- a/trunk/arch/arm/mm/ioremap.c +++ b/trunk/arch/arm/mm/ioremap.c @@ -176,3 +176,50 @@ void __iounmap(void __iomem *addr) vunmap((void *)(PAGE_MASK & (unsigned long)addr)); } EXPORT_SYMBOL(__iounmap); + +#ifdef __io +void __iomem *ioport_map(unsigned long port, unsigned int nr) +{ + return __io(port); +} +EXPORT_SYMBOL(ioport_map); + +void ioport_unmap(void __iomem *addr) +{ +} +EXPORT_SYMBOL(ioport_unmap); +#endif + +#ifdef CONFIG_PCI +#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 (maxlen && len > maxlen) + len = maxlen; + if (flags & IORESOURCE_IO) + return ioport_map(start, len); + if (flags & IORESOURCE_MEM) { + if (flags & IORESOURCE_CACHEABLE) + return ioremap(start, len); + return ioremap_nocache(start, len); + } + return NULL; +} +EXPORT_SYMBOL(pci_iomap); + +void pci_iounmap(struct pci_dev *dev, void __iomem *addr) +{ + if ((unsigned long)addr >= VMALLOC_START && + (unsigned long)addr < VMALLOC_END) + iounmap(addr); +} +EXPORT_SYMBOL(pci_iounmap); +#endif diff --git a/trunk/arch/arm/mm/nommu.c b/trunk/arch/arm/mm/nommu.c deleted file mode 100644 index 1464ed817b5d..000000000000 --- a/trunk/arch/arm/mm/nommu.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * linux/arch/arm/mm/nommu.c - * - * ARM uCLinux supporting functions. - */ -#include -#include -#include - -#include -#include -#include - -void flush_dcache_page(struct page *page) -{ - __cpuc_flush_dcache_page(page_address(page)); -} -EXPORT_SYMBOL(flush_dcache_page); - -void __iomem *__ioremap_pfn(unsigned long pfn, unsigned long offset, - size_t size, unsigned long flags) -{ - if (pfn >= (0x100000000ULL >> PAGE_SHIFT)) - return NULL; - return (void __iomem *) (offset + (pfn << PAGE_SHIFT)); -} -EXPORT_SYMBOL(__ioremap_pfn); - -void __iomem *__ioremap(unsigned long phys_addr, size_t size, - unsigned long flags) -{ - return (void __iomem *)phys_addr; -} -EXPORT_SYMBOL(__ioremap); - -void __iounmap(void __iomem *addr) -{ -} -EXPORT_SYMBOL(__iounmap); diff --git a/trunk/arch/arm/mm/proc-arm1020.S b/trunk/arch/arm/mm/proc-arm1020.S index b9abbafca812..959588884fa5 100644 --- a/trunk/arch/arm/mm/proc-arm1020.S +++ b/trunk/arch/arm/mm/proc-arm1020.S @@ -3,7 +3,6 @@ * * Copyright (C) 2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. - * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -102,9 +101,7 @@ ENTRY(cpu_arm1020_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB -#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -362,7 +359,6 @@ ENTRY(cpu_arm1020_dcache_clean_area) */ .align 5 ENTRY(cpu_arm1020_switch_mm) -#ifdef CONFIG_MMU #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r3, c7, c10, 4 mov r1, #0xF @ 16 segments @@ -387,7 +383,6 @@ ENTRY(cpu_arm1020_switch_mm) mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs -#endif /* CONFIG_MMU */ mov pc, lr /* @@ -397,7 +392,6 @@ ENTRY(cpu_arm1020_switch_mm) */ .align 5 ENTRY(cpu_arm1020_set_pte) -#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -427,7 +421,6 @@ ENTRY(cpu_arm1020_set_pte) mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif mcr p15, 0, r0, c7, c10, 4 @ drain WB -#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -437,9 +430,7 @@ __arm1020_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 -#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 -#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm1020_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-arm1020e.S b/trunk/arch/arm/mm/proc-arm1020e.S index bcd5ee022e00..be6d081ff2b7 100644 --- a/trunk/arch/arm/mm/proc-arm1020e.S +++ b/trunk/arch/arm/mm/proc-arm1020e.S @@ -3,7 +3,6 @@ * * Copyright (C) 2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. - * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -102,9 +101,7 @@ ENTRY(cpu_arm1020e_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB -#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -347,7 +344,6 @@ ENTRY(cpu_arm1020e_dcache_clean_area) */ .align 5 ENTRY(cpu_arm1020e_switch_mm) -#ifdef CONFIG_MMU #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r3, c7, c10, 4 mov r1, #0xF @ 16 segments @@ -371,7 +367,6 @@ ENTRY(cpu_arm1020e_switch_mm) mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs -#endif mov pc, lr /* @@ -381,7 +376,6 @@ ENTRY(cpu_arm1020e_switch_mm) */ .align 5 ENTRY(cpu_arm1020e_set_pte) -#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -409,7 +403,6 @@ ENTRY(cpu_arm1020e_set_pte) #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif -#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -419,9 +412,7 @@ __arm1020e_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 -#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 -#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm1020e_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-arm1022.S b/trunk/arch/arm/mm/proc-arm1022.S index b0ccff4fadd2..f778545d57a2 100644 --- a/trunk/arch/arm/mm/proc-arm1022.S +++ b/trunk/arch/arm/mm/proc-arm1022.S @@ -3,7 +3,6 @@ * * Copyright (C) 2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. - * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -91,9 +90,7 @@ ENTRY(cpu_arm1022_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB -#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -336,7 +333,6 @@ ENTRY(cpu_arm1022_dcache_clean_area) */ .align 5 ENTRY(cpu_arm1022_switch_mm) -#ifdef CONFIG_MMU #ifndef CONFIG_CPU_DCACHE_DISABLE mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments 1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries @@ -353,7 +349,6 @@ ENTRY(cpu_arm1022_switch_mm) mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs -#endif mov pc, lr /* @@ -363,7 +358,6 @@ ENTRY(cpu_arm1022_switch_mm) */ .align 5 ENTRY(cpu_arm1022_set_pte) -#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -391,7 +385,6 @@ ENTRY(cpu_arm1022_set_pte) #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif -#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -401,9 +394,7 @@ __arm1022_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 -#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 -#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm1022_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-arm1026.S b/trunk/arch/arm/mm/proc-arm1026.S index abe850c9a641..148c111fde73 100644 --- a/trunk/arch/arm/mm/proc-arm1026.S +++ b/trunk/arch/arm/mm/proc-arm1026.S @@ -3,7 +3,6 @@ * * Copyright (C) 2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. - * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -91,9 +90,7 @@ ENTRY(cpu_arm1026_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB -#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -330,7 +327,6 @@ ENTRY(cpu_arm1026_dcache_clean_area) */ .align 5 ENTRY(cpu_arm1026_switch_mm) -#ifdef CONFIG_MMU mov r1, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE 1: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate @@ -342,7 +338,6 @@ ENTRY(cpu_arm1026_switch_mm) mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs -#endif mov pc, lr /* @@ -352,7 +347,6 @@ ENTRY(cpu_arm1026_switch_mm) */ .align 5 ENTRY(cpu_arm1026_set_pte) -#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -380,7 +374,6 @@ ENTRY(cpu_arm1026_set_pte) #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif -#endif /* CONFIG_MMU */ mov pc, lr @@ -391,10 +384,8 @@ __arm1026_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 -#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 mcr p15, 0, r4, c2, c0 @ load page table pointer -#endif #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mov r0, #4 @ explicitly disable writeback mcr p15, 7, r0, c15, c0, 0 diff --git a/trunk/arch/arm/mm/proc-arm6_7.S b/trunk/arch/arm/mm/proc-arm6_7.S index 7a705edfa4b2..540359b475d0 100644 --- a/trunk/arch/arm/mm/proc-arm6_7.S +++ b/trunk/arch/arm/mm/proc-arm6_7.S @@ -2,7 +2,6 @@ * linux/arch/arm/mm/proc-arm6,7.S * * Copyright (C) 1997-2000 Russell King - * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -200,12 +199,10 @@ ENTRY(cpu_arm7_do_idle) */ ENTRY(cpu_arm6_switch_mm) ENTRY(cpu_arm7_switch_mm) -#ifdef CONFIG_MMU mov r1, #0 mcr p15, 0, r1, c7, c0, 0 @ flush cache mcr p15, 0, r0, c2, c0, 0 @ update page table ptr mcr p15, 0, r1, c5, c0, 0 @ flush TLBs -#endif mov pc, lr /* @@ -217,7 +214,6 @@ ENTRY(cpu_arm7_switch_mm) .align 5 ENTRY(cpu_arm6_set_pte) ENTRY(cpu_arm7_set_pte) -#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -236,7 +232,6 @@ ENTRY(cpu_arm7_set_pte) movne r2, #0 str r2, [r0] @ hardware version -#endif /* CONFIG_MMU */ mov pc, lr /* @@ -248,9 +243,7 @@ ENTRY(cpu_arm6_reset) ENTRY(cpu_arm7_reset) mov r1, #0 mcr p15, 0, r1, c7, c0, 0 @ flush cache -#ifdef CONFIG_MMU mcr p15, 0, r1, c5, c0, 0 @ flush TLB -#endif mov r1, #0x30 mcr p15, 0, r1, c1, c0, 0 @ turn off MMU etc mov pc, r0 @@ -260,27 +253,19 @@ ENTRY(cpu_arm7_reset) .type __arm6_setup, #function __arm6_setup: mov r0, #0 mcr p15, 0, r0, c7, c0 @ flush caches on v3 -#ifdef CONFIG_MMU mcr p15, 0, r0, c5, c0 @ flush TLBs on v3 mov r0, #0x3d @ . ..RS BLDP WCAM orr r0, r0, #0x100 @ . ..01 0011 1101 -#else - mov r0, #0x3c @ . ..RS BLDP WCA. -#endif mov pc, lr .size __arm6_setup, . - __arm6_setup .type __arm7_setup, #function __arm7_setup: mov r0, #0 mcr p15, 0, r0, c7, c0 @ flush caches on v3 -#ifdef CONFIG_MMU mcr p15, 0, r0, c5, c0 @ flush TLBs on v3 mcr p15, 0, r0, c3, c0 @ load domain access register mov r0, #0x7d @ . ..RS BLDP WCAM orr r0, r0, #0x100 @ . ..01 0111 1101 -#else - mov r0, #0x7c @ . ..RS BLDP WCA. -#endif mov pc, lr .size __arm7_setup, . - __arm7_setup diff --git a/trunk/arch/arm/mm/proc-arm720.S b/trunk/arch/arm/mm/proc-arm720.S index 86102467d37f..26f00ee2ad9a 100644 --- a/trunk/arch/arm/mm/proc-arm720.S +++ b/trunk/arch/arm/mm/proc-arm720.S @@ -4,7 +4,6 @@ * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) * Rob Scott (rscott@mtrob.fdns.net) * Copyright (C) 2000 ARM Limited, Deep Blue Solutions Ltd. - * hacked for non-paged-MM by Hyok S. Choi, 2004. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,7 +29,6 @@ * out of 'proc-arm6,7.S' per RMK discussion * 07-25-2000 SJH Added idle function. * 08-25-2000 DBS Updated for integration of ARM Ltd version. - * 04-20-2004 HSC modified for non-paged memory management mode. */ #include #include @@ -77,12 +75,10 @@ ENTRY(cpu_arm720_do_idle) * the new. */ ENTRY(cpu_arm720_switch_mm) -#ifdef CONFIG_MMU mov r1, #0 mcr p15, 0, r1, c7, c7, 0 @ invalidate cache mcr p15, 0, r0, c2, c0, 0 @ update page table ptr mcr p15, 0, r1, c8, c7, 0 @ flush TLB (v4) -#endif mov pc, lr /* @@ -93,7 +89,6 @@ ENTRY(cpu_arm720_switch_mm) */ .align 5 ENTRY(cpu_arm720_set_pte) -#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -112,7 +107,6 @@ ENTRY(cpu_arm720_set_pte) movne r2, #0 str r2, [r0] @ hardware version -#endif mov pc, lr /* @@ -123,9 +117,7 @@ ENTRY(cpu_arm720_set_pte) ENTRY(cpu_arm720_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate cache -#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4) -#endif mrc p15, 0, ip, c1, c0, 0 @ get ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x2100 @ ..v....s........ @@ -138,9 +130,7 @@ ENTRY(cpu_arm720_reset) __arm710_setup: mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ invalidate caches -#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) -#endif mrc p15, 0, r0, c1, c0 @ get control register ldr r5, arm710_cr1_clear bic r0, r0, r5 @@ -166,9 +156,7 @@ arm710_cr1_set: __arm720_setup: mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ invalidate caches -#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) -#endif mrc p15, 0, r0, c1, c0 @ get control register ldr r5, arm720_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-arm920.S b/trunk/arch/arm/mm/proc-arm920.S index 31dc839ba07c..a17f79e0199c 100644 --- a/trunk/arch/arm/mm/proc-arm920.S +++ b/trunk/arch/arm/mm/proc-arm920.S @@ -3,7 +3,6 @@ * * Copyright (C) 1999,2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. - * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -98,9 +97,7 @@ ENTRY(cpu_arm920_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB -#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -320,7 +317,6 @@ ENTRY(cpu_arm920_dcache_clean_area) */ .align 5 ENTRY(cpu_arm920_switch_mm) -#ifdef CONFIG_MMU mov ip, #0 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache @@ -341,7 +337,6 @@ ENTRY(cpu_arm920_switch_mm) mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mov pc, lr /* @@ -351,7 +346,6 @@ ENTRY(cpu_arm920_switch_mm) */ .align 5 ENTRY(cpu_arm920_set_pte) -#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -378,7 +372,6 @@ ENTRY(cpu_arm920_set_pte) mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB -#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -388,9 +381,7 @@ __arm920_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 -#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 -#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm920_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-arm922.S b/trunk/arch/arm/mm/proc-arm922.S index 9e57c34f5c09..bbde4a024a48 100644 --- a/trunk/arch/arm/mm/proc-arm922.S +++ b/trunk/arch/arm/mm/proc-arm922.S @@ -4,7 +4,6 @@ * Copyright (C) 1999,2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. * Copyright (C) 2001 Altera Corporation - * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -100,9 +99,7 @@ ENTRY(cpu_arm922_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB -#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -324,7 +321,6 @@ ENTRY(cpu_arm922_dcache_clean_area) */ .align 5 ENTRY(cpu_arm922_switch_mm) -#ifdef CONFIG_MMU mov ip, #0 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache @@ -345,7 +341,6 @@ ENTRY(cpu_arm922_switch_mm) mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mov pc, lr /* @@ -355,7 +350,6 @@ ENTRY(cpu_arm922_switch_mm) */ .align 5 ENTRY(cpu_arm922_set_pte) -#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -382,7 +376,6 @@ ENTRY(cpu_arm922_set_pte) mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB -#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -392,9 +385,7 @@ __arm922_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 -#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 -#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm922_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-arm925.S b/trunk/arch/arm/mm/proc-arm925.S index 8d47c9f3f931..224ce226a01b 100644 --- a/trunk/arch/arm/mm/proc-arm925.S +++ b/trunk/arch/arm/mm/proc-arm925.S @@ -9,8 +9,6 @@ * Update for Linux-2.6 and cache flush improvements * Copyright (C) 2004 Nokia Corporation by Tony Lindgren * - * hacked for non-paged-MM by Hyok S. Choi, 2004. - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -124,9 +122,7 @@ ENTRY(cpu_arm925_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB -#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -373,7 +369,6 @@ ENTRY(cpu_arm925_dcache_clean_area) */ .align 5 ENTRY(cpu_arm925_switch_mm) -#ifdef CONFIG_MMU mov ip, #0 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache @@ -388,7 +383,6 @@ ENTRY(cpu_arm925_switch_mm) mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mov pc, lr /* @@ -398,7 +392,6 @@ ENTRY(cpu_arm925_switch_mm) */ .align 5 ENTRY(cpu_arm925_set_pte) -#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -427,7 +420,6 @@ ENTRY(cpu_arm925_set_pte) mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif mcr p15, 0, r0, c7, c10, 4 @ drain WB -#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -446,9 +438,7 @@ __arm925_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 -#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 -#endif #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mov r0, #4 @ disable write-back on caches explicitly diff --git a/trunk/arch/arm/mm/proc-arm926.S b/trunk/arch/arm/mm/proc-arm926.S index cb4d8f33d2a3..4e2a087cf388 100644 --- a/trunk/arch/arm/mm/proc-arm926.S +++ b/trunk/arch/arm/mm/proc-arm926.S @@ -3,7 +3,6 @@ * * Copyright (C) 1999-2001 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. - * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -86,9 +85,7 @@ ENTRY(cpu_arm926_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB -#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -332,7 +329,6 @@ ENTRY(cpu_arm926_dcache_clean_area) */ .align 5 ENTRY(cpu_arm926_switch_mm) -#ifdef CONFIG_MMU mov ip, #0 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache @@ -345,7 +341,6 @@ ENTRY(cpu_arm926_switch_mm) mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mov pc, lr /* @@ -355,7 +350,6 @@ ENTRY(cpu_arm926_switch_mm) */ .align 5 ENTRY(cpu_arm926_set_pte) -#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -384,7 +378,6 @@ ENTRY(cpu_arm926_set_pte) mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif mcr p15, 0, r0, c7, c10, 4 @ drain WB -#endif mov pc, lr __INIT @@ -394,9 +387,7 @@ __arm926_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 -#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 -#endif #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH diff --git a/trunk/arch/arm/mm/proc-sa110.S b/trunk/arch/arm/mm/proc-sa110.S index 5a760a2c629c..a2dd5ae1077d 100644 --- a/trunk/arch/arm/mm/proc-sa110.S +++ b/trunk/arch/arm/mm/proc-sa110.S @@ -2,7 +2,6 @@ * linux/arch/arm/mm/proc-sa110.S * * Copyright (C) 1997-2002 Russell King - * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -68,9 +67,7 @@ ENTRY(cpu_sa110_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB -#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -133,15 +130,11 @@ ENTRY(cpu_sa110_dcache_clean_area) */ .align 5 ENTRY(cpu_sa110_switch_mm) -#ifdef CONFIG_MMU str lr, [sp, #-4]! bl v4wb_flush_kern_cache_all @ clears IP mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs ldr pc, [sp], #4 -#else - mov pc, lr -#endif /* * cpu_sa110_set_pte(ptep, pte) @@ -150,7 +143,6 @@ ENTRY(cpu_sa110_switch_mm) */ .align 5 ENTRY(cpu_sa110_set_pte) -#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -172,7 +164,6 @@ ENTRY(cpu_sa110_set_pte) mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB -#endif mov pc, lr __INIT @@ -182,9 +173,7 @@ __sa110_setup: mov r10, #0 mcr p15, 0, r10, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r10, c7, c10, 4 @ drain write buffer on v4 -#ifdef CONFIG_MMU mcr p15, 0, r10, c8, c7 @ invalidate I,D TLBs on v4 -#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, sa110_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-sa1100.S b/trunk/arch/arm/mm/proc-sa1100.S index 0a2107ad4c32..777ad99c1439 100644 --- a/trunk/arch/arm/mm/proc-sa1100.S +++ b/trunk/arch/arm/mm/proc-sa1100.S @@ -2,7 +2,6 @@ * linux/arch/arm/mm/proc-sa1100.S * * Copyright (C) 1997-2002 Russell King - * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -78,9 +77,7 @@ ENTRY(cpu_sa1100_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB -#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs -#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -145,16 +142,12 @@ ENTRY(cpu_sa1100_dcache_clean_area) */ .align 5 ENTRY(cpu_sa1100_switch_mm) -#ifdef CONFIG_MMU str lr, [sp, #-4]! bl v4wb_flush_kern_cache_all @ clears IP mcr p15, 0, ip, c9, c0, 0 @ invalidate RB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs ldr pc, [sp], #4 -#else - mov pc, lr -#endif /* * cpu_sa1100_set_pte(ptep, pte) @@ -163,7 +156,6 @@ ENTRY(cpu_sa1100_switch_mm) */ .align 5 ENTRY(cpu_sa1100_set_pte) -#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -185,7 +177,6 @@ ENTRY(cpu_sa1100_set_pte) mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB -#endif mov pc, lr __INIT @@ -195,9 +186,7 @@ __sa1100_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 -#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 -#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, sa1100_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-v6.S b/trunk/arch/arm/mm/proc-v6.S index ca13d4d05f65..09b1a41a6de8 100644 --- a/trunk/arch/arm/mm/proc-v6.S +++ b/trunk/arch/arm/mm/proc-v6.S @@ -2,7 +2,6 @@ * linux/arch/arm/mm/proc-v6.S * * Copyright (C) 2001 Deep Blue Solutions Ltd. - * Modified by Catalin Marinas for noMMU support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -89,7 +88,6 @@ ENTRY(cpu_v6_dcache_clean_area) * - we are not using split page tables */ ENTRY(cpu_v6_switch_mm) -#ifdef CONFIG_MMU mov r2, #0 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id #ifdef CONFIG_SMP @@ -99,7 +97,6 @@ ENTRY(cpu_v6_switch_mm) mcr p15, 0, r2, c7, c10, 4 @ drain write buffer mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 mcr p15, 0, r1, c13, c0, 1 @ set context ID -#endif mov pc, lr /* @@ -122,7 +119,6 @@ ENTRY(cpu_v6_switch_mm) * 1111 0 1 1 r/w r/w */ ENTRY(cpu_v6_set_pte) -#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version bic r2, r1, #0x000003f0 @@ -149,7 +145,6 @@ ENTRY(cpu_v6_set_pte) str r2, [r0] mcr p15, 0, r0, c7, c10, 1 @ flush_pte -#endif mov pc, lr @@ -199,14 +194,12 @@ __v6_setup: mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache mcr p15, 0, r0, c7, c10, 4 @ drain write buffer -#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs mcr p15, 0, r0, c2, c0, 2 @ TTB control register #ifdef CONFIG_SMP orr r4, r4, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable #endif mcr p15, 0, r4, c2, c0, 1 @ load TTB1 -#endif /* CONFIG_MMU */ #ifdef CONFIG_VFP mrc p15, 0, r0, c1, c0, 2 orr r0, r0, #(0xf << 20) diff --git a/trunk/arch/cris/Kconfig b/trunk/arch/cris/Kconfig index 6a1238a29d6c..856b665020e7 100644 --- a/trunk/arch/cris/Kconfig +++ b/trunk/arch/cris/Kconfig @@ -28,10 +28,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config IRQ_PER_CPU - bool - default y - config CRIS bool default y diff --git a/trunk/arch/cris/arch-v10/kernel/irq.c b/trunk/arch/cris/arch-v10/kernel/irq.c index 2d5be93b5197..4b368a122015 100644 --- a/trunk/arch/cris/arch-v10/kernel/irq.c +++ b/trunk/arch/cris/arch-v10/kernel/irq.c @@ -172,7 +172,7 @@ init_IRQ(void) /* Initialize IRQ handler descriptiors. */ for(i = 2; i < NR_IRQS; i++) { - irq_desc[i].chip = &crisv10_irq_type; + irq_desc[i].handler = &crisv10_irq_type; set_int_vector(i, interrupt[i]); } diff --git a/trunk/arch/cris/arch-v32/kernel/irq.c b/trunk/arch/cris/arch-v32/kernel/irq.c index 06260874f018..c78cc2685133 100644 --- a/trunk/arch/cris/arch-v32/kernel/irq.c +++ b/trunk/arch/cris/arch-v32/kernel/irq.c @@ -369,7 +369,7 @@ init_IRQ(void) /* Point all IRQ's to bad handlers. */ for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) { - irq_desc[j].chip = &crisv32_irq_type; + irq_desc[j].handler = &crisv32_irq_type; set_exception_vector(i, interrupt[j]); } diff --git a/trunk/arch/cris/kernel/irq.c b/trunk/arch/cris/kernel/irq.c index 6547bb646364..b504def3e346 100644 --- a/trunk/arch/cris/kernel/irq.c +++ b/trunk/arch/cris/kernel/irq.c @@ -69,7 +69,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index 5fa3c671c937..47c08bcd9b24 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -233,7 +233,7 @@ config NR_CPUS config SCHED_SMT bool "SMT (Hyperthreading) scheduler support" - depends on X86_HT + depends on SMP help SMT scheduler support improves the CPU scheduler's decision making when dealing with Intel Pentium 4 chips with HyperThreading at a @@ -242,7 +242,7 @@ config SCHED_SMT config SCHED_MC bool "Multi-core scheduler support" - depends on X86_HT + depends on SMP default y help Multi-core scheduler support improves the CPU scheduler's decision @@ -780,23 +780,9 @@ config HOTPLUG_CPU enable suspend on SMP systems. CPUs can be controlled through /sys/devices/system/cpu. -config COMPAT_VDSO - bool "Compat VDSO support" - default y - help - Map the VDSO to the predictable old-style address too. - ---help--- - Say N here if you are running a sufficiently recent glibc - version (2.3.3 or later), to remove the high-mapped - VDSO mapping and to exclusively use the randomized VDSO. - - If unsure, say Y. endmenu -config ARCH_ENABLE_MEMORY_HOTPLUG - def_bool y - depends on HIGHMEM menu "Power management options (ACPI, APM)" depends on !X86_VOYAGER diff --git a/trunk/arch/i386/kernel/asm-offsets.c b/trunk/arch/i386/kernel/asm-offsets.c index c80271f8f084..1c3a809e6421 100644 --- a/trunk/arch/i386/kernel/asm-offsets.c +++ b/trunk/arch/i386/kernel/asm-offsets.c @@ -14,7 +14,6 @@ #include #include #include -#include #define DEFINE(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) @@ -55,7 +54,6 @@ void foo(void) OFFSET(TI_preempt_count, thread_info, preempt_count); OFFSET(TI_addr_limit, thread_info, addr_limit); OFFSET(TI_restart_block, thread_info, restart_block); - OFFSET(TI_sysenter_return, thread_info, sysenter_return); BLANK(); OFFSET(EXEC_DOMAIN_handler, exec_domain, handler); @@ -71,7 +69,7 @@ void foo(void) sizeof(struct tss_struct)); DEFINE(PAGE_SIZE_asm, PAGE_SIZE); - DEFINE(VDSO_PRELINK, VDSO_PRELINK); + DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL)); OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx); } diff --git a/trunk/arch/i386/kernel/cpu/amd.c b/trunk/arch/i386/kernel/cpu/amd.c index e6a2d6b80cda..fd0457c9c827 100644 --- a/trunk/arch/i386/kernel/cpu/amd.c +++ b/trunk/arch/i386/kernel/cpu/amd.c @@ -235,10 +235,10 @@ static void __init init_amd(struct cpuinfo_x86 *c) while ((1 << bits) < c->x86_max_cores) bits++; } - c->cpu_core_id = c->phys_proc_id & ((1<phys_proc_id >>= bits; + cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<>= bits; printk(KERN_INFO "CPU %d(%d) -> Core %d\n", - cpu, c->x86_max_cores, c->cpu_core_id); + cpu, c->x86_max_cores, cpu_core_id[cpu]); } #endif diff --git a/trunk/arch/i386/kernel/cpu/common.c b/trunk/arch/i386/kernel/cpu/common.c index 70c87de582c7..44f2c5f2dda1 100644 --- a/trunk/arch/i386/kernel/cpu/common.c +++ b/trunk/arch/i386/kernel/cpu/common.c @@ -294,7 +294,7 @@ void __cpuinit generic_identify(struct cpuinfo_x86 * c) if (c->x86 >= 0x6) c->x86_model += ((tfms >> 16) & 0xF) << 4; c->x86_mask = tfms & 15; -#ifdef CONFIG_X86_HT +#ifdef CONFIG_SMP c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0); #else c->apicid = (ebx >> 24) & 0xFF; @@ -319,7 +319,7 @@ void __cpuinit generic_identify(struct cpuinfo_x86 * c) early_intel_workaround(c); #ifdef CONFIG_X86_HT - c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff; + phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; #endif } @@ -477,9 +477,11 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) { u32 eax, ebx, ecx, edx; int index_msb, core_bits; + int cpu = smp_processor_id(); cpuid(1, &eax, &ebx, &ecx, &edx); + if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) return; @@ -490,17 +492,16 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) } else if (smp_num_siblings > 1 ) { if (smp_num_siblings > NR_CPUS) { - printk(KERN_WARNING "CPU: Unsupported number of the " - "siblings %d", smp_num_siblings); + printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); smp_num_siblings = 1; return; } index_msb = get_count_order(smp_num_siblings); - c->phys_proc_id = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); + phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb); printk(KERN_INFO "CPU: Physical Processor ID: %d\n", - c->phys_proc_id); + phys_proc_id[cpu]); smp_num_siblings = smp_num_siblings / c->x86_max_cores; @@ -508,12 +509,12 @@ void __cpuinit detect_ht(struct cpuinfo_x86 *c) core_bits = get_count_order(c->x86_max_cores); - c->cpu_core_id = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) & + cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) & ((1 << core_bits) - 1); if (c->x86_max_cores > 1) printk(KERN_INFO "CPU: Processor Core ID: %d\n", - c->cpu_core_id); + cpu_core_id[cpu]); } } #endif @@ -612,12 +613,6 @@ void __cpuinit cpu_init(void) set_in_cr4(X86_CR4_TSD); } - /* The CPU hotplug case */ - if (cpu_gdt_descr->address) { - gdt = (struct desc_struct *)cpu_gdt_descr->address; - memset(gdt, 0, PAGE_SIZE); - goto old_gdt; - } /* * This is a horrible hack to allocate the GDT. The problem * is that cpu_init() is called really early for the boot CPU @@ -636,7 +631,7 @@ void __cpuinit cpu_init(void) local_irq_enable(); } } -old_gdt: + /* * Initialize the per-CPU GDT with the boot GDT, * and set up the GDT descriptor: diff --git a/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c b/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c index e9f0b928b0a9..6c37b4fd8ce2 100644 --- a/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/trunk/arch/i386/kernel/cpu/intel_cacheinfo.c @@ -159,13 +159,13 @@ union l2_cache { unsigned val; }; -static const unsigned short assocs[] = { +static unsigned short assocs[] = { [1] = 1, [2] = 2, [4] = 4, [6] = 8, [8] = 16, [0xf] = 0xffff // ?? }; -static const unsigned char levels[] = { 1, 1, 2 }; -static const unsigned char types[] = { 1, 2, 3 }; +static unsigned char levels[] = { 1, 1, 2 }; +static unsigned char types[] = { 1, 2, 3 }; static void __cpuinit amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, union _cpuid4_leaf_ebx *ebx, @@ -261,7 +261,7 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; -#ifdef CONFIG_X86_HT +#ifdef CONFIG_SMP unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data); #endif @@ -383,14 +383,14 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) if (new_l2) { l2 = new_l2; -#ifdef CONFIG_X86_HT +#ifdef CONFIG_SMP cpu_llc_id[cpu] = l2_id; #endif } if (new_l3) { l3 = new_l3; -#ifdef CONFIG_X86_HT +#ifdef CONFIG_SMP cpu_llc_id[cpu] = l3_id; #endif } @@ -729,7 +729,7 @@ static void __cpuexit cache_remove_dev(struct sys_device * sys_dev) return; } -static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, +static int cacheinfo_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -747,7 +747,7 @@ static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = +static struct notifier_block cacheinfo_cpu_notifier = { .notifier_call = cacheinfo_cpu_callback, }; diff --git a/trunk/arch/i386/kernel/cpu/proc.c b/trunk/arch/i386/kernel/cpu/proc.c index f54a15268ed7..a19fcb262dbb 100644 --- a/trunk/arch/i386/kernel/cpu/proc.c +++ b/trunk/arch/i386/kernel/cpu/proc.c @@ -18,7 +18,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) * applications want to get the raw CPUID data, they should access * /dev/cpu//cpuid instead. */ - static const char * const x86_cap_flags[] = { + static char *x86_cap_flags[] = { /* Intel-defined */ "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", @@ -62,7 +62,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; - static const char * const x86_power_flags[] = { + static char *x86_power_flags[] = { "ts", /* temperature sensor */ "fid", /* frequency id control */ "vid", /* voltage id control */ @@ -109,9 +109,9 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size); #ifdef CONFIG_X86_HT if (c->x86_max_cores * smp_num_siblings > 1) { - seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); + seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]); seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[n])); - seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); + seq_printf(m, "core id\t\t: %d\n", cpu_core_id[n]); seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); } #endif diff --git a/trunk/arch/i386/kernel/cpuid.c b/trunk/arch/i386/kernel/cpuid.c index f6dfa9fb675c..1d9a4abcdfc7 100644 --- a/trunk/arch/i386/kernel/cpuid.c +++ b/trunk/arch/i386/kernel/cpuid.c @@ -183,7 +183,7 @@ static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long ac return NOTIFY_OK; } -static struct notifier_block __cpuinitdata cpuid_class_cpu_notifier = +static struct notifier_block cpuid_class_cpu_notifier = { .notifier_call = cpuid_class_cpu_callback, }; diff --git a/trunk/arch/i386/kernel/entry.S b/trunk/arch/i386/kernel/entry.S index fbdb933251b6..e6e4506e749a 100644 --- a/trunk/arch/i386/kernel/entry.S +++ b/trunk/arch/i386/kernel/entry.S @@ -83,12 +83,6 @@ VM_MASK = 0x00020000 #define resume_kernel restore_nocheck #endif -#ifdef CONFIG_VM86 -#define resume_userspace_sig check_userspace -#else -#define resume_userspace_sig resume_userspace -#endif - #define SAVE_ALL \ cld; \ pushl %es; \ @@ -217,7 +211,6 @@ ret_from_exception: preempt_stop ret_from_intr: GET_THREAD_INFO(%ebp) -check_userspace: movl EFLAGS(%esp), %eax # mix EFLAGS and CS movb CS(%esp), %al testl $(VM_MASK | 3), %eax @@ -270,12 +263,7 @@ sysenter_past_esp: pushl $(__USER_CS) CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET cs, 0*/ - /* - * Push current_thread_info()->sysenter_return to the stack. - * A tiny bit of offset fixup is necessary - 4*4 means the 4 words - * pushed above; +8 corresponds to copy_thread's esp0 setting. - */ - pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp) + pushl $SYSENTER_RETURN CFI_ADJUST_CFA_OFFSET 4 CFI_REL_OFFSET eip, 0 @@ -427,7 +415,7 @@ work_notifysig: # deal with pending signals and # vm86-space xorl %edx, %edx call do_notify_resume - jmp resume_userspace_sig + jmp resume_userspace ALIGN work_notifysig_v86: @@ -440,7 +428,7 @@ work_notifysig_v86: movl %eax, %esp xorl %edx, %edx call do_notify_resume - jmp resume_userspace_sig + jmp resume_userspace #endif # perform syscall exit tracing @@ -527,7 +515,7 @@ ENTRY(irq_entries_start) .if vector CFI_ADJUST_CFA_OFFSET -4 .endif -1: pushl $~(vector) +1: pushl $vector-256 CFI_ADJUST_CFA_OFFSET 4 jmp common_interrupt .data @@ -547,7 +535,7 @@ common_interrupt: #define BUILD_INTERRUPT(name, nr) \ ENTRY(name) \ RING0_INT_FRAME; \ - pushl $~(nr); \ + pushl $nr-256; \ CFI_ADJUST_CFA_OFFSET 4; \ SAVE_ALL; \ movl %esp,%eax; \ diff --git a/trunk/arch/i386/kernel/i8259.c b/trunk/arch/i386/kernel/i8259.c index 3c6063671a9f..c1a42feba286 100644 --- a/trunk/arch/i386/kernel/i8259.c +++ b/trunk/arch/i386/kernel/i8259.c @@ -132,7 +132,7 @@ void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<orig_eax; + /* high bits used in ret_from_ code */ + int irq = regs->orig_eax & 0xff; #ifdef CONFIG_4KSTACKS union irq_ctx *curctx, *irqctx; u32 *isp; #endif - if (unlikely((unsigned)irq >= NR_IRQS)) { - printk(KERN_EMERG "%s: cannot handle IRQ %d\n", - __FUNCTION__, irq); - BUG(); - } - irq_enter(); #ifdef CONFIG_DEBUG_STACKOVERFLOW /* Debugging check for stack overflow: is there less than 1KB free? */ @@ -82,10 +76,6 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) } #endif - if (!irq_desc[irq].handle_irq) { - __do_IRQ(irq, regs); - goto out_exit; - } #ifdef CONFIG_4KSTACKS curctx = (union irq_ctx *) current_thread_info(); @@ -110,8 +100,8 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) * softirq checks work in the hardirq context. */ irqctx->tinfo.preempt_count = - (irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) | - (curctx->tinfo.preempt_count & SOFTIRQ_MASK); + irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK | + curctx->tinfo.preempt_count & SOFTIRQ_MASK; asm volatile( " xchgl %%ebx,%%esp \n" @@ -125,7 +115,6 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) #endif __do_IRQ(irq, regs); -out_exit: irq_exit(); return 1; @@ -254,7 +243,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -296,13 +285,13 @@ void fixup_irqs(cpumask_t map) if (irq == 2) continue; - cpus_and(mask, irq_desc[irq].affinity, map); + cpus_and(mask, irq_affinity[irq], map); if (any_online_cpu(mask) == NR_CPUS) { printk("Breaking affinity for irq %i\n", irq); mask = map; } - if (irq_desc[irq].chip->set_affinity) - irq_desc[irq].chip->set_affinity(irq, mask); + if (irq_desc[irq].handler->set_affinity) + irq_desc[irq].handler->set_affinity(irq, mask); else if (irq_desc[irq].action && !(warned++)) printk("Cannot set affinity for irq %i\n", irq); } diff --git a/trunk/arch/i386/kernel/msr.c b/trunk/arch/i386/kernel/msr.c index d022cb8fd725..7a328230e540 100644 --- a/trunk/arch/i386/kernel/msr.c +++ b/trunk/arch/i386/kernel/msr.c @@ -266,7 +266,7 @@ static int msr_class_cpu_callback(struct notifier_block *nfb, unsigned long acti return NOTIFY_OK; } -static struct notifier_block __cpuinitdata msr_class_cpu_notifier = +static struct notifier_block msr_class_cpu_notifier = { .notifier_call = msr_class_cpu_callback, }; diff --git a/trunk/arch/i386/kernel/scx200.c b/trunk/arch/i386/kernel/scx200.c index 9bf590cefc7d..321f5fd26e75 100644 --- a/trunk/arch/i386/kernel/scx200.c +++ b/trunk/arch/i386/kernel/scx200.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -46,19 +45,11 @@ static struct pci_driver scx200_pci_driver = { .probe = scx200_probe, }; -static DEFINE_MUTEX(scx200_gpio_config_lock); - -static void __devinit scx200_init_shadow(void) -{ - int bank; - - /* read the current values driven on the GPIO signals */ - for (bank = 0; bank < 2; ++bank) - scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank); -} +static DEFINE_SPINLOCK(scx200_gpio_config_lock); static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + int bank; unsigned base; if (pdev->device == PCI_DEVICE_ID_NS_SCx200_BRIDGE || @@ -72,7 +63,10 @@ static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_ } scx200_gpio_base = base; - scx200_init_shadow(); + + /* read the current values driven on the GPIO signals */ + for (bank = 0; bank < 2; ++bank) + scx200_gpio_shadow[bank] = inl(scx200_gpio_base + 0x10 * bank); } else { /* find the base of the Configuration Block */ @@ -93,11 +87,12 @@ static int __devinit scx200_probe(struct pci_dev *pdev, const struct pci_device_ return 0; } -u32 scx200_gpio_configure(unsigned index, u32 mask, u32 bits) +u32 scx200_gpio_configure(int index, u32 mask, u32 bits) { u32 config, new_config; + unsigned long flags; - mutex_lock(&scx200_gpio_config_lock); + spin_lock_irqsave(&scx200_gpio_config_lock, flags); outl(index, scx200_gpio_base + 0x20); config = inl(scx200_gpio_base + 0x24); @@ -105,11 +100,45 @@ u32 scx200_gpio_configure(unsigned index, u32 mask, u32 bits) new_config = (config & mask) | bits; outl(new_config, scx200_gpio_base + 0x24); - mutex_unlock(&scx200_gpio_config_lock); + spin_unlock_irqrestore(&scx200_gpio_config_lock, flags); return config; } +#if 0 +void scx200_gpio_dump(unsigned index) +{ + u32 config = scx200_gpio_configure(index, ~0, 0); + printk(KERN_DEBUG "GPIO%02u: 0x%08lx", index, (unsigned long)config); + + if (config & 1) + printk(" OE"); /* output enabled */ + else + printk(" TS"); /* tristate */ + if (config & 2) + printk(" PP"); /* push pull */ + else + printk(" OD"); /* open drain */ + if (config & 4) + printk(" PUE"); /* pull up enabled */ + else + printk(" PUD"); /* pull up disabled */ + if (config & 8) + printk(" LOCKED"); /* locked */ + if (config & 16) + printk(" LEVEL"); /* level input */ + else + printk(" EDGE"); /* edge input */ + if (config & 32) + printk(" HI"); /* trigger on rising edge */ + else + printk(" LO"); /* trigger on falling edge */ + if (config & 64) + printk(" DEBOUNCE"); /* debounce */ + printk("\n"); +} +#endif /* 0 */ + static int __init scx200_init(void) { printk(KERN_INFO NAME ": NatSemi SCx200 Driver\n"); @@ -130,3 +159,10 @@ EXPORT_SYMBOL(scx200_gpio_base); EXPORT_SYMBOL(scx200_gpio_shadow); EXPORT_SYMBOL(scx200_gpio_configure); EXPORT_SYMBOL(scx200_cb_base); + +/* + Local variables: + compile-command: "make -k -C ../../.. SUBDIRS=arch/i386/kernel modules" + c-basic-offset: 8 + End: +*/ diff --git a/trunk/arch/i386/kernel/signal.c b/trunk/arch/i386/kernel/signal.c index 43002cfb40c4..5c352c3a9e7f 100644 --- a/trunk/arch/i386/kernel/signal.c +++ b/trunk/arch/i386/kernel/signal.c @@ -351,7 +351,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, goto give_sigsegv; } - restorer = (void *)VDSO_SYM(&__kernel_sigreturn); + restorer = &__kernel_sigreturn; if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; @@ -447,7 +447,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, goto give_sigsegv; /* Set up to return from userspace. */ - restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn); + restorer = &__kernel_rt_sigreturn; if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; err |= __put_user(restorer, &frame->pretcode); diff --git a/trunk/arch/i386/kernel/smpboot.c b/trunk/arch/i386/kernel/smpboot.c index 89e7315e539c..bce5470ecb42 100644 --- a/trunk/arch/i386/kernel/smpboot.c +++ b/trunk/arch/i386/kernel/smpboot.c @@ -67,6 +67,12 @@ int smp_num_siblings = 1; EXPORT_SYMBOL(smp_num_siblings); #endif +/* Package ID of each logical CPU */ +int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; + +/* Core ID of each logical CPU */ +int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; + /* Last level cache ID of each logical CPU */ int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; @@ -448,12 +454,10 @@ cpumask_t cpu_coregroup_map(int cpu) struct cpuinfo_x86 *c = cpu_data + cpu; /* * For perf, we return last level cache shared map. - * And for power savings, we return cpu_core_map + * TBD: when power saving sched policy is added, we will return + * cpu_core_map when power saving policy is enabled */ - if (sched_mc_power_savings || sched_smt_power_savings) - return cpu_core_map[cpu]; - else - return c->llc_shared_map; + return c->llc_shared_map; } /* representing cpus for which sibling maps can be computed */ @@ -469,8 +473,8 @@ set_cpu_sibling_map(int cpu) if (smp_num_siblings > 1) { for_each_cpu_mask(i, cpu_sibling_setup_map) { - if (c[cpu].phys_proc_id == c[i].phys_proc_id && - c[cpu].cpu_core_id == c[i].cpu_core_id) { + if (phys_proc_id[cpu] == phys_proc_id[i] && + cpu_core_id[cpu] == cpu_core_id[i]) { cpu_set(i, cpu_sibling_map[cpu]); cpu_set(cpu, cpu_sibling_map[i]); cpu_set(i, cpu_core_map[cpu]); @@ -497,7 +501,7 @@ set_cpu_sibling_map(int cpu) cpu_set(i, c[cpu].llc_shared_map); cpu_set(cpu, c[i].llc_shared_map); } - if (c[cpu].phys_proc_id == c[i].phys_proc_id) { + if (phys_proc_id[cpu] == phys_proc_id[i]) { cpu_set(i, cpu_core_map[cpu]); cpu_set(cpu, cpu_core_map[i]); /* @@ -1052,7 +1056,6 @@ static int __cpuinit __smp_prepare_cpu(int cpu) struct warm_boot_cpu_info info; struct work_struct task; int apicid, ret; - struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); apicid = x86_cpu_to_apicid[cpu]; if (apicid == BAD_APICID) { @@ -1060,18 +1063,6 @@ static int __cpuinit __smp_prepare_cpu(int cpu) goto exit; } - /* - * the CPU isn't initialized at boot time, allocate gdt table here. - * cpu_init will initialize it - */ - if (!cpu_gdt_descr->address) { - cpu_gdt_descr->address = get_zeroed_page(GFP_KERNEL); - if (!cpu_gdt_descr->address) - printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); - ret = -ENOMEM; - goto exit; - } - info.complete = &done; info.apicid = apicid; info.cpu = cpu; @@ -1349,8 +1340,8 @@ remove_siblinginfo(int cpu) cpu_clear(cpu, cpu_sibling_map[sibling]); cpus_clear(cpu_sibling_map[cpu]); cpus_clear(cpu_core_map[cpu]); - c[cpu].phys_proc_id = 0; - c[cpu].cpu_core_id = 0; + phys_proc_id[cpu] = BAD_APICID; + cpu_core_id[cpu] = BAD_APICID; cpu_clear(cpu, cpu_sibling_setup_map); } diff --git a/trunk/arch/i386/kernel/sysenter.c b/trunk/arch/i386/kernel/sysenter.c index 713ba39d32c6..0bada1870bdf 100644 --- a/trunk/arch/i386/kernel/sysenter.c +++ b/trunk/arch/i386/kernel/sysenter.c @@ -2,8 +2,6 @@ * linux/arch/i386/kernel/sysenter.c * * (C) Copyright 2002 Linus Torvalds - * Portions based on the vdso-randomization code from exec-shield: - * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar * * This file contains the needed initializations to support sysenter. */ @@ -15,31 +13,12 @@ #include #include #include -#include -#include #include #include #include #include -/* - * Should the kernel map a VDSO page into processes and pass its - * address down to glibc upon exec()? - */ -unsigned int __read_mostly vdso_enabled = 1; - -EXPORT_SYMBOL_GPL(vdso_enabled); - -static int __init vdso_setup(char *s) -{ - vdso_enabled = simple_strtoul(s, NULL, 0); - - return 1; -} - -__setup("vdso=", vdso_setup); - extern asmlinkage void sysenter_entry(void); void enable_sep_cpu(void) @@ -66,120 +45,23 @@ void enable_sep_cpu(void) */ extern const char vsyscall_int80_start, vsyscall_int80_end; extern const char vsyscall_sysenter_start, vsyscall_sysenter_end; -static void *syscall_page; int __init sysenter_setup(void) { - syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); + void *page = (void *)get_zeroed_page(GFP_ATOMIC); -#ifdef CONFIG_COMPAT_VDSO - __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_READONLY); - printk("Compat vDSO mapped to %08lx.\n", __fix_to_virt(FIX_VDSO)); -#else - /* - * In the non-compat case the ELF coredumping code needs the fixmap: - */ - __set_fixmap(FIX_VDSO, __pa(syscall_page), PAGE_KERNEL_RO); -#endif + __set_fixmap(FIX_VSYSCALL, __pa(page), PAGE_READONLY_EXEC); if (!boot_cpu_has(X86_FEATURE_SEP)) { - memcpy(syscall_page, + memcpy(page, &vsyscall_int80_start, &vsyscall_int80_end - &vsyscall_int80_start); return 0; } - memcpy(syscall_page, + memcpy(page, &vsyscall_sysenter_start, &vsyscall_sysenter_end - &vsyscall_sysenter_start); return 0; } - -static struct page *syscall_nopage(struct vm_area_struct *vma, - unsigned long adr, int *type) -{ - struct page *p = virt_to_page(adr - vma->vm_start + syscall_page); - get_page(p); - return p; -} - -/* Prevent VMA merging */ -static void syscall_vma_close(struct vm_area_struct *vma) -{ -} - -static struct vm_operations_struct syscall_vm_ops = { - .close = syscall_vma_close, - .nopage = syscall_nopage, -}; - -/* Defined in vsyscall-sysenter.S */ -extern void SYSENTER_RETURN; - -/* Setup a VMA at program startup for the vsyscall page */ -int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) -{ - struct vm_area_struct *vma; - struct mm_struct *mm = current->mm; - unsigned long addr; - int ret; - - down_write(&mm->mmap_sem); - addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); - if (IS_ERR_VALUE(addr)) { - ret = addr; - goto up_fail; - } - - vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL); - if (!vma) { - ret = -ENOMEM; - goto up_fail; - } - - vma->vm_start = addr; - vma->vm_end = addr + PAGE_SIZE; - /* MAYWRITE to allow gdb to COW and set breakpoints */ - vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; - vma->vm_flags |= mm->def_flags; - vma->vm_page_prot = protection_map[vma->vm_flags & 7]; - vma->vm_ops = &syscall_vm_ops; - vma->vm_mm = mm; - - ret = insert_vm_struct(mm, vma); - if (unlikely(ret)) { - kmem_cache_free(vm_area_cachep, vma); - goto up_fail; - } - - current->mm->context.vdso = (void *)addr; - current_thread_info()->sysenter_return = - (void *)VDSO_SYM(&SYSENTER_RETURN); - mm->total_vm++; -up_fail: - up_write(&mm->mmap_sem); - return ret; -} - -const char *arch_vma_name(struct vm_area_struct *vma) -{ - if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) - return "[vdso]"; - return NULL; -} - -struct vm_area_struct *get_gate_vma(struct task_struct *tsk) -{ - return NULL; -} - -int in_gate_area(struct task_struct *task, unsigned long addr) -{ - return 0; -} - -int in_gate_area_no_task(unsigned long addr) -{ - return 0; -} diff --git a/trunk/arch/i386/kernel/topology.c b/trunk/arch/i386/kernel/topology.c index e2e281d4bcc8..296355292c7c 100644 --- a/trunk/arch/i386/kernel/topology.c +++ b/trunk/arch/i386/kernel/topology.c @@ -32,8 +32,15 @@ static struct i386_cpu cpu_devices[NR_CPUS]; -int arch_register_cpu(int num) -{ +int arch_register_cpu(int num){ + struct node *parent = NULL; + +#ifdef CONFIG_NUMA + int node = cpu_to_node(num); + if (node_online(node)) + parent = &node_devices[node].node; +#endif /* CONFIG_NUMA */ + /* * CPU0 cannot be offlined due to several * restrictions and assumptions in kernel. This basically @@ -43,13 +50,21 @@ int arch_register_cpu(int num) if (!num) cpu_devices[num].cpu.no_control = 1; - return register_cpu(&cpu_devices[num].cpu, num); + return register_cpu(&cpu_devices[num].cpu, num, parent); } #ifdef CONFIG_HOTPLUG_CPU void arch_unregister_cpu(int num) { - return unregister_cpu(&cpu_devices[num].cpu); + struct node *parent = NULL; + +#ifdef CONFIG_NUMA + int node = cpu_to_node(num); + if (node_online(node)) + parent = &node_devices[node].node; +#endif /* CONFIG_NUMA */ + + return unregister_cpu(&cpu_devices[num].cpu, parent); } EXPORT_SYMBOL(arch_register_cpu); EXPORT_SYMBOL(arch_unregister_cpu); @@ -59,13 +74,16 @@ EXPORT_SYMBOL(arch_unregister_cpu); #ifdef CONFIG_NUMA #include +#include + +struct i386_node node_devices[MAX_NUMNODES]; static int __init topology_init(void) { int i; for_each_online_node(i) - register_one_node(i); + arch_register_node(i); for_each_present_cpu(i) arch_register_cpu(i); diff --git a/trunk/arch/i386/kernel/vsyscall-sysenter.S b/trunk/arch/i386/kernel/vsyscall-sysenter.S index 1a36d26e15eb..3b62baa6a371 100644 --- a/trunk/arch/i386/kernel/vsyscall-sysenter.S +++ b/trunk/arch/i386/kernel/vsyscall-sysenter.S @@ -42,10 +42,10 @@ __kernel_vsyscall: /* 7: align return point with nop's to make disassembly easier */ .space 7,0x90 - /* 14: System call restart point is here! (SYSENTER_RETURN-2) */ + /* 14: System call restart point is here! (SYSENTER_RETURN - 2) */ jmp .Lenter_kernel /* 16: System call normal return point is here! */ - .globl SYSENTER_RETURN /* Symbol used by sysenter.c */ + .globl SYSENTER_RETURN /* Symbol used by entry.S. */ SYSENTER_RETURN: pop %ebp .Lpop_ebp: diff --git a/trunk/arch/i386/kernel/vsyscall.lds.S b/trunk/arch/i386/kernel/vsyscall.lds.S index e26975fc68b6..98699ca6e52d 100644 --- a/trunk/arch/i386/kernel/vsyscall.lds.S +++ b/trunk/arch/i386/kernel/vsyscall.lds.S @@ -7,7 +7,7 @@ SECTIONS { - . = VDSO_PRELINK + SIZEOF_HEADERS; + . = VSYSCALL_BASE + SIZEOF_HEADERS; .hash : { *(.hash) } :text .dynsym : { *(.dynsym) } @@ -20,7 +20,7 @@ SECTIONS For the layouts to match, we need to skip more than enough space for the dynamic symbol table et al. If this amount is insufficient, ld -shared will barf. Just increase it here. */ - . = VDSO_PRELINK + 0x400; + . = VSYSCALL_BASE + 0x400; .text : { *(.text) } :text =0x90909090 .note : { *(.note.*) } :text :note diff --git a/trunk/arch/i386/mach-visws/setup.c b/trunk/arch/i386/mach-visws/setup.c index 1f84cdb24779..8a9e1a6f745d 100644 --- a/trunk/arch/i386/mach-visws/setup.c +++ b/trunk/arch/i386/mach-visws/setup.c @@ -140,8 +140,8 @@ void __init time_init_hook(void) #define MB (1024 * 1024) -unsigned long sgivwfb_mem_phys; -unsigned long sgivwfb_mem_size; +static unsigned long sgivwfb_mem_phys; +static unsigned long sgivwfb_mem_size; long long mem_size __initdata = 0; @@ -177,4 +177,8 @@ char * __init machine_specific_memory_setup(void) add_memory_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); return "PROM"; + + /* Remove gcc warnings */ + (void) sanitize_e820_map(NULL, NULL); + (void) copy_e820_map(NULL, 0); } diff --git a/trunk/arch/i386/mach-visws/visws_apic.c b/trunk/arch/i386/mach-visws/visws_apic.c index c418521dd554..3e64fb721291 100644 --- a/trunk/arch/i386/mach-visws/visws_apic.c +++ b/trunk/arch/i386/mach-visws/visws_apic.c @@ -278,22 +278,22 @@ void init_VISWS_APIC_irqs(void) irq_desc[i].depth = 1; if (i == 0) { - irq_desc[i].chip = &cobalt_irq_type; + irq_desc[i].handler = &cobalt_irq_type; } else if (i == CO_IRQ_IDE0) { - irq_desc[i].chip = &cobalt_irq_type; + irq_desc[i].handler = &cobalt_irq_type; } else if (i == CO_IRQ_IDE1) { - irq_desc[i].chip = &cobalt_irq_type; + irq_desc[i].handler = &cobalt_irq_type; } else if (i == CO_IRQ_8259) { - irq_desc[i].chip = &piix4_master_irq_type; + irq_desc[i].handler = &piix4_master_irq_type; } else if (i < CO_IRQ_APIC0) { - irq_desc[i].chip = &piix4_virtual_irq_type; + irq_desc[i].handler = &piix4_virtual_irq_type; } else if (IS_CO_APIC(i)) { - irq_desc[i].chip = &cobalt_irq_type; + irq_desc[i].handler = &cobalt_irq_type; } } diff --git a/trunk/arch/i386/mach-voyager/setup.c b/trunk/arch/i386/mach-voyager/setup.c index defc6ebbd565..0e225054e222 100644 --- a/trunk/arch/i386/mach-voyager/setup.c +++ b/trunk/arch/i386/mach-voyager/setup.c @@ -5,10 +5,10 @@ #include #include #include +#include #include #include #include -#include #include void __init pre_intr_init_hook(void) @@ -27,7 +27,8 @@ void __init intr_init_hook(void) smp_intr_init(); #endif - setup_irq(2, &irq2); + if (!acpi_ioapic) + setup_irq(2, &irq2); } void __init pre_setup_arch_hook(void) diff --git a/trunk/arch/i386/mach-voyager/voyager_smp.c b/trunk/arch/i386/mach-voyager/voyager_smp.c index 5b8b579a079f..70e560a1b79a 100644 --- a/trunk/arch/i386/mach-voyager/voyager_smp.c +++ b/trunk/arch/i386/mach-voyager/voyager_smp.c @@ -661,7 +661,6 @@ do_boot_cpu(__u8 cpu) print_cpu_info(&cpu_data[cpu]); wmb(); cpu_set(cpu, cpu_callout_map); - cpu_set(cpu, cpu_present_map); } else { printk("CPU%d FAILED TO BOOT: ", cpu); @@ -1419,7 +1418,7 @@ smp_intr_init(void) * This is for later: first 16 correspond to PC IRQs; next 16 * are Primary MC IRQs and final 16 are Secondary MC IRQs */ for(i = 0; i < 48; i++) - irq_desc[i].chip = &vic_irq_type; + irq_desc[i].handler = &vic_irq_type; } /* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per @@ -1913,7 +1912,6 @@ void __devinit smp_prepare_boot_cpu(void) cpu_set(smp_processor_id(), cpu_online_map); cpu_set(smp_processor_id(), cpu_callout_map); cpu_set(smp_processor_id(), cpu_possible_map); - cpu_set(smp_processor_id(), cpu_present_map); } int __devinit diff --git a/trunk/arch/i386/mm/init.c b/trunk/arch/i386/mm/init.c index f84b16e007ff..bf19513f0cea 100644 --- a/trunk/arch/i386/mm/init.c +++ b/trunk/arch/i386/mm/init.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -655,7 +654,7 @@ void __init mem_init(void) */ #ifdef CONFIG_MEMORY_HOTPLUG #ifndef CONFIG_NEED_MULTIPLE_NODES -int arch_add_memory(int nid, u64 start, u64 size) +int add_memory(u64 start, u64 size) { struct pglist_data *pgdata = &contig_page_data; struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1; @@ -754,7 +753,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) for (addr = begin; addr < end; addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); - memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); + memset((void *)addr, 0xcc, PAGE_SIZE); free_page(addr); totalram_pages++; } diff --git a/trunk/arch/i386/mm/pageattr.c b/trunk/arch/i386/mm/pageattr.c index 353a836ed63c..0887b34bc59b 100644 --- a/trunk/arch/i386/mm/pageattr.c +++ b/trunk/arch/i386/mm/pageattr.c @@ -229,8 +229,8 @@ void kernel_map_pages(struct page *page, int numpages, int enable) if (PageHighMem(page)) return; if (!enable) - debug_check_no_locks_freed(page_address(page), - numpages * PAGE_SIZE); + mutex_debug_check_no_locks_freed(page_address(page), + numpages * PAGE_SIZE); /* the return value is ignored - the calls cannot fail, * large pages are disabled at boot time. diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index b487e227a1f7..18318749884b 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -271,9 +271,6 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. -config ARCH_ENABLE_MEMORY_HOTPLUG - def_bool y - config SCHED_SMT bool "SMT scheduler support" depends on SMP @@ -377,10 +374,6 @@ config HAVE_ARCH_EARLY_PFN_TO_NID def_bool y depends on NEED_MULTIPLE_NODES -config HAVE_ARCH_NODEDATA_EXTENSION - def_bool y - depends on NUMA - config IA32_SUPPORT bool "Support for Linux/x86 binaries" help @@ -492,10 +485,6 @@ config GENERIC_PENDING_IRQ depends on GENERIC_HARDIRQS && SMP default y -config IRQ_PER_CPU - bool - default y - source "arch/ia64/hp/sim/Kconfig" menu "Instrumentation Support" diff --git a/trunk/arch/ia64/configs/tiger_defconfig b/trunk/arch/ia64/configs/tiger_defconfig index 9d1cffb57cde..766bf4955432 100644 --- a/trunk/arch/ia64/configs/tiger_defconfig +++ b/trunk/arch/ia64/configs/tiger_defconfig @@ -114,7 +114,7 @@ CONFIG_IA64_CYCLONE=y CONFIG_IOSAPIC=y CONFIG_FORCE_MAX_ZONEORDER=17 CONFIG_SMP=y -CONFIG_NR_CPUS=16 +CONFIG_NR_CPUS=4 CONFIG_HOTPLUG_CPU=y CONFIG_PERMIT_BSP_REMOVE=y CONFIG_FORCE_CPEI_RETARGET=y diff --git a/trunk/arch/ia64/hp/sim/hpsim_irq.c b/trunk/arch/ia64/hp/sim/hpsim_irq.c index 8145547bb52d..c0d25a2a3e9c 100644 --- a/trunk/arch/ia64/hp/sim/hpsim_irq.c +++ b/trunk/arch/ia64/hp/sim/hpsim_irq.c @@ -44,8 +44,8 @@ hpsim_irq_init (void) int i; for (i = 0; i < NR_IRQS; ++i) { - idesc = irq_desc + i; - if (idesc->chip == &no_irq_type) - idesc->chip = &irq_type_hp_sim; + idesc = irq_descp(i); + if (idesc->handler == &no_irq_type) + idesc->handler = &irq_type_hp_sim; } } diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c index efc7df4b0fd2..d58c1c5c903a 100644 --- a/trunk/arch/ia64/kernel/iosapic.c +++ b/trunk/arch/ia64/kernel/iosapic.c @@ -456,7 +456,7 @@ iosapic_startup_edge_irq (unsigned int irq) static void iosapic_ack_edge_irq (unsigned int irq) { - irq_desc_t *idesc = irq_desc + irq; + irq_desc_t *idesc = irq_descp(irq); move_native_irq(irq); /* @@ -659,14 +659,14 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, else irq_type = &irq_type_iosapic_level; - idesc = irq_desc + vector; - if (idesc->chip != irq_type) { - if (idesc->chip != &no_irq_type) + idesc = irq_descp(vector); + if (idesc->handler != irq_type) { + if (idesc->handler != &no_irq_type) printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", __FUNCTION__, vector, - idesc->chip->typename, irq_type->typename); - idesc->chip = irq_type; + idesc->handler->typename, irq_type->typename); + idesc->handler = irq_type; } return 0; } @@ -793,14 +793,14 @@ iosapic_register_intr (unsigned int gsi, return -ENOSPC; } - spin_lock_irqsave(&irq_desc[vector].lock, flags); + spin_lock_irqsave(&irq_descp(vector)->lock, flags); spin_lock(&iosapic_lock); { if (gsi_to_vector(gsi) > 0) { if (list_empty(&iosapic_intr_info[vector].rtes)) free_irq_vector(vector); spin_unlock(&iosapic_lock); - spin_unlock_irqrestore(&irq_desc[vector].lock, + spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); goto again; } @@ -810,7 +810,7 @@ iosapic_register_intr (unsigned int gsi, polarity, trigger); if (err < 0) { spin_unlock(&iosapic_lock); - spin_unlock_irqrestore(&irq_desc[vector].lock, + spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); return err; } @@ -825,7 +825,7 @@ iosapic_register_intr (unsigned int gsi, set_rte(gsi, vector, dest, mask); } spin_unlock(&iosapic_lock); - spin_unlock_irqrestore(&irq_desc[vector].lock, flags); + spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), @@ -860,7 +860,7 @@ iosapic_unregister_intr (unsigned int gsi) } vector = irq_to_vector(irq); - idesc = irq_desc + irq; + idesc = irq_descp(irq); spin_lock_irqsave(&idesc->lock, flags); spin_lock(&iosapic_lock); { @@ -903,7 +903,7 @@ iosapic_unregister_intr (unsigned int gsi) BUG_ON(iosapic_intr_info[vector].count); /* Clear the interrupt controller descriptor */ - idesc->chip = &no_irq_type; + idesc->handler = &no_irq_type; /* Clear the interrupt information */ memset(&iosapic_intr_info[vector], 0, diff --git a/trunk/arch/ia64/kernel/irq.c b/trunk/arch/ia64/kernel/irq.c index 7852382de2fa..9c72ea3f6432 100644 --- a/trunk/arch/ia64/kernel/irq.c +++ b/trunk/arch/ia64/kernel/irq.c @@ -76,7 +76,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); } #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -100,7 +100,7 @@ void set_irq_affinity_info (unsigned int irq, int hwid, int redir) cpu_set(cpu_logical_id(hwid), mask); if (irq < NR_IRQS) { - irq_desc[irq].affinity = mask; + irq_affinity[irq] = mask; irq_redir[irq] = (char) (redir & 0xff); } } @@ -120,7 +120,7 @@ static void migrate_irqs(void) int irq, new_cpu; for (irq=0; irq < NR_IRQS; irq++) { - desc = irq_desc + irq; + desc = irq_descp(irq); /* * No handling for now. @@ -131,7 +131,7 @@ static void migrate_irqs(void) if (desc->status == IRQ_PER_CPU) continue; - cpus_and(mask, irq_desc[irq].affinity, cpu_online_map); + cpus_and(mask, irq_affinity[irq], cpu_online_map); if (any_online_cpu(mask) == NR_CPUS) { /* * Save it for phase 2 processing @@ -144,15 +144,15 @@ static void migrate_irqs(void) /* * Al three are essential, currently WARN_ON.. maybe panic? */ - if (desc->chip && desc->chip->disable && - desc->chip->enable && desc->chip->set_affinity) { - desc->chip->disable(irq); - desc->chip->set_affinity(irq, mask); - desc->chip->enable(irq); + if (desc->handler && desc->handler->disable && + desc->handler->enable && desc->handler->set_affinity) { + desc->handler->disable(irq); + desc->handler->set_affinity(irq, mask); + desc->handler->enable(irq); } else { - WARN_ON((!(desc->chip) || !(desc->chip->disable) || - !(desc->chip->enable) || - !(desc->chip->set_affinity))); + WARN_ON((!(desc->handler) || !(desc->handler->disable) || + !(desc->handler->enable) || + !(desc->handler->set_affinity))); } } } diff --git a/trunk/arch/ia64/kernel/irq_ia64.c b/trunk/arch/ia64/kernel/irq_ia64.c index f5035304594e..ef9a2b49307a 100644 --- a/trunk/arch/ia64/kernel/irq_ia64.c +++ b/trunk/arch/ia64/kernel/irq_ia64.c @@ -249,9 +249,9 @@ register_percpu_irq (ia64_vector vec, struct irqaction *action) for (irq = 0; irq < NR_IRQS; ++irq) if (irq_to_vector(irq) == vec) { - desc = irq_desc + irq; + desc = irq_descp(irq); desc->status |= IRQ_PER_CPU; - desc->chip = &irq_type_ia64_lsapic; + desc->handler = &irq_type_ia64_lsapic; if (action) setup_irq(irq, action); } diff --git a/trunk/arch/ia64/kernel/irq_lsapic.c b/trunk/arch/ia64/kernel/irq_lsapic.c index 1ab58b09f3d7..ea14e6a04409 100644 --- a/trunk/arch/ia64/kernel/irq_lsapic.c +++ b/trunk/arch/ia64/kernel/irq_lsapic.c @@ -26,13 +26,6 @@ lsapic_noop (unsigned int irq) /* nuthing to do... */ } -static int lsapic_retrigger(unsigned int irq) -{ - ia64_resend_irq(irq); - - return 1; -} - struct hw_interrupt_type irq_type_ia64_lsapic = { .typename = "LSAPIC", .startup = lsapic_noop_startup, @@ -40,6 +33,5 @@ struct hw_interrupt_type irq_type_ia64_lsapic = { .enable = lsapic_noop, .disable = lsapic_noop, .ack = lsapic_noop, - .end = lsapic_noop, - .retrigger = lsapic_retrigger, + .end = lsapic_noop }; diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index d7dc5e63de63..6a0880639bc9 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -1788,7 +1788,7 @@ ia64_mca_late_init(void) cpe_poll_enabled = 0; for (irq = 0; irq < NR_IRQS; ++irq) if (irq_to_vector(irq) == cpe_vector) { - desc = irq_desc + irq; + desc = irq_descp(irq); desc->status |= IRQ_PER_CPU; setup_irq(irq, &mca_cpe_irqaction); ia64_cpe_irq = irq; diff --git a/trunk/arch/ia64/kernel/palinfo.c b/trunk/arch/ia64/kernel/palinfo.c index 8a1208419138..859fb37ff49b 100644 --- a/trunk/arch/ia64/kernel/palinfo.c +++ b/trunk/arch/ia64/kernel/palinfo.c @@ -959,7 +959,7 @@ remove_palinfo_proc_entries(unsigned int hcpu) } } -static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, +static int palinfo_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -978,7 +978,7 @@ static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata palinfo_cpu_notifier = +static struct notifier_block palinfo_cpu_notifier = { .notifier_call = palinfo_cpu_callback, .priority = 0, @@ -998,7 +998,7 @@ palinfo_init(void) } /* Register for future delivery via notify registration */ - register_hotcpu_notifier(&palinfo_cpu_notifier); + register_cpu_notifier(&palinfo_cpu_notifier); return 0; } diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index a0055d3d695c..6d7bc8ff7b3a 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -6165,7 +6165,7 @@ pfm_load_regs (struct task_struct *task) /* * will replay the PMU interrupt */ - if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR); + if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR); pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; } @@ -6305,7 +6305,7 @@ pfm_load_regs (struct task_struct *task) /* * will replay the PMU interrupt */ - if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR); + if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR); pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; } diff --git a/trunk/arch/ia64/kernel/salinfo.c b/trunk/arch/ia64/kernel/salinfo.c index 9065f0f01ba3..663a186ad194 100644 --- a/trunk/arch/ia64/kernel/salinfo.c +++ b/trunk/arch/ia64/kernel/salinfo.c @@ -572,7 +572,7 @@ static struct file_operations salinfo_data_fops = { }; #ifdef CONFIG_HOTPLUG_CPU -static int __devinit +static int salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) { unsigned int i, cpu = (unsigned long)hcpu; @@ -673,7 +673,9 @@ salinfo_init(void) salinfo_timer.function = &salinfo_timeout; add_timer(&salinfo_timer); - register_hotcpu_notifier(&salinfo_cpu_notifier); +#ifdef CONFIG_HOTPLUG_CPU + register_cpu_notifier(&salinfo_cpu_notifier); +#endif return 0; } diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index 5203df78f150..44e9547878ac 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -677,16 +677,16 @@ int migrate_platform_irqs(unsigned int cpu) new_cpei_cpu = any_online_cpu(cpu_online_map); mask = cpumask_of_cpu(new_cpei_cpu); set_cpei_target_cpu(new_cpei_cpu); - desc = irq_desc + ia64_cpe_irq; + desc = irq_descp(ia64_cpe_irq); /* * Switch for now, immediatly, we need to do fake intr * as other interrupts, but need to study CPEI behaviour with * polling before making changes. */ if (desc) { - desc->chip->disable(ia64_cpe_irq); - desc->chip->set_affinity(ia64_cpe_irq, mask); - desc->chip->enable(ia64_cpe_irq); + desc->handler->disable(ia64_cpe_irq); + desc->handler->set_affinity(ia64_cpe_irq, mask); + desc->handler->enable(ia64_cpe_irq); printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu); } } diff --git a/trunk/arch/ia64/kernel/topology.c b/trunk/arch/ia64/kernel/topology.c index 5511d9c6c701..879edb51d1e0 100644 --- a/trunk/arch/ia64/kernel/topology.c +++ b/trunk/arch/ia64/kernel/topology.c @@ -26,10 +26,19 @@ #include #include +#ifdef CONFIG_NUMA +static struct node *sysfs_nodes; +#endif static struct ia64_cpu *sysfs_cpus; int arch_register_cpu(int num) { + struct node *parent = NULL; + +#ifdef CONFIG_NUMA + parent = &sysfs_nodes[cpu_to_node(num)]; +#endif /* CONFIG_NUMA */ + #if defined (CONFIG_ACPI) && defined (CONFIG_HOTPLUG_CPU) /* * If CPEI cannot be re-targetted, and this is @@ -39,14 +48,21 @@ int arch_register_cpu(int num) sysfs_cpus[num].cpu.no_control = 1; #endif - return register_cpu(&sysfs_cpus[num].cpu, num); + return register_cpu(&sysfs_cpus[num].cpu, num, parent); } #ifdef CONFIG_HOTPLUG_CPU void arch_unregister_cpu(int num) { - return unregister_cpu(&sysfs_cpus[num].cpu); + struct node *parent = NULL; + +#ifdef CONFIG_NUMA + int node = cpu_to_node(num); + parent = &sysfs_nodes[node]; +#endif /* CONFIG_NUMA */ + + return unregister_cpu(&sysfs_cpus[num].cpu, parent); } EXPORT_SYMBOL(arch_register_cpu); EXPORT_SYMBOL(arch_unregister_cpu); @@ -58,11 +74,17 @@ static int __init topology_init(void) int i, err = 0; #ifdef CONFIG_NUMA + sysfs_nodes = kzalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL); + if (!sysfs_nodes) { + err = -ENOMEM; + goto out; + } + /* * MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes? */ for_each_online_node(i) { - if ((err = register_one_node(i))) + if ((err = register_node(&sysfs_nodes[i], i, 0))) goto out; } #endif @@ -404,7 +426,7 @@ static int __cpuinit cache_remove_dev(struct sys_device * sys_dev) * When a cpu is hot-plugged, do a check and initiate * cache kobject if necessary */ -static int __cpuinit cache_cpu_callback(struct notifier_block *nfb, +static int cache_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -422,7 +444,7 @@ static int __cpuinit cache_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata cache_cpu_notifier = +static struct notifier_block cache_cpu_notifier = { .notifier_call = cache_cpu_callback }; diff --git a/trunk/arch/ia64/mm/discontig.c b/trunk/arch/ia64/mm/discontig.c index 525b082eb661..b6bcc9fa3603 100644 --- a/trunk/arch/ia64/mm/discontig.c +++ b/trunk/arch/ia64/mm/discontig.c @@ -33,6 +33,7 @@ */ struct early_node_data { struct ia64_node_data *node_data; + pg_data_t *pgdat; unsigned long pernode_addr; unsigned long pernode_size; struct bootmem_data bootmem_data; @@ -45,8 +46,6 @@ struct early_node_data { static struct early_node_data mem_data[MAX_NUMNODES] __initdata; static nodemask_t memory_less_mask __initdata; -static pg_data_t *pgdat_list[MAX_NUMNODES]; - /* * To prevent cache aliasing effects, align per-node structures so that they * start at addresses that are strided by node number. @@ -100,7 +99,7 @@ static int __init build_node_maps(unsigned long start, unsigned long len, * acpi_boot_init() (which builds the node_to_cpu_mask array) hasn't been * called yet. Note that node 0 will also count all non-existent cpus. */ -static int __meminit early_nr_cpus_node(int node) +static int __init early_nr_cpus_node(int node) { int cpu, n = 0; @@ -115,7 +114,7 @@ static int __meminit early_nr_cpus_node(int node) * compute_pernodesize - compute size of pernode data * @node: the node id. */ -static unsigned long __meminit compute_pernodesize(int node) +static unsigned long __init compute_pernodesize(int node) { unsigned long pernodesize = 0, cpus; @@ -176,13 +175,13 @@ static void __init fill_pernode(int node, unsigned long pernode, pernode += PERCPU_PAGE_SIZE * cpus; pernode += node * L1_CACHE_BYTES; - pgdat_list[node] = __va(pernode); + mem_data[node].pgdat = __va(pernode); pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); mem_data[node].node_data = __va(pernode); pernode += L1_CACHE_ALIGN(sizeof(struct ia64_node_data)); - pgdat_list[node]->bdata = bdp; + mem_data[node].pgdat->bdata = bdp; pernode += L1_CACHE_ALIGN(sizeof(pg_data_t)); cpu_data = per_cpu_node_setup(cpu_data, node); @@ -269,7 +268,7 @@ static int __init find_pernode_space(unsigned long start, unsigned long len, static int __init free_node_bootmem(unsigned long start, unsigned long len, int node) { - free_bootmem_node(pgdat_list[node], start, len); + free_bootmem_node(mem_data[node].pgdat, start, len); return 0; } @@ -288,7 +287,7 @@ static void __init reserve_pernode_space(void) int node; for_each_online_node(node) { - pg_data_t *pdp = pgdat_list[node]; + pg_data_t *pdp = mem_data[node].pgdat; if (node_isset(node, memory_less_mask)) continue; @@ -308,17 +307,6 @@ static void __init reserve_pernode_space(void) } } -static void __meminit scatter_node_data(void) -{ - pg_data_t **dst; - int node; - - for_each_online_node(node) { - dst = LOCAL_DATA_ADDR(pgdat_list[node])->pg_data_ptrs; - memcpy(dst, pgdat_list, sizeof(pgdat_list)); - } -} - /** * initialize_pernode_data - fixup per-cpu & per-node pointers * @@ -329,10 +317,17 @@ static void __meminit scatter_node_data(void) */ static void __init initialize_pernode_data(void) { + pg_data_t *pgdat_list[MAX_NUMNODES]; int cpu, node; - scatter_node_data(); + for_each_online_node(node) + pgdat_list[node] = mem_data[node].pgdat; + /* Copy the pg_data_t list to each node and init the node field */ + for_each_online_node(node) { + memcpy(mem_data[node].node_data->pg_data_ptrs, pgdat_list, + sizeof(pgdat_list)); + } #ifdef CONFIG_SMP /* Set the node_data pointer for each per-cpu struct */ for (cpu = 0; cpu < NR_CPUS; cpu++) { @@ -377,7 +372,7 @@ static void __init *memory_less_node_alloc(int nid, unsigned long pernodesize) if (bestnode == -1) bestnode = anynode; - ptr = __alloc_bootmem_node(pgdat_list[bestnode], pernodesize, + ptr = __alloc_bootmem_node(mem_data[bestnode].pgdat, pernodesize, PERCPU_PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); return ptr; @@ -481,7 +476,7 @@ void __init find_memory(void) pernodesize = mem_data[node].pernode_size; map = pernode + pernodesize; - init_bootmem_node(pgdat_list[node], + init_bootmem_node(mem_data[node].pgdat, map>>PAGE_SHIFT, bdp->node_boot_start>>PAGE_SHIFT, bdp->node_low_pfn); @@ -791,21 +786,3 @@ void __init paging_init(void) zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page)); } - -pg_data_t *arch_alloc_nodedata(int nid) -{ - unsigned long size = compute_pernodesize(nid); - - return kzalloc(size, GFP_KERNEL); -} - -void arch_free_nodedata(pg_data_t *pgdat) -{ - kfree(pgdat); -} - -void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat) -{ - pgdat_list[update_node] = update_pgdat; - scatter_node_data(); -} diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c index 38306e98f04b..11f08001f8c2 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -652,7 +652,7 @@ void online_page(struct page *page) num_physpages++; } -int arch_add_memory(int nid, u64 start, u64 size) +int add_memory(u64 start, u64 size) { pg_data_t *pgdat; struct zone *zone; @@ -660,7 +660,7 @@ int arch_add_memory(int nid, u64 start, u64 size) unsigned long nr_pages = size >> PAGE_SHIFT; int ret; - pgdat = NODE_DATA(nid); + pgdat = NODE_DATA(0); zone = pgdat->node_zones + ZONE_NORMAL; ret = __add_pages(zone, start_pfn, nr_pages); @@ -671,6 +671,7 @@ int arch_add_memory(int nid, u64 start, u64 size) return ret; } +EXPORT_SYMBOL_GPL(add_memory); int remove_memory(u64 start, u64 size) { diff --git a/trunk/arch/ia64/sn/kernel/irq.c b/trunk/arch/ia64/sn/kernel/irq.c index 7bb6ad188ba3..dc8e2b696713 100644 --- a/trunk/arch/ia64/sn/kernel/irq.c +++ b/trunk/arch/ia64/sn/kernel/irq.c @@ -27,7 +27,7 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info); int sn_force_interrupt_flag = 1; extern int sn_ioif_inited; struct list_head **sn_irq_lh; -static DEFINE_SPINLOCK(sn_irq_info_lock); /* non-IRQ lock */ +static spinlock_t sn_irq_info_lock = SPIN_LOCK_UNLOCKED; /* non-IRQ lock */ u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, struct sn_irq_info *sn_irq_info, @@ -225,8 +225,8 @@ void sn_irq_init(void) ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR; for (i = 0; i < NR_IRQS; i++) { - if (base_desc[i].chip == &no_irq_type) { - base_desc[i].chip = &irq_type_sn; + if (base_desc[i].handler == &no_irq_type) { + base_desc[i].handler = &irq_type_sn; } } } diff --git a/trunk/arch/ia64/sn/kernel/setup.c b/trunk/arch/ia64/sn/kernel/setup.c index 3bfccf354343..93577abae36d 100644 --- a/trunk/arch/ia64/sn/kernel/setup.c +++ b/trunk/arch/ia64/sn/kernel/setup.c @@ -458,7 +458,7 @@ void __init sn_setup(char **cmdline_p) * support here so we don't have to listen to failed keyboard probe * messages. */ - if (is_shub1() && version <= 0x0209 && acpi_kbd_controller_present) { + if (version <= 0x0209 && acpi_kbd_controller_present) { printk(KERN_INFO "Disabling legacy keyboard support as prom " "is too old and doesn't provide FADT\n"); acpi_kbd_controller_present = 0; @@ -577,8 +577,7 @@ void __init sn_cpu_init(void) int i; static int wars_have_been_checked; - cpuid = smp_processor_id(); - if (cpuid == 0 && IS_MEDUSA()) { + if (smp_processor_id() == 0 && IS_MEDUSA()) { if (ia64_sn_is_fake_prom()) sn_prom_type = 2; else @@ -597,12 +596,6 @@ void __init sn_cpu_init(void) BUG(); sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2; - /* - * Don't check status. The SAL call is not supported on all PROMs - * but a failure is harmless. - */ - (void) ia64_sn_set_cpu_number(cpuid); - /* * The boot cpu makes this call again after platform initialization is * complete. @@ -614,6 +607,7 @@ void __init sn_cpu_init(void) if (ia64_sn_get_prom_feature_set(i, &sn_prom_features[i]) != 0) break; + cpuid = smp_processor_id(); cpuphyid = get_sapicid(); if (ia64_sn_get_sapic_info(cpuphyid, &nasid, &subnode, &slice)) diff --git a/trunk/arch/ia64/sn/pci/tioca_provider.c b/trunk/arch/ia64/sn/pci/tioca_provider.c index e4aa839d0189..20de72791b97 100644 --- a/trunk/arch/ia64/sn/pci/tioca_provider.c +++ b/trunk/arch/ia64/sn/pci/tioca_provider.c @@ -595,7 +595,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont /* sanity check prom rev */ - if (is_shub1() && sn_sal_rev() < 0x0406) { + if (sn_sal_rev() < 0x0406) { printk (KERN_ERR "%s: SGI prom rev 4.06 or greater required " "for tioca support\n", __FUNCTION__); diff --git a/trunk/arch/m32r/kernel/irq.c b/trunk/arch/m32r/kernel/irq.c index 3841861df6a2..a4634b06f675 100644 --- a/trunk/arch/m32r/kernel/irq.c +++ b/trunk/arch/m32r/kernel/irq.c @@ -54,7 +54,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/trunk/arch/m32r/kernel/setup.c b/trunk/arch/m32r/kernel/setup.c index 1ff483c8a4c9..3cd3c2988a48 100644 --- a/trunk/arch/m32r/kernel/setup.c +++ b/trunk/arch/m32r/kernel/setup.c @@ -275,7 +275,7 @@ static int __init topology_init(void) int i; for_each_present_cpu(i) - register_cpu(&cpu_devices[i], i); + register_cpu(&cpu_devices[i], i, NULL); return 0; } diff --git a/trunk/arch/m32r/kernel/setup_m32104ut.c b/trunk/arch/m32r/kernel/setup_m32104ut.c index f9f56c270195..6328e1357a80 100644 --- a/trunk/arch/m32r/kernel/setup_m32104ut.c +++ b/trunk/arch/m32r/kernel/setup_m32104ut.c @@ -87,7 +87,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT#0: LAN controller on M32104UT-LAN (SMC91C111)*/ irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT0].chip = &m32104ut_irq_type; + irq_desc[M32R_IRQ_INT0].handler = &m32104ut_irq_type; irq_desc[M32R_IRQ_INT0].action = 0; irq_desc[M32R_IRQ_INT0].depth = 1; icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD11; /* "H" level sense */ @@ -96,7 +96,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].chip = &m32104ut_irq_type; + irq_desc[M32R_IRQ_MFT2].handler = &m32104ut_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -105,7 +105,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].chip = &m32104ut_irq_type; + irq_desc[M32R_IRQ_SIO0_R].handler = &m32104ut_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = M32R_ICUCR_IEN; @@ -113,7 +113,7 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].chip = &m32104ut_irq_type; + irq_desc[M32R_IRQ_SIO0_S].handler = &m32104ut_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = M32R_ICUCR_IEN; diff --git a/trunk/arch/m32r/kernel/setup_m32700ut.c b/trunk/arch/m32r/kernel/setup_m32700ut.c index b6ab00eff580..fad1fc99bb27 100644 --- a/trunk/arch/m32r/kernel/setup_m32700ut.c +++ b/trunk/arch/m32r/kernel/setup_m32700ut.c @@ -301,7 +301,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT#0: LAN controller on M32700UT-LAN (SMC91C111)*/ irq_desc[M32700UT_LAN_IRQ_LAN].status = IRQ_DISABLED; - irq_desc[M32700UT_LAN_IRQ_LAN].chip = &m32700ut_lanpld_irq_type; + irq_desc[M32700UT_LAN_IRQ_LAN].handler = &m32700ut_lanpld_irq_type; irq_desc[M32700UT_LAN_IRQ_LAN].action = 0; irq_desc[M32700UT_LAN_IRQ_LAN].depth = 1; /* disable nested irq */ lanpld_icu_data[irq2lanpldirq(M32700UT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ @@ -310,7 +310,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].chip = &m32700ut_irq_type; + irq_desc[M32R_IRQ_MFT2].handler = &m32700ut_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -318,7 +318,7 @@ void __init init_IRQ(void) /* SIO0 : receive */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].chip = &m32700ut_irq_type; + irq_desc[M32R_IRQ_SIO0_R].handler = &m32700ut_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -326,7 +326,7 @@ void __init init_IRQ(void) /* SIO0 : send */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].chip = &m32700ut_irq_type; + irq_desc[M32R_IRQ_SIO0_S].handler = &m32700ut_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -334,7 +334,7 @@ void __init init_IRQ(void) /* SIO1 : receive */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].chip = &m32700ut_irq_type; + irq_desc[M32R_IRQ_SIO1_R].handler = &m32700ut_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -342,7 +342,7 @@ void __init init_IRQ(void) /* SIO1 : send */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].chip = &m32700ut_irq_type; + irq_desc[M32R_IRQ_SIO1_S].handler = &m32700ut_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -350,7 +350,7 @@ void __init init_IRQ(void) /* DMA1 : */ irq_desc[M32R_IRQ_DMA1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_DMA1].chip = &m32700ut_irq_type; + irq_desc[M32R_IRQ_DMA1].handler = &m32700ut_irq_type; irq_desc[M32R_IRQ_DMA1].action = 0; irq_desc[M32R_IRQ_DMA1].depth = 1; icu_data[M32R_IRQ_DMA1].icucr = 0; @@ -359,7 +359,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_PLDSIO /* INT#1: SIO0 Receive on PLD */ irq_desc[PLD_IRQ_SIO0_RCV].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SIO0_RCV].chip = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_SIO0_RCV].handler = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_SIO0_RCV].action = 0; irq_desc[PLD_IRQ_SIO0_RCV].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; @@ -367,7 +367,7 @@ void __init init_IRQ(void) /* INT#1: SIO0 Send on PLD */ irq_desc[PLD_IRQ_SIO0_SND].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SIO0_SND].chip = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_SIO0_SND].handler = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_SIO0_SND].action = 0; irq_desc[PLD_IRQ_SIO0_SND].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; @@ -376,7 +376,7 @@ void __init init_IRQ(void) /* INT#1: CFC IREQ on PLD */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFIREQ].chip = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_CFIREQ].handler = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ @@ -384,7 +384,7 @@ void __init init_IRQ(void) /* INT#1: CFC Insert on PLD */ irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_INSERT].chip = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_CFC_INSERT].handler = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_CFC_INSERT].action = 0; irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ @@ -392,7 +392,7 @@ void __init init_IRQ(void) /* INT#1: CFC Eject on PLD */ irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_EJECT].chip = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_CFC_EJECT].handler = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_CFC_EJECT].action = 0; irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ @@ -416,7 +416,7 @@ void __init init_IRQ(void) outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ irq_desc[M32700UT_LCD_IRQ_USB_INT1].status = IRQ_DISABLED; - irq_desc[M32700UT_LCD_IRQ_USB_INT1].chip = &m32700ut_lcdpld_irq_type; + irq_desc[M32700UT_LCD_IRQ_USB_INT1].handler = &m32700ut_lcdpld_irq_type; irq_desc[M32700UT_LCD_IRQ_USB_INT1].action = 0; irq_desc[M32700UT_LCD_IRQ_USB_INT1].depth = 1; lcdpld_icu_data[irq2lcdpldirq(M32700UT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ @@ -434,7 +434,7 @@ void __init init_IRQ(void) * INT3# is used for AR */ irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT3].chip = &m32700ut_irq_type; + irq_desc[M32R_IRQ_INT3].handler = &m32700ut_irq_type; irq_desc[M32R_IRQ_INT3].action = 0; irq_desc[M32R_IRQ_INT3].depth = 1; icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; diff --git a/trunk/arch/m32r/kernel/setup_mappi.c b/trunk/arch/m32r/kernel/setup_mappi.c index c268044185f5..00f253209cb3 100644 --- a/trunk/arch/m32r/kernel/setup_mappi.c +++ b/trunk/arch/m32r/kernel/setup_mappi.c @@ -86,7 +86,7 @@ void __init init_IRQ(void) #ifdef CONFIG_NE2000 /* INT0 : LAN controller (RTL8019AS) */ irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT0].chip = &mappi_irq_type; + irq_desc[M32R_IRQ_INT0].handler = &mappi_irq_type; irq_desc[M32R_IRQ_INT0].action = 0; irq_desc[M32R_IRQ_INT0].depth = 1; icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; @@ -95,7 +95,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].chip = &mappi_irq_type; + irq_desc[M32R_IRQ_MFT2].handler = &mappi_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -104,7 +104,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].chip = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO0_R].handler = &mappi_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -112,7 +112,7 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].chip = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO0_S].handler = &mappi_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -120,7 +120,7 @@ void __init init_IRQ(void) /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].chip = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO1_R].handler = &mappi_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -128,7 +128,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].chip = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO1_S].handler = &mappi_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -138,7 +138,7 @@ void __init init_IRQ(void) #if defined(CONFIG_M32R_PCC) /* INT1 : pccard0 interrupt */ irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT1].chip = &mappi_irq_type; + irq_desc[M32R_IRQ_INT1].handler = &mappi_irq_type; irq_desc[M32R_IRQ_INT1].action = 0; irq_desc[M32R_IRQ_INT1].depth = 1; icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; @@ -146,7 +146,7 @@ void __init init_IRQ(void) /* INT2 : pccard1 interrupt */ irq_desc[M32R_IRQ_INT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT2].chip = &mappi_irq_type; + irq_desc[M32R_IRQ_INT2].handler = &mappi_irq_type; irq_desc[M32R_IRQ_INT2].action = 0; irq_desc[M32R_IRQ_INT2].depth = 1; icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; diff --git a/trunk/arch/m32r/kernel/setup_mappi2.c b/trunk/arch/m32r/kernel/setup_mappi2.c index bd2327d5cca2..eebc9d8b4e72 100644 --- a/trunk/arch/m32r/kernel/setup_mappi2.c +++ b/trunk/arch/m32r/kernel/setup_mappi2.c @@ -87,7 +87,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT0 : LAN controller (SMC91111) */ irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT0].chip = &mappi2_irq_type; + irq_desc[M32R_IRQ_INT0].handler = &mappi2_irq_type; irq_desc[M32R_IRQ_INT0].action = 0; irq_desc[M32R_IRQ_INT0].depth = 1; icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; @@ -96,7 +96,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].chip = &mappi2_irq_type; + irq_desc[M32R_IRQ_MFT2].handler = &mappi2_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -105,7 +105,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].chip = &mappi2_irq_type; + irq_desc[M32R_IRQ_SIO0_R].handler = &mappi2_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -113,14 +113,14 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].chip = &mappi2_irq_type; + irq_desc[M32R_IRQ_SIO0_S].handler = &mappi2_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; disable_mappi2_irq(M32R_IRQ_SIO0_S); /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].chip = &mappi2_irq_type; + irq_desc[M32R_IRQ_SIO1_R].handler = &mappi2_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -128,7 +128,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].chip = &mappi2_irq_type; + irq_desc[M32R_IRQ_SIO1_S].handler = &mappi2_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -138,7 +138,7 @@ void __init init_IRQ(void) #if defined(CONFIG_USB) /* INT1 : USB Host controller interrupt */ irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT1].chip = &mappi2_irq_type; + irq_desc[M32R_IRQ_INT1].handler = &mappi2_irq_type; irq_desc[M32R_IRQ_INT1].action = 0; irq_desc[M32R_IRQ_INT1].depth = 1; icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; @@ -147,7 +147,7 @@ void __init init_IRQ(void) /* ICUCR40: CFC IREQ */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFIREQ].chip = &mappi2_irq_type; + irq_desc[PLD_IRQ_CFIREQ].handler = &mappi2_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; @@ -156,7 +156,7 @@ void __init init_IRQ(void) #if defined(CONFIG_M32R_CFC) /* ICUCR41: CFC Insert */ irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_INSERT].chip = &mappi2_irq_type; + irq_desc[PLD_IRQ_CFC_INSERT].handler = &mappi2_irq_type; irq_desc[PLD_IRQ_CFC_INSERT].action = 0; irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; @@ -164,7 +164,7 @@ void __init init_IRQ(void) /* ICUCR42: CFC Eject */ irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_EJECT].chip = &mappi2_irq_type; + irq_desc[PLD_IRQ_CFC_EJECT].handler = &mappi2_irq_type; irq_desc[PLD_IRQ_CFC_EJECT].action = 0; irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; diff --git a/trunk/arch/m32r/kernel/setup_mappi3.c b/trunk/arch/m32r/kernel/setup_mappi3.c index 014b51d17505..d2ff021e2d3d 100644 --- a/trunk/arch/m32r/kernel/setup_mappi3.c +++ b/trunk/arch/m32r/kernel/setup_mappi3.c @@ -87,7 +87,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT0 : LAN controller (SMC91111) */ irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT0].chip = &mappi3_irq_type; + irq_desc[M32R_IRQ_INT0].handler = &mappi3_irq_type; irq_desc[M32R_IRQ_INT0].action = 0; irq_desc[M32R_IRQ_INT0].depth = 1; icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; @@ -96,7 +96,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].chip = &mappi3_irq_type; + irq_desc[M32R_IRQ_MFT2].handler = &mappi3_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -105,7 +105,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].chip = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO0_R].handler = &mappi3_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -113,14 +113,14 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].chip = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO0_S].handler = &mappi3_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; disable_mappi3_irq(M32R_IRQ_SIO0_S); /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].chip = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO1_R].handler = &mappi3_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -128,7 +128,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].chip = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO1_S].handler = &mappi3_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -138,7 +138,7 @@ void __init init_IRQ(void) #if defined(CONFIG_USB) /* INT1 : USB Host controller interrupt */ irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT1].chip = &mappi3_irq_type; + irq_desc[M32R_IRQ_INT1].handler = &mappi3_irq_type; irq_desc[M32R_IRQ_INT1].action = 0; irq_desc[M32R_IRQ_INT1].depth = 1; icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; @@ -147,7 +147,7 @@ void __init init_IRQ(void) /* CFC IREQ */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFIREQ].chip = &mappi3_irq_type; + irq_desc[PLD_IRQ_CFIREQ].handler = &mappi3_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; @@ -156,7 +156,7 @@ void __init init_IRQ(void) #if defined(CONFIG_M32R_CFC) /* ICUCR41: CFC Insert & eject */ irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_INSERT].chip = &mappi3_irq_type; + irq_desc[PLD_IRQ_CFC_INSERT].handler = &mappi3_irq_type; irq_desc[PLD_IRQ_CFC_INSERT].action = 0; irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; @@ -166,7 +166,7 @@ void __init init_IRQ(void) /* IDE IREQ */ irq_desc[PLD_IRQ_IDEIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_IDEIREQ].chip = &mappi3_irq_type; + irq_desc[PLD_IRQ_IDEIREQ].handler = &mappi3_irq_type; irq_desc[PLD_IRQ_IDEIREQ].action = 0; irq_desc[PLD_IRQ_IDEIREQ].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_IDEIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; diff --git a/trunk/arch/m32r/kernel/setup_oaks32r.c b/trunk/arch/m32r/kernel/setup_oaks32r.c index ea64831aef7a..0e9e63538c0f 100644 --- a/trunk/arch/m32r/kernel/setup_oaks32r.c +++ b/trunk/arch/m32r/kernel/setup_oaks32r.c @@ -85,7 +85,7 @@ void __init init_IRQ(void) #ifdef CONFIG_NE2000 /* INT3 : LAN controller (RTL8019AS) */ irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT3].chip = &oaks32r_irq_type; + irq_desc[M32R_IRQ_INT3].handler = &oaks32r_irq_type; irq_desc[M32R_IRQ_INT3].action = 0; irq_desc[M32R_IRQ_INT3].depth = 1; icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; @@ -94,7 +94,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].chip = &oaks32r_irq_type; + irq_desc[M32R_IRQ_MFT2].handler = &oaks32r_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -103,7 +103,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].chip = &oaks32r_irq_type; + irq_desc[M32R_IRQ_SIO0_R].handler = &oaks32r_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -111,7 +111,7 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].chip = &oaks32r_irq_type; + irq_desc[M32R_IRQ_SIO0_S].handler = &oaks32r_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -119,7 +119,7 @@ void __init init_IRQ(void) /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].chip = &oaks32r_irq_type; + irq_desc[M32R_IRQ_SIO1_R].handler = &oaks32r_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -127,7 +127,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].chip = &oaks32r_irq_type; + irq_desc[M32R_IRQ_SIO1_S].handler = &oaks32r_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; diff --git a/trunk/arch/m32r/kernel/setup_opsput.c b/trunk/arch/m32r/kernel/setup_opsput.c index 55e8972d455a..548e8fc7949b 100644 --- a/trunk/arch/m32r/kernel/setup_opsput.c +++ b/trunk/arch/m32r/kernel/setup_opsput.c @@ -302,7 +302,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT#0: LAN controller on OPSPUT-LAN (SMC91C111)*/ irq_desc[OPSPUT_LAN_IRQ_LAN].status = IRQ_DISABLED; - irq_desc[OPSPUT_LAN_IRQ_LAN].chip = &opsput_lanpld_irq_type; + irq_desc[OPSPUT_LAN_IRQ_LAN].handler = &opsput_lanpld_irq_type; irq_desc[OPSPUT_LAN_IRQ_LAN].action = 0; irq_desc[OPSPUT_LAN_IRQ_LAN].depth = 1; /* disable nested irq */ lanpld_icu_data[irq2lanpldirq(OPSPUT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ @@ -311,7 +311,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].chip = &opsput_irq_type; + irq_desc[M32R_IRQ_MFT2].handler = &opsput_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -319,7 +319,7 @@ void __init init_IRQ(void) /* SIO0 : receive */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].chip = &opsput_irq_type; + irq_desc[M32R_IRQ_SIO0_R].handler = &opsput_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -327,7 +327,7 @@ void __init init_IRQ(void) /* SIO0 : send */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].chip = &opsput_irq_type; + irq_desc[M32R_IRQ_SIO0_S].handler = &opsput_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -335,7 +335,7 @@ void __init init_IRQ(void) /* SIO1 : receive */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].chip = &opsput_irq_type; + irq_desc[M32R_IRQ_SIO1_R].handler = &opsput_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -343,7 +343,7 @@ void __init init_IRQ(void) /* SIO1 : send */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].chip = &opsput_irq_type; + irq_desc[M32R_IRQ_SIO1_S].handler = &opsput_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -351,7 +351,7 @@ void __init init_IRQ(void) /* DMA1 : */ irq_desc[M32R_IRQ_DMA1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_DMA1].chip = &opsput_irq_type; + irq_desc[M32R_IRQ_DMA1].handler = &opsput_irq_type; irq_desc[M32R_IRQ_DMA1].action = 0; irq_desc[M32R_IRQ_DMA1].depth = 1; icu_data[M32R_IRQ_DMA1].icucr = 0; @@ -360,7 +360,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_PLDSIO /* INT#1: SIO0 Receive on PLD */ irq_desc[PLD_IRQ_SIO0_RCV].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SIO0_RCV].chip = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_SIO0_RCV].handler = &opsput_pld_irq_type; irq_desc[PLD_IRQ_SIO0_RCV].action = 0; irq_desc[PLD_IRQ_SIO0_RCV].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; @@ -368,7 +368,7 @@ void __init init_IRQ(void) /* INT#1: SIO0 Send on PLD */ irq_desc[PLD_IRQ_SIO0_SND].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SIO0_SND].chip = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_SIO0_SND].handler = &opsput_pld_irq_type; irq_desc[PLD_IRQ_SIO0_SND].action = 0; irq_desc[PLD_IRQ_SIO0_SND].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; @@ -378,7 +378,7 @@ void __init init_IRQ(void) #if defined(CONFIG_M32R_CFC) /* INT#1: CFC IREQ on PLD */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFIREQ].chip = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_CFIREQ].handler = &opsput_pld_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ @@ -386,7 +386,7 @@ void __init init_IRQ(void) /* INT#1: CFC Insert on PLD */ irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_INSERT].chip = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_CFC_INSERT].handler = &opsput_pld_irq_type; irq_desc[PLD_IRQ_CFC_INSERT].action = 0; irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ @@ -394,7 +394,7 @@ void __init init_IRQ(void) /* INT#1: CFC Eject on PLD */ irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_EJECT].chip = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_CFC_EJECT].handler = &opsput_pld_irq_type; irq_desc[PLD_IRQ_CFC_EJECT].action = 0; irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ @@ -420,7 +420,7 @@ void __init init_IRQ(void) outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ irq_desc[OPSPUT_LCD_IRQ_USB_INT1].status = IRQ_DISABLED; - irq_desc[OPSPUT_LCD_IRQ_USB_INT1].chip = &opsput_lcdpld_irq_type; + irq_desc[OPSPUT_LCD_IRQ_USB_INT1].handler = &opsput_lcdpld_irq_type; irq_desc[OPSPUT_LCD_IRQ_USB_INT1].action = 0; irq_desc[OPSPUT_LCD_IRQ_USB_INT1].depth = 1; lcdpld_icu_data[irq2lcdpldirq(OPSPUT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ @@ -438,7 +438,7 @@ void __init init_IRQ(void) * INT3# is used for AR */ irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT3].chip = &opsput_irq_type; + irq_desc[M32R_IRQ_INT3].handler = &opsput_irq_type; irq_desc[M32R_IRQ_INT3].action = 0; irq_desc[M32R_IRQ_INT3].depth = 1; icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; diff --git a/trunk/arch/m32r/kernel/setup_usrv.c b/trunk/arch/m32r/kernel/setup_usrv.c index 7fa12d8f66b4..64be659a23e7 100644 --- a/trunk/arch/m32r/kernel/setup_usrv.c +++ b/trunk/arch/m32r/kernel/setup_usrv.c @@ -158,7 +158,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].chip = &mappi_irq_type; + irq_desc[M32R_IRQ_MFT2].handler = &mappi_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -167,7 +167,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SERIAL_M32R_SIO) /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].chip = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO0_R].handler = &mappi_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -175,7 +175,7 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].chip = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO0_S].handler = &mappi_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -183,7 +183,7 @@ void __init init_IRQ(void) /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].chip = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO1_R].handler = &mappi_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -191,7 +191,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].chip = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO1_S].handler = &mappi_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -201,7 +201,7 @@ void __init init_IRQ(void) /* INT#67-#71: CFC#0 IREQ on PLD */ for (i = 0 ; i < CONFIG_CFC_NUM ; i++ ) { irq_desc[PLD_IRQ_CF0 + i].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CF0 + i].chip = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_CF0 + i].handler = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_CF0 + i].action = 0; irq_desc[PLD_IRQ_CF0 + i].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CF0 + i)].icucr @@ -212,7 +212,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) /* INT#76: 16552D#0 IREQ on PLD */ irq_desc[PLD_IRQ_UART0].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_UART0].chip = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_UART0].handler = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_UART0].action = 0; irq_desc[PLD_IRQ_UART0].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_UART0)].icucr @@ -221,7 +221,7 @@ void __init init_IRQ(void) /* INT#77: 16552D#1 IREQ on PLD */ irq_desc[PLD_IRQ_UART1].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_UART1].chip = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_UART1].handler = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_UART1].action = 0; irq_desc[PLD_IRQ_UART1].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_UART1)].icucr @@ -232,7 +232,7 @@ void __init init_IRQ(void) #if defined(CONFIG_IDC_AK4524) || defined(CONFIG_IDC_AK4524_MODULE) /* INT#80: AK4524 IREQ on PLD */ irq_desc[PLD_IRQ_SNDINT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SNDINT].chip = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_SNDINT].handler = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_SNDINT].action = 0; irq_desc[PLD_IRQ_SNDINT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SNDINT)].icucr diff --git a/trunk/arch/m68knommu/Kconfig b/trunk/arch/m68knommu/Kconfig index e767f2ddae72..8b6e723eb82b 100644 --- a/trunk/arch/m68knommu/Kconfig +++ b/trunk/arch/m68knommu/Kconfig @@ -540,59 +540,6 @@ config RAM32BIT endchoice -comment "ROM configuration" - -config ROM - bool "Specify ROM linker regions" - default n - help - Define a ROM region for the linker script. This creates a kernel - that can be stored in flash, with possibly the text, and data - regions being copied out to RAM at startup. - -config ROMBASE - hex "Address of the base of ROM device" - default "0" - depends on ROM - help - Define the address that the ROM region starts at. Some platforms - use this to set their chip select region accordingly for the boot - device. - -config ROMVEC - hex "Address of the base of the ROM vectors" - default "0" - depends on ROM - help - This is almost always the same as the base of the ROM. Since on all - 68000 type varients the vectors are at the base of the boot device - on system startup. - -config ROMVECSIZE - hex "Size of ROM vector region (in bytes)" - default "0x400" - depends on ROM - help - Define the size of the vector region in ROM. For most 68000 - varients this would be 0x400 bytes in size. Set to 0 if you do - not want a vector region at the start of the ROM. - -config ROMSTART - hex "Address of the base of system image in ROM" - default "0x400" - depends on ROM - help - Define the start address of the system image in ROM. Commonly this - is strait after the ROM vectors. - -config ROMSIZE - hex "Size of the ROM device" - default "0x100000" - depends on ROM - help - Size of the ROM device. On some platforms this is used to setup - the chip select that controls the boot ROM device. - choice prompt "Kernel executes from" ---help--- diff --git a/trunk/arch/m68knommu/Makefile b/trunk/arch/m68knommu/Makefile index 8951793fd8d4..6f880cbff1c8 100644 --- a/trunk/arch/m68knommu/Makefile +++ b/trunk/arch/m68knommu/Makefile @@ -21,7 +21,6 @@ platform-$(CONFIG_M527x) := 527x platform-$(CONFIG_M5272) := 5272 platform-$(CONFIG_M528x) := 528x platform-$(CONFIG_M5307) := 5307 -platform-$(CONFIG_M532x) := 532x platform-$(CONFIG_M5407) := 5407 PLATFORM := $(platform-y) @@ -45,7 +44,6 @@ board-$(CONFIG_senTec) := senTec board-$(CONFIG_SNEHA) := SNEHA board-$(CONFIG_M5208EVB) := M5208EVB board-$(CONFIG_MOD5272) := MOD5272 -board-$(CONFIG_AVNET) := AVNET BOARD := $(board-y) model-$(CONFIG_RAMKERNEL) := ram @@ -67,7 +65,6 @@ cpuclass-$(CONFIG_M527x) := 5307 cpuclass-$(CONFIG_M5272) := 5307 cpuclass-$(CONFIG_M528x) := 5307 cpuclass-$(CONFIG_M5307) := 5307 -cpuclass-$(CONFIG_M532x) := 5307 cpuclass-$(CONFIG_M5407) := 5307 cpuclass-$(CONFIG_M68328) := 68328 cpuclass-$(CONFIG_M68EZ328) := 68328 @@ -84,17 +81,16 @@ export PLATFORM BOARD MODEL CPUCLASS # # Some CFLAG additions based on specific CPU type. # -cflags-$(CONFIG_M5206) := -m5200 -cflags-$(CONFIG_M5206e) := -m5200 -cflags-$(CONFIG_M520x) := -m5307 -cflags-$(CONFIG_M523x) := -m5307 -cflags-$(CONFIG_M5249) := -m5200 -cflags-$(CONFIG_M527x) := -m5307 -cflags-$(CONFIG_M5272) := -m5307 -cflags-$(CONFIG_M528x) := -m5307 -cflags-$(CONFIG_M5307) := -m5307 -cflags-$(CONFIG_M532x) := -m5307 -cflags-$(CONFIG_M5407) := -m5200 +cflags-$(CONFIG_M5206) := -m5200 -Wa,-S -Wa,-m5200 +cflags-$(CONFIG_M5206e) := -m5200 -Wa,-S -Wa,-m5200 +cflags-$(CONFIG_M520x) := -m5307 -Wa,-S -Wa,-m5307 +cflags-$(CONFIG_M523x) := -m5307 -Wa,-S -Wa,-m5307 +cflags-$(CONFIG_M5249) := -m5200 -Wa,-S -Wa,-m5200 +cflags-$(CONFIG_M527x) := -m5307 -Wa,-S -Wa,-m5307 +cflags-$(CONFIG_M5272) := -m5307 -Wa,-S -Wa,-m5307 +cflags-$(CONFIG_M528x) := -m5307 -Wa,-S -Wa,-m5307 +cflags-$(CONFIG_M5307) := -m5307 -Wa,-S -Wa,-m5307 +cflags-$(CONFIG_M5407) := -m5200 -Wa,-S -Wa,-m5200 cflags-$(CONFIG_M68328) := -m68000 cflags-$(CONFIG_M68EZ328) := -m68000 cflags-$(CONFIG_M68VZ328) := -m68000 diff --git a/trunk/arch/m68knommu/defconfig b/trunk/arch/m68knommu/defconfig index 3891de09ac23..2d59ba1a79ba 100644 --- a/trunk/arch/m68knommu/defconfig +++ b/trunk/arch/m68knommu/defconfig @@ -1,22 +1,21 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17 -# Tue Jun 27 12:57:06 2006 +# Linux kernel version: 2.6.13-uc0 +# Wed Aug 31 15:03:26 2005 # -CONFIG_M68K=y +CONFIG_M68KNOMMU=y # CONFIG_MMU is not set # CONFIG_FPU is not set +CONFIG_UID16=y CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_TIME_LOW_RES=y # # Code maturity level options # CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 @@ -24,54 +23,32 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 # General setup # CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SYSVIPC is not set # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_SYSCTL is not set # CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +# CONFIG_KOBJECT_UEVENT is not set # CONFIG_IKCONFIG is not set -# CONFIG_RELAY is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_UID16=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=y # CONFIG_KALLSYMS is not set -# CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y -CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set # CONFIG_EPOLL is not set -CONFIG_SLAB=y -CONFIG_TINY_SHMEM=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 CONFIG_BASE_SMALL=0 -# CONFIG_SLOB is not set # # Loadable module support # # CONFIG_MODULES is not set -# -# Block layer -# -# CONFIG_BLK_DEV_IO_TRACE is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" - # # Processor type and features # @@ -81,7 +58,6 @@ CONFIG_DEFAULT_IOSCHED="noop" # CONFIG_M68360 is not set # CONFIG_M5206 is not set # CONFIG_M5206e is not set -# CONFIG_M520x is not set # CONFIG_M523x is not set # CONFIG_M5249 is not set # CONFIG_M5271 is not set @@ -89,12 +65,29 @@ CONFIG_M5272=y # CONFIG_M5275 is not set # CONFIG_M528x is not set # CONFIG_M5307 is not set -# CONFIG_M532x is not set # CONFIG_M5407 is not set CONFIG_COLDFIRE=y -CONFIG_CLOCK_SET=y -CONFIG_CLOCK_FREQ=66666666 -CONFIG_CLOCK_DIV=1 +# CONFIG_CLOCK_AUTO is not set +# CONFIG_CLOCK_11MHz is not set +# CONFIG_CLOCK_16MHz is not set +# CONFIG_CLOCK_20MHz is not set +# CONFIG_CLOCK_24MHz is not set +# CONFIG_CLOCK_25MHz is not set +# CONFIG_CLOCK_33MHz is not set +# CONFIG_CLOCK_40MHz is not set +# CONFIG_CLOCK_45MHz is not set +# CONFIG_CLOCK_48MHz is not set +# CONFIG_CLOCK_50MHz is not set +# CONFIG_CLOCK_54MHz is not set +# CONFIG_CLOCK_60MHz is not set +# CONFIG_CLOCK_62_5MHz is not set +# CONFIG_CLOCK_64MHz is not set +CONFIG_CLOCK_66MHz=y +# CONFIG_CLOCK_70MHz is not set +# CONFIG_CLOCK_100MHz is not set +# CONFIG_CLOCK_140MHz is not set +# CONFIG_CLOCK_150MHz is not set +# CONFIG_CLOCK_166MHz is not set # # Platform @@ -109,14 +102,11 @@ CONFIG_M5272C3=y CONFIG_FREESCALE=y # CONFIG_LARGE_ALLOCS is not set CONFIG_4KSTACKS=y - -# -# RAM configuration -# -CONFIG_RAMBASE=0x0 -CONFIG_RAMSIZE=0x800000 -CONFIG_VECTORBASE=0x0 -CONFIG_KERNELBASE=0x20000 +CONFIG_RAMAUTO=y +# CONFIG_RAM4MB is not set +# CONFIG_RAM8MB is not set +# CONFIG_RAM16MB is not set +# CONFIG_RAM32MB is not set CONFIG_RAMAUTOBIT=y # CONFIG_RAM8BIT is not set # CONFIG_RAM16BIT is not set @@ -129,8 +119,6 @@ CONFIG_FLATMEM_MANUAL=y # 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 # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) @@ -152,7 +140,6 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_BINFMT_FLAT=y # CONFIG_BINFMT_ZFLAT is not set # CONFIG_BINFMT_SHARED_FLAT is not set -# CONFIG_BINFMT_AOUT is not set # CONFIG_BINFMT_MISC is not set # @@ -168,7 +155,6 @@ CONFIG_NET=y # # Networking options # -# CONFIG_NETDEBUG is not set CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set CONFIG_UNIX=y @@ -185,30 +171,18 @@ CONFIG_IP_FIB_HASH=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -# CONFIG_INET_DIAG is not set +# CONFIG_IP_TCPDIAG is not set +# CONFIG_IP_TCPDIAG_IPV6 is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET6_TUNNEL is not set # CONFIG_NETFILTER is not set -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - # # SCTP Configuration (EXPERIMENTAL) # # CONFIG_IP_SCTP is not set - -# -# TIPC Configuration (EXPERIMENTAL) -# -# CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set # CONFIG_VLAN_8021Q is not set @@ -221,11 +195,8 @@ CONFIG_TCP_CONG_BIC=y # 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 @@ -234,7 +205,6 @@ CONFIG_TCP_CONG_BIC=y # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_IEEE80211 is not set # # Device Drivers @@ -247,11 +217,6 @@ 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) # @@ -270,7 +235,6 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set # # RAM/ROM/Flash chip drivers @@ -290,13 +254,13 @@ CONFIG_MTD_CFI_I2=y CONFIG_MTD_RAM=y # CONFIG_MTD_ROM is not set # CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set # # Mapping drivers for chip access # # CONFIG_MTD_COMPLEX_MAPPINGS is not set CONFIG_MTD_UCLINUX=y +# CONFIG_MTD_SNAPGEARuC is not set # CONFIG_MTD_PLATRAM is not set # @@ -305,6 +269,7 @@ CONFIG_MTD_UCLINUX=y # 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 # @@ -319,11 +284,6 @@ CONFIG_MTD_UCLINUX=y # # CONFIG_MTD_NAND is not set -# -# OneNAND Flash Device Drivers -# -# CONFIG_MTD_ONENAND is not set - # # Parallel port support # @@ -336,6 +296,7 @@ CONFIG_MTD_UCLINUX=y # # Block devices # +# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -343,7 +304,16 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_BLK_DEV_INITRD is not set +CONFIG_INITRAMFS_SOURCE="" # CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set # CONFIG_ATA_OVER_ETH is not set # @@ -354,7 +324,6 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # # SCSI device support # -# CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set # @@ -384,16 +353,14 @@ CONFIG_NETDEVICES=y # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# -# PHY device support -# -# CONFIG_PHYLIB is not set - # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y # CONFIG_MII is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NE2000 is not set +# CONFIG_NET_PCI is not set CONFIG_FEC=y # CONFIG_FEC2 is not set @@ -425,7 +392,6 @@ CONFIG_PPP=y # CONFIG_PPP_SYNC_TTY is not set # CONFIG_PPP_DEFLATE is not set # CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPP_MPPE is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set # CONFIG_SHAPER is not set @@ -459,6 +425,8 @@ CONFIG_PPP=y # # CONFIG_VT is not set # CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_LEDMAN is not set +# CONFIG_RESETSWITCH is not set # # Serial drivers @@ -482,6 +450,8 @@ CONFIG_LEGACY_PTY_COUNT=256 # Watchdog Cards # # CONFIG_WATCHDOG is not set +# CONFIG_MCFWATCHDOG is not set +# CONFIG_RTC is not set # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -494,19 +464,14 @@ CONFIG_LEGACY_PTY_COUNT=256 # # TPM devices # -# CONFIG_TCG_TPM is not set -# CONFIG_TELCLOCK is not set +# CONFIG_MCF_QSPI is not set +# CONFIG_M41T11M6 is not set # # I2C support # # CONFIG_I2C is not set - -# -# SPI support -# -# CONFIG_SPI is not set -# CONFIG_SPI_MASTER is not set +# CONFIG_I2C_SENSOR is not set # # Dallas's 1-wire bus @@ -517,7 +482,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # Hardware Monitoring support # # CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set # # Misc devices @@ -527,7 +491,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # Multimedia devices # # CONFIG_VIDEO_DEV is not set -CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -539,6 +502,11 @@ CONFIG_VIDEO_V4L2=y # # CONFIG_FB is not set +# +# SPI support +# +# CONFIG_SPI is not set + # # Sound # @@ -549,11 +517,6 @@ CONFIG_VIDEO_V4L2=y # # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# # # USB Gadget Support @@ -565,32 +528,14 @@ CONFIG_VIDEO_V4L2=y # # CONFIG_MMC is not set -# -# LED devices -# -# CONFIG_NEW_LEDS is not set - -# -# LED drivers -# - -# -# LED Triggers -# - # # InfiniBand support # # -# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# SN Devices # -# -# Real Time Clock -# -# CONFIG_RTC_CLASS is not set - # # File systems # @@ -598,11 +543,15 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set + +# +# XFS support +# # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y # CONFIG_INOTIFY is not set @@ -610,7 +559,6 @@ CONFIG_ROMFS_FS=y # CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set # # CD-ROM/DVD Filesystems @@ -633,7 +581,6 @@ CONFIG_SYSFS=y # CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_CONFIGFS_FS is not set # # Miscellaneous filesystems @@ -664,7 +611,6 @@ CONFIG_RAMFS=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set # # Partition Types @@ -681,12 +627,8 @@ CONFIG_MSDOS_PARTITION=y # Kernel hacking # # CONFIG_PRINTK_TIME is not set -# CONFIG_MAGIC_SYSRQ is not set # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_UNWIND_INFO is not set # CONFIG_FULLDEBUG is not set # CONFIG_HIGHPROFILE is not set # CONFIG_BOOTPARAM is not set @@ -713,6 +655,5 @@ CONFIG_LOG_BUF_SHIFT=14 # Library routines # # CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set # CONFIG_CRC32 is not set # CONFIG_LIBCRC32C is not set diff --git a/trunk/arch/m68knommu/kernel/vmlinux.lds.S b/trunk/arch/m68knommu/kernel/vmlinux.lds.S index 59ced831b792..6a2f0c693254 100644 --- a/trunk/arch/m68knommu/kernel/vmlinux.lds.S +++ b/trunk/arch/m68knommu/kernel/vmlinux.lds.S @@ -3,13 +3,63 @@ * * (C) Copyright 2002-2006, Greg Ungerer * - * This linker script is equiped to build either ROM loaded or RAM - * run kernels. + * This ends up looking compilcated, because of the number of + * address variations for ram and rom/flash layouts. The real + * work of the linker script is all at the end, and reasonably + * strait forward. */ #include #include +/* + * Original Palm pilot (same for Xcopilot). + * There is really only a rom target for this. + */ +#ifdef CONFIG_PILOT3 +#define ROMVEC_START 0x10c00000 +#define ROMVEC_LENGTH 0x10400 +#define ROM_START 0x10c10400 +#define ROM_LENGTH 0xfec00 +#define ROM_END 0x10d00000 +#define DATA_ADDR CONFIG_KERNELBASE +#endif + +/* + * Same setup on both the uCsimm and uCdimm. + */ +#if defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM) +#ifdef CONFIG_RAMKERNEL +#define ROMVEC_START 0x10c10000 +#define ROMVEC_LENGTH 0x400 +#define ROM_START 0x10c10400 +#define ROM_LENGTH 0x1efc00 +#define ROM_END 0x10e00000 +#endif +#ifdef CONFIG_ROMKERNEL +#define ROMVEC_START 0x10c10000 +#define ROMVEC_LENGTH 0x400 +#define ROM_START 0x10c10400 +#define ROM_LENGTH 0x1efc00 +#define ROM_END 0x10e00000 +#endif +#ifdef CONFIG_HIMEMKERNEL +#define ROMVEC_START 0x00600000 +#define ROMVEC_LENGTH 0x400 +#define ROM_START 0x00600400 +#define ROM_LENGTH 0x1efc00 +#define ROM_END 0x007f0000 +#endif +#endif + +#ifdef CONFIG_UCQUICC +#define ROMVEC_START 0x00000000 +#define ROMVEC_LENGTH 0x404 +#define ROM_START 0x00000404 +#define ROM_LENGTH 0x1ff6fc +#define ROM_END 0x00200000 +#endif + #if defined(CONFIG_RAMKERNEL) #define RAM_START CONFIG_KERNELBASE #define RAM_LENGTH (CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE) @@ -21,10 +71,6 @@ #if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL) #define RAM_START CONFIG_RAMBASE #define RAM_LENGTH CONFIG_RAMSIZE -#define ROMVEC_START CONFIG_ROMVEC -#define ROMVEC_LENGTH CONFIG_ROMVECSIZE -#define ROM_START CONFIG_ROMSTART -#define ROM_LENGTH CONFIG_ROMSIZE #define TEXT rom #define DATA ram #define INIT ram @@ -44,6 +90,7 @@ MEMORY { #ifdef ROM_START romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH + erom : ORIGIN = ROM_END, LENGTH = 0 #endif } @@ -120,6 +167,13 @@ SECTIONS { _etext = . ; } > TEXT +#ifdef ROM_END + . = ROM_END ; + .erom : { + __rom_end = . ; + } > erom +#endif + .data DATA_ADDR : { . = ALIGN(4); _sdata = . ; diff --git a/trunk/arch/m68knommu/platform/68328/Makefile b/trunk/arch/m68knommu/platform/68328/Makefile index 5e5435552d56..1b3b719e4479 100644 --- a/trunk/arch/m68knommu/platform/68328/Makefile +++ b/trunk/arch/m68knommu/platform/68328/Makefile @@ -8,7 +8,6 @@ head-$(CONFIG_DRAGEN2) = head-de2.o obj-y += entry.o ints.o timers.o obj-$(CONFIG_M68328) += config.o -obj-$(CONFIG_ROM) += romvec.o extra-y := head.o extra-$(CONFIG_M68328) += bootlogo.rh head.o diff --git a/trunk/arch/m68knommu/platform/68328/head-rom.S b/trunk/arch/m68knommu/platform/68328/head-rom.S index 234430b9551c..2b448a297011 100644 --- a/trunk/arch/m68knommu/platform/68328/head-rom.S +++ b/trunk/arch/m68knommu/platform/68328/head-rom.S @@ -28,8 +28,6 @@ _ramstart: _ramend: .long 0 -#define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE) - #ifdef CONFIG_INIT_LCD splash_bits: #include "bootlogo.rh" @@ -50,7 +48,7 @@ _stext: movew #0x2700,%sr moveb #0x81, 0xfffffA27 /* LCKCON */ movew #0xff00, 0xfffff412 /* LCD pins */ #endif - moveal #RAMEND-CONFIG_MEMORY_RESERVE*0x100000 - 0x10, %sp + moveal #__ramend-CONFIG_MEMORY_RESERVE*0x100000 - 0x10, %sp movew #32767, %d0 /* PLL settle wait loop */ 1: subq #1, %d0 bne 1b @@ -75,13 +73,13 @@ _stext: movew #0x2700,%sr bhi 1b movel #_sdata, %d0 - movel %d0, _rambase - movel #_ebss, %d0 - movel %d0, _ramstart - movel #RAMEND-CONFIG_MEMORY_RESERVE*0x100000, %d0 - movel %d0, _ramend - movel #CONFIG_VECTORBASE, %d0 - movel %d0, _ramvec + movel %d0, _rambase + movel #_ebss, %d0 + movel %d0, _ramstart + movel #__ramend-CONFIG_MEMORY_RESERVE*0x100000, %d0 + movel %d0, _ramend + movel #__ramvec, %d0 + movel %d0, _ramvec /* * load the current task pointer and stack diff --git a/trunk/arch/m68knommu/platform/68328/ints.c b/trunk/arch/m68knommu/platform/68328/ints.c index 2dda7339aae5..7437217813d2 100644 --- a/trunk/arch/m68knommu/platform/68328/ints.c +++ b/trunk/arch/m68knommu/platform/68328/ints.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -83,6 +82,25 @@ unsigned int local_irq_count[NR_CPUS]; /* irq node variables for the 32 (potential) on chip sources */ static irq_node_t int_irq_list[NR_IRQS]; +#if !defined(CONFIG_DRAGEN2) +asm (".global _start, __ramend/n/t" + ".section .romvec/n" + "e_vectors:\n\t" + ".long __ramend-4, _start, buserr, trap, trap, trap, trap, trap\n\t" + ".long trap, trap, trap, trap, trap, trap, trap, trap\n\t" + ".long trap, trap, trap, trap, trap, trap, trap, trap\n\t" + ".long trap, trap, trap, trap\n\t" + ".long trap, trap, trap, trap\n\t" + /*.long inthandler, inthandler, inthandler, inthandler + .long inthandler4, inthandler, inthandler, inthandler */ + /* TRAP #0-15 */ + ".long system_call, trap, trap, trap, trap, trap, trap, trap\n\t" + ".long trap, trap, trap, trap, trap, trap, trap, trap\n\t" + ".long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n\t" + ".text\n" + "ignore: rte"); +#endif + /* * This function should be called during kernel startup to initialize * the IRQ handling routines. diff --git a/trunk/arch/m68knommu/platform/68328/romvec.S b/trunk/arch/m68knommu/platform/68328/romvec.S deleted file mode 100644 index 3e7fe1e14913..000000000000 --- a/trunk/arch/m68knommu/platform/68328/romvec.S +++ /dev/null @@ -1,37 +0,0 @@ -/* - * linux/arch/m68knommu/platform/68328/romvec.S - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * - * Copyright 1996 Roman Zippel - * Copyright 1999 D. Jeff Dionne - * Copyright 2006 Greg Ungerer - */ - -#include - -.global _start -.global _buserr -.global trap -.global system_call - -.section .romvec - -e_vectors: -.long CONFIG_RAMBASE+CONFIG_RAMSIZE-4, _start, buserr, trap -.long trap, trap, trap, trap -.long trap, trap, trap, trap -.long trap, trap, trap, trap -.long trap, trap, trap, trap -.long trap, trap, trap, trap -.long trap, trap, trap, trap -.long trap, trap, trap, trap -/* TRAP #0-15 */ -.long system_call, trap, trap, trap -.long trap, trap, trap, trap -.long trap, trap, trap, trap -.long trap, trap, trap, trap -.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - diff --git a/trunk/arch/m68knommu/platform/68360/config.c b/trunk/arch/m68knommu/platform/68360/config.c index 69c670dfd62b..3db244625f0f 100644 --- a/trunk/arch/m68knommu/platform/68360/config.c +++ b/trunk/arch/m68knommu/platform/68360/config.c @@ -141,13 +141,13 @@ int BSP_set_clock_mmss (unsigned long nowtime) void BSP_reset (void) { local_irq_disable(); - asm volatile ( - "moveal #_start, %a0;\n" - "moveb #0, 0xFFFFF300;\n" - "moveal 0(%a0), %sp;\n" - "moveal 4(%a0), %a0;\n" - "jmp (%a0);\n" - ); + asm volatile (" + moveal #_start, %a0; + moveb #0, 0xFFFFF300; + moveal 0(%a0), %sp; + moveal 4(%a0), %a0; + jmp (%a0); + "); } unsigned char *scc1_hwaddr; diff --git a/trunk/arch/m68knommu/platform/68360/head-ram.S b/trunk/arch/m68knommu/platform/68360/head-ram.S index f497713a4ec7..a5c639a51eef 100644 --- a/trunk/arch/m68knommu/platform/68360/head-ram.S +++ b/trunk/arch/m68knommu/platform/68360/head-ram.S @@ -18,6 +18,7 @@ .global _start .global _rambase +.global __ramvec .global _ramvec .global _ramstart .global _ramend @@ -25,8 +26,6 @@ .global _quicc_base .global _periph_base -#define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE) - #define REGB 0x1000 #define PEPAR (_dprbase + REGB + 0x0016) #define GMR (_dprbase + REGB + 0x0040) @@ -104,7 +103,7 @@ _stext: nop ori.w #MCU_DISABLE_INTRPTS, %sr /* disable interrupts: */ /* We should not need to setup the boot stack the reset should do it. */ - movea.l #RAMEND, %sp /*set up stack at the end of DRAM:*/ + movea.l #__ramend, %sp /*set up stack at the end of DRAM:*/ set_mbar_register: moveq.l #0x07, %d1 /* Setup MBAR */ @@ -164,7 +163,7 @@ configure_memory_controller: move.l %d0, GMR configure_chip_select_0: - move.l #RAMEND, %d0 + move.l #__ramend, %d0 subi.l #__ramstart, %d0 subq.l #0x01, %d0 eori.l #SIM_OR_MASK, %d0 @@ -235,10 +234,16 @@ store_ram_size: /* Set ram size information */ move.l #_sdata, _rambase move.l #_ebss, _ramstart - move.l #RAMEND, %d0 + move.l #__ramend, %d0 sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/ - move.l %d0, _ramend /* Different from RAMEND.*/ + move.l %d0, _ramend /* Different from __ramend.*/ +store_flash_size: + /* Set rom size information */ + move.l #__rom_end, %d0 + sub.l #__rom_start, %d0 + move.l %d0, rom_length + pea 0 pea env pea %sp@(4) @@ -281,7 +286,7 @@ _dprbase: */ .section ".data.initvect","awx" - .long RAMEND /* Reset: Initial Stack Pointer - 0. */ + .long __ramend /* Reset: Initial Stack Pointer - 0. */ .long _start /* Reset: Initial Program Counter - 1. */ .long buserr /* Bus Error - 2. */ .long trap /* Address Error - 3. */ diff --git a/trunk/arch/m68knommu/platform/68360/head-rom.S b/trunk/arch/m68knommu/platform/68360/head-rom.S index 2d28c3e19a88..0da357a4cfee 100644 --- a/trunk/arch/m68knommu/platform/68360/head-rom.S +++ b/trunk/arch/m68knommu/platform/68360/head-rom.S @@ -18,6 +18,7 @@ .global _start .global _rambase +.global __ramvec .global _ramvec .global _ramstart .global _ramend @@ -25,8 +26,6 @@ .global _quicc_base .global _periph_base -#define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE) - #define REGB 0x1000 #define PEPAR (_dprbase + REGB + 0x0016) #define GMR (_dprbase + REGB + 0x0040) @@ -116,7 +115,7 @@ _stext: nop ori.w #MCU_DISABLE_INTRPTS, %sr /* disable interrupts: */ /* We should not need to setup the boot stack the reset should do it. */ - movea.l #RAMEND, %sp /* set up stack at the end of DRAM:*/ + movea.l #__ramend, %sp /* set up stack at the end of DRAM:*/ set_mbar_register: @@ -246,10 +245,16 @@ store_ram_size: /* Set ram size information */ move.l #_sdata, _rambase move.l #_ebss, _ramstart - move.l #RAMEND, %d0 + move.l #__ramend, %d0 sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/ - move.l %d0, _ramend /* Different from RAMEND.*/ + move.l %d0, _ramend /* Different from __ramend.*/ +store_flash_size: + /* Set rom size information */ + move.l #__rom_end, %d0 + sub.l #__rom_start, %d0 + move.l %d0, rom_length + pea 0 pea env pea %sp@(4) @@ -293,7 +298,7 @@ _dprbase: */ .section ".data.initvect","awx" - .long RAMEND /* Reset: Initial Stack Pointer - 0. */ + .long __ramend /* Reset: Initial Stack Pointer - 0. */ .long _start /* Reset: Initial Program Counter - 1. */ .long buserr /* Bus Error - 2. */ .long trap /* Address Error - 3. */ diff --git a/trunk/arch/m68knommu/platform/68360/ints.c b/trunk/arch/m68knommu/platform/68360/ints.c index 0245fc4a4781..ba184db1651b 100644 --- a/trunk/arch/m68knommu/platform/68360/ints.c +++ b/trunk/arch/m68knommu/platform/68360/ints.c @@ -20,7 +20,6 @@ #include #include -#include #include #include #include diff --git a/trunk/arch/m68knommu/platform/68EZ328/config.c b/trunk/arch/m68knommu/platform/68EZ328/config.c index 15a14a67c2bf..d8d56e5de310 100644 --- a/trunk/arch/m68knommu/platform/68EZ328/config.c +++ b/trunk/arch/m68knommu/platform/68EZ328/config.c @@ -42,13 +42,13 @@ void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int void m68ez328_reset(void) { local_irq_disable(); - asm volatile ( - "moveal #0x10c00000, %a0;\n" - "moveb #0, 0xFFFFF300;\n" - "moveal 0(%a0), %sp;\n" - "moveal 4(%a0), %a0;\n" - "jmp (%a0);\n" - ); + asm volatile (" + moveal #0x10c00000, %a0; + moveb #0, 0xFFFFF300; + moveal 0(%a0), %sp; + moveal 4(%a0), %a0; + jmp (%a0); + "); } /***************************************************************************/ diff --git a/trunk/arch/m68knommu/platform/68VZ328/config.c b/trunk/arch/m68knommu/platform/68VZ328/config.c index 4058de5c8fa2..d926524cdf82 100644 --- a/trunk/arch/m68knommu/platform/68VZ328/config.c +++ b/trunk/arch/m68knommu/platform/68VZ328/config.c @@ -141,13 +141,13 @@ static void init_hardware(char *command, int size) static void m68vz328_reset(void) { local_irq_disable(); - asm volatile ( - "moveal #0x10c00000, %a0;\n\t" - "moveb #0, 0xFFFFF300;\n\t" - "moveal 0(%a0), %sp;\n\t" - "moveal 4(%a0), %a0;\n\t" - "jmp (%a0);\n" - ); + asm volatile (" + moveal #0x10c00000, %a0; + moveb #0, 0xFFFFF300; + moveal 0(%a0), %sp; + moveal 4(%a0), %a0; + jmp (%a0); + "); } unsigned char *cs8900a_hwaddr; diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 08c2ece4ae40..35e038a974c6 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -1618,11 +1618,6 @@ config GENERIC_IRQ_PROBE bool default y -config IRQ_PER_CPU - depends on SMP - bool - default y - # # - Highmem only makes sense for the 32-bit kernel. # - The current highmem code will only work properly on physically indexed diff --git a/trunk/arch/mips/au1000/common/irq.c b/trunk/arch/mips/au1000/common/irq.c index da74ac21954b..afe05ec12c27 100644 --- a/trunk/arch/mips/au1000/common/irq.c +++ b/trunk/arch/mips/au1000/common/irq.c @@ -333,31 +333,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1CLR); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - irq_desc[irq_nr].chip = &rise_edge_irq_type; + irq_desc[irq_nr].handler = &rise_edge_irq_type; break; case INTC_INT_FALL_EDGE: /* 0:1:0 */ au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - irq_desc[irq_nr].chip = &fall_edge_irq_type; + irq_desc[irq_nr].handler = &fall_edge_irq_type; break; case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - irq_desc[irq_nr].chip = &either_edge_irq_type; + irq_desc[irq_nr].handler = &either_edge_irq_type; break; case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ au_writel(1<<(irq_nr-32), IC1_CFG2SET); au_writel(1<<(irq_nr-32), IC1_CFG1CLR); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - irq_desc[irq_nr].chip = &level_irq_type; + irq_desc[irq_nr].handler = &level_irq_type; break; case INTC_INT_LOW_LEVEL: /* 1:1:0 */ au_writel(1<<(irq_nr-32), IC1_CFG2SET); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - irq_desc[irq_nr].chip = &level_irq_type; + irq_desc[irq_nr].handler = &level_irq_type; break; case INTC_INT_DISABLED: /* 0:0:0 */ au_writel(1<<(irq_nr-32), IC1_CFG0CLR); @@ -385,31 +385,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) au_writel(1<im_type) { case MSC01_IRQ_EDGE: - irq_desc[base+n].chip = &msc_edgeirq_type; + irq_desc[base+n].handler = &msc_edgeirq_type; if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT); else MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl); break; case MSC01_IRQ_LEVEL: - irq_desc[base+n].chip = &msc_levelirq_type; + irq_desc[base+n].handler = &msc_levelirq_type; if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, 0); else diff --git a/trunk/arch/mips/kernel/irq-mv6434x.c b/trunk/arch/mips/kernel/irq-mv6434x.c index f9c763a65547..0613f1f36b1b 100644 --- a/trunk/arch/mips/kernel/irq-mv6434x.c +++ b/trunk/arch/mips/kernel/irq-mv6434x.c @@ -155,7 +155,7 @@ void __init mv64340_irq_init(unsigned int base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 2; - irq_desc[i].chip = &mv64340_irq_type; + irq_desc[i].handler = &mv64340_irq_type; } irq_base = base; diff --git a/trunk/arch/mips/kernel/irq-rm7000.c b/trunk/arch/mips/kernel/irq-rm7000.c index 121da385a94d..0b130c5ac5d9 100644 --- a/trunk/arch/mips/kernel/irq-rm7000.c +++ b/trunk/arch/mips/kernel/irq-rm7000.c @@ -91,7 +91,7 @@ void __init rm7k_cpu_irq_init(int base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].chip = &rm7k_irq_controller; + irq_desc[i].handler = &rm7k_irq_controller; } irq_base = base; diff --git a/trunk/arch/mips/kernel/irq-rm9000.c b/trunk/arch/mips/kernel/irq-rm9000.c index 25109c103e44..9b5f20c32acb 100644 --- a/trunk/arch/mips/kernel/irq-rm9000.c +++ b/trunk/arch/mips/kernel/irq-rm9000.c @@ -139,11 +139,11 @@ void __init rm9k_cpu_irq_init(int base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].chip = &rm9k_irq_controller; + irq_desc[i].handler = &rm9k_irq_controller; } rm9000_perfcount_irq = base + 1; - irq_desc[rm9000_perfcount_irq].chip = &rm9k_perfcounter_irq; + irq_desc[rm9000_perfcount_irq].handler = &rm9k_perfcounter_irq; irq_base = base; } diff --git a/trunk/arch/mips/kernel/irq.c b/trunk/arch/mips/kernel/irq.c index 5c9dcd5eed59..3dce742e716f 100644 --- a/trunk/arch/mips/kernel/irq.c +++ b/trunk/arch/mips/kernel/irq.c @@ -95,7 +95,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -137,7 +137,7 @@ void __init init_IRQ(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].chip = &no_irq_type; + irq_desc[i].handler = &no_irq_type; spin_lock_init(&irq_desc[i].lock); #ifdef CONFIG_MIPS_MT_SMTC irq_hwmask[i] = 0; diff --git a/trunk/arch/mips/kernel/irq_cpu.c b/trunk/arch/mips/kernel/irq_cpu.c index 0e455a8ad860..5db67e31ec1a 100644 --- a/trunk/arch/mips/kernel/irq_cpu.c +++ b/trunk/arch/mips/kernel/irq_cpu.c @@ -167,14 +167,14 @@ void __init mips_cpu_irq_init(int irq_base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].chip = &mips_mt_cpu_irq_controller; + irq_desc[i].handler = &mips_mt_cpu_irq_controller; } for (i = irq_base + 2; i < irq_base + 8; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].chip = &mips_cpu_irq_controller; + irq_desc[i].handler = &mips_cpu_irq_controller; } mips_cpu_irq_base = irq_base; diff --git a/trunk/arch/mips/kernel/smp.c b/trunk/arch/mips/kernel/smp.c index 9096a5ea4229..298f82fe8440 100644 --- a/trunk/arch/mips/kernel/smp.c +++ b/trunk/arch/mips/kernel/smp.c @@ -446,7 +446,7 @@ static int __init topology_init(void) int ret; for_each_present_cpu(cpu) { - ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu); + ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL); if (ret) printk(KERN_WARNING "topology_init: register_cpu %d " "failed (%d)\n", cpu, ret); diff --git a/trunk/arch/mips/kernel/smtc.c b/trunk/arch/mips/kernel/smtc.c index 70cf09afdf56..2e8e52c135e6 100644 --- a/trunk/arch/mips/kernel/smtc.c +++ b/trunk/arch/mips/kernel/smtc.c @@ -367,7 +367,7 @@ void mipsmt_prepare_cpus(void) dvpe(); dmt(); - spin_lock_init(&freeIPIq.lock); + freeIPIq.lock = SPIN_LOCK_UNLOCKED; /* * We probably don't have as many VPEs as we do SMP "CPUs", @@ -375,7 +375,7 @@ void mipsmt_prepare_cpus(void) */ for (i=0; itypename, "none") + if (strcmp(irq_desc[i].handler->typename, "none") == 0) continue; if ((i >= 1) - && (irq_desc[i - 1].chip->typename == - irq_desc[i].chip->typename)) { + && (irq_desc[i - 1].handler->typename == + irq_desc[i].handler->typename)) { j++; } else { j = 0; @@ -707,12 +707,12 @@ void toshiba_rbtx4927_irq_dump(char *key) (TOSHIBA_RBTX4927_IRQ_INFO, "%s irq=0x%02x/%3d s=0x%08x h=0x%08x a=0x%08x ah=0x%08x d=%1d n=%s/%02d\n", key, i, i, irq_desc[i].status, - (u32) irq_desc[i].chip, + (u32) irq_desc[i].handler, (u32) irq_desc[i].action, (u32) (irq_desc[i].action ? irq_desc[i]. action->handler : 0), irq_desc[i].depth, - irq_desc[i].chip->typename, j); + irq_desc[i].handler->typename, j); } } #endif diff --git a/trunk/arch/mips/tx4938/common/irq.c b/trunk/arch/mips/tx4938/common/irq.c index 0b2f8c849218..873805178d8e 100644 --- a/trunk/arch/mips/tx4938/common/irq.c +++ b/trunk/arch/mips/tx4938/common/irq.c @@ -102,7 +102,7 @@ tx4938_irq_cp0_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].chip = &tx4938_irq_cp0_type; + irq_desc[i].handler = &tx4938_irq_cp0_type; } return; @@ -306,7 +306,7 @@ tx4938_irq_pic_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 2; - irq_desc[i].chip = &tx4938_irq_pic_type; + irq_desc[i].handler = &tx4938_irq_pic_type; } setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action); diff --git a/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c index 3b8245dc5bd3..9cd9c0fe2265 100644 --- a/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c +++ b/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c @@ -146,7 +146,7 @@ toshiba_rbtx4938_irq_ioc_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 3; - irq_desc[i].chip = &toshiba_rbtx4938_irq_ioc_type; + irq_desc[i].handler = &toshiba_rbtx4938_irq_ioc_type; } setup_irq(RBTX4938_IRQ_IOCINT, diff --git a/trunk/arch/mips/vr41xx/common/icu.c b/trunk/arch/mips/vr41xx/common/icu.c index b9323302cc4e..07ae19cf0c29 100644 --- a/trunk/arch/mips/vr41xx/common/icu.c +++ b/trunk/arch/mips/vr41xx/common/icu.c @@ -722,10 +722,10 @@ static int __init vr41xx_icu_init(void) icu2_write(MGIUINTHREG, 0xffff); for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++) - irq_desc[i].chip = &sysint1_irq_type; + irq_desc[i].handler = &sysint1_irq_type; for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++) - irq_desc[i].chip = &sysint2_irq_type; + irq_desc[i].handler = &sysint2_irq_type; cascade_irq(INT0_IRQ, icu_get_irq); cascade_irq(INT1_IRQ, icu_get_irq); diff --git a/trunk/arch/mips/vr41xx/common/irq.c b/trunk/arch/mips/vr41xx/common/irq.c index 66aa50802deb..86796bb63c3c 100644 --- a/trunk/arch/mips/vr41xx/common/irq.c +++ b/trunk/arch/mips/vr41xx/common/irq.c @@ -73,13 +73,13 @@ static void irq_dispatch(unsigned int irq, struct pt_regs *regs) if (cascade->get_irq != NULL) { unsigned int source_irq = irq; desc = irq_desc + source_irq; - desc->chip->ack(source_irq); + desc->handler->ack(source_irq); irq = cascade->get_irq(irq, regs); if (irq < 0) atomic_inc(&irq_err_count); else irq_dispatch(irq, regs); - desc->chip->end(source_irq); + desc->handler->end(source_irq); } else do_IRQ(irq, regs); } diff --git a/trunk/arch/mips/vr41xx/common/vrc4173.c b/trunk/arch/mips/vr41xx/common/vrc4173.c index 2d287b8893d9..3e31f8193d21 100644 --- a/trunk/arch/mips/vr41xx/common/vrc4173.c +++ b/trunk/arch/mips/vr41xx/common/vrc4173.c @@ -483,7 +483,7 @@ static inline int vrc4173_icu_init(int cascade_irq) vr41xx_set_irq_level(GIU_IRQ_TO_PIN(cascade_irq), LEVEL_LOW); for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++) - irq_desc[i].chip = &vrc4173_irq_type; + irq_desc[i].handler = &vrc4173_irq_type; return 0; } diff --git a/trunk/arch/mips/vr41xx/nec-cmbvr4133/irq.c b/trunk/arch/mips/vr41xx/nec-cmbvr4133/irq.c index 7b2511ca0a61..31db6b61a39e 100644 --- a/trunk/arch/mips/vr41xx/nec-cmbvr4133/irq.c +++ b/trunk/arch/mips/vr41xx/nec-cmbvr4133/irq.c @@ -104,7 +104,7 @@ void __init rockhopper_init_irq(void) } for (i = I8259_IRQ_BASE; i <= I8259_IRQ_LAST; i++) - irq_desc[i].chip = &i8259_irq_type; + irq_desc[i].handler = &i8259_irq_type; setup_irq(I8259_SLAVE_IRQ, &i8259_slave_cascade); diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index 6dd0ea8f88e0..910fb3afc0b5 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -51,10 +51,6 @@ config GENERIC_HARDIRQS config GENERIC_IRQ_PROBE def_bool y -config IRQ_PER_CPU - bool - default y - # unless you want to implement ACPI on PA-RISC ... ;-) config PM bool diff --git a/trunk/arch/parisc/kernel/irq.c b/trunk/arch/parisc/kernel/irq.c index 82fe6ba29727..197936d9359a 100644 --- a/trunk/arch/parisc/kernel/irq.c +++ b/trunk/arch/parisc/kernel/irq.c @@ -94,7 +94,7 @@ int cpu_check_affinity(unsigned int irq, cpumask_t *dest) if (irq == TIMER_IRQ || irq == IPI_IRQ) { /* Bad linux design decision. The mask has already * been set; we must reset it */ - irq_desc[irq].affinity = CPU_MASK_ALL; + irq_affinity[irq] = CPU_MASK_ALL; return -EINVAL; } @@ -110,7 +110,7 @@ static void cpu_set_affinity_irq(unsigned int irq, cpumask_t dest) if (cpu_check_affinity(irq, &dest)) return; - irq_desc[irq].affinity = dest; + irq_affinity[irq] = dest; } #endif @@ -125,10 +125,6 @@ static struct hw_interrupt_type cpu_interrupt_type = { #ifdef CONFIG_SMP .set_affinity = cpu_set_affinity_irq, #endif - /* XXX: Needs to be written. We managed without it so far, but - * we really ought to write it. - */ - .retrigger = NULL, }; int show_interrupts(struct seq_file *p, void *v) @@ -162,7 +158,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%10u ", kstat_irqs(i)); #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].handler->typename); #ifndef PARISC_IRQ_CR16_COUNTS seq_printf(p, " %s", action->name); @@ -214,12 +210,12 @@ int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *type, void *data) { if (irq_desc[irq].action) return -EBUSY; - if (irq_desc[irq].chip != &cpu_interrupt_type) + if (irq_desc[irq].handler != &cpu_interrupt_type) return -EBUSY; if (type) { - irq_desc[irq].chip = type; - irq_desc[irq].chip_data = data; + irq_desc[irq].handler = type; + irq_desc[irq].handler_data = data; cpu_interrupt_type.enable(irq); } return 0; @@ -269,7 +265,7 @@ int txn_alloc_irq(unsigned int bits_wide) unsigned long txn_affinity_addr(unsigned int irq, int cpu) { #ifdef CONFIG_SMP - irq_desc[irq].affinity = cpumask_of_cpu(cpu); + irq_affinity[irq] = cpumask_of_cpu(cpu); #endif return cpu_data[cpu].txn_addr; @@ -330,7 +326,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) /* Work our way from MSb to LSb...same order we alloc EIRs */ for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) { #ifdef CONFIG_SMP - cpumask_t dest = irq_desc[irq].affinity; + cpumask_t dest = irq_affinity[irq]; #endif if (!(bit & eirr_val)) continue; @@ -382,7 +378,7 @@ static void claim_cpu_irqs(void) { int i; for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) { - irq_desc[i].chip = &cpu_interrupt_type; + irq_desc[i].handler = &cpu_interrupt_type; } irq_desc[TIMER_IRQ].action = &timer_action; @@ -408,6 +404,13 @@ void __init init_IRQ(void) } +void hw_resend_irq(struct hw_interrupt_type *type, unsigned int irq) +{ + /* XXX: Needs to be written. We managed without it so far, but + * we really ought to write it. + */ +} + void ack_bad_irq(unsigned int irq) { printk("unexpected IRQ %d\n", irq); diff --git a/trunk/arch/parisc/kernel/topology.c b/trunk/arch/parisc/kernel/topology.c index 068b20d822e7..3ba040050e4c 100644 --- a/trunk/arch/parisc/kernel/topology.c +++ b/trunk/arch/parisc/kernel/topology.c @@ -26,10 +26,11 @@ static struct cpu cpu_devices[NR_CPUS] __read_mostly; static int __init topology_init(void) { + struct node *parent = NULL; int num; for_each_present_cpu(num) { - register_cpu(&cpu_devices[num], num); + register_cpu(&cpu_devices[num], num, parent); } return 0; } diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index d43e4521abf2..e922a88b2bad 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -30,10 +30,6 @@ config GENERIC_HARDIRQS bool default y -config IRQ_PER_CPU - bool - default y - config RWSEM_GENERIC_SPINLOCK bool @@ -622,9 +618,6 @@ config HOTPLUG_CPU Say N if you are unsure. -config ARCH_ENABLE_MEMORY_HOTPLUG - def_bool y - config KEXEC bool "kexec system call (EXPERIMENTAL)" depends on PPC_MULTIPLATFORM && EXPERIMENTAL diff --git a/trunk/arch/powerpc/kernel/crash.c b/trunk/arch/powerpc/kernel/crash.c index 22ceba844bf4..e253a45dcf10 100644 --- a/trunk/arch/powerpc/kernel/crash.c +++ b/trunk/arch/powerpc/kernel/crash.c @@ -190,13 +190,13 @@ void default_machine_crash_shutdown(struct pt_regs *regs) local_irq_disable(); for_each_irq(irq) { - struct irq_desc *desc = irq_desc + irq; + struct irq_desc *desc = irq_descp(irq); if (desc->status & IRQ_INPROGRESS) - desc->chip->end(irq); + desc->handler->end(irq); if (!(desc->status & IRQ_DISABLED)) - desc->chip->disable(irq); + desc->handler->disable(irq); } if (ppc_md.kexec_cpu_down) diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 24f6050aa4ab..40d4c14fde8f 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -120,8 +120,8 @@ int show_interrupts(struct seq_file *p, void *v) #else seq_printf(p, "%10u ", kstat_irqs(i)); #endif /* CONFIG_SMP */ - if (desc->chip) - seq_printf(p, " %s ", desc->chip->typename); + if (desc->handler) + seq_printf(p, " %s ", desc->handler->typename); else seq_puts(p, " None "); seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge "); @@ -164,13 +164,13 @@ void fixup_irqs(cpumask_t map) if (irq_desc[irq].status & IRQ_PER_CPU) continue; - cpus_and(mask, irq_desc[irq].affinity, map); + cpus_and(mask, irq_affinity[irq], map); if (any_online_cpu(mask) == NR_CPUS) { printk("Breaking affinity for irq %i\n", irq); mask = map; } - if (irq_desc[irq].chip->set_affinity) - irq_desc[irq].chip->set_affinity(irq, mask); + if (irq_desc[irq].handler->set_affinity) + irq_desc[irq].handler->set_affinity(irq, mask); else if (irq_desc[irq].action && !(warned++)) printk("Cannot set affinity for irq %i\n", irq); } diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index 0932a62a1c96..e5a44812441a 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -215,7 +215,7 @@ int __init ppc_init(void) /* register CPU devices */ for_each_possible_cpu(i) - register_cpu(&cpu_devices[i], i); + register_cpu(&cpu_devices[i], i, NULL); /* call platform init */ if (ppc_md.init != NULL) { diff --git a/trunk/arch/powerpc/kernel/sysfs.c b/trunk/arch/powerpc/kernel/sysfs.c index 4662b580efa1..5bc2585c8036 100644 --- a/trunk/arch/powerpc/kernel/sysfs.c +++ b/trunk/arch/powerpc/kernel/sysfs.c @@ -279,7 +279,7 @@ static void unregister_cpu_online(unsigned int cpu) } #endif /* CONFIG_HOTPLUG_CPU */ -static int __devinit sysfs_cpu_notify(struct notifier_block *self, +static int sysfs_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned int)(long)hcpu; @@ -297,19 +297,30 @@ static int __devinit sysfs_cpu_notify(struct notifier_block *self, return NOTIFY_OK; } -static struct notifier_block __devinitdata sysfs_cpu_nb = { +static struct notifier_block sysfs_cpu_nb = { .notifier_call = sysfs_cpu_notify, }; /* NUMA stuff */ #ifdef CONFIG_NUMA +static struct node node_devices[MAX_NUMNODES]; + static void register_nodes(void) { int i; - for (i = 0; i < MAX_NUMNODES; i++) - register_one_node(i); + for (i = 0; i < MAX_NUMNODES; i++) { + if (node_online(i)) { + int p_node = parent_node(i); + struct node *parent = NULL; + + if (p_node != i) + parent = &node_devices[p_node]; + + register_node(&node_devices[i], i, parent); + } + } } int sysfs_add_device_to_node(struct sys_device *dev, int nid) @@ -348,13 +359,23 @@ static SYSDEV_ATTR(physical_id, 0444, show_physical_id, NULL); static int __init topology_init(void) { int cpu; + struct node *parent = NULL; register_nodes(); + register_cpu_notifier(&sysfs_cpu_nb); for_each_possible_cpu(cpu) { struct cpu *c = &per_cpu(cpu_devices, cpu); +#ifdef CONFIG_NUMA + /* The node to which a cpu belongs can't be known + * until the cpu is made present. + */ + parent = NULL; + if (cpu_present(cpu)) + parent = &node_devices[cpu_to_node(cpu)]; +#endif /* * For now, we just see if the system supports making * the RTAS calls for CPU hotplug. But, there may be a @@ -366,7 +387,7 @@ static int __init topology_init(void) c->no_control = 1; if (cpu_online(cpu) || (c->no_control == 0)) { - register_cpu(c, cpu); + register_cpu(c, cpu, parent); sysdev_create_file(&c->sysdev, &attr_physical_id); } diff --git a/trunk/arch/powerpc/mm/init_64.c b/trunk/arch/powerpc/mm/init_64.c index d454caada265..9e30f968c184 100644 --- a/trunk/arch/powerpc/mm/init_64.c +++ b/trunk/arch/powerpc/mm/init_64.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include @@ -91,7 +90,7 @@ void free_initmem(void) addr = (unsigned long)__init_begin; for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) { - memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); + memset((void *)addr, 0xcc, PAGE_SIZE); ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); free_page(addr); diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 089d939a0b3e..69f3b9a20beb 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -114,20 +114,15 @@ void online_page(struct page *page) num_physpages++; } -#ifdef CONFIG_NUMA -int memory_add_physaddr_to_nid(u64 start) -{ - return hot_add_scn_to_nid(start); -} -#endif - -int __devinit arch_add_memory(int nid, u64 start, u64 size) +int __devinit add_memory(u64 start, u64 size) { struct pglist_data *pgdata; 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 = (unsigned long)__va(start); diff --git a/trunk/arch/powerpc/mm/numa.c b/trunk/arch/powerpc/mm/numa.c index fbe23933f731..aa98cb3b59d8 100644 --- a/trunk/arch/powerpc/mm/numa.c +++ b/trunk/arch/powerpc/mm/numa.c @@ -334,7 +334,7 @@ static int __cpuinit numa_setup_cpu(unsigned long lcpu) return nid; } -static int __cpuinit cpu_numa_callback(struct notifier_block *nfb, +static int cpu_numa_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -609,15 +609,14 @@ static void __init *careful_allocation(int nid, unsigned long size, return (void *)ret; } -static struct notifier_block __cpuinitdata ppc64_numa_nb = { - .notifier_call = cpu_numa_callback, - .priority = 1 /* Must run before sched domains notifier. */ -}; - void __init do_init_bootmem(void) { int nid; unsigned int i; + static struct notifier_block ppc64_numa_nb = { + .notifier_call = cpu_numa_callback, + .priority = 1 /* Must run before sched domains notifier. */ + }; min_low_pfn = 0; max_low_pfn = lmb_end_of_DRAM() >> PAGE_SHIFT; diff --git a/trunk/arch/powerpc/platforms/cell/interrupt.c b/trunk/arch/powerpc/platforms/cell/interrupt.c index 7bff3cbc5723..1bbf822b4efc 100644 --- a/trunk/arch/powerpc/platforms/cell/interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/interrupt.c @@ -307,7 +307,7 @@ static void iic_request_ipi(int ipi, const char *name) irq = iic_ipi_to_irq(ipi); /* IPIs are marked SA_INTERRUPT as they must run with irqs * disabled */ - get_irq_desc(irq)->chip = &iic_pic; + get_irq_desc(irq)->handler = &iic_pic; get_irq_desc(irq)->status |= IRQ_PER_CPU; request_irq(irq, iic_ipi_action, SA_INTERRUPT, name, NULL); } @@ -330,7 +330,7 @@ static void iic_setup_spe_handlers(void) for (be=0; be < num_present_cpus() / 2; be++) { for (isrc = 0; isrc < IIC_CLASS_STRIDE * 3; isrc++) { int irq = IIC_NODE_STRIDE * be + IIC_SPE_OFFSET + isrc; - get_irq_desc(irq)->chip = &iic_pic; + get_irq_desc(irq)->handler = &iic_pic; } } } diff --git a/trunk/arch/powerpc/platforms/cell/spider-pic.c b/trunk/arch/powerpc/platforms/cell/spider-pic.c index 7c3a0b6d34fd..55cbdd77a62d 100644 --- a/trunk/arch/powerpc/platforms/cell/spider-pic.c +++ b/trunk/arch/powerpc/platforms/cell/spider-pic.c @@ -162,7 +162,7 @@ void spider_init_IRQ_hardcoded(void) spider_pics[node] = ioremap(spiderpic, 0x800); for (n = 0; n < IIC_NUM_EXT; n++) { int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; - get_irq_desc(irq)->chip = &spider_pic; + get_irq_desc(irq)->handler = &spider_pic; } /* do not mask any interrupts because of level */ @@ -217,7 +217,7 @@ void spider_init_IRQ(void) for (n = 0; n < IIC_NUM_EXT; n++) { int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; - get_irq_desc(irq)->chip = &spider_pic; + get_irq_desc(irq)->handler = &spider_pic; } /* do not mask any interrupts because of level */ diff --git a/trunk/arch/powerpc/platforms/cell/spufs/switch.c b/trunk/arch/powerpc/platforms/cell/spufs/switch.c index a656d810a44a..3068b429b031 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/switch.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/switch.c @@ -2203,7 +2203,7 @@ void spu_init_csa(struct spu_state *csa) memset(lscsa, 0, sizeof(struct spu_lscsa)); csa->lscsa = lscsa; - spin_lock_init(&csa->register_lock); + 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) diff --git a/trunk/arch/powerpc/platforms/iseries/irq.c b/trunk/arch/powerpc/platforms/iseries/irq.c index 33bb4aa0e1e8..62bbbcf5ded3 100644 --- a/trunk/arch/powerpc/platforms/iseries/irq.c +++ b/trunk/arch/powerpc/platforms/iseries/irq.c @@ -242,9 +242,9 @@ void __init iSeries_activate_IRQs() for_each_irq (irq) { irq_desc_t *desc = get_irq_desc(irq); - if (desc && desc->chip && desc->chip->startup) { + if (desc && desc->handler && desc->handler->startup) { spin_lock_irqsave(&desc->lock, flags); - desc->chip->startup(irq); + desc->handler->startup(irq); spin_unlock_irqrestore(&desc->lock, flags); } } @@ -324,7 +324,7 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus, + function; virtirq = virt_irq_create_mapping(realirq); - irq_desc[virtirq].chip = &iSeries_IRQ_handler; + irq_desc[virtirq].handler = &iSeries_IRQ_handler; return virtirq; } diff --git a/trunk/arch/powerpc/platforms/powermac/backlight.c b/trunk/arch/powerpc/platforms/powermac/backlight.c index c7a27eddca6d..498b042e1837 100644 --- a/trunk/arch/powerpc/platforms/powermac/backlight.c +++ b/trunk/arch/powerpc/platforms/powermac/backlight.c @@ -119,14 +119,7 @@ int pmac_backlight_set_legacy_brightness(int brightness) down(&pmac_backlight->sem); props = pmac_backlight->props; props->brightness = brightness * - (props->max_brightness + 1) / - (OLD_BACKLIGHT_MAX + 1); - - if (props->brightness > props->max_brightness) - props->brightness = props->max_brightness; - else if (props->brightness < 0) - props->brightness = 0; - + props->max_brightness / OLD_BACKLIGHT_MAX; props->update_status(pmac_backlight); up(&pmac_backlight->sem); @@ -147,11 +140,8 @@ int pmac_backlight_get_legacy_brightness() down(&pmac_backlight->sem); props = pmac_backlight->props; - result = props->brightness * - (OLD_BACKLIGHT_MAX + 1) / - (props->max_brightness + 1); - + OLD_BACKLIGHT_MAX / props->max_brightness; up(&pmac_backlight->sem); } mutex_unlock(&pmac_backlight_mutex); diff --git a/trunk/arch/powerpc/platforms/powermac/pfunc_core.c b/trunk/arch/powerpc/platforms/powermac/pfunc_core.c index 93e7505debc5..047f954a89eb 100644 --- a/trunk/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/trunk/arch/powerpc/platforms/powermac/pfunc_core.c @@ -546,7 +546,7 @@ struct pmf_device { }; static LIST_HEAD(pmf_devices); -static DEFINE_SPINLOCK(pmf_lock); +static spinlock_t pmf_lock = SPIN_LOCK_UNLOCKED; static DEFINE_MUTEX(pmf_irq_mutex); static void pmf_release_device(struct kref *kref) diff --git a/trunk/arch/powerpc/platforms/powermac/pic.c b/trunk/arch/powerpc/platforms/powermac/pic.c index 9f6189af6dd6..18bf3011d1e3 100644 --- a/trunk/arch/powerpc/platforms/powermac/pic.c +++ b/trunk/arch/powerpc/platforms/powermac/pic.c @@ -446,7 +446,7 @@ static void __init pmac_pic_probe_oldstyle(void) /* Set the handler for the main PIC */ for ( i = 0; i < max_real_irqs ; i++ ) - irq_desc[i].chip = &pmac_pic; + 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)); @@ -493,7 +493,7 @@ static void __init pmac_pic_probe_oldstyle(void) /* Setup handlers for secondary controller and hook cascade irq*/ if (slave) { for ( i = max_real_irqs ; i < max_irqs ; i++ ) - irq_desc[i].chip = &gatwick_pic; + 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); diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_event.c b/trunk/arch/powerpc/platforms/pseries/eeh_event.c index 45ccc687e57c..8f2d12935b99 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_event.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_event.c @@ -35,7 +35,7 @@ */ /* EEH event workqueue setup. */ -static DEFINE_SPINLOCK(eeh_eventlist_lock); +static spinlock_t eeh_eventlist_lock = SPIN_LOCK_UNLOCKED; LIST_HEAD(eeh_eventlist); static void eeh_thread_launcher(void *); DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL); diff --git a/trunk/arch/powerpc/platforms/pseries/xics.c b/trunk/arch/powerpc/platforms/pseries/xics.c index 19c03dd43000..b14f9b5c114e 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.c +++ b/trunk/arch/powerpc/platforms/pseries/xics.c @@ -238,7 +238,7 @@ static int get_irq_server(unsigned int irq) { unsigned int server; /* For the moment only implement delivery to all cpus or one cpu */ - cpumask_t cpumask = irq_desc[irq].affinity; + cpumask_t cpumask = irq_affinity[irq]; cpumask_t tmp = CPU_MASK_NONE; if (!distribute_irqs) @@ -558,7 +558,7 @@ void xics_init_IRQ(void) } for (i = irq_offset_value(); i < NR_IRQS; ++i) - get_irq_desc(i)->chip = &xics_pic; + get_irq_desc(i)->handler = &xics_pic; xics_setup_cpu(); @@ -701,9 +701,9 @@ void xics_migrate_irqs_away(void) continue; /* We only need to migrate enabled IRQS */ - if (desc == NULL || desc->chip == NULL + if (desc == NULL || desc->handler == NULL || desc->action == NULL - || desc->chip->set_affinity == NULL) + || desc->handler->set_affinity == NULL) continue; spin_lock_irqsave(&desc->lock, flags); @@ -728,8 +728,8 @@ void xics_migrate_irqs_away(void) virq, cpu); /* Reset affinity to all cpus */ - desc->chip->set_affinity(virq, CPU_MASK_ALL); - irq_desc[irq].affinity = CPU_MASK_ALL; + desc->handler->set_affinity(virq, CPU_MASK_ALL); + irq_affinity[virq] = CPU_MASK_ALL; unlock: spin_unlock_irqrestore(&desc->lock, flags); } diff --git a/trunk/arch/powerpc/sysdev/i8259.c b/trunk/arch/powerpc/sysdev/i8259.c index 2bff30f6d635..b7ac32fdd776 100644 --- a/trunk/arch/powerpc/sysdev/i8259.c +++ b/trunk/arch/powerpc/sysdev/i8259.c @@ -208,7 +208,7 @@ void __init i8259_init(unsigned long intack_addr, int offset) spin_unlock_irqrestore(&i8259_lock, flags); for (i = 0; i < NUM_ISA_INTERRUPTS; ++i) - irq_desc[offset + i].chip = &i8259_pic; + irq_desc[offset + i].handler = &i8259_pic; /* reserve our resources */ setup_irq(offset + 2, &i8259_irqaction); diff --git a/trunk/arch/powerpc/sysdev/ipic.c b/trunk/arch/powerpc/sysdev/ipic.c index 46801f5ec03f..8f01e0f1d847 100644 --- a/trunk/arch/powerpc/sysdev/ipic.c +++ b/trunk/arch/powerpc/sysdev/ipic.c @@ -472,7 +472,7 @@ void __init ipic_init(phys_addr_t phys_addr, ipic_write(primary_ipic->regs, IPIC_SEMSR, temp); for (i = 0 ; i < NR_IPIC_INTS ; i++) { - irq_desc[i+irq_offset].chip = &ipic; + irq_desc[i+irq_offset].handler = &ipic; irq_desc[i+irq_offset].status = IRQ_LEVEL; } diff --git a/trunk/arch/powerpc/sysdev/mmio_nvram.c b/trunk/arch/powerpc/sysdev/mmio_nvram.c index 615350d46b52..74e0d31a3559 100644 --- a/trunk/arch/powerpc/sysdev/mmio_nvram.c +++ b/trunk/arch/powerpc/sysdev/mmio_nvram.c @@ -32,7 +32,7 @@ static void __iomem *mmio_nvram_start; static long mmio_nvram_len; -static DEFINE_SPINLOCK(mmio_nvram_lock); +static spinlock_t mmio_nvram_lock = SPIN_LOCK_UNLOCKED; static ssize_t mmio_nvram_read(char *buf, size_t count, loff_t *index) { diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index 28df9c827ca6..bffe50d02c99 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -379,14 +379,14 @@ static inline u32 mpic_physmask(u32 cpumask) /* Get the mpic structure from the IPI number */ static inline struct mpic * mpic_from_ipi(unsigned int ipi) { - return container_of(irq_desc[ipi].chip, struct mpic, hc_ipi); + return container_of(irq_desc[ipi].handler, struct mpic, hc_ipi); } #endif /* Get the mpic structure from the irq number */ static inline struct mpic * mpic_from_irq(unsigned int irq) { - return container_of(irq_desc[irq].chip, struct mpic, hc_irq); + return container_of(irq_desc[irq].handler, struct mpic, hc_irq); } /* Send an EOI */ @@ -752,7 +752,7 @@ void __init mpic_init(struct mpic *mpic) if (!(mpic->flags & MPIC_PRIMARY)) continue; irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU; - irq_desc[mpic->ipi_offset+i].chip = &mpic->hc_ipi; + irq_desc[mpic->ipi_offset+i].handler = &mpic->hc_ipi; #endif /* CONFIG_SMP */ } @@ -813,7 +813,7 @@ void __init mpic_init(struct mpic *mpic) /* init linux descriptors */ if (i < mpic->irq_count) { irq_desc[mpic->irq_offset+i].status = level ? IRQ_LEVEL : 0; - irq_desc[mpic->irq_offset+i].chip = &mpic->hc_irq; + irq_desc[mpic->irq_offset+i].handler = &mpic->hc_irq; } } @@ -906,7 +906,7 @@ void mpic_setup_this_cpu(void) /* let the mpic know we want intrs. default affinity is 0xffffffff * until changed via /proc. That's how it's done on x86. If we want * it differently, then we should make sure we also change the default - * values of irq_desc[].affinity in irq.c. + * values of irq_affinity in irq.c. */ if (distribute_irqs) { for (i = 0; i < mpic->num_sources ; i++) diff --git a/trunk/arch/ppc/8xx_io/commproc.c b/trunk/arch/ppc/8xx_io/commproc.c index 9b3ace26280c..12b84ca51327 100644 --- a/trunk/arch/ppc/8xx_io/commproc.c +++ b/trunk/arch/ppc/8xx_io/commproc.c @@ -187,7 +187,7 @@ cpm_interrupt_init(void) * interrupt vectors */ for ( i = CPM_IRQ_OFFSET ; i < CPM_IRQ_OFFSET + NR_CPM_INTS ; i++ ) - irq_desc[i].chip = &cpm_pic; + irq_desc[i].handler = &cpm_pic; /* Set our interrupt handler with the core CPU. */ if (setup_irq(CPM_INTERRUPT, &cpm_interrupt_irqaction)) diff --git a/trunk/arch/ppc/kernel/setup.c b/trunk/arch/ppc/kernel/setup.c index 4b4607d89bfa..1f79e84ab464 100644 --- a/trunk/arch/ppc/kernel/setup.c +++ b/trunk/arch/ppc/kernel/setup.c @@ -475,7 +475,7 @@ int __init ppc_init(void) /* register CPU devices */ for_each_possible_cpu(i) - register_cpu(&cpu_devices[i], i); + register_cpu(&cpu_devices[i], i, NULL); /* call platform init */ if (ppc_md.init != NULL) { diff --git a/trunk/arch/ppc/platforms/apus_setup.c b/trunk/arch/ppc/platforms/apus_setup.c index 5c4118a459f3..fe0cdc04d436 100644 --- a/trunk/arch/ppc/platforms/apus_setup.c +++ b/trunk/arch/ppc/platforms/apus_setup.c @@ -734,9 +734,9 @@ void apus_init_IRQ(void) for ( i = 0 ; i < AMI_IRQS; i++ ) { irq_desc[i].status = IRQ_LEVEL; if (i < IRQ_AMIGA_AUTO) { - irq_desc[i].chip = &amiga_irqctrl; + irq_desc[i].handler = &amiga_irqctrl; } else { - irq_desc[i].chip = &amiga_sys_irqctrl; + irq_desc[i].handler = &amiga_sys_irqctrl; action = &amiga_sys_irqaction[i-IRQ_AMIGA_AUTO]; if (action->name) setup_irq(i, action); diff --git a/trunk/arch/ppc/platforms/sbc82xx.c b/trunk/arch/ppc/platforms/sbc82xx.c index 41006d2b4b38..866807b4ad0b 100644 --- a/trunk/arch/ppc/platforms/sbc82xx.c +++ b/trunk/arch/ppc/platforms/sbc82xx.c @@ -172,7 +172,7 @@ void __init sbc82xx_init_IRQ(void) /* Set up the interrupt handlers for the i8259 IRQs */ for (i = NR_SIU_INTS; i < NR_SIU_INTS + 8; i++) { - irq_desc[i].chip = &sbc82xx_i8259_ic; + irq_desc[i].handler = &sbc82xx_i8259_ic; irq_desc[i].status |= IRQ_LEVEL; } diff --git a/trunk/arch/ppc/syslib/cpc700_pic.c b/trunk/arch/ppc/syslib/cpc700_pic.c index 172aa215fdb0..5add0a919ef6 100644 --- a/trunk/arch/ppc/syslib/cpc700_pic.c +++ b/trunk/arch/ppc/syslib/cpc700_pic.c @@ -140,12 +140,12 @@ cpc700_init_IRQ(void) /* IRQ 0 is highest */ for (i = 0; i < 17; i++) { - irq_desc[i].chip = &cpc700_pic; + irq_desc[i].handler = &cpc700_pic; cpc700_pic_init_irq(i); } for (i = 20; i < 32; i++) { - irq_desc[i].chip = &cpc700_pic; + irq_desc[i].handler = &cpc700_pic; cpc700_pic_init_irq(i); } diff --git a/trunk/arch/ppc/syslib/cpm2_pic.c b/trunk/arch/ppc/syslib/cpm2_pic.c index c0fee0beb815..29d95d415ceb 100644 --- a/trunk/arch/ppc/syslib/cpm2_pic.c +++ b/trunk/arch/ppc/syslib/cpm2_pic.c @@ -171,7 +171,7 @@ void cpm2_init_IRQ(void) /* Enable chaining to OpenPIC, and make everything level */ for (i = 0; i < NR_CPM_INTS; i++) { - irq_desc[i+CPM_IRQ_OFFSET].chip = &cpm2_pic; + irq_desc[i+CPM_IRQ_OFFSET].handler = &cpm2_pic; irq_desc[i+CPM_IRQ_OFFSET].status |= IRQ_LEVEL; } } diff --git a/trunk/arch/ppc/syslib/gt64260_pic.c b/trunk/arch/ppc/syslib/gt64260_pic.c index 91096b38ae70..dc3bd9ecbbf6 100644 --- a/trunk/arch/ppc/syslib/gt64260_pic.c +++ b/trunk/arch/ppc/syslib/gt64260_pic.c @@ -98,7 +98,7 @@ gt64260_init_irq(void) /* use the gt64260 for all (possible) interrupt sources */ for (i = gt64260_irq_base; i < (gt64260_irq_base + 96); i++) - irq_desc[i].chip = >64260_pic; + irq_desc[i].handler = >64260_pic; if (ppc_md.progress) ppc_md.progress("gt64260_init_irq: exit", 0x0); diff --git a/trunk/arch/ppc/syslib/m82xx_pci.c b/trunk/arch/ppc/syslib/m82xx_pci.c index 63fa5b313396..1941a8c7ca9a 100644 --- a/trunk/arch/ppc/syslib/m82xx_pci.c +++ b/trunk/arch/ppc/syslib/m82xx_pci.c @@ -159,7 +159,7 @@ pq2pci_init_irq(void) immap->im_memctl.memc_or8 = 0xffff8010; #endif for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++) - irq_desc[irq].chip = &pq2pci_ic; + irq_desc[irq].handler = &pq2pci_ic; /* make PCI IRQ level sensitive */ immap->im_intctl.ic_siexr &= diff --git a/trunk/arch/ppc/syslib/m8xx_setup.c b/trunk/arch/ppc/syslib/m8xx_setup.c index 0c4c0de7c59f..dae9af78bde1 100644 --- a/trunk/arch/ppc/syslib/m8xx_setup.c +++ b/trunk/arch/ppc/syslib/m8xx_setup.c @@ -347,13 +347,13 @@ m8xx_init_IRQ(void) int i; for (i = SIU_IRQ_OFFSET ; i < SIU_IRQ_OFFSET + NR_SIU_INTS ; i++) - irq_desc[i].chip = &ppc8xx_pic; + irq_desc[i].handler = &ppc8xx_pic; cpm_interrupt_init(); #if defined(CONFIG_PCI) for (i = I8259_IRQ_OFFSET ; i < I8259_IRQ_OFFSET + NR_8259_INTS ; i++) - irq_desc[i].chip = &i8259_pic; + irq_desc[i].handler = &i8259_pic; i8259_pic_irq_offset = I8259_IRQ_OFFSET; i8259_init(0); diff --git a/trunk/arch/ppc/syslib/mpc52xx_pic.c b/trunk/arch/ppc/syslib/mpc52xx_pic.c index 6425b5cee7db..c4406f9dc6a3 100644 --- a/trunk/arch/ppc/syslib/mpc52xx_pic.c +++ b/trunk/arch/ppc/syslib/mpc52xx_pic.c @@ -204,9 +204,9 @@ mpc52xx_init_irq(void) out_be32(&intr->main_pri1, 0); out_be32(&intr->main_pri2, 0); - /* Initialize irq_desc[i].chip's with mpc52xx_ic. */ + /* Initialize irq_desc[i].handler's with mpc52xx_ic. */ for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].chip = &mpc52xx_ic; + irq_desc[i].handler = &mpc52xx_ic; irq_desc[i].status = IRQ_LEVEL; } diff --git a/trunk/arch/ppc/syslib/mv64360_pic.c b/trunk/arch/ppc/syslib/mv64360_pic.c index a4244d468381..5a19697060f0 100644 --- a/trunk/arch/ppc/syslib/mv64360_pic.c +++ b/trunk/arch/ppc/syslib/mv64360_pic.c @@ -119,7 +119,7 @@ mv64360_init_irq(void) /* All interrupts are level interrupts */ for (i = mv64360_irq_base; i < (mv64360_irq_base + 96); i++) { irq_desc[i].status |= IRQ_LEVEL; - irq_desc[i].chip = &mv64360_pic; + irq_desc[i].handler = &mv64360_pic; } if (ppc_md.progress) diff --git a/trunk/arch/ppc/syslib/open_pic.c b/trunk/arch/ppc/syslib/open_pic.c index 767a0bc95817..70456c8f998c 100644 --- a/trunk/arch/ppc/syslib/open_pic.c +++ b/trunk/arch/ppc/syslib/open_pic.c @@ -373,7 +373,7 @@ void __init openpic_init(int offset) OPENPIC_VEC_IPI+i+offset); /* IPIs are per-CPU */ irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU; - irq_desc[OPENPIC_VEC_IPI+i+offset].chip = &open_pic_ipi; + irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi; } #endif @@ -408,7 +408,7 @@ void __init openpic_init(int offset) /* Init descriptors */ for (i = offset; i < NumSources + offset; i++) - irq_desc[i].chip = &open_pic; + irq_desc[i].handler = &open_pic; /* Initialize the spurious interrupt */ if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd); @@ -615,8 +615,8 @@ void __devinit do_openpic_setup_cpu(void) /* let the openpic know we want intrs. default affinity * is 0xffffffff until changed via /proc * That's how it's done on x86. If we want it differently, then - * we should make sure we also change the default values of - * irq_desc[].affinity in irq.c. + * we should make sure we also change the default values of irq_affinity + * in irq.c. */ for (i = 0; i < NumSources; i++) openpic_mapirq(i, msk, CPU_MASK_ALL); diff --git a/trunk/arch/ppc/syslib/open_pic2.c b/trunk/arch/ppc/syslib/open_pic2.c index b8154efff6ed..bcbe40de26fe 100644 --- a/trunk/arch/ppc/syslib/open_pic2.c +++ b/trunk/arch/ppc/syslib/open_pic2.c @@ -290,7 +290,7 @@ void __init openpic2_init(int offset) /* Init descriptors */ for (i = offset; i < NumSources + offset; i++) - irq_desc[i].chip = &open_pic2; + irq_desc[i].handler = &open_pic2; /* Initialize the spurious interrupt */ if (ppc_md.progress) ppc_md.progress("openpic2: spurious",0x3bd); diff --git a/trunk/arch/ppc/syslib/ppc403_pic.c b/trunk/arch/ppc/syslib/ppc403_pic.c index 1584c8b1229f..c46043c47225 100644 --- a/trunk/arch/ppc/syslib/ppc403_pic.c +++ b/trunk/arch/ppc/syslib/ppc403_pic.c @@ -121,5 +121,5 @@ ppc4xx_pic_init(void) ppc_md.get_irq = ppc403_pic_get_irq; for (i = 0; i < NR_IRQS; i++) - irq_desc[i].chip = &ppc403_aic; + irq_desc[i].handler = &ppc403_aic; } diff --git a/trunk/arch/ppc/syslib/ppc4xx_pic.c b/trunk/arch/ppc/syslib/ppc4xx_pic.c index e669c1335d47..fd9af0fc0e9f 100644 --- a/trunk/arch/ppc/syslib/ppc4xx_pic.c +++ b/trunk/arch/ppc/syslib/ppc4xx_pic.c @@ -276,7 +276,7 @@ void __init ppc4xx_pic_init(void) /* Attach low-level handlers */ for (i = 0; i < (NR_UICS << 5); ++i) { - irq_desc[i].chip = &__uic[i >> 5].decl; + irq_desc[i].handler = &__uic[i >> 5].decl; if (is_level_sensitive(i)) irq_desc[i].status |= IRQ_LEVEL; } diff --git a/trunk/arch/ppc/syslib/xilinx_pic.c b/trunk/arch/ppc/syslib/xilinx_pic.c index 39a93dc6375b..e672b600f315 100644 --- a/trunk/arch/ppc/syslib/xilinx_pic.c +++ b/trunk/arch/ppc/syslib/xilinx_pic.c @@ -143,7 +143,7 @@ ppc4xx_pic_init(void) ppc_md.get_irq = xilinx_pic_get_irq; for (i = 0; i < NR_IRQS; ++i) { - irq_desc[i].chip = &xilinx_intc; + irq_desc[i].handler = &xilinx_intc; if (XPAR_INTC_0_KIND_OF_INTR & (0x00000001 << i)) irq_desc[i].status &= ~IRQ_LEVEL; diff --git a/trunk/arch/s390/appldata/appldata_base.c b/trunk/arch/s390/appldata/appldata_base.c index 54d35c130907..9a22434a580c 100644 --- a/trunk/arch/s390/appldata/appldata_base.c +++ b/trunk/arch/s390/appldata/appldata_base.c @@ -652,7 +652,7 @@ appldata_cpu_notify(struct notifier_block *self, return NOTIFY_OK; } -static struct notifier_block __devinitdata appldata_nb = { +static struct notifier_block appldata_nb = { .notifier_call = appldata_cpu_notify, }; diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 8e03219eea76..343120c9223d 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -869,7 +869,7 @@ static int __init topology_init(void) int ret; for_each_possible_cpu(cpu) { - ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu); + ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL); if (ret) printk(KERN_WARNING "topology_init: register_cpu %d " "failed (%d)\n", cpu, ret); diff --git a/trunk/arch/sh/boards/adx/irq_maskreg.c b/trunk/arch/sh/boards/adx/irq_maskreg.c index 357fab1bac2b..c0973f8d57ba 100644 --- a/trunk/arch/sh/boards/adx/irq_maskreg.c +++ b/trunk/arch/sh/boards/adx/irq_maskreg.c @@ -102,6 +102,6 @@ static void end_maskreg_irq(unsigned int irq) void make_maskreg_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = &maskreg_irq_type; + irq_desc[irq].handler = &maskreg_irq_type; disable_maskreg_irq(irq); } diff --git a/trunk/arch/sh/boards/bigsur/irq.c b/trunk/arch/sh/boards/bigsur/irq.c index 1d32425782c0..6ddbcc77244d 100644 --- a/trunk/arch/sh/boards/bigsur/irq.c +++ b/trunk/arch/sh/boards/bigsur/irq.c @@ -253,7 +253,7 @@ static void make_bigsur_l1isr(unsigned int irq) { /* sanity check first */ if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { /* save the handler in the main description table */ - irq_desc[irq].chip = &bigsur_l1irq_type; + irq_desc[irq].handler = &bigsur_l1irq_type; irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = 0; irq_desc[irq].depth = 1; @@ -270,7 +270,7 @@ static void make_bigsur_l2isr(unsigned int irq) { /* sanity check first */ if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { /* save the handler in the main description table */ - irq_desc[irq].chip = &bigsur_l2irq_type; + irq_desc[irq].handler = &bigsur_l2irq_type; irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = 0; irq_desc[irq].depth = 1; diff --git a/trunk/arch/sh/boards/cqreek/irq.c b/trunk/arch/sh/boards/cqreek/irq.c index 2955adc52310..d1da0d844567 100644 --- a/trunk/arch/sh/boards/cqreek/irq.c +++ b/trunk/arch/sh/boards/cqreek/irq.c @@ -103,7 +103,7 @@ void __init init_cqreek_IRQ(void) cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT; cqreek_irq_data[14].bit = 1; - irq_desc[14].chip = &cqreek_irq_type; + irq_desc[14].handler = &cqreek_irq_type; irq_desc[14].status = IRQ_DISABLED; irq_desc[14].action = 0; irq_desc[14].depth = 1; @@ -117,7 +117,7 @@ void __init init_cqreek_IRQ(void) cqreek_irq_data[10].bit = (1 << 10); /* XXX: Err... we may need demultiplexer for ISA irq... */ - irq_desc[10].chip = &cqreek_irq_type; + irq_desc[10].handler = &cqreek_irq_type; irq_desc[10].status = IRQ_DISABLED; irq_desc[10].action = 0; irq_desc[10].depth = 1; diff --git a/trunk/arch/sh/boards/dreamcast/setup.c b/trunk/arch/sh/boards/dreamcast/setup.c index 0027b80a2343..55dece35cde5 100644 --- a/trunk/arch/sh/boards/dreamcast/setup.c +++ b/trunk/arch/sh/boards/dreamcast/setup.c @@ -70,7 +70,7 @@ int __init platform_setup(void) /* Assign all virtual IRQs to the System ASIC int. handler */ for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) - irq_desc[i].chip = &systemasic_int; + irq_desc[i].handler = &systemasic_int; board_time_init = aica_time_init; diff --git a/trunk/arch/sh/boards/ec3104/setup.c b/trunk/arch/sh/boards/ec3104/setup.c index 4b3ef16a0e96..5130ba2b6ff1 100644 --- a/trunk/arch/sh/boards/ec3104/setup.c +++ b/trunk/arch/sh/boards/ec3104/setup.c @@ -63,7 +63,7 @@ int __init platform_setup(void) str[i] = ctrl_readb(EC3104_BASE + i); for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++) - irq_desc[i].chip = &ec3104_int; + irq_desc[i].handler = &ec3104_int; printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n", str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE); diff --git a/trunk/arch/sh/boards/harp/irq.c b/trunk/arch/sh/boards/harp/irq.c index 701fa55d5297..52d0ba39031b 100644 --- a/trunk/arch/sh/boards/harp/irq.c +++ b/trunk/arch/sh/boards/harp/irq.c @@ -114,7 +114,7 @@ static void enable_harp_irq(unsigned int irq) static void __init make_harp_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = &harp_irq_type; + irq_desc[irq].handler = &harp_irq_type; disable_harp_irq(irq); } diff --git a/trunk/arch/sh/boards/mpc1211/setup.c b/trunk/arch/sh/boards/mpc1211/setup.c index b72f009c52c2..2bb581b91683 100644 --- a/trunk/arch/sh/boards/mpc1211/setup.c +++ b/trunk/arch/sh/boards/mpc1211/setup.c @@ -194,7 +194,7 @@ static struct hw_interrupt_type mpc1211_irq_type = { static void make_mpc1211_irq(unsigned int irq) { - irq_desc[irq].chip = &mpc1211_irq_type; + irq_desc[irq].handler = &mpc1211_irq_type; irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = 0; irq_desc[irq].depth = 1; diff --git a/trunk/arch/sh/boards/overdrive/irq.c b/trunk/arch/sh/boards/overdrive/irq.c index 2c13a7de6b22..715e8feb3a68 100644 --- a/trunk/arch/sh/boards/overdrive/irq.c +++ b/trunk/arch/sh/boards/overdrive/irq.c @@ -150,7 +150,7 @@ static void enable_od_irq(unsigned int irq) static void __init make_od_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = &od_irq_type; + irq_desc[irq].handler = &od_irq_type; disable_od_irq(irq); } diff --git a/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c b/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c index 52a98b524e1f..ed4c5b50ea45 100644 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c @@ -86,7 +86,7 @@ static struct hw_interrupt_type hs7751rvoip_irq_type = { static void make_hs7751rvoip_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = &hs7751rvoip_irq_type; + irq_desc[irq].handler = &hs7751rvoip_irq_type; disable_hs7751rvoip_irq(irq); } diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c b/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c index e16915d9cda4..d36c9374aed1 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c @@ -100,7 +100,7 @@ static struct hw_interrupt_type rts7751r2d_irq_type = { static void make_rts7751r2d_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = &rts7751r2d_irq_type; + irq_desc[irq].handler = &rts7751r2d_irq_type; disable_rts7751r2d_irq(irq); } diff --git a/trunk/arch/sh/boards/renesas/systemh/irq.c b/trunk/arch/sh/boards/renesas/systemh/irq.c index 845979181059..7a2eb10edb56 100644 --- a/trunk/arch/sh/boards/renesas/systemh/irq.c +++ b/trunk/arch/sh/boards/renesas/systemh/irq.c @@ -105,7 +105,7 @@ static void end_systemh_irq(unsigned int irq) void make_systemh_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = &systemh_irq_type; + irq_desc[irq].handler = &systemh_irq_type; disable_systemh_irq(irq); } diff --git a/trunk/arch/sh/boards/se/73180/irq.c b/trunk/arch/sh/boards/se/73180/irq.c index 402735c7c898..70f04caad9a4 100644 --- a/trunk/arch/sh/boards/se/73180/irq.c +++ b/trunk/arch/sh/boards/se/73180/irq.c @@ -85,7 +85,7 @@ void make_intreq_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = &intreq_irq_type; + irq_desc[irq].handler = &intreq_irq_type; disable_intreq_irq(irq); } diff --git a/trunk/arch/sh/boards/superh/microdev/irq.c b/trunk/arch/sh/boards/superh/microdev/irq.c index cb5999425d16..efcbd86b7cd2 100644 --- a/trunk/arch/sh/boards/superh/microdev/irq.c +++ b/trunk/arch/sh/boards/superh/microdev/irq.c @@ -147,7 +147,7 @@ static void enable_microdev_irq(unsigned int irq) static void __init make_microdev_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = µdev_irq_type; + irq_desc[irq].handler = µdev_irq_type; disable_microdev_irq(irq); } diff --git a/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c b/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c index 724db04cb392..f014b9bf6922 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c @@ -154,7 +154,7 @@ int __init setup_hd64461(void) outw(0xffff, HD64461_NIMR); for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { - irq_desc[i].chip = &hd64461_irq_type; + irq_desc[i].handler = &hd64461_irq_type; } setup_irq(CONFIG_HD64461_IRQ, &irq0); diff --git a/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c b/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c index cf9142c620b7..68e4c4e4283d 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c @@ -182,7 +182,7 @@ static int __init setup_hd64465(void) outw(0xffff, HD64465_REG_NIMR); /* mask all interrupts */ for (i = 0; i < HD64465_IRQ_NUM ; i++) { - irq_desc[HD64465_IRQ_BASE + i].chip = &hd64465_irq_type; + irq_desc[HD64465_IRQ_BASE + i].handler = &hd64465_irq_type; } setup_irq(CONFIG_HD64465_IRQ, &irq0); diff --git a/trunk/arch/sh/cchips/voyagergx/irq.c b/trunk/arch/sh/cchips/voyagergx/irq.c index 892214bade19..2ee330b3c38f 100644 --- a/trunk/arch/sh/cchips/voyagergx/irq.c +++ b/trunk/arch/sh/cchips/voyagergx/irq.c @@ -191,7 +191,7 @@ void __init setup_voyagergx_irq(void) flag = 1; } if (flag == 1) - irq_desc[VOYAGER_IRQ_BASE + i].chip = &voyagergx_irq_type; + irq_desc[VOYAGER_IRQ_BASE + i].handler = &voyagergx_irq_type; } setup_irq(IRQ_VOYAGER, &irq0); diff --git a/trunk/arch/sh/kernel/cpu/irq/imask.c b/trunk/arch/sh/kernel/cpu/irq/imask.c index a33ae3e0a5a5..baed9a550d39 100644 --- a/trunk/arch/sh/kernel/cpu/irq/imask.c +++ b/trunk/arch/sh/kernel/cpu/irq/imask.c @@ -105,6 +105,6 @@ static void shutdown_imask_irq(unsigned int irq) void make_imask_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = &imask_irq_type; + irq_desc[irq].handler = &imask_irq_type; enable_irq(irq); } diff --git a/trunk/arch/sh/kernel/cpu/irq/intc2.c b/trunk/arch/sh/kernel/cpu/irq/intc2.c index 30064bf6e154..06e8afab32e4 100644 --- a/trunk/arch/sh/kernel/cpu/irq/intc2.c +++ b/trunk/arch/sh/kernel/cpu/irq/intc2.c @@ -137,7 +137,7 @@ void make_intc2_irq(unsigned int irq, local_irq_restore(flags); - irq_desc[irq].chip = &intc2_irq_type; + irq_desc[irq].handler = &intc2_irq_type; disable_intc2_irq(irq); } diff --git a/trunk/arch/sh/kernel/cpu/irq/ipr.c b/trunk/arch/sh/kernel/cpu/irq/ipr.c index 0373b65c77f9..e55150ed0856 100644 --- a/trunk/arch/sh/kernel/cpu/irq/ipr.c +++ b/trunk/arch/sh/kernel/cpu/irq/ipr.c @@ -115,7 +115,7 @@ void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */ ipr_data[irq].priority = priority; - irq_desc[irq].chip = &ipr_irq_type; + irq_desc[irq].handler = &ipr_irq_type; disable_ipr_irq(irq); } diff --git a/trunk/arch/sh/kernel/cpu/irq/pint.c b/trunk/arch/sh/kernel/cpu/irq/pint.c index 714963a25bba..95d6024fe1ae 100644 --- a/trunk/arch/sh/kernel/cpu/irq/pint.c +++ b/trunk/arch/sh/kernel/cpu/irq/pint.c @@ -85,7 +85,7 @@ static void end_pint_irq(unsigned int irq) void make_pint_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = &pint_irq_type; + irq_desc[irq].handler = &pint_irq_type; disable_pint_irq(irq); } diff --git a/trunk/arch/sh/kernel/irq.c b/trunk/arch/sh/kernel/irq.c index c2e07f7f3496..b56e79632f24 100644 --- a/trunk/arch/sh/kernel/irq.c +++ b/trunk/arch/sh/kernel/irq.c @@ -47,7 +47,7 @@ int show_interrupts(struct seq_file *p, void *v) goto unlock; seq_printf(p, "%3d: ",i); seq_printf(p, "%10u ", kstat_irqs(i)); - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index 9af22116c9a2..bb229ef030f3 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -402,7 +402,7 @@ static int __init topology_init(void) int cpu_id; for_each_possible_cpu(cpu_id) - register_cpu(&cpu[cpu_id], cpu_id); + register_cpu(&cpu[cpu_id], cpu_id, NULL); return 0; } diff --git a/trunk/arch/sh64/kernel/irq.c b/trunk/arch/sh64/kernel/irq.c index 675776a5477e..d69879c0e063 100644 --- a/trunk/arch/sh64/kernel/irq.c +++ b/trunk/arch/sh64/kernel/irq.c @@ -65,7 +65,7 @@ int show_interrupts(struct seq_file *p, void *v) goto unlock; seq_printf(p, "%3d: ",i); seq_printf(p, "%10u ", kstat_irqs(i)); - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/trunk/arch/sh64/kernel/irq_intc.c b/trunk/arch/sh64/kernel/irq_intc.c index fa730f5fe2e6..fc99bf4e362c 100644 --- a/trunk/arch/sh64/kernel/irq_intc.c +++ b/trunk/arch/sh64/kernel/irq_intc.c @@ -178,7 +178,7 @@ static void end_intc_irq(unsigned int irq) void make_intc_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].chip = &intc_irq_type; + irq_desc[irq].handler = &intc_irq_type; disable_intc_irq(irq); } @@ -208,7 +208,7 @@ void __init init_IRQ(void) /* Set default: per-line enable/disable, priority driven ack/eoi */ for (i = 0; i < NR_INTC_IRQS; i++) { if (platform_int_priority[i] != NO_PRIORITY) { - irq_desc[i].chip = &intc_irq_type; + irq_desc[i].handler = &intc_irq_type; } } diff --git a/trunk/arch/sh64/kernel/setup.c b/trunk/arch/sh64/kernel/setup.c index da98d8dbcf95..d2711c9c9d13 100644 --- a/trunk/arch/sh64/kernel/setup.c +++ b/trunk/arch/sh64/kernel/setup.c @@ -309,7 +309,7 @@ static struct cpu cpu[1]; static int __init topology_init(void) { - return register_cpu(cpu, 0); + return register_cpu(cpu, 0, NULL); } subsys_initcall(topology_init); diff --git a/trunk/arch/sh64/mach-cayman/irq.c b/trunk/arch/sh64/mach-cayman/irq.c index 05eb7cdc26f0..f797c84bfdd1 100644 --- a/trunk/arch/sh64/mach-cayman/irq.c +++ b/trunk/arch/sh64/mach-cayman/irq.c @@ -187,7 +187,7 @@ void init_cayman_irq(void) } for (i=0; itypename); + seq_printf(p, " %9s", irq_desc[i].handler->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -224,7 +224,7 @@ static inline struct ino_bucket *virt_irq_to_bucket(unsigned int virt_irq) #ifdef CONFIG_SMP static int irq_choose_cpu(unsigned int virt_irq) { - cpumask_t mask = irq_desc[virt_irq].affinity; + cpumask_t mask = irq_affinity[virt_irq]; int cpuid; if (cpus_equal(mask, CPU_MASK_ALL)) { @@ -414,8 +414,8 @@ void irq_install_pre_handler(int virt_irq, data->pre_handler_arg1 = arg1; data->pre_handler_arg2 = arg2; - desc->chip = (desc->chip == &sun4u_irq ? - &sun4u_irq_ack : &sun4v_irq_ack); + desc->handler = (desc->handler == &sun4u_irq ? + &sun4u_irq_ack : &sun4v_irq_ack); } unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) @@ -431,7 +431,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) bucket = &ivector_table[ino]; if (!bucket->virt_irq) { bucket->virt_irq = virt_irq_alloc(__irq(bucket)); - irq_desc[bucket->virt_irq].chip = &sun4u_irq; + irq_desc[bucket->virt_irq].handler = &sun4u_irq; } desc = irq_desc + bucket->virt_irq; @@ -465,7 +465,7 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) bucket = &ivector_table[sysino]; if (!bucket->virt_irq) { bucket->virt_irq = virt_irq_alloc(__irq(bucket)); - irq_desc[bucket->virt_irq].chip = &sun4v_irq; + irq_desc[bucket->virt_irq].handler = &sun4v_irq; } desc = irq_desc + bucket->virt_irq; diff --git a/trunk/arch/sparc64/kernel/setup.c b/trunk/arch/sparc64/kernel/setup.c index 116d9632002d..a6a7d8168346 100644 --- a/trunk/arch/sparc64/kernel/setup.c +++ b/trunk/arch/sparc64/kernel/setup.c @@ -537,7 +537,7 @@ static int __init topology_init(void) for_each_possible_cpu(i) { struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); if (p) { - register_cpu(p, i); + register_cpu(p, i, NULL); err = 0; } } diff --git a/trunk/arch/sparc64/mm/init.c b/trunk/arch/sparc64/mm/init.c index cb75a27adb51..5c2bcf354ce6 100644 --- a/trunk/arch/sparc64/mm/init.c +++ b/trunk/arch/sparc64/mm/init.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -1521,7 +1520,7 @@ void free_initmem(void) page = (addr + ((unsigned long) __va(kern_base)) - ((unsigned long) KERNBASE)); - memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); + memset((void *)addr, 0xcc, PAGE_SIZE); p = virt_to_page(page); ClearPageReserved(p); diff --git a/trunk/arch/um/kernel/irq.c b/trunk/arch/um/kernel/irq.c index fae43a3054a0..2ffda012385e 100644 --- a/trunk/arch/um/kernel/irq.c +++ b/trunk/arch/um/kernel/irq.c @@ -63,7 +63,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -451,13 +451,13 @@ void __init init_IRQ(void) irq_desc[TIMER_IRQ].status = IRQ_DISABLED; irq_desc[TIMER_IRQ].action = NULL; irq_desc[TIMER_IRQ].depth = 1; - irq_desc[TIMER_IRQ].chip = &SIGVTALRM_irq_type; + irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type; enable_irq(TIMER_IRQ); for (i = 1; i < NR_IRQS; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].chip = &normal_irq_type; + irq_desc[i].handler = &normal_irq_type; enable_irq(i); } } diff --git a/trunk/arch/v850/kernel/irq.c b/trunk/arch/v850/kernel/irq.c index 858c45819aab..7a151c26f82e 100644 --- a/trunk/arch/v850/kernel/irq.c +++ b/trunk/arch/v850/kernel/irq.c @@ -65,10 +65,10 @@ int show_interrupts(struct seq_file *p, void *v) int j; int count = 0; int num = -1; - const char *type_name = irq_desc[irq].chip->typename; + const char *type_name = irq_desc[irq].handler->typename; for (j = 0; j < NR_IRQS; j++) - if (irq_desc[j].chip->typename == type_name){ + if (irq_desc[j].handler->typename == type_name){ if (irq == j) num = count; count++; @@ -117,7 +117,7 @@ init_irq_handlers (int base_irq, int num, int interval, irq_desc[base_irq].status = IRQ_DISABLED; irq_desc[base_irq].action = NULL; irq_desc[base_irq].depth = 1; - irq_desc[base_irq].chip = irq_type; + irq_desc[base_irq].handler = irq_type; base_irq += interval; } } diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig index 91039844820c..ccc4a7fb97a3 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -370,8 +370,6 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. -config ARCH_ENABLE_MEMORY_HOTPLUG - def_bool y config HPET_TIMER bool diff --git a/trunk/arch/x86_64/kernel/entry.S b/trunk/arch/x86_64/kernel/entry.S index 22cac4487b57..7290e72b9a34 100644 --- a/trunk/arch/x86_64/kernel/entry.S +++ b/trunk/arch/x86_64/kernel/entry.S @@ -588,7 +588,7 @@ END(common_interrupt) */ .macro apicinterrupt num,func INTR_FRAME - pushq $~(\num) + pushq $\num-256 CFI_ADJUST_CFA_OFFSET 8 interrupt \func jmp ret_from_intr diff --git a/trunk/arch/x86_64/kernel/i8259.c b/trunk/arch/x86_64/kernel/i8259.c index 3dd1659427dc..86b2c1e197aa 100644 --- a/trunk/arch/x86_64/kernel/i8259.c +++ b/trunk/arch/x86_64/kernel/i8259.c @@ -235,7 +235,7 @@ void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<typename); + seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -115,14 +115,8 @@ int show_interrupts(struct seq_file *p, void *v) */ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) { - /* high bit used in ret_from_ code */ - unsigned irq = ~regs->orig_rax; - - if (unlikely(irq >= NR_IRQS)) { - printk(KERN_EMERG "%s: cannot handle IRQ %d\n", - __FUNCTION__, irq); - BUG(); - } + /* high bits used in ret_from_ code */ + unsigned irq = regs->orig_rax & 0xff; exit_idle(); irq_enter(); @@ -146,13 +140,13 @@ void fixup_irqs(cpumask_t map) if (irq == 2) continue; - cpus_and(mask, irq_desc[irq].affinity, map); + cpus_and(mask, irq_affinity[irq], map); if (any_online_cpu(mask) == NR_CPUS) { printk("Breaking affinity for irq %i\n", irq); mask = map; } - if (irq_desc[irq].chip->set_affinity) - irq_desc[irq].chip->set_affinity(irq, mask); + if (irq_desc[irq].handler->set_affinity) + irq_desc[irq].handler->set_affinity(irq, mask); else if (irq_desc[irq].action && !(warned++)) printk("Cannot set affinity for irq %i\n", irq); } diff --git a/trunk/arch/x86_64/kernel/mce.c b/trunk/arch/x86_64/kernel/mce.c index 88845674c661..acd5816b1a6f 100644 --- a/trunk/arch/x86_64/kernel/mce.c +++ b/trunk/arch/x86_64/kernel/mce.c @@ -629,7 +629,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu) #endif /* Get notified when a cpu comes on/off. Be hotplug friendly. */ -static __cpuinit int +static int mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -647,7 +647,7 @@ mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) return NOTIFY_OK; } -static struct notifier_block __cpuinitdata mce_cpu_notifier = { +static struct notifier_block mce_cpu_notifier = { .notifier_call = mce_cpu_callback, }; diff --git a/trunk/arch/x86_64/kernel/nmi.c b/trunk/arch/x86_64/kernel/nmi.c index 0ef9cf2bc45e..399489c93132 100644 --- a/trunk/arch/x86_64/kernel/nmi.c +++ b/trunk/arch/x86_64/kernel/nmi.c @@ -607,13 +607,11 @@ void set_nmi_callback(nmi_callback_t callback) vmalloc_sync_all(); rcu_assign_pointer(nmi_callback, callback); } -EXPORT_SYMBOL_GPL(set_nmi_callback); void unset_nmi_callback(void) { nmi_callback = dummy_nmi_callback; } -EXPORT_SYMBOL_GPL(unset_nmi_callback); #ifdef CONFIG_SYSCTL diff --git a/trunk/arch/x86_64/kernel/smp.c b/trunk/arch/x86_64/kernel/smp.c index 5a1c0a3bf872..acee4bc3f6fa 100644 --- a/trunk/arch/x86_64/kernel/smp.c +++ b/trunk/arch/x86_64/kernel/smp.c @@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs) cpu = smp_processor_id(); /* - * orig_rax contains the negated interrupt vector. + * orig_rax contains the interrupt vector - 256. * Use that to determine where the sender put the data. */ - sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START; + sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START; f = &per_cpu(flush_state, sender); if (!cpu_isset(cpu, f->flush_cpumask)) diff --git a/trunk/arch/x86_64/kernel/smpboot.c b/trunk/arch/x86_64/kernel/smpboot.c index 540c0ccbcccc..4e9755179ecf 100644 --- a/trunk/arch/x86_64/kernel/smpboot.c +++ b/trunk/arch/x86_64/kernel/smpboot.c @@ -455,12 +455,10 @@ cpumask_t cpu_coregroup_map(int cpu) struct cpuinfo_x86 *c = cpu_data + cpu; /* * For perf, we return last level cache shared map. - * And for power savings, we return cpu_core_map + * TBD: when power saving sched policy is added, we will return + * cpu_core_map when power saving policy is enabled */ - if (sched_mc_power_savings || sched_smt_power_savings) - return cpu_core_map[cpu]; - else - return c->llc_shared_map; + return c->llc_shared_map; } /* representing cpus for which sibling maps can be computed */ diff --git a/trunk/arch/x86_64/mm/init.c b/trunk/arch/x86_64/mm/init.c index 95bd232ff0cf..02add1d1dfa8 100644 --- a/trunk/arch/x86_64/mm/init.c +++ b/trunk/arch/x86_64/mm/init.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -507,6 +506,8 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size) /* * Memory hotplug specific functions */ +#if defined(CONFIG_ACPI_HOTPLUG_MEMORY) || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) + void online_page(struct page *page) { ClearPageReserved(page); @@ -516,17 +517,31 @@ void online_page(struct page *page) num_physpages++; } -#ifdef CONFIG_MEMORY_HOTPLUG +#ifndef CONFIG_MEMORY_HOTPLUG /* - * XXX: memory_add_physaddr_to_nid() is to find node id from physical address - * via probe interface of sysfs. If acpi notifies hot-add event, then it - * can tell node id by searching dsdt. But, probe interface doesn't have - * node id. So, return 0 as node id at this time. + * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, + * just online the pages. */ -#ifdef CONFIG_NUMA -int memory_add_physaddr_to_nid(u64 start) +int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) { - return 0; + int err = -EIO; + unsigned long pfn; + unsigned long total = 0, mem = 0; + for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { + if (pfn_valid(pfn)) { + online_page(pfn_to_page(pfn)); + err = 0; + mem++; + } + total++; + } + if (!err) { + z->spanned_pages += total; + z->present_pages += mem; + z->zone_pgdat->node_spanned_pages += total; + z->zone_pgdat->node_present_pages += mem; + } + return err; } #endif @@ -534,9 +549,9 @@ int memory_add_physaddr_to_nid(u64 start) * Memory is added always to NORMAL zone. This means you will never get * additional DMA/DMA32 memory. */ -int arch_add_memory(int nid, u64 start, u64 size) +int add_memory(u64 start, u64 size) { - struct pglist_data *pgdat = NODE_DATA(nid); + struct pglist_data *pgdat = NODE_DATA(0); struct zone *zone = pgdat->node_zones + MAX_NR_ZONES-2; unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; @@ -553,7 +568,7 @@ int arch_add_memory(int nid, u64 start, u64 size) printk("%s: Problem encountered in __add_pages!\n", __func__); return ret; } -EXPORT_SYMBOL_GPL(arch_add_memory); +EXPORT_SYMBOL_GPL(add_memory); int remove_memory(u64 start, u64 size) { @@ -561,33 +576,7 @@ int remove_memory(u64 start, u64 size) } EXPORT_SYMBOL_GPL(remove_memory); -#else /* CONFIG_MEMORY_HOTPLUG */ -/* - * Memory Hotadd without sparsemem. The mem_maps have been allocated in advance, - * just online the pages. - */ -int __add_pages(struct zone *z, unsigned long start_pfn, unsigned long nr_pages) -{ - int err = -EIO; - unsigned long pfn; - unsigned long total = 0, mem = 0; - for (pfn = start_pfn; pfn < start_pfn + nr_pages; pfn++) { - if (pfn_valid(pfn)) { - online_page(pfn_to_page(pfn)); - err = 0; - mem++; - } - total++; - } - if (!err) { - z->spanned_pages += total; - z->present_pages += mem; - z->zone_pgdat->node_spanned_pages += total; - z->zone_pgdat->node_present_pages += mem; - } - return err; -} -#endif /* CONFIG_MEMORY_HOTPLUG */ +#endif static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, kcore_vsyscall; @@ -661,8 +650,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) for (addr = begin; addr < end; addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); init_page_count(virt_to_page(addr)); - memset((void *)(addr & ~(PAGE_SIZE-1)), - POISON_FREE_INITMEM, PAGE_SIZE); + memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE); free_page(addr); totalram_pages++; } @@ -670,8 +658,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) void free_initmem(void) { - memset(__initdata_begin, POISON_FREE_INITDATA, - __initdata_end - __initdata_begin); + memset(__initdata_begin, 0xba, __initdata_end - __initdata_begin); free_init_pages("unused kernel memory", (unsigned long)(&__init_begin), (unsigned long)(&__init_end)); diff --git a/trunk/arch/xtensa/kernel/irq.c b/trunk/arch/xtensa/kernel/irq.c index 1cf744ee0959..51f9bed455fa 100644 --- a/trunk/arch/xtensa/kernel/irq.c +++ b/trunk/arch/xtensa/kernel/irq.c @@ -100,7 +100,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].chip->typename); + seq_printf(p, " %14s", irq_desc[i].handler->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -181,7 +181,7 @@ void __init init_IRQ(void) int i; for (i=0; i < XTENSA_NR_IRQS; i++) - irq_desc[i].chip = &xtensa_irq_type; + irq_desc[i].handler = &xtensa_irq_type; cached_irq_mask = 0; diff --git a/trunk/arch/xtensa/kernel/time.c b/trunk/arch/xtensa/kernel/time.c index fe14909f45e0..937d81f62f43 100644 --- a/trunk/arch/xtensa/kernel/time.c +++ b/trunk/arch/xtensa/kernel/time.c @@ -29,7 +29,7 @@ extern volatile unsigned long wall_jiffies; -DEFINE_SPINLOCK(rtc_lock); +spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; EXPORT_SYMBOL(rtc_lock); diff --git a/trunk/arch/xtensa/kernel/traps.c b/trunk/arch/xtensa/kernel/traps.c index 27e409089a7b..225d64d73f04 100644 --- a/trunk/arch/xtensa/kernel/traps.c +++ b/trunk/arch/xtensa/kernel/traps.c @@ -461,7 +461,7 @@ void show_code(unsigned int *pc) } } -DEFINE_SPINLOCK(die_lock); +spinlock_t die_lock = SPIN_LOCK_UNLOCKED; void die(const char * str, struct pt_regs * regs, long err) { diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index eee03a3876a3..c04422a502da 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -3403,7 +3403,7 @@ static int blk_cpu_notify(struct notifier_block *self, unsigned long action, } -static struct notifier_block __devinitdata blk_cpu_notifier = { +static struct notifier_block blk_cpu_notifier = { .notifier_call = blk_cpu_notify, }; @@ -3541,7 +3541,9 @@ int __init blk_dev_init(void) INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i)); open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL); - register_hotcpu_notifier(&blk_cpu_notifier); +#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/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index 610d2cc02cf8..94b8d820c512 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -328,7 +328,7 @@ config ACPI_CONTAINER config ACPI_HOTPLUG_MEMORY tristate "Memory Hotplug" depends on ACPI - depends on MEMORY_HOTPLUG + depends on MEMORY_HOTPLUG || X86_64 default n help This driver adds supports for ACPI Memory Hotplug. This driver diff --git a/trunk/drivers/acpi/acpi_memhotplug.c b/trunk/drivers/acpi/acpi_memhotplug.c index 1012284ff4f7..e0a95ba72371 100644 --- a/trunk/drivers/acpi/acpi_memhotplug.c +++ b/trunk/drivers/acpi/acpi_memhotplug.c @@ -57,7 +57,6 @@ MODULE_LICENSE("GPL"); static int acpi_memory_device_add(struct acpi_device *device); static int acpi_memory_device_remove(struct acpi_device *device, int type); -static int acpi_memory_device_start(struct acpi_device *device); static struct acpi_driver acpi_memory_device_driver = { .name = ACPI_MEMORY_DEVICE_DRIVER_NAME, @@ -66,79 +65,48 @@ static struct acpi_driver acpi_memory_device_driver = { .ops = { .add = acpi_memory_device_add, .remove = acpi_memory_device_remove, - .start = acpi_memory_device_start, }, }; -struct acpi_memory_info { - struct list_head list; - u64 start_addr; /* Memory Range start physical addr */ - u64 length; /* Memory Range length */ - unsigned short caching; /* memory cache attribute */ - unsigned short write_protect; /* memory read/write attribute */ - unsigned int enabled:1; -}; - struct acpi_memory_device { acpi_handle handle; unsigned int state; /* State of the memory device */ - struct list_head res_list; + unsigned short caching; /* memory cache attribute */ + unsigned short write_protect; /* memory read/write attribute */ + u64 start_addr; /* Memory Range start physical addr */ + u64 length; /* Memory Range length */ }; -static acpi_status -acpi_memory_get_resource(struct acpi_resource *resource, void *context) -{ - struct acpi_memory_device *mem_device = context; - struct acpi_resource_address64 address64; - struct acpi_memory_info *info, *new; - acpi_status status; - - status = acpi_resource_to_address64(resource, &address64); - if (ACPI_FAILURE(status) || - (address64.resource_type != ACPI_MEMORY_RANGE)) - return AE_OK; - - list_for_each_entry(info, &mem_device->res_list, list) { - /* Can we combine the resource range information? */ - if ((info->caching == address64.info.mem.caching) && - (info->write_protect == address64.info.mem.write_protect) && - (info->start_addr + info->length == address64.minimum)) { - info->length += address64.address_length; - return AE_OK; - } - } - - new = kzalloc(sizeof(struct acpi_memory_info), GFP_KERNEL); - if (!new) - return AE_ERROR; - - INIT_LIST_HEAD(&new->list); - new->caching = address64.info.mem.caching; - new->write_protect = address64.info.mem.write_protect; - new->start_addr = address64.minimum; - new->length = address64.address_length; - list_add_tail(&new->list, &mem_device->res_list); - - return AE_OK; -} - static int acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) { acpi_status status; - struct acpi_memory_info *info, *n; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_resource *resource = NULL; + struct acpi_resource_address64 address64; ACPI_FUNCTION_TRACE("acpi_memory_get_device_resources"); - status = acpi_walk_resources(mem_device->handle, METHOD_NAME__CRS, - acpi_memory_get_resource, mem_device); - if (ACPI_FAILURE(status)) { - list_for_each_entry_safe(info, n, &mem_device->res_list, list) - kfree(info); - return -EINVAL; + /* Get the range from the _CRS */ + status = acpi_get_current_resources(mem_device->handle, &buffer); + if (ACPI_FAILURE(status)) + return_VALUE(-EINVAL); + + resource = (struct acpi_resource *)buffer.pointer; + status = acpi_resource_to_address64(resource, &address64); + if (ACPI_SUCCESS(status)) { + if (address64.resource_type == ACPI_MEMORY_RANGE) { + /* Populate the structure */ + mem_device->caching = address64.info.mem.caching; + mem_device->write_protect = + address64.info.mem.write_protect; + mem_device->start_addr = address64.minimum; + mem_device->length = address64.address_length; + } } - return 0; + acpi_os_free(buffer.pointer); + return_VALUE(0); } static int @@ -213,9 +181,7 @@ static int acpi_memory_check_device(struct acpi_memory_device *mem_device) static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) { - int result, num_enabled = 0; - struct acpi_memory_info *info; - int node; + int result; ACPI_FUNCTION_TRACE("acpi_memory_enable_device"); @@ -228,35 +194,15 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) return result; } - node = acpi_get_node(mem_device->handle); /* * Tell the VM there is more memory here... * Note: Assume that this function returns zero on success - * We don't have memory-hot-add rollback function,now. - * (i.e. memory-hot-remove function) */ - list_for_each_entry(info, &mem_device->res_list, list) { - u64 start_pfn, end_pfn; - - start_pfn = info->start_addr >> PAGE_SHIFT; - end_pfn = (info->start_addr + info->length - 1) >> PAGE_SHIFT; - - if (pfn_valid(start_pfn) || pfn_valid(end_pfn)) { - /* already enabled. try next area */ - num_enabled++; - continue; - } - - result = add_memory(node, info->start_addr, info->length); - if (result) - continue; - info->enabled = 1; - num_enabled++; - } - if (!num_enabled) { + result = add_memory(mem_device->start_addr, mem_device->length); + if (result) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "\nadd_memory failed\n")); mem_device->state = MEMORY_INVALID_STATE; - return -EINVAL; + return result; } return result; @@ -300,7 +246,8 @@ static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device) static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) { int result; - struct acpi_memory_info *info, *n; + u64 start = mem_device->start_addr; + u64 len = mem_device->length; ACPI_FUNCTION_TRACE("acpi_memory_disable_device"); @@ -308,13 +255,10 @@ static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) * Ask the VM to offline this memory range. * Note: Assume that this function returns zero on success */ - list_for_each_entry_safe(info, n, &mem_device->res_list, list) { - if (info->enabled) { - result = remove_memory(info->start_addr, info->length); - if (result) - return result; - } - kfree(info); + result = remove_memory(start, len); + if (result) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Hot-Remove failed.\n")); + return_VALUE(result); } /* Power-off and eject the device */ @@ -412,7 +356,6 @@ static int acpi_memory_device_add(struct acpi_device *device) return_VALUE(-ENOMEM); memset(mem_device, 0, sizeof(struct acpi_memory_device)); - INIT_LIST_HEAD(&mem_device->res_list); mem_device->handle = device->handle; sprintf(acpi_device_name(device), "%s", ACPI_MEMORY_DEVICE_NAME); sprintf(acpi_device_class(device), "%s", ACPI_MEMORY_DEVICE_CLASS); @@ -448,25 +391,6 @@ static int acpi_memory_device_remove(struct acpi_device *device, int type) return_VALUE(0); } -static int acpi_memory_device_start (struct acpi_device *device) -{ - struct acpi_memory_device *mem_device; - int result = 0; - - ACPI_FUNCTION_TRACE("acpi_memory_device_start"); - - mem_device = acpi_driver_data(device); - - if (!acpi_memory_check_device(mem_device)) { - /* call add_memory func */ - result = acpi_memory_enable_device(mem_device); - if (result) - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error in acpi_memory_enable_device\n")); - } - return_VALUE(result); -} - /* * Helper function to check for memory device */ diff --git a/trunk/drivers/acpi/numa.c b/trunk/drivers/acpi/numa.c index 13d6d5bdea26..e2c1a16078c9 100644 --- a/trunk/drivers/acpi/numa.c +++ b/trunk/drivers/acpi/numa.c @@ -254,18 +254,5 @@ int acpi_get_pxm(acpi_handle h) } while (ACPI_SUCCESS(status)); return -1; } -EXPORT_SYMBOL(acpi_get_pxm); - -int acpi_get_node(acpi_handle *handle) -{ - int pxm, node = -1; - - ACPI_FUNCTION_TRACE("acpi_get_node"); - pxm = acpi_get_pxm(handle); - if (pxm >= 0) - node = acpi_map_pxm_to_node(pxm); - - return_VALUE(node); -} -EXPORT_SYMBOL(acpi_get_node); +EXPORT_SYMBOL(acpi_get_pxm); diff --git a/trunk/drivers/atm/firestream.c b/trunk/drivers/atm/firestream.c index 1bca86edf570..f2eeaf9dc56a 100644 --- a/trunk/drivers/atm/firestream.c +++ b/trunk/drivers/atm/firestream.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -755,7 +754,7 @@ static void process_txdone_queue (struct fs_dev *dev, struct queue *q) fs_kfree_skb (skb); fs_dprintk (FS_DEBUG_ALLOC, "Free trans-d: %p\n", td); - memset (td, ATM_POISON_FREE, sizeof(struct FS_BPENTRY)); + memset (td, 0x12, sizeof (struct FS_BPENTRY)); kfree (td); break; default: diff --git a/trunk/drivers/base/cpu.c b/trunk/drivers/base/cpu.c index 4bef76a2f3f2..dd712b24ec91 100644 --- a/trunk/drivers/base/cpu.c +++ b/trunk/drivers/base/cpu.c @@ -8,7 +8,6 @@ #include #include #include -#include #include "base.h" @@ -58,12 +57,13 @@ static void __devinit register_cpu_control(struct cpu *cpu) { sysdev_create_file(&cpu->sysdev, &attr_online); } -void unregister_cpu(struct cpu *cpu) +void unregister_cpu(struct cpu *cpu, struct node *root) { int logical_cpu = cpu->sysdev.id; - unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu)); - + if (root) + sysfs_remove_link(&root->sysdev.kobj, + kobject_name(&cpu->sysdev.kobj)); sysdev_remove_file(&cpu->sysdev, &attr_online); sysdev_unregister(&cpu->sysdev); @@ -109,21 +109,23 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL); * * Initialize and register the CPU device. */ -int __devinit register_cpu(struct cpu *cpu, int num) +int __devinit register_cpu(struct cpu *cpu, int num, struct node *root) { int error; + cpu->node_id = cpu_to_node(num); cpu->sysdev.id = num; cpu->sysdev.cls = &cpu_sysdev_class; error = sysdev_register(&cpu->sysdev); - + if (!error && root) + error = sysfs_create_link(&root->sysdev.kobj, + &cpu->sysdev.kobj, + kobject_name(&cpu->sysdev.kobj)); if (!error && !cpu->no_control) register_cpu_control(cpu); if (!error) cpu_sys_devices[num] = &cpu->sysdev; - if (!error) - register_cpu_under_node(num, cpu_to_node(num)); #ifdef CONFIG_KEXEC if (!error) @@ -143,13 +145,5 @@ EXPORT_SYMBOL_GPL(get_cpu_sysdev); int __init cpu_dev_init(void) { - int err; - - err = sysdev_class_register(&cpu_sysdev_class); -#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) - if (!err) - err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class); -#endif - - return err; + return sysdev_class_register(&cpu_sysdev_class); } diff --git a/trunk/drivers/base/dmapool.c b/trunk/drivers/base/dmapool.c index 33c5cce1560b..e2f64f91ed05 100644 --- a/trunk/drivers/base/dmapool.c +++ b/trunk/drivers/base/dmapool.c @@ -7,7 +7,6 @@ #include #include #include -#include /* * Pool allocator ... wraps the dma_alloc_coherent page allocator, so @@ -36,6 +35,8 @@ struct dma_page { /* cacheable header for 'allocation' bytes */ }; #define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000) +#define POOL_POISON_FREED 0xa7 /* !inuse */ +#define POOL_POISON_ALLOCATED 0xa9 /* !initted */ static DECLARE_MUTEX (pools_lock); diff --git a/trunk/drivers/base/memory.c b/trunk/drivers/base/memory.c index c6b7d9c4b651..dd547af4681a 100644 --- a/trunk/drivers/base/memory.c +++ b/trunk/drivers/base/memory.c @@ -306,13 +306,11 @@ static ssize_t memory_probe_store(struct class *class, const char *buf, size_t count) { u64 phys_addr; - int nid; int ret; phys_addr = simple_strtoull(buf, NULL, 0); - nid = memory_add_physaddr_to_nid(phys_addr); - ret = add_memory(nid, phys_addr, PAGES_PER_SECTION << PAGE_SHIFT); + ret = add_memory(phys_addr, PAGES_PER_SECTION << PAGE_SHIFT); if (ret) count = ret; diff --git a/trunk/drivers/base/node.c b/trunk/drivers/base/node.c index eae2bdc183bb..c80c3aeed004 100644 --- a/trunk/drivers/base/node.c +++ b/trunk/drivers/base/node.c @@ -11,7 +11,6 @@ #include #include #include -#include static struct sysdev_class node_class = { set_kset_name("node"), @@ -191,66 +190,6 @@ void unregister_node(struct node *node) sysdev_unregister(&node->sysdev); } -struct node node_devices[MAX_NUMNODES]; - -/* - * register cpu under node - */ -int register_cpu_under_node(unsigned int cpu, unsigned int nid) -{ - if (node_online(nid)) { - struct sys_device *obj = get_cpu_sysdev(cpu); - if (!obj) - return 0; - return sysfs_create_link(&node_devices[nid].sysdev.kobj, - &obj->kobj, - kobject_name(&obj->kobj)); - } - - return 0; -} - -int unregister_cpu_under_node(unsigned int cpu, unsigned int nid) -{ - if (node_online(nid)) { - struct sys_device *obj = get_cpu_sysdev(cpu); - if (obj) - sysfs_remove_link(&node_devices[nid].sysdev.kobj, - kobject_name(&obj->kobj)); - } - return 0; -} - -int register_one_node(int nid) -{ - int error = 0; - int cpu; - - if (node_online(nid)) { - int p_node = parent_node(nid); - struct node *parent = NULL; - - if (p_node != nid) - parent = &node_devices[p_node]; - - error = register_node(&node_devices[nid], nid, parent); - - /* link cpu under this node */ - for_each_present_cpu(cpu) { - if (cpu_to_node(cpu) == nid) - register_cpu_under_node(cpu, nid); - } - } - - return error; - -} - -void unregister_one_node(int nid) -{ - unregister_node(&node_devices[nid]); -} - static int __init register_node_type(void) { return sysdev_class_register(&node_class); diff --git a/trunk/drivers/base/topology.c b/trunk/drivers/base/topology.c index c2d621632383..8c52421cbc54 100644 --- a/trunk/drivers/base/topology.c +++ b/trunk/drivers/base/topology.c @@ -107,7 +107,7 @@ static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) return 0; } -static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, +static int topology_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; @@ -125,7 +125,7 @@ static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata topology_cpu_notifier = +static struct notifier_block topology_cpu_notifier = { .notifier_call = topology_cpu_callback, }; diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index 18dd026f470d..3c74ea729fc7 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -210,7 +210,7 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, { struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ struct address_space *mapping = file->f_mapping; - const struct address_space_operations *aops = mapping->a_ops; + struct address_space_operations *aops = mapping->a_ops; pgoff_t index; unsigned offset, bv_offs; int len, ret; @@ -784,7 +784,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, error = -EINVAL; if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) { - const struct address_space_operations *aops = mapping->a_ops; + struct address_space_operations *aops = mapping->a_ops; /* * If we can't read - sorry. If we only can't write - well, * it's going to be read-only. diff --git a/trunk/drivers/block/paride/pf.c b/trunk/drivers/block/paride/pf.c index 1a9dee19efcf..852b564e903a 100644 --- a/trunk/drivers/block/paride/pf.c +++ b/trunk/drivers/block/paride/pf.c @@ -707,7 +707,7 @@ static int pf_detect(void) if (pi_init(pf->pi, 0, conf[D_PRT], conf[D_MOD], conf[D_UNI], conf[D_PRO], conf[D_DLY], pf_scratch, PI_PF, verbose, pf->name)) { - if (pf->disk && !pf_probe(pf)) { + if (!pf_probe(pf) && pf->disk) { pf->present = 1; k++; } else diff --git a/trunk/drivers/block/rd.c b/trunk/drivers/block/rd.c index 0378da04cfa2..940bfd7951e5 100644 --- a/trunk/drivers/block/rd.c +++ b/trunk/drivers/block/rd.c @@ -191,7 +191,7 @@ static int ramdisk_set_page_dirty(struct page *page) return 0; } -static const struct address_space_operations ramdisk_aops = { +static struct address_space_operations ramdisk_aops = { .readpage = ramdisk_readpage, .prepare_write = ramdisk_prepare_write, .commit_write = ramdisk_commit_write, diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index c40e487d9f5c..3610c5729553 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -939,36 +939,12 @@ config MWAVE config SCx200_GPIO tristate "NatSemi SCx200 GPIO Support" depends on SCx200 - select NSC_GPIO help Give userspace access to the GPIO pins on the National Semiconductor SCx200 processors. If compiled as a module, it will be called scx200_gpio. -config PC8736x_GPIO - tristate "NatSemi PC8736x GPIO Support" - depends on X86 - default SCx200_GPIO # mostly N - select NSC_GPIO # needed for support routines - help - Give userspace access to the GPIO pins on the National - Semiconductor PC-8736x (x=[03456]) SuperIO chip. The chip - has multiple functional units, inc several managed by - hwmon/pc87360 driver. Tested with PC-87366 - - If compiled as a module, it will be called pc8736x_gpio. - -config NSC_GPIO - tristate "NatSemi Base GPIO Support" - depends on X86_32 - # selected by SCx200_GPIO and PC8736x_GPIO - # what about 2 selectors differing: m != y - help - Common support used (and needed) by scx200_gpio and - pc8736x_gpio drivers. If those drivers are built as - modules, this one will be too, named nsc_gpio - config CS5535_GPIO tristate "AMD CS5535/CS5536 GPIO (Geode Companion Device)" depends on X86_32 diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index 6e0f4469d8bb..524105597ea7 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -82,8 +82,6 @@ obj-$(CONFIG_PPDEV) += ppdev.o obj-$(CONFIG_NWBUTTON) += nwbutton.o obj-$(CONFIG_NWFLASH) += nwflash.o obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o -obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o -obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o obj-$(CONFIG_TANBAC_TB0219) += tb0219.o diff --git a/trunk/drivers/char/agp/sgi-agp.c b/trunk/drivers/char/agp/sgi-agp.c index d73be4c2db8a..cfa7922cb431 100644 --- a/trunk/drivers/char/agp/sgi-agp.c +++ b/trunk/drivers/char/agp/sgi-agp.c @@ -329,8 +329,9 @@ static int __devinit agp_sgi_init(void) static void __devexit agp_sgi_cleanup(void) { - kfree(sgi_tioca_agp_bridges); - sgi_tioca_agp_bridges = NULL; + if (sgi_tioca_agp_bridges) + kfree(sgi_tioca_agp_bridges); + sgi_tioca_agp_bridges=NULL; } module_init(agp_sgi_init); diff --git a/trunk/drivers/char/drm/drm_memory_debug.h b/trunk/drivers/char/drm/drm_memory_debug.h index d117cc997192..6543b9a14c42 100644 --- a/trunk/drivers/char/drm/drm_memory_debug.h +++ b/trunk/drivers/char/drm/drm_memory_debug.h @@ -43,7 +43,7 @@ typedef struct drm_mem_stats { unsigned long bytes_freed; } drm_mem_stats_t; -static DEFINE_SPINLOCK(drm_mem_lock); +static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED; static unsigned long drm_ram_available = 0; /* In pages */ static unsigned long drm_ram_used = 0; static drm_mem_stats_t drm_mem_stats[] = diff --git a/trunk/drivers/char/drm/via_dmablit.c b/trunk/drivers/char/drm/via_dmablit.c index 78a81a4a99c5..b7f17457b424 100644 --- a/trunk/drivers/char/drm/via_dmablit.c +++ b/trunk/drivers/char/drm/via_dmablit.c @@ -557,7 +557,7 @@ via_init_dmablit(drm_device_t *dev) blitq->num_outstanding = 0; blitq->is_active = 0; blitq->aborting = 0; - spin_lock_init(&blitq->blit_lock); + blitq->blit_lock = SPIN_LOCK_UNLOCKED; for (j=0; jblit_queue + j); } diff --git a/trunk/drivers/char/epca.c b/trunk/drivers/char/epca.c index dc0602ae8503..9cad8501d62c 100644 --- a/trunk/drivers/char/epca.c +++ b/trunk/drivers/char/epca.c @@ -80,7 +80,7 @@ static int invalid_lilo_config; /* The ISA boards do window flipping into the same spaces so its only sane with a single lock. It's still pretty efficient */ -static DEFINE_SPINLOCK(epca_lock); +static spinlock_t epca_lock = SPIN_LOCK_UNLOCKED; /* ----------------------------------------------------------------------- MAXBOARDS is typically 12, but ISA and EISA cards are restricted to diff --git a/trunk/drivers/char/hvcs.c b/trunk/drivers/char/hvcs.c index afa26b65dac3..8d97b3911293 100644 --- a/trunk/drivers/char/hvcs.c +++ b/trunk/drivers/char/hvcs.c @@ -1320,12 +1320,11 @@ static struct tty_operations hvcs_ops = { static int hvcs_alloc_index_list(int n) { int i; - hvcs_index_list = kmalloc(n * sizeof(hvcs_index_count),GFP_KERNEL); if (!hvcs_index_list) return -ENOMEM; hvcs_index_count = n; - for (i = 0; i < hvcs_index_count; i++) + for(i = 0; i < hvcs_index_count; i++) hvcs_index_list[i] = -1; return 0; } @@ -1333,9 +1332,11 @@ static int hvcs_alloc_index_list(int n) static void hvcs_free_index_list(void) { /* Paranoia check to be thorough. */ - kfree(hvcs_index_list); - hvcs_index_list = NULL; - hvcs_index_count = 0; + if (hvcs_index_list) { + kfree(hvcs_index_list); + hvcs_index_list = NULL; + hvcs_index_count = 0; + } } static int __init hvcs_module_init(void) diff --git a/trunk/drivers/char/ipmi/ipmi_msghandler.c b/trunk/drivers/char/ipmi/ipmi_msghandler.c index ad26f4b997c5..b03ddab1bef5 100644 --- a/trunk/drivers/char/ipmi/ipmi_msghandler.c +++ b/trunk/drivers/char/ipmi/ipmi_msghandler.c @@ -57,7 +57,8 @@ static int ipmi_init_msghandler(void); static int initialized = 0; #ifdef CONFIG_PROC_FS -static struct proc_dir_entry *proc_ipmi_root = NULL; +struct proc_dir_entry *proc_ipmi_root = NULL; +EXPORT_SYMBOL(proc_ipmi_root); #endif /* CONFIG_PROC_FS */ #define MAX_EVENTS_IN_QUEUE 25 @@ -3738,8 +3739,11 @@ static int ipmi_init_msghandler(void) proc_ipmi_root->owner = THIS_MODULE; #endif /* CONFIG_PROC_FS */ - setup_timer(&ipmi_timer, ipmi_timeout, 0); - mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES); + init_timer(&ipmi_timer); + ipmi_timer.data = 0; + ipmi_timer.function = ipmi_timeout; + ipmi_timer.expires = jiffies + IPMI_TIMEOUT_JIFFIES; + add_timer(&ipmi_timer); atomic_notifier_chain_register(&panic_notifier_list, &panic_block); diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index bd4f2248b758..02a7dd7a8a55 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -55,6 +55,23 @@ #include #include #include +#ifdef CONFIG_HIGH_RES_TIMERS +#include +# if defined(schedule_next_int) +/* Old high-res timer code, do translations. */ +# define get_arch_cycles(a) quick_update_jiffies_sub(a) +# define arch_cycles_per_jiffy cycles_per_jiffies +# endif +static inline void add_usec_to_timer(struct timer_list *t, long v) +{ + t->arch_cycle_expires += nsec_to_arch_cycle(v * 1000); + while (t->arch_cycle_expires >= arch_cycles_per_jiffy) + { + t->expires++; + t->arch_cycle_expires -= arch_cycles_per_jiffy; + } +} +#endif #include #include #include @@ -226,6 +243,8 @@ static int register_xaction_notifier(struct notifier_block * nb) return atomic_notifier_chain_register(&xaction_notifier_list, nb); } +static void si_restart_short_timer(struct smi_info *smi_info); + static void deliver_recv_msg(struct smi_info *smi_info, struct ipmi_smi_msg *msg) { @@ -749,6 +768,7 @@ static void sender(void *send_info, && (smi_info->curr_msg == NULL)) { start_next_msg(smi_info); + si_restart_short_timer(smi_info); } spin_unlock_irqrestore(&(smi_info->si_lock), flags); } @@ -789,7 +809,7 @@ static int ipmi_thread(void *data) /* do nothing */ } else if (smi_result == SI_SM_CALL_WITH_DELAY) - schedule(); + udelay(1); else schedule_timeout_interruptible(1); } @@ -813,6 +833,37 @@ static void request_events(void *send_info) static int initialized = 0; +/* Must be called with interrupts off and with the si_lock held. */ +static void si_restart_short_timer(struct smi_info *smi_info) +{ +#if defined(CONFIG_HIGH_RES_TIMERS) + unsigned long flags; + unsigned long jiffies_now; + unsigned long seq; + + if (del_timer(&(smi_info->si_timer))) { + /* If we don't delete the timer, then it will go off + immediately, anyway. So we only process if we + actually delete the timer. */ + + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + jiffies_now = jiffies; + smi_info->si_timer.expires = jiffies_now; + smi_info->si_timer.arch_cycle_expires + = get_arch_cycles(jiffies_now); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); + + add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); + + add_timer(&(smi_info->si_timer)); + spin_lock_irqsave(&smi_info->count_lock, flags); + smi_info->timeout_restarts++; + spin_unlock_irqrestore(&smi_info->count_lock, flags); + } +#endif +} + static void smi_timeout(unsigned long data) { struct smi_info *smi_info = (struct smi_info *) data; @@ -853,15 +904,31 @@ static void smi_timeout(unsigned long data) /* If the state machine asks for a short delay, then shorten the timer timeout. */ if (smi_result == SI_SM_CALL_WITH_DELAY) { +#if defined(CONFIG_HIGH_RES_TIMERS) + unsigned long seq; +#endif spin_lock_irqsave(&smi_info->count_lock, flags); smi_info->short_timeouts++; spin_unlock_irqrestore(&smi_info->count_lock, flags); +#if defined(CONFIG_HIGH_RES_TIMERS) + do { + seq = read_seqbegin_irqsave(&xtime_lock, flags); + smi_info->si_timer.expires = jiffies; + smi_info->si_timer.arch_cycle_expires + = get_arch_cycles(smi_info->si_timer.expires); + } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); + add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); +#else smi_info->si_timer.expires = jiffies + 1; +#endif } else { spin_lock_irqsave(&smi_info->count_lock, flags); smi_info->long_timeouts++; spin_unlock_irqrestore(&smi_info->count_lock, flags); smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; +#if defined(CONFIG_HIGH_RES_TIMERS) + smi_info->si_timer.arch_cycle_expires = 0; +#endif } do_add_timer: diff --git a/trunk/drivers/char/ipmi/ipmi_watchdog.c b/trunk/drivers/char/ipmi/ipmi_watchdog.c index 1a0a19c53605..8f8867170973 100644 --- a/trunk/drivers/char/ipmi/ipmi_watchdog.c +++ b/trunk/drivers/char/ipmi/ipmi_watchdog.c @@ -949,10 +949,9 @@ static int wdog_reboot_handler(struct notifier_block *this, /* Disable the WDT if we are shutting down. */ ipmi_watchdog_state = WDOG_TIMEOUT_NONE; panic_halt_ipmi_set_timeout(); - } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { + } else { /* Set a long timer to let the reboot happens, but - reboot if it hangs, but only if the watchdog - timer was already running. */ + reboot if it hangs. */ timeout = 120; pretimeout = 0; ipmi_watchdog_state = WDOG_TIMEOUT_RESET; @@ -974,17 +973,16 @@ static int wdog_panic_handler(struct notifier_block *this, { static int panic_event_handled = 0; - /* On a panic, if we have a panic timeout, make sure to extend - the watchdog timer to a reasonable value to complete the - panic, if the watchdog timer is running. Plus the - pretimeout is meaningless at panic time. */ - if (watchdog_user && !panic_event_handled && - ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { - /* Make sure we do this only once. */ + /* On a panic, if we have a panic timeout, make sure that the thing + reboots, even if it hangs during that panic. */ + if (watchdog_user && !panic_event_handled) { + /* Make sure the panic doesn't hang, and make sure we + do this only once. */ panic_event_handled = 1; timeout = 255; pretimeout = 0; + ipmi_watchdog_state = WDOG_TIMEOUT_RESET; panic_halt_ipmi_set_timeout(); } diff --git a/trunk/drivers/char/istallion.c b/trunk/drivers/char/istallion.c index 216c79256de3..ef20c1fc9c4c 100644 --- a/trunk/drivers/char/istallion.c +++ b/trunk/drivers/char/istallion.c @@ -42,12 +42,13 @@ #include #include #include -#include #include #include +#ifdef CONFIG_PCI #include +#endif /*****************************************************************************/ @@ -136,10 +137,6 @@ static stlconf_t stli_brdconf[] = { static int stli_nrbrds = ARRAY_SIZE(stli_brdconf); -/* stli_lock must NOT be taken holding brd_lock */ -static spinlock_t stli_lock; /* TTY logic lock */ -static spinlock_t brd_lock; /* Board logic lock */ - /* * There is some experimental EISA board detection code in this driver. * By default it is disabled, but for those that want to try it out, @@ -176,6 +173,14 @@ static char *stli_serialname = "ttyE"; static struct tty_driver *stli_serial; +/* + * We will need to allocate a temporary write buffer for chars that + * come direct from user space. The problem is that a copy from user + * space might cause a page fault (typically on a system that is + * swapping!). All ports will share one buffer - since if the system + * is already swapping a shared buffer won't make things any worse. + */ +static char *stli_tmpwritebuf; #define STLI_TXBUFSIZE 4096 @@ -414,7 +419,7 @@ static int stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs); #endif static struct pci_device_id istallion_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA), }, + { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0 } }; MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); @@ -677,7 +682,7 @@ static int stli_startbrd(stlibrd_t *brdp); static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp); static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp); static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); -static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp); +static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp); static void stli_poll(unsigned long arg); static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp); static int stli_initopen(stlibrd_t *brdp, stliport_t *portp); @@ -688,8 +693,7 @@ static void stli_dohangup(void *arg); static int stli_setport(stliport_t *portp); static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); -static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); -static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp); +static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp); static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp); static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); static long stli_mktiocm(unsigned long sigvalue); @@ -795,8 +799,18 @@ static struct class *istallion_class; static int __init istallion_module_init(void) { + unsigned long flags; + +#ifdef DEBUG + printk("init_module()\n"); +#endif + + save_flags(flags); + cli(); stli_init(); - return 0; + restore_flags(flags); + + return(0); } /*****************************************************************************/ @@ -805,24 +819,33 @@ static void __exit istallion_module_exit(void) { stlibrd_t *brdp; stliport_t *portp; + unsigned long flags; int i, j; +#ifdef DEBUG + printk("cleanup_module()\n"); +#endif + printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle, stli_drvversion); - /* - * Free up all allocated resources used by the ports. This includes - * memory and interrupts. - */ + save_flags(flags); + cli(); + +/* + * Free up all allocated resources used by the ports. This includes + * memory and interrupts. + */ if (stli_timeron) { stli_timeron = 0; - del_timer_sync(&stli_timerlist); + del_timer(&stli_timerlist); } i = tty_unregister_driver(stli_serial); if (i) { printk("STALLION: failed to un-register tty driver, " "errno=%d\n", -i); + restore_flags(flags); return; } put_tty_driver(stli_serial); @@ -836,15 +859,16 @@ static void __exit istallion_module_exit(void) printk("STALLION: failed to un-register serial memory device, " "errno=%d\n", -i); + kfree(stli_tmpwritebuf); kfree(stli_txcookbuf); for (i = 0; (i < stli_nrbrds); i++) { - if ((brdp = stli_brds[i]) == NULL) + if ((brdp = stli_brds[i]) == (stlibrd_t *) NULL) continue; for (j = 0; (j < STL_MAXPORTS); j++) { portp = brdp->ports[j]; - if (portp != NULL) { - if (portp->tty != NULL) + if (portp != (stliport_t *) NULL) { + if (portp->tty != (struct tty_struct *) NULL) tty_hangup(portp->tty); kfree(portp); } @@ -854,8 +878,10 @@ static void __exit istallion_module_exit(void) if (brdp->iosize > 0) release_region(brdp->iobase, brdp->iosize); kfree(brdp); - stli_brds[i] = NULL; + stli_brds[i] = (stlibrd_t *) NULL; } + + restore_flags(flags); } module_init(istallion_module_init); @@ -869,15 +895,19 @@ module_exit(istallion_module_exit); static void stli_argbrds(void) { - stlconf_t conf; - stlibrd_t *brdp; - int i; + stlconf_t conf; + stlibrd_t *brdp; + int i; + +#ifdef DEBUG + printk("stli_argbrds()\n"); +#endif for (i = stli_nrbrds; i < ARRAY_SIZE(stli_brdsp); i++) { memset(&conf, 0, sizeof(conf)); if (stli_parsebrd(&conf, stli_brdsp[i]) == 0) continue; - if ((brdp = stli_allocbrd()) == NULL) + if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL) continue; stli_nrbrds = i + 1; brdp->brdnr = i; @@ -896,9 +926,9 @@ static void stli_argbrds(void) static unsigned long stli_atol(char *str) { - unsigned long val; - int base, c; - char *sp; + unsigned long val; + int base, c; + char *sp; val = 0; sp = str; @@ -932,11 +962,15 @@ static unsigned long stli_atol(char *str) static int stli_parsebrd(stlconf_t *confp, char **argp) { - char *sp; - int i; + char *sp; + int i; - if (argp[0] == NULL || *argp[0] == 0) - return 0; +#ifdef DEBUG + printk("stli_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp); +#endif + + if ((argp[0] == (char *) NULL) || (*argp[0] == 0)) + return(0); for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) *sp = TOLOWER(*sp); @@ -951,9 +985,9 @@ static int stli_parsebrd(stlconf_t *confp, char **argp) } confp->brdtype = stli_brdstr[i].type; - if (argp[1] != NULL && *argp[1] != 0) + if ((argp[1] != (char *) NULL) && (*argp[1] != 0)) confp->ioaddr1 = stli_atol(argp[1]); - if (argp[2] != NULL && *argp[2] != 0) + if ((argp[2] != (char *) NULL) && (*argp[2] != 0)) confp->memaddr = stli_atol(argp[2]); return(1); } @@ -964,29 +998,34 @@ static int stli_parsebrd(stlconf_t *confp, char **argp) static int stli_open(struct tty_struct *tty, struct file *filp) { - stlibrd_t *brdp; - stliport_t *portp; - unsigned int minordev; - int brdnr, portnr, rc; + stlibrd_t *brdp; + stliport_t *portp; + unsigned int minordev; + int brdnr, portnr, rc; + +#ifdef DEBUG + printk("stli_open(tty=%x,filp=%x): device=%s\n", (int) tty, + (int) filp, tty->name); +#endif minordev = tty->index; brdnr = MINOR2BRD(minordev); if (brdnr >= stli_nrbrds) - return -ENODEV; + return(-ENODEV); brdp = stli_brds[brdnr]; - if (brdp == NULL) - return -ENODEV; + if (brdp == (stlibrd_t *) NULL) + return(-ENODEV); if ((brdp->state & BST_STARTED) == 0) - return -ENODEV; + return(-ENODEV); portnr = MINOR2PORT(minordev); if ((portnr < 0) || (portnr > brdp->nrports)) - return -ENODEV; + return(-ENODEV); portp = brdp->ports[portnr]; - if (portp == NULL) - return -ENODEV; + if (portp == (stliport_t *) NULL) + return(-ENODEV); if (portp->devnr < 1) - return -ENODEV; + return(-ENODEV); /* @@ -998,8 +1037,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp) if (portp->flags & ASYNC_CLOSING) { interruptible_sleep_on(&portp->close_wait); if (portp->flags & ASYNC_HUP_NOTIFY) - return -EAGAIN; - return -ERESTARTSYS; + return(-EAGAIN); + return(-ERESTARTSYS); } /* @@ -1015,7 +1054,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) wait_event_interruptible(portp->raw_wait, !test_bit(ST_INITIALIZING, &portp->state)); if (signal_pending(current)) - return -ERESTARTSYS; + return(-ERESTARTSYS); if ((portp->flags & ASYNC_INITIALIZED) == 0) { set_bit(ST_INITIALIZING, &portp->state); @@ -1026,7 +1065,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) clear_bit(ST_INITIALIZING, &portp->state); wake_up_interruptible(&portp->raw_wait); if (rc < 0) - return rc; + return(rc); } /* @@ -1038,8 +1077,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp) if (portp->flags & ASYNC_CLOSING) { interruptible_sleep_on(&portp->close_wait); if (portp->flags & ASYNC_HUP_NOTIFY) - return -EAGAIN; - return -ERESTARTSYS; + return(-EAGAIN); + return(-ERESTARTSYS); } /* @@ -1049,33 +1088,38 @@ static int stli_open(struct tty_struct *tty, struct file *filp) */ if (!(filp->f_flags & O_NONBLOCK)) { if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0) - return rc; + return(rc); } portp->flags |= ASYNC_NORMAL_ACTIVE; - return 0; + return(0); } /*****************************************************************************/ static void stli_close(struct tty_struct *tty, struct file *filp) { - stlibrd_t *brdp; - stliport_t *portp; - unsigned long flags; + stlibrd_t *brdp; + stliport_t *portp; + unsigned long flags; + +#ifdef DEBUG + printk("stli_close(tty=%x,filp=%x)\n", (int) tty, (int) filp); +#endif portp = tty->driver_data; - if (portp == NULL) + if (portp == (stliport_t *) NULL) return; - spin_lock_irqsave(&stli_lock, flags); + save_flags(flags); + cli(); if (tty_hung_up_p(filp)) { - spin_unlock_irqrestore(&stli_lock, flags); + restore_flags(flags); return; } if ((tty->count == 1) && (portp->refcount != 1)) portp->refcount = 1; if (portp->refcount-- > 1) { - spin_unlock_irqrestore(&stli_lock, flags); + restore_flags(flags); return; } @@ -1090,8 +1134,6 @@ static void stli_close(struct tty_struct *tty, struct file *filp) if (tty == stli_txcooktty) stli_flushchars(tty); tty->closing = 1; - spin_unlock_irqrestore(&stli_lock, flags); - if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) tty_wait_until_sent(tty, portp->closing_wait); @@ -1115,7 +1157,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp) stli_flushbuffer(tty); tty->closing = 0; - portp->tty = NULL; + portp->tty = (struct tty_struct *) NULL; if (portp->openwaitcnt) { if (portp->close_delay) @@ -1125,6 +1167,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp) portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); wake_up_interruptible(&portp->close_wait); + restore_flags(flags); } /*****************************************************************************/ @@ -1139,41 +1182,45 @@ static void stli_close(struct tty_struct *tty, struct file *filp) static int stli_initopen(stlibrd_t *brdp, stliport_t *portp) { - struct tty_struct *tty; - asynotify_t nt; - asyport_t aport; - int rc; + struct tty_struct *tty; + asynotify_t nt; + asyport_t aport; + int rc; + +#ifdef DEBUG + printk("stli_initopen(brdp=%x,portp=%x)\n", (int) brdp, (int) portp); +#endif if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0) - return rc; + return(rc); memset(&nt, 0, sizeof(asynotify_t)); nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK); nt.signal = SG_DCD; if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt, sizeof(asynotify_t), 0)) < 0) - return rc; + return(rc); tty = portp->tty; - if (tty == NULL) - return -ENODEV; + if (tty == (struct tty_struct *) NULL) + return(-ENODEV); stli_mkasyport(portp, &aport, tty->termios); if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)) < 0) - return rc; + return(rc); set_bit(ST_GETSIGS, &portp->state); if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, sizeof(asysigs_t), 1)) < 0) - return rc; + return(rc); if (test_and_clear_bit(ST_GETSIGS, &portp->state)) portp->sigs = stli_mktiocm(portp->asig.sigvalue); stli_mkasysigs(&portp->asig, 1, 1); if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0)) < 0) - return rc; + return(rc); - return 0; + return(0); } /*****************************************************************************/ @@ -1187,15 +1234,22 @@ static int stli_initopen(stlibrd_t *brdp, stliport_t *portp) static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait) { - cdkhdr_t __iomem *hdrp; - cdkctrl_t __iomem *cp; - unsigned char __iomem *bits; - unsigned long flags; - int rc; + volatile cdkhdr_t *hdrp; + volatile cdkctrl_t *cp; + volatile unsigned char *bits; + unsigned long flags; + int rc; + +#ifdef DEBUG + printk("stli_rawopen(brdp=%x,portp=%x,arg=%x,wait=%d)\n", + (int) brdp, (int) portp, (int) arg, wait); +#endif /* * Send a message to the slave to open this port. */ + save_flags(flags); + cli(); /* * Slave is already closing this port. This can happen if a hangup @@ -1206,6 +1260,7 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i wait_event_interruptible(portp->raw_wait, !test_bit(ST_CLOSING, &portp->state)); if (signal_pending(current)) { + restore_flags(flags); return -ERESTARTSYS; } @@ -1214,20 +1269,19 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i * memory. Once the message is in set the service bits to say that * this port wants service. */ - spin_lock_irqsave(&brd_lock, flags); EBRDENABLE(brdp); - cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; - writel(arg, &cp->openarg); - writeb(1, &cp->open); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + + cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; + cp->openarg = arg; + cp->open = 1; + hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx; - writeb(readb(bits) | portp->portbit, bits); + *bits |= portp->portbit; EBRDDISABLE(brdp); if (wait == 0) { - spin_unlock_irqrestore(&brd_lock, flags); - return 0; + restore_flags(flags); + return(0); } /* @@ -1236,16 +1290,15 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i */ rc = 0; set_bit(ST_OPENING, &portp->state); - spin_unlock_irqrestore(&brd_lock, flags); - wait_event_interruptible(portp->raw_wait, !test_bit(ST_OPENING, &portp->state)); if (signal_pending(current)) rc = -ERESTARTSYS; + restore_flags(flags); if ((rc == 0) && (portp->rc != 0)) rc = -EIO; - return rc; + return(rc); } /*****************************************************************************/ @@ -1258,11 +1311,19 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait) { - cdkhdr_t __iomem *hdrp; - cdkctrl_t __iomem *cp; - unsigned char __iomem *bits; - unsigned long flags; - int rc; + volatile cdkhdr_t *hdrp; + volatile cdkctrl_t *cp; + volatile unsigned char *bits; + unsigned long flags; + int rc; + +#ifdef DEBUG + printk("stli_rawclose(brdp=%x,portp=%x,arg=%x,wait=%d)\n", + (int) brdp, (int) portp, (int) arg, wait); +#endif + + save_flags(flags); + cli(); /* * Slave is already closing this port. This can happen if a hangup @@ -1272,6 +1333,7 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, wait_event_interruptible(portp->raw_wait, !test_bit(ST_CLOSING, &portp->state)); if (signal_pending(current)) { + restore_flags(flags); return -ERESTARTSYS; } } @@ -1279,22 +1341,21 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, /* * Write the close command into shared memory. */ - spin_lock_irqsave(&brd_lock, flags); EBRDENABLE(brdp); - cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; - writel(arg, &cp->closearg); - writeb(1, &cp->close); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + + cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; + cp->closearg = arg; + cp->close = 1; + hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx; - writeb(readb(bits) |portp->portbit, bits); + *bits |= portp->portbit; EBRDDISABLE(brdp); set_bit(ST_CLOSING, &portp->state); - spin_unlock_irqrestore(&brd_lock, flags); - - if (wait == 0) - return 0; + if (wait == 0) { + restore_flags(flags); + return(0); + } /* * Slave is in action, so now we must wait for the open acknowledgment @@ -1305,10 +1366,11 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, !test_bit(ST_CLOSING, &portp->state)); if (signal_pending(current)) rc = -ERESTARTSYS; + restore_flags(flags); if ((rc == 0) && (portp->rc != 0)) rc = -EIO; - return rc; + return(rc); } /*****************************************************************************/ @@ -1322,21 +1384,36 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) { + unsigned long flags; + +#ifdef DEBUG + printk("stli_cmdwait(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d," + "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd, + (int) arg, size, copyback); +#endif + + save_flags(flags); + cli(); wait_event_interruptible(portp->raw_wait, !test_bit(ST_CMDING, &portp->state)); - if (signal_pending(current)) + if (signal_pending(current)) { + restore_flags(flags); return -ERESTARTSYS; + } stli_sendcmd(brdp, portp, cmd, arg, size, copyback); wait_event_interruptible(portp->raw_wait, !test_bit(ST_CMDING, &portp->state)); - if (signal_pending(current)) + if (signal_pending(current)) { + restore_flags(flags); return -ERESTARTSYS; + } + restore_flags(flags); if (portp->rc != 0) - return -EIO; - return 0; + return(-EIO); + return(0); } /*****************************************************************************/ @@ -1348,18 +1425,22 @@ static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, v static int stli_setport(stliport_t *portp) { - stlibrd_t *brdp; - asyport_t aport; + stlibrd_t *brdp; + asyport_t aport; - if (portp == NULL) - return -ENODEV; - if (portp->tty == NULL) - return -ENODEV; - if (portp->brdnr < 0 && portp->brdnr >= stli_nrbrds) - return -ENODEV; +#ifdef DEBUG + printk("stli_setport(portp=%x)\n", (int) portp); +#endif + + if (portp == (stliport_t *) NULL) + return(-ENODEV); + if (portp->tty == (struct tty_struct *) NULL) + return(-ENODEV); + if ((portp->brdnr < 0) && (portp->brdnr >= stli_nrbrds)) + return(-ENODEV); brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return -ENODEV; + if (brdp == (stlibrd_t *) NULL) + return(-ENODEV); stli_mkasyport(portp, &aport, portp->tty->termios); return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); @@ -1374,8 +1455,13 @@ static int stli_setport(stliport_t *portp) static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp) { - unsigned long flags; - int rc, doclocal; + unsigned long flags; + int rc, doclocal; + +#ifdef DEBUG + printk("stli_waitcarrier(brdp=%x,portp=%x,filp=%x)\n", + (int) brdp, (int) portp, (int) filp); +#endif rc = 0; doclocal = 0; @@ -1383,11 +1469,11 @@ static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *fil if (portp->tty->termios->c_cflag & CLOCAL) doclocal++; - spin_lock_irqsave(&stli_lock, flags); + save_flags(flags); + cli(); portp->openwaitcnt++; if (! tty_hung_up_p(filp)) portp->refcount--; - spin_unlock_irqrestore(&stli_lock, flags); for (;;) { stli_mkasysigs(&portp->asig, 1, 1); @@ -1413,13 +1499,12 @@ static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *fil interruptible_sleep_on(&portp->open_wait); } - spin_lock_irqsave(&stli_lock, flags); if (! tty_hung_up_p(filp)) portp->refcount++; portp->openwaitcnt--; - spin_unlock_irqrestore(&stli_lock, flags); + restore_flags(flags); - return rc; + return(rc); } /*****************************************************************************/ @@ -1432,38 +1517,46 @@ static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *fil static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count) { - cdkasy_t __iomem *ap; - cdkhdr_t __iomem *hdrp; - unsigned char __iomem *bits; - unsigned char __iomem *shbuf; - unsigned char *chbuf; - stliport_t *portp; - stlibrd_t *brdp; - unsigned int len, stlen, head, tail, size; - unsigned long flags; + volatile cdkasy_t *ap; + volatile cdkhdr_t *hdrp; + volatile unsigned char *bits; + unsigned char *shbuf, *chbuf; + stliport_t *portp; + stlibrd_t *brdp; + unsigned int len, stlen, head, tail, size; + unsigned long flags; +#ifdef DEBUG + printk("stli_write(tty=%x,buf=%x,count=%d)\n", + (int) tty, (int) buf, count); +#endif + + if ((tty == (struct tty_struct *) NULL) || + (stli_tmpwritebuf == (char *) NULL)) + return(0); if (tty == stli_txcooktty) stli_flushchars(tty); portp = tty->driver_data; - if (portp == NULL) - return 0; + if (portp == (stliport_t *) NULL) + return(0); if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) - return 0; + return(0); brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; + if (brdp == (stlibrd_t *) NULL) + return(0); chbuf = (unsigned char *) buf; /* * All data is now local, shove as much as possible into shared memory. */ - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); EBRDENABLE(brdp); - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - head = (unsigned int) readw(&ap->txq.head); - tail = (unsigned int) readw(&ap->txq.tail); - if (tail != ((unsigned int) readw(&ap->txq.tail))) - tail = (unsigned int) readw(&ap->txq.tail); + ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); + head = (unsigned int) ap->txq.head; + tail = (unsigned int) ap->txq.tail; + if (tail != ((unsigned int) ap->txq.tail)) + tail = (unsigned int) ap->txq.tail; size = portp->txsize; if (head >= tail) { len = size - (head - tail) - 1; @@ -1475,11 +1568,11 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun len = MIN(len, count); count = 0; - shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->txoffset); + shbuf = (char *) EBRDGETMEMPTR(brdp, portp->txoffset); while (len > 0) { stlen = MIN(len, stlen); - memcpy_toio(shbuf + head, chbuf, stlen); + memcpy((shbuf + head), chbuf, stlen); chbuf += stlen; len -= stlen; count += stlen; @@ -1490,19 +1583,20 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun } } - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - writew(head, &ap->txq.head); + ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); + ap->txq.head = head; if (test_bit(ST_TXBUSY, &portp->state)) { - if (readl(&ap->changed.data) & DT_TXEMPTY) - writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data); + if (ap->changed.data & DT_TXEMPTY) + ap->changed.data &= ~DT_TXEMPTY; } - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + + hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx; - writeb(readb(bits) | portp->portbit, bits); + *bits |= portp->portbit; set_bit(ST_TXBUSY, &portp->state); EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); + + restore_flags(flags); return(count); } @@ -1519,8 +1613,14 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun static void stli_putchar(struct tty_struct *tty, unsigned char ch) { +#ifdef DEBUG + printk("stli_putchar(tty=%x,ch=%x)\n", (int) tty, (int) ch); +#endif + + if (tty == (struct tty_struct *) NULL) + return; if (tty != stli_txcooktty) { - if (stli_txcooktty != NULL) + if (stli_txcooktty != (struct tty_struct *) NULL) stli_flushchars(stli_txcooktty); stli_txcooktty = tty; } @@ -1540,26 +1640,29 @@ static void stli_putchar(struct tty_struct *tty, unsigned char ch) static void stli_flushchars(struct tty_struct *tty) { - cdkhdr_t __iomem *hdrp; - unsigned char __iomem *bits; - cdkasy_t __iomem *ap; - struct tty_struct *cooktty; - stliport_t *portp; - stlibrd_t *brdp; - unsigned int len, stlen, head, tail, size, count, cooksize; - unsigned char *buf; - unsigned char __iomem *shbuf; - unsigned long flags; + volatile cdkhdr_t *hdrp; + volatile unsigned char *bits; + volatile cdkasy_t *ap; + struct tty_struct *cooktty; + stliport_t *portp; + stlibrd_t *brdp; + unsigned int len, stlen, head, tail, size, count, cooksize; + unsigned char *buf, *shbuf; + unsigned long flags; + +#ifdef DEBUG + printk("stli_flushchars(tty=%x)\n", (int) tty); +#endif cooksize = stli_txcooksize; cooktty = stli_txcooktty; stli_txcooksize = 0; stli_txcookrealsize = 0; - stli_txcooktty = NULL; + stli_txcooktty = (struct tty_struct *) NULL; - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; - if (cooktty == NULL) + if (cooktty == (struct tty_struct *) NULL) return; if (tty != cooktty) tty = cooktty; @@ -1567,22 +1670,23 @@ static void stli_flushchars(struct tty_struct *tty) return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stliport_t *) NULL) return; if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) return; brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) + if (brdp == (stlibrd_t *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); EBRDENABLE(brdp); - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - head = (unsigned int) readw(&ap->txq.head); - tail = (unsigned int) readw(&ap->txq.tail); - if (tail != ((unsigned int) readw(&ap->txq.tail))) - tail = (unsigned int) readw(&ap->txq.tail); + ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); + head = (unsigned int) ap->txq.head; + tail = (unsigned int) ap->txq.tail; + if (tail != ((unsigned int) ap->txq.tail)) + tail = (unsigned int) ap->txq.tail; size = portp->txsize; if (head >= tail) { len = size - (head - tail) - 1; @@ -1599,7 +1703,7 @@ static void stli_flushchars(struct tty_struct *tty) while (len > 0) { stlen = MIN(len, stlen); - memcpy_toio(shbuf + head, buf, stlen); + memcpy((shbuf + head), buf, stlen); buf += stlen; len -= stlen; count += stlen; @@ -1610,66 +1714,73 @@ static void stli_flushchars(struct tty_struct *tty) } } - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - writew(head, &ap->txq.head); + ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); + ap->txq.head = head; if (test_bit(ST_TXBUSY, &portp->state)) { - if (readl(&ap->changed.data) & DT_TXEMPTY) - writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data); + if (ap->changed.data & DT_TXEMPTY) + ap->changed.data &= ~DT_TXEMPTY; } - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + + hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx; - writeb(readb(bits) | portp->portbit, bits); + *bits |= portp->portbit; set_bit(ST_TXBUSY, &portp->state); EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ static int stli_writeroom(struct tty_struct *tty) { - cdkasyrq_t __iomem *rp; - stliport_t *portp; - stlibrd_t *brdp; - unsigned int head, tail, len; - unsigned long flags; + volatile cdkasyrq_t *rp; + stliport_t *portp; + stlibrd_t *brdp; + unsigned int head, tail, len; + unsigned long flags; + +#ifdef DEBUG + printk("stli_writeroom(tty=%x)\n", (int) tty); +#endif + if (tty == (struct tty_struct *) NULL) + return(0); if (tty == stli_txcooktty) { if (stli_txcookrealsize != 0) { len = stli_txcookrealsize - stli_txcooksize; - return len; + return(len); } } portp = tty->driver_data; - if (portp == NULL) - return 0; + if (portp == (stliport_t *) NULL) + return(0); if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) - return 0; + return(0); brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; + if (brdp == (stlibrd_t *) NULL) + return(0); - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); EBRDENABLE(brdp); - rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq; - head = (unsigned int) readw(&rp->head); - tail = (unsigned int) readw(&rp->tail); - if (tail != ((unsigned int) readw(&rp->tail))) - tail = (unsigned int) readw(&rp->tail); + rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq; + head = (unsigned int) rp->head; + tail = (unsigned int) rp->tail; + if (tail != ((unsigned int) rp->tail)) + tail = (unsigned int) rp->tail; len = (head >= tail) ? (portp->txsize - (head - tail)) : (tail - head); len--; EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); if (tty == stli_txcooktty) { stli_txcookrealsize = len; len -= stli_txcooksize; } - return len; + return(len); } /*****************************************************************************/ @@ -1684,37 +1795,44 @@ static int stli_writeroom(struct tty_struct *tty) static int stli_charsinbuffer(struct tty_struct *tty) { - cdkasyrq_t __iomem *rp; - stliport_t *portp; - stlibrd_t *brdp; - unsigned int head, tail, len; - unsigned long flags; + volatile cdkasyrq_t *rp; + stliport_t *portp; + stlibrd_t *brdp; + unsigned int head, tail, len; + unsigned long flags; +#ifdef DEBUG + printk("stli_charsinbuffer(tty=%x)\n", (int) tty); +#endif + + if (tty == (struct tty_struct *) NULL) + return(0); if (tty == stli_txcooktty) stli_flushchars(tty); portp = tty->driver_data; - if (portp == NULL) - return 0; + if (portp == (stliport_t *) NULL) + return(0); if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) - return 0; + return(0); brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; + if (brdp == (stlibrd_t *) NULL) + return(0); - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); EBRDENABLE(brdp); - rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq; - head = (unsigned int) readw(&rp->head); - tail = (unsigned int) readw(&rp->tail); - if (tail != ((unsigned int) readw(&rp->tail))) - tail = (unsigned int) readw(&rp->tail); + rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq; + head = (unsigned int) rp->head; + tail = (unsigned int) rp->tail; + if (tail != ((unsigned int) rp->tail)) + tail = (unsigned int) rp->tail; len = (head >= tail) ? (head - tail) : (portp->txsize - (tail - head)); if ((len == 0) && test_bit(ST_TXBUSY, &portp->state)) len = 1; EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); - return len; + return(len); } /*****************************************************************************/ @@ -1725,8 +1843,12 @@ static int stli_charsinbuffer(struct tty_struct *tty) static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp) { - struct serial_struct sio; - stlibrd_t *brdp; + struct serial_struct sio; + stlibrd_t *brdp; + +#ifdef DEBUG + printk("stli_getserial(portp=%x,sp=%x)\n", (int) portp, (int) sp); +#endif memset(&sio, 0, sizeof(struct serial_struct)); sio.type = PORT_UNKNOWN; @@ -1741,7 +1863,7 @@ static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp) sio.hub6 = 0; brdp = stli_brds[portp->brdnr]; - if (brdp != NULL) + if (brdp != (stlibrd_t *) NULL) sio.port = brdp->iobase; return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? @@ -1758,8 +1880,12 @@ static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp) static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp) { - struct serial_struct sio; - int rc; + struct serial_struct sio; + int rc; + +#ifdef DEBUG + printk("stli_setserial(portp=%p,sp=%p)\n", portp, sp); +#endif if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) return -EFAULT; @@ -1768,7 +1894,7 @@ static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp) (sio.close_delay != portp->close_delay) || ((sio.flags & ~ASYNC_USR_MASK) != (portp->flags & ~ASYNC_USR_MASK))) - return -EPERM; + return(-EPERM); } portp->flags = (portp->flags & ~ASYNC_USR_MASK) | @@ -1779,8 +1905,8 @@ static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp) portp->custom_divisor = sio.custom_divisor; if ((rc = stli_setport(portp)) < 0) - return rc; - return 0; + return(rc); + return(0); } /*****************************************************************************/ @@ -1791,19 +1917,19 @@ static int stli_tiocmget(struct tty_struct *tty, struct file *file) stlibrd_t *brdp; int rc; - if (portp == NULL) - return -ENODEV; - if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) - return 0; + if (portp == (stliport_t *) NULL) + return(-ENODEV); + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) + return(0); brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; + if (brdp == (stlibrd_t *) NULL) + return(0); if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; + return(-EIO); if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, sizeof(asysigs_t), 1)) < 0) - return rc; + return(rc); return stli_mktiocm(portp->asig.sigvalue); } @@ -1815,15 +1941,15 @@ static int stli_tiocmset(struct tty_struct *tty, struct file *file, stlibrd_t *brdp; int rts = -1, dtr = -1; - if (portp == NULL) - return -ENODEV; - if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) - return 0; + if (portp == (stliport_t *) NULL) + return(-ENODEV); + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) + return(0); brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; + if (brdp == (stlibrd_t *) NULL) + return(0); if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; + return(-EIO); if (set & TIOCM_RTS) rts = 1; @@ -1842,25 +1968,32 @@ static int stli_tiocmset(struct tty_struct *tty, struct file *file, static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { - stliport_t *portp; - stlibrd_t *brdp; - unsigned int ival; - int rc; + stliport_t *portp; + stlibrd_t *brdp; + unsigned int ival; + int rc; void __user *argp = (void __user *)arg; +#ifdef DEBUG + printk("stli_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n", + (int) tty, (int) file, cmd, (int) arg); +#endif + + if (tty == (struct tty_struct *) NULL) + return(-ENODEV); portp = tty->driver_data; - if (portp == NULL) - return -ENODEV; - if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) - return 0; + if (portp == (stliport_t *) NULL) + return(-ENODEV); + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) + return(0); brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return 0; + if (brdp == (stlibrd_t *) NULL) + return(0); if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) { if (tty->flags & (1 << TTY_IO_ERROR)) - return -EIO; + return(-EIO); } rc = 0; @@ -1907,7 +2040,7 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm break; } - return rc; + return(rc); } /*****************************************************************************/ @@ -1919,20 +2052,24 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm static void stli_settermios(struct tty_struct *tty, struct termios *old) { - stliport_t *portp; - stlibrd_t *brdp; - struct termios *tiosp; - asyport_t aport; + stliport_t *portp; + stlibrd_t *brdp; + struct termios *tiosp; + asyport_t aport; - if (tty == NULL) +#ifdef DEBUG + printk("stli_settermios(tty=%x,old=%x)\n", (int) tty, (int) old); +#endif + + if (tty == (struct tty_struct *) NULL) return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stliport_t *) NULL) return; - if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) return; brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) + if (brdp == (stlibrd_t *) NULL) return; tiosp = tty->termios; @@ -1965,9 +2102,18 @@ static void stli_settermios(struct tty_struct *tty, struct termios *old) static void stli_throttle(struct tty_struct *tty) { - stliport_t *portp = tty->driver_data; - if (portp == NULL) + stliport_t *portp; + +#ifdef DEBUG + printk("stli_throttle(tty=%x)\n", (int) tty); +#endif + + if (tty == (struct tty_struct *) NULL) + return; + portp = tty->driver_data; + if (portp == (stliport_t *) NULL) return; + set_bit(ST_RXSTOP, &portp->state); } @@ -1981,30 +2127,88 @@ static void stli_throttle(struct tty_struct *tty) static void stli_unthrottle(struct tty_struct *tty) { - stliport_t *portp = tty->driver_data; - if (portp == NULL) + stliport_t *portp; + +#ifdef DEBUG + printk("stli_unthrottle(tty=%x)\n", (int) tty); +#endif + + if (tty == (struct tty_struct *) NULL) return; + portp = tty->driver_data; + if (portp == (stliport_t *) NULL) + return; + clear_bit(ST_RXSTOP, &portp->state); } /*****************************************************************************/ /* - * Stop the transmitter. + * Stop the transmitter. Basically to do this we will just turn TX + * interrupts off. */ static void stli_stop(struct tty_struct *tty) { + stlibrd_t *brdp; + stliport_t *portp; + asyctrl_t actrl; + +#ifdef DEBUG + printk("stli_stop(tty=%x)\n", (int) tty); +#endif + + if (tty == (struct tty_struct *) NULL) + return; + portp = tty->driver_data; + if (portp == (stliport_t *) NULL) + return; + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) + return; + brdp = stli_brds[portp->brdnr]; + if (brdp == (stlibrd_t *) NULL) + return; + + memset(&actrl, 0, sizeof(asyctrl_t)); + actrl.txctrl = CT_STOPFLOW; +#if 0 + stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); +#endif } /*****************************************************************************/ /* - * Start the transmitter again. + * Start the transmitter again. Just turn TX interrupts back on. */ static void stli_start(struct tty_struct *tty) { + stliport_t *portp; + stlibrd_t *brdp; + asyctrl_t actrl; + +#ifdef DEBUG + printk("stli_start(tty=%x)\n", (int) tty); +#endif + + if (tty == (struct tty_struct *) NULL) + return; + portp = tty->driver_data; + if (portp == (stliport_t *) NULL) + return; + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) + return; + brdp = stli_brds[portp->brdnr]; + if (brdp == (stlibrd_t *) NULL) + return; + + memset(&actrl, 0, sizeof(asyctrl_t)); + actrl.txctrl = CT_STARTFLOW; +#if 0 + stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); +#endif } /*****************************************************************************/ @@ -2020,9 +2224,22 @@ static void stli_start(struct tty_struct *tty) static void stli_dohangup(void *arg) { - stliport_t *portp = (stliport_t *) arg; - if (portp->tty != NULL) { - tty_hangup(portp->tty); + stliport_t *portp; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_dohangup(portp=%x)\n", (int) arg); +#endif + + /* + * FIXME: There's a module removal race here: tty_hangup + * calls schedule_work which will call into this + * driver later. + */ + portp = (stliport_t *) arg; + if (portp != (stliport_t *) NULL) { + if (portp->tty != (struct tty_struct *) NULL) { + tty_hangup(portp->tty); + } } } @@ -2037,25 +2254,31 @@ static void stli_dohangup(void *arg) static void stli_hangup(struct tty_struct *tty) { - stliport_t *portp; - stlibrd_t *brdp; - unsigned long flags; + stliport_t *portp; + stlibrd_t *brdp; + unsigned long flags; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_hangup(tty=%x)\n", (int) tty); +#endif + if (tty == (struct tty_struct *) NULL) + return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stliport_t *) NULL) return; - if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) return; brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) + if (brdp == (stlibrd_t *) NULL) return; portp->flags &= ~ASYNC_INITIALIZED; - if (!test_bit(ST_CLOSING, &portp->state)) + save_flags(flags); + cli(); + if (! test_bit(ST_CLOSING, &portp->state)) stli_rawclose(brdp, portp, 0, 0); - - spin_lock_irqsave(&stli_lock, flags); if (tty->termios->c_cflag & HUPCL) { stli_mkasysigs(&portp->asig, 0, 0); if (test_bit(ST_CMDING, &portp->state)) { @@ -2067,15 +2290,14 @@ static void stli_hangup(struct tty_struct *tty) &portp->asig, sizeof(asysigs_t), 0); } } + restore_flags(flags); clear_bit(ST_TXBUSY, &portp->state); clear_bit(ST_RXSTOP, &portp->state); set_bit(TTY_IO_ERROR, &tty->flags); - portp->tty = NULL; + portp->tty = (struct tty_struct *) NULL; portp->flags &= ~ASYNC_NORMAL_ACTIVE; portp->refcount = 0; - spin_unlock_irqrestore(&stli_lock, flags); - wake_up_interruptible(&portp->open_wait); } @@ -2090,22 +2312,29 @@ static void stli_hangup(struct tty_struct *tty) static void stli_flushbuffer(struct tty_struct *tty) { - stliport_t *portp; - stlibrd_t *brdp; - unsigned long ftype, flags; + stliport_t *portp; + stlibrd_t *brdp; + unsigned long ftype, flags; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_flushbuffer(tty=%x)\n", (int) tty); +#endif + if (tty == (struct tty_struct *) NULL) + return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stliport_t *) NULL) return; - if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) return; brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) + if (brdp == (stlibrd_t *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); if (tty == stli_txcooktty) { - stli_txcooktty = NULL; + stli_txcooktty = (struct tty_struct *) NULL; stli_txcooksize = 0; stli_txcookrealsize = 0; } @@ -2117,10 +2346,15 @@ static void stli_flushbuffer(struct tty_struct *tty) ftype |= FLUSHRX; clear_bit(ST_DOFLUSHRX, &portp->state); } - __stli_sendcmd(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0); + stli_sendcmd(brdp, portp, A_FLUSH, &ftype, + sizeof(unsigned long), 0); } - spin_unlock_irqrestore(&brd_lock, flags); - tty_wakeup(tty); + restore_flags(flags); + + wake_up_interruptible(&tty->write_wait); + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) + (tty->ldisc.write_wakeup)(tty); } /*****************************************************************************/ @@ -2130,31 +2364,55 @@ static void stli_breakctl(struct tty_struct *tty, int state) stlibrd_t *brdp; stliport_t *portp; long arg; + /* long savestate, savetime; */ +#ifdef DEBUG + printk(KERN_DEBUG "stli_breakctl(tty=%x,state=%d)\n", (int) tty, state); +#endif + + if (tty == (struct tty_struct *) NULL) + return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stliport_t *) NULL) return; - if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) return; brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) + if (brdp == (stlibrd_t *) NULL) return; +/* + * Due to a bug in the tty send_break() code we need to preserve + * the current process state and timeout... + savetime = current->timeout; + savestate = current->state; + */ + arg = (state == -1) ? BREAKON : BREAKOFF; stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0); + +/* + * + current->timeout = savetime; + current->state = savestate; + */ } /*****************************************************************************/ static void stli_waituntilsent(struct tty_struct *tty, int timeout) { - stliport_t *portp; - unsigned long tend; + stliport_t *portp; + unsigned long tend; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_waituntilsent(tty=%x,timeout=%x)\n", (int) tty, timeout); +#endif - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stliport_t *) NULL) return; if (timeout == 0) @@ -2178,13 +2436,19 @@ static void stli_sendxchar(struct tty_struct *tty, char ch) stliport_t *portp; asyctrl_t actrl; +#ifdef DEBUG + printk(KERN_DEBUG "stli_sendxchar(tty=%x,ch=%x)\n", (int) tty, ch); +#endif + + if (tty == (struct tty_struct *) NULL) + return; portp = tty->driver_data; - if (portp == NULL) + if (portp == (stliport_t *) NULL) return; - if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) + if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) return; brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) + if (brdp == (stlibrd_t *) NULL) return; memset(&actrl, 0, sizeof(asyctrl_t)); @@ -2196,6 +2460,7 @@ static void stli_sendxchar(struct tty_struct *tty, char ch) actrl.txctrl = CT_SENDCHR; actrl.tximdch = ch; } + stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); } @@ -2211,17 +2476,17 @@ static void stli_sendxchar(struct tty_struct *tty, char ch) static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos) { - char *sp, *uart; - int rc, cnt; + char *sp, *uart; + int rc, cnt; rc = stli_portcmdstats(portp); uart = "UNKNOWN"; if (brdp->state & BST_STARTED) { switch (stli_comstats.hwid) { - case 0: uart = "2681"; break; - case 1: uart = "SC26198"; break; - default:uart = "CD1400"; break; + case 0: uart = "2681"; break; + case 1: uart = "SC26198"; break; + default: uart = "CD1400"; break; } } @@ -2272,11 +2537,17 @@ static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *p static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) { - stlibrd_t *brdp; - stliport_t *portp; - int brdnr, portnr, totalport; - int curoff, maxoff; - char *pos; + stlibrd_t *brdp; + stliport_t *portp; + int brdnr, portnr, totalport; + int curoff, maxoff; + char *pos; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_readproc(page=%x,start=%x,off=%x,count=%d,eof=%x," + "data=%x\n", (int) page, (int) start, (int) off, count, + (int) eof, (int) data); +#endif pos = page; totalport = 0; @@ -2297,7 +2568,7 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo */ for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { brdp = stli_brds[brdnr]; - if (brdp == NULL) + if (brdp == (stlibrd_t *) NULL) continue; if (brdp->state == 0) continue; @@ -2312,7 +2583,7 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo for (portnr = 0; (portnr < brdp->nrports); portnr++, totalport++) { portp = brdp->ports[portnr]; - if (portp == NULL) + if (portp == (stliport_t *) NULL) continue; if (off >= (curoff += MAXLINE)) continue; @@ -2339,54 +2610,49 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo * a poll routine that does not have user context. Therefore you cannot * copy back directly into user space, or to the kernel stack of a * process. This routine does not sleep, so can be called from anywhere. - * - * The caller must hold the brd_lock (see also stli_sendcmd the usual - * entry point) */ -static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) +static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) { - cdkhdr_t __iomem *hdrp; - cdkctrl_t __iomem *cp; - unsigned char __iomem *bits; - unsigned long flags; + volatile cdkhdr_t *hdrp; + volatile cdkctrl_t *cp; + volatile unsigned char *bits; + unsigned long flags; - spin_lock_irqsave(&brd_lock, flags); +#ifdef DEBUG + printk(KERN_DEBUG "stli_sendcmd(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d," + "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd, + (int) arg, size, copyback); +#endif + + save_flags(flags); + cli(); if (test_bit(ST_CMDING, &portp->state)) { printk(KERN_ERR "STALLION: command already busy, cmd=%x!\n", (int) cmd); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); return; } EBRDENABLE(brdp); - cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; + cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; if (size > 0) { - memcpy_toio((void __iomem *) &(cp->args[0]), arg, size); + memcpy((void *) &(cp->args[0]), arg, size); if (copyback) { portp->argp = arg; portp->argsize = size; } } - writel(0, &cp->status); - writel(cmd, &cp->cmd); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + + cp->status = 0; + cp->cmd = cmd; + hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + portp->portidx; - writeb(readb(bits) | portp->portbit, bits); + *bits |= portp->portbit; set_bit(ST_CMDING, &portp->state); EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); -} - -static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) -{ - unsigned long flags; - - spin_lock_irqsave(&brd_lock, flags); - __stli_sendcmd(brdp, portp, cmd, arg, size, copyback); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -2401,23 +2667,28 @@ static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, static void stli_read(stlibrd_t *brdp, stliport_t *portp) { - cdkasyrq_t __iomem *rp; - char __iomem *shbuf; + volatile cdkasyrq_t *rp; + volatile char *shbuf; struct tty_struct *tty; - unsigned int head, tail, size; - unsigned int len, stlen; + unsigned int head, tail, size; + unsigned int len, stlen; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_read(brdp=%x,portp=%d)\n", + (int) brdp, (int) portp); +#endif if (test_bit(ST_RXSTOP, &portp->state)) return; tty = portp->tty; - if (tty == NULL) + if (tty == (struct tty_struct *) NULL) return; - rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; - head = (unsigned int) readw(&rp->head); - if (head != ((unsigned int) readw(&rp->head))) - head = (unsigned int) readw(&rp->head); - tail = (unsigned int) readw(&rp->tail); + rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; + head = (unsigned int) rp->head; + if (head != ((unsigned int) rp->head)) + head = (unsigned int) rp->head; + tail = (unsigned int) rp->tail; size = portp->rxsize; if (head >= tail) { len = head - tail; @@ -2428,15 +2699,12 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp) } len = tty_buffer_request_room(tty, len); - - shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->rxoffset); + /* FIXME : iomap ? */ + shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset); while (len > 0) { - unsigned char *cptr; - stlen = MIN(len, stlen); - tty_prepare_flip_string(tty, &cptr, stlen); - memcpy_fromio(cptr, shbuf + tail, stlen); + tty_insert_flip_string(tty, (char *)(shbuf + tail), stlen); len -= stlen; tail += stlen; if (tail >= size) { @@ -2444,8 +2712,8 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp) stlen = head; } } - rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; - writew(tail, &rp->tail); + rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; + rp->tail = tail; if (head != tail) set_bit(ST_RXING, &portp->state); @@ -2461,9 +2729,9 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp) * difficult to deal with them here. */ -static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp) +static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp) { - int cmd; + int cmd; if (test_bit(ST_DOSIGS, &portp->state)) { if (test_bit(ST_DOFLUSHTX, &portp->state) && @@ -2478,10 +2746,10 @@ static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp) clear_bit(ST_DOFLUSHTX, &portp->state); clear_bit(ST_DOFLUSHRX, &portp->state); clear_bit(ST_DOSIGS, &portp->state); - memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &portp->asig, + memcpy((void *) &(cp->args[0]), (void *) &portp->asig, sizeof(asysigs_t)); - writel(0, &cp->status); - writel(cmd, &cp->cmd); + cp->status = 0; + cp->cmd = cmd; set_bit(ST_CMDING, &portp->state); } else if (test_bit(ST_DOFLUSHTX, &portp->state) || test_bit(ST_DOFLUSHRX, &portp->state)) { @@ -2489,9 +2757,9 @@ static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp) cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0); clear_bit(ST_DOFLUSHTX, &portp->state); clear_bit(ST_DOFLUSHRX, &portp->state); - memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &cmd, sizeof(int)); - writel(0, &cp->status); - writel(A_FLUSH, &cp->cmd); + memcpy((void *) &(cp->args[0]), (void *) &cmd, sizeof(int)); + cp->status = 0; + cp->cmd = A_FLUSH; set_bit(ST_CMDING, &portp->state); } } @@ -2511,25 +2779,30 @@ static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp) static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) { - cdkasy_t __iomem *ap; - cdkctrl_t __iomem *cp; - struct tty_struct *tty; - asynotify_t nt; - unsigned long oldsigs; - int rc, donerx; - - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); + volatile cdkasy_t *ap; + volatile cdkctrl_t *cp; + struct tty_struct *tty; + asynotify_t nt; + unsigned long oldsigs; + int rc, donerx; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_hostcmd(brdp=%x,channr=%d)\n", + (int) brdp, channr); +#endif + + ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); cp = &ap->ctrl; /* * Check if we are waiting for an open completion message. */ if (test_bit(ST_OPENING, &portp->state)) { - rc = readl(&cp->openarg); - if (readb(&cp->open) == 0 && rc != 0) { + rc = (int) cp->openarg; + if ((cp->open == 0) && (rc != 0)) { if (rc > 0) rc--; - writel(0, &cp->openarg); + cp->openarg = 0; portp->rc = rc; clear_bit(ST_OPENING, &portp->state); wake_up_interruptible(&portp->raw_wait); @@ -2540,11 +2813,11 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) * Check if we are waiting for a close completion message. */ if (test_bit(ST_CLOSING, &portp->state)) { - rc = (int) readl(&cp->closearg); - if (readb(&cp->close) == 0 && rc != 0) { + rc = (int) cp->closearg; + if ((cp->close == 0) && (rc != 0)) { if (rc > 0) rc--; - writel(0, &cp->closearg); + cp->closearg = 0; portp->rc = rc; clear_bit(ST_CLOSING, &portp->state); wake_up_interruptible(&portp->raw_wait); @@ -2556,16 +2829,16 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) * need to copy out the command results associated with this command. */ if (test_bit(ST_CMDING, &portp->state)) { - rc = readl(&cp->status); - if (readl(&cp->cmd) == 0 && rc != 0) { + rc = cp->status; + if ((cp->cmd == 0) && (rc != 0)) { if (rc > 0) rc--; - if (portp->argp != NULL) { - memcpy_fromio(portp->argp, (void __iomem *) &(cp->args[0]), + if (portp->argp != (void *) NULL) { + memcpy(portp->argp, (void *) &(cp->args[0]), portp->argsize); - portp->argp = NULL; + portp->argp = (void *) NULL; } - writel(0, &cp->status); + cp->status = 0; portp->rc = rc; clear_bit(ST_CMDING, &portp->state); stli_dodelaycmd(portp, cp); @@ -2604,15 +2877,18 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) if (nt.data & DT_TXEMPTY) clear_bit(ST_TXBUSY, &portp->state); if (nt.data & (DT_TXEMPTY | DT_TXLOW)) { - if (tty != NULL) { - tty_wakeup(tty); - EBRDENABLE(brdp); + if (tty != (struct tty_struct *) NULL) { + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc.write_wakeup) { + (tty->ldisc.write_wakeup)(tty); + EBRDENABLE(brdp); + } wake_up_interruptible(&tty->write_wait); } } if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) { - if (tty != NULL) { + if (tty != (struct tty_struct *) NULL) { tty_insert_flip_char(tty, 0, TTY_BREAK); if (portp->flags & ASYNC_SAK) { do_SAK(tty); @@ -2656,14 +2932,14 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) * at the cdk header structure. */ -static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp) +static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp) { - stliport_t *portp; - unsigned char hostbits[(STL_MAXCHANS / 8) + 1]; - unsigned char slavebits[(STL_MAXCHANS / 8) + 1]; - unsigned char __iomem *slavep; - int bitpos, bitat, bitsize; - int channr, nrdevs, slavebitchange; + stliport_t *portp; + unsigned char hostbits[(STL_MAXCHANS / 8) + 1]; + unsigned char slavebits[(STL_MAXCHANS / 8) + 1]; + unsigned char *slavep; + int bitpos, bitat, bitsize; + int channr, nrdevs, slavebitchange; bitsize = brdp->bitsize; nrdevs = brdp->nrdevs; @@ -2675,7 +2951,7 @@ static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp) * 8 service bits at a time in the inner loop, so we can bypass * the lot if none of them want service. */ - memcpy_fromio(&hostbits[0], (((unsigned char __iomem *) hdrp) + brdp->hostoffset), + memcpy(&hostbits[0], (((unsigned char *) hdrp) + brdp->hostoffset), bitsize); memset(&slavebits[0], 0, bitsize); @@ -2702,11 +2978,11 @@ static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp) * service may initiate more slave requests. */ if (slavebitchange) { - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - slavep = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset; + hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + slavep = ((unsigned char *) hdrp) + brdp->slaveoffset; for (bitpos = 0; (bitpos < bitsize); bitpos++) { - if (readb(slavebits + bitpos)) - writeb(readb(slavep + bitpos) & ~slavebits[bitpos], slavebits + bitpos); + if (slavebits[bitpos]) + slavep[bitpos] &= ~slavebits[bitpos]; } } } @@ -2724,9 +3000,9 @@ static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp) static void stli_poll(unsigned long arg) { - cdkhdr_t __iomem *hdrp; - stlibrd_t *brdp; - int brdnr; + volatile cdkhdr_t *hdrp; + stlibrd_t *brdp; + int brdnr; stli_timerlist.expires = STLI_TIMEOUT; add_timer(&stli_timerlist); @@ -2736,18 +3012,16 @@ static void stli_poll(unsigned long arg) */ for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { brdp = stli_brds[brdnr]; - if (brdp == NULL) + if (brdp == (stlibrd_t *) NULL) continue; if ((brdp->state & BST_STARTED) == 0) continue; - spin_lock(&brd_lock); EBRDENABLE(brdp); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - if (readb(&hdrp->hostreq)) + hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + if (hdrp->hostreq) stli_brdpoll(brdp, hdrp); EBRDDISABLE(brdp); - spin_unlock(&brd_lock); } } @@ -2760,6 +3034,11 @@ static void stli_poll(unsigned long arg) static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp) { +#ifdef DEBUG + printk(KERN_DEBUG "stli_mkasyport(portp=%x,pp=%x,tiosp=%d)\n", + (int) portp, (int) pp, (int) tiosp); +#endif + memset(pp, 0, sizeof(asyport_t)); /* @@ -2878,6 +3157,11 @@ static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tio static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts) { +#ifdef DEBUG + printk(KERN_DEBUG "stli_mkasysigs(sp=%x,dtr=%d,rts=%d)\n", + (int) sp, dtr, rts); +#endif + memset(sp, 0, sizeof(asysigs_t)); if (dtr >= 0) { sp->signal |= SG_DTR; @@ -2898,7 +3182,13 @@ static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts) static long stli_mktiocm(unsigned long sigvalue) { - long tiocm = 0; + long tiocm; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_mktiocm(sigvalue=%x)\n", (int) sigvalue); +#endif + + tiocm = 0; tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0); tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0); tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0); @@ -2920,6 +3210,10 @@ static int stli_initports(stlibrd_t *brdp) stliport_t *portp; int i, panelnr, panelport; +#ifdef DEBUG + printk(KERN_DEBUG "stli_initports(brdp=%x)\n", (int) brdp); +#endif + for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { portp = kzalloc(sizeof(stliport_t), GFP_KERNEL); if (!portp) { @@ -2946,7 +3240,7 @@ static int stli_initports(stlibrd_t *brdp) brdp->ports[i] = portp; } - return 0; + return(0); } /*****************************************************************************/ @@ -2959,6 +3253,10 @@ static void stli_ecpinit(stlibrd_t *brdp) { unsigned long memconf; +#ifdef DEBUG + printk(KERN_DEBUG "stli_ecpinit(brdp=%d)\n", (int) brdp); +#endif + outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); udelay(10); outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); @@ -2972,6 +3270,9 @@ static void stli_ecpinit(stlibrd_t *brdp) static void stli_ecpenable(stlibrd_t *brdp) { +#ifdef DEBUG + printk(KERN_DEBUG "stli_ecpenable(brdp=%x)\n", (int) brdp); +#endif outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR)); } @@ -2979,6 +3280,9 @@ static void stli_ecpenable(stlibrd_t *brdp) static void stli_ecpdisable(stlibrd_t *brdp) { +#ifdef DEBUG + printk(KERN_DEBUG "stli_ecpdisable(brdp=%x)\n", (int) brdp); +#endif outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); } @@ -2986,8 +3290,13 @@ static void stli_ecpdisable(stlibrd_t *brdp) static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void *ptr; - unsigned char val; + void *ptr; + unsigned char val; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_ecpgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, + (int) offset); +#endif if (offset > brdp->memsize) { printk(KERN_ERR "STALLION: shared memory pointer=%x out of " @@ -3007,6 +3316,10 @@ static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) static void stli_ecpreset(stlibrd_t *brdp) { +#ifdef DEBUG + printk(KERN_DEBUG "stli_ecpreset(brdp=%x)\n", (int) brdp); +#endif + outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); udelay(10); outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); @@ -3017,6 +3330,9 @@ static void stli_ecpreset(stlibrd_t *brdp) static void stli_ecpintr(stlibrd_t *brdp) { +#ifdef DEBUG + printk(KERN_DEBUG "stli_ecpintr(brdp=%x)\n", (int) brdp); +#endif outb(0x1, brdp->iobase); } @@ -3030,6 +3346,10 @@ static void stli_ecpeiinit(stlibrd_t *brdp) { unsigned long memconf; +#ifdef DEBUG + printk(KERN_DEBUG "stli_ecpeiinit(brdp=%x)\n", (int) brdp); +#endif + outb(0x1, (brdp->iobase + ECP_EIBRDENAB)); outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); udelay(10); @@ -3063,6 +3383,11 @@ static char *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line void *ptr; unsigned char val; +#ifdef DEBUG + printk(KERN_DEBUG "stli_ecpeigetmemptr(brdp=%x,offset=%x,line=%d)\n", + (int) brdp, (int) offset, line); +#endif + if (offset > brdp->memsize) { printk(KERN_ERR "STALLION: shared memory pointer=%x out of " "range at line=%d(%d), brd=%d\n", @@ -3112,8 +3437,8 @@ static void stli_ecpmcdisable(stlibrd_t *brdp) static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void *ptr; - unsigned char val; + void *ptr; + unsigned char val; if (offset > brdp->memsize) { printk(KERN_ERR "STALLION: shared memory pointer=%x out of " @@ -3147,6 +3472,10 @@ static void stli_ecpmcreset(stlibrd_t *brdp) static void stli_ecppciinit(stlibrd_t *brdp) { +#ifdef DEBUG + printk(KERN_DEBUG "stli_ecppciinit(brdp=%x)\n", (int) brdp); +#endif + outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); udelay(10); outb(0, (brdp->iobase + ECP_PCICONFR)); @@ -3160,6 +3489,11 @@ static char *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int lin void *ptr; unsigned char val; +#ifdef DEBUG + printk(KERN_DEBUG "stli_ecppcigetmemptr(brdp=%x,offset=%x,line=%d)\n", + (int) brdp, (int) offset, line); +#endif + if (offset > brdp->memsize) { printk(KERN_ERR "STALLION: shared memory pointer=%x out of " "range at line=%d(%d), board=%d\n", @@ -3194,6 +3528,10 @@ static void stli_onbinit(stlibrd_t *brdp) { unsigned long memconf; +#ifdef DEBUG + printk(KERN_DEBUG "stli_onbinit(brdp=%d)\n", (int) brdp); +#endif + outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); udelay(10); outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); @@ -3209,6 +3547,9 @@ static void stli_onbinit(stlibrd_t *brdp) static void stli_onbenable(stlibrd_t *brdp) { +#ifdef DEBUG + printk(KERN_DEBUG "stli_onbenable(brdp=%x)\n", (int) brdp); +#endif outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR)); } @@ -3216,6 +3557,9 @@ static void stli_onbenable(stlibrd_t *brdp) static void stli_onbdisable(stlibrd_t *brdp) { +#ifdef DEBUG + printk(KERN_DEBUG "stli_onbdisable(brdp=%x)\n", (int) brdp); +#endif outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR)); } @@ -3225,6 +3569,11 @@ static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { void *ptr; +#ifdef DEBUG + printk(KERN_DEBUG "stli_onbgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, + (int) offset); +#endif + if (offset > brdp->memsize) { printk(KERN_ERR "STALLION: shared memory pointer=%x out of " "range at line=%d(%d), brd=%d\n", @@ -3240,6 +3589,11 @@ static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) static void stli_onbreset(stlibrd_t *brdp) { + +#ifdef DEBUG + printk(KERN_DEBUG "stli_onbreset(brdp=%x)\n", (int) brdp); +#endif + outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); udelay(10); outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); @@ -3256,6 +3610,10 @@ static void stli_onbeinit(stlibrd_t *brdp) { unsigned long memconf; +#ifdef DEBUG + printk(KERN_DEBUG "stli_onbeinit(brdp=%d)\n", (int) brdp); +#endif + outb(0x1, (brdp->iobase + ONB_EIBRDENAB)); outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); udelay(10); @@ -3274,6 +3632,9 @@ static void stli_onbeinit(stlibrd_t *brdp) static void stli_onbeenable(stlibrd_t *brdp) { +#ifdef DEBUG + printk(KERN_DEBUG "stli_onbeenable(brdp=%x)\n", (int) brdp); +#endif outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR)); } @@ -3281,6 +3642,9 @@ static void stli_onbeenable(stlibrd_t *brdp) static void stli_onbedisable(stlibrd_t *brdp) { +#ifdef DEBUG + printk(KERN_DEBUG "stli_onbedisable(brdp=%x)\n", (int) brdp); +#endif outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); } @@ -3288,8 +3652,13 @@ static void stli_onbedisable(stlibrd_t *brdp) static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void *ptr; - unsigned char val; + void *ptr; + unsigned char val; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_onbegetmemptr(brdp=%x,offset=%x,line=%d)\n", + (int) brdp, (int) offset, line); +#endif if (offset > brdp->memsize) { printk(KERN_ERR "STALLION: shared memory pointer=%x out of " @@ -3312,6 +3681,11 @@ static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line) static void stli_onbereset(stlibrd_t *brdp) { + +#ifdef DEBUG + printk(KERN_ERR "stli_onbereset(brdp=%x)\n", (int) brdp); +#endif + outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); udelay(10); outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); @@ -3326,6 +3700,11 @@ static void stli_onbereset(stlibrd_t *brdp) static void stli_bbyinit(stlibrd_t *brdp) { + +#ifdef DEBUG + printk(KERN_ERR "stli_bbyinit(brdp=%d)\n", (int) brdp); +#endif + outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); udelay(10); outb(0, (brdp->iobase + BBY_ATCONFR)); @@ -3338,13 +3717,24 @@ static void stli_bbyinit(stlibrd_t *brdp) static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void *ptr; - unsigned char val; + void *ptr; + unsigned char val; - BUG_ON(offset > brdp->memsize); +#ifdef DEBUG + printk(KERN_ERR "stli_bbygetmemptr(brdp=%x,offset=%x)\n", (int) brdp, + (int) offset); +#endif - ptr = brdp->membase + (offset % BBY_PAGESIZE); - val = (unsigned char) (offset / BBY_PAGESIZE); + if (offset > brdp->memsize) { + printk(KERN_ERR "STALLION: shared memory pointer=%x out of " + "range at line=%d(%d), brd=%d\n", + (int) offset, line, __LINE__, brdp->brdnr); + ptr = NULL; + val = 0; + } else { + ptr = brdp->membase + (offset % BBY_PAGESIZE); + val = (unsigned char) (offset / BBY_PAGESIZE); + } outb(val, (brdp->iobase + BBY_ATCONFR)); return(ptr); } @@ -3353,6 +3743,11 @@ static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line) static void stli_bbyreset(stlibrd_t *brdp) { + +#ifdef DEBUG + printk(KERN_DEBUG "stli_bbyreset(brdp=%x)\n", (int) brdp); +#endif + outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); udelay(10); outb(0, (brdp->iobase + BBY_ATCONFR)); @@ -3367,6 +3762,11 @@ static void stli_bbyreset(stlibrd_t *brdp) static void stli_stalinit(stlibrd_t *brdp) { + +#ifdef DEBUG + printk(KERN_DEBUG "stli_stalinit(brdp=%d)\n", (int) brdp); +#endif + outb(0x1, brdp->iobase); mdelay(1000); } @@ -3375,18 +3775,36 @@ static void stli_stalinit(stlibrd_t *brdp) static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - BUG_ON(offset > brdp->memsize); - return brdp->membase + (offset % STAL_PAGESIZE); + void *ptr; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_stalgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, + (int) offset); +#endif + + if (offset > brdp->memsize) { + printk(KERN_ERR "STALLION: shared memory pointer=%x out of " + "range at line=%d(%d), brd=%d\n", + (int) offset, line, __LINE__, brdp->brdnr); + ptr = NULL; + } else { + ptr = brdp->membase + (offset % STAL_PAGESIZE); + } + return(ptr); } /*****************************************************************************/ static void stli_stalreset(stlibrd_t *brdp) { - u32 __iomem *vecp; + volatile unsigned long *vecp; - vecp = (u32 __iomem *) (brdp->membase + 0x30); - writel(0xffff0000, vecp); +#ifdef DEBUG + printk(KERN_DEBUG "stli_stalreset(brdp=%x)\n", (int) brdp); +#endif + + vecp = (volatile unsigned long *) (brdp->membase + 0x30); + *vecp = 0xffff0000; outb(0, brdp->iobase); mdelay(1000); } @@ -3400,11 +3818,15 @@ static void stli_stalreset(stlibrd_t *brdp) static int stli_initecp(stlibrd_t *brdp) { - cdkecpsig_t sig; - cdkecpsig_t __iomem *sigsp; - unsigned int status, nxtid; - char *name; - int panelnr, nrports; + cdkecpsig_t sig; + cdkecpsig_t *sigsp; + unsigned int status, nxtid; + char *name; + int panelnr, nrports; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_initecp(brdp=%x)\n", (int) brdp); +#endif if (!request_region(brdp->iobase, brdp->iosize, "istallion")) return -EIO; @@ -3412,7 +3834,7 @@ static int stli_initecp(stlibrd_t *brdp) if ((brdp->iobase == 0) || (brdp->memaddr == 0)) { release_region(brdp->iobase, brdp->iosize); - return -ENODEV; + return(-ENODEV); } brdp->iosize = ECP_IOSIZE; @@ -3481,7 +3903,7 @@ static int stli_initecp(stlibrd_t *brdp) default: release_region(brdp->iobase, brdp->iosize); - return -EINVAL; + return(-EINVAL); } /* @@ -3493,10 +3915,10 @@ static int stli_initecp(stlibrd_t *brdp) EBRDINIT(brdp); brdp->membase = ioremap(brdp->memaddr, brdp->memsize); - if (brdp->membase == NULL) + if (brdp->membase == (void *) NULL) { release_region(brdp->iobase, brdp->iosize); - return -ENOMEM; + return(-ENOMEM); } /* @@ -3505,14 +3927,23 @@ static int stli_initecp(stlibrd_t *brdp) * this is, and what it is connected to it. */ EBRDENABLE(brdp); - sigsp = (cdkecpsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); + sigsp = (cdkecpsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); memcpy(&sig, sigsp, sizeof(cdkecpsig_t)); EBRDDISABLE(brdp); - if (sig.magic != cpu_to_le32(ECP_MAGIC)) +#if 0 + printk("%s(%d): sig-> magic=%x rom=%x panel=%x,%x,%x,%x,%x,%x,%x,%x\n", + __FILE__, __LINE__, (int) sig.magic, sig.romver, sig.panelid[0], + (int) sig.panelid[1], (int) sig.panelid[2], + (int) sig.panelid[3], (int) sig.panelid[4], + (int) sig.panelid[5], (int) sig.panelid[6], + (int) sig.panelid[7]); +#endif + + if (sig.magic != ECP_MAGIC) { release_region(brdp->iobase, brdp->iosize); - return -ENODEV; + return(-ENODEV); } /* @@ -3536,7 +3967,7 @@ static int stli_initecp(stlibrd_t *brdp) brdp->state |= BST_FOUND; - return 0; + return(0); } /*****************************************************************************/ @@ -3548,16 +3979,20 @@ static int stli_initecp(stlibrd_t *brdp) static int stli_initonb(stlibrd_t *brdp) { - cdkonbsig_t sig; - cdkonbsig_t __iomem *sigsp; - char *name; - int i; + cdkonbsig_t sig; + cdkonbsig_t *sigsp; + char *name; + int i; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_initonb(brdp=%x)\n", (int) brdp); +#endif /* * Do a basic sanity check on the IO and memory addresses. */ - if (brdp->iobase == 0 || brdp->memaddr == 0) - return -ENODEV; + if ((brdp->iobase == 0) || (brdp->memaddr == 0)) + return(-ENODEV); brdp->iosize = ONB_IOSIZE; @@ -3575,6 +4010,7 @@ static int stli_initonb(stlibrd_t *brdp) case BRD_ONBOARD2: case BRD_ONBOARD2_32: case BRD_ONBOARDRS: + brdp->membase = (void *) brdp->memaddr; brdp->memsize = ONB_MEMSIZE; brdp->pagesize = ONB_ATPAGESIZE; brdp->init = stli_onbinit; @@ -3592,6 +4028,7 @@ static int stli_initonb(stlibrd_t *brdp) break; case BRD_ONBOARDE: + brdp->membase = (void *) brdp->memaddr; brdp->memsize = ONB_EIMEMSIZE; brdp->pagesize = ONB_EIPAGESIZE; brdp->init = stli_onbeinit; @@ -3607,6 +4044,7 @@ static int stli_initonb(stlibrd_t *brdp) case BRD_BRUMBY4: case BRD_BRUMBY8: case BRD_BRUMBY16: + brdp->membase = (void *) brdp->memaddr; brdp->memsize = BBY_MEMSIZE; brdp->pagesize = BBY_PAGESIZE; brdp->init = stli_bbyinit; @@ -3620,6 +4058,7 @@ static int stli_initonb(stlibrd_t *brdp) break; case BRD_STALLION: + brdp->membase = (void *) brdp->memaddr; brdp->memsize = STAL_MEMSIZE; brdp->pagesize = STAL_PAGESIZE; brdp->init = stli_stalinit; @@ -3634,7 +4073,7 @@ static int stli_initonb(stlibrd_t *brdp) default: release_region(brdp->iobase, brdp->iosize); - return -EINVAL; + return(-EINVAL); } /* @@ -3646,10 +4085,10 @@ static int stli_initonb(stlibrd_t *brdp) EBRDINIT(brdp); brdp->membase = ioremap(brdp->memaddr, brdp->memsize); - if (brdp->membase == NULL) + if (brdp->membase == (void *) NULL) { release_region(brdp->iobase, brdp->iosize); - return -ENOMEM; + return(-ENOMEM); } /* @@ -3658,17 +4097,21 @@ static int stli_initonb(stlibrd_t *brdp) * this is, and how many ports. */ EBRDENABLE(brdp); - sigsp = (cdkonbsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); - memcpy_fromio(&sig, sigsp, sizeof(cdkonbsig_t)); + sigsp = (cdkonbsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); + memcpy(&sig, sigsp, sizeof(cdkonbsig_t)); EBRDDISABLE(brdp); - if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) || - sig.magic1 != cpu_to_le16(ONB_MAGIC1) || - sig.magic2 != cpu_to_le16(ONB_MAGIC2) || - sig.magic3 != cpu_to_le16(ONB_MAGIC3)) +#if 0 + printk("%s(%d): sig-> magic=%x:%x:%x:%x romver=%x amask=%x:%x:%x\n", + __FILE__, __LINE__, sig.magic0, sig.magic1, sig.magic2, + sig.magic3, sig.romver, sig.amask0, sig.amask1, sig.amask2); +#endif + + if ((sig.magic0 != ONB_MAGIC0) || (sig.magic1 != ONB_MAGIC1) || + (sig.magic2 != ONB_MAGIC2) || (sig.magic3 != ONB_MAGIC3)) { release_region(brdp->iobase, brdp->iosize); - return -ENODEV; + return(-ENODEV); } /* @@ -3689,7 +4132,7 @@ static int stli_initonb(stlibrd_t *brdp) brdp->state |= BST_FOUND; - return 0; + return(0); } /*****************************************************************************/ @@ -3702,25 +4145,31 @@ static int stli_initonb(stlibrd_t *brdp) static int stli_startbrd(stlibrd_t *brdp) { - cdkhdr_t __iomem *hdrp; - cdkmem_t __iomem *memp; - cdkasy_t __iomem *ap; - unsigned long flags; - stliport_t *portp; - int portnr, nrdevs, i, rc = 0; - u32 memoff; - - spin_lock_irqsave(&brd_lock, flags); + volatile cdkhdr_t *hdrp; + volatile cdkmem_t *memp; + volatile cdkasy_t *ap; + unsigned long flags; + stliport_t *portp; + int portnr, nrdevs, i, rc; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_startbrd(brdp=%x)\n", (int) brdp); +#endif + + rc = 0; + + save_flags(flags); + cli(); EBRDENABLE(brdp); - hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); nrdevs = hdrp->nrdevs; #if 0 printk("%s(%d): CDK version %d.%d.%d --> " "nrdevs=%d memp=%x hostp=%x slavep=%x\n", - __FILE__, __LINE__, readb(&hdrp->ver_release), readb(&hdrp->ver_modification), - readb(&hdrp->ver_fix), nrdevs, (int) readl(&hdrp->memp), readl(&hdrp->hostp), - readl(&hdrp->slavep)); + __FILE__, __LINE__, hdrp->ver_release, hdrp->ver_modification, + hdrp->ver_fix, nrdevs, (int) hdrp->memp, (int) hdrp->hostp, + (int) hdrp->slavep); #endif if (nrdevs < (brdp->nrports + 1)) { @@ -3732,14 +4181,14 @@ static int stli_startbrd(stlibrd_t *brdp) brdp->hostoffset = hdrp->hostp - CDK_CDKADDR; brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR; brdp->bitsize = (nrdevs + 7) / 8; - memoff = readl(&hdrp->memp); - if (memoff > brdp->memsize) { + memp = (volatile cdkmem_t *) hdrp->memp; + if (((unsigned long) memp) > brdp->memsize) { printk(KERN_ERR "STALLION: corrupted shared memory region?\n"); rc = -EIO; goto stli_donestartup; } - memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff); - if (readw(&memp->dtype) != TYP_ASYNCTRL) { + memp = (volatile cdkmem_t *) EBRDGETMEMPTR(brdp, (unsigned long) memp); + if (memp->dtype != TYP_ASYNCTRL) { printk(KERN_ERR "STALLION: no slave control device found\n"); goto stli_donestartup; } @@ -3751,19 +4200,19 @@ static int stli_startbrd(stlibrd_t *brdp) * change pages while reading memory map. */ for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) { - if (readw(&memp->dtype) != TYP_ASYNC) + if (memp->dtype != TYP_ASYNC) break; portp = brdp->ports[portnr]; - if (portp == NULL) + if (portp == (stliport_t *) NULL) break; portp->devnr = i; - portp->addr = readl(&memp->offset); + portp->addr = memp->offset; portp->reqbit = (unsigned char) (0x1 << (i * 8 / nrdevs)); portp->portidx = (unsigned char) (i / 8); portp->portbit = (unsigned char) (0x1 << (i % 8)); } - writeb(0xff, &hdrp->slavereq); + hdrp->slavereq = 0xff; /* * For each port setup a local copy of the RX and TX buffer offsets @@ -3772,22 +4221,22 @@ static int stli_startbrd(stlibrd_t *brdp) */ for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) { portp = brdp->ports[portnr]; - if (portp == NULL) + if (portp == (stliport_t *) NULL) break; if (portp->addr == 0) break; - ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); - if (ap != NULL) { - portp->rxsize = readw(&ap->rxq.size); - portp->txsize = readw(&ap->txq.size); - portp->rxoffset = readl(&ap->rxq.offset); - portp->txoffset = readl(&ap->txq.offset); + ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); + if (ap != (volatile cdkasy_t *) NULL) { + portp->rxsize = ap->rxq.size; + portp->txsize = ap->txq.size; + portp->rxoffset = ap->rxq.offset; + portp->txoffset = ap->txq.offset; } } stli_donestartup: EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); if (rc == 0) brdp->state |= BST_STARTED; @@ -3798,7 +4247,7 @@ static int stli_startbrd(stlibrd_t *brdp) add_timer(&stli_timerlist); } - return rc; + return(rc); } /*****************************************************************************/ @@ -3809,6 +4258,10 @@ static int stli_startbrd(stlibrd_t *brdp) static int __init stli_brdinit(stlibrd_t *brdp) { +#ifdef DEBUG + printk(KERN_DEBUG "stli_brdinit(brdp=%x)\n", (int) brdp); +#endif + stli_brds[brdp->brdnr] = brdp; switch (brdp->brdtype) { @@ -3836,11 +4289,11 @@ static int __init stli_brdinit(stlibrd_t *brdp) case BRD_ECHPCI: printk(KERN_ERR "STALLION: %s board type not supported in " "this driver\n", stli_brdnames[brdp->brdtype]); - return -ENODEV; + return(ENODEV); default: printk(KERN_ERR "STALLION: board=%d is unknown board " "type=%d\n", brdp->brdnr, brdp->brdtype); - return -ENODEV; + return(ENODEV); } if ((brdp->state & BST_FOUND) == 0) { @@ -3848,7 +4301,7 @@ static int __init stli_brdinit(stlibrd_t *brdp) "io=%x mem=%x\n", stli_brdnames[brdp->brdtype], brdp->brdnr, brdp->iobase, (int) brdp->memaddr); - return -ENODEV; + return(ENODEV); } stli_initports(brdp); @@ -3856,7 +4309,7 @@ static int __init stli_brdinit(stlibrd_t *brdp) "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype], brdp->brdnr, brdp->iobase, (int) brdp->memaddr, brdp->nrpanels, brdp->nrports); - return 0; + return(0); } /*****************************************************************************/ @@ -3868,10 +4321,14 @@ static int __init stli_brdinit(stlibrd_t *brdp) static int stli_eisamemprobe(stlibrd_t *brdp) { - cdkecpsig_t ecpsig, __iomem *ecpsigp; - cdkonbsig_t onbsig, __iomem *onbsigp; + cdkecpsig_t ecpsig, *ecpsigp; + cdkonbsig_t onbsig, *onbsigp; int i, foundit; +#ifdef DEBUG + printk(KERN_DEBUG "stli_eisamemprobe(brdp=%x)\n", (int) brdp); +#endif + /* * First up we reset the board, to get it into a known state. There * is only 2 board types here we need to worry about. Don;t use the @@ -3895,7 +4352,7 @@ static int stli_eisamemprobe(stlibrd_t *brdp) mdelay(1); stli_onbeenable(brdp); } else { - return -ENODEV; + return(-ENODEV); } foundit = 0; @@ -3907,24 +4364,25 @@ static int stli_eisamemprobe(stlibrd_t *brdp) */ for (i = 0; (i < stli_eisamempsize); i++) { brdp->memaddr = stli_eisamemprobeaddrs[i]; + brdp->membase = (void *) brdp->memaddr; brdp->membase = ioremap(brdp->memaddr, brdp->memsize); - if (brdp->membase == NULL) + if (brdp->membase == (void *) NULL) continue; if (brdp->brdtype == BRD_ECPE) { - ecpsigp = (cdkecpsig_t __iomem *) stli_ecpeigetmemptr(brdp, + ecpsigp = (cdkecpsig_t *) stli_ecpeigetmemptr(brdp, CDK_SIGADDR, __LINE__); - memcpy_fromio(&ecpsig, ecpsigp, sizeof(cdkecpsig_t)); - if (ecpsig.magic == cpu_to_le32(ECP_MAGIC)) + memcpy(&ecpsig, ecpsigp, sizeof(cdkecpsig_t)); + if (ecpsig.magic == ECP_MAGIC) foundit = 1; } else { - onbsigp = (cdkonbsig_t __iomem *) stli_onbegetmemptr(brdp, + onbsigp = (cdkonbsig_t *) stli_onbegetmemptr(brdp, CDK_SIGADDR, __LINE__); - memcpy_fromio(&onbsig, onbsigp, sizeof(cdkonbsig_t)); - if ((onbsig.magic0 == cpu_to_le16(ONB_MAGIC0)) && - (onbsig.magic1 == cpu_to_le16(ONB_MAGIC1)) && - (onbsig.magic2 == cpu_to_le16(ONB_MAGIC2)) && - (onbsig.magic3 == cpu_to_le16(ONB_MAGIC3))) + memcpy(&onbsig, onbsigp, sizeof(cdkonbsig_t)); + if ((onbsig.magic0 == ONB_MAGIC0) && + (onbsig.magic1 == ONB_MAGIC1) && + (onbsig.magic2 == ONB_MAGIC2) && + (onbsig.magic3 == ONB_MAGIC3)) foundit = 1; } @@ -3948,9 +4406,9 @@ static int stli_eisamemprobe(stlibrd_t *brdp) printk(KERN_ERR "STALLION: failed to probe shared memory " "region for %s in EISA slot=%d\n", stli_brdnames[brdp->brdtype], (brdp->iobase >> 12)); - return -ENODEV; + return(-ENODEV); } - return 0; + return(0); } static int stli_getbrdnr(void) @@ -3981,16 +4439,22 @@ static int stli_getbrdnr(void) static int stli_findeisabrds(void) { - stlibrd_t *brdp; - unsigned int iobase, eid; - int i; + stlibrd_t *brdp; + unsigned int iobase, eid; + int i; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_findeisabrds()\n"); +#endif /* - * Firstly check if this is an EISA system. If this is not an EISA system then + * Firstly check if this is an EISA system. Do this by probing for + * the system board EISA ID. If this is not an EISA system then * don't bother going any further! */ - if (EISA_bus) - return 0; + outb(0xff, 0xc80); + if (inb(0xc80) == 0xff) + return(0); /* * Looks like an EISA system, so go searching for EISA boards. @@ -4008,7 +4472,7 @@ static int stli_findeisabrds(void) */ for (i = 0; (i < STL_MAXBRDS); i++) { brdp = stli_brds[i]; - if (brdp == NULL) + if (brdp == (stlibrd_t *) NULL) continue; if (brdp->iobase == iobase) break; @@ -4020,10 +4484,10 @@ static int stli_findeisabrds(void) * We have found a Stallion board and it is not configured already. * Allocate a board structure and initialize it. */ - if ((brdp = stli_allocbrd()) == NULL) - return -ENOMEM; + if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL) + return(-ENOMEM); if ((brdp->brdnr = stli_getbrdnr()) < 0) - return -ENOMEM; + return(-ENOMEM); eid = inb(iobase + 0xc82); if (eid == ECP_EISAID) brdp->brdtype = BRD_ECPE; @@ -4038,7 +4502,7 @@ static int stli_findeisabrds(void) stli_brdinit(brdp); } - return 0; + return(0); } /*****************************************************************************/ @@ -4059,18 +4523,32 @@ static int stli_findeisabrds(void) static int stli_initpcibrd(int brdtype, struct pci_dev *devp) { - stlibrd_t *brdp; + stlibrd_t *brdp; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n", + brdtype, dev->bus->number, dev->devfn); +#endif if (pci_enable_device(devp)) - return -EIO; - if ((brdp = stli_allocbrd()) == NULL) - return -ENOMEM; + return(-EIO); + if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL) + return(-ENOMEM); if ((brdp->brdnr = stli_getbrdnr()) < 0) { printk(KERN_INFO "STALLION: too many boards found, " "maximum supported %d\n", STL_MAXBRDS); - return 0; + return(0); } brdp->brdtype = brdtype; + +#ifdef DEBUG + printk(KERN_DEBUG "%s(%d): BAR[]=%lx,%lx,%lx,%lx\n", __FILE__, __LINE__, + pci_resource_start(devp, 0), + pci_resource_start(devp, 1), + pci_resource_start(devp, 2), + pci_resource_start(devp, 3)); +#endif + /* * We have all resources from the board, so lets setup the actual * board structure now. @@ -4079,7 +4557,7 @@ static int stli_initpcibrd(int brdtype, struct pci_dev *devp) brdp->memaddr = pci_resource_start(devp, 2); stli_brdinit(brdp); - return 0; + return(0); } /*****************************************************************************/ @@ -4091,12 +4569,20 @@ static int stli_initpcibrd(int brdtype, struct pci_dev *devp) static int stli_findpcibrds(void) { - struct pci_dev *dev = NULL; + struct pci_dev *dev = NULL; + int rc; + +#ifdef DEBUG + printk("stli_findpcibrds()\n"); +#endif - while ((dev = pci_get_device(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, dev))) { - stli_initpcibrd(BRD_ECPPCI, dev); + while ((dev = pci_find_device(PCI_VENDOR_ID_STALLION, + PCI_DEVICE_ID_ECRA, dev))) { + if ((rc = stli_initpcibrd(BRD_ECPPCI, dev))) + return(rc); } - return 0; + + return(0); } #endif @@ -4109,16 +4595,17 @@ static int stli_findpcibrds(void) static stlibrd_t *stli_allocbrd(void) { - stlibrd_t *brdp; + stlibrd_t *brdp; brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL); if (!brdp) { printk(KERN_ERR "STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(stlibrd_t)); + "(size=%d)\n", sizeof(stlibrd_t)); return NULL; } + brdp->magic = STLI_BOARDMAGIC; - return brdp; + return(brdp); } /*****************************************************************************/ @@ -4130,9 +4617,13 @@ static stlibrd_t *stli_allocbrd(void) static int stli_initbrds(void) { - stlibrd_t *brdp, *nxtbrdp; - stlconf_t *confp; - int i, j; + stlibrd_t *brdp, *nxtbrdp; + stlconf_t *confp; + int i, j; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_initbrds()\n"); +#endif if (stli_nrbrds > STL_MAXBRDS) { printk(KERN_INFO "STALLION: too many boards in configuration " @@ -4147,9 +4638,11 @@ static int stli_initbrds(void) */ for (i = 0; (i < stli_nrbrds); i++) { confp = &stli_brdconf[i]; +#ifdef MODULE stli_parsebrd(confp, stli_brdsp[i]); - if ((brdp = stli_allocbrd()) == NULL) - return -ENOMEM; +#endif + if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL) + return(-ENOMEM); brdp->brdnr = i; brdp->brdtype = confp->brdtype; brdp->iobase = confp->ioaddr1; @@ -4161,7 +4654,9 @@ static int stli_initbrds(void) * Static configuration table done, so now use dynamic methods to * see if any more boards should be configured. */ +#ifdef MODULE stli_argbrds(); +#endif if (STLI_EISAPROBE) stli_findeisabrds(); #ifdef CONFIG_PCI @@ -4177,11 +4672,11 @@ static int stli_initbrds(void) if (stli_nrbrds > 1) { for (i = 0; (i < stli_nrbrds); i++) { brdp = stli_brds[i]; - if (brdp == NULL) + if (brdp == (stlibrd_t *) NULL) continue; for (j = i + 1; (j < stli_nrbrds); j++) { nxtbrdp = stli_brds[j]; - if (nxtbrdp == NULL) + if (nxtbrdp == (stlibrd_t *) NULL) continue; if ((brdp->membase >= nxtbrdp->membase) && (brdp->membase <= (nxtbrdp->membase + @@ -4196,7 +4691,7 @@ static int stli_initbrds(void) if (stli_shared == 0) { for (i = 0; (i < stli_nrbrds); i++) { brdp = stli_brds[i]; - if (brdp == NULL) + if (brdp == (stlibrd_t *) NULL) continue; if (brdp->state & BST_FOUND) { EBRDENABLE(brdp); @@ -4206,7 +4701,7 @@ static int stli_initbrds(void) } } - return 0; + return(0); } /*****************************************************************************/ @@ -4219,55 +4714,48 @@ static int stli_initbrds(void) static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp) { - unsigned long flags; - void *memptr; - stlibrd_t *brdp; - int brdnr, size, n; - void *p; - loff_t off = *offp; + unsigned long flags; + void *memptr; + stlibrd_t *brdp; + int brdnr, size, n; + +#ifdef DEBUG + printk(KERN_DEBUG "stli_memread(fp=%x,buf=%x,count=%x,offp=%x)\n", + (int) fp, (int) buf, count, (int) offp); +#endif brdnr = iminor(fp->f_dentry->d_inode); if (brdnr >= stli_nrbrds) - return -ENODEV; + return(-ENODEV); brdp = stli_brds[brdnr]; - if (brdp == NULL) - return -ENODEV; + if (brdp == (stlibrd_t *) NULL) + return(-ENODEV); if (brdp->state == 0) - return -ENODEV; - if (off >= brdp->memsize || off + count < off) - return 0; - - size = MIN(count, (brdp->memsize - off)); - - /* - * Copy the data a page at a time - */ + return(-ENODEV); + if (fp->f_pos >= brdp->memsize) + return(0); - p = (void *)__get_free_page(GFP_KERNEL); - if(p == NULL) - return -ENOMEM; + size = MIN(count, (brdp->memsize - fp->f_pos)); + save_flags(flags); + cli(); + EBRDENABLE(brdp); while (size > 0) { - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - memptr = (void *) EBRDGETMEMPTR(brdp, off); - n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); - n = MIN(n, PAGE_SIZE); - memcpy_fromio(p, memptr, n); - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - if (copy_to_user(buf, p, n)) { + memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos); + n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize))); + if (copy_to_user(buf, memptr, n)) { count = -EFAULT; goto out; } - off += n; + fp->f_pos += n; buf += n; size -= n; } out: - *offp = off; - free_page((unsigned long)p); - return count; + EBRDDISABLE(brdp); + restore_flags(flags); + + return(count); } /*****************************************************************************/ @@ -4276,65 +4764,54 @@ static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, lof * Code to handle an "staliomem" write operation. This device is the * contents of the board shared memory. It is used for down loading * the slave image (and debugging :-) - * - * FIXME: copy under lock */ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp) { - unsigned long flags; - void *memptr; - stlibrd_t *brdp; - char __user *chbuf; - int brdnr, size, n; - void *p; - loff_t off = *offp; + unsigned long flags; + void *memptr; + stlibrd_t *brdp; + char __user *chbuf; + int brdnr, size, n; - brdnr = iminor(fp->f_dentry->d_inode); +#ifdef DEBUG + printk(KERN_DEBUG "stli_memwrite(fp=%x,buf=%x,count=%x,offp=%x)\n", + (int) fp, (int) buf, count, (int) offp); +#endif + brdnr = iminor(fp->f_dentry->d_inode); if (brdnr >= stli_nrbrds) - return -ENODEV; + return(-ENODEV); brdp = stli_brds[brdnr]; - if (brdp == NULL) - return -ENODEV; + if (brdp == (stlibrd_t *) NULL) + return(-ENODEV); if (brdp->state == 0) - return -ENODEV; - if (off >= brdp->memsize || off + count < off) - return 0; + return(-ENODEV); + if (fp->f_pos >= brdp->memsize) + return(0); chbuf = (char __user *) buf; - size = MIN(count, (brdp->memsize - off)); - - /* - * Copy the data a page at a time - */ - - p = (void *)__get_free_page(GFP_KERNEL); - if(p == NULL) - return -ENOMEM; + size = MIN(count, (brdp->memsize - fp->f_pos)); + save_flags(flags); + cli(); + EBRDENABLE(brdp); while (size > 0) { - n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); - n = MIN(n, PAGE_SIZE); - if (copy_from_user(p, chbuf, n)) { - if (count == 0) - count = -EFAULT; + memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos); + n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize))); + if (copy_from_user(memptr, chbuf, n)) { + count = -EFAULT; goto out; } - spin_lock_irqsave(&brd_lock, flags); - EBRDENABLE(brdp); - memptr = (void *) EBRDGETMEMPTR(brdp, off); - memcpy_toio(memptr, p, n); - EBRDDISABLE(brdp); - spin_unlock_irqrestore(&brd_lock, flags); - off += n; + fp->f_pos += n; chbuf += n; size -= n; } out: - free_page((unsigned long) p); - *offp = off; - return count; + EBRDDISABLE(brdp); + restore_flags(flags); + + return(count); } /*****************************************************************************/ @@ -4345,16 +4822,16 @@ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t cou static int stli_getbrdstats(combrd_t __user *bp) { - stlibrd_t *brdp; - int i; + stlibrd_t *brdp; + int i; if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t))) return -EFAULT; if (stli_brdstats.brd >= STL_MAXBRDS) - return -ENODEV; + return(-ENODEV); brdp = stli_brds[stli_brdstats.brd]; - if (brdp == NULL) - return -ENODEV; + if (brdp == (stlibrd_t *) NULL) + return(-ENODEV); memset(&stli_brdstats, 0, sizeof(combrd_t)); stli_brdstats.brd = brdp->brdnr; @@ -4373,7 +4850,7 @@ static int stli_getbrdstats(combrd_t __user *bp) if (copy_to_user(bp, &stli_brdstats, sizeof(combrd_t))) return -EFAULT; - return 0; + return(0); } /*****************************************************************************/ @@ -4384,19 +4861,19 @@ static int stli_getbrdstats(combrd_t __user *bp) static stliport_t *stli_getport(int brdnr, int panelnr, int portnr) { - stlibrd_t *brdp; - int i; + stlibrd_t *brdp; + int i; - if (brdnr < 0 || brdnr >= STL_MAXBRDS) - return NULL; + if ((brdnr < 0) || (brdnr >= STL_MAXBRDS)) + return((stliport_t *) NULL); brdp = stli_brds[brdnr]; - if (brdp == NULL) - return NULL; + if (brdp == (stlibrd_t *) NULL) + return((stliport_t *) NULL); for (i = 0; (i < panelnr); i++) portnr += brdp->panels[i]; if ((portnr < 0) || (portnr >= brdp->nrports)) - return NULL; - return brdp->ports[portnr]; + return((stliport_t *) NULL); + return(brdp->ports[portnr]); } /*****************************************************************************/ @@ -4415,16 +4892,16 @@ static int stli_portcmdstats(stliport_t *portp) memset(&stli_comstats, 0, sizeof(comstats_t)); - if (portp == NULL) - return -ENODEV; + if (portp == (stliport_t *) NULL) + return(-ENODEV); brdp = stli_brds[portp->brdnr]; - if (brdp == NULL) - return -ENODEV; + if (brdp == (stlibrd_t *) NULL) + return(-ENODEV); if (brdp->state & BST_STARTED) { if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, &stli_cdkstats, sizeof(asystats_t), 1)) < 0) - return rc; + return(rc); } else { memset(&stli_cdkstats, 0, sizeof(asystats_t)); } @@ -4435,12 +4912,13 @@ static int stli_portcmdstats(stliport_t *portp) stli_comstats.state = portp->state; stli_comstats.flags = portp->flags; - spin_lock_irqsave(&brd_lock, flags); - if (portp->tty != NULL) { + save_flags(flags); + cli(); + if (portp->tty != (struct tty_struct *) NULL) { if (portp->tty->driver_data == portp) { stli_comstats.ttystate = portp->tty->flags; - stli_comstats.rxbuffered = -1; - if (portp->tty->termios != NULL) { + stli_comstats.rxbuffered = -1 /*portp->tty->flip.count*/; + if (portp->tty->termios != (struct termios *) NULL) { stli_comstats.cflags = portp->tty->termios->c_cflag; stli_comstats.iflags = portp->tty->termios->c_iflag; stli_comstats.oflags = portp->tty->termios->c_oflag; @@ -4448,7 +4926,7 @@ static int stli_portcmdstats(stliport_t *portp) } } } - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); stli_comstats.txtotal = stli_cdkstats.txchars; stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover; @@ -4470,7 +4948,7 @@ static int stli_portcmdstats(stliport_t *portp) stli_comstats.hwid = stli_cdkstats.hwid; stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals); - return 0; + return(0); } /*****************************************************************************/ @@ -4483,8 +4961,8 @@ static int stli_portcmdstats(stliport_t *portp) static int stli_getportstats(stliport_t *portp, comstats_t __user *cp) { - stlibrd_t *brdp; - int rc; + stlibrd_t *brdp; + int rc; if (!portp) { if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) @@ -4514,8 +4992,8 @@ static int stli_getportstats(stliport_t *portp, comstats_t __user *cp) static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp) { - stlibrd_t *brdp; - int rc; + stlibrd_t *brdp; + int rc; if (!portp) { if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) @@ -4553,7 +5031,7 @@ static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp) static int stli_getportstruct(stliport_t __user *arg) { - stliport_t *portp; + stliport_t *portp; if (copy_from_user(&stli_dummyport, arg, sizeof(stliport_t))) return -EFAULT; @@ -4574,7 +5052,7 @@ static int stli_getportstruct(stliport_t __user *arg) static int stli_getbrdstruct(stlibrd_t __user *arg) { - stlibrd_t *brdp; + stlibrd_t *brdp; if (copy_from_user(&stli_dummybrd, arg, sizeof(stlibrd_t))) return -EFAULT; @@ -4598,10 +5076,15 @@ static int stli_getbrdstruct(stlibrd_t __user *arg) static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) { - stlibrd_t *brdp; - int brdnr, rc, done; + stlibrd_t *brdp; + int brdnr, rc, done; void __user *argp = (void __user *)arg; +#ifdef DEBUG + printk(KERN_DEBUG "stli_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", + (int) ip, (int) fp, cmd, (int) arg); +#endif + /* * First up handle the board independent ioctls. */ @@ -4632,7 +5115,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un } if (done) - return rc; + return(rc); /* * Now handle the board specific ioctls. These all depend on the @@ -4640,12 +5123,12 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un */ brdnr = iminor(ip); if (brdnr >= STL_MAXBRDS) - return -ENODEV; + return(-ENODEV); brdp = stli_brds[brdnr]; if (!brdp) - return -ENODEV; + return(-ENODEV); if (brdp->state == 0) - return -ENODEV; + return(-ENODEV); switch (cmd) { case STL_BINTR: @@ -4669,7 +5152,8 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un rc = -ENOIOCTLCMD; break; } - return rc; + + return(rc); } static struct tty_operations stli_ops = { @@ -4703,9 +5187,6 @@ int __init stli_init(void) int i; printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion); - spin_lock_init(&stli_lock); - spin_lock_init(&brd_lock); - stli_initbrds(); stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); @@ -4715,6 +5196,10 @@ int __init stli_init(void) /* * Allocate a temporary write buffer. */ + stli_tmpwritebuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); + if (!stli_tmpwritebuf) + printk(KERN_ERR "STALLION: failed to allocate memory " + "(size=%d)\n", STLI_TXBUFSIZE); stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); if (!stli_txcookbuf) printk(KERN_ERR "STALLION: failed to allocate memory " @@ -4758,7 +5243,7 @@ int __init stli_init(void) printk(KERN_ERR "STALLION: failed to register serial driver\n"); return -EBUSY; } - return 0; + return(0); } /*****************************************************************************/ diff --git a/trunk/drivers/char/moxa.c b/trunk/drivers/char/moxa.c index 01247cccb89f..f43c2e04eadd 100644 --- a/trunk/drivers/char/moxa.c +++ b/trunk/drivers/char/moxa.c @@ -301,7 +301,7 @@ static struct tty_operations moxa_ops = { .tiocmset = moxa_tiocmset, }; -static DEFINE_SPINLOCK(moxa_lock); +static spinlock_t moxa_lock = SPIN_LOCK_UNLOCKED; #ifdef CONFIG_PCI static int moxa_get_PCI_conf(struct pci_dev *p, int board_type, moxa_board_conf * board) diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index 72cfd09091e0..645d9d713aec 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -996,6 +996,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) info->session = current->signal->session; info->pgrp = process_group(current); + clear_bit(TTY_DONT_FLIP, &tty->flags); /* status = mxser_get_msr(info->base, 0, info->port); diff --git a/trunk/drivers/char/n_tty.c b/trunk/drivers/char/n_tty.c index 603b9ade5eb0..b9371d5bf790 100644 --- a/trunk/drivers/char/n_tty.c +++ b/trunk/drivers/char/n_tty.c @@ -1132,7 +1132,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) * buffer, and once to drain the space from the (physical) beginning of * the buffer to head pointer. * - * Called under the tty->atomic_read_lock sem + * Called under the tty->atomic_read_lock sem and with TTY_DONT_FLIP set * */ @@ -1271,6 +1271,7 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, } add_wait_queue(&tty->read_wait, &wait); + set_bit(TTY_DONT_FLIP, &tty->flags); while (nr) { /* First test for status change. */ if (tty->packet && tty->link->ctrl_status) { @@ -1314,7 +1315,9 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, break; } n_tty_set_room(tty); + clear_bit(TTY_DONT_FLIP, &tty->flags); timeout = schedule_timeout(timeout); + set_bit(TTY_DONT_FLIP, &tty->flags); continue; } __set_current_state(TASK_RUNNING); @@ -1391,6 +1394,7 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, if (time) timeout = time; } + clear_bit(TTY_DONT_FLIP, &tty->flags); mutex_unlock(&tty->atomic_read_lock); remove_wait_queue(&tty->read_wait, &wait); diff --git a/trunk/drivers/char/nsc_gpio.c b/trunk/drivers/char/nsc_gpio.c deleted file mode 100644 index 5b91e4e25641..000000000000 --- a/trunk/drivers/char/nsc_gpio.c +++ /dev/null @@ -1,142 +0,0 @@ -/* linux/drivers/char/nsc_gpio.c - - National Semiconductor common GPIO device-file/VFS methods. - Allows a user space process to control the GPIO pins. - - Copyright (c) 2001,2002 Christer Weinigel - Copyright (c) 2005 Jim Cromie -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NAME "nsc_gpio" - -void nsc_gpio_dump(struct nsc_gpio_ops *amp, unsigned index) -{ - /* retrieve current config w/o changing it */ - u32 config = amp->gpio_config(index, ~0, 0); - - /* user requested via 'v' command, so its INFO */ - dev_info(amp->dev, "io%02u: 0x%04x %s %s %s %s %s %s %s\tio:%d/%d\n", - index, config, - (config & 1) ? "OE" : "TS", /* output-enabled/tristate */ - (config & 2) ? "PP" : "OD", /* push pull / open drain */ - (config & 4) ? "PUE" : "PUD", /* pull up enabled/disabled */ - (config & 8) ? "LOCKED" : "", /* locked / unlocked */ - (config & 16) ? "LEVEL" : "EDGE",/* level/edge input */ - (config & 32) ? "HI" : "LO", /* trigger on rise/fall edge */ - (config & 64) ? "DEBOUNCE" : "", /* debounce */ - - amp->gpio_get(index), amp->gpio_current(index)); -} - -ssize_t nsc_gpio_write(struct file *file, const char __user *data, - size_t len, loff_t *ppos) -{ - unsigned m = iminor(file->f_dentry->d_inode); - struct nsc_gpio_ops *amp = file->private_data; - struct device *dev = amp->dev; - size_t i; - int err = 0; - - for (i = 0; i < len; ++i) { - char c; - if (get_user(c, data + i)) - return -EFAULT; - switch (c) { - case '0': - amp->gpio_set(m, 0); - break; - case '1': - amp->gpio_set(m, 1); - break; - case 'O': - dev_dbg(dev, "GPIO%d output enabled\n", m); - amp->gpio_config(m, ~1, 1); - break; - case 'o': - dev_dbg(dev, "GPIO%d output disabled\n", m); - amp->gpio_config(m, ~1, 0); - break; - case 'T': - dev_dbg(dev, "GPIO%d output is push pull\n", - m); - amp->gpio_config(m, ~2, 2); - break; - case 't': - dev_dbg(dev, "GPIO%d output is open drain\n", - m); - amp->gpio_config(m, ~2, 0); - break; - case 'P': - dev_dbg(dev, "GPIO%d pull up enabled\n", m); - amp->gpio_config(m, ~4, 4); - break; - case 'p': - dev_dbg(dev, "GPIO%d pull up disabled\n", m); - amp->gpio_config(m, ~4, 0); - break; - case 'v': - /* View Current pin settings */ - amp->gpio_dump(amp, m); - break; - case '\n': - /* end of settings string, do nothing */ - break; - default: - dev_err(dev, "io%2d bad setting: chr<0x%2x>\n", - m, (int)c); - err++; - } - } - if (err) - return -EINVAL; /* full string handled, report error */ - - return len; -} - -ssize_t nsc_gpio_read(struct file *file, char __user * buf, - size_t len, loff_t * ppos) -{ - unsigned m = iminor(file->f_dentry->d_inode); - int value; - struct nsc_gpio_ops *amp = file->private_data; - - value = amp->gpio_get(m); - if (put_user(value ? '1' : '0', buf)) - return -EFAULT; - - return 1; -} - -/* common file-ops routines for both scx200_gpio and pc87360_gpio */ -EXPORT_SYMBOL(nsc_gpio_write); -EXPORT_SYMBOL(nsc_gpio_read); -EXPORT_SYMBOL(nsc_gpio_dump); - -static int __init nsc_gpio_init(void) -{ - printk(KERN_DEBUG NAME " initializing\n"); - return 0; -} - -static void __exit nsc_gpio_cleanup(void) -{ - printk(KERN_DEBUG NAME " cleanup\n"); -} - -module_init(nsc_gpio_init); -module_exit(nsc_gpio_cleanup); - -MODULE_AUTHOR("Jim Cromie "); -MODULE_DESCRIPTION("NatSemi GPIO Common Methods"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/char/pc8736x_gpio.c b/trunk/drivers/char/pc8736x_gpio.c deleted file mode 100644 index 1c706ccfdbb3..000000000000 --- a/trunk/drivers/char/pc8736x_gpio.c +++ /dev/null @@ -1,340 +0,0 @@ -/* linux/drivers/char/pc8736x_gpio.c - - National Semiconductor PC8736x GPIO driver. Allows a user space - process to play with the GPIO pins. - - Copyright (c) 2005 Jim Cromie - - adapted from linux/drivers/char/scx200_gpio.c - Copyright (c) 2001,2002 Christer Weinigel , -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEVNAME "pc8736x_gpio" - -MODULE_AUTHOR("Jim Cromie "); -MODULE_DESCRIPTION("NatSemi PC-8736x GPIO Pin Driver"); -MODULE_LICENSE("GPL"); - -static int major; /* default to dynamic major */ -module_param(major, int, 0); -MODULE_PARM_DESC(major, "Major device number"); - -static DEFINE_MUTEX(pc8736x_gpio_config_lock); -static unsigned pc8736x_gpio_base; -static u8 pc8736x_gpio_shadow[4]; - -#define SIO_BASE1 0x2E /* 1st command-reg to check */ -#define SIO_BASE2 0x4E /* alt command-reg to check */ -#define SIO_BASE_OFFSET 0x20 - -#define SIO_SID 0x20 /* SuperI/O ID Register */ -#define SIO_SID_VALUE 0xe9 /* Expected value in SuperI/O ID Register */ - -#define SIO_CF1 0x21 /* chip config, bit0 is chip enable */ - -#define PC8736X_GPIO_SIZE 16 - -#define SIO_UNIT_SEL 0x7 /* unit select reg */ -#define SIO_UNIT_ACT 0x30 /* unit enable */ -#define SIO_GPIO_UNIT 0x7 /* unit number of GPIO */ -#define SIO_VLM_UNIT 0x0D -#define SIO_TMS_UNIT 0x0E - -/* config-space addrs to read/write each unit's runtime addr */ -#define SIO_BASE_HADDR 0x60 -#define SIO_BASE_LADDR 0x61 - -/* GPIO config-space pin-control addresses */ -#define SIO_GPIO_PIN_SELECT 0xF0 -#define SIO_GPIO_PIN_CONFIG 0xF1 -#define SIO_GPIO_PIN_EVENT 0xF2 - -static unsigned char superio_cmd = 0; -static unsigned char selected_device = 0xFF; /* bogus start val */ - -/* GPIO port runtime access, functionality */ -static int port_offset[] = { 0, 4, 8, 10 }; /* non-uniform offsets ! */ -/* static int event_capable[] = { 1, 1, 0, 0 }; ports 2,3 are hobbled */ - -#define PORT_OUT 0 -#define PORT_IN 1 -#define PORT_EVT_EN 2 -#define PORT_EVT_STST 3 - -static struct platform_device *pdev; /* use in dev_*() */ - -static inline void superio_outb(int addr, int val) -{ - outb_p(addr, superio_cmd); - outb_p(val, superio_cmd + 1); -} - -static inline int superio_inb(int addr) -{ - outb_p(addr, superio_cmd); - return inb_p(superio_cmd + 1); -} - -static int pc8736x_superio_present(void) -{ - /* try the 2 possible values, read a hardware reg to verify */ - superio_cmd = SIO_BASE1; - if (superio_inb(SIO_SID) == SIO_SID_VALUE) - return superio_cmd; - - superio_cmd = SIO_BASE2; - if (superio_inb(SIO_SID) == SIO_SID_VALUE) - return superio_cmd; - - return 0; -} - -static void device_select(unsigned devldn) -{ - superio_outb(SIO_UNIT_SEL, devldn); - selected_device = devldn; -} - -static void select_pin(unsigned iminor) -{ - /* select GPIO port/pin from device minor number */ - device_select(SIO_GPIO_UNIT); - superio_outb(SIO_GPIO_PIN_SELECT, - ((iminor << 1) & 0xF0) | (iminor & 0x7)); -} - -static inline u32 pc8736x_gpio_configure_fn(unsigned index, u32 mask, u32 bits, - u32 func_slct) -{ - u32 config, new_config; - - mutex_lock(&pc8736x_gpio_config_lock); - - device_select(SIO_GPIO_UNIT); - select_pin(index); - - /* read current config value */ - config = superio_inb(func_slct); - - /* set new config */ - new_config = (config & mask) | bits; - superio_outb(func_slct, new_config); - - mutex_unlock(&pc8736x_gpio_config_lock); - - return config; -} - -static u32 pc8736x_gpio_configure(unsigned index, u32 mask, u32 bits) -{ - return pc8736x_gpio_configure_fn(index, mask, bits, - SIO_GPIO_PIN_CONFIG); -} - -static int pc8736x_gpio_get(unsigned minor) -{ - int port, bit, val; - - port = minor >> 3; - bit = minor & 7; - val = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_IN); - val >>= bit; - val &= 1; - - dev_dbg(&pdev->dev, "_gpio_get(%d from %x bit %d) == val %d\n", - minor, pc8736x_gpio_base + port_offset[port] + PORT_IN, bit, - val); - - return val; -} - -static void pc8736x_gpio_set(unsigned minor, int val) -{ - int port, bit, curval; - - minor &= 0x1f; - port = minor >> 3; - bit = minor & 7; - curval = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_OUT); - - dev_dbg(&pdev->dev, "addr:%x cur:%x bit-pos:%d cur-bit:%x + new:%d -> bit-new:%d\n", - pc8736x_gpio_base + port_offset[port] + PORT_OUT, - curval, bit, (curval & ~(1 << bit)), val, (val << bit)); - - val = (curval & ~(1 << bit)) | (val << bit); - - dev_dbg(&pdev->dev, "gpio_set(minor:%d port:%d bit:%d)" - " %2x -> %2x\n", minor, port, bit, curval, val); - - outb_p(val, pc8736x_gpio_base + port_offset[port] + PORT_OUT); - - curval = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_OUT); - val = inb_p(pc8736x_gpio_base + port_offset[port] + PORT_IN); - - dev_dbg(&pdev->dev, "wrote %x, read: %x\n", curval, val); - pc8736x_gpio_shadow[port] = val; -} - -static void pc8736x_gpio_set_high(unsigned index) -{ - pc8736x_gpio_set(index, 1); -} - -static void pc8736x_gpio_set_low(unsigned index) -{ - pc8736x_gpio_set(index, 0); -} - -static int pc8736x_gpio_current(unsigned minor) -{ - int port, bit; - minor &= 0x1f; - port = minor >> 3; - bit = minor & 7; - return ((pc8736x_gpio_shadow[port] >> bit) & 0x01); -} - -static void pc8736x_gpio_change(unsigned index) -{ - pc8736x_gpio_set(index, !pc8736x_gpio_current(index)); -} - -static struct nsc_gpio_ops pc8736x_access = { - .owner = THIS_MODULE, - .gpio_config = pc8736x_gpio_configure, - .gpio_dump = nsc_gpio_dump, - .gpio_get = pc8736x_gpio_get, - .gpio_set = pc8736x_gpio_set, - .gpio_set_high = pc8736x_gpio_set_high, - .gpio_set_low = pc8736x_gpio_set_low, - .gpio_change = pc8736x_gpio_change, - .gpio_current = pc8736x_gpio_current -}; - -static int pc8736x_gpio_open(struct inode *inode, struct file *file) -{ - unsigned m = iminor(inode); - file->private_data = &pc8736x_access; - - dev_dbg(&pdev->dev, "open %d\n", m); - - if (m > 63) - return -EINVAL; - return nonseekable_open(inode, file); -} - -static struct file_operations pc8736x_gpio_fops = { - .owner = THIS_MODULE, - .open = pc8736x_gpio_open, - .write = nsc_gpio_write, - .read = nsc_gpio_read, -}; - -static void __init pc8736x_init_shadow(void) -{ - int port; - - /* read the current values driven on the GPIO signals */ - for (port = 0; port < 4; ++port) - pc8736x_gpio_shadow[port] - = inb_p(pc8736x_gpio_base + port_offset[port] - + PORT_OUT); - -} - -static int __init pc8736x_gpio_init(void) -{ - int rc = 0; - - pdev = platform_device_alloc(DEVNAME, 0); - if (!pdev) - return -ENOMEM; - - rc = platform_device_add(pdev); - if (rc) { - rc = -ENODEV; - goto undo_platform_dev_alloc; - } - dev_info(&pdev->dev, "NatSemi pc8736x GPIO Driver Initializing\n"); - - if (!pc8736x_superio_present()) { - rc = -ENODEV; - dev_err(&pdev->dev, "no device found\n"); - goto undo_platform_dev_add; - } - pc8736x_access.dev = &pdev->dev; - - /* Verify that chip and it's GPIO unit are both enabled. - My BIOS does this, so I take minimum action here - */ - rc = superio_inb(SIO_CF1); - if (!(rc & 0x01)) { - rc = -ENODEV; - dev_err(&pdev->dev, "device not enabled\n"); - goto undo_platform_dev_add; - } - device_select(SIO_GPIO_UNIT); - if (!superio_inb(SIO_UNIT_ACT)) { - rc = -ENODEV; - dev_err(&pdev->dev, "GPIO unit not enabled\n"); - goto undo_platform_dev_add; - } - - /* read the GPIO unit base addr that chip responds to */ - pc8736x_gpio_base = (superio_inb(SIO_BASE_HADDR) << 8 - | superio_inb(SIO_BASE_LADDR)); - - if (!request_region(pc8736x_gpio_base, 16, DEVNAME)) { - rc = -ENODEV; - dev_err(&pdev->dev, "GPIO ioport %x busy\n", - pc8736x_gpio_base); - goto undo_platform_dev_add; - } - dev_info(&pdev->dev, "GPIO ioport %x reserved\n", pc8736x_gpio_base); - - rc = register_chrdev(major, DEVNAME, &pc8736x_gpio_fops); - if (rc < 0) { - dev_err(&pdev->dev, "register-chrdev failed: %d\n", rc); - goto undo_platform_dev_add; - } - if (!major) { - major = rc; - dev_dbg(&pdev->dev, "got dynamic major %d\n", major); - } - - pc8736x_init_shadow(); - return 0; - -undo_platform_dev_add: - platform_device_put(pdev); -undo_platform_dev_alloc: - kfree(pdev); - return rc; -} - -static void __exit pc8736x_gpio_cleanup(void) -{ - dev_dbg(&pdev->dev, " cleanup\n"); - - release_region(pc8736x_gpio_base, 16); - - unregister_chrdev(major, DEVNAME); -} - -EXPORT_SYMBOL(pc8736x_access); - -module_init(pc8736x_gpio_init); -module_exit(pc8736x_gpio_cleanup); diff --git a/trunk/drivers/char/pty.c b/trunk/drivers/char/pty.c index 0c17f61549b4..9b5a2c0e7008 100644 --- a/trunk/drivers/char/pty.c +++ b/trunk/drivers/char/pty.c @@ -101,7 +101,7 @@ static void pty_unthrottle(struct tty_struct * tty) * * FIXME: Our pty_write method is called with our ldisc lock held but * not our partners. We can't just take the other one blindly without - * risking deadlocks. + * risking deadlocks. There is also the small matter of TTY_DONT_FLIP */ static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count) { diff --git a/trunk/drivers/char/scx200_gpio.c b/trunk/drivers/char/scx200_gpio.c index 5a280a330401..664a6e97eb1a 100644 --- a/trunk/drivers/char/scx200_gpio.c +++ b/trunk/drivers/char/scx200_gpio.c @@ -1,4 +1,4 @@ -/* linux/drivers/char/scx200_gpio.c +/* linux/drivers/char/scx200_gpio.c National Semiconductor SCx200 GPIO driver. Allows a user space process to play with the GPIO pins. @@ -6,26 +6,17 @@ Copyright (c) 2001,2002 Christer Weinigel */ #include -#include #include #include #include #include #include -#include #include #include -#include -#include - #include -#include #define NAME "scx200_gpio" -#define DEVNAME NAME - -static struct platform_device *pdev; MODULE_AUTHOR("Christer Weinigel "); MODULE_DESCRIPTION("NatSemi SCx200 GPIO Pin Driver"); @@ -35,23 +26,70 @@ static int major = 0; /* default to dynamic major */ module_param(major, int, 0); MODULE_PARM_DESC(major, "Major device number"); -struct nsc_gpio_ops scx200_access = { - .owner = THIS_MODULE, - .gpio_config = scx200_gpio_configure, - .gpio_dump = nsc_gpio_dump, - .gpio_get = scx200_gpio_get, - .gpio_set = scx200_gpio_set, - .gpio_set_high = scx200_gpio_set_high, - .gpio_set_low = scx200_gpio_set_low, - .gpio_change = scx200_gpio_change, - .gpio_current = scx200_gpio_current -}; +static ssize_t scx200_gpio_write(struct file *file, const char __user *data, + size_t len, loff_t *ppos) +{ + unsigned m = iminor(file->f_dentry->d_inode); + size_t i; + + for (i = 0; i < len; ++i) { + char c; + if (get_user(c, data+i)) + return -EFAULT; + switch (c) + { + case '0': + scx200_gpio_set(m, 0); + break; + case '1': + scx200_gpio_set(m, 1); + break; + case 'O': + printk(KERN_INFO NAME ": GPIO%d output enabled\n", m); + scx200_gpio_configure(m, ~1, 1); + break; + case 'o': + printk(KERN_INFO NAME ": GPIO%d output disabled\n", m); + scx200_gpio_configure(m, ~1, 0); + break; + case 'T': + printk(KERN_INFO NAME ": GPIO%d output is push pull\n", m); + scx200_gpio_configure(m, ~2, 2); + break; + case 't': + printk(KERN_INFO NAME ": GPIO%d output is open drain\n", m); + scx200_gpio_configure(m, ~2, 0); + break; + case 'P': + printk(KERN_INFO NAME ": GPIO%d pull up enabled\n", m); + scx200_gpio_configure(m, ~4, 4); + break; + case 'p': + printk(KERN_INFO NAME ": GPIO%d pull up disabled\n", m); + scx200_gpio_configure(m, ~4, 0); + break; + } + } + + return len; +} + +static ssize_t scx200_gpio_read(struct file *file, char __user *buf, + size_t len, loff_t *ppos) +{ + unsigned m = iminor(file->f_dentry->d_inode); + int value; + + value = scx200_gpio_get(m); + if (put_user(value ? '1' : '0', buf)) + return -EFAULT; + + return 1; +} static int scx200_gpio_open(struct inode *inode, struct file *file) { unsigned m = iminor(inode); - file->private_data = &scx200_access; - if (m > 63) return -EINVAL; return nonseekable_open(inode, file); @@ -65,81 +103,47 @@ static int scx200_gpio_release(struct inode *inode, struct file *file) static struct file_operations scx200_gpio_fops = { .owner = THIS_MODULE, - .write = nsc_gpio_write, - .read = nsc_gpio_read, + .write = scx200_gpio_write, + .read = scx200_gpio_read, .open = scx200_gpio_open, .release = scx200_gpio_release, }; -struct cdev *scx200_devices; -static int num_pins = 32; - static int __init scx200_gpio_init(void) { - int rc, i; - dev_t dev = MKDEV(major, 0); + int r; + + printk(KERN_DEBUG NAME ": NatSemi SCx200 GPIO Driver\n"); if (!scx200_gpio_present()) { - printk(KERN_ERR NAME ": no SCx200 gpio present\n"); + printk(KERN_ERR NAME ": no SCx200 gpio pins available\n"); return -ENODEV; } - /* support dev_dbg() with pdev->dev */ - pdev = platform_device_alloc(DEVNAME, 0); - if (!pdev) - return -ENOMEM; - - rc = platform_device_add(pdev); - if (rc) - goto undo_malloc; - - /* nsc_gpio uses dev_dbg(), so needs this */ - scx200_access.dev = &pdev->dev; - - if (major) - rc = register_chrdev_region(dev, num_pins, "scx200_gpio"); - else { - rc = alloc_chrdev_region(&dev, 0, num_pins, "scx200_gpio"); - major = MAJOR(dev); + r = register_chrdev(major, NAME, &scx200_gpio_fops); + if (r < 0) { + printk(KERN_ERR NAME ": unable to register character device\n"); + return r; } - if (rc < 0) { - dev_err(&pdev->dev, "SCx200 chrdev_region err: %d\n", rc); - goto undo_platform_device_add; + if (!major) { + major = r; + printk(KERN_DEBUG NAME ": got dynamic major %d\n", major); } - scx200_devices = kzalloc(num_pins * sizeof(struct cdev), GFP_KERNEL); - if (!scx200_devices) { - rc = -ENOMEM; - goto undo_chrdev_region; - } - for (i = 0; i < num_pins; i++) { - struct cdev *cdev = &scx200_devices[i]; - cdev_init(cdev, &scx200_gpio_fops); - cdev->owner = THIS_MODULE; - rc = cdev_add(cdev, MKDEV(major, i), 1); - /* tolerate 'minor' errors */ - if (rc) - dev_err(&pdev->dev, "Error %d on minor %d", rc, i); - } - - return 0; /* succeed */ -undo_chrdev_region: - unregister_chrdev_region(dev, num_pins); -undo_platform_device_add: - platform_device_put(pdev); -undo_malloc: - kfree(pdev); - return rc; + return 0; } static void __exit scx200_gpio_cleanup(void) { - kfree(scx200_devices); - unregister_chrdev_region(MKDEV(major, 0), num_pins); - platform_device_put(pdev); - platform_device_unregister(pdev); - /* kfree(pdev); */ + unregister_chrdev(major, NAME); } module_init(scx200_gpio_init); module_exit(scx200_gpio_cleanup); + +/* + Local variables: + compile-command: "make -k -C ../.. SUBDIRS=drivers/char modules" + c-basic-offset: 8 + End: +*/ diff --git a/trunk/drivers/char/specialix.c b/trunk/drivers/char/specialix.c index d2d6b01dcd05..1b5330299e30 100644 --- a/trunk/drivers/char/specialix.c +++ b/trunk/drivers/char/specialix.c @@ -2477,7 +2477,7 @@ static int __init specialix_init(void) #endif for (i = 0; i < SX_NBOARD; i++) - spin_lock_init(&sx_board[i].lock); + sx_board[i].lock = SPIN_LOCK_UNLOCKED; if (sx_init_drivers()) { func_exit(); diff --git a/trunk/drivers/char/stallion.c b/trunk/drivers/char/stallion.c index 00b4a2187164..a9c5a7230f89 100644 --- a/trunk/drivers/char/stallion.c +++ b/trunk/drivers/char/stallion.c @@ -140,6 +140,15 @@ static char *stl_drvversion = "5.6.0"; static struct tty_driver *stl_serial; +/* + * We will need to allocate a temporary write buffer for chars that + * come direct from user space. The problem is that a copy from user + * space might cause a page fault (typically on a system that is + * swapping!). All ports will share one buffer - since if the system + * is already swapping a shared buffer won't make things any worse. + */ +static char *stl_tmpwritebuf; + /* * Define a local default termios struct. All ports will be created * with this termios initially. Basically all it defines is a raw port @@ -353,14 +362,6 @@ static unsigned char stl_vecmap[] = { 0xff, 0xff, 0x00, 0x02, 0x01, 0xff, 0xff, 0x03 }; -/* - * Lock ordering is that you may not take stallion_lock holding - * brd_lock. - */ - -static spinlock_t brd_lock; /* Guard the board mapping */ -static spinlock_t stallion_lock; /* Guard the tty driver */ - /* * Set up enable and disable macros for the ECH boards. They require * the secondary io address space to be activated and deactivated. @@ -724,7 +725,17 @@ static struct class *stallion_class; static int __init stallion_module_init(void) { + unsigned long flags; + +#ifdef DEBUG + printk("init_module()\n"); +#endif + + save_flags(flags); + cli(); stl_init(); + restore_flags(flags); + return 0; } @@ -735,6 +746,7 @@ static void __exit stallion_module_exit(void) stlbrd_t *brdp; stlpanel_t *panelp; stlport_t *portp; + unsigned long flags; int i, j, k; #ifdef DEBUG @@ -744,6 +756,9 @@ static void __exit stallion_module_exit(void) printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, stl_drvversion); + save_flags(flags); + cli(); + /* * Free up all allocated resources used by the ports. This includes * memory and interrupts. As part of this process we will also do @@ -755,6 +770,7 @@ static void __exit stallion_module_exit(void) if (i) { printk("STALLION: failed to un-register tty driver, " "errno=%d\n", -i); + restore_flags(flags); return; } for (i = 0; i < 4; i++) { @@ -767,6 +783,8 @@ static void __exit stallion_module_exit(void) "errno=%d\n", -i); class_destroy(stallion_class); + kfree(stl_tmpwritebuf); + for (i = 0; (i < stl_nrbrds); i++) { if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) continue; @@ -796,6 +814,8 @@ static void __exit stallion_module_exit(void) kfree(brdp); stl_brds[i] = (stlbrd_t *) NULL; } + + restore_flags(flags); } module_init(stallion_module_init); @@ -928,7 +948,7 @@ static stlbrd_t *stl_allocbrd(void) brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); if (!brdp) { - printk("STALLION: failed to allocate memory (size=%Zd)\n", + printk("STALLION: failed to allocate memory (size=%d)\n", sizeof(stlbrd_t)); return NULL; } @@ -1046,17 +1066,16 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) rc = 0; doclocal = 0; - spin_lock_irqsave(&stallion_lock, flags); - if (portp->tty->termios->c_cflag & CLOCAL) doclocal++; + save_flags(flags); + cli(); portp->openwaitcnt++; if (! tty_hung_up_p(filp)) portp->refcount--; for (;;) { - /* Takes brd_lock internally */ stl_setsignals(portp, 1, 1); if (tty_hung_up_p(filp) || ((portp->flags & ASYNC_INITIALIZED) == 0)) { @@ -1074,14 +1093,13 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) rc = -ERESTARTSYS; break; } - /* FIXME */ interruptible_sleep_on(&portp->open_wait); } if (! tty_hung_up_p(filp)) portp->refcount++; portp->openwaitcnt--; - spin_unlock_irqrestore(&stallion_lock, flags); + restore_flags(flags); return rc; } @@ -1101,15 +1119,16 @@ static void stl_close(struct tty_struct *tty, struct file *filp) if (portp == (stlport_t *) NULL) return; - spin_lock_irqsave(&stallion_lock, flags); + save_flags(flags); + cli(); if (tty_hung_up_p(filp)) { - spin_unlock_irqrestore(&stallion_lock, flags); + restore_flags(flags); return; } if ((tty->count == 1) && (portp->refcount != 1)) portp->refcount = 1; if (portp->refcount-- > 1) { - spin_unlock_irqrestore(&stallion_lock, flags); + restore_flags(flags); return; } @@ -1123,18 +1142,11 @@ static void stl_close(struct tty_struct *tty, struct file *filp) * (The sc26198 has no "end-of-data" interrupt only empty FIFO) */ tty->closing = 1; - - spin_unlock_irqrestore(&stallion_lock, flags); - if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) tty_wait_until_sent(tty, portp->closing_wait); stl_waituntilsent(tty, (HZ / 2)); - - spin_lock_irqsave(&stallion_lock, flags); portp->flags &= ~ASYNC_INITIALIZED; - spin_unlock_irqrestore(&stallion_lock, flags); - stl_disableintrs(portp); if (tty->termios->c_cflag & HUPCL) stl_setsignals(portp, 0, 0); @@ -1161,6 +1173,7 @@ static void stl_close(struct tty_struct *tty, struct file *filp) portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); wake_up_interruptible(&portp->close_wait); + restore_flags(flags); } /*****************************************************************************/ @@ -1182,6 +1195,9 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count (int) tty, (int) buf, count); #endif + if ((tty == (struct tty_struct *) NULL) || + (stl_tmpwritebuf == (char *) NULL)) + return 0; portp = tty->driver_data; if (portp == (stlport_t *) NULL) return 0; @@ -1286,6 +1302,11 @@ static void stl_flushchars(struct tty_struct *tty) if (portp->tx.buf == (char *) NULL) return; +#if 0 + if (tty->stopped || tty->hw_stopped || + (portp->tx.head == portp->tx.tail)) + return; +#endif stl_startrxtx(portp, -1, 1); } @@ -1956,14 +1977,12 @@ static int stl_eiointr(stlbrd_t *brdp) unsigned int iobase; int handled = 0; - spin_lock(&brd_lock); panelp = brdp->panels[0]; iobase = panelp->iobase; while (inb(brdp->iostatus) & EIO_INTRPEND) { handled = 1; (* panelp->isr)(panelp, iobase); } - spin_unlock(&brd_lock); return handled; } @@ -2149,7 +2168,7 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); if (!portp) { printk("STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(stlport_t)); + "(size=%d)\n", sizeof(stlport_t)); break; } @@ -2285,7 +2304,7 @@ static inline int stl_initeio(stlbrd_t *brdp) panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); if (!panelp) { printk(KERN_WARNING "STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(stlpanel_t)); + "(size=%d)\n", sizeof(stlpanel_t)); return -ENOMEM; } @@ -2459,7 +2478,7 @@ static inline int stl_initech(stlbrd_t *brdp) panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); if (!panelp) { printk("STALLION: failed to allocate memory " - "(size=%Zd)\n", sizeof(stlpanel_t)); + "(size=%d)\n", sizeof(stlpanel_t)); break; } panelp->magic = STL_PANELMAGIC; @@ -2860,7 +2879,8 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) portp->stats.lflags = 0; portp->stats.rxbuffered = 0; - spin_lock_irqsave(&stallion_lock, flags); + save_flags(flags); + cli(); if (portp->tty != (struct tty_struct *) NULL) { if (portp->tty->driver_data == portp) { portp->stats.ttystate = portp->tty->flags; @@ -2874,7 +2894,7 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) } } } - spin_unlock_irqrestore(&stallion_lock, flags); + restore_flags(flags); head = portp->tx.head; tail = portp->tx.tail; @@ -3029,15 +3049,20 @@ static int __init stl_init(void) int i; printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); - spin_lock_init(&stallion_lock); - spin_lock_init(&brd_lock); - stl_initbrds(); stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); if (!stl_serial) return -1; +/* + * Allocate a temporary write buffer. + */ + stl_tmpwritebuf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); + if (!stl_tmpwritebuf) + printk("STALLION: failed to allocate memory (size=%d)\n", + STL_TXBUFSIZE); + /* * Set up a character driver for per board stuff. This is mainly used * to do stats ioctls on the ports. @@ -3122,13 +3147,11 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) unsigned int gfrcr; int chipmask, i, j; int nrchips, uartaddr, ioaddr; - unsigned long flags; #ifdef DEBUG printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); #endif - spin_lock_irqsave(&brd_lock, flags); BRDENABLE(panelp->brdnr, panelp->pagenr); /* @@ -3166,7 +3189,6 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) } BRDDISABLE(panelp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); return chipmask; } @@ -3178,7 +3200,6 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) { - unsigned long flags; #ifdef DEBUG printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", (int) brdp, (int) panelp, (int) portp); @@ -3188,7 +3209,6 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po (portp == (stlport_t *) NULL)) return; - spin_lock_irqsave(&brd_lock, flags); portp->ioaddr = panelp->iobase + (((brdp->brdtype == BRD_ECHPCI) || (portp->portnr < 8)) ? 0 : EREG_BANKSIZE); portp->uartaddr = (portp->portnr & 0x04) << 5; @@ -3199,7 +3219,6 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po stl_cd1400setreg(portp, LIVR, (portp->portnr << 3)); portp->hwid = stl_cd1400getreg(portp, GFRCR); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); } /*****************************************************************************/ @@ -3409,7 +3428,8 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x3)); srer = stl_cd1400getreg(portp, SRER); @@ -3446,7 +3466,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) portp->sigs &= ~TIOCM_CD; stl_cd1400setreg(portp, SRER, ((srer & ~sreroff) | sreron)); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3472,7 +3492,8 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) if (rts > 0) msvr2 = MSVR2_RTS; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); if (rts >= 0) @@ -3480,7 +3501,7 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) if (dtr >= 0) stl_cd1400setreg(portp, MSVR1, msvr1); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3499,13 +3520,14 @@ static int stl_cd1400getsignals(stlport_t *portp) printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); msvr1 = stl_cd1400getreg(portp, MSVR1); msvr2 = stl_cd1400getreg(portp, MSVR2); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); sigs = 0; sigs |= (msvr1 & MSVR1_DCD) ? TIOCM_CD : 0; @@ -3547,14 +3569,15 @@ static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx) else if (rx > 0) ccr |= CCR_RXENABLE; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); stl_cd1400ccrwait(portp); stl_cd1400setreg(portp, CCR, ccr); stl_cd1400ccrwait(portp); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3586,7 +3609,8 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) else if (rx > 0) sreron |= SRER_RXDATA; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); stl_cd1400setreg(portp, SRER, @@ -3594,7 +3618,7 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) BRDDISABLE(portp->brdnr); if (tx > 0) set_bit(ASYI_TXBUSY, &portp->istate); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3610,12 +3634,13 @@ static void stl_cd1400disableintrs(stlport_t *portp) #ifdef DEBUG printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); stl_cd1400setreg(portp, SRER, 0); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3628,7 +3653,8 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); stl_cd1400setreg(portp, SRER, @@ -3638,7 +3664,7 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) portp->brklen = len; if (len == 1) portp->stats.txbreaks++; - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3662,7 +3688,8 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) if (tty == (struct tty_struct *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); @@ -3702,7 +3729,7 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) } BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3726,7 +3753,8 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) if (tty == (struct tty_struct *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); if (state) { @@ -3741,7 +3769,7 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) stl_cd1400ccrwait(portp); } BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3757,7 +3785,8 @@ static void stl_cd1400flush(stlport_t *portp) if (portp == (stlport_t *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); stl_cd1400ccrwait(portp); @@ -3765,7 +3794,7 @@ static void stl_cd1400flush(stlport_t *portp) stl_cd1400ccrwait(portp); portp->tx.tail = portp->tx.head; BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -3804,7 +3833,6 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) (int) panelp, iobase); #endif - spin_lock(&brd_lock); outb(SVRR, iobase); svrtype = inb(iobase + EREG_DATA); if (panelp->nrports > 4) { @@ -3818,8 +3846,6 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) stl_cd1400txisr(panelp, iobase); else if (svrtype & SVRR_MDM) stl_cd1400mdmisr(panelp, iobase); - - spin_unlock(&brd_lock); } /*****************************************************************************/ @@ -4407,7 +4433,8 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_sc26198setreg(portp, IMR, 0); stl_sc26198updatereg(portp, MR0, mr0); @@ -4434,7 +4461,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) portp->imr = (portp->imr & ~imroff) | imron; stl_sc26198setreg(portp, IMR, portp->imr); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4464,12 +4491,13 @@ static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts) else if (rts > 0) iopioron |= IPR_RTS; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_sc26198setreg(portp, IOPIOR, ((stl_sc26198getreg(portp, IOPIOR) & ~iopioroff) | iopioron)); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4488,11 +4516,12 @@ static int stl_sc26198getsignals(stlport_t *portp) printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); ipr = stl_sc26198getreg(portp, IPR); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); sigs = 0; sigs |= (ipr & IPR_DCD) ? 0 : TIOCM_CD; @@ -4529,12 +4558,13 @@ static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx) else if (rx > 0) ccr |= CR_RXENABLE; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_sc26198setreg(portp, SCCR, ccr); BRDDISABLE(portp->brdnr); portp->crenable = ccr; - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4563,14 +4593,15 @@ static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx) else if (rx > 0) imr |= IR_RXRDY | IR_RXBREAK | IR_RXWATCHDOG; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_sc26198setreg(portp, IMR, imr); BRDDISABLE(portp->brdnr); portp->imr = imr; if (tx > 0) set_bit(ASYI_TXBUSY, &portp->istate); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4587,12 +4618,13 @@ static void stl_sc26198disableintrs(stlport_t *portp) printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); portp->imr = 0; stl_sc26198setreg(portp, IMR, 0); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4605,7 +4637,8 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); #endif - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); if (len == 1) { stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); @@ -4614,7 +4647,7 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); } BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4639,7 +4672,8 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) if (tty == (struct tty_struct *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); if (state) { @@ -4685,7 +4719,7 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) } BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4710,7 +4744,8 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) if (tty == (struct tty_struct *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); if (state) { mr0 = stl_sc26198getreg(portp, MR0); @@ -4730,7 +4765,7 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) stl_sc26198setreg(portp, MR0, mr0); } BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4746,13 +4781,14 @@ static void stl_sc26198flush(stlport_t *portp) if (portp == (stlport_t *) NULL) return; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); stl_sc26198setreg(portp, SCCR, CR_TXRESET); stl_sc26198setreg(portp, SCCR, portp->crenable); BRDDISABLE(portp->brdnr); portp->tx.tail = portp->tx.head; - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); } /*****************************************************************************/ @@ -4779,11 +4815,12 @@ static int stl_sc26198datastate(stlport_t *portp) if (test_bit(ASYI_TXBUSY, &portp->istate)) return 1; - spin_lock_irqsave(&brd_lock, flags); + save_flags(flags); + cli(); BRDENABLE(portp->brdnr, portp->pagenr); sr = stl_sc26198getreg(portp, SR); BRDDISABLE(portp->brdnr); - spin_unlock_irqrestore(&brd_lock, flags); + restore_flags(flags); return (sr & SR_TXEMPTY) ? 0 : 1; } @@ -4841,8 +4878,6 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) stlport_t *portp; unsigned int iack; - spin_lock(&brd_lock); - /* * Work around bug in sc26198 chip... Cannot have A6 address * line of UART high, else iack will be returned as 0. @@ -4858,8 +4893,6 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) stl_sc26198txisr(portp); else stl_sc26198otherisr(portp, iack); - - spin_unlock(&brd_lock); } /*****************************************************************************/ diff --git a/trunk/drivers/char/sx.c b/trunk/drivers/char/sx.c index 76b9107f7f81..3b4747230270 100644 --- a/trunk/drivers/char/sx.c +++ b/trunk/drivers/char/sx.c @@ -2320,7 +2320,7 @@ static int sx_init_portstructs (int nboards, int nports) #ifdef NEW_WRITE_LOCKING port->gs.port_write_mutex = MUTEX; #endif - spin_lock_init(&port->gs.driver_lock); + port->gs.driver_lock = SPIN_LOCK_UNLOCKED; /* * Initializing wait queue */ diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 8d19f7281f0b..8b2a59969868 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -267,6 +267,7 @@ static struct tty_buffer *tty_buffer_alloc(size_t size) p->used = 0; p->size = size; p->next = NULL; + p->active = 0; p->commit = 0; p->read = 0; p->char_buf_ptr = (char *)(p->data); @@ -326,9 +327,10 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) /* OPTIMISATION: We could keep a per tty "zero" sized buffer to remove this conditional if its worth it. This would be invisible to the callers */ - if ((b = tty->buf.tail) != NULL) + if ((b = tty->buf.tail) != NULL) { left = b->size - b->used; - else + b->active = 1; + } else left = 0; if (left < size) { @@ -336,10 +338,12 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) if ((n = tty_buffer_find(tty, size)) != NULL) { if (b != NULL) { b->next = n; + b->active = 0; b->commit = b->used; } else tty->buf.head = n; tty->buf.tail = n; + n->active = 1; } else size = left; } @@ -400,8 +404,10 @@ void tty_schedule_flip(struct tty_struct *tty) { unsigned long flags; spin_lock_irqsave(&tty->buf.lock, flags); - if (tty->buf.tail != NULL) + if (tty->buf.tail != NULL) { + tty->buf.tail->active = 0; tty->buf.tail->commit = tty->buf.tail->used; + } spin_unlock_irqrestore(&tty->buf.lock, flags); schedule_delayed_work(&tty->buf.work, 1); } @@ -778,8 +784,11 @@ static int tty_set_ldisc(struct tty_struct *tty, int ldisc) } clear_bit(TTY_LDISC, &tty->flags); - if (o_tty) + clear_bit(TTY_DONT_FLIP, &tty->flags); + if (o_tty) { clear_bit(TTY_LDISC, &o_tty->flags); + clear_bit(TTY_DONT_FLIP, &o_tty->flags); + } spin_unlock_irqrestore(&tty_ldisc_lock, flags); /* @@ -1946,6 +1955,7 @@ static void release_dev(struct file * filp) * race with the set_ldisc code path. */ clear_bit(TTY_LDISC, &tty->flags); + clear_bit(TTY_DONT_FLIP, &tty->flags); cancel_delayed_work(&tty->buf.work); /* @@ -2611,9 +2621,10 @@ int tty_ioctl(struct inode * inode, struct file * file, tty->driver->break_ctl(tty, 0); return 0; case TCSBRK: /* SVID version: non-zero arg --> no break */ - /* non-zero arg means wait for all output data - * to be sent (performed above) but don't send break. - * This is used by the tcdrain() termios function. + /* + * XXX is the above comment correct, or the + * code below correct? Is this ioctl used at + * all by anyone? */ if (!arg) return send_break(tty, 250); @@ -2765,7 +2776,8 @@ static void flush_to_ldisc(void *private_) struct tty_struct *tty = (struct tty_struct *) private_; unsigned long flags; struct tty_ldisc *disc; - struct tty_buffer *tbuf, *head; + struct tty_buffer *tbuf; + int count; char *char_buf; unsigned char *flag_buf; @@ -2773,37 +2785,32 @@ static void flush_to_ldisc(void *private_) if (disc == NULL) /* !TTY_LDISC */ return; + if (test_bit(TTY_DONT_FLIP, &tty->flags)) { + /* + * Do it after the next timer tick: + */ + schedule_delayed_work(&tty->buf.work, 1); + goto out; + } spin_lock_irqsave(&tty->buf.lock, flags); - head = tty->buf.head; - if (head != NULL) { - tty->buf.head = NULL; - for (;;) { - int count = head->commit - head->read; - if (!count) { - if (head->next == NULL) - break; - tbuf = head; - head = head->next; - tty_buffer_free(tty, tbuf); - continue; - } - if (!tty->receive_room) { - schedule_delayed_work(&tty->buf.work, 1); - break; - } - if (count > tty->receive_room) - count = tty->receive_room; - char_buf = head->char_buf_ptr + head->read; - flag_buf = head->flag_buf_ptr + head->read; - head->read += count; + while((tbuf = tty->buf.head) != NULL) { + while ((count = tbuf->commit - tbuf->read) != 0) { + char_buf = tbuf->char_buf_ptr + tbuf->read; + flag_buf = tbuf->flag_buf_ptr + tbuf->read; + tbuf->read += count; spin_unlock_irqrestore(&tty->buf.lock, flags); disc->receive_buf(tty, char_buf, flag_buf, count); spin_lock_irqsave(&tty->buf.lock, flags); } - tty->buf.head = head; + if (tbuf->active) + break; + tty->buf.head = tbuf->next; + if (tty->buf.head == NULL) + tty->buf.tail = NULL; + tty_buffer_free(tty, tbuf); } spin_unlock_irqrestore(&tty->buf.lock, flags); - +out: tty_ldisc_deref(disc); } @@ -2896,8 +2903,10 @@ void tty_flip_buffer_push(struct tty_struct *tty) { unsigned long flags; spin_lock_irqsave(&tty->buf.lock, flags); - if (tty->buf.tail != NULL) + if (tty->buf.tail != NULL) { + tty->buf.tail->active = 0; tty->buf.tail->commit = tty->buf.tail->used; + } spin_unlock_irqrestore(&tty->buf.lock, flags); if (tty->low_latency) diff --git a/trunk/drivers/char/vr41xx_giu.c b/trunk/drivers/char/vr41xx_giu.c index 073da48c092e..05e6e814d86f 100644 --- a/trunk/drivers/char/vr41xx_giu.c +++ b/trunk/drivers/char/vr41xx_giu.c @@ -689,9 +689,9 @@ static int __devinit giu_probe(struct platform_device *dev) for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { if (i < GIU_IRQ(GIUINT_HIGH_OFFSET)) - irq_desc[i].chip = &giuint_low_irq_type; + irq_desc[i].handler = &giuint_low_irq_type; else - irq_desc[i].chip = &giuint_high_irq_type; + irq_desc[i].handler = &giuint_high_irq_type; } return cascade_irq(GIUINT_IRQ, giu_get_irq); diff --git a/trunk/drivers/char/watchdog/at91_wdt.c b/trunk/drivers/char/watchdog/at91_wdt.c index 00080655533d..ac83bc4b019a 100644 --- a/trunk/drivers/char/watchdog/at91_wdt.c +++ b/trunk/drivers/char/watchdog/at91_wdt.c @@ -17,15 +17,14 @@ #include #include #include -#include #include #include #include #include -#define WDT_DEFAULT_TIME 5 /* seconds */ -#define WDT_MAX_TIME 256 /* seconds */ +#define WDT_DEFAULT_TIME 5 /* 5 seconds */ +#define WDT_MAX_TIME 256 /* 256 seconds */ static int wdt_time = WDT_DEFAULT_TIME; static int nowayout = WATCHDOG_NOWAYOUT; @@ -33,10 +32,8 @@ static int nowayout = WATCHDOG_NOWAYOUT; module_param(wdt_time, int, 0); MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); -#ifdef CONFIG_WATCHDOG_NOWAYOUT module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); -#endif static unsigned long at91wdt_busy; @@ -141,7 +138,7 @@ static int at91_wdt_ioctl(struct inode *inode, struct file *file, case WDIOC_SETTIMEOUT: if (get_user(new_value, p)) return -EFAULT; - + if (at91_wdt_settimeout(new_value)) return -EINVAL; @@ -199,84 +196,27 @@ static struct miscdevice at91wdt_miscdev = { .fops = &at91wdt_fops, }; -static int __init at91wdt_probe(struct platform_device *pdev) +static int __init at91_wdt_init(void) { int res; - if (at91wdt_miscdev.dev) - return -EBUSY; - at91wdt_miscdev.dev = &pdev->dev; + /* Check that the heartbeat value is within range; if not reset to the default */ + if (at91_wdt_settimeout(wdt_time)) { + at91_wdt_settimeout(WDT_DEFAULT_TIME); + printk(KERN_INFO "at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); + } res = misc_register(&at91wdt_miscdev); if (res) return res; - printk("AT91 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); + printk("AT91 Watchdog Timer enabled (%d seconds, nowayout=%d)\n", wdt_time, nowayout); return 0; } -static int __exit at91wdt_remove(struct platform_device *pdev) -{ - int res; - - res = misc_deregister(&at91wdt_miscdev); - if (!res) - at91wdt_miscdev.dev = NULL; - - return res; -} - -static void at91wdt_shutdown(struct platform_device *pdev) -{ - at91_wdt_stop(); -} - -#ifdef CONFIG_PM - -static int at91wdt_suspend(struct platform_device *pdev, pm_message_t message) -{ - at91_wdt_stop(); - return 0; -} - -static int at91wdt_resume(struct platform_device *pdev) -{ - if (at91wdt_busy) - at91_wdt_start(); - return 0; -} - -#else -#define at91wdt_suspend NULL -#define at91wdt_resume NULL -#endif - -static struct platform_driver at91wdt_driver = { - .probe = at91wdt_probe, - .remove = __exit_p(at91wdt_remove), - .shutdown = at91wdt_shutdown, - .suspend = at91wdt_suspend, - .resume = at91wdt_resume, - .driver = { - .name = "at91_wdt", - .owner = THIS_MODULE, - }, -}; - -static int __init at91_wdt_init(void) -{ - /* Check that the heartbeat value is within range; if not reset to the default */ - if (at91_wdt_settimeout(wdt_time)) { - at91_wdt_settimeout(WDT_DEFAULT_TIME); - pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); - } - - return platform_driver_register(&at91wdt_driver); -} - static void __exit at91_wdt_exit(void) { - platform_driver_unregister(&at91wdt_driver); + misc_deregister(&at91wdt_miscdev); } module_init(at91_wdt_init); diff --git a/trunk/drivers/char/watchdog/i8xx_tco.c b/trunk/drivers/char/watchdog/i8xx_tco.c index bfbdbbf3c2f2..fa2ba9ebe42a 100644 --- a/trunk/drivers/char/watchdog/i8xx_tco.c +++ b/trunk/drivers/char/watchdog/i8xx_tco.c @@ -205,23 +205,6 @@ static int tco_timer_set_heartbeat (int t) return 0; } -static int tco_timer_get_timeleft (int *time_left) -{ - unsigned char val; - - spin_lock(&tco_lock); - - /* read the TCO Timer */ - val = inb (TCO1_RLD); - val &= 0x3f; - - spin_unlock(&tco_lock); - - *time_left = (int)((val * 6) / 10); - - return 0; -} - /* * /dev/watchdog handling */ @@ -289,7 +272,6 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file, { int new_options, retval = -EINVAL; int new_heartbeat; - int time_left; void __user *argp = (void __user *)arg; int __user *p = argp; static struct watchdog_info ident = { @@ -338,7 +320,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file, return -EFAULT; if (tco_timer_set_heartbeat(new_heartbeat)) - return -EINVAL; + return -EINVAL; tco_timer_keepalive (); /* Fall */ @@ -347,14 +329,6 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file, case WDIOC_GETTIMEOUT: return put_user(heartbeat, p); - case WDIOC_GETTIMELEFT: - { - if (tco_timer_get_timeleft(&time_left)) - return -EINVAL; - - return put_user(time_left, p); - } - default: return -ENOIOCTLCMD; } diff --git a/trunk/drivers/char/watchdog/pcwd_pci.c b/trunk/drivers/char/watchdog/pcwd_pci.c index 1f40ecefbf72..2451edbefece 100644 --- a/trunk/drivers/char/watchdog/pcwd_pci.c +++ b/trunk/drivers/char/watchdog/pcwd_pci.c @@ -21,7 +21,7 @@ */ /* - * A bells and whistles driver is available from: + * A bells and whistles driver is available from: * http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/ * * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ @@ -390,24 +390,6 @@ static int pcipcwd_get_temperature(int *temperature) return 0; } -static int pcipcwd_get_timeleft(int *time_left) -{ - int msb; - int lsb; - - /* Read the time that's left before rebooting */ - /* Note: if the board is not yet armed then we will read 0xFFFF */ - send_command(CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb); - - *time_left = (msb << 8) + lsb; - - if (debug >= VERBOSE) - printk(KERN_DEBUG PFX "Time left before next reboot: %d\n", - *time_left); - - return 0; -} - /* * /dev/watchdog handling */ @@ -530,16 +512,6 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file, case WDIOC_GETTIMEOUT: return put_user(heartbeat, p); - case WDIOC_GETTIMELEFT: - { - int time_left; - - if (pcipcwd_get_timeleft(&time_left)) - return -EFAULT; - - return put_user(time_left, p); - } - default: return -ENOIOCTLCMD; } diff --git a/trunk/drivers/char/watchdog/pcwd_usb.c b/trunk/drivers/char/watchdog/pcwd_usb.c index 0d072bed501d..3fdfda9324fa 100644 --- a/trunk/drivers/char/watchdog/pcwd_usb.c +++ b/trunk/drivers/char/watchdog/pcwd_usb.c @@ -317,19 +317,6 @@ static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd, int *temp return 0; } -static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd, int *time_left) -{ - unsigned char msb, lsb; - - /* Read the time that's left before rebooting */ - /* Note: if the board is not yet armed then we will read 0xFFFF */ - usb_pcwd_send_command(usb_pcwd, CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb); - - *time_left = (msb << 8) + lsb; - - return 0; -} - /* * /dev/watchdog handling */ @@ -435,16 +422,6 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file, case WDIOC_GETTIMEOUT: return put_user(heartbeat, p); - case WDIOC_GETTIMELEFT: - { - int time_left; - - if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left)) - return -EFAULT; - - return put_user(time_left, p); - } - default: return -ENOIOCTLCMD; } diff --git a/trunk/drivers/cpufreq/cpufreq.c b/trunk/drivers/cpufreq/cpufreq.c index 35e0b9ceecf7..44d1eca83a72 100644 --- a/trunk/drivers/cpufreq/cpufreq.c +++ b/trunk/drivers/cpufreq/cpufreq.c @@ -1497,7 +1497,6 @@ int cpufreq_update_policy(unsigned int cpu) } EXPORT_SYMBOL(cpufreq_update_policy); -#ifdef CONFIG_HOTPLUG_CPU static int cpufreq_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -1533,11 +1532,10 @@ static int cpufreq_cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata cpufreq_cpu_notifier = +static struct notifier_block cpufreq_cpu_notifier = { .notifier_call = cpufreq_cpu_callback, }; -#endif /* CONFIG_HOTPLUG_CPU */ /********************************************************************* * REGISTER / UNREGISTER CPUFREQ DRIVER * @@ -1598,7 +1596,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data) } if (!ret) { - register_hotcpu_notifier(&cpufreq_cpu_notifier); + register_cpu_notifier(&cpufreq_cpu_notifier); dprintk("driver %s up and running\n", driver_data->name); cpufreq_debug_enable_ratelimit(); } @@ -1630,7 +1628,7 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver) dprintk("unregistering driver %s\n", driver->name); sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver); - unregister_hotcpu_notifier(&cpufreq_cpu_notifier); + unregister_cpu_notifier(&cpufreq_cpu_notifier); spin_lock_irqsave(&cpufreq_driver_lock, flags); cpufreq_driver = NULL; diff --git a/trunk/drivers/cpufreq/cpufreq_stats.c b/trunk/drivers/cpufreq/cpufreq_stats.c index 145061b8472a..c576c0b3f452 100644 --- a/trunk/drivers/cpufreq/cpufreq_stats.c +++ b/trunk/drivers/cpufreq/cpufreq_stats.c @@ -350,7 +350,7 @@ __init cpufreq_stats_init(void) return ret; } - register_hotcpu_notifier(&cpufreq_stat_cpu_notifier); + register_cpu_notifier(&cpufreq_stat_cpu_notifier); lock_cpu_hotplug(); for_each_online_cpu(cpu) { cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_ONLINE, @@ -368,7 +368,7 @@ __exit cpufreq_stats_exit(void) CPUFREQ_POLICY_NOTIFIER); cpufreq_unregister_notifier(¬ifier_trans_block, CPUFREQ_TRANSITION_NOTIFIER); - unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier); + unregister_cpu_notifier(&cpufreq_stat_cpu_notifier); lock_cpu_hotplug(); for_each_online_cpu(cpu) { cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_DEAD, diff --git a/trunk/drivers/i2c/busses/i2c-i801.c b/trunk/drivers/i2c/busses/i2c-i801.c index 8b46ef7d9ff8..3e0d04d5a800 100644 --- a/trunk/drivers/i2c/busses/i2c-i801.c +++ b/trunk/drivers/i2c/busses/i2c-i801.c @@ -488,7 +488,7 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id dev_err(&dev->dev, "SMBus base address uninitialized, " "upgrade BIOS\n"); err = -ENODEV; - goto exit; + goto exit_disable; } err = pci_request_region(dev, SMBBAR, i801_driver.name); @@ -496,7 +496,7 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id dev_err(&dev->dev, "Failed to request SMBus region " "0x%lx-0x%lx\n", i801_smba, pci_resource_end(dev, SMBBAR)); - goto exit; + goto exit_disable; } pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); @@ -520,12 +520,11 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id err = i2c_add_adapter(&i801_adapter); if (err) { dev_err(&dev->dev, "Failed to add SMBus adapter\n"); - goto exit_release; + goto exit_disable; } - return 0; -exit_release: - pci_release_region(dev, SMBBAR); +exit_disable: + pci_disable_device(dev); exit: return err; } @@ -534,10 +533,7 @@ static void __devexit i801_remove(struct pci_dev *dev) { i2c_del_adapter(&i801_adapter); pci_release_region(dev, SMBBAR); - /* - * do not call pci_disable_device(dev) since it can cause hard hangs on - * some systems during power-off (eg. Fujitsu-Siemens Lifebook E8010) - */ + pci_disable_device(dev); } static struct pci_driver i801_driver = { diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index 26ceab1e90bb..935cb2583770 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -505,7 +505,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 } } - if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0) + if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ) try_to_flush_leftover_data(drive); if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) diff --git a/trunk/drivers/ide/ide-iops.c b/trunk/drivers/ide/ide-iops.c index 32117f0ec5c0..97a49e77a8f1 100644 --- a/trunk/drivers/ide/ide-iops.c +++ b/trunk/drivers/ide/ide-iops.c @@ -597,10 +597,6 @@ u8 eighty_ninty_three (ide_drive_t *drive) { if(HWIF(drive)->udma_four == 0) return 0; - - /* Check for SATA but only if we are ATA5 or higher */ - if (drive->id->hw_config == 0 && (drive->id->major_rev_num & 0x7FE0)) - return 1; if (!(drive->id->hw_config & 0x6000)) return 0; #ifndef CONFIG_IDEDMA_IVB diff --git a/trunk/drivers/ide/pci/aec62xx.c b/trunk/drivers/ide/pci/aec62xx.c index ff0cdc142f17..c743e68c33aa 100644 --- a/trunk/drivers/ide/pci/aec62xx.c +++ b/trunk/drivers/ide/pci/aec62xx.c @@ -22,7 +22,7 @@ struct chipset_bus_clock_list_entry { u8 ultra_settings; }; -static const struct chipset_bus_clock_list_entry aec6xxx_33_base [] = { +static struct chipset_bus_clock_list_entry aec6xxx_33_base [] = { { XFER_UDMA_6, 0x31, 0x07 }, { XFER_UDMA_5, 0x31, 0x06 }, { XFER_UDMA_4, 0x31, 0x05 }, @@ -42,7 +42,7 @@ static const struct chipset_bus_clock_list_entry aec6xxx_33_base [] = { { 0, 0x00, 0x00 } }; -static const struct chipset_bus_clock_list_entry aec6xxx_34_base [] = { +static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = { { XFER_UDMA_6, 0x41, 0x06 }, { XFER_UDMA_5, 0x41, 0x05 }, { XFER_UDMA_4, 0x41, 0x04 }, @@ -425,12 +425,12 @@ static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_devi return d->init_setup(dev, d); } -static const struct pci_device_id aec62xx_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF), 0 }, - { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860), 1 }, - { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R), 2 }, - { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865), 3 }, - { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R), 4 }, +static struct pci_device_id aec62xx_pci_tbl[] = { + { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, + { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, + { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, + { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, aec62xx_pci_tbl); diff --git a/trunk/drivers/ide/pci/amd74xx.c b/trunk/drivers/ide/pci/amd74xx.c index 85007cb12c52..6e9dbf4d8077 100644 --- a/trunk/drivers/ide/pci/amd74xx.c +++ b/trunk/drivers/ide/pci/amd74xx.c @@ -75,7 +75,6 @@ static struct amd_ide_chip { { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, 0x50, AMD_UDMA_133 }, - { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_AMD_CS5536_IDE, 0x40, AMD_UDMA_100 }, { 0 } }; @@ -491,8 +490,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), /* 17 */ DECLARE_NV_DEV("NFORCE-MCP61"), - /* 18 */ DECLARE_NV_DEV("NFORCE-MCP65"), - /* 19 */ DECLARE_AMD_DEV("AMD5536"), + /* 18 */ DECLARE_AMD_DEV("AMD5536"), }; static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) @@ -530,8 +528,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = { { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17 }, - { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 19 }, + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); diff --git a/trunk/drivers/ide/pci/cmd64x.c b/trunk/drivers/ide/pci/cmd64x.c index 92b7b1549b16..3d9c7afc8695 100644 --- a/trunk/drivers/ide/pci/cmd64x.c +++ b/trunk/drivers/ide/pci/cmd64x.c @@ -189,6 +189,14 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) #endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */ +/* + * Registers and masks for easy access by drive index: + */ +#if 0 +static u8 prefetch_regs[4] = {CNTRL, CNTRL, ARTTIM23, ARTTIM23}; +static u8 prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3}; +#endif + /* * This routine writes the prepared setup/active/recovery counts * for a drive into the cmd646 chipset registers to active them. @@ -598,6 +606,13 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; +#ifdef __i386__ + if (dev->resource[PCI_ROM_RESOURCE].start) { + pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); + printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); + } +#endif + switch(dev->device) { case PCI_DEVICE_ID_CMD_643: break; diff --git a/trunk/drivers/ide/pci/pdc202xx_new.c b/trunk/drivers/ide/pci/pdc202xx_new.c index 2c9e938dd1cd..acd63173199b 100644 --- a/trunk/drivers/ide/pci/pdc202xx_new.c +++ b/trunk/drivers/ide/pci/pdc202xx_new.c @@ -338,8 +338,6 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) hwif->ultra_mask = 0x7f; hwif->mwdma_mask = 0x07; - hwif->err_stops_fifo = 1; - hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; hwif->ide_dma_lostirq = &pdcnew_ide_dma_lostirq; hwif->ide_dma_timeout = &pdcnew_ide_dma_timeout; diff --git a/trunk/drivers/ide/pci/pdc202xx_old.c b/trunk/drivers/ide/pci/pdc202xx_old.c index 26bc688a1821..22d17548ecdb 100644 --- a/trunk/drivers/ide/pci/pdc202xx_old.c +++ b/trunk/drivers/ide/pci/pdc202xx_old.c @@ -101,6 +101,31 @@ static const char *pdc_quirk_drives[] = { #define MC1 0x02 /* DMA"C" timing */ #define MC0 0x01 /* DMA"C" timing */ +#if 0 + unsigned long bibma = pci_resource_start(dev, 4); + u8 hi = 0, lo = 0; + + u8 sc1c = inb_p((u16)bibma + 0x1c); + u8 sc1e = inb_p((u16)bibma + 0x1e); + u8 sc1f = inb_p((u16)bibma + 0x1f); + + p += sprintf(p, "Host Mode : %s\n", + (sc1f & 0x08) ? "Tri-Stated" : "Normal"); + p += sprintf(p, "Bus Clocking : %s\n", + ((sc1f & 0xC0) == 0xC0) ? "100 External" : + ((sc1f & 0x80) == 0x80) ? "66 External" : + ((sc1f & 0x40) == 0x40) ? "33 External" : "33 PCI Internal"); + p += sprintf(p, "IO pad select : %s mA\n", + ((sc1c & 0x03) == 0x03) ? "10" : + ((sc1c & 0x02) == 0x02) ? "8" : + ((sc1c & 0x01) == 0x01) ? "6" : + ((sc1c & 0x00) == 0x00) ? "4" : "??"); + hi = sc1e >> 4; + lo = sc1e & 0xf; + p += sprintf(p, "Status Polling Period : %d\n", hi); + p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo); +#endif + static u8 pdc202xx_ratemask (ide_drive_t *drive) { u8 mode; @@ -480,13 +505,42 @@ static void pdc202xx_reset (ide_drive_t *drive) pdc202xx_reset_host(hwif); pdc202xx_reset_host(mate); +#if 0 + /* + * FIXME: Have to kick all the drives again :-/ + * What a pain in the ACE! + */ + if (hwif->present) { + u16 hunit = 0; + for (hunit = 0; hunit < MAX_DRIVES; ++hunit) { + ide_drive_t *hdrive = &hwif->drives[hunit]; + if (hdrive->present) { + if (hwif->ide_dma_check) + hwif->ide_dma_check(hdrive); + else + hwif->tuneproc(hdrive, 5); + } + } + } + if (mate->present) { + u16 munit = 0; + for (munit = 0; munit < MAX_DRIVES; ++munit) { + ide_drive_t *mdrive = &mate->drives[munit]; + if (mdrive->present) { + if (mate->ide_dma_check) + mate->ide_dma_check(mdrive); + else + mate->tuneproc(mdrive, 5); + } + } + } +#else hwif->tuneproc(drive, 5); +#endif } -static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, - const char *name) +static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, const char *name) { - /* This doesn't appear needed */ if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); @@ -494,6 +548,30 @@ static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, name, dev->resource[PCI_ROM_RESOURCE].start); } + /* + * software reset - this is required because the bios + * will set UDMA timing on if the hdd supports it. The + * user may want to turn udma off. A bug in the pdc20262 + * is that it cannot handle a downgrade in timing from + * UDMA to DMA. Disk accesses after issuing a set + * feature command will result in errors. A software + * reset leaves the timing registers intact, + * but resets the drives. + */ +#if 0 + if ((dev->device == PCI_DEVICE_ID_PROMISE_20267) || + (dev->device == PCI_DEVICE_ID_PROMISE_20265) || + (dev->device == PCI_DEVICE_ID_PROMISE_20263) || + (dev->device == PCI_DEVICE_ID_PROMISE_20262)) { + unsigned long high_16 = pci_resource_start(dev, 4); + byte udma_speed_flag = inb(high_16 + 0x001f); + outb(udma_speed_flag | 0x10, high_16 + 0x001f); + mdelay(100); + outb(udma_speed_flag & ~0x10, high_16 + 0x001f); + mdelay(2000); /* 2 seconds ?! */ + } + +#endif return dev->irq; } @@ -521,8 +599,6 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; - hwif->err_stops_fifo = 1; - hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; hwif->ide_dma_lostirq = &pdc202xx_ide_dma_lostirq; hwif->ide_dma_timeout = &pdc202xx_ide_dma_timeout; @@ -611,6 +687,19 @@ static int __devinit init_setup_pdc202ata4(struct pci_dev *dev, "mirror fixed.\n", d->name); } } + +#if 0 + if (dev->device == PCI_DEVICE_ID_PROMISE_20262) + if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || + (tmp & e->mask) != e->val)) + + if (d->enablebits[0].reg != d->enablebits[1].reg) { + d->enablebits[0].reg = d->enablebits[1].reg; + d->enablebits[0].mask = d->enablebits[1].mask; + d->enablebits[0].val = d->enablebits[1].val; + } +#endif + return ide_setup_pci_device(dev, d); } @@ -625,6 +714,22 @@ static int __devinit init_setup_pdc20265(struct pci_dev *dev, "attached to I2O RAID controller.\n"); return -ENODEV; } + +#if 0 + { + u8 pri = 0, sec = 0; + + if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || + (tmp & e->mask) != e->val)) + + if (d->enablebits[0].reg != d->enablebits[1].reg) { + d->enablebits[0].reg = d->enablebits[1].reg; + d->enablebits[0].mask = d->enablebits[1].mask; + d->enablebits[0].val = d->enablebits[1].val; + } + } +#endif + return ide_setup_pci_device(dev, d); } diff --git a/trunk/drivers/ide/pci/sc1200.c b/trunk/drivers/ide/pci/sc1200.c index 778b82ae964d..24e21b2838c1 100644 --- a/trunk/drivers/ide/pci/sc1200.c +++ b/trunk/drivers/ide/pci/sc1200.c @@ -395,6 +395,7 @@ static int sc1200_resume (struct pci_dev *dev) { ide_hwif_t *hwif = NULL; +printk("SC1200: resume\n"); pci_set_power_state(dev, PCI_D0); // bring chip back from sleep state dev->current_state = PM_EVENT_ON; pci_enable_device(dev); @@ -404,6 +405,7 @@ static int sc1200_resume (struct pci_dev *dev) while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) { unsigned int basereg, r, d, format; sc1200_saved_state_t *ss = (sc1200_saved_state_t *)hwif->config_data; +printk("%s: SC1200: resume\n", hwif->name); // // Restore timing registers: this may be unnecessary if BIOS also does it @@ -491,7 +493,7 @@ static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_devic } static struct pci_device_id sc1200_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE), 0}, + { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 0, }, }; MODULE_DEVICE_TABLE(pci, sc1200_pci_tbl); diff --git a/trunk/drivers/ide/pci/serverworks.c b/trunk/drivers/ide/pci/serverworks.c index 5100b827a935..0d3073f4eab4 100644 --- a/trunk/drivers/ide/pci/serverworks.c +++ b/trunk/drivers/ide/pci/serverworks.c @@ -123,11 +123,11 @@ static u8 svwks_csb_check (struct pci_dev *dev) } static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) { - static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; - static const u8 dma_modes[] = { 0x77, 0x21, 0x20 }; - static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; - static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; - static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; + u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + u8 dma_modes[] = { 0x77, 0x21, 0x20 }; + u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; + u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; + u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -392,6 +392,16 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha } outb_p(0x06, 0x0c00); dev->irq = inb_p(0x0c01); +#if 0 + printk("%s: device class (0x%04x)\n", + name, dev->class); + if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) { + dev->class &= ~0x000F0F00; + // dev->class |= ~0x00000400; + dev->class |= ~0x00010100; + /**/ + } +#endif } else { struct pci_dev * findev = NULL; u8 reg41 = 0; @@ -442,7 +452,7 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha pci_write_config_byte(dev, 0x5A, btr); } - return dev->irq; + return (dev->irq) ? dev->irq : 0; } static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif) @@ -490,6 +500,11 @@ static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; + /* Per Specified Design by OEM, and ASIC Architect */ + if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || + (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) + return 1; + /* Server Works */ if (dev->subsystem_vendor == PCI_VENDOR_ID_SERVERWORKS) return ata66_svwks_svwks (hwif); @@ -502,14 +517,10 @@ static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif) if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN) return ata66_svwks_cobalt (hwif); - /* Per Specified Design by OEM, and ASIC Architect */ - if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || - (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) - return 1; - return 0; } +#undef CAN_SW_DMA static void __devinit init_hwif_svwks (ide_hwif_t *hwif) { u8 dma_stat = 0; @@ -526,6 +537,9 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) hwif->ultra_mask = 0x3f; hwif->mwdma_mask = 0x07; +#ifdef CAN_SW_DMA + hwif->swdma_mask = 0x07; +#endif /* CAN_SW_DMA */ hwif->autodma = 0; @@ -548,6 +562,8 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) hwif->drives[1].autodma = (dma_stat & 0x40); hwif->drives[0].autotune = (!(dma_stat & 0x20)); hwif->drives[1].autotune = (!(dma_stat & 0x40)); +// hwif->drives[0].autodma = hwif->autodma; +// hwif->drives[1].autodma = hwif->autodma; } /* @@ -577,6 +593,11 @@ static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d) if (dev->resource[0].start == 0x01f1) d->bootable = ON_BOARD; } +#if 0 + if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_CSB6) && + (!(PCI_FUNC(dev->devfn) & 1))) + d->autodma = AUTODMA; +#endif d->channels = ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE || dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) && @@ -650,11 +671,11 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device } static struct pci_device_id svwks_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0}, - { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 1}, - { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2}, - { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 3}, - { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 4}, + { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, + { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, + { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, { 0, }, }; MODULE_DEVICE_TABLE(pci, svwks_pci_tbl); diff --git a/trunk/drivers/ide/pci/siimage.c b/trunk/drivers/ide/pci/siimage.c index 72dade14c725..f1ca154dd52c 100644 --- a/trunk/drivers/ide/pci/siimage.c +++ b/trunk/drivers/ide/pci/siimage.c @@ -38,6 +38,9 @@ #include +#undef SIIMAGE_VIRTUAL_DMAPIO +#undef SIIMAGE_LARGE_DMA + /** * pdev_is_sata - check if device is SATA * @pdev: PCI device to check @@ -458,6 +461,36 @@ static int siimage_io_ide_dma_test_irq (ide_drive_t *drive) return 0; } +#if 0 +/** + * siimage_mmio_ide_dma_count - DMA bytes done + * @drive + * + * If we are doing VDMA the CMD680 requires a little bit + * of more careful handling and we have to read the counts + * off ourselves. For non VDMA life is normal. + */ + +static int siimage_mmio_ide_dma_count (ide_drive_t *drive) +{ +#ifdef SIIMAGE_VIRTUAL_DMAPIO + struct request *rq = HWGROUP(drive)->rq; + ide_hwif_t *hwif = HWIF(drive); + u32 count = (rq->nr_sectors * SECTOR_SIZE); + u32 rcount = 0; + unsigned long addr = siimage_selreg(hwif, 0x1C); + + hwif->OUTL(count, addr); + rcount = hwif->INL(addr); + + printk("\n%s: count = %d, rcount = %d, nr_sectors = %lu\n", + drive->name, count, rcount, rq->nr_sectors); + +#endif /* SIIMAGE_VIRTUAL_DMAPIO */ + return __ide_dma_count(drive); +} +#endif + /** * siimage_mmio_ide_dma_test_irq - check we caused an IRQ * @drive: drive we are testing @@ -479,10 +512,12 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive) u32 sata_error = hwif->INL(SATA_ERROR_REG); hwif->OUTL(sata_error, SATA_ERROR_REG); watchdog = (sata_error & 0x00680000) ? 1 : 0; +#if 1 printk(KERN_WARNING "%s: sata_error = 0x%08x, " "watchdog = %d, %s\n", drive->name, sata_error, watchdog, __FUNCTION__); +#endif } else { watchdog = (ext_stat & 0x8000) ? 1 : 0; @@ -828,7 +863,7 @@ static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const ch * time. * * The hardware supports buffered taskfiles and also some rather nice - * extended PRD tables. For better SI3112 support use the libata driver + * extended PRD tables. Unfortunately right now we don't. */ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) @@ -865,6 +900,9 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) * so we can't currently use it sanely since we want to * use LBA48 mode. */ +// base += 0x10; +// hwif->no_lba48 = 1; + hw.io_ports[IDE_DATA_OFFSET] = base; hw.io_ports[IDE_ERROR_OFFSET] = base + 1; hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2; @@ -898,8 +936,15 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) base = (unsigned long) addr; +#ifdef SIIMAGE_LARGE_DMA +/* Watch the brackets - even Ken and Dennis get some language design wrong */ + hwif->dma_base = base + (ch ? 0x18 : 0x10); + hwif->dma_base2 = base + (ch ? 0x08 : 0x00); + hwif->dma_prdtable = hwif->dma_base2 + 4; +#else /* ! SIIMAGE_LARGE_DMA */ hwif->dma_base = base + (ch ? 0x08 : 0x00); hwif->dma_base2 = base + (ch ? 0x18 : 0x10); +#endif /* SIIMAGE_LARGE_DMA */ hwif->mmio = 2; } @@ -1007,16 +1052,9 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) hwif->reset_poll = &siimage_reset_poll; hwif->pre_reset = &siimage_pre_reset; - if(is_sata(hwif)) { - static int first = 1; - + if(is_sata(hwif)) hwif->busproc = &siimage_busproc; - if (first) { - printk(KERN_INFO "siimage: For full SATA support you should use the libata sata_sil module.\n"); - first = 0; - } - } if (!hwif->dma_base) { hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; @@ -1083,10 +1121,10 @@ static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_devi } static struct pci_device_id siimage_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680), 0}, + { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, #ifdef CONFIG_BLK_DEV_IDE_SATA - { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112), 1}, - { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA), 2}, + { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, #endif { 0, }, }; diff --git a/trunk/drivers/ide/pci/sl82c105.c b/trunk/drivers/ide/pci/sl82c105.c index 900301e43818..8a5c7b286b2b 100644 --- a/trunk/drivers/ide/pci/sl82c105.c +++ b/trunk/drivers/ide/pci/sl82c105.c @@ -447,6 +447,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", hwif->name, rev); } else { +#ifdef CONFIG_BLK_DEV_IDEDMA dma_state |= 0x60; hwif->atapi_dma = 1; @@ -467,6 +468,7 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) if (hwif->mate) hwif->serialized = hwif->mate->serialized = 1; +#endif /* CONFIG_BLK_DEV_IDEDMA */ } hwif->OUTB(dma_state, hwif->dma_base + 2); } @@ -487,7 +489,7 @@ static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_dev } static struct pci_device_id sl82c105_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105), 0}, + { PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 0, }, }; MODULE_DEVICE_TABLE(pci, sl82c105_pci_tbl); diff --git a/trunk/drivers/ide/pci/slc90e66.c b/trunk/drivers/ide/pci/slc90e66.c index 0968f6bc669a..5112c726633b 100644 --- a/trunk/drivers/ide/pci/slc90e66.c +++ b/trunk/drivers/ide/pci/slc90e66.c @@ -72,8 +72,7 @@ static void slc90e66_tune_drive (ide_drive_t *drive, u8 pio) u16 master_data; u8 slave_data; /* ISP RTC */ - static const u8 timings[][2]= { - { 0, 0 }, + u8 timings[][2] = { { 0, 0 }, { 0, 0 }, { 1, 0 }, { 2, 1 }, @@ -120,6 +119,7 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) pci_read_config_word(dev, 0x4a, ®4a); switch(speed) { +#ifdef CONFIG_BLK_DEV_IDEDMA case XFER_UDMA_4: u_speed = 4 << (drive->dn * 4); break; case XFER_UDMA_3: u_speed = 3 << (drive->dn * 4); break; case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; @@ -128,6 +128,7 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_SW_DMA_2: break; +#endif /* CONFIG_BLK_DEV_IDEDMA */ case XFER_PIO_4: case XFER_PIO_3: case XFER_PIO_2: @@ -155,6 +156,7 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) return (ide_config_drive_speed(drive, speed)); } +#ifdef CONFIG_BLK_DEV_IDEDMA static int slc90e66_config_drive_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive)); @@ -192,6 +194,7 @@ static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive) /* IORDY not supported */ return 0; } +#endif /* CONFIG_BLK_DEV_IDEDMA */ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) { @@ -219,6 +222,7 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; +#ifdef CONFIG_BLK_DEV_IDEDMA if (!(hwif->udma_four)) /* bit[0(1)]: 0:80, 1:40 */ hwif->udma_four = (reg47 & mask) ? 0 : 1; @@ -228,6 +232,7 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) hwif->autodma = 1; hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma; +#endif /* !CONFIG_BLK_DEV_IDEDMA */ } static ide_pci_device_t slc90e66_chipset __devinitdata = { @@ -245,7 +250,7 @@ static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_dev } static struct pci_device_id slc90e66_pci_tbl[] = { - { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1), 0}, + { PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 0, }, }; MODULE_DEVICE_TABLE(pci, slc90e66_pci_tbl); diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c index a90486f5e491..de2e7546b491 100644 --- a/trunk/drivers/input/input.c +++ b/trunk/drivers/input/input.c @@ -998,13 +998,12 @@ void input_unregister_device(struct input_dev *dev) sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group); sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group); sysfs_remove_group(&dev->cdev.kobj, &input_dev_attr_group); + class_device_unregister(&dev->cdev); mutex_lock(&dev->mutex); dev->name = dev->phys = dev->uniq = NULL; mutex_unlock(&dev->mutex); - class_device_unregister(&dev->cdev); - input_wakeup_procfs_readers(); } EXPORT_SYMBOL(input_unregister_device); diff --git a/trunk/drivers/input/joystick/db9.c b/trunk/drivers/input/joystick/db9.c index 5080e15c6d30..6f31f054d1bb 100644 --- a/trunk/drivers/input/joystick/db9.c +++ b/trunk/drivers/input/joystick/db9.c @@ -584,7 +584,7 @@ static struct db9 __init *db9_probe(int parport, int mode) goto err_out; } - if (db9_mode->bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) { + if (db9_mode[mode].bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) { printk(KERN_ERR "db9.c: specified parport is not bidirectional\n"); err = -EINVAL; goto err_put_pp; diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index ce1f10e8984b..ffde8f86e0fb 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -459,7 +459,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, } input_regs(dev, regs); - input_event(dev, EV_KEY, keycode, value); + input_report_key(dev, keycode, value); input_sync(dev); if (value && add_release_event) { diff --git a/trunk/drivers/input/misc/wistron_btns.c b/trunk/drivers/input/misc/wistron_btns.c index ccf0faeee5c1..e4e5be111c96 100644 --- a/trunk/drivers/input/misc/wistron_btns.c +++ b/trunk/drivers/input/misc/wistron_btns.c @@ -285,15 +285,6 @@ static struct key_entry keymap_fujitsu_n3510[] = { { KE_END, 0 } }; -static struct key_entry keymap_wistron_ms2111[] = { - { KE_KEY, 0x11, KEY_PROG1 }, - { KE_KEY, 0x12, KEY_PROG2 }, - { KE_KEY, 0x13, KEY_PROG3 }, - { KE_KEY, 0x31, KEY_MAIL }, - { KE_KEY, 0x36, KEY_WWW }, - { KE_END, 0 } -}; - static struct key_entry keymap_wistron_ms2141[] = { { KE_KEY, 0x11, KEY_PROG1 }, { KE_KEY, 0x12, KEY_PROG2 }, @@ -335,7 +326,6 @@ static struct key_entry keymap_aopen_1559as[] = { { KE_WIFI, 0x30, 0 }, { KE_KEY, 0x31, KEY_MAIL }, { KE_KEY, 0x36, KEY_WWW }, - { KE_END, 0 }, }; /* @@ -398,15 +388,6 @@ static struct dmi_system_id dmi_ids[] = { }, .driver_data = keymap_aopen_1559as }, - { - .callback = dmi_matched, - .ident = "Medion MD 9783", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), - DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"), - }, - .driver_data = keymap_wistron_ms2111 - }, { NULL, } }; diff --git a/trunk/drivers/isdn/gigaset/common.c b/trunk/drivers/isdn/gigaset/common.c index 2a56bf33a673..acb7e2656780 100644 --- a/trunk/drivers/isdn/gigaset/common.c +++ b/trunk/drivers/isdn/gigaset/common.c @@ -981,7 +981,7 @@ void gigaset_stop(struct cardstate *cs) EXPORT_SYMBOL_GPL(gigaset_stop); static LIST_HEAD(drivers); -static DEFINE_SPINLOCK(driver_lock); +static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; struct cardstate *gigaset_get_cs_by_id(int id) { diff --git a/trunk/drivers/isdn/i4l/isdn_tty.c b/trunk/drivers/isdn/i4l/isdn_tty.c index 433389daedb2..2ac90242d263 100644 --- a/trunk/drivers/isdn/i4l/isdn_tty.c +++ b/trunk/drivers/isdn/i4l/isdn_tty.c @@ -82,7 +82,7 @@ isdn_tty_try_read(modem_info * info, struct sk_buff *skb) int l = skb->len; unsigned char *dp = skb->data; while (--l) { - if (*dp == DLE) + if (*skb->data == DLE) tty_insert_flip_char(tty, DLE, 0); tty_insert_flip_char(tty, *dp++, 0); } diff --git a/trunk/drivers/isdn/i4l/isdn_x25iface.c b/trunk/drivers/isdn/i4l/isdn_x25iface.c index 8b3efc243161..743ac4077f35 100644 --- a/trunk/drivers/isdn/i4l/isdn_x25iface.c +++ b/trunk/drivers/isdn/i4l/isdn_x25iface.c @@ -208,7 +208,7 @@ static int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb */ static int isdn_x25iface_connect_ind(struct concap_proto *cprot) { - struct sk_buff * skb; + struct sk_buff * skb = dev_alloc_skb(1); enum wan_states *state_p = &( ( (ix25_pdata_t*) (cprot->proto_data) ) -> state); IX25DEBUG( "isdn_x25iface_connect_ind %s \n" @@ -220,8 +220,6 @@ static int isdn_x25iface_connect_ind(struct concap_proto *cprot) return -1; } *state_p = WAN_CONNECTED; - - skb = dev_alloc_skb(1); if( skb ){ *( skb_put(skb, 1) ) = 0x01; skb->protocol = x25_type_trans(skb, cprot->net_dev); diff --git a/trunk/drivers/leds/led-core.c b/trunk/drivers/leds/led-core.c index 9b015f9af351..fe6541326c71 100644 --- a/trunk/drivers/leds/led-core.c +++ b/trunk/drivers/leds/led-core.c @@ -18,7 +18,7 @@ #include #include "leds.h" -DEFINE_RWLOCK(leds_list_lock); +rwlock_t leds_list_lock = RW_LOCK_UNLOCKED; LIST_HEAD(leds_list); EXPORT_SYMBOL_GPL(leds_list); diff --git a/trunk/drivers/leds/led-triggers.c b/trunk/drivers/leds/led-triggers.c index 1b1ce6523960..5e2cd8be1191 100644 --- a/trunk/drivers/leds/led-triggers.c +++ b/trunk/drivers/leds/led-triggers.c @@ -26,7 +26,7 @@ /* * Nests outside led_cdev->trigger_lock */ -static DEFINE_RWLOCK(triggers_list_lock); +static rwlock_t triggers_list_lock = RW_LOCK_UNLOCKED; static LIST_HEAD(trigger_list); ssize_t led_trigger_store(struct class_device *dev, const char *buf, diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index 837ec4eb3d60..f920e50ea124 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -2827,6 +2827,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski struct stripe_head *sh; int pd_idx; int raid_disks = conf->raid_disks; + int data_disks = raid_disks - conf->max_degraded; sector_t max_sector = mddev->size << 1; int sync_blocks; int still_degraded = 0; diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index 6d532f170ce5..e4290491fa9e 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -445,8 +445,6 @@ endmenu # encoder / decoder chips menu "V4L USB devices" depends on USB && VIDEO_DEV -source "drivers/media/video/pvrusb2/Kconfig" - source "drivers/media/video/em28xx/Kconfig" config USB_DSBR diff --git a/trunk/drivers/media/video/Makefile b/trunk/drivers/media/video/Makefile index 353d61cfac1b..6c401b46398a 100644 --- a/trunk/drivers/media/video/Makefile +++ b/trunk/drivers/media/video/Makefile @@ -47,7 +47,6 @@ obj-$(CONFIG_VIDEO_SAA7134) += ir-kbd-i2c.o saa7134/ obj-$(CONFIG_VIDEO_CX88) += cx88/ obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ obj-$(CONFIG_VIDEO_EM28XX) += tvp5150.o -obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o diff --git a/trunk/drivers/media/video/cx2341x.c b/trunk/drivers/media/video/cx2341x.c index 65f00fc08fa9..01b22eab5725 100644 --- a/trunk/drivers/media/video/cx2341x.c +++ b/trunk/drivers/media/video/cx2341x.c @@ -601,7 +601,7 @@ static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params) } int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, - struct v4l2_ext_controls *ctrls, unsigned int cmd) + struct v4l2_ext_controls *ctrls, int cmd) { int err = 0; int i; @@ -847,22 +847,22 @@ static const char *cx2341x_menu_item(struct cx2341x_mpeg_params *p, u32 id) return ""; } -void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix) +void cx2341x_log_status(struct cx2341x_mpeg_params *p, int card_id) { int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; /* Stream */ - printk(KERN_INFO "%s: Stream: %s\n", - prefix, + printk(KERN_INFO "cx2341x-%d: Stream: %s\n", + card_id, cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE)); /* Video */ - printk(KERN_INFO "%s: Video: %dx%d, %d fps\n", - prefix, + printk(KERN_INFO "cx2341x-%d: Video: %dx%d, %d fps\n", + card_id, p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1), p->is_50hz ? 25 : 30); - printk(KERN_INFO "%s: Video: %s, %s, %s, %d", - prefix, + printk(KERN_INFO "cx2341x-%d: Video: %s, %s, %s, %d", + card_id, cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING), cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT), cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE), @@ -871,19 +871,19 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix) printk(", Peak %d", p->video_bitrate_peak); } printk("\n"); - printk(KERN_INFO "%s: Video: GOP Size %d, %d B-Frames, %sGOP Closure, %s3:2 Pulldown\n", - prefix, + printk(KERN_INFO "cx2341x-%d: Video: GOP Size %d, %d B-Frames, %sGOP Closure, %s3:2 Pulldown\n", + card_id, p->video_gop_size, p->video_b_frames, p->video_gop_closure ? "" : "No ", p->video_pulldown ? "" : "No "); if (p->video_temporal_decimation) { - printk(KERN_INFO "%s: Video: Temporal Decimation %d\n", - prefix, p->video_temporal_decimation); + printk(KERN_INFO "cx2341x-%d: Video: Temporal Decimation %d\n", + card_id, p->video_temporal_decimation); } /* Audio */ - printk(KERN_INFO "%s: Audio: %s, %s, %s, %s", - prefix, + printk(KERN_INFO "cx2341x-%d: Audio: %s, %s, %s, %s", + card_id, cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ), cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING), cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE), @@ -897,18 +897,18 @@ void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix) cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC)); /* Encoding filters */ - printk(KERN_INFO "%s: Spatial Filter: %s, Luma %s, Chroma %s, %d\n", - prefix, + printk(KERN_INFO "cx2341x-%d: Spatial Filter: %s, Luma %s, Chroma %s, %d\n", + card_id, cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE), cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE), cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE), p->video_spatial_filter); - printk(KERN_INFO "%s: Temporal Filter: %s, %d\n", - prefix, + printk(KERN_INFO "cx2341x-%d: Temporal Filter: %s, %d\n", + card_id, cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE), p->video_temporal_filter); - printk(KERN_INFO "%s: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n", - prefix, + printk(KERN_INFO "cx2341x-%d: Median Filter: %s, Luma [%d, %d], Chroma [%d, %d]\n", + card_id, cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE), p->video_luma_median_filter_bottom, p->video_luma_median_filter_top, diff --git a/trunk/drivers/media/video/cx88/cx88-blackbird.c b/trunk/drivers/media/video/cx88/cx88-blackbird.c index 4ff81582ec56..78df66671ea2 100644 --- a/trunk/drivers/media/video/cx88/cx88-blackbird.c +++ b/trunk/drivers/media/video/cx88/cx88-blackbird.c @@ -853,19 +853,6 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, fh->mpegq.field); return 0; } - case VIDIOC_LOG_STATUS: - { - char name[32 + 2]; - - snprintf(name, sizeof(name), "%s/2", core->name); - printk("%s/2: ============ START LOG STATUS ============\n", - core->name); - cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, 0); - cx2341x_log_status(&dev->params, name); - printk("%s/2: ============= END LOG STATUS =============\n", - core->name); - return 0; - } default: return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl); diff --git a/trunk/drivers/media/video/pvrusb2/Kconfig b/trunk/drivers/media/video/pvrusb2/Kconfig deleted file mode 100644 index 7e727fe14b32..000000000000 --- a/trunk/drivers/media/video/pvrusb2/Kconfig +++ /dev/null @@ -1,62 +0,0 @@ -config VIDEO_PVRUSB2 - tristate "Hauppauge WinTV-PVR USB2 support" - depends on VIDEO_V4L2 && USB && I2C && EXPERIMENTAL - select FW_LOADER - select VIDEO_TUNER - select VIDEO_TVEEPROM - select VIDEO_CX2341X - select VIDEO_SAA711X - select VIDEO_MSP3400 - ---help--- - This is a video4linux driver for Conexant 23416 based - usb2 personal video recorder devices. - - To compile this driver as a module, choose M here: the - module will be called pvrusb2 - -config VIDEO_PVRUSB2_24XXX - bool "Hauppauge WinTV-PVR USB2 support for 24xxx model series" - depends on VIDEO_PVRUSB2 && EXPERIMENTAL - select VIDEO_CX25840 - select VIDEO_WM8775 - ---help--- - This option enables inclusion of additional logic to operate - newer WinTV-PVR USB2 devices whose model number is of the - form "24xxx" (leading prefix of "24" followed by 3 digits). - To see if you may need this option, examine the white - sticker on the underside of your device. Enabling this - option will not harm support for older devices, however it - is a separate option because of the experimental nature of - this new feature. - - If you are in doubt, say N. - - Note: This feature is _very_ experimental. You have been - warned. - -config VIDEO_PVRUSB2_SYSFS - bool "pvrusb2 sysfs support (EXPERIMENTAL)" - default y - depends on VIDEO_PVRUSB2 && SYSFS && EXPERIMENTAL - ---help--- - This option enables the operation of a sysfs based - interface for query and control of the pvrusb2 driver. - - This is not generally needed for v4l applications, - although certain applications are optimized to take - advantage of this feature. - - If you are in doubt, say Y. - - Note: This feature is experimental and subject to change. - -config VIDEO_PVRUSB2_DEBUGIFC - bool "pvrusb2 debug interface" - depends on VIDEO_PVRUSB2_SYSFS - ---help--- - This option enables the inclusion of a debug interface - in the pvrusb2 driver, hosted through sysfs. - - You do not need to select this option unless you plan - on debugging the driver or performing a manual firmware - extraction. diff --git a/trunk/drivers/media/video/pvrusb2/Makefile b/trunk/drivers/media/video/pvrusb2/Makefile deleted file mode 100644 index fed603ad0a67..000000000000 --- a/trunk/drivers/media/video/pvrusb2/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o -obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o - -obj-pvrusb2-24xxx-$(CONFIG_VIDEO_PVRUSB2_24XXX) := \ - pvrusb2-cx2584x-v4l.o \ - pvrusb2-wm8775.o - -pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \ - pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \ - pvrusb2-encoder.o pvrusb2-video-v4l.o \ - pvrusb2-eeprom.o pvrusb2-tuner.o pvrusb2-demod.o \ - pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \ - pvrusb2-ctrl.o pvrusb2-std.o \ - pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \ - $(obj-pvrusb2-24xxx-y) \ - $(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y) - -obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2.o diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c deleted file mode 100644 index 313d2dcf9e4b..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * 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 "pvrusb2-audio.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include -#include -#include - -struct pvr2_msp3400_handler { - struct pvr2_hdw *hdw; - struct pvr2_i2c_client *client; - struct pvr2_i2c_handler i2c_handler; - struct pvr2_audio_stat astat; - unsigned long stale_mask; -}; - - -/* This function selects the correct audio input source */ -static void set_stereo(struct pvr2_msp3400_handler *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - struct v4l2_routing route; - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c msp3400 v4l2 set_stereo"); - - if (hdw->input_val == PVR2_CVAL_INPUT_TV) { - struct v4l2_tuner vt; - memset(&vt,0,sizeof(vt)); - vt.audmode = hdw->audiomode_val; - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_TUNER,&vt); - } - - route.input = MSP_INPUT_DEFAULT; - route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1); - switch (hdw->input_val) { - case PVR2_CVAL_INPUT_TV: - break; - case PVR2_CVAL_INPUT_RADIO: - /* Assume that msp34xx also handle FM decoding, in which case - we're still using the tuner. */ - /* HV: actually it is more likely to be the SCART2 input if - the ivtv experience is any indication. */ - route.input = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, - MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); - break; - case PVR2_CVAL_INPUT_SVIDEO: - case PVR2_CVAL_INPUT_COMPOSITE: - /* SCART 1 input */ - route.input = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, - MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); - break; - } - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); -} - - -static int check_stereo(struct pvr2_msp3400_handler *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - return (hdw->input_dirty || - hdw->audiomode_dirty); -} - - -struct pvr2_msp3400_ops { - void (*update)(struct pvr2_msp3400_handler *); - int (*check)(struct pvr2_msp3400_handler *); -}; - - -static const struct pvr2_msp3400_ops msp3400_ops[] = { - { .update = set_stereo, .check = check_stereo}, -}; - - -static int msp3400_check(struct pvr2_msp3400_handler *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]); - idx++) { - msk = 1 << idx; - if (ctxt->stale_mask & msk) continue; - if (msp3400_ops[idx].check(ctxt)) { - ctxt->stale_mask |= msk; - } - } - return ctxt->stale_mask != 0; -} - - -static void msp3400_update(struct pvr2_msp3400_handler *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(msp3400_ops)/sizeof(msp3400_ops[0]); - idx++) { - msk = 1 << idx; - if (!(ctxt->stale_mask & msk)) continue; - ctxt->stale_mask &= ~msk; - msp3400_ops[idx].update(ctxt); - } -} - - -/* This reads back the current signal type */ -static int get_audio_status(struct pvr2_msp3400_handler *ctxt) -{ - struct v4l2_tuner vt; - int stat; - - memset(&vt,0,sizeof(vt)); - stat = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt); - if (stat < 0) return stat; - - ctxt->hdw->flag_stereo = (vt.audmode & V4L2_TUNER_MODE_STEREO) != 0; - ctxt->hdw->flag_bilingual = - (vt.audmode & V4L2_TUNER_MODE_LANG2) != 0; - return 0; -} - - -static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt) -{ - ctxt->client->handler = 0; - ctxt->hdw->audio_stat = 0; - kfree(ctxt); -} - - -static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler *ctxt, - char *buf,unsigned int cnt) -{ - return scnprintf(buf,cnt,"handler: pvrusb2-audio v4l2"); -} - - -const static struct pvr2_i2c_handler_functions msp3400_funcs = { - .detach = (void (*)(void *))pvr2_msp3400_detach, - .check = (int (*)(void *))msp3400_check, - .update = (void (*)(void *))msp3400_update, - .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_msp3400_describe, -}; - - -int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) -{ - struct pvr2_msp3400_handler *ctxt; - if (hdw->audio_stat) return 0; - if (cp->handler) return 0; - - ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); - if (!ctxt) return 0; - memset(ctxt,0,sizeof(*ctxt)); - - ctxt->i2c_handler.func_data = ctxt; - ctxt->i2c_handler.func_table = &msp3400_funcs; - ctxt->client = cp; - ctxt->hdw = hdw; - ctxt->astat.ctxt = ctxt; - ctxt->astat.status = (int (*)(void *))get_audio_status; - ctxt->astat.detach = (void (*)(void *))pvr2_msp3400_detach; - ctxt->stale_mask = (1 << (sizeof(msp3400_ops)/ - sizeof(msp3400_ops[0]))) - 1; - cp->handler = &ctxt->i2c_handler; - hdw->audio_stat = &ctxt->astat; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up", - cp->client->addr); - return !0; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.h deleted file mode 100644 index 536339b68843..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-audio.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_AUDIO_H -#define __PVRUSB2_AUDIO_H - -#include "pvrusb2-i2c-core.h" - -int pvr2_i2c_msp3400_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); - -#endif /* __PVRUSB2_AUDIO_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-context.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-context.c deleted file mode 100644 index 40dc59871a45..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-context.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * 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 "pvrusb2-context.h" -#include "pvrusb2-io.h" -#include "pvrusb2-ioread.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2-debug.h" -#include -#include -#include -#include - - -static void pvr2_context_destroy(struct pvr2_context *mp) -{ - if (mp->hdw) pvr2_hdw_destroy(mp->hdw); - pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr_main id=%p",mp); - flush_workqueue(mp->workqueue); - destroy_workqueue(mp->workqueue); - kfree(mp); -} - - -static void pvr2_context_trigger_poll(struct pvr2_context *mp) -{ - queue_work(mp->workqueue,&mp->workpoll); -} - - -static void pvr2_context_poll(struct pvr2_context *mp) -{ - pvr2_context_enter(mp); do { - pvr2_hdw_poll(mp->hdw); - } while (0); pvr2_context_exit(mp); -} - - -static void pvr2_context_setup(struct pvr2_context *mp) -{ - pvr2_context_enter(mp); do { - if (!pvr2_hdw_dev_ok(mp->hdw)) break; - pvr2_hdw_setup(mp->hdw); - pvr2_hdw_setup_poll_trigger( - mp->hdw, - (void (*)(void *))pvr2_context_trigger_poll, - mp); - if (!pvr2_hdw_dev_ok(mp->hdw)) break; - if (!pvr2_hdw_init_ok(mp->hdw)) break; - mp->video_stream.stream = pvr2_hdw_get_video_stream(mp->hdw); - if (mp->setup_func) { - mp->setup_func(mp); - } - } while (0); pvr2_context_exit(mp); -} - - -struct pvr2_context *pvr2_context_create( - struct usb_interface *intf, - const struct usb_device_id *devid, - void (*setup_func)(struct pvr2_context *)) -{ - struct pvr2_context *mp = 0; - mp = kmalloc(sizeof(*mp),GFP_KERNEL); - if (!mp) goto done; - memset(mp,0,sizeof(*mp)); - pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_main id=%p",mp); - mp->setup_func = setup_func; - mutex_init(&mp->mutex); - mp->hdw = pvr2_hdw_create(intf,devid); - if (!mp->hdw) { - pvr2_context_destroy(mp); - mp = 0; - goto done; - } - - mp->workqueue = create_singlethread_workqueue("pvrusb2"); - INIT_WORK(&mp->workinit,(void (*)(void*))pvr2_context_setup,mp); - INIT_WORK(&mp->workpoll,(void (*)(void*))pvr2_context_poll,mp); - queue_work(mp->workqueue,&mp->workinit); - done: - return mp; -} - - -void pvr2_context_enter(struct pvr2_context *mp) -{ - mutex_lock(&mp->mutex); - pvr2_trace(PVR2_TRACE_CREG,"pvr2_context_enter(id=%p)",mp); -} - - -void pvr2_context_exit(struct pvr2_context *mp) -{ - int destroy_flag = 0; - if (!(mp->mc_first || !mp->disconnect_flag)) { - destroy_flag = !0; - } - pvr2_trace(PVR2_TRACE_CREG,"pvr2_context_exit(id=%p) outside",mp); - mutex_unlock(&mp->mutex); - if (destroy_flag) pvr2_context_destroy(mp); -} - - -static void pvr2_context_run_checks(struct pvr2_context *mp) -{ - struct pvr2_channel *ch1,*ch2; - for (ch1 = mp->mc_first; ch1; ch1 = ch2) { - ch2 = ch1->mc_next; - if (ch1->check_func) { - ch1->check_func(ch1); - } - } -} - - -void pvr2_context_disconnect(struct pvr2_context *mp) -{ - pvr2_context_enter(mp); do { - pvr2_hdw_disconnect(mp->hdw); - mp->disconnect_flag = !0; - pvr2_context_run_checks(mp); - } while (0); pvr2_context_exit(mp); -} - - -void pvr2_channel_init(struct pvr2_channel *cp,struct pvr2_context *mp) -{ - cp->hdw = mp->hdw; - cp->mc_head = mp; - cp->mc_next = 0; - cp->mc_prev = mp->mc_last; - if (mp->mc_last) { - mp->mc_last->mc_next = cp; - } else { - mp->mc_first = cp; - } - mp->mc_last = cp; -} - - -static void pvr2_channel_disclaim_stream(struct pvr2_channel *cp) -{ - if (!cp->stream) return; - pvr2_stream_kill(cp->stream->stream); - cp->stream->user = 0; - cp->stream = 0; -} - - -void pvr2_channel_done(struct pvr2_channel *cp) -{ - struct pvr2_context *mp = cp->mc_head; - pvr2_channel_disclaim_stream(cp); - if (cp->mc_next) { - cp->mc_next->mc_prev = cp->mc_prev; - } else { - mp->mc_last = cp->mc_prev; - } - if (cp->mc_prev) { - cp->mc_prev->mc_next = cp->mc_next; - } else { - mp->mc_first = cp->mc_next; - } - cp->hdw = 0; -} - - -int pvr2_channel_claim_stream(struct pvr2_channel *cp, - struct pvr2_context_stream *sp) -{ - int code = 0; - pvr2_context_enter(cp->mc_head); do { - if (sp == cp->stream) break; - if (sp->user) { - code = -EBUSY; - break; - } - pvr2_channel_disclaim_stream(cp); - if (!sp) break; - sp->user = cp; - cp->stream = sp; - } while (0); pvr2_context_exit(cp->mc_head); - return code; -} - - -// This is the marker for the real beginning of a legitimate mpeg2 stream. -static char stream_sync_key[] = { - 0x00, 0x00, 0x01, 0xba, -}; - -struct pvr2_ioread *pvr2_channel_create_mpeg_stream( - struct pvr2_context_stream *sp) -{ - struct pvr2_ioread *cp; - cp = pvr2_ioread_create(); - if (!cp) return 0; - pvr2_ioread_setup(cp,sp->stream); - pvr2_ioread_set_sync_key(cp,stream_sync_key,sizeof(stream_sync_key)); - return cp; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-context.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-context.h deleted file mode 100644 index 6327fa1f7e4f..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-context.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_BASE_H -#define __PVRUSB2_BASE_H - -#include -#include -#include - -struct pvr2_hdw; /* hardware interface - defined elsewhere */ -struct pvr2_stream; /* stream interface - defined elsewhere */ - -struct pvr2_context; /* All central state */ -struct pvr2_channel; /* One I/O pathway to a user */ -struct pvr2_context_stream; /* Wrapper for a stream */ -struct pvr2_crit_reg; /* Critical region pointer */ -struct pvr2_ioread; /* Low level stream structure */ - -struct pvr2_context_stream { - struct pvr2_channel *user; - struct pvr2_stream *stream; -}; - -struct pvr2_context { - struct pvr2_channel *mc_first; - struct pvr2_channel *mc_last; - struct pvr2_hdw *hdw; - struct pvr2_context_stream video_stream; - struct mutex mutex; - int disconnect_flag; - - /* Called after pvr2_context initialization is complete */ - void (*setup_func)(struct pvr2_context *); - - /* Work queue overhead for out-of-line processing */ - struct workqueue_struct *workqueue; - struct work_struct workinit; - struct work_struct workpoll; -}; - -struct pvr2_channel { - struct pvr2_context *mc_head; - struct pvr2_channel *mc_next; - struct pvr2_channel *mc_prev; - struct pvr2_context_stream *stream; - struct pvr2_hdw *hdw; - void (*check_func)(struct pvr2_channel *); -}; - -void pvr2_context_enter(struct pvr2_context *); -void pvr2_context_exit(struct pvr2_context *); - -struct pvr2_context *pvr2_context_create(struct usb_interface *intf, - const struct usb_device_id *devid, - void (*setup_func)(struct pvr2_context *)); -void pvr2_context_disconnect(struct pvr2_context *); - -void pvr2_channel_init(struct pvr2_channel *,struct pvr2_context *); -void pvr2_channel_done(struct pvr2_channel *); -int pvr2_channel_claim_stream(struct pvr2_channel *, - struct pvr2_context_stream *); -struct pvr2_ioread *pvr2_channel_create_mpeg_stream( - struct pvr2_context_stream *); - - -#endif /* __PVRUSB2_CONTEXT_H */ -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.c deleted file mode 100644 index d5df9fbeba2f..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.c +++ /dev/null @@ -1,593 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * 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 "pvrusb2-ctrl.h" -#include "pvrusb2-hdw-internal.h" -#include -#include -#include - - -/* Set the given control. */ -int pvr2_ctrl_set_value(struct pvr2_ctrl *cptr,int val) -{ - return pvr2_ctrl_set_mask_value(cptr,~0,val); -} - - -/* Set/clear specific bits of the given control. */ -int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val) -{ - int ret = 0; - if (!cptr) return -EINVAL; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->set_value != 0) { - if (cptr->info->type == pvr2_ctl_bitmask) { - mask &= cptr->info->def.type_bitmask.valid_bits; - } else if (cptr->info->type == pvr2_ctl_int) { - if (val < cptr->info->def.type_int.min_value) { - break; - } - if (val > cptr->info->def.type_int.max_value) { - break; - } - } else if (cptr->info->type == pvr2_ctl_enum) { - if (val >= cptr->info->def.type_enum.count) { - break; - } - } else if (cptr->info->type != pvr2_ctl_bool) { - break; - } - ret = cptr->info->set_value(cptr,mask,val); - } else { - ret = -EPERM; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Get the current value of the given control. */ -int pvr2_ctrl_get_value(struct pvr2_ctrl *cptr,int *valptr) -{ - int ret = 0; - if (!cptr) return -EINVAL; - LOCK_TAKE(cptr->hdw->big_lock); do { - ret = cptr->info->get_value(cptr,valptr); - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's type */ -enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *cptr) -{ - if (!cptr) return pvr2_ctl_int; - return cptr->info->type; -} - - -/* Retrieve control's maximum value (int type) */ -int pvr2_ctrl_get_max(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_int) { - ret = cptr->info->def.type_int.max_value; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's minimum value (int type) */ -int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_int) { - ret = cptr->info->def.type_int.min_value; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's default value (any type) */ -int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_int) { - ret = cptr->info->default_value; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's enumeration count (enum only) */ -int pvr2_ctrl_get_cnt(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_enum) { - ret = cptr->info->def.type_enum.count; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve control's valid mask bits (bit mask only) */ -int pvr2_ctrl_get_mask(struct pvr2_ctrl *cptr) -{ - int ret = 0; - if (!cptr) return 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_bitmask) { - ret = cptr->info->def.type_bitmask.valid_bits; - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Retrieve the control's name */ -const char *pvr2_ctrl_get_name(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - return cptr->info->name; -} - - -/* Retrieve the control's desc */ -const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - return cptr->info->desc; -} - - -/* Retrieve a control enumeration or bit mask value */ -int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val, - char *bptr,unsigned int bmax, - unsigned int *blen) -{ - int ret = -EINVAL; - if (!cptr) return 0; - *blen = 0; - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_enum) { - const char **names; - names = cptr->info->def.type_enum.value_names; - if ((val >= 0) && - (val < cptr->info->def.type_enum.count)) { - if (names[val]) { - *blen = scnprintf( - bptr,bmax,"%s", - names[val]); - } else { - *blen = 0; - } - ret = 0; - } - } else if (cptr->info->type == pvr2_ctl_bitmask) { - const char **names; - unsigned int idx; - int msk; - names = cptr->info->def.type_bitmask.bit_names; - val &= cptr->info->def.type_bitmask.valid_bits; - for (idx = 0, msk = 1; val; idx++, msk <<= 1) { - if (val & msk) { - *blen = scnprintf(bptr,bmax,"%s", - names[idx]); - ret = 0; - break; - } - } - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Return V4L ID for this control or zero if none */ -int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - return cptr->info->v4l_id; -} - - -unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr) -{ - unsigned int flags = 0; - - if (cptr->info->get_v4lflags) { - flags = cptr->info->get_v4lflags(cptr); - } - - if (cptr->info->set_value) { - flags &= ~V4L2_CTRL_FLAG_READ_ONLY; - } else { - flags |= V4L2_CTRL_FLAG_READ_ONLY; - } - - return flags; -} - - -/* Return true if control is writable */ -int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - return cptr->info->set_value != 0; -} - - -/* Return true if control has custom symbolic representation */ -int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *cptr) -{ - if (!cptr) return 0; - if (!cptr->info->val_to_sym) return 0; - if (!cptr->info->sym_to_val) return 0; - return !0; -} - - -/* Convert a given mask/val to a custom symbolic value */ -int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *cptr, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len) -{ - if (!cptr) return -EINVAL; - if (!cptr->info->val_to_sym) return -EINVAL; - return cptr->info->val_to_sym(cptr,mask,val,buf,maxlen,len); -} - - -/* Convert a symbolic value to a mask/value pair */ -int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *cptr, - const char *buf,unsigned int len, - int *maskptr,int *valptr) -{ - if (!cptr) return -EINVAL; - if (!cptr->info->sym_to_val) return -EINVAL; - return cptr->info->sym_to_val(cptr,buf,len,maskptr,valptr); -} - - -static unsigned int gen_bitmask_string(int msk,int val,int msk_only, - const char **names, - char *ptr,unsigned int len) -{ - unsigned int idx; - long sm,um; - int spcFl; - unsigned int uc,cnt; - const char *idStr; - - spcFl = 0; - uc = 0; - um = 0; - for (idx = 0, sm = 1; msk; idx++, sm <<= 1) { - if (sm & msk) { - msk &= ~sm; - idStr = names[idx]; - if (idStr) { - cnt = scnprintf(ptr,len,"%s%s%s", - (spcFl ? " " : ""), - (msk_only ? "" : - ((val & sm) ? "+" : "-")), - idStr); - ptr += cnt; len -= cnt; uc += cnt; - spcFl = !0; - } else { - um |= sm; - } - } - } - if (um) { - if (msk_only) { - cnt = scnprintf(ptr,len,"%s0x%lx", - (spcFl ? " " : ""), - um); - ptr += cnt; len -= cnt; uc += cnt; - spcFl = !0; - } else if (um & val) { - cnt = scnprintf(ptr,len,"%s+0x%lx", - (spcFl ? " " : ""), - um & val); - ptr += cnt; len -= cnt; uc += cnt; - spcFl = !0; - } else if (um & ~val) { - cnt = scnprintf(ptr,len,"%s+0x%lx", - (spcFl ? " " : ""), - um & ~val); - ptr += cnt; len -= cnt; uc += cnt; - spcFl = !0; - } - } - return uc; -} - - -static const char *boolNames[] = { - "false", - "true", - "no", - "yes", -}; - - -static int parse_token(const char *ptr,unsigned int len, - int *valptr, - const char **names,unsigned int namecnt) -{ - char buf[33]; - unsigned int slen; - unsigned int idx; - int negfl; - char *p2; - *valptr = 0; - if (!names) namecnt = 0; - for (idx = 0; idx < namecnt; idx++) { - if (!names[idx]) continue; - slen = strlen(names[idx]); - if (slen != len) continue; - if (memcmp(names[idx],ptr,slen)) continue; - *valptr = idx; - return 0; - } - negfl = 0; - if ((*ptr == '-') || (*ptr == '+')) { - negfl = (*ptr == '-'); - ptr++; len--; - } - if (len >= sizeof(buf)) return -EINVAL; - memcpy(buf,ptr,len); - buf[len] = 0; - *valptr = simple_strtol(buf,&p2,0); - if (negfl) *valptr = -(*valptr); - if (*p2) return -EINVAL; - return 1; -} - - -static int parse_mtoken(const char *ptr,unsigned int len, - int *valptr, - const char **names,int valid_bits) -{ - char buf[33]; - unsigned int slen; - unsigned int idx; - char *p2; - int msk; - *valptr = 0; - for (idx = 0, msk = 1; valid_bits; idx++, msk <<= 1) { - if (!msk & valid_bits) continue; - valid_bits &= ~msk; - if (!names[idx]) continue; - slen = strlen(names[idx]); - if (slen != len) continue; - if (memcmp(names[idx],ptr,slen)) continue; - *valptr = msk; - return 0; - } - if (len >= sizeof(buf)) return -EINVAL; - memcpy(buf,ptr,len); - buf[len] = 0; - *valptr = simple_strtol(buf,&p2,0); - if (*p2) return -EINVAL; - return 0; -} - - -static int parse_tlist(const char *ptr,unsigned int len, - int *maskptr,int *valptr, - const char **names,int valid_bits) -{ - unsigned int cnt; - int mask,val,kv,mode,ret; - mask = 0; - val = 0; - ret = 0; - while (len) { - cnt = 0; - while ((cnt < len) && - ((ptr[cnt] <= 32) || - (ptr[cnt] >= 127))) cnt++; - ptr += cnt; - len -= cnt; - mode = 0; - if ((*ptr == '-') || (*ptr == '+')) { - mode = (*ptr == '-') ? -1 : 1; - ptr++; - len--; - } - cnt = 0; - while (cnt < len) { - if (ptr[cnt] <= 32) break; - if (ptr[cnt] >= 127) break; - cnt++; - } - if (!cnt) break; - if (parse_mtoken(ptr,cnt,&kv,names,valid_bits)) { - ret = -EINVAL; - break; - } - ptr += cnt; - len -= cnt; - switch (mode) { - case 0: - mask = valid_bits; - val |= kv; - break; - case -1: - mask |= kv; - val &= ~kv; - break; - case 1: - mask |= kv; - val |= kv; - break; - default: - break; - } - } - *maskptr = mask; - *valptr = val; - return ret; -} - - -/* Convert a symbolic value to a mask/value pair */ -int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr, - const char *ptr,unsigned int len, - int *maskptr,int *valptr) -{ - int ret = -EINVAL; - unsigned int cnt; - - *maskptr = 0; - *valptr = 0; - - cnt = 0; - while ((cnt < len) && ((ptr[cnt] <= 32) || (ptr[cnt] >= 127))) cnt++; - len -= cnt; ptr += cnt; - cnt = 0; - while ((cnt < len) && ((ptr[len-(cnt+1)] <= 32) || - (ptr[len-(cnt+1)] >= 127))) cnt++; - len -= cnt; - - if (!len) return -EINVAL; - - LOCK_TAKE(cptr->hdw->big_lock); do { - if (cptr->info->type == pvr2_ctl_int) { - ret = parse_token(ptr,len,valptr,0,0); - if ((ret >= 0) && - ((*valptr < cptr->info->def.type_int.min_value) || - (*valptr > cptr->info->def.type_int.max_value))) { - ret = -ERANGE; - } - if (maskptr) *maskptr = ~0; - } else if (cptr->info->type == pvr2_ctl_bool) { - ret = parse_token( - ptr,len,valptr,boolNames, - sizeof(boolNames)/sizeof(boolNames[0])); - if (ret == 1) { - *valptr = *valptr ? !0 : 0; - } else if (ret == 0) { - *valptr = (*valptr & 1) ? !0 : 0; - } - if (maskptr) *maskptr = 1; - } else if (cptr->info->type == pvr2_ctl_enum) { - ret = parse_token( - ptr,len,valptr, - cptr->info->def.type_enum.value_names, - cptr->info->def.type_enum.count); - if ((ret >= 0) && - ((*valptr < 0) || - (*valptr >= cptr->info->def.type_enum.count))) { - ret = -ERANGE; - } - if (maskptr) *maskptr = ~0; - } else if (cptr->info->type == pvr2_ctl_bitmask) { - ret = parse_tlist( - ptr,len,maskptr,valptr, - cptr->info->def.type_bitmask.bit_names, - cptr->info->def.type_bitmask.valid_bits); - } - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* Convert a given mask/val to a symbolic value */ -int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *cptr, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len) -{ - int ret = -EINVAL; - - *len = 0; - if (cptr->info->type == pvr2_ctl_int) { - *len = scnprintf(buf,maxlen,"%d",val); - ret = 0; - } else if (cptr->info->type == pvr2_ctl_bool) { - *len = scnprintf(buf,maxlen,"%s",val ? "true" : "false"); - ret = 0; - } else if (cptr->info->type == pvr2_ctl_enum) { - const char **names; - names = cptr->info->def.type_enum.value_names; - if ((val >= 0) && - (val < cptr->info->def.type_enum.count)) { - if (names[val]) { - *len = scnprintf( - buf,maxlen,"%s", - names[val]); - } else { - *len = 0; - } - ret = 0; - } - } else if (cptr->info->type == pvr2_ctl_bitmask) { - *len = gen_bitmask_string( - val & mask & cptr->info->def.type_bitmask.valid_bits, - ~0,!0, - cptr->info->def.type_bitmask.bit_names, - buf,maxlen); - } - return ret; -} - - -/* Convert a given mask/val to a symbolic value */ -int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *cptr, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len) -{ - int ret; - LOCK_TAKE(cptr->hdw->big_lock); do { - ret = pvr2_ctrl_value_to_sym_internal(cptr,mask,val, - buf,maxlen,len); - } while(0); LOCK_GIVE(cptr->hdw->big_lock); - return ret; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.h deleted file mode 100644 index c1680053cd64..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-ctrl.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_CTRL_H -#define __PVRUSB2_CTRL_H - -struct pvr2_ctrl; - -enum pvr2_ctl_type { - pvr2_ctl_int = 0, - pvr2_ctl_enum = 1, - pvr2_ctl_bitmask = 2, - pvr2_ctl_bool = 3, -}; - - -/* Set the given control. */ -int pvr2_ctrl_set_value(struct pvr2_ctrl *,int val); - -/* Set/clear specific bits of the given control. */ -int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *,int mask,int val); - -/* Get the current value of the given control. */ -int pvr2_ctrl_get_value(struct pvr2_ctrl *,int *valptr); - -/* Retrieve control's type */ -enum pvr2_ctl_type pvr2_ctrl_get_type(struct pvr2_ctrl *); - -/* Retrieve control's maximum value (int type) */ -int pvr2_ctrl_get_max(struct pvr2_ctrl *); - -/* Retrieve control's minimum value (int type) */ -int pvr2_ctrl_get_min(struct pvr2_ctrl *); - -/* Retrieve control's default value (any type) */ -int pvr2_ctrl_get_def(struct pvr2_ctrl *); - -/* Retrieve control's enumeration count (enum only) */ -int pvr2_ctrl_get_cnt(struct pvr2_ctrl *); - -/* Retrieve control's valid mask bits (bit mask only) */ -int pvr2_ctrl_get_mask(struct pvr2_ctrl *); - -/* Retrieve the control's name */ -const char *pvr2_ctrl_get_name(struct pvr2_ctrl *); - -/* Retrieve the control's desc */ -const char *pvr2_ctrl_get_desc(struct pvr2_ctrl *); - -/* Retrieve a control enumeration or bit mask value */ -int pvr2_ctrl_get_valname(struct pvr2_ctrl *,int,char *,unsigned int, - unsigned int *); - -/* Return true if control is writable */ -int pvr2_ctrl_is_writable(struct pvr2_ctrl *); - -/* Return V4L flags value for control (or zero if there is no v4l control - actually under this control) */ -unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *); - -/* Return V4L ID for this control or zero if none */ -int pvr2_ctrl_get_v4lid(struct pvr2_ctrl *); - -/* Return true if control has custom symbolic representation */ -int pvr2_ctrl_has_custom_symbols(struct pvr2_ctrl *); - -/* Convert a given mask/val to a custom symbolic value */ -int pvr2_ctrl_custom_value_to_sym(struct pvr2_ctrl *, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len); - -/* Convert a symbolic value to a mask/value pair */ -int pvr2_ctrl_custom_sym_to_value(struct pvr2_ctrl *, - const char *buf,unsigned int len, - int *maskptr,int *valptr); - -/* Convert a given mask/val to a symbolic value */ -int pvr2_ctrl_value_to_sym(struct pvr2_ctrl *, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len); - -/* Convert a symbolic value to a mask/value pair */ -int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *, - const char *buf,unsigned int len, - int *maskptr,int *valptr); - -/* Convert a given mask/val to a symbolic value - must already be - inside of critical region. */ -int pvr2_ctrl_value_to_sym_internal(struct pvr2_ctrl *, - int mask,int val, - char *buf,unsigned int maxlen, - unsigned int *len); - -#endif /* __PVRUSB2_CTRL_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c deleted file mode 100644 index 27eadaff75a0..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * 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 - * - */ - -/* - - This source file is specifically designed to interface with the - cx2584x, in kernels 2.6.16 or newer. - -*/ - -#include "pvrusb2-cx2584x-v4l.h" -#include "pvrusb2-video-v4l.h" -#include "pvrusb2-i2c-cmd-v4l2.h" - - -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include -#include -#include -#include -#include - -struct pvr2_v4l_cx2584x { - struct pvr2_i2c_handler handler; - struct pvr2_decoder_ctrl ctrl; - struct pvr2_i2c_client *client; - struct pvr2_hdw *hdw; - unsigned long stale_mask; -}; - - -static void set_input(struct pvr2_v4l_cx2584x *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - struct v4l2_routing route; - enum cx25840_video_input vid_input; - enum cx25840_audio_input aud_input; - - memset(&route,0,sizeof(route)); - - switch(hdw->input_val) { - case PVR2_CVAL_INPUT_TV: - vid_input = CX25840_COMPOSITE7; - aud_input = CX25840_AUDIO8; - break; - case PVR2_CVAL_INPUT_COMPOSITE: - vid_input = CX25840_COMPOSITE3; - aud_input = CX25840_AUDIO_SERIAL; - break; - case PVR2_CVAL_INPUT_SVIDEO: - vid_input = CX25840_SVIDEO1; - aud_input = CX25840_AUDIO_SERIAL; - break; - case PVR2_CVAL_INPUT_RADIO: - default: - // Just set it to be composite input for now... - vid_input = CX25840_COMPOSITE3; - aud_input = CX25840_AUDIO_SERIAL; - break; - } - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x", - vid_input,aud_input); - route.input = (u32)vid_input; - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route); - route.input = (u32)aud_input; - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); -} - - -static int check_input(struct pvr2_v4l_cx2584x *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - return hdw->input_dirty != 0; -} - - -static void set_audio(struct pvr2_v4l_cx2584x *ctxt) -{ - u32 val; - struct pvr2_hdw *hdw = ctxt->hdw; - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_audio %d", - hdw->srate_val); - switch (hdw->srate_val) { - default: - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000: - val = 48000; - break; - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100: - val = 44100; - break; - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000: - val = 32000; - break; - } - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); -} - - -static int check_audio(struct pvr2_v4l_cx2584x *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - return hdw->srate_dirty != 0; -} - - -struct pvr2_v4l_cx2584x_ops { - void (*update)(struct pvr2_v4l_cx2584x *); - int (*check)(struct pvr2_v4l_cx2584x *); -}; - - -static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = { - { .update = set_input, .check = check_input}, - { .update = set_audio, .check = check_audio}, -}; - - -static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt) -{ - ctxt->client->handler = 0; - ctxt->hdw->decoder_ctrl = 0; - kfree(ctxt); -} - - -static int decoder_check(struct pvr2_v4l_cx2584x *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); - idx++) { - msk = 1 << idx; - if (ctxt->stale_mask & msk) continue; - if (decoder_ops[idx].check(ctxt)) { - ctxt->stale_mask |= msk; - } - } - return ctxt->stale_mask != 0; -} - - -static void decoder_update(struct pvr2_v4l_cx2584x *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); - idx++) { - msk = 1 << idx; - if (!(ctxt->stale_mask & msk)) continue; - ctxt->stale_mask &= ~msk; - decoder_ops[idx].update(ctxt); - } -} - - -static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl) -{ - pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl); - pvr2_v4l2_cmd_stream(ctxt->client,fl); -} - - -static int decoder_detect(struct pvr2_i2c_client *cp) -{ - int ret; - /* Attempt to query the decoder - let's see if it will answer */ - struct v4l2_queryctrl qc; - - memset(&qc,0,sizeof(qc)); - - qc.id = V4L2_CID_BRIGHTNESS; - - ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc); - return ret == 0; /* Return true if it answered */ -} - - -static int decoder_is_tuned(struct pvr2_v4l_cx2584x *ctxt) -{ - struct v4l2_tuner vt; - int ret; - - memset(&vt,0,sizeof(vt)); - ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt); - if (ret < 0) return -EINVAL; - return vt.signal ? 1 : 0; -} - - -static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt, - char *buf,unsigned int cnt) -{ - return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l"); -} - - -static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt) -{ - int ret; - ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,0); - pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret); -} - - -const static struct pvr2_i2c_handler_functions hfuncs = { - .detach = (void (*)(void *))decoder_detach, - .check = (int (*)(void *))decoder_check, - .update = (void (*)(void *))decoder_update, - .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe, -}; - - -int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw, - struct pvr2_i2c_client *cp) -{ - struct pvr2_v4l_cx2584x *ctxt; - - if (hdw->decoder_ctrl) return 0; - if (cp->handler) return 0; - if (!decoder_detect(cp)) return 0; - - ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); - if (!ctxt) return 0; - memset(ctxt,0,sizeof(*ctxt)); - - ctxt->handler.func_data = ctxt; - ctxt->handler.func_table = &hfuncs; - ctxt->ctrl.ctxt = ctxt; - ctxt->ctrl.detach = (void (*)(void *))decoder_detach; - ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable; - ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned; - ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset; - ctxt->client = cp; - ctxt->hdw = hdw; - ctxt->stale_mask = (1 << (sizeof(decoder_ops)/ - sizeof(decoder_ops[0]))) - 1; - hdw->decoder_ctrl = &ctxt->ctrl; - cp->handler = &ctxt->handler; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up", - cp->client->addr); - return !0; -} - - - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h deleted file mode 100644 index 54b2844e7a71..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_CX2584X_V4L_H -#define __PVRUSB2_CX2584X_V4L_H - -/* - - This module connects the pvrusb2 driver to the I2C chip level - driver which handles combined device audio & video processing. - This interface is used internally by the driver; higher level code - should only interact through the interface provided by - pvrusb2-hdw.h. - -*/ - - - -#include "pvrusb2-i2c-core.h" - -int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); - - -#endif /* __PVRUSB2_CX2584X_V4L_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-debug.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-debug.h deleted file mode 100644 index d95a8588e4f8..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-debug.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_DEBUG_H -#define __PVRUSB2_DEBUG_H - -extern int pvrusb2_debug; - -#define pvr2_trace(msk, fmt, arg...) do {if(msk & pvrusb2_debug) printk(KERN_INFO "pvrusb2: " fmt "\n", ##arg); } while (0) - -/* These are listed in *rough* order of decreasing usefulness and - increasing noise level. */ -#define PVR2_TRACE_INFO (1 << 0) // Normal messages -#define PVR2_TRACE_ERROR_LEGS (1 << 1) // error messages -#define PVR2_TRACE_TOLERANCE (1 << 2) // track tolerance-affected errors -#define PVR2_TRACE_TRAP (1 << 3) // Trap & report misbehavior from app -#define PVR2_TRACE_INIT (1 << 4) // misc initialization steps -#define PVR2_TRACE_START_STOP (1 << 5) // Streaming start / stop -#define PVR2_TRACE_CTL (1 << 6) // commit of control changes -#define PVR2_TRACE_DEBUG (1 << 7) // Temporary debug code -#define PVR2_TRACE_EEPROM (1 << 8) // eeprom parsing / report -#define PVR2_TRACE_STRUCT (1 << 9) // internal struct creation -#define PVR2_TRACE_OPEN_CLOSE (1 << 10) // application open / close -#define PVR2_TRACE_CREG (1 << 11) // Main critical region entry / exit -#define PVR2_TRACE_SYSFS (1 << 12) // Sysfs driven I/O -#define PVR2_TRACE_FIRMWARE (1 << 13) // firmware upload actions -#define PVR2_TRACE_CHIPS (1 << 14) // chip broadcast operation -#define PVR2_TRACE_I2C (1 << 15) // I2C related stuff -#define PVR2_TRACE_I2C_CMD (1 << 16) // Software commands to I2C modules -#define PVR2_TRACE_I2C_CORE (1 << 17) // I2C core debugging -#define PVR2_TRACE_I2C_TRAF (1 << 18) // I2C traffic through the adapter -#define PVR2_TRACE_V4LIOCTL (1 << 19) // v4l ioctl details -#define PVR2_TRACE_ENCODER (1 << 20) // mpeg2 encoder operation -#define PVR2_TRACE_BUF_POOL (1 << 21) // Track buffer pool management -#define PVR2_TRACE_BUF_FLOW (1 << 22) // Track buffer flow in system -#define PVR2_TRACE_DATA_FLOW (1 << 23) // Track data flow -#define PVR2_TRACE_DEBUGIFC (1 << 24) // Debug interface actions -#define PVR2_TRACE_GPIO (1 << 25) // GPIO state bit changes - - -#endif /* __PVRUSB2_HDW_INTERNAL_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.c deleted file mode 100644 index 586900e365ff..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * 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 "pvrusb2-debugifc.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-i2c-core.h" - -struct debugifc_mask_item { - const char *name; - unsigned long msk; -}; - -static struct debugifc_mask_item mask_items[] = { - {"ENC_FIRMWARE",(1<= 2) && (buf[0] == '0') && - ((buf[1] == 'x') || (buf[1] == 'X'))) { - radix = 16; - count -= 2; - buf += 2; - } else if ((count >= 1) && (buf[0] == '0')) { - radix = 8; - } - - while (count--) { - ch = *buf++; - if ((ch >= '0') && (ch <= '9')) { - val = ch - '0'; - } else if ((ch >= 'a') && (ch <= 'f')) { - val = ch - 'a' + 10; - } else if ((ch >= 'A') && (ch <= 'F')) { - val = ch - 'A' + 10; - } else { - return -EINVAL; - } - if (val >= radix) return -EINVAL; - result *= radix; - result += val; - } - *num_ptr = result; - return 0; -} - - -static int debugifc_match_keyword(const char *buf,unsigned int count, - const char *keyword) -{ - unsigned int kl; - if (!keyword) return 0; - kl = strlen(keyword); - if (kl != count) return 0; - return !memcmp(buf,keyword,kl); -} - - -static unsigned long debugifc_find_mask(const char *buf,unsigned int count) -{ - struct debugifc_mask_item *mip; - unsigned int idx; - for (idx = 0; idx < sizeof(mask_items)/sizeof(mask_items[0]); idx++) { - mip = mask_items + idx; - if (debugifc_match_keyword(buf,count,mip->name)) { - return mip->msk; - } - } - return 0; -} - - -static int debugifc_print_mask(char *buf,unsigned int sz, - unsigned long msk,unsigned long val) -{ - struct debugifc_mask_item *mip; - unsigned int idx; - int bcnt = 0; - int ccnt; - for (idx = 0; idx < sizeof(mask_items)/sizeof(mask_items[0]); idx++) { - mip = mask_items + idx; - if (!(mip->msk & msk)) continue; - ccnt = scnprintf(buf,sz,"%s%c%s", - (bcnt ? " " : ""), - ((mip->msk & val) ? '+' : '-'), - mip->name); - sz -= ccnt; - buf += ccnt; - bcnt += ccnt; - } - return bcnt; -} - -static unsigned int debugifc_parse_subsys_mask(const char *buf, - unsigned int count, - unsigned long *mskPtr, - unsigned long *valPtr) -{ - const char *wptr; - unsigned int consume_cnt = 0; - unsigned int scnt; - unsigned int wlen; - int mode; - unsigned long m1,msk,val; - - msk = 0; - val = 0; - - while (count) { - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) break; - consume_cnt += scnt; count -= scnt; buf += scnt; - if (!wptr) break; - - mode = 0; - if (wlen) switch (wptr[0]) { - case '+': - wptr++; - wlen--; - break; - case '-': - mode = 1; - wptr++; - wlen--; - break; - } - if (!wlen) continue; - m1 = debugifc_find_mask(wptr,wlen); - if (!m1) break; - msk |= m1; - if (!mode) val |= m1; - } - *mskPtr = msk; - *valPtr = val; - return consume_cnt; -} - - -int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt) -{ - int bcnt = 0; - int ccnt; - struct pvr2_hdw_debug_info dbg; - - pvr2_hdw_get_debug_info(hdw,&dbg); - - ccnt = scnprintf(buf,acnt,"big lock %s; ctl lock %s", - (dbg.big_lock_held ? "held" : "free"), - (dbg.ctl_lock_held ? "held" : "free")); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - if (dbg.ctl_lock_held) { - ccnt = scnprintf(buf,acnt,"; cmd_state=%d cmd_code=%d" - " cmd_wlen=%d cmd_rlen=%d" - " wpend=%d rpend=%d tmout=%d rstatus=%d" - " wstatus=%d", - dbg.cmd_debug_state,dbg.cmd_code, - dbg.cmd_debug_write_len, - dbg.cmd_debug_read_len, - dbg.cmd_debug_write_pend, - dbg.cmd_debug_read_pend, - dbg.cmd_debug_timeout, - dbg.cmd_debug_rstatus, - dbg.cmd_debug_wstatus); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - } - ccnt = scnprintf(buf,acnt,"\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf( - buf,acnt,"driver flags: %s %s %s\n", - (dbg.flag_init_ok ? "initialized" : "uninitialized"), - (dbg.flag_ok ? "ok" : "fail"), - (dbg.flag_disconnected ? "disconnected" : "connected")); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"Subsystems enabled / configured: "); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = debugifc_print_mask(buf,acnt,dbg.subsys_flags,dbg.subsys_flags); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"Subsystems disabled / unconfigured: "); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = debugifc_print_mask(buf,acnt,~dbg.subsys_flags,dbg.subsys_flags); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - ccnt = scnprintf(buf,acnt,"Attached I2C modules:\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = pvr2_i2c_report(hdw,buf,acnt); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - return bcnt; -} - - -int pvr2_debugifc_print_status(struct pvr2_hdw *hdw, - char *buf,unsigned int acnt) -{ - int bcnt = 0; - int ccnt; - unsigned long msk; - int ret; - u32 gpio_dir,gpio_in,gpio_out; - - ret = pvr2_hdw_is_hsm(hdw); - ccnt = scnprintf(buf,acnt,"USB link speed: %s\n", - (ret < 0 ? "FAIL" : (ret ? "high" : "full"))); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - gpio_dir = 0; gpio_in = 0; gpio_out = 0; - pvr2_hdw_gpio_get_dir(hdw,&gpio_dir); - pvr2_hdw_gpio_get_out(hdw,&gpio_out); - pvr2_hdw_gpio_get_in(hdw,&gpio_in); - ccnt = scnprintf(buf,acnt,"GPIO state: dir=0x%x in=0x%x out=0x%x\n", - gpio_dir,gpio_in,gpio_out); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - ccnt = scnprintf(buf,acnt,"Streaming is %s\n", - pvr2_hdw_get_streaming(hdw) ? "on" : "off"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - msk = pvr2_hdw_subsys_get(hdw); - ccnt = scnprintf(buf,acnt,"Subsystems enabled / configured: "); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = debugifc_print_mask(buf,acnt,msk,msk); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"Subsystems disabled / unconfigured: "); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = debugifc_print_mask(buf,acnt,~msk,msk); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - msk = pvr2_hdw_subsys_stream_get(hdw); - ccnt = scnprintf(buf,acnt,"Subsystems stopped on stream shutdown: "); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = debugifc_print_mask(buf,acnt,msk,msk); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - ccnt = scnprintf(buf,acnt,"\n"); - bcnt += ccnt; acnt -= ccnt; buf += ccnt; - - return bcnt; -} - - -int pvr2_debugifc_do1cmd(struct pvr2_hdw *hdw,const char *buf, - unsigned int count) -{ - const char *wptr; - unsigned int wlen; - unsigned int scnt; - - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return 0; - count -= scnt; buf += scnt; - if (!wptr) return 0; - - pvr2_trace(PVR2_TRACE_DEBUGIFC,"debugifc cmd: \"%.*s\"",wlen,wptr); - if (debugifc_match_keyword(wptr,wlen,"reset")) { - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return -EINVAL; - count -= scnt; buf += scnt; - if (!wptr) return -EINVAL; - if (debugifc_match_keyword(wptr,wlen,"cpu")) { - pvr2_hdw_cpureset_assert(hdw,!0); - pvr2_hdw_cpureset_assert(hdw,0); - return 0; - } else if (debugifc_match_keyword(wptr,wlen,"bus")) { - pvr2_hdw_device_reset(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"soft")) { - return pvr2_hdw_cmd_powerup(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"deep")) { - return pvr2_hdw_cmd_deep_reset(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"firmware")) { - return pvr2_upload_firmware2(hdw); - } else if (debugifc_match_keyword(wptr,wlen,"decoder")) { - return pvr2_hdw_cmd_decoder_reset(hdw); - } - return -EINVAL; - } else if (debugifc_match_keyword(wptr,wlen,"subsys_flags")) { - unsigned long msk = 0; - unsigned long val = 0; - if (debugifc_parse_subsys_mask(buf,count,&msk,&val) != count) { - pvr2_trace(PVR2_TRACE_DEBUGIFC, - "debugifc parse error on subsys mask"); - return -EINVAL; - } - pvr2_hdw_subsys_bit_chg(hdw,msk,val); - return 0; - } else if (debugifc_match_keyword(wptr,wlen,"stream_flags")) { - unsigned long msk = 0; - unsigned long val = 0; - if (debugifc_parse_subsys_mask(buf,count,&msk,&val) != count) { - pvr2_trace(PVR2_TRACE_DEBUGIFC, - "debugifc parse error on stream mask"); - return -EINVAL; - } - pvr2_hdw_subsys_stream_bit_chg(hdw,msk,val); - return 0; - } else if (debugifc_match_keyword(wptr,wlen,"cpufw")) { - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return -EINVAL; - count -= scnt; buf += scnt; - if (!wptr) return -EINVAL; - if (debugifc_match_keyword(wptr,wlen,"fetch")) { - pvr2_hdw_cpufw_set_enabled(hdw,!0); - return 0; - } else if (debugifc_match_keyword(wptr,wlen,"done")) { - pvr2_hdw_cpufw_set_enabled(hdw,0); - return 0; - } else { - return -EINVAL; - } - } else if (debugifc_match_keyword(wptr,wlen,"gpio")) { - int dir_fl = 0; - int ret; - u32 msk,val; - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return -EINVAL; - count -= scnt; buf += scnt; - if (!wptr) return -EINVAL; - if (debugifc_match_keyword(wptr,wlen,"dir")) { - dir_fl = !0; - } else if (!debugifc_match_keyword(wptr,wlen,"out")) { - return -EINVAL; - } - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (!scnt) return -EINVAL; - count -= scnt; buf += scnt; - if (!wptr) return -EINVAL; - ret = debugifc_parse_unsigned_number(wptr,wlen,&msk); - if (ret) return ret; - scnt = debugifc_isolate_word(buf,count,&wptr,&wlen); - if (wptr) { - ret = debugifc_parse_unsigned_number(wptr,wlen,&val); - if (ret) return ret; - } else { - val = msk; - msk = 0xffffffff; - } - if (dir_fl) { - ret = pvr2_hdw_gpio_chg_dir(hdw,msk,val); - } else { - ret = pvr2_hdw_gpio_chg_out(hdw,msk,val); - } - return ret; - } - pvr2_trace(PVR2_TRACE_DEBUGIFC, - "debugifc failed to recognize cmd: \"%.*s\"",wlen,wptr); - return -EINVAL; -} - - -int pvr2_debugifc_docmd(struct pvr2_hdw *hdw,const char *buf, - unsigned int count) -{ - unsigned int bcnt = 0; - int ret; - - while (count) { - for (bcnt = 0; bcnt < count; bcnt++) { - if (buf[bcnt] == '\n') break; - } - - ret = pvr2_debugifc_do1cmd(hdw,buf,bcnt); - if (ret < 0) return ret; - if (bcnt < count) bcnt++; - buf += bcnt; - count -= bcnt; - } - - return 0; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.h deleted file mode 100644 index 990b02d35d36..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-debugifc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_DEBUGIFC_H -#define __PVRUSB2_DEBUGIFC_H - -struct pvr2_hdw; - -/* Non-intrusively print some useful debugging info from inside the - driver. This should work even if the driver appears to be - wedged. */ -int pvr2_debugifc_print_info(struct pvr2_hdw *, - char *buf_ptr,unsigned int buf_size); - -/* Print general status of driver. This will also trigger a probe of - the USB link. Unlike print_info(), this one synchronizes with the - driver so the information should be self-consistent (but it will - hang if the driver is wedged). */ -int pvr2_debugifc_print_status(struct pvr2_hdw *, - char *buf_ptr,unsigned int buf_size); - -/* Parse a string command into a driver action. */ -int pvr2_debugifc_docmd(struct pvr2_hdw *, - const char *buf_ptr,unsigned int buf_size); - -#endif /* __PVRUSB2_DEBUGIFC_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-demod.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-demod.c deleted file mode 100644 index 9686569a11f6..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-demod.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * 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 "pvrusb2.h" -#include "pvrusb2-util.h" -#include "pvrusb2-demod.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include -#include -#include - - -struct pvr2_demod_handler { - struct pvr2_hdw *hdw; - struct pvr2_i2c_client *client; - struct pvr2_i2c_handler i2c_handler; - int type_update_fl; -}; - - -static void set_config(struct pvr2_demod_handler *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - int cfg = 0; - - switch (hdw->tuner_type) { - case TUNER_PHILIPS_FM1216ME_MK3: - case TUNER_PHILIPS_FM1236_MK3: - cfg = TDA9887_PORT1_ACTIVE|TDA9887_PORT2_ACTIVE; - break; - default: - break; - } - pvr2_trace(PVR2_TRACE_CHIPS,"i2c demod set_config(0x%x)",cfg); - pvr2_i2c_client_cmd(ctxt->client,TDA9887_SET_CONFIG,&cfg); - ctxt->type_update_fl = 0; -} - - -static int demod_check(struct pvr2_demod_handler *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - if (hdw->tuner_updated) ctxt->type_update_fl = !0; - return ctxt->type_update_fl != 0; -} - - -static void demod_update(struct pvr2_demod_handler *ctxt) -{ - if (ctxt->type_update_fl) set_config(ctxt); -} - - -static void demod_detach(struct pvr2_demod_handler *ctxt) -{ - ctxt->client->handler = 0; - kfree(ctxt); -} - - -static unsigned int demod_describe(struct pvr2_demod_handler *ctxt,char *buf,unsigned int cnt) -{ - return scnprintf(buf,cnt,"handler: pvrusb2-demod"); -} - - -const static struct pvr2_i2c_handler_functions tuner_funcs = { - .detach = (void (*)(void *))demod_detach, - .check = (int (*)(void *))demod_check, - .update = (void (*)(void *))demod_update, - .describe = (unsigned int (*)(void *,char *,unsigned int))demod_describe, -}; - - -int pvr2_i2c_demod_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) -{ - struct pvr2_demod_handler *ctxt; - if (cp->handler) return 0; - - ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); - if (!ctxt) return 0; - memset(ctxt,0,sizeof(*ctxt)); - - ctxt->i2c_handler.func_data = ctxt; - ctxt->i2c_handler.func_table = &tuner_funcs; - ctxt->type_update_fl = !0; - ctxt->client = cp; - ctxt->hdw = hdw; - cp->handler = &ctxt->i2c_handler; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tda9887 V4L2 handler set up", - cp->client->addr); - return !0; -} - - - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-demod.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-demod.h deleted file mode 100644 index 4c4e40ffbf03..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-demod.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_DEMOD_H -#define __PVRUSB2_DEMOD_H - -#include "pvrusb2-i2c-core.h" - -int pvr2_i2c_demod_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); - -#endif /* __PVRUSB2_DEMOD_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-eeprom.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-eeprom.c deleted file mode 100644 index 94d383ff9889..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-eeprom.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * 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 "pvrusb2-eeprom.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" - -#define trace_eeprom(...) pvr2_trace(PVR2_TRACE_EEPROM,__VA_ARGS__) - - - -/* - - Read and analyze data in the eeprom. Use tveeprom to figure out - the packet structure, since this is another Hauppauge device and - internally it has a family resemblence to ivtv-type devices - -*/ - -#include - -/* We seem to only be interested in the last 128 bytes of the EEPROM */ -#define EEPROM_SIZE 128 - -/* Grab EEPROM contents, needed for direct method. */ -static u8 *pvr2_eeprom_fetch(struct pvr2_hdw *hdw) -{ - struct i2c_msg msg[2]; - u8 *eeprom; - u8 iadd[2]; - u8 addr; - u16 eepromSize; - unsigned int offs; - int ret; - int mode16 = 0; - unsigned pcnt,tcnt; - eeprom = kmalloc(EEPROM_SIZE,GFP_KERNEL); - if (!eeprom) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to allocate memory" - " required to read eeprom"); - return 0; - } - - trace_eeprom("Value for eeprom addr from controller was 0x%x", - hdw->eeprom_addr); - addr = hdw->eeprom_addr; - /* Seems that if the high bit is set, then the *real* eeprom - address is shifted right now bit position (noticed this in - newer PVR USB2 hardware) */ - if (addr & 0x80) addr >>= 1; - - /* FX2 documentation states that a 16bit-addressed eeprom is - expected if the I2C address is an odd number (yeah, this is - strange but it's what they do) */ - mode16 = (addr & 1); - eepromSize = (mode16 ? 4096 : 256); - trace_eeprom("Examining %d byte eeprom at location 0x%x" - " using %d bit addressing",eepromSize,addr, - mode16 ? 16 : 8); - - msg[0].addr = addr; - msg[0].flags = 0; - msg[0].len = mode16 ? 2 : 1; - msg[0].buf = iadd; - msg[1].addr = addr; - msg[1].flags = I2C_M_RD; - - /* We have to do the actual eeprom data fetch ourselves, because - (1) we're only fetching part of the eeprom, and (2) if we were - getting the whole thing our I2C driver can't grab it in one - pass - which is what tveeprom is otherwise going to attempt */ - memset(eeprom,0,EEPROM_SIZE); - for (tcnt = 0; tcnt < EEPROM_SIZE; tcnt += pcnt) { - pcnt = 16; - if (pcnt + tcnt > EEPROM_SIZE) pcnt = EEPROM_SIZE-tcnt; - offs = tcnt + (eepromSize - EEPROM_SIZE); - if (mode16) { - iadd[0] = offs >> 8; - iadd[1] = offs; - } else { - iadd[0] = offs; - } - msg[1].len = pcnt; - msg[1].buf = eeprom+tcnt; - if ((ret = i2c_transfer( - &hdw->i2c_adap, - msg,sizeof(msg)/sizeof(msg[0]))) != 2) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "eeprom fetch set offs err=%d",ret); - kfree(eeprom); - return 0; - } - } - return eeprom; -} - - -/* Directly call eeprom analysis function within tveeprom. */ -int pvr2_eeprom_analyze(struct pvr2_hdw *hdw) -{ - u8 *eeprom; - struct tveeprom tvdata; - - memset(&tvdata,0,sizeof(tvdata)); - - eeprom = pvr2_eeprom_fetch(hdw); - if (!eeprom) return -EINVAL; - - { - struct i2c_client fake_client; - /* Newer version expects a useless client interface */ - fake_client.addr = hdw->eeprom_addr; - fake_client.adapter = &hdw->i2c_adap; - tveeprom_hauppauge_analog(&fake_client,&tvdata,eeprom); - } - - trace_eeprom("eeprom assumed v4l tveeprom module"); - trace_eeprom("eeprom direct call results:"); - trace_eeprom("has_radio=%d",tvdata.has_radio); - trace_eeprom("tuner_type=%d",tvdata.tuner_type); - trace_eeprom("tuner_formats=0x%x",tvdata.tuner_formats); - trace_eeprom("audio_processor=%d",tvdata.audio_processor); - trace_eeprom("model=%d",tvdata.model); - trace_eeprom("revision=%d",tvdata.revision); - trace_eeprom("serial_number=%d",tvdata.serial_number); - trace_eeprom("rev_str=%s",tvdata.rev_str); - hdw->tuner_type = tvdata.tuner_type; - hdw->serial_number = tvdata.serial_number; - hdw->std_mask_eeprom = tvdata.tuner_formats; - - kfree(eeprom); - - return 0; -} - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-eeprom.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-eeprom.h deleted file mode 100644 index 84242975dea7..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-eeprom.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_EEPROM_H -#define __PVRUSB2_EEPROM_H - -struct pvr2_hdw; - -int pvr2_eeprom_analyze(struct pvr2_hdw *); - -#endif /* __PVRUSB2_EEPROM_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c deleted file mode 100644 index 2cc31695b435..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-encoder.c +++ /dev/null @@ -1,418 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * 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 // for linux/firmware.h -#include -#include "pvrusb2-util.h" -#include "pvrusb2-encoder.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" - - - -/* Firmware mailbox flags - definitions found from ivtv */ -#define IVTV_MBOX_FIRMWARE_DONE 0x00000004 -#define IVTV_MBOX_DRIVER_DONE 0x00000002 -#define IVTV_MBOX_DRIVER_BUSY 0x00000001 - - -static int pvr2_encoder_write_words(struct pvr2_hdw *hdw, - const u32 *data, unsigned int dlen) -{ - unsigned int idx; - int ret; - unsigned int offs = 0; - unsigned int chunkCnt; - - /* - - Format: First byte must be 0x01. Remaining 32 bit words are - spread out into chunks of 7 bytes each, little-endian ordered, - offset at zero within each 2 blank bytes following and a - single byte that is 0x44 plus the offset of the word. Repeat - request for additional words, with offset adjusted - accordingly. - - */ - while (dlen) { - chunkCnt = 8; - if (chunkCnt > dlen) chunkCnt = dlen; - memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer)); - hdw->cmd_buffer[0] = 0x01; - for (idx = 0; idx < chunkCnt; idx++) { - hdw->cmd_buffer[1+(idx*7)+6] = 0x44 + idx + offs; - PVR2_DECOMPOSE_LE(hdw->cmd_buffer, 1+(idx*7), - data[idx]); - } - ret = pvr2_send_request(hdw, - hdw->cmd_buffer,1+(chunkCnt*7), - 0,0); - if (ret) return ret; - data += chunkCnt; - dlen -= chunkCnt; - offs += chunkCnt; - } - - return 0; -} - - -static int pvr2_encoder_read_words(struct pvr2_hdw *hdw,int statusFl, - u32 *data, unsigned int dlen) -{ - unsigned int idx; - int ret; - unsigned int offs = 0; - unsigned int chunkCnt; - - /* - - Format: First byte must be 0x02 (status check) or 0x28 (read - back block of 32 bit words). Next 6 bytes must be zero, - followed by a single byte of 0x44+offset for portion to be - read. Returned data is packed set of 32 bits words that were - read. - - */ - - while (dlen) { - chunkCnt = 16; - if (chunkCnt > dlen) chunkCnt = dlen; - memset(hdw->cmd_buffer,0,sizeof(hdw->cmd_buffer)); - hdw->cmd_buffer[0] = statusFl ? 0x02 : 0x28; - hdw->cmd_buffer[7] = 0x44 + offs; - ret = pvr2_send_request(hdw, - hdw->cmd_buffer,8, - hdw->cmd_buffer,chunkCnt * 4); - if (ret) return ret; - - for (idx = 0; idx < chunkCnt; idx++) { - data[idx] = PVR2_COMPOSE_LE(hdw->cmd_buffer,idx*4); - } - data += chunkCnt; - dlen -= chunkCnt; - offs += chunkCnt; - } - - return 0; -} - - -/* This prototype is set up to be compatible with the - cx2341x_mbox_func prototype in cx2341x.h, which should be in - kernels 2.6.18 or later. We do this so that we can enable - cx2341x.ko to write to our encoder (by handing it a pointer to this - function). For earlier kernels this doesn't really matter. */ -static int pvr2_encoder_cmd(void *ctxt, - int cmd, - int arg_cnt_send, - int arg_cnt_recv, - u32 *argp) -{ - unsigned int poll_count; - int ret = 0; - unsigned int idx; - /* These sizes look to be limited by the FX2 firmware implementation */ - u32 wrData[16]; - u32 rdData[16]; - struct pvr2_hdw *hdw = (struct pvr2_hdw *)ctxt; - - - /* - - The encoder seems to speak entirely using blocks 32 bit words. - In ivtv driver terms, this is a mailbox which we populate with - data and watch what the hardware does with it. The first word - is a set of flags used to control the transaction, the second - word is the command to execute, the third byte is zero (ivtv - driver suggests that this is some kind of return value), and - the fourth byte is a specified timeout (windows driver always - uses 0x00060000 except for one case when it is zero). All - successive words are the argument words for the command. - - First, write out the entire set of words, with the first word - being zero. - - Next, write out just the first word again, but set it to - IVTV_MBOX_DRIVER_DONE | IVTV_DRIVER_BUSY this time (which - probably means "go"). - - Next, read back 16 words as status. Check the first word, - which should have IVTV_MBOX_FIRMWARE_DONE set. If however - that bit is not set, then the command isn't done so repeat the - read. - - Next, read back 32 words and compare with the original - arugments. Hopefully they will match. - - Finally, write out just the first word again, but set it to - 0x0 this time (which probably means "idle"). - - */ - - if (arg_cnt_send > (sizeof(wrData)/sizeof(wrData[0]))-4) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Failed to write cx23416 command" - " - too many input arguments" - " (was given %u limit %u)", - arg_cnt_send, - (unsigned int)(sizeof(wrData)/sizeof(wrData[0])) - 4); - return -EINVAL; - } - - if (arg_cnt_recv > (sizeof(rdData)/sizeof(rdData[0]))-4) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Failed to write cx23416 command" - " - too many return arguments" - " (was given %u limit %u)", - arg_cnt_recv, - (unsigned int)(sizeof(rdData)/sizeof(rdData[0])) - 4); - return -EINVAL; - } - - - LOCK_TAKE(hdw->ctl_lock); do { - - wrData[0] = 0; - wrData[1] = cmd; - wrData[2] = 0; - wrData[3] = 0x00060000; - for (idx = 0; idx < arg_cnt_send; idx++) { - wrData[idx+4] = argp[idx]; - } - for (; idx < (sizeof(wrData)/sizeof(wrData[0]))-4; idx++) { - wrData[idx+4] = 0; - } - - ret = pvr2_encoder_write_words(hdw,wrData,idx); - if (ret) break; - wrData[0] = IVTV_MBOX_DRIVER_DONE|IVTV_MBOX_DRIVER_BUSY; - ret = pvr2_encoder_write_words(hdw,wrData,1); - if (ret) break; - poll_count = 0; - while (1) { - if (poll_count < 10000000) poll_count++; - ret = pvr2_encoder_read_words(hdw,!0,rdData,1); - if (ret) break; - if (rdData[0] & IVTV_MBOX_FIRMWARE_DONE) { - break; - } - if (poll_count == 100) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "***WARNING*** device's encoder" - " appears to be stuck" - " (status=0%08x)",rdData[0]); - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Encoder command: 0x%02x",cmd); - for (idx = 4; idx < arg_cnt_send; idx++) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Encoder arg%d: 0x%08x", - idx-3,wrData[idx]); - } - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Giving up waiting." - " It is likely that" - " this is a bad idea..."); - ret = -EBUSY; - break; - } - } - if (ret) break; - wrData[0] = 0x7; - ret = pvr2_encoder_read_words( - hdw,0,rdData, - sizeof(rdData)/sizeof(rdData[0])); - if (ret) break; - for (idx = 0; idx < arg_cnt_recv; idx++) { - argp[idx] = rdData[idx+4]; - } - - wrData[0] = 0x0; - ret = pvr2_encoder_write_words(hdw,wrData,1); - if (ret) break; - - } while(0); LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -static int pvr2_encoder_vcmd(struct pvr2_hdw *hdw, int cmd, - int args, ...) -{ - va_list vl; - unsigned int idx; - u32 data[12]; - - if (args > sizeof(data)/sizeof(data[0])) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Failed to write cx23416 command" - " - too many arguments" - " (was given %u limit %u)", - args,(unsigned int)(sizeof(data)/sizeof(data[0]))); - return -EINVAL; - } - - va_start(vl, args); - for (idx = 0; idx < args; idx++) { - data[idx] = va_arg(vl, u32); - } - va_end(vl); - - return pvr2_encoder_cmd(hdw,cmd,args,0,data); -} - -int pvr2_encoder_configure(struct pvr2_hdw *hdw) -{ - int ret; - pvr2_trace(PVR2_TRACE_ENCODER,"pvr2_encoder_configure" - " (cx2341x module)"); - hdw->enc_ctl_state.port = CX2341X_PORT_STREAMING; - hdw->enc_ctl_state.width = hdw->res_hor_val; - hdw->enc_ctl_state.height = hdw->res_ver_val; - hdw->enc_ctl_state.is_50hz = ((hdw->std_mask_cur & - (V4L2_STD_NTSC|V4L2_STD_PAL_M)) ? - 0 : 1); - - ret = 0; - - if (!ret) ret = pvr2_encoder_vcmd( - hdw,CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, - 0xf0, 0xf0); - - /* setup firmware to notify us about some events (don't know why...) */ - if (!ret) ret = pvr2_encoder_vcmd( - hdw,CX2341X_ENC_SET_EVENT_NOTIFICATION, 4, - 0, 0, 0x10000000, 0xffffffff); - - if (!ret) ret = pvr2_encoder_vcmd( - hdw,CX2341X_ENC_SET_VBI_LINE, 5, - 0xffffffff,0,0,0,0); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to configure cx32416"); - return ret; - } - - ret = cx2341x_update(hdw,pvr2_encoder_cmd, - (hdw->enc_cur_valid ? &hdw->enc_cur_state : 0), - &hdw->enc_ctl_state); - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Error from cx2341x module code=%d",ret); - return ret; - } - - ret = 0; - - if (!ret) ret = pvr2_encoder_vcmd( - hdw, CX2341X_ENC_INITIALIZE_INPUT, 0); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to initialize cx32416 video input"); - return ret; - } - - hdw->subsys_enabled_mask |= (1<enc_cur_state,&hdw->enc_ctl_state, - sizeof(struct cx2341x_mpeg_params)); - hdw->enc_cur_valid = !0; - return 0; -} - - -int pvr2_encoder_start(struct pvr2_hdw *hdw) -{ - int status; - - /* unmask some interrupts */ - pvr2_write_register(hdw, 0x0048, 0xbfffffff); - - /* change some GPIO data */ - pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000481); - pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000); - - if (hdw->config == pvr2_config_vbi) { - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, - 0x01,0x14); - } else if (hdw->config == pvr2_config_mpeg) { - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, - 0,0x13); - } else { - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_START_CAPTURE,2, - 0,0x13); - } - if (!status) { - hdw->subsys_enabled_mask |= (1<config == pvr2_config_vbi) { - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, - 0x01,0x01,0x14); - } else if (hdw->config == pvr2_config_mpeg) { - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, - 0x01,0,0x13); - } else { - status = pvr2_encoder_vcmd(hdw,CX2341X_ENC_STOP_CAPTURE,3, - 0x01,0,0x13); - } - - /* change some GPIO data */ - /* Note: Bit d7 of dir appears to control the LED. So we shut it - off here. */ - pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000401); - pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000000); - - if (!status) { - hdw->subsys_enabled_mask &= ~(1< - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_ENCODER_H -#define __PVRUSB2_ENCODER_H - -struct pvr2_hdw; - -int pvr2_encoder_configure(struct pvr2_hdw *); -int pvr2_encoder_start(struct pvr2_hdw *); -int pvr2_encoder_stop(struct pvr2_hdw *); - -#endif /* __PVRUSB2_ENCODER_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h deleted file mode 100644 index ba2afbfe32c5..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h +++ /dev/null @@ -1,384 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_HDW_INTERNAL_H -#define __PVRUSB2_HDW_INTERNAL_H - -/* - - This header sets up all the internal structures and definitions needed to - track and coordinate the driver's interaction with the hardware. ONLY - source files which actually implement part of that whole circus should be - including this header. Higher levels, like the external layers to the - various public APIs (V4L, sysfs, etc) should NOT ever include this - private, internal header. This means that pvrusb2-hdw, pvrusb2-encoder, - etc will include this, but pvrusb2-v4l should not. - -*/ - -#include -#include -#include -#include -#include "pvrusb2-hdw.h" -#include "pvrusb2-io.h" -#include - -/* Legal values for the SRATE state variable */ -#define PVR2_CVAL_SRATE_48 0 -#define PVR2_CVAL_SRATE_44_1 1 - -/* Legal values for the AUDIOBITRATE state variable */ -#define PVR2_CVAL_AUDIOBITRATE_384 0 -#define PVR2_CVAL_AUDIOBITRATE_320 1 -#define PVR2_CVAL_AUDIOBITRATE_256 2 -#define PVR2_CVAL_AUDIOBITRATE_224 3 -#define PVR2_CVAL_AUDIOBITRATE_192 4 -#define PVR2_CVAL_AUDIOBITRATE_160 5 -#define PVR2_CVAL_AUDIOBITRATE_128 6 -#define PVR2_CVAL_AUDIOBITRATE_112 7 -#define PVR2_CVAL_AUDIOBITRATE_96 8 -#define PVR2_CVAL_AUDIOBITRATE_80 9 -#define PVR2_CVAL_AUDIOBITRATE_64 10 -#define PVR2_CVAL_AUDIOBITRATE_56 11 -#define PVR2_CVAL_AUDIOBITRATE_48 12 -#define PVR2_CVAL_AUDIOBITRATE_32 13 -#define PVR2_CVAL_AUDIOBITRATE_VBR 14 - -/* Legal values for the AUDIOEMPHASIS state variable */ -#define PVR2_CVAL_AUDIOEMPHASIS_NONE 0 -#define PVR2_CVAL_AUDIOEMPHASIS_50_15 1 -#define PVR2_CVAL_AUDIOEMPHASIS_CCITT 2 - -/* Legal values for PVR2_CID_HSM */ -#define PVR2_CVAL_HSM_FAIL 0 -#define PVR2_CVAL_HSM_FULL 1 -#define PVR2_CVAL_HSM_HIGH 2 - -#define PVR2_VID_ENDPOINT 0x84 -#define PVR2_UNK_ENDPOINT 0x86 /* maybe raw yuv ? */ -#define PVR2_VBI_ENDPOINT 0x88 - -#define PVR2_CTL_BUFFSIZE 64 - -#define FREQTABLE_SIZE 500 - -#define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0) -#define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0) - -struct pvr2_decoder; - -typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *); -typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *); -typedef int (*pvr2_ctlf_get_value)(struct pvr2_ctrl *,int *); -typedef int (*pvr2_ctlf_set_value)(struct pvr2_ctrl *,int msk,int val); -typedef int (*pvr2_ctlf_val_to_sym)(struct pvr2_ctrl *,int msk,int val, - char *,unsigned int,unsigned int *); -typedef int (*pvr2_ctlf_sym_to_val)(struct pvr2_ctrl *, - const char *,unsigned int, - int *mskp,int *valp); -typedef unsigned int (*pvr2_ctlf_get_v4lflags)(struct pvr2_ctrl *); - -/* This structure describes a specific control. A table of these is set up - in pvrusb2-hdw.c. */ -struct pvr2_ctl_info { - /* Control's name suitable for use as an identifier */ - const char *name; - - /* Short description of control */ - const char *desc; - - /* Control's implementation */ - pvr2_ctlf_get_value get_value; /* Get its value */ - pvr2_ctlf_set_value set_value; /* Set its value */ - pvr2_ctlf_val_to_sym val_to_sym; /* Custom convert value->symbol */ - pvr2_ctlf_sym_to_val sym_to_val; /* Custom convert symbol->value */ - pvr2_ctlf_is_dirty is_dirty; /* Return true if dirty */ - pvr2_ctlf_clear_dirty clear_dirty; /* Clear dirty state */ - pvr2_ctlf_get_v4lflags get_v4lflags;/* Retrieve v4l flags */ - - /* Control's type (int, enum, bitmask) */ - enum pvr2_ctl_type type; - - /* Associated V4L control ID, if any */ - int v4l_id; - - /* Associated driver internal ID, if any */ - int internal_id; - - /* Don't implicitly initialize this control's value */ - int skip_init; - - /* Starting value for this control */ - int default_value; - - /* Type-specific control information */ - union { - struct { /* Integer control */ - long min_value; /* lower limit */ - long max_value; /* upper limit */ - } type_int; - struct { /* enumerated control */ - unsigned int count; /* enum value count */ - const char **value_names; /* symbol names */ - } type_enum; - struct { /* bitmask control */ - unsigned int valid_bits; /* bits in use */ - const char **bit_names; /* symbol name/bit */ - } type_bitmask; - } def; -}; - - -/* Same as pvr2_ctl_info, but includes storage for the control description */ -#define PVR2_CTLD_INFO_DESC_SIZE 32 -struct pvr2_ctld_info { - struct pvr2_ctl_info info; - char desc[PVR2_CTLD_INFO_DESC_SIZE]; -}; - -struct pvr2_ctrl { - const struct pvr2_ctl_info *info; - struct pvr2_hdw *hdw; -}; - - -struct pvr2_audio_stat { - void *ctxt; - void (*detach)(void *); - int (*status)(void *); -}; - -struct pvr2_decoder_ctrl { - void *ctxt; - void (*detach)(void *); - void (*enable)(void *,int); - int (*tuned)(void *); - void (*force_reset)(void *); -}; - -#define PVR2_I2C_PEND_DETECT 0x01 /* Need to detect a client type */ -#define PVR2_I2C_PEND_CLIENT 0x02 /* Client needs a specific update */ -#define PVR2_I2C_PEND_REFRESH 0x04 /* Client has specific pending bits */ -#define PVR2_I2C_PEND_STALE 0x08 /* Broadcast pending bits */ - -#define PVR2_I2C_PEND_ALL (PVR2_I2C_PEND_DETECT |\ - PVR2_I2C_PEND_CLIENT |\ - PVR2_I2C_PEND_REFRESH |\ - PVR2_I2C_PEND_STALE) - -/* Disposition of firmware1 loading situation */ -#define FW1_STATE_UNKNOWN 0 -#define FW1_STATE_MISSING 1 -#define FW1_STATE_FAILED 2 -#define FW1_STATE_RELOAD 3 -#define FW1_STATE_OK 4 - -/* Known major hardware variants, keyed from device ID */ -#define PVR2_HDW_TYPE_29XXX 0 -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX -#define PVR2_HDW_TYPE_24XXX 1 -#endif - -typedef int (*pvr2_i2c_func)(struct pvr2_hdw *,u8,u8 *,u16,u8 *, u16); -#define PVR2_I2C_FUNC_CNT 128 - -/* This structure contains all state data directly needed to - manipulate the hardware (as opposed to complying with a kernel - interface) */ -struct pvr2_hdw { - /* Underlying USB device handle */ - struct usb_device *usb_dev; - struct usb_interface *usb_intf; - - /* Device type, one of PVR2_HDW_TYPE_xxxxx */ - unsigned int hdw_type; - - /* Video spigot */ - struct pvr2_stream *vid_stream; - - /* Mutex for all hardware state control */ - struct mutex big_lock_mutex; - int big_lock_held; /* For debugging */ - - void (*poll_trigger_func)(void *); - void *poll_trigger_data; - - char name[32]; - - /* I2C stuff */ - struct i2c_adapter i2c_adap; - struct i2c_algorithm i2c_algo; - pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT]; - int i2c_cx25840_hack_state; - int i2c_linked; - unsigned int i2c_pend_types; /* Which types of update are needed */ - unsigned long i2c_pend_mask; /* Change bits we need to scan */ - unsigned long i2c_stale_mask; /* Pending broadcast change bits */ - unsigned long i2c_active_mask; /* All change bits currently in use */ - struct list_head i2c_clients; - struct mutex i2c_list_lock; - - /* Frequency table */ - unsigned int freqTable[FREQTABLE_SIZE]; - unsigned int freqProgSlot; - unsigned int freqSlot; - - /* Stuff for handling low level control interaction with device */ - struct mutex ctl_lock_mutex; - int ctl_lock_held; /* For debugging */ - struct urb *ctl_write_urb; - struct urb *ctl_read_urb; - unsigned char *ctl_write_buffer; - unsigned char *ctl_read_buffer; - volatile int ctl_write_pend_flag; - volatile int ctl_read_pend_flag; - volatile int ctl_timeout_flag; - struct completion ctl_done; - unsigned char cmd_buffer[PVR2_CTL_BUFFSIZE]; - int cmd_debug_state; // Low level command debugging info - unsigned char cmd_debug_code; // - unsigned int cmd_debug_write_len; // - unsigned int cmd_debug_read_len; // - - int flag_ok; // device in known good state - int flag_disconnected; // flag_ok == 0 due to disconnect - int flag_init_ok; // true if structure is fully initialized - int flag_streaming_enabled; // true if streaming should be on - int fw1_state; // current situation with fw1 - - int flag_decoder_is_tuned; - - struct pvr2_decoder_ctrl *decoder_ctrl; - - // CPU firmware info (used to help find / save firmware data) - char *fw_buffer; - unsigned int fw_size; - - // Which subsystem pieces have been enabled / configured - unsigned long subsys_enabled_mask; - - // Which subsystems are manipulated to enable streaming - unsigned long subsys_stream_mask; - - // True if there is a request to trigger logging of state in each - // module. - int log_requested; - - /* Tuner / frequency control stuff */ - unsigned int tuner_type; - int tuner_updated; - unsigned int freqVal; - int freqDirty; - - /* Video standard handling */ - v4l2_std_id std_mask_eeprom; // Hardware supported selections - v4l2_std_id std_mask_avail; // Which standards we may select from - v4l2_std_id std_mask_cur; // Currently selected standard(s) - unsigned int std_enum_cnt; // # of enumerated standards - int std_enum_cur; // selected standard enumeration value - int std_dirty; // True if std_mask_cur has changed - struct pvr2_ctl_info std_info_enum; - struct pvr2_ctl_info std_info_avail; - struct pvr2_ctl_info std_info_cur; - struct v4l2_standard *std_defs; - const char **std_enum_names; - - // Generated string names, one per actual V4L2 standard - const char *std_mask_ptrs[32]; - char std_mask_names[32][10]; - - int unit_number; /* ID for driver instance */ - unsigned long serial_number; /* ID for hardware itself */ - - /* Minor number used by v4l logic (yes, this is a hack, as there should - be no v4l junk here). Probably a better way to do this. */ - int v4l_minor_number; - - /* Location of eeprom or a negative number if none */ - int eeprom_addr; - - enum pvr2_config config; - - /* Information about what audio signal we're hearing */ - int flag_stereo; - int flag_bilingual; - struct pvr2_audio_stat *audio_stat; - - /* Control state needed for cx2341x module */ - struct cx2341x_mpeg_params enc_cur_state; - struct cx2341x_mpeg_params enc_ctl_state; - /* True if an encoder attribute has changed */ - int enc_stale; - /* True if enc_cur_state is valid */ - int enc_cur_valid; - - /* Control state */ -#define VCREATE_DATA(lab) int lab##_val; int lab##_dirty - VCREATE_DATA(brightness); - VCREATE_DATA(contrast); - VCREATE_DATA(saturation); - VCREATE_DATA(hue); - VCREATE_DATA(volume); - VCREATE_DATA(balance); - VCREATE_DATA(bass); - VCREATE_DATA(treble); - VCREATE_DATA(mute); - VCREATE_DATA(input); - VCREATE_DATA(audiomode); - VCREATE_DATA(res_hor); - VCREATE_DATA(res_ver); - VCREATE_DATA(srate); -#undef VCREATE_DATA - - struct pvr2_ctld_info *mpeg_ctrl_info; - - struct pvr2_ctrl *controls; - unsigned int control_cnt; -}; - -int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw); - -unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *); - -void pvr2_hdw_subsys_bit_chg_no_lock(struct pvr2_hdw *hdw, - unsigned long msk,unsigned long val); -void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw, - unsigned long msk, - unsigned long val); - -void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw); -void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw); - -int pvr2_i2c_basic_op(struct pvr2_hdw *,u8 i2c_addr, - u8 *wdata,u16 wlen, - u8 *rdata,u16 rlen); - -#endif /* __PVRUSB2_HDW_INTERNAL_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c deleted file mode 100644 index 643c471375da..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ /dev/null @@ -1,3120 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * 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 "pvrusb2.h" -#include "pvrusb2-std.h" -#include "pvrusb2-util.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2-i2c-core.h" -#include "pvrusb2-tuner.h" -#include "pvrusb2-eeprom.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-encoder.h" -#include "pvrusb2-debug.h" - -struct usb_device_id pvr2_device_table[] = { - [PVR2_HDW_TYPE_29XXX] = { USB_DEVICE(0x2040, 0x2900) }, -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - [PVR2_HDW_TYPE_24XXX] = { USB_DEVICE(0x2040, 0x2400) }, -#endif - { } -}; - -MODULE_DEVICE_TABLE(usb, pvr2_device_table); - -static const char *pvr2_device_names[] = { - [PVR2_HDW_TYPE_29XXX] = "WinTV PVR USB2 Model Category 29xxxx", -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - [PVR2_HDW_TYPE_24XXX] = "WinTV PVR USB2 Model Category 24xxxx", -#endif -}; - -struct pvr2_string_table { - const char **lst; - unsigned int cnt; -}; - -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX -// Names of other client modules to request for 24xxx model hardware -static const char *pvr2_client_24xxx[] = { - "cx25840", - "tuner", - "tda9887", - "wm8775", -}; -#endif - -// Names of other client modules to request for 29xxx model hardware -static const char *pvr2_client_29xxx[] = { - "msp3400", - "saa7115", - "tuner", - "tda9887", -}; - -static struct pvr2_string_table pvr2_client_lists[] = { - [PVR2_HDW_TYPE_29XXX] = { - pvr2_client_29xxx, - sizeof(pvr2_client_29xxx)/sizeof(pvr2_client_29xxx[0]), - }, -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - [PVR2_HDW_TYPE_24XXX] = { - pvr2_client_24xxx, - sizeof(pvr2_client_24xxx)/sizeof(pvr2_client_24xxx[0]), - }, -#endif -}; - -static struct pvr2_hdw *unit_pointers[PVR_NUM] = {[ 0 ... PVR_NUM-1 ] = 0}; -DECLARE_MUTEX(pvr2_unit_sem); - -static int ctlchg = 0; -static int initusbreset = 1; -static int procreload = 0; -static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 }; -static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; -static int video_std[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; -static int init_pause_msec = 0; - -module_param(ctlchg, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value"); -module_param(init_pause_msec, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(init_pause_msec, "hardware initialization settling delay"); -module_param(initusbreset, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(initusbreset, "Do USB reset device on probe"); -module_param(procreload, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(procreload, - "Attempt init failure recovery with firmware reload"); -module_param_array(tuner, int, NULL, 0444); -MODULE_PARM_DESC(tuner,"specify installed tuner type"); -module_param_array(video_std, int, NULL, 0444); -MODULE_PARM_DESC(video_std,"specify initial video standard"); -module_param_array(tolerance, int, NULL, 0444); -MODULE_PARM_DESC(tolerance,"specify stream error tolerance"); - -#define PVR2_CTL_WRITE_ENDPOINT 0x01 -#define PVR2_CTL_READ_ENDPOINT 0x81 - -#define PVR2_GPIO_IN 0x9008 -#define PVR2_GPIO_OUT 0x900c -#define PVR2_GPIO_DIR 0x9020 - -#define trace_firmware(...) pvr2_trace(PVR2_TRACE_FIRMWARE,__VA_ARGS__) - -#define PVR2_FIRMWARE_ENDPOINT 0x02 - -/* size of a firmware chunk */ -#define FIRMWARE_CHUNK_SIZE 0x2000 - -/* Define the list of additional controls we'll dynamically construct based - on query of the cx2341x module. */ -struct pvr2_mpeg_ids { - const char *strid; - int id; -}; -static const struct pvr2_mpeg_ids mpeg_ids[] = { - { - .strid = "audio_layer", - .id = V4L2_CID_MPEG_AUDIO_ENCODING, - },{ - .strid = "audio_bitrate", - .id = V4L2_CID_MPEG_AUDIO_L2_BITRATE, - },{ - /* Already using audio_mode elsewhere :-( */ - .strid = "mpeg_audio_mode", - .id = V4L2_CID_MPEG_AUDIO_MODE, - },{ - .strid = "mpeg_audio_mode_extension", - .id = V4L2_CID_MPEG_AUDIO_MODE_EXTENSION, - },{ - .strid = "audio_emphasis", - .id = V4L2_CID_MPEG_AUDIO_EMPHASIS, - },{ - .strid = "audio_crc", - .id = V4L2_CID_MPEG_AUDIO_CRC, - },{ - .strid = "video_aspect", - .id = V4L2_CID_MPEG_VIDEO_ASPECT, - },{ - .strid = "video_b_frames", - .id = V4L2_CID_MPEG_VIDEO_B_FRAMES, - },{ - .strid = "video_gop_size", - .id = V4L2_CID_MPEG_VIDEO_GOP_SIZE, - },{ - .strid = "video_gop_closure", - .id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE, - },{ - .strid = "video_pulldown", - .id = V4L2_CID_MPEG_VIDEO_PULLDOWN, - },{ - .strid = "video_bitrate_mode", - .id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE, - },{ - .strid = "video_bitrate", - .id = V4L2_CID_MPEG_VIDEO_BITRATE, - },{ - .strid = "video_bitrate_peak", - .id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK, - },{ - .strid = "video_temporal_decimation", - .id = V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION, - },{ - .strid = "stream_type", - .id = V4L2_CID_MPEG_STREAM_TYPE, - },{ - .strid = "video_spatial_filter_mode", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE, - },{ - .strid = "video_spatial_filter", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER, - },{ - .strid = "video_luma_spatial_filter_type", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE, - },{ - .strid = "video_chroma_spatial_filter_type", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE, - },{ - .strid = "video_temporal_filter_mode", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE, - },{ - .strid = "video_temporal_filter", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER, - },{ - .strid = "video_median_filter_type", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE, - },{ - .strid = "video_luma_median_filter_top", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP, - },{ - .strid = "video_luma_median_filter_bottom", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM, - },{ - .strid = "video_chroma_median_filter_top", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP, - },{ - .strid = "video_chroma_median_filter_bottom", - .id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM, - } -}; -#define MPEGDEF_COUNT (sizeof(mpeg_ids)/sizeof(mpeg_ids[0])) - -static const char *control_values_srate[] = { - [PVR2_CVAL_SRATE_48] = "48KHz", - [PVR2_CVAL_SRATE_44_1] = "44.1KHz", -}; - - - - -static const char *control_values_input[] = { - [PVR2_CVAL_INPUT_TV] = "television", /*xawtv needs this name*/ - [PVR2_CVAL_INPUT_RADIO] = "radio", - [PVR2_CVAL_INPUT_SVIDEO] = "s-video", - [PVR2_CVAL_INPUT_COMPOSITE] = "composite", -}; - - -static const char *control_values_audiomode[] = { - [V4L2_TUNER_MODE_MONO] = "Mono", - [V4L2_TUNER_MODE_STEREO] = "Stereo", - [V4L2_TUNER_MODE_LANG1] = "Lang1", - [V4L2_TUNER_MODE_LANG2] = "Lang2", - [V4L2_TUNER_MODE_LANG1_LANG2] = "Lang1+Lang2", -}; - - -static const char *control_values_hsm[] = { - [PVR2_CVAL_HSM_FAIL] = "Fail", - [PVR2_CVAL_HSM_HIGH] = "High", - [PVR2_CVAL_HSM_FULL] = "Full", -}; - - -static const char *control_values_subsystem[] = { - [PVR2_SUBSYS_B_ENC_FIRMWARE] = "enc_firmware", - [PVR2_SUBSYS_B_ENC_CFG] = "enc_config", - [PVR2_SUBSYS_B_DIGITIZER_RUN] = "digitizer_run", - [PVR2_SUBSYS_B_USBSTREAM_RUN] = "usbstream_run", - [PVR2_SUBSYS_B_ENC_RUN] = "enc_run", -}; - - -static int ctrl_channelfreq_get(struct pvr2_ctrl *cptr,int *vp) -{ - struct pvr2_hdw *hdw = cptr->hdw; - if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) { - *vp = hdw->freqTable[hdw->freqProgSlot-1]; - } else { - *vp = 0; - } - return 0; -} - -static int ctrl_channelfreq_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - if ((hdw->freqProgSlot > 0) && (hdw->freqProgSlot <= FREQTABLE_SIZE)) { - hdw->freqTable[hdw->freqProgSlot-1] = v; - } - return 0; -} - -static int ctrl_channelprog_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->freqProgSlot; - return 0; -} - -static int ctrl_channelprog_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - if ((v >= 0) && (v <= FREQTABLE_SIZE)) { - hdw->freqProgSlot = v; - } - return 0; -} - -static int ctrl_channel_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->freqSlot; - return 0; -} - -static int ctrl_channel_set(struct pvr2_ctrl *cptr,int m,int v) -{ - unsigned freq = 0; - struct pvr2_hdw *hdw = cptr->hdw; - hdw->freqSlot = v; - if ((hdw->freqSlot > 0) && (hdw->freqSlot <= FREQTABLE_SIZE)) { - freq = hdw->freqTable[hdw->freqSlot-1]; - } - if (freq && (freq != hdw->freqVal)) { - hdw->freqVal = freq; - hdw->freqDirty = !0; - } - return 0; -} - -static int ctrl_freq_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->freqVal; - return 0; -} - -static int ctrl_freq_is_dirty(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->freqDirty != 0; -} - -static void ctrl_freq_clear_dirty(struct pvr2_ctrl *cptr) -{ - cptr->hdw->freqDirty = 0; -} - -static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - hdw->freqVal = v; - hdw->freqDirty = !0; - hdw->freqSlot = 0; - return 0; -} - -static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->enc_stale != 0; -} - -static void ctrl_cx2341x_clear_dirty(struct pvr2_ctrl *cptr) -{ - cptr->hdw->enc_stale = 0; -} - -static int ctrl_cx2341x_get(struct pvr2_ctrl *cptr,int *vp) -{ - int ret; - struct v4l2_ext_controls cs; - struct v4l2_ext_control c1; - memset(&cs,0,sizeof(cs)); - memset(&c1,0,sizeof(c1)); - cs.controls = &c1; - cs.count = 1; - c1.id = cptr->info->v4l_id; - ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs, - VIDIOC_G_EXT_CTRLS); - if (ret) return ret; - *vp = c1.value; - return 0; -} - -static int ctrl_cx2341x_set(struct pvr2_ctrl *cptr,int m,int v) -{ - int ret; - struct v4l2_ext_controls cs; - struct v4l2_ext_control c1; - memset(&cs,0,sizeof(cs)); - memset(&c1,0,sizeof(c1)); - cs.controls = &c1; - cs.count = 1; - c1.id = cptr->info->v4l_id; - c1.value = v; - ret = cx2341x_ext_ctrls(&cptr->hdw->enc_ctl_state,&cs, - VIDIOC_S_EXT_CTRLS); - if (ret) return ret; - cptr->hdw->enc_stale = !0; - return 0; -} - -static unsigned int ctrl_cx2341x_getv4lflags(struct pvr2_ctrl *cptr) -{ - struct v4l2_queryctrl qctrl; - struct pvr2_ctl_info *info; - qctrl.id = cptr->info->v4l_id; - cx2341x_ctrl_query(&cptr->hdw->enc_ctl_state,&qctrl); - /* Strip out the const so we can adjust a function pointer. It's - OK to do this here because we know this is a dynamically created - control, so the underlying storage for the info pointer is (a) - private to us, and (b) not in read-only storage. Either we do - this or we significantly complicate the underlying control - implementation. */ - info = (struct pvr2_ctl_info *)(cptr->info); - if (qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY) { - if (info->set_value) { - info->set_value = 0; - } - } else { - if (!(info->set_value)) { - info->set_value = ctrl_cx2341x_set; - } - } - return qctrl.flags; -} - -static int ctrl_streamingenabled_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->flag_streaming_enabled; - return 0; -} - -static int ctrl_hsm_get(struct pvr2_ctrl *cptr,int *vp) -{ - int result = pvr2_hdw_is_hsm(cptr->hdw); - *vp = PVR2_CVAL_HSM_FULL; - if (result < 0) *vp = PVR2_CVAL_HSM_FAIL; - if (result) *vp = PVR2_CVAL_HSM_HIGH; - return 0; -} - -static int ctrl_stdavail_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->std_mask_avail; - return 0; -} - -static int ctrl_stdavail_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - v4l2_std_id ns; - ns = hdw->std_mask_avail; - ns = (ns & ~m) | (v & m); - if (ns == hdw->std_mask_avail) return 0; - hdw->std_mask_avail = ns; - pvr2_hdw_internal_set_std_avail(hdw); - pvr2_hdw_internal_find_stdenum(hdw); - return 0; -} - -static int ctrl_std_val_to_sym(struct pvr2_ctrl *cptr,int msk,int val, - char *bufPtr,unsigned int bufSize, - unsigned int *len) -{ - *len = pvr2_std_id_to_str(bufPtr,bufSize,msk & val); - return 0; -} - -static int ctrl_std_sym_to_val(struct pvr2_ctrl *cptr, - const char *bufPtr,unsigned int bufSize, - int *mskp,int *valp) -{ - int ret; - v4l2_std_id id; - ret = pvr2_std_str_to_id(&id,bufPtr,bufSize); - if (ret < 0) return ret; - if (mskp) *mskp = id; - if (valp) *valp = id; - return 0; -} - -static int ctrl_stdcur_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->std_mask_cur; - return 0; -} - -static int ctrl_stdcur_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - v4l2_std_id ns; - ns = hdw->std_mask_cur; - ns = (ns & ~m) | (v & m); - if (ns == hdw->std_mask_cur) return 0; - hdw->std_mask_cur = ns; - hdw->std_dirty = !0; - pvr2_hdw_internal_find_stdenum(hdw); - return 0; -} - -static int ctrl_stdcur_is_dirty(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->std_dirty != 0; -} - -static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr) -{ - cptr->hdw->std_dirty = 0; -} - -static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = ((pvr2_hdw_get_signal_status_internal(cptr->hdw) & - PVR2_SIGNAL_OK) ? 1 : 0); - return 0; -} - -static int ctrl_subsys_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->subsys_enabled_mask; - return 0; -} - -static int ctrl_subsys_set(struct pvr2_ctrl *cptr,int m,int v) -{ - pvr2_hdw_subsys_bit_chg_no_lock(cptr->hdw,m,v); - return 0; -} - -static int ctrl_subsys_stream_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->subsys_stream_mask; - return 0; -} - -static int ctrl_subsys_stream_set(struct pvr2_ctrl *cptr,int m,int v) -{ - pvr2_hdw_subsys_stream_bit_chg_no_lock(cptr->hdw,m,v); - return 0; -} - -static int ctrl_stdenumcur_set(struct pvr2_ctrl *cptr,int m,int v) -{ - struct pvr2_hdw *hdw = cptr->hdw; - if (v < 0) return -EINVAL; - if (v > hdw->std_enum_cnt) return -EINVAL; - hdw->std_enum_cur = v; - if (!v) return 0; - v--; - if (hdw->std_mask_cur == hdw->std_defs[v].id) return 0; - hdw->std_mask_cur = hdw->std_defs[v].id; - hdw->std_dirty = !0; - return 0; -} - - -static int ctrl_stdenumcur_get(struct pvr2_ctrl *cptr,int *vp) -{ - *vp = cptr->hdw->std_enum_cur; - return 0; -} - - -static int ctrl_stdenumcur_is_dirty(struct pvr2_ctrl *cptr) -{ - return cptr->hdw->std_dirty != 0; -} - - -static void ctrl_stdenumcur_clear_dirty(struct pvr2_ctrl *cptr) -{ - cptr->hdw->std_dirty = 0; -} - - -#define DEFINT(vmin,vmax) \ - .type = pvr2_ctl_int, \ - .def.type_int.min_value = vmin, \ - .def.type_int.max_value = vmax - -#define DEFENUM(tab) \ - .type = pvr2_ctl_enum, \ - .def.type_enum.count = (sizeof(tab)/sizeof((tab)[0])), \ - .def.type_enum.value_names = tab - -#define DEFBOOL \ - .type = pvr2_ctl_bool - -#define DEFMASK(msk,tab) \ - .type = pvr2_ctl_bitmask, \ - .def.type_bitmask.valid_bits = msk, \ - .def.type_bitmask.bit_names = tab - -#define DEFREF(vname) \ - .set_value = ctrl_set_##vname, \ - .get_value = ctrl_get_##vname, \ - .is_dirty = ctrl_isdirty_##vname, \ - .clear_dirty = ctrl_cleardirty_##vname - - -#define VCREATE_FUNCS(vname) \ -static int ctrl_get_##vname(struct pvr2_ctrl *cptr,int *vp) \ -{*vp = cptr->hdw->vname##_val; return 0;} \ -static int ctrl_set_##vname(struct pvr2_ctrl *cptr,int m,int v) \ -{cptr->hdw->vname##_val = v; cptr->hdw->vname##_dirty = !0; return 0;} \ -static int ctrl_isdirty_##vname(struct pvr2_ctrl *cptr) \ -{return cptr->hdw->vname##_dirty != 0;} \ -static void ctrl_cleardirty_##vname(struct pvr2_ctrl *cptr) \ -{cptr->hdw->vname##_dirty = 0;} - -VCREATE_FUNCS(brightness) -VCREATE_FUNCS(contrast) -VCREATE_FUNCS(saturation) -VCREATE_FUNCS(hue) -VCREATE_FUNCS(volume) -VCREATE_FUNCS(balance) -VCREATE_FUNCS(bass) -VCREATE_FUNCS(treble) -VCREATE_FUNCS(mute) -VCREATE_FUNCS(input) -VCREATE_FUNCS(audiomode) -VCREATE_FUNCS(res_hor) -VCREATE_FUNCS(res_ver) -VCREATE_FUNCS(srate) - -#define MIN_FREQ 55250000L -#define MAX_FREQ 850000000L - -/* Table definition of all controls which can be manipulated */ -static const struct pvr2_ctl_info control_defs[] = { - { - .v4l_id = V4L2_CID_BRIGHTNESS, - .desc = "Brightness", - .name = "brightness", - .default_value = 128, - DEFREF(brightness), - DEFINT(0,255), - },{ - .v4l_id = V4L2_CID_CONTRAST, - .desc = "Contrast", - .name = "contrast", - .default_value = 68, - DEFREF(contrast), - DEFINT(0,127), - },{ - .v4l_id = V4L2_CID_SATURATION, - .desc = "Saturation", - .name = "saturation", - .default_value = 64, - DEFREF(saturation), - DEFINT(0,127), - },{ - .v4l_id = V4L2_CID_HUE, - .desc = "Hue", - .name = "hue", - .default_value = 0, - DEFREF(hue), - DEFINT(-128,127), - },{ - .v4l_id = V4L2_CID_AUDIO_VOLUME, - .desc = "Volume", - .name = "volume", - .default_value = 65535, - DEFREF(volume), - DEFINT(0,65535), - },{ - .v4l_id = V4L2_CID_AUDIO_BALANCE, - .desc = "Balance", - .name = "balance", - .default_value = 0, - DEFREF(balance), - DEFINT(-32768,32767), - },{ - .v4l_id = V4L2_CID_AUDIO_BASS, - .desc = "Bass", - .name = "bass", - .default_value = 0, - DEFREF(bass), - DEFINT(-32768,32767), - },{ - .v4l_id = V4L2_CID_AUDIO_TREBLE, - .desc = "Treble", - .name = "treble", - .default_value = 0, - DEFREF(treble), - DEFINT(-32768,32767), - },{ - .v4l_id = V4L2_CID_AUDIO_MUTE, - .desc = "Mute", - .name = "mute", - .default_value = 0, - DEFREF(mute), - DEFBOOL, - },{ - .desc = "Video Source", - .name = "input", - .internal_id = PVR2_CID_INPUT, - .default_value = PVR2_CVAL_INPUT_TV, - DEFREF(input), - DEFENUM(control_values_input), - },{ - .desc = "Audio Mode", - .name = "audio_mode", - .internal_id = PVR2_CID_AUDIOMODE, - .default_value = V4L2_TUNER_MODE_STEREO, - DEFREF(audiomode), - DEFENUM(control_values_audiomode), - },{ - .desc = "Horizontal capture resolution", - .name = "resolution_hor", - .internal_id = PVR2_CID_HRES, - .default_value = 720, - DEFREF(res_hor), - DEFINT(320,720), - },{ - .desc = "Vertical capture resolution", - .name = "resolution_ver", - .internal_id = PVR2_CID_VRES, - .default_value = 480, - DEFREF(res_ver), - DEFINT(200,625), - },{ - .v4l_id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, - .desc = "Sample rate", - .name = "srate", - .default_value = PVR2_CVAL_SRATE_48, - DEFREF(srate), - DEFENUM(control_values_srate), - },{ - .desc = "Tuner Frequency (Hz)", - .name = "frequency", - .internal_id = PVR2_CID_FREQUENCY, - .default_value = 175250000L, - .set_value = ctrl_freq_set, - .get_value = ctrl_freq_get, - .is_dirty = ctrl_freq_is_dirty, - .clear_dirty = ctrl_freq_clear_dirty, - DEFINT(MIN_FREQ,MAX_FREQ), - },{ - .desc = "Channel", - .name = "channel", - .set_value = ctrl_channel_set, - .get_value = ctrl_channel_get, - DEFINT(0,FREQTABLE_SIZE), - },{ - .desc = "Channel Program Frequency", - .name = "freq_table_value", - .set_value = ctrl_channelfreq_set, - .get_value = ctrl_channelfreq_get, - DEFINT(MIN_FREQ,MAX_FREQ), - },{ - .desc = "Channel Program ID", - .name = "freq_table_channel", - .set_value = ctrl_channelprog_set, - .get_value = ctrl_channelprog_get, - DEFINT(0,FREQTABLE_SIZE), - },{ - .desc = "Streaming Enabled", - .name = "streaming_enabled", - .get_value = ctrl_streamingenabled_get, - DEFBOOL, - },{ - .desc = "USB Speed", - .name = "usb_speed", - .get_value = ctrl_hsm_get, - DEFENUM(control_values_hsm), - },{ - .desc = "Signal Present", - .name = "signal_present", - .get_value = ctrl_signal_get, - DEFBOOL, - },{ - .desc = "Video Standards Available Mask", - .name = "video_standard_mask_available", - .internal_id = PVR2_CID_STDAVAIL, - .skip_init = !0, - .get_value = ctrl_stdavail_get, - .set_value = ctrl_stdavail_set, - .val_to_sym = ctrl_std_val_to_sym, - .sym_to_val = ctrl_std_sym_to_val, - .type = pvr2_ctl_bitmask, - },{ - .desc = "Video Standards In Use Mask", - .name = "video_standard_mask_active", - .internal_id = PVR2_CID_STDCUR, - .skip_init = !0, - .get_value = ctrl_stdcur_get, - .set_value = ctrl_stdcur_set, - .is_dirty = ctrl_stdcur_is_dirty, - .clear_dirty = ctrl_stdcur_clear_dirty, - .val_to_sym = ctrl_std_val_to_sym, - .sym_to_val = ctrl_std_sym_to_val, - .type = pvr2_ctl_bitmask, - },{ - .desc = "Subsystem enabled mask", - .name = "debug_subsys_mask", - .skip_init = !0, - .get_value = ctrl_subsys_get, - .set_value = ctrl_subsys_set, - DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem), - },{ - .desc = "Subsystem stream mask", - .name = "debug_subsys_stream_mask", - .skip_init = !0, - .get_value = ctrl_subsys_stream_get, - .set_value = ctrl_subsys_stream_set, - DEFMASK(PVR2_SUBSYS_ALL,control_values_subsystem), - },{ - .desc = "Video Standard Name", - .name = "video_standard", - .internal_id = PVR2_CID_STDENUM, - .skip_init = !0, - .get_value = ctrl_stdenumcur_get, - .set_value = ctrl_stdenumcur_set, - .is_dirty = ctrl_stdenumcur_is_dirty, - .clear_dirty = ctrl_stdenumcur_clear_dirty, - .type = pvr2_ctl_enum, - } -}; - -#define CTRLDEF_COUNT (sizeof(control_defs)/sizeof(control_defs[0])) - - -const char *pvr2_config_get_name(enum pvr2_config cfg) -{ - switch (cfg) { - case pvr2_config_empty: return "empty"; - case pvr2_config_mpeg: return "mpeg"; - case pvr2_config_vbi: return "vbi"; - case pvr2_config_radio: return "radio"; - } - return ""; -} - - -struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *hdw) -{ - return hdw->usb_dev; -} - - -unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *hdw) -{ - return hdw->serial_number; -} - - -struct pvr2_hdw *pvr2_hdw_find(int unit_number) -{ - if (unit_number < 0) return 0; - if (unit_number >= PVR_NUM) return 0; - return unit_pointers[unit_number]; -} - - -int pvr2_hdw_get_unit_number(struct pvr2_hdw *hdw) -{ - return hdw->unit_number; -} - - -/* Attempt to locate one of the given set of files. Messages are logged - appropriate to what has been found. The return value will be 0 or - greater on success (it will be the index of the file name found) and - fw_entry will be filled in. Otherwise a negative error is returned on - failure. If the return value is -ENOENT then no viable firmware file - could be located. */ -static int pvr2_locate_firmware(struct pvr2_hdw *hdw, - const struct firmware **fw_entry, - const char *fwtypename, - unsigned int fwcount, - const char *fwnames[]) -{ - unsigned int idx; - int ret = -EINVAL; - for (idx = 0; idx < fwcount; idx++) { - ret = request_firmware(fw_entry, - fwnames[idx], - &hdw->usb_dev->dev); - if (!ret) { - trace_firmware("Located %s firmware: %s;" - " uploading...", - fwtypename, - fwnames[idx]); - return idx; - } - if (ret == -ENOENT) continue; - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware fatal error with code=%d",ret); - return ret; - } - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "***WARNING***" - " Device %s firmware" - " seems to be missing.", - fwtypename); - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Did you install the pvrusb2 firmware files" - " in their proper location?"); - if (fwcount == 1) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware unable to locate %s file %s", - fwtypename,fwnames[0]); - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware unable to locate" - " one of the following %s files:", - fwtypename); - for (idx = 0; idx < fwcount; idx++) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "request_firmware: Failed to find %s", - fwnames[idx]); - } - } - return ret; -} - - -/* - * pvr2_upload_firmware1(). - * - * Send the 8051 firmware to the device. After the upload, arrange for - * device to re-enumerate. - * - * NOTE : the pointer to the firmware data given by request_firmware() - * is not suitable for an usb transaction. - * - */ -int pvr2_upload_firmware1(struct pvr2_hdw *hdw) -{ - const struct firmware *fw_entry = 0; - void *fw_ptr; - unsigned int pipe; - int ret; - u16 address; - static const char *fw_files_29xxx[] = { - "v4l-pvrusb2-29xxx-01.fw", - }; -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - static const char *fw_files_24xxx[] = { - "v4l-pvrusb2-24xxx-01.fw", - }; -#endif - static const struct pvr2_string_table fw_file_defs[] = { - [PVR2_HDW_TYPE_29XXX] = { - fw_files_29xxx, - sizeof(fw_files_29xxx)/sizeof(fw_files_29xxx[0]), - }, -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - [PVR2_HDW_TYPE_24XXX] = { - fw_files_24xxx, - sizeof(fw_files_24xxx)/sizeof(fw_files_24xxx[0]), - }, -#endif - }; - hdw->fw1_state = FW1_STATE_FAILED; // default result - - trace_firmware("pvr2_upload_firmware1"); - - ret = pvr2_locate_firmware(hdw,&fw_entry,"fx2 controller", - fw_file_defs[hdw->hdw_type].cnt, - fw_file_defs[hdw->hdw_type].lst); - if (ret < 0) { - if (ret == -ENOENT) hdw->fw1_state = FW1_STATE_MISSING; - return ret; - } - - usb_settoggle(hdw->usb_dev, 0 & 0xf, !(0 & USB_DIR_IN), 0); - usb_clear_halt(hdw->usb_dev, usb_sndbulkpipe(hdw->usb_dev, 0 & 0x7f)); - - pipe = usb_sndctrlpipe(hdw->usb_dev, 0); - - if (fw_entry->size != 0x2000){ - pvr2_trace(PVR2_TRACE_ERROR_LEGS,"wrong fx2 firmware size"); - release_firmware(fw_entry); - return -ENOMEM; - } - - fw_ptr = kmalloc(0x800, GFP_KERNEL); - if (fw_ptr == NULL){ - release_firmware(fw_entry); - return -ENOMEM; - } - - /* We have to hold the CPU during firmware upload. */ - pvr2_hdw_cpureset_assert(hdw,1); - - /* upload the firmware to address 0000-1fff in 2048 (=0x800) bytes - chunk. */ - - ret = 0; - for(address = 0; address < fw_entry->size; address += 0x800) { - memcpy(fw_ptr, fw_entry->data + address, 0x800); - ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address, - 0, fw_ptr, 0x800, HZ); - } - - trace_firmware("Upload done, releasing device's CPU"); - - /* Now release the CPU. It will disconnect and reconnect later. */ - pvr2_hdw_cpureset_assert(hdw,0); - - kfree(fw_ptr); - release_firmware(fw_entry); - - trace_firmware("Upload done (%d bytes sent)",ret); - - /* We should have written 8192 bytes */ - if (ret == 8192) { - hdw->fw1_state = FW1_STATE_RELOAD; - return 0; - } - - return -EIO; -} - - -/* - * pvr2_upload_firmware2() - * - * This uploads encoder firmware on endpoint 2. - * - */ - -int pvr2_upload_firmware2(struct pvr2_hdw *hdw) -{ - const struct firmware *fw_entry = 0; - void *fw_ptr; - unsigned int pipe, fw_len, fw_done; - int actual_length; - int ret = 0; - int fwidx; - static const char *fw_files[] = { - CX2341X_FIRM_ENC_FILENAME, - }; - - trace_firmware("pvr2_upload_firmware2"); - - ret = pvr2_locate_firmware(hdw,&fw_entry,"encoder", - sizeof(fw_files)/sizeof(fw_files[0]), - fw_files); - if (ret < 0) return ret; - fwidx = ret; - ret = 0; - /* Since we're about to completely reinitialize the encoder, - invalidate our cached copy of its configuration state. Next - time we configure the encoder, then we'll fully configure it. */ - hdw->enc_cur_valid = 0; - - /* First prepare firmware loading */ - ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/ - ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/ - ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/ - ret |= pvr2_hdw_cmd_deep_reset(hdw); - ret |= pvr2_write_register(hdw, 0xa064, 0x00000000); /*APU command*/ - ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000408); /*gpio dir*/ - ret |= pvr2_hdw_gpio_chg_out(hdw,0xffffffff,0x00000008); /*gpio output state*/ - ret |= pvr2_write_register(hdw, 0x9058, 0xffffffed); /*VPU ctrl*/ - ret |= pvr2_write_register(hdw, 0x9054, 0xfffffffd); /*reset hw blocks*/ - ret |= pvr2_write_register(hdw, 0x07f8, 0x80000800); /*encoder SDRAM refresh*/ - ret |= pvr2_write_register(hdw, 0x07fc, 0x0000001a); /*encoder SDRAM pre-charge*/ - ret |= pvr2_write_register(hdw, 0x0700, 0x00000000); /*I2C clock*/ - ret |= pvr2_write_register(hdw, 0xaa00, 0x00000000); /*unknown*/ - ret |= pvr2_write_register(hdw, 0xaa04, 0x00057810); /*unknown*/ - ret |= pvr2_write_register(hdw, 0xaa10, 0x00148500); /*unknown*/ - ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/ - ret |= pvr2_write_u8(hdw, 0x52, 0); - ret |= pvr2_write_u16(hdw, 0x0600, 0); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "firmware2 upload prep failed, ret=%d",ret); - release_firmware(fw_entry); - return ret; - } - - /* Now send firmware */ - - fw_len = fw_entry->size; - - if (fw_len % FIRMWARE_CHUNK_SIZE) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "size of %s firmware" - " must be a multiple of 8192B", - fw_files[fwidx]); - release_firmware(fw_entry); - return -1; - } - - fw_ptr = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL); - if (fw_ptr == NULL){ - release_firmware(fw_entry); - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "failed to allocate memory for firmware2 upload"); - return -ENOMEM; - } - - pipe = usb_sndbulkpipe(hdw->usb_dev, PVR2_FIRMWARE_ENDPOINT); - - for (fw_done = 0 ; (fw_done < fw_len) && !ret ; - fw_done += FIRMWARE_CHUNK_SIZE ) { - int i; - memcpy(fw_ptr, fw_entry->data + fw_done, FIRMWARE_CHUNK_SIZE); - /* Usbsnoop log shows that we must swap bytes... */ - for (i = 0; i < FIRMWARE_CHUNK_SIZE/4 ; i++) - ((u32 *)fw_ptr)[i] = ___swab32(((u32 *)fw_ptr)[i]); - - ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr, - FIRMWARE_CHUNK_SIZE, - &actual_length, HZ); - ret |= (actual_length != FIRMWARE_CHUNK_SIZE); - } - - trace_firmware("upload of %s : %i / %i ", - fw_files[fwidx],fw_done,fw_len); - - kfree(fw_ptr); - release_firmware(fw_entry); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "firmware2 upload transfer failure"); - return ret; - } - - /* Finish upload */ - - ret |= pvr2_write_register(hdw, 0x9054, 0xffffffff); /*reset hw blocks*/ - ret |= pvr2_write_register(hdw, 0x9058, 0xffffffe8); /*VPU ctrl*/ - ret |= pvr2_write_u16(hdw, 0x0600, 0); - - if (ret) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "firmware2 upload post-proc failure"); - } else { - hdw->subsys_enabled_mask |= (1<flag_ok) return; - - msk &= PVR2_SUBSYS_ALL; - nmsk = (hdw->subsys_enabled_mask & ~msk) | (val & msk); - nmsk &= PVR2_SUBSYS_ALL; - - for (;;) { - tryCount++; - if (!((nmsk ^ hdw->subsys_enabled_mask) & - PVR2_SUBSYS_ALL)) break; - if (tryCount > 4) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Too many retries when configuring device;" - " giving up"); - pvr2_hdw_render_useless(hdw); - break; - } - if (tryCount > 1) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Retrying device reconfiguration"); - } - pvr2_trace(PVR2_TRACE_INIT, - "subsys mask changing 0x%lx:0x%lx" - " from 0x%lx to 0x%lx", - msk,val,hdw->subsys_enabled_mask,nmsk); - - vmsk = (nmsk ^ hdw->subsys_enabled_mask) & - hdw->subsys_enabled_mask; - if (vmsk) { - if (vmsk & (1<subsys_enabled_mask &= - ~FIRMWARE_RECOVERY_BITS; - continue; - } - } - if (vmsk & (1<decoder_ctrl) { - hdw->decoder_ctrl->enable( - hdw->decoder_ctrl->ctxt,0); - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING:" - " No decoder present"); - } - hdw->subsys_enabled_mask &= - ~(1<subsys_enabled_mask &= - ~(vmsk & PVR2_SUBSYS_CFG_ALL); - } - } - vmsk = (nmsk ^ hdw->subsys_enabled_mask) & nmsk; - if (vmsk) { - if (vmsk & (1<subsys_enabled_mask &= - ~FIRMWARE_RECOVERY_BITS; - continue; - } - } - if (vmsk & (1<decoder_ctrl) { - hdw->decoder_ctrl->enable( - hdw->decoder_ctrl->ctxt,!0); - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING:" - " No decoder present"); - } - hdw->subsys_enabled_mask |= - (1<subsys_enabled_mask &= - ~FIRMWARE_RECOVERY_BITS; - continue; - } - } - } - } -} - - -void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw, - unsigned long msk,unsigned long val) -{ - LOCK_TAKE(hdw->big_lock); do { - pvr2_hdw_subsys_bit_chg_no_lock(hdw,msk,val); - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -void pvr2_hdw_subsys_bit_set(struct pvr2_hdw *hdw,unsigned long msk) -{ - pvr2_hdw_subsys_bit_chg(hdw,msk,msk); -} - - -void pvr2_hdw_subsys_bit_clr(struct pvr2_hdw *hdw,unsigned long msk) -{ - pvr2_hdw_subsys_bit_chg(hdw,msk,0); -} - - -unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *hdw) -{ - return hdw->subsys_enabled_mask; -} - - -unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *hdw) -{ - return hdw->subsys_stream_mask; -} - - -void pvr2_hdw_subsys_stream_bit_chg_no_lock(struct pvr2_hdw *hdw, - unsigned long msk, - unsigned long val) -{ - unsigned long val2; - msk &= PVR2_SUBSYS_ALL; - val2 = ((hdw->subsys_stream_mask & ~msk) | (val & msk)); - pvr2_trace(PVR2_TRACE_INIT, - "stream mask changing 0x%lx:0x%lx from 0x%lx to 0x%lx", - msk,val,hdw->subsys_stream_mask,val2); - hdw->subsys_stream_mask = val2; -} - - -void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw, - unsigned long msk, - unsigned long val) -{ - LOCK_TAKE(hdw->big_lock); do { - pvr2_hdw_subsys_stream_bit_chg_no_lock(hdw,msk,val); - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -int pvr2_hdw_set_streaming_no_lock(struct pvr2_hdw *hdw,int enableFl) -{ - if ((!enableFl) == !(hdw->flag_streaming_enabled)) return 0; - if (enableFl) { - pvr2_trace(PVR2_TRACE_START_STOP, - "/*--TRACE_STREAM--*/ enable"); - pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,~0); - } else { - pvr2_trace(PVR2_TRACE_START_STOP, - "/*--TRACE_STREAM--*/ disable"); - pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0); - } - if (!hdw->flag_ok) return -EIO; - hdw->flag_streaming_enabled = enableFl != 0; - return 0; -} - - -int pvr2_hdw_get_streaming(struct pvr2_hdw *hdw) -{ - return hdw->flag_streaming_enabled != 0; -} - - -int pvr2_hdw_set_streaming(struct pvr2_hdw *hdw,int enable_flag) -{ - int ret; - LOCK_TAKE(hdw->big_lock); do { - ret = pvr2_hdw_set_streaming_no_lock(hdw,enable_flag); - } while (0); LOCK_GIVE(hdw->big_lock); - return ret; -} - - -int pvr2_hdw_set_stream_type_no_lock(struct pvr2_hdw *hdw, - enum pvr2_config config) -{ - unsigned long sm = hdw->subsys_enabled_mask; - if (!hdw->flag_ok) return -EIO; - pvr2_hdw_subsys_bit_chg_no_lock(hdw,hdw->subsys_stream_mask,0); - hdw->config = config; - pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,sm); - return 0; -} - - -int pvr2_hdw_set_stream_type(struct pvr2_hdw *hdw,enum pvr2_config config) -{ - int ret; - if (!hdw->flag_ok) return -EIO; - LOCK_TAKE(hdw->big_lock); - ret = pvr2_hdw_set_stream_type_no_lock(hdw,config); - LOCK_GIVE(hdw->big_lock); - return ret; -} - - -static int get_default_tuner_type(struct pvr2_hdw *hdw) -{ - int unit_number = hdw->unit_number; - int tp = -1; - if ((unit_number >= 0) && (unit_number < PVR_NUM)) { - tp = tuner[unit_number]; - } - if (tp < 0) return -EINVAL; - hdw->tuner_type = tp; - return 0; -} - - -static v4l2_std_id get_default_standard(struct pvr2_hdw *hdw) -{ - int unit_number = hdw->unit_number; - int tp = 0; - if ((unit_number >= 0) && (unit_number < PVR_NUM)) { - tp = video_std[unit_number]; - } - return tp; -} - - -static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw) -{ - int unit_number = hdw->unit_number; - int tp = 0; - if ((unit_number >= 0) && (unit_number < PVR_NUM)) { - tp = tolerance[unit_number]; - } - return tp; -} - - -static int pvr2_hdw_check_firmware(struct pvr2_hdw *hdw) -{ - /* Try a harmless request to fetch the eeprom's address over - endpoint 1. See what happens. Only the full FX2 image can - respond to this. If this probe fails then likely the FX2 - firmware needs be loaded. */ - int result; - LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = 0xeb; - result = pvr2_send_request_ex(hdw,HZ*1,!0, - hdw->cmd_buffer,1, - hdw->cmd_buffer,1); - if (result < 0) break; - } while(0); LOCK_GIVE(hdw->ctl_lock); - if (result) { - pvr2_trace(PVR2_TRACE_INIT, - "Probe of device endpoint 1 result status %d", - result); - } else { - pvr2_trace(PVR2_TRACE_INIT, - "Probe of device endpoint 1 succeeded"); - } - return result == 0; -} - -static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw) -{ - char buf[40]; - unsigned int bcnt; - v4l2_std_id std1,std2; - - std1 = get_default_standard(hdw); - - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),hdw->std_mask_eeprom); - pvr2_trace(PVR2_TRACE_INIT, - "Supported video standard(s) reported by eeprom: %.*s", - bcnt,buf); - - hdw->std_mask_avail = hdw->std_mask_eeprom; - - std2 = std1 & ~hdw->std_mask_avail; - if (std2) { - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std2); - pvr2_trace(PVR2_TRACE_INIT, - "Expanding supported video standards" - " to include: %.*s", - bcnt,buf); - hdw->std_mask_avail |= std2; - } - - pvr2_hdw_internal_set_std_avail(hdw); - - if (std1) { - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),std1); - pvr2_trace(PVR2_TRACE_INIT, - "Initial video standard forced to %.*s", - bcnt,buf); - hdw->std_mask_cur = std1; - hdw->std_dirty = !0; - pvr2_hdw_internal_find_stdenum(hdw); - return; - } - - if (hdw->std_enum_cnt > 1) { - // Autoselect the first listed standard - hdw->std_enum_cur = 1; - hdw->std_mask_cur = hdw->std_defs[hdw->std_enum_cur-1].id; - hdw->std_dirty = !0; - pvr2_trace(PVR2_TRACE_INIT, - "Initial video standard auto-selected to %s", - hdw->std_defs[hdw->std_enum_cur-1].name); - return; - } - - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Unable to select a viable initial video standard"); -} - - -static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) -{ - int ret; - unsigned int idx; - struct pvr2_ctrl *cptr; - int reloadFl = 0; - if (!reloadFl) { - reloadFl = (hdw->usb_intf->cur_altsetting->desc.bNumEndpoints - == 0); - if (reloadFl) { - pvr2_trace(PVR2_TRACE_INIT, - "USB endpoint config looks strange" - "; possibly firmware needs to be loaded"); - } - } - if (!reloadFl) { - reloadFl = !pvr2_hdw_check_firmware(hdw); - if (reloadFl) { - pvr2_trace(PVR2_TRACE_INIT, - "Check for FX2 firmware failed" - "; possibly firmware needs to be loaded"); - } - } - if (reloadFl) { - if (pvr2_upload_firmware1(hdw) != 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failure uploading firmware1"); - } - return; - } - hdw->fw1_state = FW1_STATE_OK; - - if (initusbreset) { - pvr2_hdw_device_reset(hdw); - } - if (!pvr2_hdw_dev_ok(hdw)) return; - - for (idx = 0; idx < pvr2_client_lists[hdw->hdw_type].cnt; idx++) { - request_module(pvr2_client_lists[hdw->hdw_type].lst[idx]); - } - - pvr2_hdw_cmd_powerup(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - - if (pvr2_upload_firmware2(hdw)){ - pvr2_trace(PVR2_TRACE_ERROR_LEGS,"device unstable!!"); - pvr2_hdw_render_useless(hdw); - return; - } - - // This step MUST happen after the earlier powerup step. - pvr2_i2c_core_init(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - - for (idx = 0; idx < CTRLDEF_COUNT; idx++) { - cptr = hdw->controls + idx; - if (cptr->info->skip_init) continue; - if (!cptr->info->set_value) continue; - cptr->info->set_value(cptr,~0,cptr->info->default_value); - } - - // Do not use pvr2_reset_ctl_endpoints() here. It is not - // thread-safe against the normal pvr2_send_request() mechanism. - // (We should make it thread safe). - - ret = pvr2_hdw_get_eeprom_addr(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Unable to determine location of eeprom, skipping"); - } else { - hdw->eeprom_addr = ret; - pvr2_eeprom_analyze(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - } - - pvr2_hdw_setup_std(hdw); - - if (!get_default_tuner_type(hdw)) { - pvr2_trace(PVR2_TRACE_INIT, - "pvr2_hdw_setup: Tuner type overridden to %d", - hdw->tuner_type); - } - - hdw->tuner_updated = !0; - pvr2_i2c_core_check_stale(hdw); - hdw->tuner_updated = 0; - - if (!pvr2_hdw_dev_ok(hdw)) return; - - pvr2_hdw_commit_ctl_internal(hdw); - if (!pvr2_hdw_dev_ok(hdw)) return; - - hdw->vid_stream = pvr2_stream_create(); - if (!pvr2_hdw_dev_ok(hdw)) return; - pvr2_trace(PVR2_TRACE_INIT, - "pvr2_hdw_setup: video stream is %p",hdw->vid_stream); - if (hdw->vid_stream) { - idx = get_default_error_tolerance(hdw); - if (idx) { - pvr2_trace(PVR2_TRACE_INIT, - "pvr2_hdw_setup: video stream %p" - " setting tolerance %u", - hdw->vid_stream,idx); - } - pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev, - PVR2_VID_ENDPOINT,idx); - } - - if (!pvr2_hdw_dev_ok(hdw)) return; - - /* Make sure everything is up to date */ - pvr2_i2c_core_sync(hdw); - - if (!pvr2_hdw_dev_ok(hdw)) return; - - hdw->flag_init_ok = !0; -} - - -int pvr2_hdw_setup(struct pvr2_hdw *hdw) -{ - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) begin",hdw); - LOCK_TAKE(hdw->big_lock); do { - pvr2_hdw_setup_low(hdw); - pvr2_trace(PVR2_TRACE_INIT, - "pvr2_hdw_setup(hdw=%p) done, ok=%d init_ok=%d", - hdw,hdw->flag_ok,hdw->flag_init_ok); - if (pvr2_hdw_dev_ok(hdw)) { - if (pvr2_hdw_init_ok(hdw)) { - pvr2_trace( - PVR2_TRACE_INFO, - "Device initialization" - " completed successfully."); - break; - } - if (hdw->fw1_state == FW1_STATE_RELOAD) { - pvr2_trace( - PVR2_TRACE_INFO, - "Device microcontroller firmware" - " (re)loaded; it should now reset" - " and reconnect."); - break; - } - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Device initialization was not successful."); - if (hdw->fw1_state == FW1_STATE_MISSING) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Giving up since device" - " microcontroller firmware" - " appears to be missing."); - break; - } - } - if (procreload) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Attempting pvrusb2 recovery by reloading" - " primary firmware."); - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "If this works, device should disconnect" - " and reconnect in a sane state."); - hdw->fw1_state = FW1_STATE_UNKNOWN; - pvr2_upload_firmware1(hdw); - } else { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "***WARNING*** pvrusb2 device hardware" - " appears to be jammed" - " and I can't clear it."); - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "You might need to power cycle" - " the pvrusb2 device" - " in order to recover."); - } - } while (0); LOCK_GIVE(hdw->big_lock); - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_setup(hdw=%p) end",hdw); - return hdw->flag_init_ok; -} - - -/* Create and return a structure for interacting with the underlying - hardware */ -struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, - const struct usb_device_id *devid) -{ - unsigned int idx,cnt1,cnt2; - struct pvr2_hdw *hdw; - unsigned int hdw_type; - int valid_std_mask; - struct pvr2_ctrl *cptr; - __u8 ifnum; - struct v4l2_queryctrl qctrl; - struct pvr2_ctl_info *ciptr; - - hdw_type = devid - pvr2_device_table; - if (hdw_type >= - sizeof(pvr2_device_names)/sizeof(pvr2_device_names[0])) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Bogus device type of %u reported",hdw_type); - return 0; - } - - hdw = kmalloc(sizeof(*hdw),GFP_KERNEL); - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", - hdw,pvr2_device_names[hdw_type]); - if (!hdw) goto fail; - memset(hdw,0,sizeof(*hdw)); - cx2341x_fill_defaults(&hdw->enc_ctl_state); - - hdw->control_cnt = CTRLDEF_COUNT; - hdw->control_cnt += MPEGDEF_COUNT; - hdw->controls = kmalloc(sizeof(struct pvr2_ctrl) * hdw->control_cnt, - GFP_KERNEL); - if (!hdw->controls) goto fail; - memset(hdw->controls,0,sizeof(struct pvr2_ctrl) * hdw->control_cnt); - hdw->hdw_type = hdw_type; - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - cptr->hdw = hdw; - } - for (idx = 0; idx < 32; idx++) { - hdw->std_mask_ptrs[idx] = hdw->std_mask_names[idx]; - } - for (idx = 0; idx < CTRLDEF_COUNT; idx++) { - cptr = hdw->controls + idx; - cptr->info = control_defs+idx; - } - /* Define and configure additional controls from cx2341x module. */ - hdw->mpeg_ctrl_info = kmalloc( - sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT, GFP_KERNEL); - if (!hdw->mpeg_ctrl_info) goto fail; - memset(hdw->mpeg_ctrl_info,0, - sizeof(*(hdw->mpeg_ctrl_info)) * MPEGDEF_COUNT); - for (idx = 0; idx < MPEGDEF_COUNT; idx++) { - cptr = hdw->controls + idx + CTRLDEF_COUNT; - ciptr = &(hdw->mpeg_ctrl_info[idx].info); - ciptr->desc = hdw->mpeg_ctrl_info[idx].desc; - ciptr->name = mpeg_ids[idx].strid; - ciptr->v4l_id = mpeg_ids[idx].id; - ciptr->skip_init = !0; - ciptr->get_value = ctrl_cx2341x_get; - ciptr->get_v4lflags = ctrl_cx2341x_getv4lflags; - ciptr->is_dirty = ctrl_cx2341x_is_dirty; - if (!idx) ciptr->clear_dirty = ctrl_cx2341x_clear_dirty; - qctrl.id = ciptr->v4l_id; - cx2341x_ctrl_query(&hdw->enc_ctl_state,&qctrl); - if (!(qctrl.flags & V4L2_CTRL_FLAG_READ_ONLY)) { - ciptr->set_value = ctrl_cx2341x_set; - } - strncpy(hdw->mpeg_ctrl_info[idx].desc,qctrl.name, - PVR2_CTLD_INFO_DESC_SIZE); - hdw->mpeg_ctrl_info[idx].desc[PVR2_CTLD_INFO_DESC_SIZE-1] = 0; - ciptr->default_value = qctrl.default_value; - switch (qctrl.type) { - default: - case V4L2_CTRL_TYPE_INTEGER: - ciptr->type = pvr2_ctl_int; - ciptr->def.type_int.min_value = qctrl.minimum; - ciptr->def.type_int.max_value = qctrl.maximum; - break; - case V4L2_CTRL_TYPE_BOOLEAN: - ciptr->type = pvr2_ctl_bool; - break; - case V4L2_CTRL_TYPE_MENU: - ciptr->type = pvr2_ctl_enum; - ciptr->def.type_enum.value_names = - cx2341x_ctrl_get_menu(ciptr->v4l_id); - for (cnt1 = 0; - ciptr->def.type_enum.value_names[cnt1] != NULL; - cnt1++) { } - ciptr->def.type_enum.count = cnt1; - break; - } - cptr->info = ciptr; - } - - // Initialize video standard enum dynamic control - cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDENUM); - if (cptr) { - memcpy(&hdw->std_info_enum,cptr->info, - sizeof(hdw->std_info_enum)); - cptr->info = &hdw->std_info_enum; - - } - // Initialize control data regarding video standard masks - valid_std_mask = pvr2_std_get_usable(); - for (idx = 0; idx < 32; idx++) { - if (!(valid_std_mask & (1 << idx))) continue; - cnt1 = pvr2_std_id_to_str( - hdw->std_mask_names[idx], - sizeof(hdw->std_mask_names[idx])-1, - 1 << idx); - hdw->std_mask_names[idx][cnt1] = 0; - } - cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDAVAIL); - if (cptr) { - memcpy(&hdw->std_info_avail,cptr->info, - sizeof(hdw->std_info_avail)); - cptr->info = &hdw->std_info_avail; - hdw->std_info_avail.def.type_bitmask.bit_names = - hdw->std_mask_ptrs; - hdw->std_info_avail.def.type_bitmask.valid_bits = - valid_std_mask; - } - cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR); - if (cptr) { - memcpy(&hdw->std_info_cur,cptr->info, - sizeof(hdw->std_info_cur)); - cptr->info = &hdw->std_info_cur; - hdw->std_info_cur.def.type_bitmask.bit_names = - hdw->std_mask_ptrs; - hdw->std_info_avail.def.type_bitmask.valid_bits = - valid_std_mask; - } - - hdw->eeprom_addr = -1; - hdw->unit_number = -1; - hdw->v4l_minor_number = -1; - hdw->ctl_write_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL); - if (!hdw->ctl_write_buffer) goto fail; - hdw->ctl_read_buffer = kmalloc(PVR2_CTL_BUFFSIZE,GFP_KERNEL); - if (!hdw->ctl_read_buffer) goto fail; - hdw->ctl_write_urb = usb_alloc_urb(0,GFP_KERNEL); - if (!hdw->ctl_write_urb) goto fail; - hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL); - if (!hdw->ctl_read_urb) goto fail; - - down(&pvr2_unit_sem); do { - for (idx = 0; idx < PVR_NUM; idx++) { - if (unit_pointers[idx]) continue; - hdw->unit_number = idx; - unit_pointers[idx] = hdw; - break; - } - } while (0); up(&pvr2_unit_sem); - - cnt1 = 0; - cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2"); - cnt1 += cnt2; - if (hdw->unit_number >= 0) { - cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"_%c", - ('a' + hdw->unit_number)); - cnt1 += cnt2; - } - if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1; - hdw->name[cnt1] = 0; - - pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s", - hdw->unit_number,hdw->name); - - hdw->tuner_type = -1; - hdw->flag_ok = !0; - /* Initialize the mask of subsystems that we will shut down when we - stop streaming. */ - hdw->subsys_stream_mask = PVR2_SUBSYS_RUN_ALL; - hdw->subsys_stream_mask |= (1<subsys_stream_mask); - - hdw->usb_intf = intf; - hdw->usb_dev = interface_to_usbdev(intf); - - ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber; - usb_set_interface(hdw->usb_dev,ifnum,0); - - mutex_init(&hdw->ctl_lock_mutex); - mutex_init(&hdw->big_lock_mutex); - - return hdw; - fail: - if (hdw) { - if (hdw->ctl_read_urb) usb_free_urb(hdw->ctl_read_urb); - if (hdw->ctl_write_urb) usb_free_urb(hdw->ctl_write_urb); - if (hdw->ctl_read_buffer) kfree(hdw->ctl_read_buffer); - if (hdw->ctl_write_buffer) kfree(hdw->ctl_write_buffer); - if (hdw->controls) kfree(hdw->controls); - if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info); - kfree(hdw); - } - return 0; -} - - -/* Remove _all_ associations between this driver and the underlying USB - layer. */ -void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw) -{ - if (hdw->flag_disconnected) return; - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_remove_usb_stuff: hdw=%p",hdw); - if (hdw->ctl_read_urb) { - usb_kill_urb(hdw->ctl_read_urb); - usb_free_urb(hdw->ctl_read_urb); - hdw->ctl_read_urb = 0; - } - if (hdw->ctl_write_urb) { - usb_kill_urb(hdw->ctl_write_urb); - usb_free_urb(hdw->ctl_write_urb); - hdw->ctl_write_urb = 0; - } - if (hdw->ctl_read_buffer) { - kfree(hdw->ctl_read_buffer); - hdw->ctl_read_buffer = 0; - } - if (hdw->ctl_write_buffer) { - kfree(hdw->ctl_write_buffer); - hdw->ctl_write_buffer = 0; - } - pvr2_hdw_render_useless_unlocked(hdw); - hdw->flag_disconnected = !0; - hdw->usb_dev = 0; - hdw->usb_intf = 0; -} - - -/* Destroy hardware interaction structure */ -void pvr2_hdw_destroy(struct pvr2_hdw *hdw) -{ - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_destroy: hdw=%p",hdw); - if (hdw->fw_buffer) { - kfree(hdw->fw_buffer); - hdw->fw_buffer = 0; - } - if (hdw->vid_stream) { - pvr2_stream_destroy(hdw->vid_stream); - hdw->vid_stream = 0; - } - if (hdw->audio_stat) { - hdw->audio_stat->detach(hdw->audio_stat->ctxt); - } - if (hdw->decoder_ctrl) { - hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt); - } - pvr2_i2c_core_done(hdw); - pvr2_hdw_remove_usb_stuff(hdw); - down(&pvr2_unit_sem); do { - if ((hdw->unit_number >= 0) && - (hdw->unit_number < PVR_NUM) && - (unit_pointers[hdw->unit_number] == hdw)) { - unit_pointers[hdw->unit_number] = 0; - } - } while (0); up(&pvr2_unit_sem); - if (hdw->controls) kfree(hdw->controls); - if (hdw->mpeg_ctrl_info) kfree(hdw->mpeg_ctrl_info); - if (hdw->std_defs) kfree(hdw->std_defs); - if (hdw->std_enum_names) kfree(hdw->std_enum_names); - kfree(hdw); -} - - -int pvr2_hdw_init_ok(struct pvr2_hdw *hdw) -{ - return hdw->flag_init_ok; -} - - -int pvr2_hdw_dev_ok(struct pvr2_hdw *hdw) -{ - return (hdw && hdw->flag_ok); -} - - -/* Called when hardware has been unplugged */ -void pvr2_hdw_disconnect(struct pvr2_hdw *hdw) -{ - pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_disconnect(hdw=%p)",hdw); - LOCK_TAKE(hdw->big_lock); - LOCK_TAKE(hdw->ctl_lock); - pvr2_hdw_remove_usb_stuff(hdw); - LOCK_GIVE(hdw->ctl_lock); - LOCK_GIVE(hdw->big_lock); -} - - -// Attempt to autoselect an appropriate value for std_enum_cur given -// whatever is currently in std_mask_cur -void pvr2_hdw_internal_find_stdenum(struct pvr2_hdw *hdw) -{ - unsigned int idx; - for (idx = 1; idx < hdw->std_enum_cnt; idx++) { - if (hdw->std_defs[idx-1].id == hdw->std_mask_cur) { - hdw->std_enum_cur = idx; - return; - } - } - hdw->std_enum_cur = 0; -} - - -// Calculate correct set of enumerated standards based on currently known -// set of available standards bits. -void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw) -{ - struct v4l2_standard *newstd; - unsigned int std_cnt; - unsigned int idx; - - newstd = pvr2_std_create_enum(&std_cnt,hdw->std_mask_avail); - - if (hdw->std_defs) { - kfree(hdw->std_defs); - hdw->std_defs = 0; - } - hdw->std_enum_cnt = 0; - if (hdw->std_enum_names) { - kfree(hdw->std_enum_names); - hdw->std_enum_names = 0; - } - - if (!std_cnt) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "WARNING: Failed to identify any viable standards"); - } - hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL); - hdw->std_enum_names[0] = "none"; - for (idx = 0; idx < std_cnt; idx++) { - hdw->std_enum_names[idx+1] = - newstd[idx].name; - } - // Set up the dynamic control for this standard - hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names; - hdw->std_info_enum.def.type_enum.count = std_cnt+1; - hdw->std_defs = newstd; - hdw->std_enum_cnt = std_cnt+1; - hdw->std_enum_cur = 0; - hdw->std_info_cur.def.type_bitmask.valid_bits = hdw->std_mask_avail; -} - - -int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw, - struct v4l2_standard *std, - unsigned int idx) -{ - int ret = -EINVAL; - if (!idx) return ret; - LOCK_TAKE(hdw->big_lock); do { - if (idx >= hdw->std_enum_cnt) break; - idx--; - memcpy(std,hdw->std_defs+idx,sizeof(*std)); - ret = 0; - } while (0); LOCK_GIVE(hdw->big_lock); - return ret; -} - - -/* Get the number of defined controls */ -unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *hdw) -{ - return hdw->control_cnt; -} - - -/* Retrieve a control handle given its index (0..count-1) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *hdw, - unsigned int idx) -{ - if (idx >= hdw->control_cnt) return 0; - return hdw->controls + idx; -} - - -/* Retrieve a control handle given its index (0..count-1) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *hdw, - unsigned int ctl_id) -{ - struct pvr2_ctrl *cptr; - unsigned int idx; - int i; - - /* This could be made a lot more efficient, but for now... */ - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - i = cptr->info->internal_id; - if (i && (i == ctl_id)) return cptr; - } - return 0; -} - - -/* Given a V4L ID, retrieve the control structure associated with it. */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *hdw,unsigned int ctl_id) -{ - struct pvr2_ctrl *cptr; - unsigned int idx; - int i; - - /* This could be made a lot more efficient, but for now... */ - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - i = cptr->info->v4l_id; - if (i && (i == ctl_id)) return cptr; - } - return 0; -} - - -/* Given a V4L ID for its immediate predecessor, retrieve the control - structure associated with it. */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *hdw, - unsigned int ctl_id) -{ - struct pvr2_ctrl *cptr,*cp2; - unsigned int idx; - int i; - - /* This could be made a lot more efficient, but for now... */ - cp2 = 0; - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - i = cptr->info->v4l_id; - if (!i) continue; - if (i <= ctl_id) continue; - if (cp2 && (cp2->info->v4l_id < i)) continue; - cp2 = cptr; - } - return cp2; - return 0; -} - - -static const char *get_ctrl_typename(enum pvr2_ctl_type tp) -{ - switch (tp) { - case pvr2_ctl_int: return "integer"; - case pvr2_ctl_enum: return "enum"; - case pvr2_ctl_bool: return "boolean"; - case pvr2_ctl_bitmask: return "bitmask"; - } - return ""; -} - - -/* Commit all control changes made up to this point. Subsystems can be - indirectly affected by these changes. For a given set of things being - committed, we'll clear the affected subsystem bits and then once we're - done committing everything we'll make a request to restore the subsystem - state(s) back to their previous value before this function was called. - Thus we can automatically reconfigure affected pieces of the driver as - controls are changed. */ -int pvr2_hdw_commit_ctl_internal(struct pvr2_hdw *hdw) -{ - unsigned long saved_subsys_mask = hdw->subsys_enabled_mask; - unsigned long stale_subsys_mask = 0; - unsigned int idx; - struct pvr2_ctrl *cptr; - int value; - int commit_flag = 0; - char buf[100]; - unsigned int bcnt,ccnt; - - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - if (cptr->info->is_dirty == 0) continue; - if (!cptr->info->is_dirty(cptr)) continue; - if (!commit_flag) { - commit_flag = !0; - } - - bcnt = scnprintf(buf,sizeof(buf),"\"%s\" <-- ", - cptr->info->name); - value = 0; - cptr->info->get_value(cptr,&value); - pvr2_ctrl_value_to_sym_internal(cptr,~0,value, - buf+bcnt, - sizeof(buf)-bcnt,&ccnt); - bcnt += ccnt; - bcnt += scnprintf(buf+bcnt,sizeof(buf)-bcnt," <%s>", - get_ctrl_typename(cptr->info->type)); - pvr2_trace(PVR2_TRACE_CTL, - "/*--TRACE_COMMIT--*/ %.*s", - bcnt,buf); - } - - if (!commit_flag) { - /* Nothing has changed */ - return 0; - } - - /* When video standard changes, reset the hres and vres values - - but if the user has pending changes there, then let the changes - take priority. */ - if (hdw->std_dirty) { - /* Rewrite the vertical resolution to be appropriate to the - video standard that has been selected. */ - int nvres; - if (hdw->std_mask_cur & V4L2_STD_525_60) { - nvres = 480; - } else { - nvres = 576; - } - if (nvres != hdw->res_ver_val) { - hdw->res_ver_val = nvres; - hdw->res_ver_dirty = !0; - } - } - - if (hdw->std_dirty || - 0) { - /* If any of this changes, then the encoder needs to be - reconfigured, and we need to reset the stream. */ - stale_subsys_mask |= (1<subsys_stream_mask; - } - - if (hdw->srate_dirty) { - /* Write new sample rate into control structure since - * the master copy is stale. We must track srate - * separate from the mpeg control structure because - * other logic also uses this value. */ - struct v4l2_ext_controls cs; - struct v4l2_ext_control c1; - memset(&cs,0,sizeof(cs)); - memset(&c1,0,sizeof(c1)); - cs.controls = &c1; - cs.count = 1; - c1.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ; - c1.value = hdw->srate_val; - cx2341x_ext_ctrls(&hdw->enc_ctl_state,&cs,VIDIOC_S_EXT_CTRLS); - } - - /* Scan i2c core at this point - before we clear all the dirty - bits. Various parts of the i2c core will notice dirty bits as - appropriate and arrange to broadcast or directly send updates to - the client drivers in order to keep everything in sync */ - pvr2_i2c_core_check_stale(hdw); - - for (idx = 0; idx < hdw->control_cnt; idx++) { - cptr = hdw->controls + idx; - if (!cptr->info->clear_dirty) continue; - cptr->info->clear_dirty(cptr); - } - - /* Now execute i2c core update */ - pvr2_i2c_core_sync(hdw); - - pvr2_hdw_subsys_bit_chg_no_lock(hdw,stale_subsys_mask,0); - pvr2_hdw_subsys_bit_chg_no_lock(hdw,~0,saved_subsys_mask); - - return 0; -} - - -int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw) -{ - LOCK_TAKE(hdw->big_lock); do { - pvr2_hdw_commit_ctl_internal(hdw); - } while (0); LOCK_GIVE(hdw->big_lock); - return 0; -} - - -void pvr2_hdw_poll(struct pvr2_hdw *hdw) -{ - LOCK_TAKE(hdw->big_lock); do { - pvr2_i2c_core_sync(hdw); - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *hdw, - void (*func)(void *), - void *data) -{ - LOCK_TAKE(hdw->big_lock); do { - hdw->poll_trigger_func = func; - hdw->poll_trigger_data = data; - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *hdw) -{ - if (hdw->poll_trigger_func) { - hdw->poll_trigger_func(hdw->poll_trigger_data); - } -} - - -void pvr2_hdw_poll_trigger(struct pvr2_hdw *hdw) -{ - LOCK_TAKE(hdw->big_lock); do { - pvr2_hdw_poll_trigger_unlocked(hdw); - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -/* Return name for this driver instance */ -const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *hdw) -{ - return hdw->name; -} - - -/* Return bit mask indicating signal status */ -unsigned int pvr2_hdw_get_signal_status_internal(struct pvr2_hdw *hdw) -{ - unsigned int msk = 0; - switch (hdw->input_val) { - case PVR2_CVAL_INPUT_TV: - case PVR2_CVAL_INPUT_RADIO: - if (hdw->decoder_ctrl && - hdw->decoder_ctrl->tuned(hdw->decoder_ctrl->ctxt)) { - msk |= PVR2_SIGNAL_OK; - if (hdw->audio_stat && - hdw->audio_stat->status(hdw->audio_stat->ctxt)) { - if (hdw->flag_stereo) { - msk |= PVR2_SIGNAL_STEREO; - } - if (hdw->flag_bilingual) { - msk |= PVR2_SIGNAL_SAP; - } - } - } - break; - default: - msk |= PVR2_SIGNAL_OK | PVR2_SIGNAL_STEREO; - } - return msk; -} - - -int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw) -{ - int result; - LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = 0x0b; - result = pvr2_send_request(hdw, - hdw->cmd_buffer,1, - hdw->cmd_buffer,1); - if (result < 0) break; - result = (hdw->cmd_buffer[0] != 0); - } while(0); LOCK_GIVE(hdw->ctl_lock); - return result; -} - - -/* Return bit mask indicating signal status */ -unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *hdw) -{ - unsigned int msk = 0; - LOCK_TAKE(hdw->big_lock); do { - msk = pvr2_hdw_get_signal_status_internal(hdw); - } while (0); LOCK_GIVE(hdw->big_lock); - return msk; -} - - -/* Get handle to video output stream */ -struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *hp) -{ - return hp->vid_stream; -} - - -void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw) -{ - int nr = pvr2_hdw_get_unit_number(hdw); - LOCK_TAKE(hdw->big_lock); do { - hdw->log_requested = !0; - printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr); - pvr2_i2c_core_check_stale(hdw); - hdw->log_requested = 0; - pvr2_i2c_core_sync(hdw); - pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:"); - cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2"); - printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr); - } while (0); LOCK_GIVE(hdw->big_lock); -} - -void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, int enable_flag) -{ - int ret; - u16 address; - unsigned int pipe; - LOCK_TAKE(hdw->big_lock); do { - if ((hdw->fw_buffer == 0) == !enable_flag) break; - - if (!enable_flag) { - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Cleaning up after CPU firmware fetch"); - kfree(hdw->fw_buffer); - hdw->fw_buffer = 0; - hdw->fw_size = 0; - /* Now release the CPU. It will disconnect and - reconnect later. */ - pvr2_hdw_cpureset_assert(hdw,0); - break; - } - - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Preparing to suck out CPU firmware"); - hdw->fw_size = 0x2000; - hdw->fw_buffer = kmalloc(hdw->fw_size,GFP_KERNEL); - if (!hdw->fw_buffer) { - hdw->fw_size = 0; - break; - } - - memset(hdw->fw_buffer,0,hdw->fw_size); - - /* We have to hold the CPU during firmware upload. */ - pvr2_hdw_cpureset_assert(hdw,1); - - /* download the firmware from address 0000-1fff in 2048 - (=0x800) bytes chunk. */ - - pvr2_trace(PVR2_TRACE_FIRMWARE,"Grabbing CPU firmware"); - pipe = usb_rcvctrlpipe(hdw->usb_dev, 0); - for(address = 0; address < hdw->fw_size; address += 0x800) { - ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0xc0, - address,0, - hdw->fw_buffer+address,0x800,HZ); - if (ret < 0) break; - } - - pvr2_trace(PVR2_TRACE_FIRMWARE,"Done grabbing CPU firmware"); - - } while (0); LOCK_GIVE(hdw->big_lock); -} - - -/* Return true if we're in a mode for retrieval CPU firmware */ -int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw) -{ - return hdw->fw_buffer != 0; -} - - -int pvr2_hdw_cpufw_get(struct pvr2_hdw *hdw,unsigned int offs, - char *buf,unsigned int cnt) -{ - int ret = -EINVAL; - LOCK_TAKE(hdw->big_lock); do { - if (!buf) break; - if (!cnt) break; - - if (!hdw->fw_buffer) { - ret = -EIO; - break; - } - - if (offs >= hdw->fw_size) { - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Read firmware data offs=%d EOF", - offs); - ret = 0; - break; - } - - if (offs + cnt > hdw->fw_size) cnt = hdw->fw_size - offs; - - memcpy(buf,hdw->fw_buffer+offs,cnt); - - pvr2_trace(PVR2_TRACE_FIRMWARE, - "Read firmware data offs=%d cnt=%d", - offs,cnt); - ret = cnt; - } while (0); LOCK_GIVE(hdw->big_lock); - - return ret; -} - - -int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *hdw) -{ - return hdw->v4l_minor_number; -} - - -/* Store the v4l minor device number */ -void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *hdw,int v) -{ - hdw->v4l_minor_number = v; -} - - -void pvr2_reset_ctl_endpoints(struct pvr2_hdw *hdw) -{ - if (!hdw->usb_dev) return; - usb_settoggle(hdw->usb_dev, PVR2_CTL_WRITE_ENDPOINT & 0xf, - !(PVR2_CTL_WRITE_ENDPOINT & USB_DIR_IN), 0); - usb_settoggle(hdw->usb_dev, PVR2_CTL_READ_ENDPOINT & 0xf, - !(PVR2_CTL_READ_ENDPOINT & USB_DIR_IN), 0); - usb_clear_halt(hdw->usb_dev, - usb_rcvbulkpipe(hdw->usb_dev, - PVR2_CTL_READ_ENDPOINT & 0x7f)); - usb_clear_halt(hdw->usb_dev, - usb_sndbulkpipe(hdw->usb_dev, - PVR2_CTL_WRITE_ENDPOINT & 0x7f)); -} - - -static void pvr2_ctl_write_complete(struct urb *urb, struct pt_regs *regs) -{ - struct pvr2_hdw *hdw = urb->context; - hdw->ctl_write_pend_flag = 0; - if (hdw->ctl_read_pend_flag) return; - complete(&hdw->ctl_done); -} - - -static void pvr2_ctl_read_complete(struct urb *urb, struct pt_regs *regs) -{ - struct pvr2_hdw *hdw = urb->context; - hdw->ctl_read_pend_flag = 0; - if (hdw->ctl_write_pend_flag) return; - complete(&hdw->ctl_done); -} - - -static void pvr2_ctl_timeout(unsigned long data) -{ - struct pvr2_hdw *hdw = (struct pvr2_hdw *)data; - if (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) { - hdw->ctl_timeout_flag = !0; - if (hdw->ctl_write_pend_flag && hdw->ctl_write_urb) { - usb_unlink_urb(hdw->ctl_write_urb); - } - if (hdw->ctl_read_pend_flag && hdw->ctl_read_urb) { - usb_unlink_urb(hdw->ctl_read_urb); - } - } -} - - -int pvr2_send_request_ex(struct pvr2_hdw *hdw, - unsigned int timeout,int probe_fl, - void *write_data,unsigned int write_len, - void *read_data,unsigned int read_len) -{ - unsigned int idx; - int status = 0; - struct timer_list timer; - if (!hdw->ctl_lock_held) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Attempted to execute control transfer" - " without lock!!"); - return -EDEADLK; - } - if ((!hdw->flag_ok) && !probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Attempted to execute control transfer" - " when device not ok"); - return -EIO; - } - if (!(hdw->ctl_read_urb && hdw->ctl_write_urb)) { - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Attempted to execute control transfer" - " when USB is disconnected"); - } - return -ENOTTY; - } - - /* Ensure that we have sane parameters */ - if (!write_data) write_len = 0; - if (!read_data) read_len = 0; - if (write_len > PVR2_CTL_BUFFSIZE) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Attempted to execute %d byte" - " control-write transfer (limit=%d)", - write_len,PVR2_CTL_BUFFSIZE); - return -EINVAL; - } - if (read_len > PVR2_CTL_BUFFSIZE) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Attempted to execute %d byte" - " control-read transfer (limit=%d)", - write_len,PVR2_CTL_BUFFSIZE); - return -EINVAL; - } - if ((!write_len) && (!read_len)) { - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "Attempted to execute null control transfer?"); - return -EINVAL; - } - - - hdw->cmd_debug_state = 1; - if (write_len) { - hdw->cmd_debug_code = ((unsigned char *)write_data)[0]; - } else { - hdw->cmd_debug_code = 0; - } - hdw->cmd_debug_write_len = write_len; - hdw->cmd_debug_read_len = read_len; - - /* Initialize common stuff */ - init_completion(&hdw->ctl_done); - hdw->ctl_timeout_flag = 0; - hdw->ctl_write_pend_flag = 0; - hdw->ctl_read_pend_flag = 0; - init_timer(&timer); - timer.expires = jiffies + timeout; - timer.data = (unsigned long)hdw; - timer.function = pvr2_ctl_timeout; - - if (write_len) { - hdw->cmd_debug_state = 2; - /* Transfer write data to internal buffer */ - for (idx = 0; idx < write_len; idx++) { - hdw->ctl_write_buffer[idx] = - ((unsigned char *)write_data)[idx]; - } - /* Initiate a write request */ - usb_fill_bulk_urb(hdw->ctl_write_urb, - hdw->usb_dev, - usb_sndbulkpipe(hdw->usb_dev, - PVR2_CTL_WRITE_ENDPOINT), - hdw->ctl_write_buffer, - write_len, - pvr2_ctl_write_complete, - hdw); - hdw->ctl_write_urb->actual_length = 0; - hdw->ctl_write_pend_flag = !0; - status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL); - if (status < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to submit write-control" - " URB status=%d",status); - hdw->ctl_write_pend_flag = 0; - goto done; - } - } - - if (read_len) { - hdw->cmd_debug_state = 3; - memset(hdw->ctl_read_buffer,0x43,read_len); - /* Initiate a read request */ - usb_fill_bulk_urb(hdw->ctl_read_urb, - hdw->usb_dev, - usb_rcvbulkpipe(hdw->usb_dev, - PVR2_CTL_READ_ENDPOINT), - hdw->ctl_read_buffer, - read_len, - pvr2_ctl_read_complete, - hdw); - hdw->ctl_read_urb->actual_length = 0; - hdw->ctl_read_pend_flag = !0; - status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL); - if (status < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to submit read-control" - " URB status=%d",status); - hdw->ctl_read_pend_flag = 0; - goto done; - } - } - - /* Start timer */ - add_timer(&timer); - - /* Now wait for all I/O to complete */ - hdw->cmd_debug_state = 4; - while (hdw->ctl_write_pend_flag || hdw->ctl_read_pend_flag) { - wait_for_completion(&hdw->ctl_done); - } - hdw->cmd_debug_state = 5; - - /* Stop timer */ - del_timer_sync(&timer); - - hdw->cmd_debug_state = 6; - status = 0; - - if (hdw->ctl_timeout_flag) { - status = -ETIMEDOUT; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Timed out control-write"); - } - goto done; - } - - if (write_len) { - /* Validate results of write request */ - if ((hdw->ctl_write_urb->status != 0) && - (hdw->ctl_write_urb->status != -ENOENT) && - (hdw->ctl_write_urb->status != -ESHUTDOWN) && - (hdw->ctl_write_urb->status != -ECONNRESET)) { - /* USB subsystem is reporting some kind of failure - on the write */ - status = hdw->ctl_write_urb->status; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-write URB failure," - " status=%d", - status); - } - goto done; - } - if (hdw->ctl_write_urb->actual_length < write_len) { - /* Failed to write enough data */ - status = -EIO; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-write URB short," - " expected=%d got=%d", - write_len, - hdw->ctl_write_urb->actual_length); - } - goto done; - } - } - if (read_len) { - /* Validate results of read request */ - if ((hdw->ctl_read_urb->status != 0) && - (hdw->ctl_read_urb->status != -ENOENT) && - (hdw->ctl_read_urb->status != -ESHUTDOWN) && - (hdw->ctl_read_urb->status != -ECONNRESET)) { - /* USB subsystem is reporting some kind of failure - on the read */ - status = hdw->ctl_read_urb->status; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-read URB failure," - " status=%d", - status); - } - goto done; - } - if (hdw->ctl_read_urb->actual_length < read_len) { - /* Failed to read enough data */ - status = -EIO; - if (!probe_fl) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "control-read URB short," - " expected=%d got=%d", - read_len, - hdw->ctl_read_urb->actual_length); - } - goto done; - } - /* Transfer retrieved data out from internal buffer */ - for (idx = 0; idx < read_len; idx++) { - ((unsigned char *)read_data)[idx] = - hdw->ctl_read_buffer[idx]; - } - } - - done: - - hdw->cmd_debug_state = 0; - if ((status < 0) && (!probe_fl)) { - pvr2_hdw_render_useless_unlocked(hdw); - } - return status; -} - - -int pvr2_send_request(struct pvr2_hdw *hdw, - void *write_data,unsigned int write_len, - void *read_data,unsigned int read_len) -{ - return pvr2_send_request_ex(hdw,HZ*4,0, - write_data,write_len, - read_data,read_len); -} - -int pvr2_write_register(struct pvr2_hdw *hdw, u16 reg, u32 data) -{ - int ret; - - LOCK_TAKE(hdw->ctl_lock); - - hdw->cmd_buffer[0] = 0x04; /* write register prefix */ - PVR2_DECOMPOSE_LE(hdw->cmd_buffer,1,data); - hdw->cmd_buffer[5] = 0; - hdw->cmd_buffer[6] = (reg >> 8) & 0xff; - hdw->cmd_buffer[7] = reg & 0xff; - - - ret = pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 0); - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -int pvr2_read_register(struct pvr2_hdw *hdw, u16 reg, u32 *data) -{ - int ret = 0; - - LOCK_TAKE(hdw->ctl_lock); - - hdw->cmd_buffer[0] = 0x05; /* read register prefix */ - hdw->cmd_buffer[1] = 0; - hdw->cmd_buffer[2] = 0; - hdw->cmd_buffer[3] = 0; - hdw->cmd_buffer[4] = 0; - hdw->cmd_buffer[5] = 0; - hdw->cmd_buffer[6] = (reg >> 8) & 0xff; - hdw->cmd_buffer[7] = reg & 0xff; - - ret |= pvr2_send_request(hdw, hdw->cmd_buffer, 8, hdw->cmd_buffer, 4); - *data = PVR2_COMPOSE_LE(hdw->cmd_buffer,0); - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -int pvr2_write_u16(struct pvr2_hdw *hdw, u16 data, int res) -{ - int ret; - - LOCK_TAKE(hdw->ctl_lock); - - hdw->cmd_buffer[0] = (data >> 8) & 0xff; - hdw->cmd_buffer[1] = data & 0xff; - - ret = pvr2_send_request(hdw, hdw->cmd_buffer, 2, hdw->cmd_buffer, res); - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -int pvr2_write_u8(struct pvr2_hdw *hdw, u8 data, int res) -{ - int ret; - - LOCK_TAKE(hdw->ctl_lock); - - hdw->cmd_buffer[0] = data; - - ret = pvr2_send_request(hdw, hdw->cmd_buffer, 1, hdw->cmd_buffer, res); - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - - -void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw) -{ - if (!hdw->flag_ok) return; - pvr2_trace(PVR2_TRACE_INIT,"render_useless"); - hdw->flag_ok = 0; - if (hdw->vid_stream) { - pvr2_stream_setup(hdw->vid_stream,0,0,0); - } - hdw->flag_streaming_enabled = 0; - hdw->subsys_enabled_mask = 0; -} - - -void pvr2_hdw_render_useless(struct pvr2_hdw *hdw) -{ - LOCK_TAKE(hdw->ctl_lock); - pvr2_hdw_render_useless_unlocked(hdw); - LOCK_GIVE(hdw->ctl_lock); -} - - -void pvr2_hdw_device_reset(struct pvr2_hdw *hdw) -{ - int ret; - pvr2_trace(PVR2_TRACE_INIT,"Performing a device reset..."); - ret = usb_lock_device_for_reset(hdw->usb_dev,0); - if (ret == 1) { - ret = usb_reset_device(hdw->usb_dev); - usb_unlock_device(hdw->usb_dev); - } else { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to lock USB device ret=%d",ret); - } - if (init_pause_msec) { - pvr2_trace(PVR2_TRACE_INFO, - "Waiting %u msec for hardware to settle", - init_pause_msec); - msleep(init_pause_msec); - } - -} - - -void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val) -{ - char da[1]; - unsigned int pipe; - int ret; - - if (!hdw->usb_dev) return; - - pvr2_trace(PVR2_TRACE_INIT,"cpureset_assert(%d)",val); - - da[0] = val ? 0x01 : 0x00; - - /* Write the CPUCS register on the 8051. The lsb of the register - is the reset bit; a 1 asserts reset while a 0 clears it. */ - pipe = usb_sndctrlpipe(hdw->usb_dev, 0); - ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ); - if (ret < 0) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "cpureset_assert(%d) error=%d",val,ret); - pvr2_hdw_render_useless(hdw); - } -} - - -int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *hdw) -{ - int status; - LOCK_TAKE(hdw->ctl_lock); do { - pvr2_trace(PVR2_TRACE_INIT,"Requesting uproc hard reset"); - hdw->flag_ok = !0; - hdw->cmd_buffer[0] = 0xdd; - status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0); - } while (0); LOCK_GIVE(hdw->ctl_lock); - return status; -} - - -int pvr2_hdw_cmd_powerup(struct pvr2_hdw *hdw) -{ - int status; - LOCK_TAKE(hdw->ctl_lock); do { - pvr2_trace(PVR2_TRACE_INIT,"Requesting powerup"); - hdw->cmd_buffer[0] = 0xde; - status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0); - } while (0); LOCK_GIVE(hdw->ctl_lock); - return status; -} - - -int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw) -{ - if (!hdw->decoder_ctrl) { - pvr2_trace(PVR2_TRACE_INIT, - "Unable to reset decoder: nothing attached"); - return -ENOTTY; - } - - if (!hdw->decoder_ctrl->force_reset) { - pvr2_trace(PVR2_TRACE_INIT, - "Unable to reset decoder: not implemented"); - return -ENOTTY; - } - - pvr2_trace(PVR2_TRACE_INIT, - "Requesting decoder reset"); - hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt); - return 0; -} - - -int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl) -{ - int status; - LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = (runFl ? 0x36 : 0x37); - status = pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0); - } while (0); LOCK_GIVE(hdw->ctl_lock); - if (!status) { - hdw->subsys_enabled_mask = - ((hdw->subsys_enabled_mask & - ~(1<big_lock_held = hdw->big_lock_held; - ptr->ctl_lock_held = hdw->ctl_lock_held; - ptr->flag_ok = hdw->flag_ok; - ptr->flag_disconnected = hdw->flag_disconnected; - ptr->flag_init_ok = hdw->flag_init_ok; - ptr->flag_streaming_enabled = hdw->flag_streaming_enabled; - ptr->subsys_flags = hdw->subsys_enabled_mask; - ptr->cmd_debug_state = hdw->cmd_debug_state; - ptr->cmd_code = hdw->cmd_debug_code; - ptr->cmd_debug_write_len = hdw->cmd_debug_write_len; - ptr->cmd_debug_read_len = hdw->cmd_debug_read_len; - ptr->cmd_debug_timeout = hdw->ctl_timeout_flag; - ptr->cmd_debug_write_pend = hdw->ctl_write_pend_flag; - ptr->cmd_debug_read_pend = hdw->ctl_read_pend_flag; - ptr->cmd_debug_rstatus = hdw->ctl_read_urb->status; - ptr->cmd_debug_wstatus = hdw->ctl_read_urb->status; -} - - -int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *dp) -{ - return pvr2_read_register(hdw,PVR2_GPIO_DIR,dp); -} - - -int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *dp) -{ - return pvr2_read_register(hdw,PVR2_GPIO_OUT,dp); -} - - -int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *dp) -{ - return pvr2_read_register(hdw,PVR2_GPIO_IN,dp); -} - - -int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val) -{ - u32 cval,nval; - int ret; - if (~msk) { - ret = pvr2_read_register(hdw,PVR2_GPIO_DIR,&cval); - if (ret) return ret; - nval = (cval & ~msk) | (val & msk); - pvr2_trace(PVR2_TRACE_GPIO, - "GPIO direction changing 0x%x:0x%x" - " from 0x%x to 0x%x", - msk,val,cval,nval); - } else { - nval = val; - pvr2_trace(PVR2_TRACE_GPIO, - "GPIO direction changing to 0x%x",nval); - } - return pvr2_write_register(hdw,PVR2_GPIO_DIR,nval); -} - - -int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val) -{ - u32 cval,nval; - int ret; - if (~msk) { - ret = pvr2_read_register(hdw,PVR2_GPIO_OUT,&cval); - if (ret) return ret; - nval = (cval & ~msk) | (val & msk); - pvr2_trace(PVR2_TRACE_GPIO, - "GPIO output changing 0x%x:0x%x from 0x%x to 0x%x", - msk,val,cval,nval); - } else { - nval = val; - pvr2_trace(PVR2_TRACE_GPIO, - "GPIO output changing to 0x%x",nval); - } - return pvr2_write_register(hdw,PVR2_GPIO_OUT,nval); -} - - -int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw) -{ - int result; - LOCK_TAKE(hdw->ctl_lock); do { - hdw->cmd_buffer[0] = 0xeb; - result = pvr2_send_request(hdw, - hdw->cmd_buffer,1, - hdw->cmd_buffer,1); - if (result < 0) break; - result = hdw->cmd_buffer[0]; - } while(0); LOCK_GIVE(hdw->ctl_lock); - return result; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h deleted file mode 100644 index 63f529154431..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.h +++ /dev/null @@ -1,335 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_HDW_H -#define __PVRUSB2_HDW_H - -#include -#include -#include "pvrusb2-io.h" -#include "pvrusb2-ctrl.h" - - -/* Private internal control ids, look these up with - pvr2_hdw_get_ctrl_by_id() - these are NOT visible in V4L */ -#define PVR2_CID_STDENUM 1 -#define PVR2_CID_STDCUR 2 -#define PVR2_CID_STDAVAIL 3 -#define PVR2_CID_INPUT 4 -#define PVR2_CID_AUDIOMODE 5 -#define PVR2_CID_FREQUENCY 6 -#define PVR2_CID_HRES 7 -#define PVR2_CID_VRES 8 - -/* Legal values for the INPUT state variable */ -#define PVR2_CVAL_INPUT_TV 0 -#define PVR2_CVAL_INPUT_SVIDEO 1 -#define PVR2_CVAL_INPUT_COMPOSITE 2 -#define PVR2_CVAL_INPUT_RADIO 3 - -/* Values that pvr2_hdw_get_signal_status() returns */ -#define PVR2_SIGNAL_OK 0x0001 -#define PVR2_SIGNAL_STEREO 0x0002 -#define PVR2_SIGNAL_SAP 0x0004 - - -/* Subsystem definitions - these are various pieces that can be - independently stopped / started. Usually you don't want to mess with - this directly (let the driver handle things itself), but it is useful - for debugging. */ -#define PVR2_SUBSYS_B_ENC_FIRMWARE 0 -#define PVR2_SUBSYS_B_ENC_CFG 1 -#define PVR2_SUBSYS_B_DIGITIZER_RUN 2 -#define PVR2_SUBSYS_B_USBSTREAM_RUN 3 -#define PVR2_SUBSYS_B_ENC_RUN 4 - -#define PVR2_SUBSYS_CFG_ALL ( \ - (1 << PVR2_SUBSYS_B_ENC_FIRMWARE) | \ - (1 << PVR2_SUBSYS_B_ENC_CFG) ) -#define PVR2_SUBSYS_RUN_ALL ( \ - (1 << PVR2_SUBSYS_B_DIGITIZER_RUN) | \ - (1 << PVR2_SUBSYS_B_USBSTREAM_RUN) | \ - (1 << PVR2_SUBSYS_B_ENC_RUN) ) -#define PVR2_SUBSYS_ALL ( \ - PVR2_SUBSYS_CFG_ALL | \ - PVR2_SUBSYS_RUN_ALL ) - -enum pvr2_config { - pvr2_config_empty, - pvr2_config_mpeg, - pvr2_config_vbi, - pvr2_config_radio, -}; - -const char *pvr2_config_get_name(enum pvr2_config); - -struct pvr2_hdw; - -/* Create and return a structure for interacting with the underlying - hardware */ -struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, - const struct usb_device_id *devid); - -/* Poll for background activity (if any) */ -void pvr2_hdw_poll(struct pvr2_hdw *); - -/* Trigger a poll to take place later at a convenient time */ -void pvr2_hdw_poll_trigger(struct pvr2_hdw *); -void pvr2_hdw_poll_trigger_unlocked(struct pvr2_hdw *); - -/* Register a callback used to trigger a future poll */ -void pvr2_hdw_setup_poll_trigger(struct pvr2_hdw *, - void (*func)(void *), - void *data); - -/* Get pointer to structure given unit number */ -struct pvr2_hdw *pvr2_hdw_find(int unit_number); - -/* Destroy hardware interaction structure */ -void pvr2_hdw_destroy(struct pvr2_hdw *); - -/* Set up the structure and attempt to put the device into a usable state. - This can be a time-consuming operation, which is why it is not done - internally as part of the create() step. Return value is exactly the - same as pvr2_hdw_init_ok(). */ -int pvr2_hdw_setup(struct pvr2_hdw *); - -/* Initialization succeeded */ -int pvr2_hdw_init_ok(struct pvr2_hdw *); - -/* Return true if in the ready (normal) state */ -int pvr2_hdw_dev_ok(struct pvr2_hdw *); - -/* Return small integer number [1..N] for logical instance number of this - device. This is useful for indexing array-valued module parameters. */ -int pvr2_hdw_get_unit_number(struct pvr2_hdw *); - -/* Get pointer to underlying USB device */ -struct usb_device *pvr2_hdw_get_dev(struct pvr2_hdw *); - -/* Retrieve serial number of device */ -unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *); - -/* Called when hardware has been unplugged */ -void pvr2_hdw_disconnect(struct pvr2_hdw *); - -/* Get the number of defined controls */ -unsigned int pvr2_hdw_get_ctrl_count(struct pvr2_hdw *); - -/* Retrieve a control handle given its index (0..count-1) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_index(struct pvr2_hdw *,unsigned int); - -/* Retrieve a control handle given its internal ID (if any) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_by_id(struct pvr2_hdw *,unsigned int); - -/* Retrieve a control handle given its V4L ID (if any) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_v4l(struct pvr2_hdw *,unsigned int ctl_id); - -/* Retrieve a control handle given its immediate predecessor V4L ID (if any) */ -struct pvr2_ctrl *pvr2_hdw_get_ctrl_nextv4l(struct pvr2_hdw *, - unsigned int ctl_id); - -/* Commit all control changes made up to this point */ -int pvr2_hdw_commit_ctl(struct pvr2_hdw *); - -/* Return name for this driver instance */ -const char *pvr2_hdw_get_driver_name(struct pvr2_hdw *); - -/* Return PVR2_SIGNAL_XXXX bit mask indicating signal status */ -unsigned int pvr2_hdw_get_signal_status(struct pvr2_hdw *); - -/* Query device and see if it thinks it is on a high-speed USB link */ -int pvr2_hdw_is_hsm(struct pvr2_hdw *); - -/* Turn streaming on/off */ -int pvr2_hdw_set_streaming(struct pvr2_hdw *,int); - -/* Find out if streaming is on */ -int pvr2_hdw_get_streaming(struct pvr2_hdw *); - -/* Configure the type of stream to generate */ -int pvr2_hdw_set_stream_type(struct pvr2_hdw *, enum pvr2_config); - -/* Get handle to video output stream */ -struct pvr2_stream *pvr2_hdw_get_video_stream(struct pvr2_hdw *); - -/* Emit a video standard struct */ -int pvr2_hdw_get_stdenum_value(struct pvr2_hdw *hdw,struct v4l2_standard *std, - unsigned int idx); - -/* Enable / disable various pieces of hardware. Items to change are - identified by bit positions within msk, and new state for each item is - identified by corresponding bit positions within val. */ -void pvr2_hdw_subsys_bit_chg(struct pvr2_hdw *hdw, - unsigned long msk,unsigned long val); - -/* Shortcut for pvr2_hdw_subsys_bit_chg(hdw,msk,msk) */ -void pvr2_hdw_subsys_bit_set(struct pvr2_hdw *hdw,unsigned long msk); - -/* Shortcut for pvr2_hdw_subsys_bit_chg(hdw,msk,0) */ -void pvr2_hdw_subsys_bit_clr(struct pvr2_hdw *hdw,unsigned long msk); - -/* Retrieve mask indicating which pieces of hardware are currently enabled - / configured. */ -unsigned long pvr2_hdw_subsys_get(struct pvr2_hdw *); - -/* Adjust mask of what get shut down when streaming is stopped. This is a - debugging aid. */ -void pvr2_hdw_subsys_stream_bit_chg(struct pvr2_hdw *hdw, - unsigned long msk,unsigned long val); - -/* Retrieve mask indicating which pieces of hardware are disabled when - streaming is turned off. */ -unsigned long pvr2_hdw_subsys_stream_get(struct pvr2_hdw *); - - -/* Enable / disable retrieval of CPU firmware. This must be enabled before - pvr2_hdw_cpufw_get() will function. Note that doing this may prevent - the device from running (and leaving this mode may imply a device - reset). */ -void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *, int enable_flag); - -/* Return true if we're in a mode for retrieval CPU firmware */ -int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *); - -/* Retrieve a piece of the CPU's firmware at the given offset. Return - value is the number of bytes retrieved or zero if we're past the end or - an error otherwise (e.g. if firmware retrieval is not enabled). */ -int pvr2_hdw_cpufw_get(struct pvr2_hdw *,unsigned int offs, - char *buf,unsigned int cnt); - -/* Retrieve previously stored v4l minor device number */ -int pvr2_hdw_v4l_get_minor_number(struct pvr2_hdw *); - -/* Store the v4l minor device number */ -void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,int); - - -/* The following entry points are all lower level things you normally don't - want to worry about. */ - -/* Attempt to recover from a USB foul-up (in practice I find that if you - have to do this, then it's already too late). */ -void pvr2_reset_ctl_endpoints(struct pvr2_hdw *hdw); - -/* Issue a command and get a response from the device. LOTS of higher - level stuff is built on this. */ -int pvr2_send_request(struct pvr2_hdw *, - void *write_ptr,unsigned int write_len, - void *read_ptr,unsigned int read_len); - -/* Issue a command and get a response from the device. This extended - version includes a probe flag (which if set means that device errors - should not be logged or treated as fatal) and a timeout in jiffies. - This can be used to non-lethally probe the health of endpoint 1. */ -int pvr2_send_request_ex(struct pvr2_hdw *,unsigned int timeout,int probe_fl, - void *write_ptr,unsigned int write_len, - void *read_ptr,unsigned int read_len); - -/* Slightly higher level device communication functions. */ -int pvr2_write_register(struct pvr2_hdw *, u16, u32); -int pvr2_read_register(struct pvr2_hdw *, u16, u32 *); -int pvr2_write_u16(struct pvr2_hdw *, u16, int); -int pvr2_write_u8(struct pvr2_hdw *, u8, int); - -/* Call if for any reason we can't talk to the hardware anymore - this will - cause the driver to stop flailing on the device. */ -void pvr2_hdw_render_useless(struct pvr2_hdw *); -void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *); - -/* Set / clear 8051's reset bit */ -void pvr2_hdw_cpureset_assert(struct pvr2_hdw *,int); - -/* Execute a USB-commanded device reset */ -void pvr2_hdw_device_reset(struct pvr2_hdw *); - -/* Execute hard reset command (after this point it's likely that the - encoder will have to be reconfigured). This also clears the "useless" - state. */ -int pvr2_hdw_cmd_deep_reset(struct pvr2_hdw *); - -/* Execute simple reset command */ -int pvr2_hdw_cmd_powerup(struct pvr2_hdw *); - -/* Order decoder to reset */ -int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *); - -/* Stop / start video stream transport */ -int pvr2_hdw_cmd_usbstream(struct pvr2_hdw *hdw,int runFl); - -/* Find I2C address of eeprom */ -int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *); - -/* Direct manipulation of GPIO bits */ -int pvr2_hdw_gpio_get_dir(struct pvr2_hdw *hdw,u32 *); -int pvr2_hdw_gpio_get_out(struct pvr2_hdw *hdw,u32 *); -int pvr2_hdw_gpio_get_in(struct pvr2_hdw *hdw,u32 *); -int pvr2_hdw_gpio_chg_dir(struct pvr2_hdw *hdw,u32 msk,u32 val); -int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val); - -/* This data structure is specifically for the next function... */ -struct pvr2_hdw_debug_info { - int big_lock_held; - int ctl_lock_held; - int flag_ok; - int flag_disconnected; - int flag_init_ok; - int flag_streaming_enabled; - unsigned long subsys_flags; - int cmd_debug_state; - int cmd_debug_write_len; - int cmd_debug_read_len; - int cmd_debug_write_pend; - int cmd_debug_read_pend; - int cmd_debug_timeout; - int cmd_debug_rstatus; - int cmd_debug_wstatus; - unsigned char cmd_code; -}; - -/* Non-intrusively retrieve internal state info - this is useful for - diagnosing lockups. Note that this operation is completed without any - kind of locking and so it is not atomic and may yield inconsistent - results. This is *purely* a debugging aid. */ -void pvr2_hdw_get_debug_info(const struct pvr2_hdw *hdw, - struct pvr2_hdw_debug_info *); - -/* Cause modules to log their state once */ -void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw); - -/* Cause encoder firmware to be uploaded into the device. This is normally - done autonomously, but the interface is exported here because it is also - a debugging aid. */ -int pvr2_upload_firmware2(struct pvr2_hdw *hdw); - -/* List of device types that we can match */ -extern struct usb_device_id pvr2_device_table[]; - -#endif /* __PVRUSB2_HDW_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c deleted file mode 100644 index 1dd4f6249b99..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * 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 "pvrusb2-i2c-core.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-i2c-cmd-v4l2.h" -#include "pvrusb2-audio.h" -#include "pvrusb2-tuner.h" -#include "pvrusb2-demod.h" -#include "pvrusb2-video-v4l.h" -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX -#include "pvrusb2-cx2584x-v4l.h" -#include "pvrusb2-wm8775.h" -#endif - -#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__) - -#define OP_STANDARD 0 -#define OP_BCSH 1 -#define OP_VOLUME 2 -#define OP_FREQ 3 -#define OP_AUDIORATE 4 -#define OP_SIZE 5 -#define OP_LOG 6 - -static const struct pvr2_i2c_op * const ops[] = { - [OP_STANDARD] = &pvr2_i2c_op_v4l2_standard, - [OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh, - [OP_VOLUME] = &pvr2_i2c_op_v4l2_volume, - [OP_FREQ] = &pvr2_i2c_op_v4l2_frequency, - [OP_SIZE] = &pvr2_i2c_op_v4l2_size, - [OP_LOG] = &pvr2_i2c_op_v4l2_log, -}; - -void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) -{ - int id; - id = cp->client->driver->id; - cp->ctl_mask = ((1 << OP_STANDARD) | - (1 << OP_BCSH) | - (1 << OP_VOLUME) | - (1 << OP_FREQ) | - (1 << OP_SIZE) | - (1 << OP_LOG)); - - if (id == I2C_DRIVERID_MSP3400) { - if (pvr2_i2c_msp3400_setup(hdw,cp)) { - return; - } - } - if (id == I2C_DRIVERID_TUNER) { - if (pvr2_i2c_tuner_setup(hdw,cp)) { - return; - } - } -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - if (id == I2C_DRIVERID_CX25840) { - if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) { - return; - } - } - if (id == I2C_DRIVERID_WM8775) { - if (pvr2_i2c_wm8775_setup(hdw,cp)) { - return; - } - } -#endif - if (id == I2C_DRIVERID_SAA711X) { - if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) { - return; - } - } - if (id == I2C_DRIVERID_TDA9887) { - if (pvr2_i2c_demod_setup(hdw,cp)) { - return; - } - } -} - - -const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx) -{ - if (idx >= sizeof(ops)/sizeof(ops[0])) return 0; - return ops[idx]; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c deleted file mode 100644 index 9f81aff2b38a..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * 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 "pvrusb2-i2c-cmd-v4l2.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include - - -static void set_standard(struct pvr2_hdw *hdw) -{ - v4l2_std_id vs; - vs = hdw->std_mask_cur; - pvr2_trace(PVR2_TRACE_CHIPS, - "i2c v4l2 set_standard(0x%llx)",(__u64)vs); - - pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs); -} - - -static int check_standard(struct pvr2_hdw *hdw) -{ - return hdw->std_dirty != 0; -} - - -const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard = { - .check = check_standard, - .update = set_standard, - .name = "v4l2_standard", -}; - - -static void set_bcsh(struct pvr2_hdw *hdw) -{ - struct v4l2_control ctrl; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_bcsh" - " b=%d c=%d s=%d h=%d", - hdw->brightness_val,hdw->contrast_val, - hdw->saturation_val,hdw->hue_val); - memset(&ctrl,0,sizeof(ctrl)); - ctrl.id = V4L2_CID_BRIGHTNESS; - ctrl.value = hdw->brightness_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_CONTRAST; - ctrl.value = hdw->contrast_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_SATURATION; - ctrl.value = hdw->saturation_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_HUE; - ctrl.value = hdw->hue_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); -} - - -static int check_bcsh(struct pvr2_hdw *hdw) -{ - return (hdw->brightness_dirty || - hdw->contrast_dirty || - hdw->saturation_dirty || - hdw->hue_dirty); -} - - -const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh = { - .check = check_bcsh, - .update = set_bcsh, - .name = "v4l2_bcsh", -}; - - -static void set_volume(struct pvr2_hdw *hdw) -{ - struct v4l2_control ctrl; - pvr2_trace(PVR2_TRACE_CHIPS, - "i2c v4l2 set_volume" - "(vol=%d bal=%d bas=%d treb=%d mute=%d)", - hdw->volume_val, - hdw->balance_val, - hdw->bass_val, - hdw->treble_val, - hdw->mute_val); - memset(&ctrl,0,sizeof(ctrl)); - ctrl.id = V4L2_CID_AUDIO_MUTE; - ctrl.value = hdw->mute_val ? 1 : 0; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_AUDIO_VOLUME; - ctrl.value = hdw->volume_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_AUDIO_BALANCE; - ctrl.value = hdw->balance_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_AUDIO_BASS; - ctrl.value = hdw->bass_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); - ctrl.id = V4L2_CID_AUDIO_TREBLE; - ctrl.value = hdw->treble_val; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl); -} - - -static int check_volume(struct pvr2_hdw *hdw) -{ - return (hdw->volume_dirty || - hdw->balance_dirty || - hdw->bass_dirty || - hdw->treble_dirty || - hdw->mute_dirty); -} - - -const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume = { - .check = check_volume, - .update = set_volume, - .name = "v4l2_volume", -}; - - -static void set_frequency(struct pvr2_hdw *hdw) -{ - unsigned long fv; - struct v4l2_frequency freq; - fv = hdw->freqVal; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_freq(%lu)",fv); - memset(&freq,0,sizeof(freq)); - freq.frequency = fv / 62500; - freq.tuner = 0; - freq.type = V4L2_TUNER_ANALOG_TV; - pvr2_i2c_core_cmd(hdw,VIDIOC_S_FREQUENCY,&freq); -} - - -static int check_frequency(struct pvr2_hdw *hdw) -{ - return hdw->freqDirty != 0; -} - - -const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency = { - .check = check_frequency, - .update = set_frequency, - .name = "v4l2_freq", -}; - - -static void set_size(struct pvr2_hdw *hdw) -{ - struct v4l2_format fmt; - - memset(&fmt,0,sizeof(fmt)); - - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = hdw->res_hor_val; - fmt.fmt.pix.height = hdw->res_ver_val; - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_size(%dx%d)", - fmt.fmt.pix.width,fmt.fmt.pix.height); - - pvr2_i2c_core_cmd(hdw,VIDIOC_S_FMT,&fmt); -} - - -static int check_size(struct pvr2_hdw *hdw) -{ - return (hdw->res_hor_dirty || hdw->res_ver_dirty); -} - - -const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = { - .check = check_size, - .update = set_size, - .name = "v4l2_size", -}; - - -static void do_log(struct pvr2_hdw *hdw) -{ - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()"); - pvr2_i2c_core_cmd(hdw,VIDIOC_LOG_STATUS,0); - -} - - -static int check_log(struct pvr2_hdw *hdw) -{ - return hdw->log_requested != 0; -} - - -const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log = { - .check = check_log, - .update = do_log, - .name = "v4l2_log", -}; - - -void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl) -{ - pvr2_i2c_client_cmd(cp, - (fl ? VIDIOC_STREAMON : VIDIOC_STREAMOFF),0); -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h deleted file mode 100644 index ecabddba1ec5..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_CMD_V4L2_H -#define __PVRUSB2_CMD_V4L2_H - -#include "pvrusb2-i2c-core.h" - -extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard; -extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh; -extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume; -extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency; -extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size; -extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log; - -void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int); - -#endif /* __PVRUSB2_CMD_V4L2_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c deleted file mode 100644 index c8d0bdee3ff1..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c +++ /dev/null @@ -1,937 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * 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 "pvrusb2-i2c-core.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" - -#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__) - -/* - - This module attempts to implement a compliant I2C adapter for the pvrusb2 - device. By doing this we can then make use of existing functionality in - V4L (e.g. tuner.c) rather than rolling our own. - -*/ - -static unsigned int i2c_scan = 0; -module_param(i2c_scan, int, S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time"); - -static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */ - u8 i2c_addr, /* I2C address we're talking to */ - u8 *data, /* Data to write */ - u16 length) /* Size of data to write */ -{ - /* Return value - default 0 means success */ - int ret; - - - if (!data) length = 0; - if (length > (sizeof(hdw->cmd_buffer) - 3)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Killing an I2C write to %u that is too large" - " (desired=%u limit=%u)", - i2c_addr, - length,(unsigned int)(sizeof(hdw->cmd_buffer) - 3)); - return -ENOTSUPP; - } - - LOCK_TAKE(hdw->ctl_lock); - - /* Clear the command buffer (likely to be paranoia) */ - memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer)); - - /* Set up command buffer for an I2C write */ - hdw->cmd_buffer[0] = 0x08; /* write prefix */ - hdw->cmd_buffer[1] = i2c_addr; /* i2c addr of chip */ - hdw->cmd_buffer[2] = length; /* length of what follows */ - if (length) memcpy(hdw->cmd_buffer + 3, data, length); - - /* Do the operation */ - ret = pvr2_send_request(hdw, - hdw->cmd_buffer, - length + 3, - hdw->cmd_buffer, - 1); - if (!ret) { - if (hdw->cmd_buffer[0] != 8) { - ret = -EIO; - if (hdw->cmd_buffer[0] != 7) { - trace_i2c("unexpected status" - " from i2_write[%d]: %d", - i2c_addr,hdw->cmd_buffer[0]); - } - } - } - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - -static int pvr2_i2c_read(struct pvr2_hdw *hdw, /* Context */ - u8 i2c_addr, /* I2C address we're talking to */ - u8 *data, /* Data to write */ - u16 dlen, /* Size of data to write */ - u8 *res, /* Where to put data we read */ - u16 rlen) /* Amount of data to read */ -{ - /* Return value - default 0 means success */ - int ret; - - - if (!data) dlen = 0; - if (dlen > (sizeof(hdw->cmd_buffer) - 4)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Killing an I2C read to %u that has wlen too large" - " (desired=%u limit=%u)", - i2c_addr, - dlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 4)); - return -ENOTSUPP; - } - if (res && (rlen > (sizeof(hdw->cmd_buffer) - 1))) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Killing an I2C read to %u that has rlen too large" - " (desired=%u limit=%u)", - i2c_addr, - rlen,(unsigned int)(sizeof(hdw->cmd_buffer) - 1)); - return -ENOTSUPP; - } - - LOCK_TAKE(hdw->ctl_lock); - - /* Clear the command buffer (likely to be paranoia) */ - memset(hdw->cmd_buffer, 0, sizeof(hdw->cmd_buffer)); - - /* Set up command buffer for an I2C write followed by a read */ - hdw->cmd_buffer[0] = 0x09; /* read prefix */ - hdw->cmd_buffer[1] = dlen; /* arg length */ - hdw->cmd_buffer[2] = rlen; /* answer length. Device will send one - more byte (status). */ - hdw->cmd_buffer[3] = i2c_addr; /* i2c addr of chip */ - if (dlen) memcpy(hdw->cmd_buffer + 4, data, dlen); - - /* Do the operation */ - ret = pvr2_send_request(hdw, - hdw->cmd_buffer, - 4 + dlen, - hdw->cmd_buffer, - rlen + 1); - if (!ret) { - if (hdw->cmd_buffer[0] != 8) { - ret = -EIO; - if (hdw->cmd_buffer[0] != 7) { - trace_i2c("unexpected status" - " from i2_read[%d]: %d", - i2c_addr,hdw->cmd_buffer[0]); - } - } - } - - /* Copy back the result */ - if (res && rlen) { - if (ret) { - /* Error, just blank out the return buffer */ - memset(res, 0, rlen); - } else { - memcpy(res, hdw->cmd_buffer + 1, rlen); - } - } - - LOCK_GIVE(hdw->ctl_lock); - - return ret; -} - -/* This is the common low level entry point for doing I2C operations to the - hardware. */ -int pvr2_i2c_basic_op(struct pvr2_hdw *hdw, - u8 i2c_addr, - u8 *wdata, - u16 wlen, - u8 *rdata, - u16 rlen) -{ - if (!rdata) rlen = 0; - if (!wdata) wlen = 0; - if (rlen || !wlen) { - return pvr2_i2c_read(hdw,i2c_addr,wdata,wlen,rdata,rlen); - } else { - return pvr2_i2c_write(hdw,i2c_addr,wdata,wlen); - } -} - -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - -/* This is a special entry point that is entered if an I2C operation is - attempted to a wm8775 chip on model 24xxx hardware. Autodetect of this - part doesn't work, but we know it is really there. So let's look for - the autodetect attempt and just return success if we see that. */ -static int i2c_hack_wm8775(struct pvr2_hdw *hdw, - u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen) -{ - if (!(rlen || wlen)) { - // This is a probe attempt. Just let it succeed. - return 0; - } - return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen); -} - -/* This is a special entry point that is entered if an I2C operation is - attempted to a cx25840 chip on model 24xxx hardware. This chip can - sometimes wedge itself. Worse still, when this happens msp3400 can - falsely detect this part and then the system gets hosed up after msp3400 - gets confused and dies. What we want to do here is try to keep msp3400 - away and also try to notice if the chip is wedged and send a warning to - the system log. */ -static int i2c_hack_cx25840(struct pvr2_hdw *hdw, - u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen) -{ - int ret; - unsigned int subaddr; - u8 wbuf[2]; - int state = hdw->i2c_cx25840_hack_state; - - if (!(rlen || wlen)) { - // Probe attempt - always just succeed and don't bother the - // hardware (this helps to make the state machine further - // down somewhat easier). - return 0; - } - - if (state == 3) { - return pvr2_i2c_basic_op(hdw,i2c_addr,wdata,wlen,rdata,rlen); - } - - /* We're looking for the exact pattern where the revision register - is being read. The cx25840 module will always look at the - revision register first. Any other pattern of access therefore - has to be a probe attempt from somebody else so we'll reject it. - Normally we could just let each client just probe the part - anyway, but when the cx25840 is wedged, msp3400 will get a false - positive and that just screws things up... */ - - if (wlen == 0) { - switch (state) { - case 1: subaddr = 0x0100; break; - case 2: subaddr = 0x0101; break; - default: goto fail; - } - } else if (wlen == 2) { - subaddr = (wdata[0] << 8) | wdata[1]; - switch (subaddr) { - case 0x0100: state = 1; break; - case 0x0101: state = 2; break; - default: goto fail; - } - } else { - goto fail; - } - if (!rlen) goto success; - state = 0; - if (rlen != 1) goto fail; - - /* If we get to here then we have a legitimate read for one of the - two revision bytes, so pass it through. */ - wbuf[0] = subaddr >> 8; - wbuf[1] = subaddr; - ret = pvr2_i2c_basic_op(hdw,i2c_addr,wbuf,2,rdata,rlen); - - if ((ret != 0) || (*rdata == 0x04) || (*rdata == 0x0a)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING: Detected a wedged cx25840 chip;" - " the device will not work."); - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING: Try power cycling the pvrusb2 device."); - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "WARNING: Disabling further access to the device" - " to prevent other foul-ups."); - // This blocks all further communication with the part. - hdw->i2c_func[0x44] = 0; - pvr2_hdw_render_useless(hdw); - goto fail; - } - - /* Success! */ - pvr2_trace(PVR2_TRACE_CHIPS,"cx25840 appears to be OK."); - state = 3; - - success: - hdw->i2c_cx25840_hack_state = state; - return 0; - - fail: - hdw->i2c_cx25840_hack_state = state; - return -EIO; -} - -#endif /* CONFIG_VIDEO_PVRUSB2_24XXX */ - -/* This is a very, very limited I2C adapter implementation. We can only - support what we actually know will work on the device... */ -static int pvr2_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msgs[], - int num) -{ - int ret = -ENOTSUPP; - pvr2_i2c_func funcp = 0; - struct pvr2_hdw *hdw = (struct pvr2_hdw *)(i2c_adap->algo_data); - - if (!num) { - ret = -EINVAL; - goto done; - } - if ((msgs[0].flags & I2C_M_NOSTART)) { - trace_i2c("i2c refusing I2C_M_NOSTART"); - goto done; - } - if (msgs[0].addr < PVR2_I2C_FUNC_CNT) { - funcp = hdw->i2c_func[msgs[0].addr]; - } - if (!funcp) { - ret = -EIO; - goto done; - } - - if (num == 1) { - if (msgs[0].flags & I2C_M_RD) { - /* Simple read */ - u16 tcnt,bcnt,offs; - if (!msgs[0].len) { - /* Length == 0 read. This is a probe. */ - if (funcp(hdw,msgs[0].addr,0,0,0,0)) { - ret = -EIO; - goto done; - } - ret = 1; - goto done; - } - /* If the read is short enough we'll do the whole - thing atomically. Otherwise we have no choice - but to break apart the reads. */ - tcnt = msgs[0].len; - offs = 0; - while (tcnt) { - bcnt = tcnt; - if (bcnt > sizeof(hdw->cmd_buffer)-1) { - bcnt = sizeof(hdw->cmd_buffer)-1; - } - if (funcp(hdw,msgs[0].addr,0,0, - msgs[0].buf+offs,bcnt)) { - ret = -EIO; - goto done; - } - offs += bcnt; - tcnt -= bcnt; - } - ret = 1; - goto done; - } else { - /* Simple write */ - ret = 1; - if (funcp(hdw,msgs[0].addr, - msgs[0].buf,msgs[0].len,0,0)) { - ret = -EIO; - } - goto done; - } - } else if (num == 2) { - if (msgs[0].addr != msgs[1].addr) { - trace_i2c("i2c refusing 2 phase transfer with" - " conflicting target addresses"); - ret = -ENOTSUPP; - goto done; - } - if ((!((msgs[0].flags & I2C_M_RD))) && - (msgs[1].flags & I2C_M_RD)) { - u16 tcnt,bcnt,wcnt,offs; - /* Write followed by atomic read. If the read - portion is short enough we'll do the whole thing - atomically. Otherwise we have no choice but to - break apart the reads. */ - tcnt = msgs[1].len; - wcnt = msgs[0].len; - offs = 0; - while (tcnt || wcnt) { - bcnt = tcnt; - if (bcnt > sizeof(hdw->cmd_buffer)-1) { - bcnt = sizeof(hdw->cmd_buffer)-1; - } - if (funcp(hdw,msgs[0].addr, - msgs[0].buf,wcnt, - msgs[1].buf+offs,bcnt)) { - ret = -EIO; - goto done; - } - offs += bcnt; - tcnt -= bcnt; - wcnt = 0; - } - ret = 2; - goto done; - } else { - trace_i2c("i2c refusing complex transfer" - " read0=%d read1=%d", - (msgs[0].flags & I2C_M_RD), - (msgs[1].flags & I2C_M_RD)); - } - } else { - trace_i2c("i2c refusing %d phase transfer",num); - } - - done: - if (pvrusb2_debug & PVR2_TRACE_I2C_TRAF) { - unsigned int idx,offs,cnt; - for (idx = 0; idx < num; idx++) { - cnt = msgs[idx].len; - printk(KERN_INFO - "pvrusb2 i2c xfer %u/%u:" - " addr=0x%x len=%d %s%s", - idx+1,num, - msgs[idx].addr, - cnt, - (msgs[idx].flags & I2C_M_RD ? - "read" : "write"), - (msgs[idx].flags & I2C_M_NOSTART ? - " nostart" : "")); - if ((ret > 0) || !(msgs[idx].flags & I2C_M_RD)) { - if (cnt > 8) cnt = 8; - printk(" ["); - for (offs = 0; offs < (cnt>8?8:cnt); offs++) { - if (offs) printk(" "); - printk("%02x",msgs[idx].buf[offs]); - } - if (offs < cnt) printk(" ..."); - printk("]"); - } - if (idx+1 == num) { - printk(" result=%d",ret); - } - printk("\n"); - } - if (!num) { - printk(KERN_INFO - "pvrusb2 i2c xfer null transfer result=%d\n", - ret); - } - } - return ret; -} - -static int pvr2_i2c_control(struct i2c_adapter *adapter, - unsigned int cmd, unsigned long arg) -{ - return 0; -} - -static u32 pvr2_i2c_functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA; -} - -static int pvr2_i2c_core_singleton(struct i2c_client *cp, - unsigned int cmd,void *arg) -{ - int stat; - if (!cp) return -EINVAL; - if (!(cp->driver)) return -EINVAL; - if (!(cp->driver->command)) return -EINVAL; - if (!try_module_get(cp->driver->driver.owner)) return -EAGAIN; - stat = cp->driver->command(cp,cmd,arg); - module_put(cp->driver->driver.owner); - return stat; -} - -int pvr2_i2c_client_cmd(struct pvr2_i2c_client *cp,unsigned int cmd,void *arg) -{ - int stat; - if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) { - char buf[100]; - unsigned int cnt; - cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG, - buf,sizeof(buf)); - pvr2_trace(PVR2_TRACE_I2C_CMD, - "i2c COMMAND (code=%u 0x%x) to %.*s", - cmd,cmd,cnt,buf); - } - stat = pvr2_i2c_core_singleton(cp->client,cmd,arg); - if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) { - char buf[100]; - unsigned int cnt; - cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG, - buf,sizeof(buf)); - pvr2_trace(PVR2_TRACE_I2C_CMD, - "i2c COMMAND to %.*s (ret=%d)",cnt,buf,stat); - } - return stat; -} - -int pvr2_i2c_core_cmd(struct pvr2_hdw *hdw,unsigned int cmd,void *arg) -{ - struct list_head *item,*nc; - struct pvr2_i2c_client *cp; - int stat = -EINVAL; - - if (!hdw) return stat; - - mutex_lock(&hdw->i2c_list_lock); - list_for_each_safe(item,nc,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client,list); - if (!cp->recv_enable) continue; - mutex_unlock(&hdw->i2c_list_lock); - stat = pvr2_i2c_client_cmd(cp,cmd,arg); - mutex_lock(&hdw->i2c_list_lock); - } - mutex_unlock(&hdw->i2c_list_lock); - return stat; -} - - -static int handler_check(struct pvr2_i2c_client *cp) -{ - struct pvr2_i2c_handler *hp = cp->handler; - if (!hp) return 0; - if (!hp->func_table->check) return 0; - return hp->func_table->check(hp->func_data) != 0; -} - -#define BUFSIZE 500 - -void pvr2_i2c_core_sync(struct pvr2_hdw *hdw) -{ - unsigned long msk; - unsigned int idx; - struct list_head *item,*nc; - struct pvr2_i2c_client *cp; - - if (!hdw->i2c_linked) return; - if (!(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL)) { - return; - } - mutex_lock(&hdw->i2c_list_lock); do { - pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync BEGIN"); - if (hdw->i2c_pend_types & PVR2_I2C_PEND_DETECT) { - /* One or more I2C clients have attached since we - last synced. So scan the list and identify the - new clients. */ - char *buf; - unsigned int cnt; - unsigned long amask = 0; - buf = kmalloc(BUFSIZE,GFP_KERNEL); - pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_DETECT"); - hdw->i2c_pend_types &= ~PVR2_I2C_PEND_DETECT; - list_for_each(item,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client, - list); - if (!cp->detected_flag) { - cp->ctl_mask = 0; - pvr2_i2c_probe(hdw,cp); - cp->detected_flag = !0; - msk = cp->ctl_mask; - cnt = 0; - if (buf) { - cnt = pvr2_i2c_client_describe( - cp, - PVR2_I2C_DETAIL_ALL, - buf,BUFSIZE); - } - trace_i2c("Probed: %.*s",cnt,buf); - if (handler_check(cp)) { - hdw->i2c_pend_types |= - PVR2_I2C_PEND_CLIENT; - } - cp->pend_mask = msk; - hdw->i2c_pend_mask |= msk; - hdw->i2c_pend_types |= - PVR2_I2C_PEND_REFRESH; - } - amask |= cp->ctl_mask; - } - hdw->i2c_active_mask = amask; - if (buf) kfree(buf); - } - if (hdw->i2c_pend_types & PVR2_I2C_PEND_STALE) { - /* Need to do one or more global updates. Arrange - for this to happen. */ - unsigned long m2; - pvr2_trace(PVR2_TRACE_I2C_CORE, - "i2c: PEND_STALE (0x%lx)", - hdw->i2c_stale_mask); - hdw->i2c_pend_types &= ~PVR2_I2C_PEND_STALE; - list_for_each(item,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client, - list); - m2 = hdw->i2c_stale_mask; - m2 &= cp->ctl_mask; - m2 &= ~cp->pend_mask; - if (m2) { - pvr2_trace(PVR2_TRACE_I2C_CORE, - "i2c: cp=%p setting 0x%lx", - cp,m2); - cp->pend_mask |= m2; - } - } - hdw->i2c_pend_mask |= hdw->i2c_stale_mask; - hdw->i2c_stale_mask = 0; - hdw->i2c_pend_types |= PVR2_I2C_PEND_REFRESH; - } - if (hdw->i2c_pend_types & PVR2_I2C_PEND_CLIENT) { - /* One or more client handlers are asking for an - update. Run through the list of known clients - and update each one. */ - pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_CLIENT"); - hdw->i2c_pend_types &= ~PVR2_I2C_PEND_CLIENT; - list_for_each_safe(item,nc,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client, - list); - if (!cp->handler) continue; - if (!cp->handler->func_table->update) continue; - pvr2_trace(PVR2_TRACE_I2C_CORE, - "i2c: cp=%p update",cp); - mutex_unlock(&hdw->i2c_list_lock); - cp->handler->func_table->update( - cp->handler->func_data); - mutex_lock(&hdw->i2c_list_lock); - /* If client's update function set some - additional pending bits, account for that - here. */ - if (cp->pend_mask & ~hdw->i2c_pend_mask) { - hdw->i2c_pend_mask |= cp->pend_mask; - hdw->i2c_pend_types |= - PVR2_I2C_PEND_REFRESH; - } - } - } - if (hdw->i2c_pend_types & PVR2_I2C_PEND_REFRESH) { - const struct pvr2_i2c_op *opf; - unsigned long pm; - /* Some actual updates are pending. Walk through - each update type and perform it. */ - pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_REFRESH" - " (0x%lx)",hdw->i2c_pend_mask); - hdw->i2c_pend_types &= ~PVR2_I2C_PEND_REFRESH; - pm = hdw->i2c_pend_mask; - hdw->i2c_pend_mask = 0; - for (idx = 0, msk = 1; pm; idx++, msk <<= 1) { - if (!(pm & msk)) continue; - pm &= ~msk; - list_for_each(item,&hdw->i2c_clients) { - cp = list_entry(item, - struct pvr2_i2c_client, - list); - if (cp->pend_mask & msk) { - cp->pend_mask &= ~msk; - cp->recv_enable = !0; - } else { - cp->recv_enable = 0; - } - } - opf = pvr2_i2c_get_op(idx); - if (!opf) continue; - mutex_unlock(&hdw->i2c_list_lock); - opf->update(hdw); - mutex_lock(&hdw->i2c_list_lock); - } - } - pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync END"); - } while (0); mutex_unlock(&hdw->i2c_list_lock); -} - -int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw) -{ - unsigned long msk,sm,pm; - unsigned int idx; - const struct pvr2_i2c_op *opf; - struct list_head *item; - struct pvr2_i2c_client *cp; - unsigned int pt = 0; - - pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale BEGIN"); - - pm = hdw->i2c_active_mask; - sm = 0; - for (idx = 0, msk = 1; pm; idx++, msk <<= 1) { - if (!(msk & pm)) continue; - pm &= ~msk; - opf = pvr2_i2c_get_op(idx); - if (!opf) continue; - if (opf->check(hdw)) { - sm |= msk; - } - } - if (sm) pt |= PVR2_I2C_PEND_STALE; - - list_for_each(item,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client,list); - if (!handler_check(cp)) continue; - pt |= PVR2_I2C_PEND_CLIENT; - } - - if (pt) { - mutex_lock(&hdw->i2c_list_lock); do { - hdw->i2c_pend_types |= pt; - hdw->i2c_stale_mask |= sm; - hdw->i2c_pend_mask |= hdw->i2c_stale_mask; - } while (0); mutex_unlock(&hdw->i2c_list_lock); - } - - pvr2_trace(PVR2_TRACE_I2C_CORE, - "i2c: types=0x%x stale=0x%lx pend=0x%lx", - hdw->i2c_pend_types, - hdw->i2c_stale_mask, - hdw->i2c_pend_mask); - pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale END"); - - return (hdw->i2c_pend_types & PVR2_I2C_PEND_ALL) != 0; -} - -unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp, - unsigned int detail, - char *buf,unsigned int maxlen) -{ - unsigned int ccnt,bcnt; - int spcfl = 0; - const struct pvr2_i2c_op *opf; - - ccnt = 0; - if (detail & PVR2_I2C_DETAIL_DEBUG) { - bcnt = scnprintf(buf,maxlen, - "ctxt=%p ctl_mask=0x%lx", - cp,cp->ctl_mask); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - spcfl = !0; - } - bcnt = scnprintf(buf,maxlen, - "%s%s @ 0x%x", - (spcfl ? " " : ""), - cp->client->name, - cp->client->addr); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - if ((detail & PVR2_I2C_DETAIL_HANDLER) && - cp->handler && cp->handler->func_table->describe) { - bcnt = scnprintf(buf,maxlen," ("); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - bcnt = cp->handler->func_table->describe( - cp->handler->func_data,buf,maxlen); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - bcnt = scnprintf(buf,maxlen,")"); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - } - if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) { - unsigned int idx; - unsigned long msk,sm; - int spcfl; - bcnt = scnprintf(buf,maxlen," ["); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - sm = 0; - spcfl = 0; - for (idx = 0, msk = 1; msk; idx++, msk <<= 1) { - if (!(cp->ctl_mask & msk)) continue; - opf = pvr2_i2c_get_op(idx); - if (opf) { - bcnt = scnprintf(buf,maxlen,"%s%s", - spcfl ? " " : "", - opf->name); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - spcfl = !0; - } else { - sm |= msk; - } - } - if (sm) { - bcnt = scnprintf(buf,maxlen,"%s%lx", - idx != 0 ? " " : "",sm); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - } - bcnt = scnprintf(buf,maxlen,"]"); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - } - return ccnt; -} - -unsigned int pvr2_i2c_report(struct pvr2_hdw *hdw, - char *buf,unsigned int maxlen) -{ - unsigned int ccnt,bcnt; - struct list_head *item; - struct pvr2_i2c_client *cp; - ccnt = 0; - mutex_lock(&hdw->i2c_list_lock); do { - list_for_each(item,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client,list); - bcnt = pvr2_i2c_client_describe( - cp, - (PVR2_I2C_DETAIL_HANDLER| - PVR2_I2C_DETAIL_CTLMASK), - buf,maxlen); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - bcnt = scnprintf(buf,maxlen,"\n"); - ccnt += bcnt; buf += bcnt; maxlen -= bcnt; - } - } while (0); mutex_unlock(&hdw->i2c_list_lock); - return ccnt; -} - -static int pvr2_i2c_attach_inform(struct i2c_client *client) -{ - struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data); - struct pvr2_i2c_client *cp; - int fl = !(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL); - cp = kmalloc(sizeof(*cp),GFP_KERNEL); - trace_i2c("i2c_attach [client=%s @ 0x%x ctxt=%p]", - client->name, - client->addr,cp); - if (!cp) return -ENOMEM; - memset(cp,0,sizeof(*cp)); - INIT_LIST_HEAD(&cp->list); - cp->client = client; - mutex_lock(&hdw->i2c_list_lock); do { - list_add_tail(&cp->list,&hdw->i2c_clients); - hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT; - } while (0); mutex_unlock(&hdw->i2c_list_lock); - if (fl) pvr2_hdw_poll_trigger_unlocked(hdw); - return 0; -} - -static int pvr2_i2c_detach_inform(struct i2c_client *client) -{ - struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data); - struct pvr2_i2c_client *cp; - struct list_head *item,*nc; - unsigned long amask = 0; - int foundfl = 0; - mutex_lock(&hdw->i2c_list_lock); do { - list_for_each_safe(item,nc,&hdw->i2c_clients) { - cp = list_entry(item,struct pvr2_i2c_client,list); - if (cp->client == client) { - trace_i2c("pvr2_i2c_detach" - " [client=%s @ 0x%x ctxt=%p]", - client->name, - client->addr,cp); - if (cp->handler && - cp->handler->func_table->detach) { - cp->handler->func_table->detach( - cp->handler->func_data); - } - list_del(&cp->list); - kfree(cp); - foundfl = !0; - continue; - } - amask |= cp->ctl_mask; - } - hdw->i2c_active_mask = amask; - } while (0); mutex_unlock(&hdw->i2c_list_lock); - if (!foundfl) { - trace_i2c("pvr2_i2c_detach [client=%s @ 0x%x ctxt=]", - client->name, - client->addr); - } - return 0; -} - -static struct i2c_algorithm pvr2_i2c_algo_template = { - .master_xfer = pvr2_i2c_xfer, - .algo_control = pvr2_i2c_control, - .functionality = pvr2_i2c_functionality, -}; - -static struct i2c_adapter pvr2_i2c_adap_template = { - .owner = THIS_MODULE, - .class = I2C_CLASS_TV_ANALOG, - .id = I2C_HW_B_BT848, - .client_register = pvr2_i2c_attach_inform, - .client_unregister = pvr2_i2c_detach_inform, -}; - -static void do_i2c_scan(struct pvr2_hdw *hdw) -{ - struct i2c_msg msg[1]; - int i,rc; - msg[0].addr = 0; - msg[0].flags = I2C_M_RD; - msg[0].len = 0; - msg[0].buf = 0; - printk("%s: i2c scan beginning\n",hdw->name); - for (i = 0; i < 128; i++) { - msg[0].addr = i; - rc = i2c_transfer(&hdw->i2c_adap,msg, - sizeof(msg)/sizeof(msg[0])); - if (rc != 1) continue; - printk("%s: i2c scan: found device @ 0x%x\n",hdw->name,i); - } - printk("%s: i2c scan done.\n",hdw->name); -} - -void pvr2_i2c_core_init(struct pvr2_hdw *hdw) -{ - unsigned int idx; - - // The default action for all possible I2C addresses is just to do - // the transfer normally. - for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) { - hdw->i2c_func[idx] = pvr2_i2c_basic_op; - } - -#ifdef CONFIG_VIDEO_PVRUSB2_24XXX - // If however we're dealing with new hardware, insert some hacks in - // the I2C transfer stack to let things work better. - if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) { - hdw->i2c_func[0x1b] = i2c_hack_wm8775; - hdw->i2c_func[0x44] = i2c_hack_cx25840; - } -#endif - - // Configure the adapter and set up everything else related to it. - memcpy(&hdw->i2c_adap,&pvr2_i2c_adap_template,sizeof(hdw->i2c_adap)); - memcpy(&hdw->i2c_algo,&pvr2_i2c_algo_template,sizeof(hdw->i2c_algo)); - strlcpy(hdw->i2c_adap.name,hdw->name,sizeof(hdw->i2c_adap.name)); - hdw->i2c_adap.algo = &hdw->i2c_algo; - hdw->i2c_adap.algo_data = hdw; - hdw->i2c_pend_mask = 0; - hdw->i2c_stale_mask = 0; - hdw->i2c_active_mask = 0; - INIT_LIST_HEAD(&hdw->i2c_clients); - mutex_init(&hdw->i2c_list_lock); - hdw->i2c_linked = !0; - i2c_add_adapter(&hdw->i2c_adap); - if (i2c_scan) do_i2c_scan(hdw); -} - -void pvr2_i2c_core_done(struct pvr2_hdw *hdw) -{ - if (hdw->i2c_linked) { - i2c_del_adapter(&hdw->i2c_adap); - hdw->i2c_linked = 0; - } -} - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h deleted file mode 100644 index e8af5b0ed3ce..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_I2C_CORE_H -#define __PVRUSB2_I2C_CORE_H - -#include -#include - -struct pvr2_hdw; -struct pvr2_i2c_client; -struct pvr2_i2c_handler; -struct pvr2_i2c_handler_functions; -struct pvr2_i2c_op; -struct pvr2_i2c_op_functions; - -struct pvr2_i2c_client { - struct i2c_client *client; - struct pvr2_i2c_handler *handler; - struct list_head list; - int detected_flag; - int recv_enable; - unsigned long pend_mask; - unsigned long ctl_mask; -}; - -struct pvr2_i2c_handler { - void *func_data; - const struct pvr2_i2c_handler_functions *func_table; -}; - -struct pvr2_i2c_handler_functions { - void (*detach)(void *); - int (*check)(void *); - void (*update)(void *); - unsigned int (*describe)(void *,char *,unsigned int); -}; - -struct pvr2_i2c_op { - int (*check)(struct pvr2_hdw *); - void (*update)(struct pvr2_hdw *); - const char *name; -}; - -void pvr2_i2c_core_init(struct pvr2_hdw *); -void pvr2_i2c_core_done(struct pvr2_hdw *); - -int pvr2_i2c_client_cmd(struct pvr2_i2c_client *,unsigned int cmd,void *arg); -int pvr2_i2c_core_cmd(struct pvr2_hdw *,unsigned int cmd,void *arg); - -int pvr2_i2c_core_check_stale(struct pvr2_hdw *); -void pvr2_i2c_core_sync(struct pvr2_hdw *); -unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen); -#define PVR2_I2C_DETAIL_DEBUG 0x0001 -#define PVR2_I2C_DETAIL_HANDLER 0x0002 -#define PVR2_I2C_DETAIL_CTLMASK 0x0004 -#define PVR2_I2C_DETAIL_ALL (\ - PVR2_I2C_DETAIL_DEBUG |\ - PVR2_I2C_DETAIL_HANDLER |\ - PVR2_I2C_DETAIL_CTLMASK) -unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *, - unsigned int detail_mask, - char *buf,unsigned int maxlen); - -void pvr2_i2c_probe(struct pvr2_hdw *,struct pvr2_i2c_client *); -const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx); - -#endif /* __PVRUSB2_I2C_CORE_H */ - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-io.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-io.c deleted file mode 100644 index a984c91f571c..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-io.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * 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 "pvrusb2-io.h" -#include "pvrusb2-debug.h" -#include -#include -#include -#include - -#define BUFFER_SIG 0x47653271 - -// #define SANITY_CHECK_BUFFERS - - -#ifdef SANITY_CHECK_BUFFERS -#define BUFFER_CHECK(bp) do { \ - if ((bp)->signature != BUFFER_SIG) { \ - pvr2_trace(PVR2_TRACE_ERROR_LEGS, \ - "Buffer %p is bad at %s:%d", \ - (bp),__FILE__,__LINE__); \ - pvr2_buffer_describe(bp,"BadSig"); \ - BUG(); \ - } \ -} while (0) -#else -#define BUFFER_CHECK(bp) do {} while(0) -#endif - -struct pvr2_stream { - /* Buffers queued for reading */ - struct list_head queued_list; - unsigned int q_count; - unsigned int q_bcount; - /* Buffers with retrieved data */ - struct list_head ready_list; - unsigned int r_count; - unsigned int r_bcount; - /* Buffers available for use */ - struct list_head idle_list; - unsigned int i_count; - unsigned int i_bcount; - /* Pointers to all buffers */ - struct pvr2_buffer **buffers; - /* Array size of buffers */ - unsigned int buffer_slot_count; - /* Total buffers actually in circulation */ - unsigned int buffer_total_count; - /* Designed number of buffers to be in circulation */ - unsigned int buffer_target_count; - /* Executed when ready list become non-empty */ - pvr2_stream_callback callback_func; - void *callback_data; - /* Context for transfer endpoint */ - struct usb_device *dev; - int endpoint; - /* Overhead for mutex enforcement */ - spinlock_t list_lock; - struct mutex mutex; - /* Tracking state for tolerating errors */ - unsigned int fail_count; - unsigned int fail_tolerance; -}; - -struct pvr2_buffer { - int id; - int signature; - enum pvr2_buffer_state state; - void *ptr; /* Pointer to storage area */ - unsigned int max_count; /* Size of storage area */ - unsigned int used_count; /* Amount of valid data in storage area */ - int status; /* Transfer result status */ - struct pvr2_stream *stream; - struct list_head list_overhead; - struct urb *purb; -}; - -const char *pvr2_buffer_state_decode(enum pvr2_buffer_state st) -{ - switch (st) { - case pvr2_buffer_state_none: return "none"; - case pvr2_buffer_state_idle: return "idle"; - case pvr2_buffer_state_queued: return "queued"; - case pvr2_buffer_state_ready: return "ready"; - } - return "unknown"; -} - -void pvr2_buffer_describe(struct pvr2_buffer *bp,const char *msg) -{ - pvr2_trace(PVR2_TRACE_INFO, - "buffer%s%s %p state=%s id=%d status=%d" - " stream=%p purb=%p sig=0x%x", - (msg ? " " : ""), - (msg ? msg : ""), - bp, - (bp ? pvr2_buffer_state_decode(bp->state) : "(invalid)"), - (bp ? bp->id : 0), - (bp ? bp->status : 0), - (bp ? bp->stream : 0), - (bp ? bp->purb : 0), - (bp ? bp->signature : 0)); -} - -static void pvr2_buffer_remove(struct pvr2_buffer *bp) -{ - unsigned int *cnt; - unsigned int *bcnt; - unsigned int ccnt; - struct pvr2_stream *sp = bp->stream; - switch (bp->state) { - case pvr2_buffer_state_idle: - cnt = &sp->i_count; - bcnt = &sp->i_bcount; - ccnt = bp->max_count; - break; - case pvr2_buffer_state_queued: - cnt = &sp->q_count; - bcnt = &sp->q_bcount; - ccnt = bp->max_count; - break; - case pvr2_buffer_state_ready: - cnt = &sp->r_count; - bcnt = &sp->r_bcount; - ccnt = bp->used_count; - break; - default: - return; - } - list_del_init(&bp->list_overhead); - (*cnt)--; - (*bcnt) -= ccnt; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s dec cap=%07d cnt=%02d", - pvr2_buffer_state_decode(bp->state),*bcnt,*cnt); - bp->state = pvr2_buffer_state_none; -} - -static void pvr2_buffer_set_none(struct pvr2_buffer *bp) -{ - unsigned long irq_flags; - struct pvr2_stream *sp; - BUFFER_CHECK(bp); - sp = bp->stream; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", - bp, - pvr2_buffer_state_decode(bp->state), - pvr2_buffer_state_decode(pvr2_buffer_state_none)); - spin_lock_irqsave(&sp->list_lock,irq_flags); - pvr2_buffer_remove(bp); - spin_unlock_irqrestore(&sp->list_lock,irq_flags); -} - -static int pvr2_buffer_set_ready(struct pvr2_buffer *bp) -{ - int fl; - unsigned long irq_flags; - struct pvr2_stream *sp; - BUFFER_CHECK(bp); - sp = bp->stream; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", - bp, - pvr2_buffer_state_decode(bp->state), - pvr2_buffer_state_decode(pvr2_buffer_state_ready)); - spin_lock_irqsave(&sp->list_lock,irq_flags); - fl = (sp->r_count == 0); - pvr2_buffer_remove(bp); - list_add_tail(&bp->list_overhead,&sp->ready_list); - bp->state = pvr2_buffer_state_ready; - (sp->r_count)++; - sp->r_bcount += bp->used_count; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s inc cap=%07d cnt=%02d", - pvr2_buffer_state_decode(bp->state), - sp->r_bcount,sp->r_count); - spin_unlock_irqrestore(&sp->list_lock,irq_flags); - return fl; -} - -static void pvr2_buffer_set_idle(struct pvr2_buffer *bp) -{ - unsigned long irq_flags; - struct pvr2_stream *sp; - BUFFER_CHECK(bp); - sp = bp->stream; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", - bp, - pvr2_buffer_state_decode(bp->state), - pvr2_buffer_state_decode(pvr2_buffer_state_idle)); - spin_lock_irqsave(&sp->list_lock,irq_flags); - pvr2_buffer_remove(bp); - list_add_tail(&bp->list_overhead,&sp->idle_list); - bp->state = pvr2_buffer_state_idle; - (sp->i_count)++; - sp->i_bcount += bp->max_count; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s inc cap=%07d cnt=%02d", - pvr2_buffer_state_decode(bp->state), - sp->i_bcount,sp->i_count); - spin_unlock_irqrestore(&sp->list_lock,irq_flags); -} - -static void pvr2_buffer_set_queued(struct pvr2_buffer *bp) -{ - unsigned long irq_flags; - struct pvr2_stream *sp; - BUFFER_CHECK(bp); - sp = bp->stream; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferState %p %6s --> %6s", - bp, - pvr2_buffer_state_decode(bp->state), - pvr2_buffer_state_decode(pvr2_buffer_state_queued)); - spin_lock_irqsave(&sp->list_lock,irq_flags); - pvr2_buffer_remove(bp); - list_add_tail(&bp->list_overhead,&sp->queued_list); - bp->state = pvr2_buffer_state_queued; - (sp->q_count)++; - sp->q_bcount += bp->max_count; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/" - " bufferPool %8s inc cap=%07d cnt=%02d", - pvr2_buffer_state_decode(bp->state), - sp->q_bcount,sp->q_count); - spin_unlock_irqrestore(&sp->list_lock,irq_flags); -} - -static void pvr2_buffer_wipe(struct pvr2_buffer *bp) -{ - if (bp->state == pvr2_buffer_state_queued) { - usb_kill_urb(bp->purb); - } -} - -static int pvr2_buffer_init(struct pvr2_buffer *bp, - struct pvr2_stream *sp, - unsigned int id) -{ - memset(bp,0,sizeof(*bp)); - bp->signature = BUFFER_SIG; - bp->id = id; - pvr2_trace(PVR2_TRACE_BUF_POOL, - "/*---TRACE_FLOW---*/ bufferInit %p stream=%p",bp,sp); - bp->stream = sp; - bp->state = pvr2_buffer_state_none; - INIT_LIST_HEAD(&bp->list_overhead); - bp->purb = usb_alloc_urb(0,GFP_KERNEL); - if (! bp->purb) return -ENOMEM; -#ifdef SANITY_CHECK_BUFFERS - pvr2_buffer_describe(bp,"create"); -#endif - return 0; -} - -static void pvr2_buffer_done(struct pvr2_buffer *bp) -{ -#ifdef SANITY_CHECK_BUFFERS - pvr2_buffer_describe(bp,"delete"); -#endif - pvr2_buffer_wipe(bp); - pvr2_buffer_set_none(bp); - bp->signature = 0; - bp->stream = 0; - if (bp->purb) usb_free_urb(bp->purb); - pvr2_trace(PVR2_TRACE_BUF_POOL,"/*---TRACE_FLOW---*/" - " bufferDone %p",bp); -} - -static int pvr2_stream_buffer_count(struct pvr2_stream *sp,unsigned int cnt) -{ - int ret; - unsigned int scnt; - - /* Allocate buffers pointer array in multiples of 32 entries */ - if (cnt == sp->buffer_total_count) return 0; - - pvr2_trace(PVR2_TRACE_BUF_POOL, - "/*---TRACE_FLOW---*/ poolResize " - " stream=%p cur=%d adj=%+d", - sp, - sp->buffer_total_count, - cnt-sp->buffer_total_count); - - scnt = cnt & ~0x1f; - if (cnt > scnt) scnt += 0x20; - - if (cnt > sp->buffer_total_count) { - if (scnt > sp->buffer_slot_count) { - struct pvr2_buffer **nb; - nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL); - if (!nb) return -ENOMEM; - if (sp->buffer_slot_count) { - memcpy(nb,sp->buffers, - sp->buffer_slot_count * sizeof(*nb)); - kfree(sp->buffers); - } - sp->buffers = nb; - sp->buffer_slot_count = scnt; - } - while (sp->buffer_total_count < cnt) { - struct pvr2_buffer *bp; - bp = kmalloc(sizeof(*bp),GFP_KERNEL); - if (!bp) return -ENOMEM; - ret = pvr2_buffer_init(bp,sp,sp->buffer_total_count); - if (ret) { - kfree(bp); - return -ENOMEM; - } - sp->buffers[sp->buffer_total_count] = bp; - (sp->buffer_total_count)++; - pvr2_buffer_set_idle(bp); - } - } else { - while (sp->buffer_total_count > cnt) { - struct pvr2_buffer *bp; - bp = sp->buffers[sp->buffer_total_count - 1]; - /* Paranoia */ - sp->buffers[sp->buffer_total_count - 1] = 0; - (sp->buffer_total_count)--; - pvr2_buffer_done(bp); - kfree(bp); - } - if (scnt < sp->buffer_slot_count) { - struct pvr2_buffer **nb = 0; - if (scnt) { - nb = kmalloc(scnt * sizeof(*nb),GFP_KERNEL); - if (!nb) return -ENOMEM; - memcpy(nb,sp->buffers,scnt * sizeof(*nb)); - } - kfree(sp->buffers); - sp->buffers = nb; - sp->buffer_slot_count = scnt; - } - } - return 0; -} - -static int pvr2_stream_achieve_buffer_count(struct pvr2_stream *sp) -{ - struct pvr2_buffer *bp; - unsigned int cnt; - - if (sp->buffer_total_count == sp->buffer_target_count) return 0; - - pvr2_trace(PVR2_TRACE_BUF_POOL, - "/*---TRACE_FLOW---*/" - " poolCheck stream=%p cur=%d tgt=%d", - sp,sp->buffer_total_count,sp->buffer_target_count); - - if (sp->buffer_total_count < sp->buffer_target_count) { - return pvr2_stream_buffer_count(sp,sp->buffer_target_count); - } - - cnt = 0; - while ((sp->buffer_total_count - cnt) > sp->buffer_target_count) { - bp = sp->buffers[sp->buffer_total_count - (cnt + 1)]; - if (bp->state != pvr2_buffer_state_idle) break; - cnt++; - } - if (cnt) { - pvr2_stream_buffer_count(sp,sp->buffer_total_count - cnt); - } - - return 0; -} - -static void pvr2_stream_internal_flush(struct pvr2_stream *sp) -{ - struct list_head *lp; - struct pvr2_buffer *bp1; - while ((lp = sp->queued_list.next) != &sp->queued_list) { - bp1 = list_entry(lp,struct pvr2_buffer,list_overhead); - pvr2_buffer_wipe(bp1); - /* At this point, we should be guaranteed that no - completion callback may happen on this buffer. But it's - possible that it might have completed after we noticed - it but before we wiped it. So double check its status - here first. */ - if (bp1->state != pvr2_buffer_state_queued) continue; - pvr2_buffer_set_idle(bp1); - } - if (sp->buffer_total_count != sp->buffer_target_count) { - pvr2_stream_achieve_buffer_count(sp); - } -} - -static void pvr2_stream_init(struct pvr2_stream *sp) -{ - spin_lock_init(&sp->list_lock); - mutex_init(&sp->mutex); - INIT_LIST_HEAD(&sp->queued_list); - INIT_LIST_HEAD(&sp->ready_list); - INIT_LIST_HEAD(&sp->idle_list); -} - -static void pvr2_stream_done(struct pvr2_stream *sp) -{ - mutex_lock(&sp->mutex); do { - pvr2_stream_internal_flush(sp); - pvr2_stream_buffer_count(sp,0); - } while (0); mutex_unlock(&sp->mutex); -} - -static void buffer_complete(struct urb *urb, struct pt_regs *regs) -{ - struct pvr2_buffer *bp = urb->context; - struct pvr2_stream *sp; - unsigned long irq_flags; - BUFFER_CHECK(bp); - sp = bp->stream; - bp->used_count = 0; - bp->status = 0; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferComplete %p stat=%d cnt=%d", - bp,urb->status,urb->actual_length); - spin_lock_irqsave(&sp->list_lock,irq_flags); - if ((!(urb->status)) || - (urb->status == -ENOENT) || - (urb->status == -ECONNRESET) || - (urb->status == -ESHUTDOWN)) { - bp->used_count = urb->actual_length; - if (sp->fail_count) { - pvr2_trace(PVR2_TRACE_TOLERANCE, - "stream %p transfer ok" - " - fail count reset",sp); - sp->fail_count = 0; - } - } else if (sp->fail_count < sp->fail_tolerance) { - // We can tolerate this error, because we're below the - // threshold... - (sp->fail_count)++; - pvr2_trace(PVR2_TRACE_TOLERANCE, - "stream %p ignoring error %d" - " - fail count increased to %u", - sp,urb->status,sp->fail_count); - } else { - bp->status = urb->status; - } - spin_unlock_irqrestore(&sp->list_lock,irq_flags); - pvr2_buffer_set_ready(bp); - if (sp && sp->callback_func) { - sp->callback_func(sp->callback_data); - } -} - -struct pvr2_stream *pvr2_stream_create(void) -{ - struct pvr2_stream *sp; - sp = kmalloc(sizeof(*sp),GFP_KERNEL); - if (!sp) return sp; - memset(sp,0,sizeof(*sp)); - pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_create: sp=%p",sp); - pvr2_stream_init(sp); - return sp; -} - -void pvr2_stream_destroy(struct pvr2_stream *sp) -{ - if (!sp) return; - pvr2_trace(PVR2_TRACE_INIT,"pvr2_stream_destroy: sp=%p",sp); - pvr2_stream_done(sp); - kfree(sp); -} - -void pvr2_stream_setup(struct pvr2_stream *sp, - struct usb_device *dev, - int endpoint, - unsigned int tolerance) -{ - mutex_lock(&sp->mutex); do { - pvr2_stream_internal_flush(sp); - sp->dev = dev; - sp->endpoint = endpoint; - sp->fail_tolerance = tolerance; - } while(0); mutex_unlock(&sp->mutex); -} - -void pvr2_stream_set_callback(struct pvr2_stream *sp, - pvr2_stream_callback func, - void *data) -{ - unsigned long irq_flags; - mutex_lock(&sp->mutex); do { - spin_lock_irqsave(&sp->list_lock,irq_flags); - sp->callback_data = data; - sp->callback_func = func; - spin_unlock_irqrestore(&sp->list_lock,irq_flags); - } while(0); mutex_unlock(&sp->mutex); -} - -/* Query / set the nominal buffer count */ -int pvr2_stream_get_buffer_count(struct pvr2_stream *sp) -{ - return sp->buffer_target_count; -} - -int pvr2_stream_set_buffer_count(struct pvr2_stream *sp,unsigned int cnt) -{ - int ret; - if (sp->buffer_target_count == cnt) return 0; - mutex_lock(&sp->mutex); do { - sp->buffer_target_count = cnt; - ret = pvr2_stream_achieve_buffer_count(sp); - } while(0); mutex_unlock(&sp->mutex); - return ret; -} - -struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *sp) -{ - struct list_head *lp = sp->idle_list.next; - if (lp == &sp->idle_list) return 0; - return list_entry(lp,struct pvr2_buffer,list_overhead); -} - -struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *sp) -{ - struct list_head *lp = sp->ready_list.next; - if (lp == &sp->ready_list) return 0; - return list_entry(lp,struct pvr2_buffer,list_overhead); -} - -struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id) -{ - if (id < 0) return 0; - if (id >= sp->buffer_total_count) return 0; - return sp->buffers[id]; -} - -int pvr2_stream_get_ready_count(struct pvr2_stream *sp) -{ - return sp->r_count; -} - -int pvr2_stream_get_idle_count(struct pvr2_stream *sp) -{ - return sp->i_count; -} - -void pvr2_stream_flush(struct pvr2_stream *sp) -{ - mutex_lock(&sp->mutex); do { - pvr2_stream_internal_flush(sp); - } while(0); mutex_unlock(&sp->mutex); -} - -void pvr2_stream_kill(struct pvr2_stream *sp) -{ - struct pvr2_buffer *bp; - mutex_lock(&sp->mutex); do { - pvr2_stream_internal_flush(sp); - while ((bp = pvr2_stream_get_ready_buffer(sp)) != 0) { - pvr2_buffer_set_idle(bp); - } - if (sp->buffer_total_count != sp->buffer_target_count) { - pvr2_stream_achieve_buffer_count(sp); - } - } while(0); mutex_unlock(&sp->mutex); -} - -int pvr2_buffer_queue(struct pvr2_buffer *bp) -{ -#undef SEED_BUFFER -#ifdef SEED_BUFFER - unsigned int idx; - unsigned int val; -#endif - int ret = 0; - struct pvr2_stream *sp; - if (!bp) return -EINVAL; - sp = bp->stream; - mutex_lock(&sp->mutex); do { - pvr2_buffer_wipe(bp); - if (!sp->dev) { - ret = -EIO; - break; - } - pvr2_buffer_set_queued(bp); -#ifdef SEED_BUFFER - for (idx = 0; idx < (bp->max_count) / 4; idx++) { - val = bp->id << 24; - val |= idx; - ((unsigned int *)(bp->ptr))[idx] = val; - } -#endif - bp->status = -EINPROGRESS; - usb_fill_bulk_urb(bp->purb, // struct urb *urb - sp->dev, // struct usb_device *dev - // endpoint (below) - usb_rcvbulkpipe(sp->dev,sp->endpoint), - bp->ptr, // void *transfer_buffer - bp->max_count, // int buffer_length - buffer_complete, - bp); - usb_submit_urb(bp->purb,GFP_KERNEL); - } while(0); mutex_unlock(&sp->mutex); - return ret; -} - -int pvr2_buffer_idle(struct pvr2_buffer *bp) -{ - struct pvr2_stream *sp; - if (!bp) return -EINVAL; - sp = bp->stream; - mutex_lock(&sp->mutex); do { - pvr2_buffer_wipe(bp); - pvr2_buffer_set_idle(bp); - if (sp->buffer_total_count != sp->buffer_target_count) { - pvr2_stream_achieve_buffer_count(sp); - } - } while(0); mutex_unlock(&sp->mutex); - return 0; -} - -int pvr2_buffer_set_buffer(struct pvr2_buffer *bp,void *ptr,unsigned int cnt) -{ - int ret = 0; - unsigned long irq_flags; - struct pvr2_stream *sp; - if (!bp) return -EINVAL; - sp = bp->stream; - mutex_lock(&sp->mutex); do { - spin_lock_irqsave(&sp->list_lock,irq_flags); - if (bp->state != pvr2_buffer_state_idle) { - ret = -EPERM; - } else { - bp->ptr = ptr; - bp->stream->i_bcount -= bp->max_count; - bp->max_count = cnt; - bp->stream->i_bcount += bp->max_count; - pvr2_trace(PVR2_TRACE_BUF_FLOW, - "/*---TRACE_FLOW---*/ bufferPool " - " %8s cap cap=%07d cnt=%02d", - pvr2_buffer_state_decode( - pvr2_buffer_state_idle), - bp->stream->i_bcount,bp->stream->i_count); - } - spin_unlock_irqrestore(&sp->list_lock,irq_flags); - } while(0); mutex_unlock(&sp->mutex); - return ret; -} - -unsigned int pvr2_buffer_get_count(struct pvr2_buffer *bp) -{ - return bp->used_count; -} - -int pvr2_buffer_get_status(struct pvr2_buffer *bp) -{ - return bp->status; -} - -enum pvr2_buffer_state pvr2_buffer_get_state(struct pvr2_buffer *bp) -{ - return bp->state; -} - -int pvr2_buffer_get_id(struct pvr2_buffer *bp) -{ - return bp->id; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-io.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-io.h deleted file mode 100644 index 65e11385b2b3..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-io.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_IO_H -#define __PVRUSB2_IO_H - -#include -#include - -typedef void (*pvr2_stream_callback)(void *); - -enum pvr2_buffer_state { - pvr2_buffer_state_none = 0, // Not on any list - pvr2_buffer_state_idle = 1, // Buffer is ready to be used again - pvr2_buffer_state_queued = 2, // Buffer has been queued for filling - pvr2_buffer_state_ready = 3, // Buffer has data available -}; - -struct pvr2_stream; -struct pvr2_buffer; - -const char *pvr2_buffer_state_decode(enum pvr2_buffer_state); - -/* Initialize / tear down stream structure */ -struct pvr2_stream *pvr2_stream_create(void); -void pvr2_stream_destroy(struct pvr2_stream *); -void pvr2_stream_setup(struct pvr2_stream *, - struct usb_device *dev,int endpoint, - unsigned int tolerance); -void pvr2_stream_set_callback(struct pvr2_stream *, - pvr2_stream_callback func, - void *data); - -/* Query / set the nominal buffer count */ -int pvr2_stream_get_buffer_count(struct pvr2_stream *); -int pvr2_stream_set_buffer_count(struct pvr2_stream *,unsigned int); - -/* Get a pointer to a buffer that is either idle, ready, or is specified - named. */ -struct pvr2_buffer *pvr2_stream_get_idle_buffer(struct pvr2_stream *); -struct pvr2_buffer *pvr2_stream_get_ready_buffer(struct pvr2_stream *); -struct pvr2_buffer *pvr2_stream_get_buffer(struct pvr2_stream *sp,int id); - -/* Find out how many buffers are idle or ready */ -int pvr2_stream_get_idle_count(struct pvr2_stream *); -int pvr2_stream_get_ready_count(struct pvr2_stream *); - -/* Kill all pending operations */ -void pvr2_stream_flush(struct pvr2_stream *); - -/* Kill all pending buffers and throw away any ready buffers as well */ -void pvr2_stream_kill(struct pvr2_stream *); - -/* Set up the actual storage for a buffer */ -int pvr2_buffer_set_buffer(struct pvr2_buffer *,void *ptr,unsigned int cnt); - -/* Find out size of data in the given ready buffer */ -unsigned int pvr2_buffer_get_count(struct pvr2_buffer *); - -/* Retrieve completion code for given ready buffer */ -int pvr2_buffer_get_status(struct pvr2_buffer *); - -/* Retrieve state of given buffer */ -enum pvr2_buffer_state pvr2_buffer_get_state(struct pvr2_buffer *); - -/* Retrieve ID of given buffer */ -int pvr2_buffer_get_id(struct pvr2_buffer *); - -/* Start reading into given buffer (kill it if needed) */ -int pvr2_buffer_queue(struct pvr2_buffer *); - -/* Move buffer back to idle pool (kill it if needed) */ -int pvr2_buffer_idle(struct pvr2_buffer *); - -#endif /* __PVRUSB2_IO_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-ioread.c deleted file mode 100644 index 49da062e3271..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-ioread.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * 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 "pvrusb2-ioread.h" -#include "pvrusb2-debug.h" -#include -#include -#include -#include -#include - -#define BUFFER_COUNT 32 -#define BUFFER_SIZE PAGE_ALIGN(0x4000) - -struct pvr2_ioread { - struct pvr2_stream *stream; - char *buffer_storage[BUFFER_COUNT]; - char *sync_key_ptr; - unsigned int sync_key_len; - unsigned int sync_buf_offs; - unsigned int sync_state; - unsigned int sync_trashed_count; - int enabled; // Streaming is on - int spigot_open; // OK to pass data to client - int stream_running; // Passing data to client now - - /* State relevant to current buffer being read */ - struct pvr2_buffer *c_buf; - char *c_data_ptr; - unsigned int c_data_len; - unsigned int c_data_offs; - struct mutex mutex; -}; - -static int pvr2_ioread_init(struct pvr2_ioread *cp) -{ - unsigned int idx; - - cp->stream = 0; - mutex_init(&cp->mutex); - - for (idx = 0; idx < BUFFER_COUNT; idx++) { - cp->buffer_storage[idx] = kmalloc(BUFFER_SIZE,GFP_KERNEL); - if (!(cp->buffer_storage[idx])) break; - } - - if (idx < BUFFER_COUNT) { - // An allocation appears to have failed - for (idx = 0; idx < BUFFER_COUNT; idx++) { - if (!(cp->buffer_storage[idx])) continue; - kfree(cp->buffer_storage[idx]); - } - return -ENOMEM; - } - return 0; -} - -static void pvr2_ioread_done(struct pvr2_ioread *cp) -{ - unsigned int idx; - - pvr2_ioread_setup(cp,0); - for (idx = 0; idx < BUFFER_COUNT; idx++) { - if (!(cp->buffer_storage[idx])) continue; - kfree(cp->buffer_storage[idx]); - } -} - -struct pvr2_ioread *pvr2_ioread_create(void) -{ - struct pvr2_ioread *cp; - cp = kmalloc(sizeof(*cp),GFP_KERNEL); - if (!cp) return 0; - pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_create id=%p",cp); - memset(cp,0,sizeof(*cp)); - if (pvr2_ioread_init(cp) < 0) { - kfree(cp); - return 0; - } - return cp; -} - -void pvr2_ioread_destroy(struct pvr2_ioread *cp) -{ - if (!cp) return; - pvr2_ioread_done(cp); - pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_destroy id=%p",cp); - if (cp->sync_key_ptr) { - kfree(cp->sync_key_ptr); - cp->sync_key_ptr = 0; - } - kfree(cp); -} - -void pvr2_ioread_set_sync_key(struct pvr2_ioread *cp, - const char *sync_key_ptr, - unsigned int sync_key_len) -{ - if (!cp) return; - - if (!sync_key_ptr) sync_key_len = 0; - if ((sync_key_len == cp->sync_key_len) && - ((!sync_key_len) || - (!memcmp(sync_key_ptr,cp->sync_key_ptr,sync_key_len)))) return; - - if (sync_key_len != cp->sync_key_len) { - if (cp->sync_key_ptr) { - kfree(cp->sync_key_ptr); - cp->sync_key_ptr = 0; - } - cp->sync_key_len = 0; - if (sync_key_len) { - cp->sync_key_ptr = kmalloc(sync_key_len,GFP_KERNEL); - if (cp->sync_key_ptr) { - cp->sync_key_len = sync_key_len; - } - } - } - if (!cp->sync_key_len) return; - memcpy(cp->sync_key_ptr,sync_key_ptr,cp->sync_key_len); -} - -static void pvr2_ioread_stop(struct pvr2_ioread *cp) -{ - if (!(cp->enabled)) return; - pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/ pvr2_ioread_stop id=%p",cp); - pvr2_stream_kill(cp->stream); - cp->c_buf = 0; - cp->c_data_ptr = 0; - cp->c_data_len = 0; - cp->c_data_offs = 0; - cp->enabled = 0; - cp->stream_running = 0; - cp->spigot_open = 0; - if (cp->sync_state) { - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/ sync_state <== 0"); - cp->sync_state = 0; - } -} - -static int pvr2_ioread_start(struct pvr2_ioread *cp) -{ - int stat; - struct pvr2_buffer *bp; - if (cp->enabled) return 0; - if (!(cp->stream)) return 0; - pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/ pvr2_ioread_start id=%p",cp); - while ((bp = pvr2_stream_get_idle_buffer(cp->stream)) != 0) { - stat = pvr2_buffer_queue(bp); - if (stat < 0) { - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " pvr2_ioread_start id=%p" - " error=%d", - cp,stat); - pvr2_ioread_stop(cp); - return stat; - } - } - cp->enabled = !0; - cp->c_buf = 0; - cp->c_data_ptr = 0; - cp->c_data_len = 0; - cp->c_data_offs = 0; - cp->stream_running = 0; - if (cp->sync_key_len) { - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/ sync_state <== 1"); - cp->sync_state = 1; - cp->sync_trashed_count = 0; - cp->sync_buf_offs = 0; - } - cp->spigot_open = 0; - return 0; -} - -struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *cp) -{ - return cp->stream; -} - -int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp) -{ - int ret; - unsigned int idx; - struct pvr2_buffer *bp; - - mutex_lock(&cp->mutex); do { - if (cp->stream) { - pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/" - " pvr2_ioread_setup (tear-down) id=%p",cp); - pvr2_ioread_stop(cp); - pvr2_stream_kill(cp->stream); - pvr2_stream_set_buffer_count(cp->stream,0); - cp->stream = 0; - } - if (sp) { - pvr2_trace(PVR2_TRACE_START_STOP, - "/*---TRACE_READ---*/" - " pvr2_ioread_setup (setup) id=%p",cp); - pvr2_stream_kill(sp); - ret = pvr2_stream_set_buffer_count(sp,BUFFER_COUNT); - if (ret < 0) return ret; - for (idx = 0; idx < BUFFER_COUNT; idx++) { - bp = pvr2_stream_get_buffer(sp,idx); - pvr2_buffer_set_buffer(bp, - cp->buffer_storage[idx], - BUFFER_SIZE); - } - cp->stream = sp; - } - } while (0); mutex_unlock(&cp->mutex); - - return 0; -} - -int pvr2_ioread_set_enabled(struct pvr2_ioread *cp,int fl) -{ - int ret = 0; - if ((!fl) == (!(cp->enabled))) return ret; - - mutex_lock(&cp->mutex); do { - if (fl) { - ret = pvr2_ioread_start(cp); - } else { - pvr2_ioread_stop(cp); - } - } while (0); mutex_unlock(&cp->mutex); - return ret; -} - -int pvr2_ioread_get_enabled(struct pvr2_ioread *cp) -{ - return cp->enabled != 0; -} - -int pvr2_ioread_get_buffer(struct pvr2_ioread *cp) -{ - int stat; - - while (cp->c_data_len <= cp->c_data_offs) { - if (cp->c_buf) { - // Flush out current buffer first. - stat = pvr2_buffer_queue(cp->c_buf); - if (stat < 0) { - // Streaming error... - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " pvr2_ioread_read id=%p" - " queue_error=%d", - cp,stat); - pvr2_ioread_stop(cp); - return 0; - } - cp->c_buf = 0; - cp->c_data_ptr = 0; - cp->c_data_len = 0; - cp->c_data_offs = 0; - } - // Now get a freshly filled buffer. - cp->c_buf = pvr2_stream_get_ready_buffer(cp->stream); - if (!cp->c_buf) break; // Nothing ready; done. - cp->c_data_len = pvr2_buffer_get_count(cp->c_buf); - if (!cp->c_data_len) { - // Nothing transferred. Was there an error? - stat = pvr2_buffer_get_status(cp->c_buf); - if (stat < 0) { - // Streaming error... - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " pvr2_ioread_read id=%p" - " buffer_error=%d", - cp,stat); - pvr2_ioread_stop(cp); - // Give up. - return 0; - } - // Start over... - continue; - } - cp->c_data_offs = 0; - cp->c_data_ptr = cp->buffer_storage[ - pvr2_buffer_get_id(cp->c_buf)]; - } - return !0; -} - -void pvr2_ioread_filter(struct pvr2_ioread *cp) -{ - unsigned int idx; - if (!cp->enabled) return; - if (cp->sync_state != 1) return; - - // Search the stream for our synchronization key. This is made - // complicated by the fact that in order to be honest with - // ourselves here we must search across buffer boundaries... - mutex_lock(&cp->mutex); while (1) { - // Ensure we have a buffer - if (!pvr2_ioread_get_buffer(cp)) break; - if (!cp->c_data_len) break; - - // Now walk the buffer contents until we match the key or - // run out of buffer data. - for (idx = cp->c_data_offs; idx < cp->c_data_len; idx++) { - if (cp->sync_buf_offs >= cp->sync_key_len) break; - if (cp->c_data_ptr[idx] == - cp->sync_key_ptr[cp->sync_buf_offs]) { - // Found the next key byte - (cp->sync_buf_offs)++; - } else { - // Whoops, mismatched. Start key over... - cp->sync_buf_offs = 0; - } - } - - // Consume what we've walked through - cp->c_data_offs += idx; - cp->sync_trashed_count += idx; - - // If we've found the key, then update state and get out. - if (cp->sync_buf_offs >= cp->sync_key_len) { - cp->sync_trashed_count -= cp->sync_key_len; - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " sync_state <== 2 (skipped %u bytes)", - cp->sync_trashed_count); - cp->sync_state = 2; - cp->sync_buf_offs = 0; - break; - } - - if (cp->c_data_offs < cp->c_data_len) { - // Sanity check - should NEVER get here - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "ERROR: pvr2_ioread filter sync problem" - " len=%u offs=%u", - cp->c_data_len,cp->c_data_offs); - // Get out so we don't get stuck in an infinite - // loop. - break; - } - - continue; // (for clarity) - } mutex_unlock(&cp->mutex); -} - -int pvr2_ioread_avail(struct pvr2_ioread *cp) -{ - int ret; - if (!(cp->enabled)) { - // Stream is not enabled; so this is an I/O error - return -EIO; - } - - if (cp->sync_state == 1) { - pvr2_ioread_filter(cp); - if (cp->sync_state == 1) return -EAGAIN; - } - - ret = 0; - if (cp->stream_running) { - if (!pvr2_stream_get_ready_count(cp->stream)) { - // No data available at all right now. - ret = -EAGAIN; - } - } else { - if (pvr2_stream_get_ready_count(cp->stream) < BUFFER_COUNT/2) { - // Haven't buffered up enough yet; try again later - ret = -EAGAIN; - } - } - - if ((!(cp->spigot_open)) != (!(ret == 0))) { - cp->spigot_open = (ret == 0); - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/ data is %s", - cp->spigot_open ? "available" : "pending"); - } - - return ret; -} - -int pvr2_ioread_read(struct pvr2_ioread *cp,void __user *buf,unsigned int cnt) -{ - unsigned int copied_cnt; - unsigned int bcnt; - const char *src; - int stat; - int ret = 0; - unsigned int req_cnt = cnt; - - if (!cnt) { - pvr2_trace(PVR2_TRACE_TRAP, - "/*---TRACE_READ---*/ pvr2_ioread_read id=%p" - " ZERO Request? Returning zero.",cp); - return 0; - } - - stat = pvr2_ioread_avail(cp); - if (stat < 0) return stat; - - cp->stream_running = !0; - - mutex_lock(&cp->mutex); do { - - // Suck data out of the buffers and copy to the user - copied_cnt = 0; - if (!buf) cnt = 0; - while (1) { - if (!pvr2_ioread_get_buffer(cp)) { - ret = -EIO; - break; - } - - if (!cnt) break; - - if (cp->sync_state == 2) { - // We're repeating the sync key data into - // the stream. - src = cp->sync_key_ptr + cp->sync_buf_offs; - bcnt = cp->sync_key_len - cp->sync_buf_offs; - } else { - // Normal buffer copy - src = cp->c_data_ptr + cp->c_data_offs; - bcnt = cp->c_data_len - cp->c_data_offs; - } - - if (!bcnt) break; - - // Don't run past user's buffer - if (bcnt > cnt) bcnt = cnt; - - if (copy_to_user(buf,src,bcnt)) { - // User supplied a bad pointer? - // Give up - this *will* cause data - // to be lost. - ret = -EFAULT; - break; - } - cnt -= bcnt; - buf += bcnt; - copied_cnt += bcnt; - - if (cp->sync_state == 2) { - // Update offset inside sync key that we're - // repeating back out. - cp->sync_buf_offs += bcnt; - if (cp->sync_buf_offs >= cp->sync_key_len) { - // Consumed entire key; switch mode - // to normal. - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/" - " sync_state <== 0"); - cp->sync_state = 0; - } - } else { - // Update buffer offset. - cp->c_data_offs += bcnt; - } - } - - } while (0); mutex_unlock(&cp->mutex); - - if (!ret) { - if (copied_cnt) { - // If anything was copied, return that count - ret = copied_cnt; - } else { - // Nothing copied; suggest to caller that another - // attempt should be tried again later - ret = -EAGAIN; - } - } - - pvr2_trace(PVR2_TRACE_DATA_FLOW, - "/*---TRACE_READ---*/ pvr2_ioread_read" - " id=%p request=%d result=%d", - cp,req_cnt,ret); - return ret; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-ioread.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-ioread.h deleted file mode 100644 index 6b002597f5de..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-ioread.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_IOREAD_H -#define __PVRUSB2_IOREAD_H - -#include "pvrusb2-io.h" - -struct pvr2_ioread; - -struct pvr2_ioread *pvr2_ioread_create(void); -void pvr2_ioread_destroy(struct pvr2_ioread *); -int pvr2_ioread_setup(struct pvr2_ioread *,struct pvr2_stream *); -struct pvr2_stream *pvr2_ioread_get_stream(struct pvr2_ioread *); -void pvr2_ioread_set_sync_key(struct pvr2_ioread *, - const char *sync_key_ptr, - unsigned int sync_key_len); -int pvr2_ioread_set_enabled(struct pvr2_ioread *,int fl); -int pvr2_ioread_get_enabled(struct pvr2_ioread *); -int pvr2_ioread_read(struct pvr2_ioread *,void __user *buf,unsigned int cnt); -int pvr2_ioread_avail(struct pvr2_ioread *); - -#endif /* __PVRUSB2_IOREAD_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c deleted file mode 100644 index b95248274ed0..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-main.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * 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 "pvrusb2-hdw.h" -#include "pvrusb2-context.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-v4l2.h" -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS -#include "pvrusb2-sysfs.h" -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - -#define DRIVER_AUTHOR "Mike Isely " -#define DRIVER_DESC "Hauppauge WinTV-PVR-USB2 MPEG2 Encoder/Tuner" -#define DRIVER_VERSION "V4L in-tree version" - -#define DEFAULT_DEBUG_MASK (PVR2_TRACE_ERROR_LEGS| \ - PVR2_TRACE_INFO| \ - PVR2_TRACE_TOLERANCE| \ - PVR2_TRACE_TRAP| \ - 0) - -int pvrusb2_debug = DEFAULT_DEBUG_MASK; - -module_param_named(debug,pvrusb2_debug,int,S_IRUGO|S_IWUSR); -MODULE_PARM_DESC(debug, "Debug trace mask"); - -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS -static struct pvr2_sysfs_class *class_ptr = 0; -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - -static void pvr_setup_attach(struct pvr2_context *pvr) -{ - /* Create association with v4l layer */ - pvr2_v4l2_create(pvr); -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS - pvr2_sysfs_create(pvr,class_ptr); -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ -} - -static int pvr_probe(struct usb_interface *intf, - const struct usb_device_id *devid) -{ - struct pvr2_context *pvr; - - /* Create underlying hardware interface */ - pvr = pvr2_context_create(intf,devid,pvr_setup_attach); - if (!pvr) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "Failed to create hdw handler"); - return -ENOMEM; - } - - pvr2_trace(PVR2_TRACE_INIT,"pvr_probe(pvr=%p)",pvr); - - usb_set_intfdata(intf, pvr); - - return 0; -} - -/* - * pvr_disconnect() - * - */ -static void pvr_disconnect(struct usb_interface *intf) -{ - struct pvr2_context *pvr = usb_get_intfdata(intf); - - pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) BEGIN",pvr); - - usb_set_intfdata (intf, NULL); - pvr2_context_disconnect(pvr); - - pvr2_trace(PVR2_TRACE_INIT,"pvr_disconnect(pvr=%p) DONE",pvr); - -} - -static struct usb_driver pvr_driver = { - name: "pvrusb2", - id_table: pvr2_device_table, - probe: pvr_probe, - disconnect: pvr_disconnect -}; - -/* - * pvr_init() / pvr_exit() - * - * This code is run to initialize/exit the driver. - * - */ -static int __init pvr_init(void) -{ - int ret; - - pvr2_trace(PVR2_TRACE_INIT,"pvr_init"); - -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS - class_ptr = pvr2_sysfs_class_create(); -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - - ret = usb_register(&pvr_driver); - - if (ret == 0) - info(DRIVER_DESC " : " DRIVER_VERSION); - if (pvrusb2_debug) info("Debug mask is %d (0x%x)", - pvrusb2_debug,pvrusb2_debug); - - return ret; -} - -static void __exit pvr_exit(void) -{ - - pvr2_trace(PVR2_TRACE_INIT,"pvr_exit"); - -#ifdef CONFIG_VIDEO_PVRUSB2_SYSFS - pvr2_sysfs_class_destroy(class_ptr); -#endif /* CONFIG_VIDEO_PVRUSB2_SYSFS */ - - usb_deregister(&pvr_driver); -} - -module_init(pvr_init); -module_exit(pvr_exit); - -/* Mike Isely 11-Mar-2006: See pvrusb2-hdw.c for - MODULE_DEVICE_TABLE(). We have to declare that attribute there - because that's where the device table actually is now and it seems - that certain gcc configurations get angry if MODULE_DEVICE_TABLE() - is used on what ends up being an external symbol. */ -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-std.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-std.c deleted file mode 100644 index 134063693643..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-std.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * 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 "pvrusb2-std.h" -#include "pvrusb2-debug.h" -#include -#include - -struct std_name { - const char *name; - v4l2_std_id id; -}; - - -#define CSTD_PAL \ - (V4L2_STD_PAL_B| \ - V4L2_STD_PAL_B1| \ - V4L2_STD_PAL_G| \ - V4L2_STD_PAL_H| \ - V4L2_STD_PAL_I| \ - V4L2_STD_PAL_D| \ - V4L2_STD_PAL_D1| \ - V4L2_STD_PAL_K| \ - V4L2_STD_PAL_M| \ - V4L2_STD_PAL_N| \ - V4L2_STD_PAL_Nc| \ - V4L2_STD_PAL_60) - -#define CSTD_NTSC \ - (V4L2_STD_NTSC_M| \ - V4L2_STD_NTSC_M_JP| \ - V4L2_STD_NTSC_M_KR| \ - V4L2_STD_NTSC_443) - -#define CSTD_SECAM \ - (V4L2_STD_SECAM_B| \ - V4L2_STD_SECAM_D| \ - V4L2_STD_SECAM_G| \ - V4L2_STD_SECAM_H| \ - V4L2_STD_SECAM_K| \ - V4L2_STD_SECAM_K1| \ - V4L2_STD_SECAM_L| \ - V4L2_STD_SECAM_LC) - -#define TSTD_B (V4L2_STD_PAL_B|V4L2_STD_SECAM_B) -#define TSTD_B1 (V4L2_STD_PAL_B1) -#define TSTD_D (V4L2_STD_PAL_D|V4L2_STD_SECAM_D) -#define TSTD_D1 (V4L2_STD_PAL_D1) -#define TSTD_G (V4L2_STD_PAL_G|V4L2_STD_SECAM_G) -#define TSTD_H (V4L2_STD_PAL_H|V4L2_STD_SECAM_H) -#define TSTD_I (V4L2_STD_PAL_I) -#define TSTD_K (V4L2_STD_PAL_K|V4L2_STD_SECAM_K) -#define TSTD_K1 (V4L2_STD_SECAM_K1) -#define TSTD_L (V4L2_STD_SECAM_L) -#define TSTD_M (V4L2_STD_PAL_M|V4L2_STD_NTSC_M) -#define TSTD_N (V4L2_STD_PAL_N) -#define TSTD_Nc (V4L2_STD_PAL_Nc) -#define TSTD_60 (V4L2_STD_PAL_60) - -#define CSTD_ALL (CSTD_PAL|CSTD_NTSC|CSTD_SECAM) - -/* Mapping of standard bits to color system */ -const static struct std_name std_groups[] = { - {"PAL",CSTD_PAL}, - {"NTSC",CSTD_NTSC}, - {"SECAM",CSTD_SECAM}, -}; - -/* Mapping of standard bits to modulation system */ -const static struct std_name std_items[] = { - {"B",TSTD_B}, - {"B1",TSTD_B1}, - {"D",TSTD_D}, - {"D1",TSTD_D1}, - {"G",TSTD_G}, - {"H",TSTD_H}, - {"I",TSTD_I}, - {"K",TSTD_K}, - {"K1",TSTD_K1}, - {"L",TSTD_L}, - {"LC",V4L2_STD_SECAM_LC}, - {"M",TSTD_M}, - {"Mj",V4L2_STD_NTSC_M_JP}, - {"443",V4L2_STD_NTSC_443}, - {"Mk",V4L2_STD_NTSC_M_KR}, - {"N",TSTD_N}, - {"Nc",TSTD_Nc}, - {"60",TSTD_60}, -}; - - -// Search an array of std_name structures and return a pointer to the -// element with the matching name. -static const struct std_name *find_std_name(const struct std_name *arrPtr, - unsigned int arrSize, - const char *bufPtr, - unsigned int bufSize) -{ - unsigned int idx; - const struct std_name *p; - for (idx = 0; idx < arrSize; idx++) { - p = arrPtr + idx; - if (strlen(p->name) != bufSize) continue; - if (!memcmp(bufPtr,p->name,bufSize)) return p; - } - return 0; -} - - -int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr, - unsigned int bufSize) -{ - v4l2_std_id id = 0; - v4l2_std_id cmsk = 0; - v4l2_std_id t; - int mMode = 0; - unsigned int cnt; - char ch; - const struct std_name *sp; - - while (bufSize) { - if (!mMode) { - cnt = 0; - while ((cnt < bufSize) && (bufPtr[cnt] != '-')) cnt++; - if (cnt >= bufSize) return 0; // No more characters - sp = find_std_name( - std_groups, - sizeof(std_groups)/sizeof(std_groups[0]), - bufPtr,cnt); - if (!sp) return 0; // Illegal color system name - cnt++; - bufPtr += cnt; - bufSize -= cnt; - mMode = !0; - cmsk = sp->id; - continue; - } - cnt = 0; - while (cnt < bufSize) { - ch = bufPtr[cnt]; - if (ch == ';') { - mMode = 0; - break; - } - if (ch == '/') break; - cnt++; - } - sp = find_std_name(std_items, - sizeof(std_items)/sizeof(std_items[0]), - bufPtr,cnt); - if (!sp) return 0; // Illegal modulation system ID - t = sp->id & cmsk; - if (!t) return 0; // Specific color + modulation system illegal - id |= t; - if (cnt < bufSize) cnt++; - bufPtr += cnt; - bufSize -= cnt; - } - - if (idPtr) *idPtr = id; - return !0; -} - - -unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize, - v4l2_std_id id) -{ - unsigned int idx1,idx2; - const struct std_name *ip,*gp; - int gfl,cfl; - unsigned int c1,c2; - cfl = 0; - c1 = 0; - for (idx1 = 0; - idx1 < sizeof(std_groups)/sizeof(std_groups[0]); - idx1++) { - gp = std_groups + idx1; - gfl = 0; - for (idx2 = 0; - idx2 < sizeof(std_items)/sizeof(std_items[0]); - idx2++) { - ip = std_items + idx2; - if (!(gp->id & ip->id & id)) continue; - if (!gfl) { - if (cfl) { - c2 = scnprintf(bufPtr,bufSize,";"); - c1 += c2; - bufSize -= c2; - bufPtr += c2; - } - cfl = !0; - c2 = scnprintf(bufPtr,bufSize, - "%s-",gp->name); - gfl = !0; - } else { - c2 = scnprintf(bufPtr,bufSize,"/"); - } - c1 += c2; - bufSize -= c2; - bufPtr += c2; - c2 = scnprintf(bufPtr,bufSize, - ip->name); - c1 += c2; - bufSize -= c2; - bufPtr += c2; - } - } - return c1; -} - - -// Template data for possible enumerated video standards. Here we group -// standards which share common frame rates and resolution. -static struct v4l2_standard generic_standards[] = { - { - .id = (TSTD_B|TSTD_B1| - TSTD_D|TSTD_D1| - TSTD_G| - TSTD_H| - TSTD_I| - TSTD_K|TSTD_K1| - TSTD_L| - V4L2_STD_SECAM_LC | - TSTD_N|TSTD_Nc), - .frameperiod = - { - .numerator = 1, - .denominator= 25 - }, - .framelines = 625, - .reserved = {0,0,0,0} - }, { - .id = (TSTD_M| - V4L2_STD_NTSC_M_JP| - V4L2_STD_NTSC_M_KR), - .frameperiod = - { - .numerator = 1001, - .denominator= 30000 - }, - .framelines = 525, - .reserved = {0,0,0,0} - }, { // This is a total wild guess - .id = (TSTD_60), - .frameperiod = - { - .numerator = 1001, - .denominator= 30000 - }, - .framelines = 525, - .reserved = {0,0,0,0} - }, { // This is total wild guess - .id = V4L2_STD_NTSC_443, - .frameperiod = - { - .numerator = 1001, - .denominator= 30000 - }, - .framelines = 525, - .reserved = {0,0,0,0} - } -}; - -#define generic_standards_cnt (sizeof(generic_standards)/sizeof(generic_standards[0])) - -static struct v4l2_standard *match_std(v4l2_std_id id) -{ - unsigned int idx; - for (idx = 0; idx < generic_standards_cnt; idx++) { - if (generic_standards[idx].id & id) { - return generic_standards + idx; - } - } - return 0; -} - -static int pvr2_std_fill(struct v4l2_standard *std,v4l2_std_id id) -{ - struct v4l2_standard *template; - int idx; - unsigned int bcnt; - template = match_std(id); - if (!template) return 0; - idx = std->index; - memcpy(std,template,sizeof(*template)); - std->index = idx; - std->id = id; - bcnt = pvr2_std_id_to_str(std->name,sizeof(std->name)-1,id); - std->name[bcnt] = 0; - pvr2_trace(PVR2_TRACE_INIT,"Set up standard idx=%u name=%s", - std->index,std->name); - return !0; -} - -/* These are special cases of combined standards that we should enumerate - separately if the component pieces are present. */ -static v4l2_std_id std_mixes[] = { - V4L2_STD_PAL_B | V4L2_STD_PAL_G, - V4L2_STD_PAL_D | V4L2_STD_PAL_K, - V4L2_STD_SECAM_B | V4L2_STD_SECAM_G, - V4L2_STD_SECAM_D | V4L2_STD_SECAM_K, -}; - -struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, - v4l2_std_id id) -{ - unsigned int std_cnt = 0; - unsigned int idx,bcnt,idx2; - v4l2_std_id idmsk,cmsk,fmsk; - struct v4l2_standard *stddefs; - - if (pvrusb2_debug & PVR2_TRACE_INIT) { - char buf[50]; - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),id); - pvr2_trace( - PVR2_TRACE_INIT,"Mapping standards mask=0x%x (%.*s)", - (int)id,bcnt,buf); - } - - *countptr = 0; - std_cnt = 0; - fmsk = 0; - for (idmsk = 1, cmsk = id; cmsk; idmsk <<= 1) { - if (!(idmsk & cmsk)) continue; - cmsk &= ~idmsk; - if (match_std(idmsk)) { - std_cnt++; - continue; - } - fmsk |= idmsk; - } - - for (idx2 = 0; idx2 < sizeof(std_mixes)/sizeof(std_mixes[0]); idx2++) { - if ((id & std_mixes[idx2]) == std_mixes[idx2]) std_cnt++; - } - - if (fmsk) { - char buf[50]; - bcnt = pvr2_std_id_to_str(buf,sizeof(buf),fmsk); - pvr2_trace( - PVR2_TRACE_ERROR_LEGS, - "WARNING:" - " Failed to classify the following standard(s): %.*s", - bcnt,buf); - } - - pvr2_trace(PVR2_TRACE_INIT,"Setting up %u unique standard(s)", - std_cnt); - if (!std_cnt) return 0; // paranoia - - stddefs = kmalloc(sizeof(struct v4l2_standard) * std_cnt, - GFP_KERNEL); - memset(stddefs,0,sizeof(struct v4l2_standard) * std_cnt); - for (idx = 0; idx < std_cnt; idx++) stddefs[idx].index = idx; - - idx = 0; - - /* Enumerate potential special cases */ - for (idx2 = 0; ((idx2 < sizeof(std_mixes)/sizeof(std_mixes[0])) && - (idx < std_cnt)); idx2++) { - if (!(id & std_mixes[idx2])) continue; - if (pvr2_std_fill(stddefs+idx,std_mixes[idx2])) idx++; - } - /* Now enumerate individual pieces */ - for (idmsk = 1, cmsk = id; cmsk && (idx < std_cnt); idmsk <<= 1) { - if (!(idmsk & cmsk)) continue; - cmsk &= ~idmsk; - if (!pvr2_std_fill(stddefs+idx,idmsk)) continue; - idx++; - } - - *countptr = std_cnt; - return stddefs; -} - -v4l2_std_id pvr2_std_get_usable(void) -{ - return CSTD_ALL; -} - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-std.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-std.h deleted file mode 100644 index 07c399375341..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-std.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_STD_H -#define __PVRUSB2_STD_H - -#include - -// Convert string describing one or more video standards into a mask of V4L -// standard bits. Return true if conversion succeeds otherwise return -// false. String is expected to be of the form: C1-x/y;C2-a/b where C1 and -// C2 are color system names (e.g. "PAL", "NTSC") and x, y, a, and b are -// modulation schemes (e.g. "M", "B", "G", etc). -int pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr, - unsigned int bufSize); - -// Convert any arbitrary set of video standard bits into an unambiguous -// readable string. Return value is the number of bytes consumed in the -// buffer. The formatted string is of a form that can be parsed by our -// sibling std_std_to_id() function. -unsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize, - v4l2_std_id id); - -// Create an array of suitable v4l2_standard structures given a bit mask of -// video standards to support. The array is allocated from the heap, and -// the number of elements is returned in the first argument. -struct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr, - v4l2_std_id id); - -// Return mask of which video standard bits are valid -v4l2_std_id pvr2_std_get_usable(void); - -#endif /* __PVRUSB2_STD_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c deleted file mode 100644 index c6e6523d74b4..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.c +++ /dev/null @@ -1,865 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * 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 "pvrusb2-sysfs.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2-debug.h" -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC -#include "pvrusb2-debugifc.h" -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - -#define pvr2_sysfs_trace(...) pvr2_trace(PVR2_TRACE_SYSFS,__VA_ARGS__) - -struct pvr2_sysfs { - struct pvr2_channel channel; - struct class_device *class_dev; -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC - struct pvr2_sysfs_debugifc *debugifc; -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - struct pvr2_sysfs_ctl_item *item_first; - struct pvr2_sysfs_ctl_item *item_last; - struct sysfs_ops kops; - struct kobj_type ktype; - struct class_device_attribute attr_v4l_minor_number; - struct class_device_attribute attr_unit_number; -}; - -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC -struct pvr2_sysfs_debugifc { - struct class_device_attribute attr_debugcmd; - struct class_device_attribute attr_debuginfo; -}; -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - -struct pvr2_sysfs_ctl_item { - struct class_device_attribute attr_name; - struct class_device_attribute attr_type; - struct class_device_attribute attr_min; - struct class_device_attribute attr_max; - struct class_device_attribute attr_enum; - struct class_device_attribute attr_bits; - struct class_device_attribute attr_val; - struct class_device_attribute attr_custom; - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *chptr; - struct pvr2_sysfs_ctl_item *item_next; - struct attribute *attr_gen[7]; - struct attribute_group grp; - char name[80]; -}; - -struct pvr2_sysfs_class { - struct class class; -}; - -static ssize_t show_name(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - const char *name; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - - name = pvr2_ctrl_get_desc(cptr); - pvr2_sysfs_trace("pvr2_sysfs(%p) show_name(cid=%d) is %s",sfp,id,name); - - if (!name) return -EINVAL; - - return scnprintf(buf,PAGE_SIZE,"%s\n",name); -} - -static ssize_t show_type(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - const char *name; - enum pvr2_ctl_type tp; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - - tp = pvr2_ctrl_get_type(cptr); - switch (tp) { - case pvr2_ctl_int: name = "integer"; break; - case pvr2_ctl_enum: name = "enum"; break; - case pvr2_ctl_bitmask: name = "bitmask"; break; - case pvr2_ctl_bool: name = "boolean"; break; - default: name = "?"; break; - } - pvr2_sysfs_trace("pvr2_sysfs(%p) show_type(cid=%d) is %s",sfp,id,name); - - if (!name) return -EINVAL; - - return scnprintf(buf,PAGE_SIZE,"%s\n",name); -} - -static ssize_t show_min(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - long val; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - val = pvr2_ctrl_get_min(cptr); - - pvr2_sysfs_trace("pvr2_sysfs(%p) show_min(cid=%d) is %ld",sfp,id,val); - - return scnprintf(buf,PAGE_SIZE,"%ld\n",val); -} - -static ssize_t show_max(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - long val; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - val = pvr2_ctrl_get_max(cptr); - - pvr2_sysfs_trace("pvr2_sysfs(%p) show_max(cid=%d) is %ld",sfp,id,val); - - return scnprintf(buf,PAGE_SIZE,"%ld\n",val); -} - -static ssize_t show_val_norm(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - int val,ret; - unsigned int cnt = 0; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - - ret = pvr2_ctrl_get_value(cptr,&val); - if (ret < 0) return ret; - - ret = pvr2_ctrl_value_to_sym(cptr,~0,val, - buf,PAGE_SIZE-1,&cnt); - - pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_norm(cid=%d) is %.*s (%d)", - sfp,id,cnt,buf,val); - buf[cnt] = '\n'; - return cnt+1; -} - -static ssize_t show_val_custom(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - int val,ret; - unsigned int cnt = 0; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - - ret = pvr2_ctrl_get_value(cptr,&val); - if (ret < 0) return ret; - - ret = pvr2_ctrl_custom_value_to_sym(cptr,~0,val, - buf,PAGE_SIZE-1,&cnt); - - pvr2_sysfs_trace("pvr2_sysfs(%p) show_val_custom(cid=%d) is %.*s (%d)", - sfp,id,cnt,buf,val); - buf[cnt] = '\n'; - return cnt+1; -} - -static ssize_t show_enum(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - long val; - unsigned int bcnt,ccnt,ecnt; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - ecnt = pvr2_ctrl_get_cnt(cptr); - bcnt = 0; - for (val = 0; val < ecnt; val++) { - pvr2_ctrl_get_valname(cptr,val,buf+bcnt,PAGE_SIZE-bcnt,&ccnt); - if (!ccnt) continue; - bcnt += ccnt; - if (bcnt >= PAGE_SIZE) break; - buf[bcnt] = '\n'; - bcnt++; - } - pvr2_sysfs_trace("pvr2_sysfs(%p) show_enum(cid=%d)",sfp,id); - return bcnt; -} - -static ssize_t show_bits(int id,struct class_device *class_dev,char *buf) -{ - struct pvr2_ctrl *cptr; - struct pvr2_sysfs *sfp; - int valid_bits,msk; - unsigned int bcnt,ccnt; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (!cptr) return -EINVAL; - valid_bits = pvr2_ctrl_get_mask(cptr); - bcnt = 0; - for (msk = 1; valid_bits; msk <<= 1) { - if (!(msk & valid_bits)) continue; - valid_bits &= ~msk; - pvr2_ctrl_get_valname(cptr,msk,buf+bcnt,PAGE_SIZE-bcnt,&ccnt); - bcnt += ccnt; - if (bcnt >= PAGE_SIZE) break; - buf[bcnt] = '\n'; - bcnt++; - } - pvr2_sysfs_trace("pvr2_sysfs(%p) show_bits(cid=%d)",sfp,id); - return bcnt; -} - -static int store_val_any(int id,int customfl,struct pvr2_sysfs *sfp, - const char *buf,unsigned int count) -{ - struct pvr2_ctrl *cptr; - int ret; - int mask,val; - - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,id); - if (customfl) { - ret = pvr2_ctrl_custom_sym_to_value(cptr,buf,count,&mask,&val); - } else { - ret = pvr2_ctrl_sym_to_value(cptr,buf,count,&mask,&val); - } - if (ret < 0) return ret; - ret = pvr2_ctrl_set_mask_value(cptr,mask,val); - pvr2_hdw_commit_ctl(sfp->channel.hdw); - return ret; -} - -static ssize_t store_val_norm(int id,struct class_device *class_dev, - const char *buf,size_t count) -{ - struct pvr2_sysfs *sfp; - int ret; - sfp = (struct pvr2_sysfs *)class_dev->class_data; - ret = store_val_any(id,0,sfp,buf,count); - if (!ret) ret = count; - return ret; -} - -static ssize_t store_val_custom(int id,struct class_device *class_dev, - const char *buf,size_t count) -{ - struct pvr2_sysfs *sfp; - int ret; - sfp = (struct pvr2_sysfs *)class_dev->class_data; - ret = store_val_any(id,1,sfp,buf,count); - if (!ret) ret = count; - return ret; -} - -/* - Mike Isely 30-April-2005 - - This next batch of horrible preprocessor hackery is needed because the - kernel's class_device_attribute mechanism fails to pass the actual - attribute through to the show / store functions, which means we have no - way to package up any attribute-specific parameters, like for example the - control id. So we work around this brain-damage by encoding the control - id into the show / store functions themselves and pick the function based - on the control id we're setting up. These macros try to ease the pain. - Yuck. -*/ - -#define CREATE_SHOW_INSTANCE(sf_name,ctl_id) \ -static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,char *buf) \ -{ return sf_name(ctl_id,class_dev,buf); } - -#define CREATE_STORE_INSTANCE(sf_name,ctl_id) \ -static ssize_t sf_name##_##ctl_id(struct class_device *class_dev,const char *buf,size_t count) \ -{ return sf_name(ctl_id,class_dev,buf,count); } - -#define CREATE_BATCH(ctl_id) \ -CREATE_SHOW_INSTANCE(show_name,ctl_id) \ -CREATE_SHOW_INSTANCE(show_type,ctl_id) \ -CREATE_SHOW_INSTANCE(show_min,ctl_id) \ -CREATE_SHOW_INSTANCE(show_max,ctl_id) \ -CREATE_SHOW_INSTANCE(show_val_norm,ctl_id) \ -CREATE_SHOW_INSTANCE(show_val_custom,ctl_id) \ -CREATE_SHOW_INSTANCE(show_enum,ctl_id) \ -CREATE_SHOW_INSTANCE(show_bits,ctl_id) \ -CREATE_STORE_INSTANCE(store_val_norm,ctl_id) \ -CREATE_STORE_INSTANCE(store_val_custom,ctl_id) \ - -CREATE_BATCH(0) -CREATE_BATCH(1) -CREATE_BATCH(2) -CREATE_BATCH(3) -CREATE_BATCH(4) -CREATE_BATCH(5) -CREATE_BATCH(6) -CREATE_BATCH(7) -CREATE_BATCH(8) -CREATE_BATCH(9) -CREATE_BATCH(10) -CREATE_BATCH(11) -CREATE_BATCH(12) -CREATE_BATCH(13) -CREATE_BATCH(14) -CREATE_BATCH(15) -CREATE_BATCH(16) -CREATE_BATCH(17) -CREATE_BATCH(18) -CREATE_BATCH(19) -CREATE_BATCH(20) -CREATE_BATCH(21) -CREATE_BATCH(22) -CREATE_BATCH(23) -CREATE_BATCH(24) -CREATE_BATCH(25) -CREATE_BATCH(26) -CREATE_BATCH(27) -CREATE_BATCH(28) -CREATE_BATCH(29) -CREATE_BATCH(30) -CREATE_BATCH(31) -CREATE_BATCH(32) -CREATE_BATCH(33) -CREATE_BATCH(34) -CREATE_BATCH(35) -CREATE_BATCH(36) -CREATE_BATCH(37) -CREATE_BATCH(38) -CREATE_BATCH(39) -CREATE_BATCH(40) -CREATE_BATCH(41) -CREATE_BATCH(42) -CREATE_BATCH(43) -CREATE_BATCH(44) -CREATE_BATCH(45) -CREATE_BATCH(46) -CREATE_BATCH(47) -CREATE_BATCH(48) -CREATE_BATCH(49) -CREATE_BATCH(50) -CREATE_BATCH(51) -CREATE_BATCH(52) -CREATE_BATCH(53) -CREATE_BATCH(54) -CREATE_BATCH(55) -CREATE_BATCH(56) -CREATE_BATCH(57) -CREATE_BATCH(58) -CREATE_BATCH(59) - -struct pvr2_sysfs_func_set { - ssize_t (*show_name)(struct class_device *,char *); - ssize_t (*show_type)(struct class_device *,char *); - ssize_t (*show_min)(struct class_device *,char *); - ssize_t (*show_max)(struct class_device *,char *); - ssize_t (*show_enum)(struct class_device *,char *); - ssize_t (*show_bits)(struct class_device *,char *); - ssize_t (*show_val_norm)(struct class_device *,char *); - ssize_t (*store_val_norm)(struct class_device *, - const char *,size_t); - ssize_t (*show_val_custom)(struct class_device *,char *); - ssize_t (*store_val_custom)(struct class_device *, - const char *,size_t); -}; - -#define INIT_BATCH(ctl_id) \ -[ctl_id] = { \ - .show_name = show_name_##ctl_id, \ - .show_type = show_type_##ctl_id, \ - .show_min = show_min_##ctl_id, \ - .show_max = show_max_##ctl_id, \ - .show_enum = show_enum_##ctl_id, \ - .show_bits = show_bits_##ctl_id, \ - .show_val_norm = show_val_norm_##ctl_id, \ - .store_val_norm = store_val_norm_##ctl_id, \ - .show_val_custom = show_val_custom_##ctl_id, \ - .store_val_custom = store_val_custom_##ctl_id, \ -} \ - -static struct pvr2_sysfs_func_set funcs[] = { - INIT_BATCH(0), - INIT_BATCH(1), - INIT_BATCH(2), - INIT_BATCH(3), - INIT_BATCH(4), - INIT_BATCH(5), - INIT_BATCH(6), - INIT_BATCH(7), - INIT_BATCH(8), - INIT_BATCH(9), - INIT_BATCH(10), - INIT_BATCH(11), - INIT_BATCH(12), - INIT_BATCH(13), - INIT_BATCH(14), - INIT_BATCH(15), - INIT_BATCH(16), - INIT_BATCH(17), - INIT_BATCH(18), - INIT_BATCH(19), - INIT_BATCH(20), - INIT_BATCH(21), - INIT_BATCH(22), - INIT_BATCH(23), - INIT_BATCH(24), - INIT_BATCH(25), - INIT_BATCH(26), - INIT_BATCH(27), - INIT_BATCH(28), - INIT_BATCH(29), - INIT_BATCH(30), - INIT_BATCH(31), - INIT_BATCH(32), - INIT_BATCH(33), - INIT_BATCH(34), - INIT_BATCH(35), - INIT_BATCH(36), - INIT_BATCH(37), - INIT_BATCH(38), - INIT_BATCH(39), - INIT_BATCH(40), - INIT_BATCH(41), - INIT_BATCH(42), - INIT_BATCH(43), - INIT_BATCH(44), - INIT_BATCH(45), - INIT_BATCH(46), - INIT_BATCH(47), - INIT_BATCH(48), - INIT_BATCH(49), - INIT_BATCH(50), - INIT_BATCH(51), - INIT_BATCH(52), - INIT_BATCH(53), - INIT_BATCH(54), - INIT_BATCH(55), - INIT_BATCH(56), - INIT_BATCH(57), - INIT_BATCH(58), - INIT_BATCH(59), -}; - - -static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) -{ - struct pvr2_sysfs_ctl_item *cip; - struct pvr2_sysfs_func_set *fp; - struct pvr2_ctrl *cptr; - unsigned int cnt,acnt; - - if ((ctl_id < 0) || (ctl_id >= (sizeof(funcs)/sizeof(funcs[0])))) { - return; - } - - fp = funcs + ctl_id; - cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id); - if (!cptr) return; - - cip = kmalloc(sizeof(*cip),GFP_KERNEL); - if (!cip) return; - memset(cip,0,sizeof(*cip)); - pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip); - - cip->cptr = cptr; - - cip->chptr = sfp; - cip->item_next = 0; - if (sfp->item_last) { - sfp->item_last->item_next = cip; - } else { - sfp->item_first = cip; - } - sfp->item_last = cip; - - cip->attr_name.attr.owner = THIS_MODULE; - cip->attr_name.attr.name = "name"; - cip->attr_name.attr.mode = S_IRUGO; - cip->attr_name.show = fp->show_name; - - cip->attr_type.attr.owner = THIS_MODULE; - cip->attr_type.attr.name = "type"; - cip->attr_type.attr.mode = S_IRUGO; - cip->attr_type.show = fp->show_type; - - cip->attr_min.attr.owner = THIS_MODULE; - cip->attr_min.attr.name = "min_val"; - cip->attr_min.attr.mode = S_IRUGO; - cip->attr_min.show = fp->show_min; - - cip->attr_max.attr.owner = THIS_MODULE; - cip->attr_max.attr.name = "max_val"; - cip->attr_max.attr.mode = S_IRUGO; - cip->attr_max.show = fp->show_max; - - cip->attr_val.attr.owner = THIS_MODULE; - cip->attr_val.attr.name = "cur_val"; - cip->attr_val.attr.mode = S_IRUGO; - - cip->attr_custom.attr.owner = THIS_MODULE; - cip->attr_custom.attr.name = "custom_val"; - cip->attr_custom.attr.mode = S_IRUGO; - - cip->attr_enum.attr.owner = THIS_MODULE; - cip->attr_enum.attr.name = "enum_val"; - cip->attr_enum.attr.mode = S_IRUGO; - cip->attr_enum.show = fp->show_enum; - - cip->attr_bits.attr.owner = THIS_MODULE; - cip->attr_bits.attr.name = "bit_val"; - cip->attr_bits.attr.mode = S_IRUGO; - cip->attr_bits.show = fp->show_bits; - - if (pvr2_ctrl_is_writable(cptr)) { - cip->attr_val.attr.mode |= S_IWUSR|S_IWGRP; - cip->attr_custom.attr.mode |= S_IWUSR|S_IWGRP; - } - - acnt = 0; - cip->attr_gen[acnt++] = &cip->attr_name.attr; - cip->attr_gen[acnt++] = &cip->attr_type.attr; - cip->attr_gen[acnt++] = &cip->attr_val.attr; - cip->attr_val.show = fp->show_val_norm; - cip->attr_val.store = fp->store_val_norm; - if (pvr2_ctrl_has_custom_symbols(cptr)) { - cip->attr_gen[acnt++] = &cip->attr_custom.attr; - cip->attr_custom.show = fp->show_val_custom; - cip->attr_custom.store = fp->store_val_custom; - } - switch (pvr2_ctrl_get_type(cptr)) { - case pvr2_ctl_enum: - // Control is an enumeration - cip->attr_gen[acnt++] = &cip->attr_enum.attr; - break; - case pvr2_ctl_int: - // Control is an integer - cip->attr_gen[acnt++] = &cip->attr_min.attr; - cip->attr_gen[acnt++] = &cip->attr_max.attr; - break; - case pvr2_ctl_bitmask: - // Control is an bitmask - cip->attr_gen[acnt++] = &cip->attr_bits.attr; - break; - default: break; - } - - cnt = scnprintf(cip->name,sizeof(cip->name)-1,"ctl_%s", - pvr2_ctrl_get_name(cptr)); - cip->name[cnt] = 0; - cip->grp.name = cip->name; - cip->grp.attrs = cip->attr_gen; - - sysfs_create_group(&sfp->class_dev->kobj,&cip->grp); -} - -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC -static ssize_t debuginfo_show(struct class_device *,char *); -static ssize_t debugcmd_show(struct class_device *,char *); -static ssize_t debugcmd_store(struct class_device *,const char *,size_t count); - -static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) -{ - struct pvr2_sysfs_debugifc *dip; - dip = kmalloc(sizeof(*dip),GFP_KERNEL); - if (!dip) return; - memset(dip,0,sizeof(*dip)); - dip->attr_debugcmd.attr.owner = THIS_MODULE; - dip->attr_debugcmd.attr.name = "debugcmd"; - dip->attr_debugcmd.attr.mode = S_IRUGO|S_IWUSR|S_IWGRP; - dip->attr_debugcmd.show = debugcmd_show; - dip->attr_debugcmd.store = debugcmd_store; - dip->attr_debuginfo.attr.owner = THIS_MODULE; - dip->attr_debuginfo.attr.name = "debuginfo"; - dip->attr_debuginfo.attr.mode = S_IRUGO; - dip->attr_debuginfo.show = debuginfo_show; - sfp->debugifc = dip; - class_device_create_file(sfp->class_dev,&dip->attr_debugcmd); - class_device_create_file(sfp->class_dev,&dip->attr_debuginfo); -} - - -static void pvr2_sysfs_tear_down_debugifc(struct pvr2_sysfs *sfp) -{ - if (!sfp->debugifc) return; - class_device_remove_file(sfp->class_dev, - &sfp->debugifc->attr_debuginfo); - class_device_remove_file(sfp->class_dev,&sfp->debugifc->attr_debugcmd); - kfree(sfp->debugifc); - sfp->debugifc = 0; -} -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - - -static void pvr2_sysfs_add_controls(struct pvr2_sysfs *sfp) -{ - unsigned int idx,cnt; - cnt = pvr2_hdw_get_ctrl_count(sfp->channel.hdw); - for (idx = 0; idx < cnt; idx++) { - pvr2_sysfs_add_control(sfp,idx); - } -} - - -static void pvr2_sysfs_tear_down_controls(struct pvr2_sysfs *sfp) -{ - struct pvr2_sysfs_ctl_item *cip1,*cip2; - for (cip1 = sfp->item_first; cip1; cip1 = cip2) { - cip2 = cip1->item_next; - sysfs_remove_group(&sfp->class_dev->kobj,&cip1->grp); - pvr2_sysfs_trace("Destroying pvr2_sysfs_ctl_item id=%p",cip1); - kfree(cip1); - } -} - - -static void pvr2_sysfs_class_release(struct class *class) -{ - struct pvr2_sysfs_class *clp; - clp = container_of(class,struct pvr2_sysfs_class,class); - pvr2_sysfs_trace("Destroying pvr2_sysfs_class id=%p",clp); - kfree(clp); -} - - -static void pvr2_sysfs_release(struct class_device *class_dev) -{ - pvr2_sysfs_trace("Releasing class_dev id=%p",class_dev); - kfree(class_dev); -} - - -static void class_dev_destroy(struct pvr2_sysfs *sfp) -{ - if (!sfp->class_dev) return; -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC - pvr2_sysfs_tear_down_debugifc(sfp); -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - pvr2_sysfs_tear_down_controls(sfp); - class_device_remove_file(sfp->class_dev,&sfp->attr_v4l_minor_number); - class_device_remove_file(sfp->class_dev,&sfp->attr_unit_number); - pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev); - sfp->class_dev->class_data = 0; - class_device_unregister(sfp->class_dev); - sfp->class_dev = 0; -} - - -static ssize_t v4l_minor_number_show(struct class_device *class_dev,char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - return scnprintf(buf,PAGE_SIZE,"%d\n", - pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw)); -} - - -static ssize_t unit_number_show(struct class_device *class_dev,char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - return scnprintf(buf,PAGE_SIZE,"%d\n", - pvr2_hdw_get_unit_number(sfp->channel.hdw)); -} - - -static void class_dev_create(struct pvr2_sysfs *sfp, - struct pvr2_sysfs_class *class_ptr) -{ - struct usb_device *usb_dev; - struct class_device *class_dev; - usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw); - if (!usb_dev) return; - class_dev = kmalloc(sizeof(*class_dev),GFP_KERNEL); - if (!class_dev) return; - memset(class_dev,0,sizeof(*class_dev)); - - pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); - - class_dev->class = &class_ptr->class; - if (pvr2_hdw_get_sn(sfp->channel.hdw)) { - snprintf(class_dev->class_id,BUS_ID_SIZE,"sn-%lu", - pvr2_hdw_get_sn(sfp->channel.hdw)); - } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) { - snprintf(class_dev->class_id,BUS_ID_SIZE,"unit-%c", - pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a'); - } else { - kfree(class_dev); - return; - } - - class_dev->dev = &usb_dev->dev; - - sfp->class_dev = class_dev; - class_dev->class_data = sfp; - class_device_register(class_dev); - - sfp->attr_v4l_minor_number.attr.owner = THIS_MODULE; - sfp->attr_v4l_minor_number.attr.name = "v4l_minor_number"; - sfp->attr_v4l_minor_number.attr.mode = S_IRUGO; - sfp->attr_v4l_minor_number.show = v4l_minor_number_show; - sfp->attr_v4l_minor_number.store = 0; - class_device_create_file(sfp->class_dev,&sfp->attr_v4l_minor_number); - sfp->attr_unit_number.attr.owner = THIS_MODULE; - sfp->attr_unit_number.attr.name = "unit_number"; - sfp->attr_unit_number.attr.mode = S_IRUGO; - sfp->attr_unit_number.show = unit_number_show; - sfp->attr_unit_number.store = 0; - class_device_create_file(sfp->class_dev,&sfp->attr_unit_number); - - pvr2_sysfs_add_controls(sfp); -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC - pvr2_sysfs_add_debugifc(sfp); -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ -} - - -static void pvr2_sysfs_internal_check(struct pvr2_channel *chp) -{ - struct pvr2_sysfs *sfp; - sfp = container_of(chp,struct pvr2_sysfs,channel); - if (!sfp->channel.mc_head->disconnect_flag) return; - pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_sysfs id=%p",sfp); - class_dev_destroy(sfp); - pvr2_channel_done(&sfp->channel); - kfree(sfp); -} - - -struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *mp, - struct pvr2_sysfs_class *class_ptr) -{ - struct pvr2_sysfs *sfp; - sfp = kmalloc(sizeof(*sfp),GFP_KERNEL); - if (!sfp) return sfp; - memset(sfp,0,sizeof(*sfp)); - pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp); - pvr2_channel_init(&sfp->channel,mp); - sfp->channel.check_func = pvr2_sysfs_internal_check; - - class_dev_create(sfp,class_ptr); - return sfp; -} - - -static int pvr2_sysfs_hotplug(struct class_device *cd,char **envp, - int numenvp,char *buf,int size) -{ - /* Even though we don't do anything here, we still need this function - because sysfs will still try to call it. */ - return 0; -} - -struct pvr2_sysfs_class *pvr2_sysfs_class_create(void) -{ - struct pvr2_sysfs_class *clp; - clp = kmalloc(sizeof(*clp),GFP_KERNEL); - if (!clp) return clp; - memset(clp,0,sizeof(*clp)); - pvr2_sysfs_trace("Creating pvr2_sysfs_class id=%p",clp); - clp->class.name = "pvrusb2"; - clp->class.class_release = pvr2_sysfs_class_release; - clp->class.release = pvr2_sysfs_release; - clp->class.uevent = pvr2_sysfs_hotplug; - if (class_register(&clp->class)) { - pvr2_sysfs_trace( - "Registration failed for pvr2_sysfs_class id=%p",clp); - kfree(clp); - clp = 0; - } - return clp; -} - - -void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *clp) -{ - class_unregister(&clp->class); -} - - -#ifdef CONFIG_VIDEO_PVRUSB2_DEBUGIFC -static ssize_t debuginfo_show(struct class_device *class_dev,char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - pvr2_hdw_trigger_module_log(sfp->channel.hdw); - return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE); -} - - -static ssize_t debugcmd_show(struct class_device *class_dev,char *buf) -{ - struct pvr2_sysfs *sfp; - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE); -} - - -static ssize_t debugcmd_store(struct class_device *class_dev, - const char *buf,size_t count) -{ - struct pvr2_sysfs *sfp; - int ret; - - sfp = (struct pvr2_sysfs *)class_dev->class_data; - if (!sfp) return -EINVAL; - - ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count); - if (ret < 0) return ret; - return count; -} -#endif /* CONFIG_VIDEO_PVRUSB2_DEBUGIFC */ - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.h deleted file mode 100644 index ff9373b47f8f..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-sysfs.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_SYSFS_H -#define __PVRUSB2_SYSFS_H - -#include -#include -#include "pvrusb2-context.h" - -struct pvr2_sysfs; -struct pvr2_sysfs_class; - -struct pvr2_sysfs_class *pvr2_sysfs_class_create(void); -void pvr2_sysfs_class_destroy(struct pvr2_sysfs_class *); - -struct pvr2_sysfs *pvr2_sysfs_create(struct pvr2_context *, - struct pvr2_sysfs_class *); - -#endif /* __PVRUSB2_SYSFS_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.c deleted file mode 100644 index f4aba8144ce0..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * 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 "pvrusb2.h" -#include "pvrusb2-util.h" -#include "pvrusb2-tuner.h" -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include -#include -#include - -struct pvr2_tuner_handler { - struct pvr2_hdw *hdw; - struct pvr2_i2c_client *client; - struct pvr2_i2c_handler i2c_handler; - int type_update_fl; -}; - - -static void set_type(struct pvr2_tuner_handler *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - struct tuner_setup setup; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c tuner set_type(%d)",hdw->tuner_type); - if (((int)(hdw->tuner_type)) < 0) return; - - setup.addr = ADDR_UNSET; - setup.type = hdw->tuner_type; - setup.mode_mask = T_RADIO | T_ANALOG_TV; - /* We may really want mode_mask to be T_ANALOG_TV for now */ - pvr2_i2c_client_cmd(ctxt->client,TUNER_SET_TYPE_ADDR,&setup); - ctxt->type_update_fl = 0; -} - - -static int tuner_check(struct pvr2_tuner_handler *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - if (hdw->tuner_updated) ctxt->type_update_fl = !0; - return ctxt->type_update_fl != 0; -} - - -static void tuner_update(struct pvr2_tuner_handler *ctxt) -{ - if (ctxt->type_update_fl) set_type(ctxt); -} - - -static void pvr2_tuner_detach(struct pvr2_tuner_handler *ctxt) -{ - ctxt->client->handler = 0; - kfree(ctxt); -} - - -static unsigned int pvr2_tuner_describe(struct pvr2_tuner_handler *ctxt,char *buf,unsigned int cnt) -{ - return scnprintf(buf,cnt,"handler: pvrusb2-tuner"); -} - - -const static struct pvr2_i2c_handler_functions tuner_funcs = { - .detach = (void (*)(void *))pvr2_tuner_detach, - .check = (int (*)(void *))tuner_check, - .update = (void (*)(void *))tuner_update, - .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_tuner_describe, -}; - - -int pvr2_i2c_tuner_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) -{ - struct pvr2_tuner_handler *ctxt; - if (cp->handler) return 0; - - ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); - if (!ctxt) return 0; - memset(ctxt,0,sizeof(*ctxt)); - - ctxt->i2c_handler.func_data = ctxt; - ctxt->i2c_handler.func_table = &tuner_funcs; - ctxt->type_update_fl = !0; - ctxt->client = cp; - ctxt->hdw = hdw; - cp->handler = &ctxt->i2c_handler; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tuner handler set up", - cp->client->addr); - return !0; -} - - - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.h deleted file mode 100644 index 556f12aa9160..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-tuner.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_TUNER_H -#define __PVRUSB2_TUNER_H - -#include "pvrusb2-i2c-core.h" - -int pvr2_i2c_tuner_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); - -#endif /* __PVRUSB2_TUNER_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-util.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-util.h deleted file mode 100644 index e53aee416f56..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-util.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_UTIL_H -#define __PVRUSB2_UTIL_H - -#define PVR2_DECOMPOSE_LE(t,i,d) \ - do { \ - (t)[i] = (d) & 0xff;\ - (t)[i+1] = ((d) >> 8) & 0xff;\ - (t)[i+2] = ((d) >> 16) & 0xff;\ - (t)[i+3] = ((d) >> 24) & 0xff;\ - } while(0) - -#define PVR2_DECOMPOSE_BE(t,i,d) \ - do { \ - (t)[i+3] = (d) & 0xff;\ - (t)[i+2] = ((d) >> 8) & 0xff;\ - (t)[i+1] = ((d) >> 16) & 0xff;\ - (t)[i] = ((d) >> 24) & 0xff;\ - } while(0) - -#define PVR2_COMPOSE_LE(t,i) \ - ((((u32)((t)[i+3])) << 24) | \ - (((u32)((t)[i+2])) << 16) | \ - (((u32)((t)[i+1])) << 8) | \ - ((u32)((t)[i]))) - -#define PVR2_COMPOSE_BE(t,i) \ - ((((u32)((t)[i])) << 24) | \ - (((u32)((t)[i+1])) << 16) | \ - (((u32)((t)[i+2])) << 8) | \ - ((u32)((t)[i+3]))) - - -#endif /* __PVRUSB2_UTIL_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c deleted file mode 100644 index 961951010c27..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * 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 "pvrusb2-context.h" -#include "pvrusb2-hdw.h" -#include "pvrusb2.h" -#include "pvrusb2-debug.h" -#include "pvrusb2-v4l2.h" -#include "pvrusb2-ioread.h" -#include -#include - -struct pvr2_v4l2_dev; -struct pvr2_v4l2_fh; -struct pvr2_v4l2; - -/* V4L no longer provide the ability to set / get a private context pointer - (i.e. video_get_drvdata / video_set_drvdata), which means we have to - concoct our own context locating mechanism. Supposedly this is intended - to simplify driver implementation. It's not clear to me how that can - possibly be true. Our solution here is to maintain a lookup table of - our context instances, indexed by the minor device number of the V4L - device. See pvr2_v4l2_open() for some implications of this approach. */ -static struct pvr2_v4l2_dev *devices[256]; -static DEFINE_MUTEX(device_lock); - -struct pvr2_v4l2_dev { - struct pvr2_v4l2 *v4lp; - struct video_device *vdev; - struct pvr2_context_stream *stream; - int ctxt_idx; - enum pvr2_config config; -}; - -struct pvr2_v4l2_fh { - struct pvr2_channel channel; - struct pvr2_v4l2_dev *dev_info; - enum v4l2_priority prio; - struct pvr2_ioread *rhp; - struct file *file; - struct pvr2_v4l2 *vhead; - struct pvr2_v4l2_fh *vnext; - struct pvr2_v4l2_fh *vprev; - wait_queue_head_t wait_data; - int fw_mode_flag; -}; - -struct pvr2_v4l2 { - struct pvr2_channel channel; - struct pvr2_v4l2_fh *vfirst; - struct pvr2_v4l2_fh *vlast; - - struct v4l2_prio_state prio; - - /* streams */ - struct pvr2_v4l2_dev video_dev; -}; - -static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1}; -module_param_array(video_nr, int, NULL, 0444); -MODULE_PARM_DESC(video_nr, "Offset for device's minor"); - -struct v4l2_capability pvr_capability ={ - .driver = "pvrusb2", - .card = "Hauppauge WinTV pvr-usb2", - .bus_info = "usb", - .version = KERNEL_VERSION(0,8,0), - .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE | - V4L2_CAP_TUNER | V4L2_CAP_AUDIO | - V4L2_CAP_READWRITE), - .reserved = {0,0,0,0} -}; - -static struct v4l2_tuner pvr_v4l2_tuners[]= { - { - .index = 0, - .name = "TV Tuner", - .type = V4L2_TUNER_ANALOG_TV, - .capability = (V4L2_TUNER_CAP_NORM | - V4L2_TUNER_CAP_STEREO | - V4L2_TUNER_CAP_LANG1 | - V4L2_TUNER_CAP_LANG2), - .rangelow = 0, - .rangehigh = 0, - .rxsubchans = V4L2_TUNER_SUB_STEREO, - .audmode = V4L2_TUNER_MODE_STEREO, - .signal = 0, - .afc = 0, - .reserved = {0,0,0,0} - } -}; - -struct v4l2_fmtdesc pvr_fmtdesc [] = { - { - .index = 0, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .flags = V4L2_FMT_FLAG_COMPRESSED, - .description = "MPEG1/2", - // This should really be V4L2_PIX_FMT_MPEG, but xawtv - // breaks when I do that. - .pixelformat = 0, // V4L2_PIX_FMT_MPEG, - .reserved = { 0, 0, 0, 0 } - } -}; - -#define PVR_FORMAT_PIX 0 -#define PVR_FORMAT_VBI 1 - -struct v4l2_format pvr_format [] = { - [PVR_FORMAT_PIX] = { - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .fmt = { - .pix = { - .width = 720, - .height = 576, - // This should really be V4L2_PIX_FMT_MPEG, - // but xawtv breaks when I do that. - .pixelformat = 0, // V4L2_PIX_FMT_MPEG, - .field = V4L2_FIELD_INTERLACED, - .bytesperline = 0, // doesn't make sense - // here - //FIXME : Don't know what to put here... - .sizeimage = (32*1024), - .colorspace = 0, // doesn't make sense here - .priv = 0 - } - } - }, - [PVR_FORMAT_VBI] = { - .type = V4L2_BUF_TYPE_VBI_CAPTURE, - .fmt = { - .vbi = { - .sampling_rate = 27000000, - .offset = 248, - .samples_per_line = 1443, - .sample_format = V4L2_PIX_FMT_GREY, - .start = { 0, 0 }, - .count = { 0, 0 }, - .flags = 0, - .reserved = { 0, 0 } - } - } - } -}; - -/* - * pvr_ioctl() - * - * This is part of Video 4 Linux API. The procedure handles ioctl() calls. - * - */ -static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - struct pvr2_v4l2 *vp = fh->vhead; - struct pvr2_v4l2_dev *dev_info = fh->dev_info; - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - int ret = -EINVAL; - - if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { - v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd); - } - - if (!pvr2_hdw_dev_ok(hdw)) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, - "ioctl failed - bad or no context"); - return -EFAULT; - } - - /* check priority */ - switch (cmd) { - case VIDIOC_S_CTRL: - case VIDIOC_S_STD: - case VIDIOC_S_INPUT: - case VIDIOC_S_TUNER: - case VIDIOC_S_FREQUENCY: - ret = v4l2_prio_check(&vp->prio, &fh->prio); - if (ret) - return ret; - } - - switch (cmd) { - case VIDIOC_QUERYCAP: - { - struct v4l2_capability *cap = arg; - - memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability)); - - ret = 0; - break; - } - - case VIDIOC_G_PRIORITY: - { - enum v4l2_priority *p = arg; - - *p = v4l2_prio_max(&vp->prio); - ret = 0; - break; - } - - case VIDIOC_S_PRIORITY: - { - enum v4l2_priority *prio = arg; - - ret = v4l2_prio_change(&vp->prio, &fh->prio, *prio); - break; - } - - case VIDIOC_ENUMSTD: - { - struct v4l2_standard *vs = (struct v4l2_standard *)arg; - int idx = vs->index; - ret = pvr2_hdw_get_stdenum_value(hdw,vs,idx+1); - break; - } - - case VIDIOC_G_STD: - { - int val = 0; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),&val); - *(v4l2_std_id *)arg = val; - break; - } - - case VIDIOC_S_STD: - { - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR), - *(v4l2_std_id *)arg); - break; - } - - case VIDIOC_ENUMINPUT: - { - struct pvr2_ctrl *cptr; - struct v4l2_input *vi = (struct v4l2_input *)arg; - struct v4l2_input tmp; - unsigned int cnt; - - cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); - - memset(&tmp,0,sizeof(tmp)); - tmp.index = vi->index; - ret = 0; - switch (vi->index) { - case PVR2_CVAL_INPUT_TV: - case PVR2_CVAL_INPUT_RADIO: - tmp.type = V4L2_INPUT_TYPE_TUNER; - break; - case PVR2_CVAL_INPUT_SVIDEO: - case PVR2_CVAL_INPUT_COMPOSITE: - tmp.type = V4L2_INPUT_TYPE_CAMERA; - break; - default: - ret = -EINVAL; - break; - } - if (ret < 0) break; - - cnt = 0; - pvr2_ctrl_get_valname(cptr,vi->index, - tmp.name,sizeof(tmp.name)-1,&cnt); - tmp.name[cnt] = 0; - - /* Don't bother with audioset, since this driver currently - always switches the audio whenever the video is - switched. */ - - /* Handling std is a tougher problem. It doesn't make - sense in cases where a device might be multi-standard. - We could just copy out the current value for the - standard, but it can change over time. For now just - leave it zero. */ - - memcpy(vi, &tmp, sizeof(tmp)); - - ret = 0; - break; - } - - case VIDIOC_G_INPUT: - { - struct pvr2_ctrl *cptr; - struct v4l2_input *vi = (struct v4l2_input *)arg; - int val; - cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT); - val = 0; - ret = pvr2_ctrl_get_value(cptr,&val); - vi->index = val; - break; - } - - case VIDIOC_S_INPUT: - { - struct v4l2_input *vi = (struct v4l2_input *)arg; - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT), - vi->index); - break; - } - - case VIDIOC_ENUMAUDIO: - { - ret = -EINVAL; - break; - } - - case VIDIOC_G_AUDIO: - { - ret = -EINVAL; - break; - } - - case VIDIOC_S_AUDIO: - { - ret = -EINVAL; - break; - } - case VIDIOC_G_TUNER: - { - struct v4l2_tuner *vt = (struct v4l2_tuner *)arg; - unsigned int status_mask; - int val; - if (vt->index !=0) break; - - status_mask = pvr2_hdw_get_signal_status(hdw); - - memcpy(vt, &pvr_v4l2_tuners[vt->index], - sizeof(struct v4l2_tuner)); - - vt->signal = 0; - if (status_mask & PVR2_SIGNAL_OK) { - if (status_mask & PVR2_SIGNAL_STEREO) { - vt->rxsubchans = V4L2_TUNER_SUB_STEREO; - } else { - vt->rxsubchans = V4L2_TUNER_SUB_MONO; - } - if (status_mask & PVR2_SIGNAL_SAP) { - vt->rxsubchans |= (V4L2_TUNER_SUB_LANG1 | - V4L2_TUNER_SUB_LANG2); - } - vt->signal = 65535; - } - - val = 0; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE), - &val); - vt->audmode = val; - break; - } - - case VIDIOC_S_TUNER: - { - struct v4l2_tuner *vt=(struct v4l2_tuner *)arg; - - if (vt->index != 0) - break; - - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE), - vt->audmode); - } - - case VIDIOC_S_FREQUENCY: - { - const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg; - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY), - vf->frequency * 62500); - break; - } - - case VIDIOC_G_FREQUENCY: - { - struct v4l2_frequency *vf = (struct v4l2_frequency *)arg; - int val = 0; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY), - &val); - val /= 62500; - vf->frequency = val; - break; - } - - case VIDIOC_ENUM_FMT: - { - struct v4l2_fmtdesc *fd = (struct v4l2_fmtdesc *)arg; - - /* Only one format is supported : mpeg.*/ - if (fd->index != 0) - break; - - memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc)); - ret = 0; - break; - } - - case VIDIOC_G_FMT: - { - struct v4l2_format *vf = (struct v4l2_format *)arg; - int val; - switch(vf->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - memcpy(vf, &pvr_format[PVR_FORMAT_PIX], - sizeof(struct v4l2_format)); - val = 0; - pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES), - &val); - vf->fmt.pix.width = val; - val = 0; - pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES), - &val); - vf->fmt.pix.height = val; - ret = 0; - break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - // ????? Still need to figure out to do VBI correctly - ret = -EINVAL; - break; - default: - ret = -EINVAL; - break; - } - break; - } - - case VIDIOC_TRY_FMT: - case VIDIOC_S_FMT: - { - struct v4l2_format *vf = (struct v4l2_format *)arg; - - ret = 0; - switch(vf->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: { - int h = vf->fmt.pix.height; - int w = vf->fmt.pix.width; - - if (h < 200) { - h = 200; - } else if (h > 625) { - h = 625; - } - if (w < 320) { - w = 320; - } else if (w > 720) { - w = 720; - } - - memcpy(vf, &pvr_format[PVR_FORMAT_PIX], - sizeof(struct v4l2_format)); - vf->fmt.pix.width = w; - vf->fmt.pix.height = h; - - if (cmd == VIDIOC_S_FMT) { - pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, - PVR2_CID_HRES), - vf->fmt.pix.width); - pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id(hdw, - PVR2_CID_VRES), - vf->fmt.pix.height); - } - } break; - case V4L2_BUF_TYPE_VBI_CAPTURE: - // ????? Still need to figure out to do VBI correctly - ret = -EINVAL; - break; - default: - ret = -EINVAL; - break; - } - break; - } - - case VIDIOC_STREAMON: - { - ret = pvr2_hdw_set_stream_type(hdw,dev_info->config); - if (ret < 0) return ret; - ret = pvr2_hdw_set_streaming(hdw,!0); - break; - } - - case VIDIOC_STREAMOFF: - { - ret = pvr2_hdw_set_streaming(hdw,0); - break; - } - - case VIDIOC_QUERYCTRL: - { - struct pvr2_ctrl *cptr; - struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg; - ret = 0; - if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) { - cptr = pvr2_hdw_get_ctrl_nextv4l( - hdw,(vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL)); - if (cptr) vc->id = pvr2_ctrl_get_v4lid(cptr); - } else { - cptr = pvr2_hdw_get_ctrl_v4l(hdw,vc->id); - } - if (!cptr) { - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "QUERYCTRL id=0x%x not implemented here", - vc->id); - ret = -EINVAL; - break; - } - - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "QUERYCTRL id=0x%x mapping name=%s (%s)", - vc->id,pvr2_ctrl_get_name(cptr), - pvr2_ctrl_get_desc(cptr)); - strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name)); - vc->flags = pvr2_ctrl_get_v4lflags(cptr); - vc->default_value = pvr2_ctrl_get_def(cptr); - switch (pvr2_ctrl_get_type(cptr)) { - case pvr2_ctl_enum: - vc->type = V4L2_CTRL_TYPE_MENU; - vc->minimum = 0; - vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1; - vc->step = 1; - break; - case pvr2_ctl_bool: - vc->type = V4L2_CTRL_TYPE_BOOLEAN; - vc->minimum = 0; - vc->maximum = 1; - vc->step = 1; - break; - case pvr2_ctl_int: - vc->type = V4L2_CTRL_TYPE_INTEGER; - vc->minimum = pvr2_ctrl_get_min(cptr); - vc->maximum = pvr2_ctrl_get_max(cptr); - vc->step = 1; - break; - default: - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "QUERYCTRL id=0x%x name=%s not mappable", - vc->id,pvr2_ctrl_get_name(cptr)); - ret = -EINVAL; - break; - } - break; - } - - case VIDIOC_QUERYMENU: - { - struct v4l2_querymenu *vm = (struct v4l2_querymenu *)arg; - unsigned int cnt = 0; - ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw,vm->id), - vm->index, - vm->name,sizeof(vm->name)-1, - &cnt); - vm->name[cnt] = 0; - break; - } - - case VIDIOC_G_CTRL: - { - struct v4l2_control *vc = (struct v4l2_control *)arg; - int val = 0; - ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id), - &val); - vc->value = val; - break; - } - - case VIDIOC_S_CTRL: - { - struct v4l2_control *vc = (struct v4l2_control *)arg; - ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id), - vc->value); - break; - } - - case VIDIOC_G_EXT_CTRLS: - { - struct v4l2_ext_controls *ctls = - (struct v4l2_ext_controls *)arg; - struct v4l2_ext_control *ctrl; - unsigned int idx; - int val; - for (idx = 0; idx < ctls->count; idx++) { - ctrl = ctls->controls + idx; - ret = pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id),&val); - if (ret) { - ctls->error_idx = idx; - break; - } - /* Ensure that if read as a 64 bit value, the user - will still get a hopefully sane value */ - ctrl->value64 = 0; - ctrl->value = val; - } - break; - } - - case VIDIOC_S_EXT_CTRLS: - { - struct v4l2_ext_controls *ctls = - (struct v4l2_ext_controls *)arg; - struct v4l2_ext_control *ctrl; - unsigned int idx; - for (idx = 0; idx < ctls->count; idx++) { - ctrl = ctls->controls + idx; - ret = pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id), - ctrl->value); - if (ret) { - ctls->error_idx = idx; - break; - } - } - break; - } - - case VIDIOC_TRY_EXT_CTRLS: - { - struct v4l2_ext_controls *ctls = - (struct v4l2_ext_controls *)arg; - struct v4l2_ext_control *ctrl; - struct pvr2_ctrl *pctl; - unsigned int idx; - /* For the moment just validate that the requested control - actually exists. */ - for (idx = 0; idx < ctls->count; idx++) { - ctrl = ctls->controls + idx; - pctl = pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id); - if (!pctl) { - ret = -EINVAL; - ctls->error_idx = idx; - break; - } - } - break; - } - - case VIDIOC_LOG_STATUS: - { - pvr2_hdw_trigger_module_log(hdw); - ret = 0; - break; - } - - default : - ret = v4l_compat_translate_ioctl(inode,file,cmd, - arg,pvr2_v4l2_do_ioctl); - } - - pvr2_hdw_commit_ctl(hdw); - - if (ret < 0) { - if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl failure, ret=%d",ret); - } else { - if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl failure, ret=%d" - " command was:",ret); - v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw), - cmd); - } - } - } else { - pvr2_trace(PVR2_TRACE_V4LIOCTL, - "pvr2_v4l2_do_ioctl complete, ret=%d (0x%x)", - ret,ret); - } - return ret; -} - - -static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) -{ - pvr2_trace(PVR2_TRACE_INIT, - "unregistering device video%d [%s]", - dip->vdev->minor,pvr2_config_get_name(dip->config)); - if (dip->ctxt_idx >= 0) { - mutex_lock(&device_lock); - devices[dip->ctxt_idx] = NULL; - dip->ctxt_idx = -1; - mutex_unlock(&device_lock); - } - video_unregister_device(dip->vdev); -} - - -static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp) -{ - pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,-1); - pvr2_v4l2_dev_destroy(&vp->video_dev); - - pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp); - pvr2_channel_done(&vp->channel); - kfree(vp); -} - - -void pvr2_v4l2_internal_check(struct pvr2_channel *chp) -{ - struct pvr2_v4l2 *vp; - vp = container_of(chp,struct pvr2_v4l2,channel); - if (!vp->channel.mc_head->disconnect_flag) return; - if (vp->vfirst) return; - pvr2_v4l2_destroy_no_lock(vp); -} - - -int pvr2_v4l2_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - -/* Temporary hack : use ivtv api until a v4l2 one is available. */ -#define IVTV_IOC_G_CODEC 0xFFEE7703 -#define IVTV_IOC_S_CODEC 0xFFEE7704 - if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0; - return video_usercopy(inode, file, cmd, arg, pvr2_v4l2_do_ioctl); -} - - -int pvr2_v4l2_release(struct inode *inode, struct file *file) -{ - struct pvr2_v4l2_fh *fhp = file->private_data; - struct pvr2_v4l2 *vp = fhp->vhead; - struct pvr2_context *mp = fhp->vhead->channel.mc_head; - - pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release"); - - if (fhp->rhp) { - struct pvr2_stream *sp; - struct pvr2_hdw *hdw; - hdw = fhp->channel.mc_head->hdw; - pvr2_hdw_set_streaming(hdw,0); - sp = pvr2_ioread_get_stream(fhp->rhp); - if (sp) pvr2_stream_set_callback(sp,0,0); - pvr2_ioread_destroy(fhp->rhp); - fhp->rhp = 0; - } - v4l2_prio_close(&vp->prio, &fhp->prio); - file->private_data = NULL; - - pvr2_context_enter(mp); do { - if (fhp->vnext) { - fhp->vnext->vprev = fhp->vprev; - } else { - vp->vlast = fhp->vprev; - } - if (fhp->vprev) { - fhp->vprev->vnext = fhp->vnext; - } else { - vp->vfirst = fhp->vnext; - } - fhp->vnext = 0; - fhp->vprev = 0; - fhp->vhead = 0; - pvr2_channel_done(&fhp->channel); - pvr2_trace(PVR2_TRACE_STRUCT, - "Destroying pvr_v4l2_fh id=%p",fhp); - kfree(fhp); - if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) { - pvr2_v4l2_destroy_no_lock(vp); - } - } while (0); pvr2_context_exit(mp); - return 0; -} - - -int pvr2_v4l2_open(struct inode *inode, struct file *file) -{ - struct pvr2_v4l2_dev *dip = 0; /* Our own context pointer */ - struct pvr2_v4l2_fh *fhp; - struct pvr2_v4l2 *vp; - struct pvr2_hdw *hdw; - - mutex_lock(&device_lock); - /* MCI 7-Jun-2006 Even though we're just doing what amounts to an - atomic read of the device mapping array here, we still need the - mutex. The problem is that there is a tiny race possible when - we register the device. We can't update the device mapping - array until after the device has been registered, owing to the - fact that we can't know the minor device number until after the - registration succeeds. And if another thread tries to open the - device in the window of time after registration but before the - map is updated, then it will get back an erroneous null pointer - and the open will result in a spurious failure. The only way to - prevent that is to (a) be inside the mutex here before we access - the array, and (b) cover the entire registration process later - on with this same mutex. Thus if we get inside the mutex here, - then we can be assured that the registration process actually - completed correctly. This is an unhappy complication from the - use of global data in a driver that lives in a preemptible - environment. It sure would be nice if the video device itself - had a means for storing and retrieving a local context pointer. - Oh wait. It did. But now it's gone. Silly me. */ - { - unsigned int midx = iminor(file->f_dentry->d_inode); - if (midx < sizeof(devices)/sizeof(devices[0])) { - dip = devices[midx]; - } - } - mutex_unlock(&device_lock); - - if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */ - - vp = dip->v4lp; - hdw = vp->channel.hdw; - - pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open"); - - if (!pvr2_hdw_dev_ok(hdw)) { - pvr2_trace(PVR2_TRACE_OPEN_CLOSE, - "pvr2_v4l2_open: hardware not ready"); - return -EIO; - } - - fhp = kmalloc(sizeof(*fhp),GFP_KERNEL); - if (!fhp) { - return -ENOMEM; - } - memset(fhp,0,sizeof(*fhp)); - - init_waitqueue_head(&fhp->wait_data); - fhp->dev_info = dip; - - pvr2_context_enter(vp->channel.mc_head); do { - pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp); - pvr2_channel_init(&fhp->channel,vp->channel.mc_head); - fhp->vnext = 0; - fhp->vprev = vp->vlast; - if (vp->vlast) { - vp->vlast->vnext = fhp; - } else { - vp->vfirst = fhp; - } - vp->vlast = fhp; - fhp->vhead = vp; - } while (0); pvr2_context_exit(vp->channel.mc_head); - - fhp->file = file; - file->private_data = fhp; - v4l2_prio_open(&vp->prio,&fhp->prio); - - fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw); - - return 0; -} - - -static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp) -{ - wake_up(&fhp->wait_data); -} - -static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh) -{ - int ret; - struct pvr2_stream *sp; - struct pvr2_hdw *hdw; - if (fh->rhp) return 0; - - /* First read() attempt. Try to claim the stream and start - it... */ - if ((ret = pvr2_channel_claim_stream(&fh->channel, - fh->dev_info->stream)) != 0) { - /* Someone else must already have it */ - return ret; - } - - fh->rhp = pvr2_channel_create_mpeg_stream(fh->dev_info->stream); - if (!fh->rhp) { - pvr2_channel_claim_stream(&fh->channel,0); - return -ENOMEM; - } - - hdw = fh->channel.mc_head->hdw; - sp = fh->dev_info->stream->stream; - pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh); - pvr2_hdw_set_stream_type(hdw,fh->dev_info->config); - pvr2_hdw_set_streaming(hdw,!0); - ret = pvr2_ioread_set_enabled(fh->rhp,!0); - - return ret; -} - - -static ssize_t pvr2_v4l2_read(struct file *file, - char __user *buff, size_t count, loff_t *ppos) -{ - struct pvr2_v4l2_fh *fh = file->private_data; - int ret; - - if (fh->fw_mode_flag) { - struct pvr2_hdw *hdw = fh->channel.mc_head->hdw; - char *tbuf; - int c1,c2; - int tcnt = 0; - unsigned int offs = *ppos; - - tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL); - if (!tbuf) return -ENOMEM; - - while (count) { - c1 = count; - if (c1 > PAGE_SIZE) c1 = PAGE_SIZE; - c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1); - if (c2 < 0) { - tcnt = c2; - break; - } - if (!c2) break; - if (copy_to_user(buff,tbuf,c2)) { - tcnt = -EFAULT; - break; - } - offs += c2; - tcnt += c2; - buff += c2; - count -= c2; - *ppos += c2; - } - kfree(tbuf); - return tcnt; - } - - if (!fh->rhp) { - ret = pvr2_v4l2_iosetup(fh); - if (ret) { - return ret; - } - } - - for (;;) { - ret = pvr2_ioread_read(fh->rhp,buff,count); - if (ret >= 0) break; - if (ret != -EAGAIN) break; - if (file->f_flags & O_NONBLOCK) break; - /* Doing blocking I/O. Wait here. */ - ret = wait_event_interruptible( - fh->wait_data, - pvr2_ioread_avail(fh->rhp) >= 0); - if (ret < 0) break; - } - - return ret; -} - - -static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait) -{ - unsigned int mask = 0; - struct pvr2_v4l2_fh *fh = file->private_data; - int ret; - - if (fh->fw_mode_flag) { - mask |= POLLIN | POLLRDNORM; - return mask; - } - - if (!fh->rhp) { - ret = pvr2_v4l2_iosetup(fh); - if (ret) return POLLERR; - } - - poll_wait(file,&fh->wait_data,wait); - - if (pvr2_ioread_avail(fh->rhp) >= 0) { - mask |= POLLIN | POLLRDNORM; - } - - return mask; -} - - -static struct file_operations vdev_fops = { - .owner = THIS_MODULE, - .open = pvr2_v4l2_open, - .release = pvr2_v4l2_release, - .read = pvr2_v4l2_read, - .ioctl = pvr2_v4l2_ioctl, - .llseek = no_llseek, - .poll = pvr2_v4l2_poll, -}; - - -#define VID_HARDWARE_PVRUSB2 38 /* FIXME : need a good value */ - -static struct video_device vdev_template = { - .owner = THIS_MODULE, - .type = VID_TYPE_CAPTURE | VID_TYPE_TUNER, - .type2 = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE - | V4L2_CAP_TUNER | V4L2_CAP_AUDIO - | V4L2_CAP_READWRITE), - .hardware = VID_HARDWARE_PVRUSB2, - .fops = &vdev_fops, -}; - - -static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, - struct pvr2_v4l2 *vp, - enum pvr2_config cfg) -{ - int mindevnum; - int unit_number; - int v4l_type; - dip->v4lp = vp; - dip->config = cfg; - - - switch (cfg) { - case pvr2_config_mpeg: - v4l_type = VFL_TYPE_GRABBER; - dip->stream = &vp->channel.mc_head->video_stream; - break; - case pvr2_config_vbi: - v4l_type = VFL_TYPE_VBI; - break; - case pvr2_config_radio: - v4l_type = VFL_TYPE_RADIO; - break; - default: - /* Bail out (this should be impossible) */ - err("Failed to set up pvrusb2 v4l dev" - " due to unrecognized config"); - return; - } - - if (!dip->stream) { - err("Failed to set up pvrusb2 v4l dev" - " due to missing stream instance"); - return; - } - - dip->vdev = video_device_alloc(); - if (!dip->vdev) { - err("Alloc of pvrusb2 v4l video device failed"); - return; - } - - memcpy(dip->vdev,&vdev_template,sizeof(vdev_template)); - dip->vdev->release = video_device_release; - mutex_lock(&device_lock); - - mindevnum = -1; - unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw); - if ((unit_number >= 0) && (unit_number < PVR_NUM)) { - mindevnum = video_nr[unit_number]; - } - if ((video_register_device(dip->vdev, v4l_type, mindevnum) < 0) && - (video_register_device(dip->vdev, v4l_type, -1) < 0)) { - err("Failed to register pvrusb2 v4l video device"); - } else { - pvr2_trace(PVR2_TRACE_INIT, - "registered device video%d [%s]", - dip->vdev->minor,pvr2_config_get_name(dip->config)); - } - - if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) && - (devices[dip->vdev->minor] == NULL)) { - dip->ctxt_idx = dip->vdev->minor; - devices[dip->ctxt_idx] = dip; - } - mutex_unlock(&device_lock); - - pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw, - dip->vdev->minor); -} - - -struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp) -{ - struct pvr2_v4l2 *vp; - - vp = kmalloc(sizeof(*vp),GFP_KERNEL); - if (!vp) return vp; - memset(vp,0,sizeof(*vp)); - vp->video_dev.ctxt_idx = -1; - pvr2_channel_init(&vp->channel,mnp); - pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp); - - vp->channel.check_func = pvr2_v4l2_internal_check; - - /* register streams */ - pvr2_v4l2_dev_init(&vp->video_dev,vp,pvr2_config_mpeg); - - - return vp; -} - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.h deleted file mode 100644 index 9a995e2d2256..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-v4l2.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef __PVRUSB2_V4L2_H -#define __PVRUSB2_V4L2_H - -#include "pvrusb2-context.h" - -struct pvr2_v4l2; - -struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *); - -#endif /* __PVRUSB2_V4L2_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 75 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c deleted file mode 100644 index e4ec7f25194c..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * 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 - * - */ - -/* - - This source file is specifically designed to interface with the - saa711x support that is available in the v4l available starting - with linux 2.6.15. - -*/ - -#include "pvrusb2-video-v4l.h" -#include "pvrusb2-i2c-cmd-v4l2.h" - - -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include -#include -#include -#include -#include - -struct pvr2_v4l_decoder { - struct pvr2_i2c_handler handler; - struct pvr2_decoder_ctrl ctrl; - struct pvr2_i2c_client *client; - struct pvr2_hdw *hdw; - unsigned long stale_mask; -}; - - -static void set_input(struct pvr2_v4l_decoder *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - struct v4l2_routing route; - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val); - switch(hdw->input_val) { - case PVR2_CVAL_INPUT_TV: - route.input = SAA7115_COMPOSITE4; - break; - case PVR2_CVAL_INPUT_COMPOSITE: - route.input = SAA7115_COMPOSITE5; - break; - case PVR2_CVAL_INPUT_SVIDEO: - route.input = SAA7115_SVIDEO2; - break; - case PVR2_CVAL_INPUT_RADIO: - // ????? No idea yet what to do here - default: - return; - } - route.output = 0; - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route); -} - - -static int check_input(struct pvr2_v4l_decoder *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - return hdw->input_dirty != 0; -} - - -static void set_audio(struct pvr2_v4l_decoder *ctxt) -{ - u32 val; - struct pvr2_hdw *hdw = ctxt->hdw; - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_audio %d", - hdw->srate_val); - switch (hdw->srate_val) { - default: - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000: - val = 48000; - break; - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100: - val = 44100; - break; - case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000: - val = 32000; - break; - } - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val); -} - - -static int check_audio(struct pvr2_v4l_decoder *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - return hdw->srate_dirty != 0; -} - - -struct pvr2_v4l_decoder_ops { - void (*update)(struct pvr2_v4l_decoder *); - int (*check)(struct pvr2_v4l_decoder *); -}; - - -static const struct pvr2_v4l_decoder_ops decoder_ops[] = { - { .update = set_input, .check = check_input}, - { .update = set_audio, .check = check_audio}, -}; - - -static void decoder_detach(struct pvr2_v4l_decoder *ctxt) -{ - ctxt->client->handler = 0; - ctxt->hdw->decoder_ctrl = 0; - kfree(ctxt); -} - - -static int decoder_check(struct pvr2_v4l_decoder *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); - idx++) { - msk = 1 << idx; - if (ctxt->stale_mask & msk) continue; - if (decoder_ops[idx].check(ctxt)) { - ctxt->stale_mask |= msk; - } - } - return ctxt->stale_mask != 0; -} - - -static void decoder_update(struct pvr2_v4l_decoder *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(decoder_ops)/sizeof(decoder_ops[0]); - idx++) { - msk = 1 << idx; - if (!(ctxt->stale_mask & msk)) continue; - ctxt->stale_mask &= ~msk; - decoder_ops[idx].update(ctxt); - } -} - - -static int decoder_detect(struct pvr2_i2c_client *cp) -{ - /* Attempt to query the decoder - let's see if it will answer */ - struct v4l2_tuner vt; - int ret; - - memset(&vt,0,sizeof(vt)); - ret = pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&vt); - return ret == 0; /* Return true if it answered */ -} - - -static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl) -{ - pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl); - pvr2_v4l2_cmd_stream(ctxt->client,fl); -} - - -static int decoder_is_tuned(struct pvr2_v4l_decoder *ctxt) -{ - struct v4l2_tuner vt; - int ret; - - memset(&vt,0,sizeof(vt)); - ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_G_TUNER,&vt); - if (ret < 0) return -EINVAL; - return vt.signal ? 1 : 0; -} - - -static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt) -{ - return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l"); -} - - -const static struct pvr2_i2c_handler_functions hfuncs = { - .detach = (void (*)(void *))decoder_detach, - .check = (int (*)(void *))decoder_check, - .update = (void (*)(void *))decoder_update, - .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe, -}; - - -int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw, - struct pvr2_i2c_client *cp) -{ - struct pvr2_v4l_decoder *ctxt; - - if (hdw->decoder_ctrl) return 0; - if (cp->handler) return 0; - if (!decoder_detect(cp)) return 0; - - ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); - if (!ctxt) return 0; - memset(ctxt,0,sizeof(*ctxt)); - - ctxt->handler.func_data = ctxt; - ctxt->handler.func_table = &hfuncs; - ctxt->ctrl.ctxt = ctxt; - ctxt->ctrl.detach = (void (*)(void *))decoder_detach; - ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable; - ctxt->ctrl.tuned = (int (*)(void *))decoder_is_tuned; - ctxt->client = cp; - ctxt->hdw = hdw; - ctxt->stale_mask = (1 << (sizeof(decoder_ops)/ - sizeof(decoder_ops[0]))) - 1; - hdw->decoder_ctrl = &ctxt->ctrl; - cp->handler = &ctxt->handler; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up", - cp->client->addr); - return !0; -} - - - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h deleted file mode 100644 index 2b917fda02e4..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_VIDEO_V4L_H -#define __PVRUSB2_VIDEO_V4L_H - -/* - - This module connects the pvrusb2 driver to the I2C chip level - driver which handles device video processing. This interface is - used internally by the driver; higher level code should only - interact through the interface provided by pvrusb2-hdw.h. - -*/ - - - -#include "pvrusb2-i2c-core.h" - -int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); - - -#endif /* __PVRUSB2_VIDEO_V4L_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.c deleted file mode 100644 index fcad346e3955..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * 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 - * - */ - -/* - - This source file is specifically designed to interface with the - wm8775. - -*/ - -#include "pvrusb2-wm8775.h" -#include "pvrusb2-i2c-cmd-v4l2.h" - - -#include "pvrusb2-hdw-internal.h" -#include "pvrusb2-debug.h" -#include -#include -#include -#include - -struct pvr2_v4l_wm8775 { - struct pvr2_i2c_handler handler; - struct pvr2_i2c_client *client; - struct pvr2_hdw *hdw; - unsigned long stale_mask; -}; - - -static void set_input(struct pvr2_v4l_wm8775 *ctxt) -{ - struct v4l2_routing route; - struct pvr2_hdw *hdw = ctxt->hdw; - int msk = 0; - - memset(&route,0,sizeof(route)); - - pvr2_trace(PVR2_TRACE_CHIPS,"i2c wm8775 set_input(val=%d msk=0x%x)", - hdw->input_val,msk); - - // Always point to input #1 no matter what - route.input = 2; - pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route); -} - -static int check_input(struct pvr2_v4l_wm8775 *ctxt) -{ - struct pvr2_hdw *hdw = ctxt->hdw; - return hdw->input_dirty != 0; -} - - -struct pvr2_v4l_wm8775_ops { - void (*update)(struct pvr2_v4l_wm8775 *); - int (*check)(struct pvr2_v4l_wm8775 *); -}; - - -static const struct pvr2_v4l_wm8775_ops wm8775_ops[] = { - { .update = set_input, .check = check_input}, -}; - - -static unsigned int wm8775_describe(struct pvr2_v4l_wm8775 *ctxt, - char *buf,unsigned int cnt) -{ - return scnprintf(buf,cnt,"handler: pvrusb2-wm8775"); -} - - -static void wm8775_detach(struct pvr2_v4l_wm8775 *ctxt) -{ - ctxt->client->handler = 0; - kfree(ctxt); -} - - -static int wm8775_check(struct pvr2_v4l_wm8775 *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(wm8775_ops)/sizeof(wm8775_ops[0]); - idx++) { - msk = 1 << idx; - if (ctxt->stale_mask & msk) continue; - if (wm8775_ops[idx].check(ctxt)) { - ctxt->stale_mask |= msk; - } - } - return ctxt->stale_mask != 0; -} - - -static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt) -{ - unsigned long msk; - unsigned int idx; - - for (idx = 0; idx < sizeof(wm8775_ops)/sizeof(wm8775_ops[0]); - idx++) { - msk = 1 << idx; - if (!(ctxt->stale_mask & msk)) continue; - ctxt->stale_mask &= ~msk; - wm8775_ops[idx].update(ctxt); - } -} - - -const static struct pvr2_i2c_handler_functions hfuncs = { - .detach = (void (*)(void *))wm8775_detach, - .check = (int (*)(void *))wm8775_check, - .update = (void (*)(void *))wm8775_update, - .describe = (unsigned int (*)(void *,char *,unsigned int))wm8775_describe, -}; - - -int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp) -{ - struct pvr2_v4l_wm8775 *ctxt; - - if (cp->handler) return 0; - - ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL); - if (!ctxt) return 0; - memset(ctxt,0,sizeof(*ctxt)); - - ctxt->handler.func_data = ctxt; - ctxt->handler.func_table = &hfuncs; - ctxt->client = cp; - ctxt->hdw = hdw; - ctxt->stale_mask = (1 << (sizeof(wm8775_ops)/ - sizeof(wm8775_ops[0]))) - 1; - cp->handler = &ctxt->handler; - pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x wm8775 V4L2 handler set up", - cp->client->addr); - return !0; -} - - - - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.h deleted file mode 100644 index 8aaeff4e1e20..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2-wm8775.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_WM8775_H -#define __PVRUSB2_WM8775_H - -/* - - This module connects the pvrusb2 driver to the I2C chip level - driver which performs analog -> digital audio conversion for - external audio inputs. This interface is used internally by the - driver; higher level code should only interact through the - interface provided by pvrusb2-hdw.h. - -*/ - - - -#include "pvrusb2-i2c-core.h" - -int pvr2_i2c_wm8775_setup(struct pvr2_hdw *,struct pvr2_i2c_client *); - - -#endif /* __PVRUSB2_WM8775_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/pvrusb2/pvrusb2.h b/trunk/drivers/media/video/pvrusb2/pvrusb2.h deleted file mode 100644 index 074533e9c21e..000000000000 --- a/trunk/drivers/media/video/pvrusb2/pvrusb2.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * - * $Id$ - * - * Copyright (C) 2005 Mike Isely - * Copyright (C) 2004 Aurelien Alleaume - * - * 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 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __PVRUSB2_H -#define __PVRUSB2_H - -/* Maximum number of pvrusb2 instances we can track at once. You - might want to increase this - however the driver operation will not - be impaired if it is too small. Instead additional units just - won't have an ID assigned and it might not be possible to specify - module paramters for those extra units. */ -#define PVR_NUM 20 - -#endif /* __PVRUSB2_H */ - -/* - Stuff for Emacs to see, in order to encourage consistent editing style: - *** Local Variables: *** - *** mode: c *** - *** fill-column: 70 *** - *** tab-width: 8 *** - *** c-basic-offset: 8 *** - *** End: *** - */ diff --git a/trunk/drivers/media/video/saa7134/saa6752hs.c b/trunk/drivers/media/video/saa7134/saa6752hs.c index afc8f352b8e7..de7b9e6e932a 100644 --- a/trunk/drivers/media/video/saa7134/saa6752hs.c +++ b/trunk/drivers/media/video/saa7134/saa6752hs.c @@ -432,10 +432,10 @@ static void saa6752hs_old_set_params(struct i2c_client* client, } static int handle_ctrl(struct saa6752hs_mpeg_params *params, - struct v4l2_ext_control *ctrl, unsigned int cmd) + struct v4l2_ext_control *ctrl, int cmd) { int old = 0, new; - int set = (cmd == VIDIOC_S_EXT_CTRLS); + int set = cmd == VIDIOC_S_EXT_CTRLS; new = ctrl->value; switch (ctrl->id) { diff --git a/trunk/drivers/media/video/stradis.c b/trunk/drivers/media/video/stradis.c index c18b31d9928c..6be9c1131e1f 100644 --- a/trunk/drivers/media/video/stradis.c +++ b/trunk/drivers/media/video/stradis.c @@ -2190,7 +2190,7 @@ static struct pci_driver stradis_driver = { .remove = __devexit_p(stradis_remove) }; -static int __init stradis_init(void) +int __init stradis_init(void) { int retval; @@ -2203,7 +2203,7 @@ static int __init stradis_init(void) return retval; } -static void __exit stradis_exit(void) +void __exit stradis_exit(void) { pci_unregister_driver(&stradis_driver); printk(KERN_INFO "stradis: module cleanup complete\n"); diff --git a/trunk/drivers/media/video/tda9887.c b/trunk/drivers/media/video/tda9887.c index 2fadabf99688..b6ae969563b2 100644 --- a/trunk/drivers/media/video/tda9887.c +++ b/trunk/drivers/media/video/tda9887.c @@ -22,11 +22,11 @@ */ #define tda9887_info(fmt, arg...) do {\ - printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.name, \ + printk(KERN_INFO "%s %d-%04x (tda9887): " fmt, t->i2c.name, \ i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) #define tda9887_dbg(fmt, arg...) do {\ if (tuner_debug) \ - printk(KERN_INFO "%s %d-%04x: " fmt, t->i2c.name, \ + printk(KERN_INFO "%s %d-%04x (tda9887): " fmt, t->i2c.name, \ i2c_adapter_id(t->i2c.adapter), t->i2c.addr , ##arg); } while (0) @@ -84,7 +84,8 @@ struct tvnorm { #define cAudioGain6 0x80 // bit c7 #define cTopMask 0x1f // bit c0:4 -#define cTopDefault 0x10 // 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 @@ -122,7 +123,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis50 | - cTopDefault), + cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_5_5 | cVideoIF_38_90 ), @@ -133,7 +134,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis50 | - cTopDefault), + cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_6_0 | cVideoIF_38_90 ), @@ -144,7 +145,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis50 | - cTopDefault), + cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_6_5 | cVideoIF_38_90 ), @@ -155,7 +156,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis75 | - cTopDefault), + cTopNtscRadioDefault), .e = ( cGating_36 | cAudioIF_4_5 | cVideoIF_45_75 ), @@ -164,7 +165,7 @@ static struct tvnorm tvnorms[] = { .name = "SECAM-BGH", .b = ( cPositiveAmTV | cQSS ), - .c = ( cTopDefault), + .c = ( cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_5_5 | cVideoIF_38_90 ), @@ -173,7 +174,7 @@ static struct tvnorm tvnorms[] = { .name = "SECAM-L", .b = ( cPositiveAmTV | cQSS ), - .c = ( cTopDefault), + .c = ( cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_6_5 | cVideoIF_38_90 ), @@ -183,7 +184,7 @@ static struct tvnorm tvnorms[] = { .b = ( cOutputPort2Inactive | cPositiveAmTV | cQSS ), - .c = ( cTopDefault), + .c = ( cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_6_5 | cVideoIF_33_90 ), @@ -194,7 +195,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis50 | - cTopDefault), + cTopPalSecamDefault), .e = ( cGating_36 | cAudioIF_6_5 | cVideoIF_38_90 ), @@ -205,7 +206,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis75 | - cTopDefault), + cTopNtscRadioDefault), .e = ( cGating_36 | cAudioIF_4_5 | cVideoIF_45_75 ), @@ -216,7 +217,7 @@ static struct tvnorm tvnorms[] = { cQSS ), .c = ( cDeemphasisON | cDeemphasis50 | - cTopDefault), + cTopNtscRadioDefault), .e = ( cGating_36 | cAudioIF_4_5 | cVideoIF_58_75 ), @@ -229,7 +230,7 @@ static struct tvnorm radio_stereo = { cQSS ), .c = ( cDeemphasisOFF | cAudioGain6 | - cTopDefault), + cTopNtscRadioDefault), .e = ( cTunerGainLow | cAudioIF_5_5 | cRadioIF_38_90 ), @@ -241,7 +242,7 @@ static struct tvnorm radio_mono = { cQSS ), .c = ( cDeemphasisON | cDeemphasis75 | - cTopDefault), + cTopNtscRadioDefault), .e = ( cTunerGainLow | cAudioIF_5_5 | cRadioIF_38_90 ), diff --git a/trunk/drivers/media/video/tuner-core.c b/trunk/drivers/media/video/tuner-core.c index 011413cf34a8..a26ded7d6fae 100644 --- a/trunk/drivers/media/video/tuner-core.c +++ b/trunk/drivers/media/video/tuner-core.c @@ -40,6 +40,7 @@ static unsigned int no_autodetect = 0; static unsigned int show_i2c = 0; /* insmod options used at runtime => read/write */ +static unsigned int tuner_debug_old = 0; int tuner_debug = 0; static unsigned int tv_range[2] = { 44, 958 }; @@ -53,6 +54,8 @@ 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_named(tuner_debug,tuner_debug_old, int, 0444); module_param_named(debug,tuner_debug, int, 0644); module_param_string(pal, pal, sizeof(pal), 0644); module_param_string(secam, secam, sizeof(secam), 0644); @@ -439,6 +442,11 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) t->audmode = V4L2_TUNER_MODE_STEREO; t->mode_mask = T_UNINITIALIZED; t->tuner_status = tuner_status; + if (tuner_debug_old) { + tuner_debug = tuner_debug_old; + 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]; diff --git a/trunk/drivers/media/video/v4l2-common.c b/trunk/drivers/media/video/v4l2-common.c index 97f946db8597..f4b3d64ebf73 100644 --- a/trunk/drivers/media/video/v4l2-common.c +++ b/trunk/drivers/media/video/v4l2-common.c @@ -1103,7 +1103,7 @@ const char **v4l2_ctrl_get_menu(u32 id) }; static const char *mpeg_stream_vbi_fmt[] = { "No VBI", - "Private packet, IVTV format", + "VBI in private packets, IVTV format", NULL }; diff --git a/trunk/drivers/message/fusion/mptfc.c b/trunk/drivers/message/fusion/mptfc.c index 3ff8378ea660..74714e5bcf03 100644 --- a/trunk/drivers/message/fusion/mptfc.c +++ b/trunk/drivers/message/fusion/mptfc.c @@ -305,8 +305,10 @@ mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port, } out: - kfree(pp0_array); - kfree(p0_array); + if (pp0_array) + kfree(pp0_array); + if (p0_array) + kfree(p0_array); return rc; } diff --git a/trunk/drivers/message/fusion/mptsas.c b/trunk/drivers/message/fusion/mptsas.c index 85689ab46cbc..af6ec553ff7c 100644 --- a/trunk/drivers/message/fusion/mptsas.c +++ b/trunk/drivers/message/fusion/mptsas.c @@ -1378,7 +1378,8 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) return 0; out_free_port_info: - kfree(hba); + if (hba) + kfree(hba); out: return error; } diff --git a/trunk/drivers/message/i2o/iop.c b/trunk/drivers/message/i2o/iop.c index c74e5460f834..febbdd4e0605 100644 --- a/trunk/drivers/message/i2o/iop.c +++ b/trunk/drivers/message/i2o/iop.c @@ -1239,6 +1239,7 @@ EXPORT_SYMBOL(i2o_cntxt_list_remove); EXPORT_SYMBOL(i2o_cntxt_list_get_ptr); #endif EXPORT_SYMBOL(i2o_msg_get_wait); +EXPORT_SYMBOL(i2o_msg_nop); EXPORT_SYMBOL(i2o_find_iop); EXPORT_SYMBOL(i2o_iop_find_device); EXPORT_SYMBOL(i2o_event_register); diff --git a/trunk/drivers/misc/ibmasm/module.c b/trunk/drivers/misc/ibmasm/module.c index 9706cc19134a..1fdf03fd2da7 100644 --- a/trunk/drivers/misc/ibmasm/module.c +++ b/trunk/drivers/misc/ibmasm/module.c @@ -85,7 +85,7 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi } memset(sp, 0, sizeof(struct service_processor)); - spin_lock_init(&sp->lock); + sp->lock = SPIN_LOCK_UNLOCKED; INIT_LIST_HEAD(&sp->command_queue); pci_set_drvdata(pdev, (void *)sp); diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c index 39edb8250fbc..0d435814aaa1 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0001.c @@ -357,7 +357,6 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) mtd->resume = cfi_intelext_resume; mtd->flags = MTD_CAP_NORFLASH; mtd->name = map->name; - mtd->writesize = 1; mtd->reboot_notifier.notifier_call = cfi_intelext_reboot; diff --git a/trunk/drivers/mtd/chips/jedec.c b/trunk/drivers/mtd/chips/jedec.c index 2c3f019197c1..c40b48dabed3 100644 --- a/trunk/drivers/mtd/chips/jedec.c +++ b/trunk/drivers/mtd/chips/jedec.c @@ -256,7 +256,6 @@ static struct mtd_info *jedec_probe(struct map_info *map) MTD->name = map->name; MTD->type = MTD_NORFLASH; MTD->flags = MTD_CAP_NORFLASH; - MTD->writesize = 1; MTD->erasesize = SectorSize*(map->buswidth); // printk("MTD->erasesize is %x\n",(unsigned int)MTD->erasesize); MTD->size = priv->size; diff --git a/trunk/drivers/mtd/chips/map_absent.c b/trunk/drivers/mtd/chips/map_absent.c index ac01a949b687..a611de9b1515 100644 --- a/trunk/drivers/mtd/chips/map_absent.c +++ b/trunk/drivers/mtd/chips/map_absent.c @@ -64,8 +64,7 @@ static struct mtd_info *map_absent_probe(struct map_info *map) mtd->write = map_absent_write; mtd->sync = map_absent_sync; mtd->flags = 0; - mtd->erasesize = PAGE_SIZE; - mtd->writesize = 1; + mtd->erasesize = PAGE_SIZE; __module_get(THIS_MODULE); return mtd; diff --git a/trunk/drivers/mtd/chips/map_ram.c b/trunk/drivers/mtd/chips/map_ram.c index 3a66680abfd0..763925747db6 100644 --- a/trunk/drivers/mtd/chips/map_ram.c +++ b/trunk/drivers/mtd/chips/map_ram.c @@ -71,7 +71,6 @@ static struct mtd_info *map_ram_probe(struct map_info *map) mtd->write = mapram_write; mtd->sync = mapram_nop; mtd->flags = MTD_CAP_RAM; - mtd->writesize = 1; mtd->erasesize = PAGE_SIZE; while(mtd->size & (mtd->erasesize - 1)) diff --git a/trunk/drivers/mtd/chips/map_rom.c b/trunk/drivers/mtd/chips/map_rom.c index 1b328b1378fd..bc6ee9ef8a31 100644 --- a/trunk/drivers/mtd/chips/map_rom.c +++ b/trunk/drivers/mtd/chips/map_rom.c @@ -47,7 +47,6 @@ static struct mtd_info *map_rom_probe(struct map_info *map) mtd->sync = maprom_nop; mtd->flags = MTD_CAP_ROM; mtd->erasesize = map->size; - mtd->writesize = 1; __module_get(THIS_MODULE); return mtd; diff --git a/trunk/drivers/mtd/devices/block2mtd.c b/trunk/drivers/mtd/devices/block2mtd.c index be3f1c136d02..0d98c223c5fc 100644 --- a/trunk/drivers/mtd/devices/block2mtd.c +++ b/trunk/drivers/mtd/devices/block2mtd.c @@ -324,7 +324,6 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; dev->mtd.erasesize = erase_size; - dev->mtd.writesize = 1; dev->mtd.type = MTD_RAM; dev->mtd.flags = MTD_CAP_RAM; dev->mtd.erase = block2mtd_erase; diff --git a/trunk/drivers/mtd/devices/ms02-nv.c b/trunk/drivers/mtd/devices/ms02-nv.c index 08dfb899b272..4ab7670770e4 100644 --- a/trunk/drivers/mtd/devices/ms02-nv.c +++ b/trunk/drivers/mtd/devices/ms02-nv.c @@ -225,7 +225,6 @@ static int __init ms02nv_init_one(ulong addr) mtd->owner = THIS_MODULE; mtd->read = ms02nv_read; mtd->write = ms02nv_write; - mtd->writesize = 1; ret = -EIO; if (add_mtd_device(mtd)) { diff --git a/trunk/drivers/mtd/devices/mtd_dataflash.c b/trunk/drivers/mtd/devices/mtd_dataflash.c index 04271d02b6b6..a19480d07888 100644 --- a/trunk/drivers/mtd/devices/mtd_dataflash.c +++ b/trunk/drivers/mtd/devices/mtd_dataflash.c @@ -478,7 +478,6 @@ add_dataflash(struct spi_device *spi, char *name, device->name = (pdata && pdata->name) ? pdata->name : priv->name; device->size = nr_pages * pagesize; device->erasesize = pagesize; - device->writesize = pagesize; device->owner = THIS_MODULE; device->type = MTD_DATAFLASH; device->flags = MTD_CAP_NORFLASH; diff --git a/trunk/drivers/mtd/devices/phram.c b/trunk/drivers/mtd/devices/phram.c index 6c7337f9ebbb..e09e416667d3 100644 --- a/trunk/drivers/mtd/devices/phram.c +++ b/trunk/drivers/mtd/devices/phram.c @@ -151,7 +151,6 @@ static int register_device(char *name, unsigned long start, unsigned long len) new->mtd.owner = THIS_MODULE; new->mtd.type = MTD_RAM; new->mtd.erasesize = PAGE_SIZE; - new->mtd.writesize = 1; ret = -EAGAIN; if (add_mtd_device(&new->mtd)) { diff --git a/trunk/drivers/mtd/devices/pmc551.c b/trunk/drivers/mtd/devices/pmc551.c index f620d74f1004..666cce1bf60c 100644 --- a/trunk/drivers/mtd/devices/pmc551.c +++ b/trunk/drivers/mtd/devices/pmc551.c @@ -778,8 +778,7 @@ static int __init init_pmc551(void) mtd->type = MTD_RAM; mtd->name = "PMC551 RAM board"; mtd->erasesize = 0x10000; - mtd->writesize = 1; - mtd->owner = THIS_MODULE; + mtd->owner = THIS_MODULE; if (add_mtd_device(mtd)) { printk(KERN_NOTICE "pmc551: Failed to register new device\n"); diff --git a/trunk/drivers/mtd/devices/slram.c b/trunk/drivers/mtd/devices/slram.c index 542a0c009006..b3f665e3c38b 100644 --- a/trunk/drivers/mtd/devices/slram.c +++ b/trunk/drivers/mtd/devices/slram.c @@ -209,7 +209,6 @@ static int register_device(char *name, unsigned long start, unsigned long length (*curmtd)->mtdinfo->owner = THIS_MODULE; (*curmtd)->mtdinfo->type = MTD_RAM; (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ; - (*curmtd)->mtdinfo->writesize = 1; if (add_mtd_device((*curmtd)->mtdinfo)) { E("slram: Failed to register new device\n"); diff --git a/trunk/drivers/mtd/maps/ixp2000.c b/trunk/drivers/mtd/maps/ixp2000.c index c26488a1793a..2c9cc7f37e92 100644 --- a/trunk/drivers/mtd/maps/ixp2000.c +++ b/trunk/drivers/mtd/maps/ixp2000.c @@ -42,6 +42,7 @@ struct ixp2000_flash_info { struct map_info map; struct mtd_partition *partitions; struct resource *res; + int nr_banks; }; static inline unsigned long flash_bank_setup(struct map_info *map, unsigned long ofs) @@ -182,6 +183,7 @@ static int ixp2000_flash_probe(struct platform_device *dev) */ info->map.phys = NO_XIP; + info->nr_banks = ixp_data->nr_banks; info->map.size = ixp_data->nr_banks * window_size; info->map.bankwidth = 1; diff --git a/trunk/drivers/mtd/maps/physmap.c b/trunk/drivers/mtd/maps/physmap.c index d6301f08906d..433c3cac3ca9 100644 --- a/trunk/drivers/mtd/maps/physmap.c +++ b/trunk/drivers/mtd/maps/physmap.c @@ -182,7 +182,7 @@ static struct physmap_flash_data physmap_flash_data = { static struct resource physmap_flash_resource = { .start = CONFIG_MTD_PHYSMAP_START, - .end = CONFIG_MTD_PHYSMAP_START + CONFIG_MTD_PHYSMAP_LEN - 1, + .end = CONFIG_MTD_PHYSMAP_START + CONFIG_MTD_PHYSMAP_LEN, .flags = IORESOURCE_MEM, }; diff --git a/trunk/drivers/mtd/mtdchar.c b/trunk/drivers/mtd/mtdchar.c index 9a4b59d92525..aa18d45b264b 100644 --- a/trunk/drivers/mtd/mtdchar.c +++ b/trunk/drivers/mtd/mtdchar.c @@ -78,7 +78,7 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) return -EINVAL; } - if (offset >= 0 && offset <= mtd->size) + if (offset >= 0 && offset < mtd->size) return file->f_pos = offset; return -EINVAL; diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index 80a76654d963..27083ed0a017 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -1176,7 +1176,7 @@ static int nand_write_oob_std(struct mtd_info *mtd, struct nand_chip *chip, status = chip->waitfunc(mtd, chip); - return status & NAND_STATUS_FAIL ? -EIO : 0; + return status; } /** @@ -1271,6 +1271,10 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, sndcmd = chip->ecc.read_oob(mtd, chip, page, sndcmd); buf = nand_transfer_oob(chip, buf, ops); + readlen -= ops->ooblen; + if (!readlen) + break; + if (!(chip->options & NAND_NO_READRDY)) { /* * Apply delay or wait for ready/busy pin. Do this @@ -1284,10 +1288,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, nand_wait_ready(mtd); } - readlen -= ops->ooblen; - if (!readlen) - break; - /* Increment page address */ realpage++; @@ -1610,13 +1610,13 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, if (!writelen) return 0; - chipnr = (int)(to >> chip->chip_shift); - chip->select_chip(mtd, chipnr); - /* Check, if it is write protected */ if (nand_check_wp(mtd)) return -EIO; + chipnr = (int)(to >> chip->chip_shift); + chip->select_chip(mtd, chipnr); + realpage = (int)(to >> chip->page_shift); page = realpage & chip->pagemask; blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; diff --git a/trunk/drivers/mtd/nand/ndfc.c b/trunk/drivers/mtd/nand/ndfc.c index e5bd88f2d560..fe8d38514ba6 100644 --- a/trunk/drivers/mtd/nand/ndfc.c +++ b/trunk/drivers/mtd/nand/ndfc.c @@ -61,15 +61,15 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip) static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) { - struct ndfc_controller *ndfc = &ndfc_ctrl; + struct nand_chip *chip = mtd->priv; if (cmd == NAND_CMD_NONE) return; if (ctrl & NAND_CLE) - writel(cmd & 0xFF, ndfc->ndfcbase + NDFC_CMD); + writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_CMD); else - writel(cmd & 0xFF, ndfc->ndfcbase + NDFC_ALE); + writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_ALE); } static int ndfc_ready(struct mtd_info *mtd) diff --git a/trunk/drivers/mtd/nand/s3c2410.c b/trunk/drivers/mtd/nand/s3c2410.c index ff5cef24d5bb..2c262fe03d8a 100644 --- a/trunk/drivers/mtd/nand/s3c2410.c +++ b/trunk/drivers/mtd/nand/s3c2410.c @@ -63,6 +63,8 @@ #include #include +#define PFX "s3c2410-nand: " + #ifdef CONFIG_MTD_NAND_S3C2410_HWECC static int hardware_ecc = 1; #else @@ -97,12 +99,6 @@ struct s3c2410_nand_mtd { int scan_res; }; -enum s3c_cpu_type { - TYPE_S3C2410, - TYPE_S3C2412, - TYPE_S3C2440, -}; - /* overview of the s3c2410 nand state */ struct s3c2410_nand_info { @@ -116,11 +112,9 @@ struct s3c2410_nand_info { struct resource *area; struct clk *clk; void __iomem *regs; - void __iomem *sel_reg; - int sel_bit; int mtd_count; - enum s3c_cpu_type cpu_type; + unsigned char is_s3c2440; }; /* conversion functions */ @@ -154,7 +148,7 @@ static inline int allow_clk_stop(struct s3c2410_nand_info *info) #define NS_IN_KHZ 1000000 -static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max) +static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max) { int result; @@ -178,58 +172,53 @@ static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max) /* controller setup */ -static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, - struct platform_device *pdev) +static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, struct platform_device *pdev) { struct s3c2410_platform_nand *plat = to_nand_plat(pdev); unsigned long clkrate = clk_get_rate(info->clk); - int tacls_max = (info->cpu_type == TYPE_S3C2412) ? 8 : 4; int tacls, twrph0, twrph1; - unsigned long cfg = 0; + unsigned long cfg; /* calculate the timing information for the controller */ clkrate /= 1000; /* turn clock into kHz for ease of use */ if (plat != NULL) { - tacls = s3c_nand_calc_rate(plat->tacls, clkrate, tacls_max); - twrph0 = s3c_nand_calc_rate(plat->twrph0, clkrate, 8); - twrph1 = s3c_nand_calc_rate(plat->twrph1, clkrate, 8); + tacls = s3c2410_nand_calc_rate(plat->tacls, clkrate, 4); + twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8); + twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8); } else { /* default timings */ - tacls = tacls_max; + tacls = 4; twrph0 = 8; twrph1 = 8; } if (tacls < 0 || twrph0 < 0 || twrph1 < 0) { - dev_err(info->device, "cannot get suitable timings\n"); + printk(KERN_ERR PFX "cannot get timings suitable for board\n"); return -EINVAL; } - dev_info(info->device, "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", + printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", tacls, to_ns(tacls, clkrate), twrph0, to_ns(twrph0, clkrate), twrph1, to_ns(twrph1, clkrate)); - switch (info->cpu_type) { - case TYPE_S3C2410: + if (!info->is_s3c2440) { cfg = S3C2410_NFCONF_EN; cfg |= S3C2410_NFCONF_TACLS(tacls - 1); cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1); - break; - - case TYPE_S3C2440: - case TYPE_S3C2412: + } else { cfg = S3C2440_NFCONF_TACLS(tacls - 1); cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1); cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1); /* enable the controller and de-assert nFCE */ - writel(S3C2440_NFCONT_ENABLE, info->regs + S3C2440_NFCONT); + writel(S3C2440_NFCONT_ENABLE | S3C2440_NFCONT_ENABLE, + info->regs + S3C2440_NFCONT); } - dev_dbg(info->device, "NF_CONF is 0x%lx\n", cfg); + pr_debug(PFX "NF_CONF is 0x%lx\n", cfg); writel(cfg, info->regs + S3C2410_NFCONF); return 0; @@ -242,21 +231,26 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) struct s3c2410_nand_info *info; struct s3c2410_nand_mtd *nmtd; struct nand_chip *this = mtd->priv; + void __iomem *reg; unsigned long cur; + unsigned long bit; nmtd = this->priv; info = nmtd->info; + bit = (info->is_s3c2440) ? S3C2440_NFCONT_nFCE : S3C2410_NFCONF_nFCE; + reg = info->regs + ((info->is_s3c2440) ? S3C2440_NFCONT : S3C2410_NFCONF); + if (chip != -1 && allow_clk_stop(info)) clk_enable(info->clk); - cur = readl(info->sel_reg); + cur = readl(reg); if (chip == -1) { - cur |= info->sel_bit; + cur |= bit; } else { if (nmtd->set != NULL && chip > nmtd->set->nr_chips) { - dev_err(info->device, "invalid chip %d\n", chip); + printk(KERN_ERR PFX "chip %d out of range\n", chip); return; } @@ -265,10 +259,10 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) (info->platform->select_chip) (nmtd->set, chip); } - cur &= ~info->sel_bit; + cur &= ~bit; } - writel(cur, info->sel_reg); + writel(cur, reg); if (chip == -1 && allow_clk_stop(info)) clk_disable(info->clk); @@ -317,25 +311,15 @@ static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd, static int s3c2410_nand_devready(struct mtd_info *mtd) { struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); - return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; -} - -static int s3c2440_nand_devready(struct mtd_info *mtd) -{ - struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); - return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; -} -static int s3c2412_nand_devready(struct mtd_info *mtd) -{ - struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); - return readb(info->regs + S3C2412_NFSTAT) & S3C2412_NFSTAT_READY; + if (info->is_s3c2440) + return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; + return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; } /* ECC handling functions */ -static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, - u_char *read_ecc, u_char *calc_ecc) +static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) { pr_debug("s3c2410_nand_correct_data(%p,%p,%p,%p)\n", mtd, dat, read_ecc, calc_ecc); @@ -503,8 +487,11 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, struct s3c2410_nand_set *set) { struct nand_chip *chip = &nmtd->chip; - void __iomem *regs = info->regs; + chip->IO_ADDR_R = info->regs + S3C2410_NFDATA; + chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; + chip->cmd_ctrl = s3c2410_nand_hwcontrol; + chip->dev_ready = s3c2410_nand_devready; chip->write_buf = s3c2410_nand_write_buf; chip->read_buf = s3c2410_nand_read_buf; chip->select_chip = s3c2410_nand_select_chip; @@ -513,37 +500,11 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, chip->options = 0; chip->controller = &info->controller; - switch (info->cpu_type) { - case TYPE_S3C2410: - chip->IO_ADDR_W = regs + S3C2410_NFDATA; - info->sel_reg = regs + S3C2410_NFCONF; - info->sel_bit = S3C2410_NFCONF_nFCE; - chip->cmd_ctrl = s3c2410_nand_hwcontrol; - chip->dev_ready = s3c2410_nand_devready; - break; - - case TYPE_S3C2440: - chip->IO_ADDR_W = regs + S3C2440_NFDATA; - info->sel_reg = regs + S3C2440_NFCONT; - info->sel_bit = S3C2440_NFCONT_nFCE; - chip->cmd_ctrl = s3c2440_nand_hwcontrol; - chip->dev_ready = s3c2440_nand_devready; - break; - - case TYPE_S3C2412: - chip->IO_ADDR_W = regs + S3C2440_NFDATA; - info->sel_reg = regs + S3C2440_NFCONT; - info->sel_bit = S3C2412_NFCONT_nFCE0; - chip->cmd_ctrl = s3c2440_nand_hwcontrol; - chip->dev_ready = s3c2412_nand_devready; - - if (readl(regs + S3C2410_NFCONF) & S3C2412_NFCONF_NANDBOOT) - dev_info(info->device, "System booted from NAND\n"); - - break; - } - - chip->IO_ADDR_R = chip->IO_ADDR_W; + if (info->is_s3c2440) { + chip->IO_ADDR_R = info->regs + S3C2440_NFDATA; + chip->IO_ADDR_W = info->regs + S3C2440_NFDATA; + chip->cmd_ctrl = s3c2440_nand_hwcontrol; + } nmtd->info = info; nmtd->mtd.priv = chip; @@ -551,25 +512,17 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, nmtd->set = set; if (hardware_ecc) { - chip->ecc.calculate = s3c2410_nand_calculate_ecc; chip->ecc.correct = s3c2410_nand_correct_data; + chip->ecc.hwctl = s3c2410_nand_enable_hwecc; + chip->ecc.calculate = s3c2410_nand_calculate_ecc; chip->ecc.mode = NAND_ECC_HW; chip->ecc.size = 512; chip->ecc.bytes = 3; chip->ecc.layout = &nand_hw_eccoob; - switch (info->cpu_type) { - case TYPE_S3C2410: - chip->ecc.hwctl = s3c2410_nand_enable_hwecc; - chip->ecc.calculate = s3c2410_nand_calculate_ecc; - break; - - case TYPE_S3C2412: - case TYPE_S3C2440: - chip->ecc.hwctl = s3c2440_nand_enable_hwecc; - chip->ecc.calculate = s3c2440_nand_calculate_ecc; - break; - + if (info->is_s3c2440) { + chip->ecc.hwctl = s3c2440_nand_enable_hwecc; + chip->ecc.calculate = s3c2440_nand_calculate_ecc; } } else { chip->ecc.mode = NAND_ECC_SOFT; @@ -584,8 +537,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, * nand layer to look for devices */ -static int s3c24xx_nand_probe(struct platform_device *pdev, - enum s3c_cpu_type cpu_type) +static int s3c24xx_nand_probe(struct platform_device *pdev, int is_s3c2440) { struct s3c2410_platform_nand *plat = to_nand_plat(pdev); struct s3c2410_nand_info *info; @@ -640,7 +592,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, info->device = &pdev->dev; info->platform = plat; info->regs = ioremap(res->start, size); - info->cpu_type = cpu_type; + info->is_s3c2440 = is_s3c2440; if (info->regs == NULL) { dev_err(&pdev->dev, "cannot reserve register region\n"); @@ -747,17 +699,12 @@ static int s3c24xx_nand_resume(struct platform_device *dev) static int s3c2410_nand_probe(struct platform_device *dev) { - return s3c24xx_nand_probe(dev, TYPE_S3C2410); + return s3c24xx_nand_probe(dev, 0); } static int s3c2440_nand_probe(struct platform_device *dev) { - return s3c24xx_nand_probe(dev, TYPE_S3C2440); -} - -static int s3c2412_nand_probe(struct platform_device *dev) -{ - return s3c24xx_nand_probe(dev, TYPE_S3C2412); + return s3c24xx_nand_probe(dev, 1); } static struct platform_driver s3c2410_nand_driver = { @@ -782,29 +729,16 @@ static struct platform_driver s3c2440_nand_driver = { }, }; -static struct platform_driver s3c2412_nand_driver = { - .probe = s3c2412_nand_probe, - .remove = s3c2410_nand_remove, - .suspend = s3c24xx_nand_suspend, - .resume = s3c24xx_nand_resume, - .driver = { - .name = "s3c2412-nand", - .owner = THIS_MODULE, - }, -}; - static int __init s3c2410_nand_init(void) { printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronics\n"); - platform_driver_register(&s3c2412_nand_driver); platform_driver_register(&s3c2440_nand_driver); return platform_driver_register(&s3c2410_nand_driver); } static void __exit s3c2410_nand_exit(void) { - platform_driver_unregister(&s3c2412_nand_driver); platform_driver_unregister(&s3c2440_nand_driver); platform_driver_unregister(&s3c2410_nand_driver); } diff --git a/trunk/drivers/mtd/nand/ts7250.c b/trunk/drivers/mtd/nand/ts7250.c index f40081069ab2..a0b4b1edcb0d 100644 --- a/trunk/drivers/mtd/nand/ts7250.c +++ b/trunk/drivers/mtd/nand/ts7250.c @@ -97,7 +97,7 @@ static void ts7250_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) unsigned long addr = TS72XX_NAND_CONTROL_VIRT_BASE; unsigned char bits; - bits = (ctrl & NAND_NCE) << 2; + bits = (ctrl & NAND_CNE) << 2; bits |= ctrl & NAND_CLE; bits |= (ctrl & NAND_ALE) >> 2; diff --git a/trunk/drivers/net/3c59x.c b/trunk/drivers/net/3c59x.c index b467c383ae60..e27778926eba 100644 --- a/trunk/drivers/net/3c59x.c +++ b/trunk/drivers/net/3c59x.c @@ -375,7 +375,8 @@ limit of 4K. of the drivers, and will likely be provided by some future kernel. */ enum pci_flags_bit { - PCI_USES_MASTER=4, + PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, + PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, }; enum { IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4, IS_TORNADO=8, @@ -445,95 +446,95 @@ static struct vortex_chip_info { int io_size; } vortex_info_tbl[] __devinitdata = { {"3c590 Vortex 10Mbps", - PCI_USES_MASTER, IS_VORTEX, 32, }, + PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, {"3c592 EISA 10Mbps Demon/Vortex", /* AKPM: from Don's 3c59x_cb.c 0.49H */ - PCI_USES_MASTER, IS_VORTEX, 32, }, + PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, {"3c597 EISA Fast Demon/Vortex", /* AKPM: from Don's 3c59x_cb.c 0.49H */ - PCI_USES_MASTER, IS_VORTEX, 32, }, + PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, {"3c595 Vortex 100baseTx", - PCI_USES_MASTER, IS_VORTEX, 32, }, + PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, {"3c595 Vortex 100baseT4", - PCI_USES_MASTER, IS_VORTEX, 32, }, + PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, {"3c595 Vortex 100base-MII", - PCI_USES_MASTER, IS_VORTEX, 32, }, + PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, }, {"3c900 Boomerang 10baseT", - PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, }, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, }, {"3c900 Boomerang 10Mbps Combo", - PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, }, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, }, {"3c900 Cyclone 10Mbps TPO", /* AKPM: from Don's 0.99M */ - PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c900 Cyclone 10Mbps Combo", - PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c900 Cyclone 10Mbps TPC", /* AKPM: from Don's 0.99M */ - PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c900B-FL Cyclone 10base-FL", - PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c905 Boomerang 100baseTx", - PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, }, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, }, {"3c905 Boomerang 100baseT4", - PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, }, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, }, {"3c905B Cyclone 100baseTx", - PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, {"3c905B Cyclone 10/100/BNC", - PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c905B-FX Cyclone 100baseFx", - PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c905C Tornado", - PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, {"3c920B-EMB-WNM (ATI Radeon 9100 IGP)", - PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, }, {"3c980 Cyclone", - PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, }, {"3c980C Python-T", - PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, {"3cSOHO100-TX Hurricane", - PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c555 Laptop Hurricane", - PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, }, {"3c556 Laptop Tornado", - PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_8BIT|HAS_CB_FNS|INVERT_MII_PWR| + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_8BIT|HAS_CB_FNS|INVERT_MII_PWR| HAS_HWCKSM, 128, }, {"3c556B Laptop Hurricane", - PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR| + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR| WNO_XCVR_PWR|HAS_HWCKSM, 128, }, {"3c575 [Megahertz] 10/100 LAN CardBus", - PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, {"3c575 Boomerang CardBus", - PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, }, {"3CCFE575BT Cyclone CardBus", - PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT| + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT| INVERT_LED_PWR|HAS_HWCKSM, 128, }, {"3CCFE575CT Tornado CardBus", - PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| MAX_COLLISION_RESET|HAS_HWCKSM, 128, }, {"3CCFE656 Cyclone CardBus", - PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| INVERT_LED_PWR|HAS_HWCKSM, 128, }, {"3CCFEM656B Cyclone+Winmodem CardBus", - PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| INVERT_LED_PWR|HAS_HWCKSM, 128, }, {"3CXFEM656C Tornado+Winmodem CardBus", /* From pcmcia-cs-3.1.5 */ - PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR| MAX_COLLISION_RESET|HAS_HWCKSM, 128, }, {"3c450 HomePNA Tornado", /* AKPM: from Don's 0.99Q */ - PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c920 Tornado", - PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, {"3c982 Hydra Dual Port A", - PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, {"3c982 Hydra Dual Port B", - PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, }, {"3c905B-T4", - PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, }, {"3c920B-EMB-WNM Tornado", - PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, + PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, }, {NULL,}, /* NULL terminated list. */ }; diff --git a/trunk/drivers/net/dl2k.h b/trunk/drivers/net/dl2k.h index 53449207e53b..6e75482d75f2 100644 --- a/trunk/drivers/net/dl2k.h +++ b/trunk/drivers/net/dl2k.h @@ -683,6 +683,11 @@ struct netdev_private { }; /* The station address location in the EEPROM. */ +#ifdef MEM_MAPPING +#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1) +#else +#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0) +#endif /* The struct pci_device_id consist of: vendor, device Vendor and device ID to match (or PCI_ANY_ID) subvendor, subdevice Subsystem vendor and device ID to match (or PCI_ANY_ID) @@ -690,10 +695,9 @@ struct netdev_private { class_mask of the class are honored during the comparison. driver_data Data private to the driver. */ - -static const struct pci_device_id rio_pci_tbl[] = { - {0x1186, 0x4000, PCI_ANY_ID, PCI_ANY_ID, }, - { } +static struct pci_device_id rio_pci_tbl[] = { + {0x1186, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0,} }; MODULE_DEVICE_TABLE (pci, rio_pci_tbl); #define TX_TIMEOUT (4*HZ) diff --git a/trunk/drivers/net/dm9000.c b/trunk/drivers/net/dm9000.c index 7965a9b08e79..24996da4c1c4 100644 --- a/trunk/drivers/net/dm9000.c +++ b/trunk/drivers/net/dm9000.c @@ -410,7 +410,10 @@ dm9000_probe(struct platform_device *pdev) if (pdev->num_resources < 2) { ret = -ENODEV; goto out; - } else if (pdev->num_resources == 2) { + } + + switch (pdev->num_resources) { + case 2: base = pdev->resource[0].start; if (!request_mem_region(base, 4, ndev->name)) { @@ -420,16 +423,17 @@ dm9000_probe(struct platform_device *pdev) ndev->base_addr = base; ndev->irq = pdev->resource[1].start; - db->io_addr = (void __iomem *)base; - db->io_data = (void __iomem *)(base + 4); + db->io_addr = (void *)base; + db->io_data = (void *)(base + 4); - } else { + break; + + case 3: db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); db->irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (db->addr_res == NULL || db->data_res == NULL || - db->irq_res == NULL) { + if (db->addr_res == NULL || db->data_res == NULL) { printk(KERN_ERR PFX "insufficient resources\n"); ret = -ENOENT; goto out; @@ -478,6 +482,7 @@ dm9000_probe(struct platform_device *pdev) /* ensure at least we have a default set of IO routines */ dm9000_set_io(db, iosize); + } /* check to see if anything is being over-ridden */ @@ -559,13 +564,6 @@ dm9000_probe(struct platform_device *pdev) for (i = 0; i < 6; i++) ndev->dev_addr[i] = db->srom[i]; - if (!is_valid_ether_addr(ndev->dev_addr)) { - /* try reading from mac */ - - for (i = 0; i < 6; i++) - ndev->dev_addr[i] = ior(db, i+DM9000_PAR); - } - if (!is_valid_ether_addr(ndev->dev_addr)) printk("%s: Invalid ethernet MAC address. Please " "set using ifconfig\n", ndev->name); @@ -665,6 +663,7 @@ dm9000_init_dm9000(struct net_device *dev) db->tx_pkt_cnt = 0; db->queue_pkt_len = 0; dev->trans_start = 0; + spin_lock_init(&db->lock); } /* @@ -768,7 +767,7 @@ dm9000_stop(struct net_device *ndev) * receive the packet to upper layer, free the transmitted packet */ -static void +void dm9000_tx_done(struct net_device *dev, board_info_t * db) { int tx_status = ior(db, DM9000_NSR); /* Got TX status */ @@ -1188,14 +1187,13 @@ dm9000_drv_remove(struct platform_device *pdev) } static struct platform_driver dm9000_driver = { - .driver = { - .name = "dm9000", - .owner = THIS_MODULE, - }, .probe = dm9000_probe, .remove = dm9000_drv_remove, .suspend = dm9000_drv_suspend, .resume = dm9000_drv_resume, + .driver = { + .name = "dm9000", + }, }; static int __init diff --git a/trunk/drivers/net/eepro100.c b/trunk/drivers/net/eepro100.c index ecf5ad85a684..467fc861360d 100644 --- a/trunk/drivers/net/eepro100.c +++ b/trunk/drivers/net/eepro100.c @@ -278,6 +278,11 @@ having to sign an Intel NDA when I'm helping Intel sell their own product! static int speedo_found1(struct pci_dev *pdev, void __iomem *ioaddr, int fnd_cnt, int acpi_idle_state); +enum pci_flags_bit { + PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, + PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3, +}; + /* Offsets to the various registers. All accesses need not be longword aligned. */ enum speedo_offsets { diff --git a/trunk/drivers/net/epic100.c b/trunk/drivers/net/epic100.c index ee34a16eb4e2..724d7dc35fa3 100644 --- a/trunk/drivers/net/epic100.c +++ b/trunk/drivers/net/epic100.c @@ -191,10 +191,23 @@ IVc. Errata */ +enum pci_id_flags_bits { + /* Set PCI command register bits before calling probe1(). */ + PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, + /* Read and map the single following PCI BAR. */ + PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4, + PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400, +}; + enum chip_capability_flags { MII_PWRDWN=1, TYPE2_INTR=2, NO_MII=4 }; #define EPIC_TOTAL_SIZE 0x100 #define USE_IO_OPS 1 +#ifdef USE_IO_OPS +#define EPIC_IOTYPE PCI_USES_MASTER|PCI_USES_IO|PCI_ADDR0 +#else +#define EPIC_IOTYPE PCI_USES_MASTER|PCI_USES_MEM|PCI_ADDR1 +#endif typedef enum { SMSC_83C170_0, @@ -205,6 +218,7 @@ typedef enum { struct epic_chip_info { const char *name; + enum pci_id_flags_bits pci_flags; int io_size; /* Needed for I/O region check or ioremap(). */ int drv_flags; /* Driver use, intended as capability flags. */ }; @@ -213,11 +227,11 @@ struct epic_chip_info { /* indexed by chip_t */ static const struct epic_chip_info pci_id_tbl[] = { { "SMSC EPIC/100 83c170", - EPIC_TOTAL_SIZE, TYPE2_INTR | NO_MII | MII_PWRDWN }, + EPIC_IOTYPE, EPIC_TOTAL_SIZE, TYPE2_INTR | NO_MII | MII_PWRDWN }, { "SMSC EPIC/100 83c170", - EPIC_TOTAL_SIZE, TYPE2_INTR }, + EPIC_IOTYPE, EPIC_TOTAL_SIZE, TYPE2_INTR }, { "SMSC EPIC/C 83c175", - EPIC_TOTAL_SIZE, TYPE2_INTR | MII_PWRDWN }, + EPIC_IOTYPE, EPIC_TOTAL_SIZE, TYPE2_INTR | MII_PWRDWN }, }; diff --git a/trunk/drivers/net/fealnx.c b/trunk/drivers/net/fealnx.c index 13eca7ede2af..a8449265e5fd 100644 --- a/trunk/drivers/net/fealnx.c +++ b/trunk/drivers/net/fealnx.c @@ -126,6 +126,16 @@ MODULE_PARM_DESC(full_duplex, "fealnx full duplex setting(s) (1)"); #define MIN_REGION_SIZE 136 +enum pci_flags_bit { + PCI_USES_IO = 1, + PCI_USES_MEM = 2, + PCI_USES_MASTER = 4, + PCI_ADDR0 = 0x10 << 0, + PCI_ADDR1 = 0x10 << 1, + PCI_ADDR2 = 0x10 << 2, + PCI_ADDR3 = 0x10 << 3, +}; + /* A chip capabilities table, matching the entries in pci_tbl[] above. */ enum chip_capability_flags { HAS_MII_XCVR, diff --git a/trunk/drivers/net/fec.c b/trunk/drivers/net/fec.c index db694c832989..bd6983d1afba 100644 --- a/trunk/drivers/net/fec.c +++ b/trunk/drivers/net/fec.c @@ -22,7 +22,7 @@ * Copyright (c) 2001-2005 Greg Ungerer (gerg@snapgear.com) * * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) - * Copyright (c) 2004-2006 Macq Electronique SA. + * Copyright (c) 2004-2005 Macq Electronique SA. */ #include @@ -51,7 +51,7 @@ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \ defined(CONFIG_M5272) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) || defined(CONFIG_M532x) + defined(CONFIG_M520x) #include #include #include "fec.h" @@ -80,8 +80,6 @@ static unsigned int fec_hw[] = { (MCF_MBAR + 0x1000), #elif defined(CONFIG_M520x) (MCF_MBAR+0x30000), -#elif defined(CONFIG_M532x) - (MCF_MBAR+0xfc030000), #else &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec), #endif @@ -145,7 +143,7 @@ typedef struct { #define TX_RING_MOD_MASK 15 /* for this to work */ #if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE) -#error "FEC: descriptor ring size constants too large" +#error "FEC: descriptor ring size contants too large" #endif /* Interrupt events/masks. @@ -169,12 +167,12 @@ typedef struct { /* - * The 5270/5271/5280/5282/532x RX control register also contains maximum frame + * The 5270/5271/5280/5282 RX control register also contains maximum frame * size bits. Other FEC hardware does not, so we need to take that into * account when setting it. */ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \ - defined(CONFIG_M520x) || defined(CONFIG_M532x) + defined(CONFIG_M520x) #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16) #else #define OPT_FRAME_SIZE 0 @@ -310,7 +308,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) struct fec_enet_private *fep; volatile fec_t *fecp; volatile cbd_t *bdp; - unsigned short status; fep = netdev_priv(dev); fecp = (volatile fec_t*)dev->base_addr; @@ -323,9 +320,8 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Fill in a Tx ring entry */ bdp = fep->cur_tx; - status = bdp->cbd_sc; #ifndef final_version - if (status & BD_ENET_TX_READY) { + if (bdp->cbd_sc & BD_ENET_TX_READY) { /* Ooops. All transmit buffers are full. Bail out. * This should not happen, since dev->tbusy should be set. */ @@ -336,7 +332,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Clear all of the status flags. */ - status &= ~BD_ENET_TX_STATS; + bdp->cbd_sc &= ~BD_ENET_TX_STATS; /* Set buffer length and buffer pointer. */ @@ -370,22 +366,21 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) spin_lock_irq(&fep->lock); - /* Send it on its way. Tell FEC it's ready, interrupt when done, - * it's the last BD of the frame, and to put the CRC on the end. + /* Send it on its way. Tell FEC its ready, interrupt when done, + * its the last BD of the frame, and to put the CRC on the end. */ - status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR + bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC); - bdp->cbd_sc = status; dev->trans_start = jiffies; /* Trigger transmission start */ - fecp->fec_x_des_active = 0; + fecp->fec_x_des_active = 0x01000000; /* If this was the last BD in the ring, start at the beginning again. */ - if (status & BD_ENET_TX_WRAP) { + if (bdp->cbd_sc & BD_ENET_TX_WRAP) { bdp = fep->tx_bd_base; } else { bdp++; @@ -496,44 +491,43 @@ fec_enet_tx(struct net_device *dev) { struct fec_enet_private *fep; volatile cbd_t *bdp; - unsigned short status; struct sk_buff *skb; fep = netdev_priv(dev); spin_lock(&fep->lock); bdp = fep->dirty_tx; - while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { + while ((bdp->cbd_sc&BD_ENET_TX_READY) == 0) { if (bdp == fep->cur_tx && fep->tx_full == 0) break; skb = fep->tx_skbuff[fep->skb_dirty]; /* Check for errors. */ - if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | + if (bdp->cbd_sc & (BD_ENET_TX_HB | BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) { fep->stats.tx_errors++; - if (status & BD_ENET_TX_HB) /* No heartbeat */ + if (bdp->cbd_sc & BD_ENET_TX_HB) /* No heartbeat */ fep->stats.tx_heartbeat_errors++; - if (status & BD_ENET_TX_LC) /* Late collision */ + if (bdp->cbd_sc & BD_ENET_TX_LC) /* Late collision */ fep->stats.tx_window_errors++; - if (status & BD_ENET_TX_RL) /* Retrans limit */ + if (bdp->cbd_sc & BD_ENET_TX_RL) /* Retrans limit */ fep->stats.tx_aborted_errors++; - if (status & BD_ENET_TX_UN) /* Underrun */ + if (bdp->cbd_sc & BD_ENET_TX_UN) /* Underrun */ fep->stats.tx_fifo_errors++; - if (status & BD_ENET_TX_CSL) /* Carrier lost */ + if (bdp->cbd_sc & BD_ENET_TX_CSL) /* Carrier lost */ fep->stats.tx_carrier_errors++; } else { fep->stats.tx_packets++; } #ifndef final_version - if (status & BD_ENET_TX_READY) + if (bdp->cbd_sc & BD_ENET_TX_READY) printk("HEY! Enet xmit interrupt and TX_READY.\n"); #endif /* Deferred means some collisions occurred during transmit, * but we eventually sent the packet OK. */ - if (status & BD_ENET_TX_DEF) + if (bdp->cbd_sc & BD_ENET_TX_DEF) fep->stats.collisions++; /* Free the sk buffer associated with this last transmit. @@ -544,7 +538,7 @@ fec_enet_tx(struct net_device *dev) /* Update pointer to next buffer descriptor to be transmitted. */ - if (status & BD_ENET_TX_WRAP) + if (bdp->cbd_sc & BD_ENET_TX_WRAP) bdp = fep->tx_bd_base; else bdp++; @@ -574,14 +568,9 @@ fec_enet_rx(struct net_device *dev) struct fec_enet_private *fep; volatile fec_t *fecp; volatile cbd_t *bdp; - unsigned short status; struct sk_buff *skb; ushort pkt_len; __u8 *data; - -#ifdef CONFIG_M532x - flush_cache_all(); -#endif fep = netdev_priv(dev); fecp = (volatile fec_t*)dev->base_addr; @@ -591,13 +580,13 @@ fec_enet_rx(struct net_device *dev) */ bdp = fep->cur_rx; -while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { +while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) { #ifndef final_version /* Since we have allocated space to hold a complete frame, * the last indicator should be set. */ - if ((status & BD_ENET_RX_LAST) == 0) + if ((bdp->cbd_sc & BD_ENET_RX_LAST) == 0) printk("FEC ENET: rcv is not +last\n"); #endif @@ -605,26 +594,26 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { goto rx_processing_done; /* Check for errors. */ - if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | + if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO | BD_ENET_RX_CR | BD_ENET_RX_OV)) { fep->stats.rx_errors++; - if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { + if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH)) { /* Frame too long or too short. */ fep->stats.rx_length_errors++; } - if (status & BD_ENET_RX_NO) /* Frame alignment */ + if (bdp->cbd_sc & BD_ENET_RX_NO) /* Frame alignment */ fep->stats.rx_frame_errors++; - if (status & BD_ENET_RX_CR) /* CRC Error */ + if (bdp->cbd_sc & BD_ENET_RX_CR) /* CRC Error */ + fep->stats.rx_crc_errors++; + if (bdp->cbd_sc & BD_ENET_RX_OV) /* FIFO overrun */ fep->stats.rx_crc_errors++; - if (status & BD_ENET_RX_OV) /* FIFO overrun */ - fep->stats.rx_fifo_errors++; } /* Report late collisions as a frame error. * On this error, the BD is closed, but we don't know what we * have in the buffer. So, just drop this frame on the floor. */ - if (status & BD_ENET_RX_CL) { + if (bdp->cbd_sc & BD_ENET_RX_CL) { fep->stats.rx_errors++; fep->stats.rx_frame_errors++; goto rx_processing_done; @@ -650,7 +639,9 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { } else { skb->dev = dev; skb_put(skb,pkt_len-4); /* Make room */ - eth_copy_and_sum(skb, data, pkt_len-4, 0); + eth_copy_and_sum(skb, + (unsigned char *)__va(bdp->cbd_bufaddr), + pkt_len-4, 0); skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); } @@ -658,16 +649,15 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { /* Clear the status flags for this buffer. */ - status &= ~BD_ENET_RX_STATS; + bdp->cbd_sc &= ~BD_ENET_RX_STATS; /* Mark the buffer empty. */ - status |= BD_ENET_RX_EMPTY; - bdp->cbd_sc = status; + bdp->cbd_sc |= BD_ENET_RX_EMPTY; /* Update BD pointer to next entry. */ - if (status & BD_ENET_RX_WRAP) + if (bdp->cbd_sc & BD_ENET_RX_WRAP) bdp = fep->rx_bd_base; else bdp++; @@ -677,9 +667,9 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { * incoming frames. On a heavily loaded network, we should be * able to keep up at the expense of system resources. */ - fecp->fec_r_des_active = 0; + fecp->fec_r_des_active = 0x01000000; #endif - } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */ + } /* while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) */ fep->cur_rx = (cbd_t *)bdp; #if 0 @@ -690,12 +680,11 @@ while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) { * our way back to the interrupt return only to come right back * here. */ - fecp->fec_r_des_active = 0; + fecp->fec_r_des_active = 0x01000000; #endif } -/* called from interrupt context */ static void fec_enet_mii(struct net_device *dev) { @@ -707,12 +696,10 @@ fec_enet_mii(struct net_device *dev) fep = netdev_priv(dev); ep = fep->hwp; mii_reg = ep->fec_mii_data; - - spin_lock(&fep->lock); if ((mip = mii_head) == NULL) { printk("MII and no head!\n"); - goto unlock; + return; } if (mip->mii_func != NULL) @@ -724,9 +711,6 @@ fec_enet_mii(struct net_device *dev) if ((mip = mii_head) != NULL) ep->fec_mii_data = mip->mii_regval; - -unlock: - spin_unlock(&fep->lock); } static int @@ -744,7 +728,8 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi retval = 0; - spin_lock_irqsave(&fep->lock,flags); + save_flags(flags); + cli(); if ((mip = mii_free) != NULL) { mii_free = mip->mii_next; @@ -764,7 +749,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi retval = 1; } - spin_unlock_irqrestore(&fep->lock,flags); + restore_flags(flags); return(retval); } @@ -1231,7 +1216,7 @@ static phy_info_t const * const phy_info[] = { }; /* ------------------------------------------------------------------------- */ -#if !defined(CONFIG_M532x) + #ifdef CONFIG_RPXCLASSIC static void mii_link_interrupt(void *dev_id); @@ -1239,7 +1224,6 @@ mii_link_interrupt(void *dev_id); static irqreturn_t mii_link_interrupt(int irq, void * dev_id, struct pt_regs * regs); #endif -#endif #if defined(CONFIG_M5272) @@ -1400,13 +1384,13 @@ static void __inline__ fec_request_intrs(struct net_device *dev) { volatile unsigned char *icrp; volatile unsigned long *imrp; - int i, ilip; + int i; b = (fep->index) ? MCFICM_INTC1 : MCFICM_INTC0; icrp = (volatile unsigned char *) (MCF_IPSBAR + b + MCFINTC_ICR0); - for (i = 23, ilip = 0x28; (i < 36); i++) - icrp[i] = ilip--; + for (i = 23; (i < 36); i++) + icrp[i] = 0x23; imrp = (volatile unsigned long *) (MCF_IPSBAR + b + MCFINTC_IMRH); @@ -1634,159 +1618,6 @@ static void __inline__ fec_uncache(unsigned long addr) /* ------------------------------------------------------------------------- */ -#elif defined(CONFIG_M532x) -/* - * Code specific for M532x - */ -static void __inline__ fec_request_intrs(struct net_device *dev) -{ - struct fec_enet_private *fep; - int b; - static const struct idesc { - char *name; - unsigned short irq; - } *idp, id[] = { - { "fec(TXF)", 36 }, - { "fec(TXB)", 37 }, - { "fec(TXFIFO)", 38 }, - { "fec(TXCR)", 39 }, - { "fec(RXF)", 40 }, - { "fec(RXB)", 41 }, - { "fec(MII)", 42 }, - { "fec(LC)", 43 }, - { "fec(HBERR)", 44 }, - { "fec(GRA)", 45 }, - { "fec(EBERR)", 46 }, - { "fec(BABT)", 47 }, - { "fec(BABR)", 48 }, - { NULL }, - }; - - fep = netdev_priv(dev); - b = (fep->index) ? 128 : 64; - - /* Setup interrupt handlers. */ - for (idp = id; idp->name; idp++) { - if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0) - printk("FEC: Could not allocate %s IRQ(%d)!\n", - idp->name, b+idp->irq); - } - - /* Unmask interrupts */ - MCF_INTC0_ICR36 = 0x2; - MCF_INTC0_ICR37 = 0x2; - MCF_INTC0_ICR38 = 0x2; - MCF_INTC0_ICR39 = 0x2; - MCF_INTC0_ICR40 = 0x2; - MCF_INTC0_ICR41 = 0x2; - MCF_INTC0_ICR42 = 0x2; - MCF_INTC0_ICR43 = 0x2; - MCF_INTC0_ICR44 = 0x2; - MCF_INTC0_ICR45 = 0x2; - MCF_INTC0_ICR46 = 0x2; - MCF_INTC0_ICR47 = 0x2; - MCF_INTC0_ICR48 = 0x2; - - MCF_INTC0_IMRH &= ~( - MCF_INTC_IMRH_INT_MASK36 | - MCF_INTC_IMRH_INT_MASK37 | - MCF_INTC_IMRH_INT_MASK38 | - MCF_INTC_IMRH_INT_MASK39 | - MCF_INTC_IMRH_INT_MASK40 | - MCF_INTC_IMRH_INT_MASK41 | - MCF_INTC_IMRH_INT_MASK42 | - MCF_INTC_IMRH_INT_MASK43 | - MCF_INTC_IMRH_INT_MASK44 | - MCF_INTC_IMRH_INT_MASK45 | - MCF_INTC_IMRH_INT_MASK46 | - MCF_INTC_IMRH_INT_MASK47 | - MCF_INTC_IMRH_INT_MASK48 ); - - /* Set up gpio outputs for MII lines */ - MCF_GPIO_PAR_FECI2C |= (0 | - MCF_GPIO_PAR_FECI2C_PAR_MDC_EMDC | - MCF_GPIO_PAR_FECI2C_PAR_MDIO_EMDIO); - MCF_GPIO_PAR_FEC = (0 | - MCF_GPIO_PAR_FEC_PAR_FEC_7W_FEC | - MCF_GPIO_PAR_FEC_PAR_FEC_MII_FEC); -} - -static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) -{ - volatile fec_t *fecp; - - fecp = fep->hwp; - fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04; - fecp->fec_x_cntrl = 0x00; - - /* - * Set MII speed to 2.5 MHz - */ - fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2; - fecp->fec_mii_speed = fep->phy_speed; - - fec_restart(dev, 0); -} - -static void __inline__ fec_get_mac(struct net_device *dev) -{ - struct fec_enet_private *fep = netdev_priv(dev); - volatile fec_t *fecp; - unsigned char *iap, tmpaddr[ETH_ALEN]; - - fecp = fep->hwp; - - if (FEC_FLASHMAC) { - /* - * Get MAC address from FLASH. - * If it is all 1's or 0's, use the default. - */ - iap = FEC_FLASHMAC; - if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) && - (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0)) - iap = fec_mac_default; - if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) && - (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff)) - iap = fec_mac_default; - } else { - *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low; - *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16); - iap = &tmpaddr[0]; - } - - memcpy(dev->dev_addr, iap, ETH_ALEN); - - /* Adjust MAC if using default MAC address */ - if (iap == fec_mac_default) - dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index; -} - -static void __inline__ fec_enable_phy_intr(void) -{ -} - -static void __inline__ fec_disable_phy_intr(void) -{ -} - -static void __inline__ fec_phy_ack_intr(void) -{ -} - -static void __inline__ fec_localhw_setup(void) -{ -} - -/* - * Do not need to make region uncached on 532x. - */ -static void __inline__ fec_uncache(unsigned long addr) -{ -} - -/* ------------------------------------------------------------------------- */ - - #else /* @@ -2154,12 +1985,9 @@ fec_enet_open(struct net_device *dev) mii_do_cmd(dev, fep->phy->config); mii_do_cmd(dev, phy_cmd_config); /* display configuration */ - /* Poll until the PHY tells us its configuration - * (not link state). - * Request is initiated by mii_do_cmd above, but answer - * comes by interrupt. - * This should take about 25 usec per register at 2.5 MHz, - * and we read approximately 5 registers. + /* FIXME: use netif_carrier_{on,off} ; this polls + * until link is up which is wrong... could be + * 30 seconds or more we are trapped in here. -jgarzik */ while(!fep->sequence_done) schedule(); @@ -2425,11 +2253,15 @@ int __init fec_enet_init(struct net_device *dev) */ fec_request_intrs(dev); + /* Clear and enable interrupts */ + fecp->fec_ievent = 0xffc00000; + fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); fecp->fec_hash_table_high = 0; fecp->fec_hash_table_low = 0; fecp->fec_r_buff_size = PKT_MAXBLR_SIZE; fecp->fec_ecntrl = 2; - fecp->fec_r_des_active = 0; + fecp->fec_r_des_active = 0x01000000; dev->base_addr = (unsigned long)fecp; @@ -2449,11 +2281,6 @@ int __init fec_enet_init(struct net_device *dev) /* setup MII interface */ fec_set_mii(dev, fep); - /* Clear and enable interrupts */ - fecp->fec_ievent = 0xffc00000; - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | - FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); - /* Queue up command to detect the PHY and initialize the * remainder of the interface. */ @@ -2485,6 +2312,11 @@ fec_restart(struct net_device *dev, int duplex) fecp->fec_ecntrl = 1; udelay(10); + /* Enable interrupts we wish to service. + */ + fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | + FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); + /* Clear any outstanding interrupt. */ fecp->fec_ievent = 0xffc00000; @@ -2576,12 +2408,7 @@ fec_restart(struct net_device *dev, int duplex) /* And last, enable the transmit and receive processing. */ fecp->fec_ecntrl = 2; - fecp->fec_r_des_active = 0; - - /* Enable interrupts we wish to service. - */ - fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB | - FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII); + fecp->fec_r_des_active = 0x01000000; } static void @@ -2593,16 +2420,9 @@ fec_stop(struct net_device *dev) fep = netdev_priv(dev); fecp = fep->hwp; - /* - ** We cannot expect a graceful transmit stop without link !!! - */ - if (fep->link) - { - fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ - udelay(10); - if (!(fecp->fec_ievent & FEC_ENET_GRA)) - printk("fec_stop : Graceful transmit stop did not complete !\n"); - } + fecp->fec_x_cntrl = 0x01; /* Graceful transmit stop */ + + while(!(fecp->fec_ievent & FEC_ENET_GRA)); /* Whack a reset. We should wait for this. */ diff --git a/trunk/drivers/net/fs_enet/fs_enet-mii.c b/trunk/drivers/net/fs_enet/fs_enet-mii.c index 0cd07150bf4a..c6770377ef87 100644 --- a/trunk/drivers/net/fs_enet/fs_enet-mii.c +++ b/trunk/drivers/net/fs_enet/fs_enet-mii.c @@ -431,7 +431,8 @@ static struct fs_enet_mii_bus *create_bus(const struct fs_mii_bus_info *bi) return bus; err: - kfree(bus); + if (bus) + kfree(bus); return ERR_PTR(ret); } diff --git a/trunk/drivers/net/hamradio/dmascc.c b/trunk/drivers/net/hamradio/dmascc.c index c9a46b89942a..0d5fccc984bb 100644 --- a/trunk/drivers/net/hamradio/dmascc.c +++ b/trunk/drivers/net/hamradio/dmascc.c @@ -436,7 +436,7 @@ static int __init dmascc_init(void) module_init(dmascc_init); module_exit(dmascc_exit); -static void __init dev_setup(struct net_device *dev) +static void dev_setup(struct net_device *dev) { dev->type = ARPHRD_AX25; dev->hard_header_len = AX25_MAX_HEADER_LEN; diff --git a/trunk/drivers/net/natsemi.c b/trunk/drivers/net/natsemi.c index 5657049c2160..2e4ecedba057 100644 --- a/trunk/drivers/net/natsemi.c +++ b/trunk/drivers/net/natsemi.c @@ -226,6 +226,7 @@ static int full_duplex[MAX_UNITS]; NATSEMI_PG1_NREGS) #define NATSEMI_REGS_VER 1 /* v1 added RFDR registers */ #define NATSEMI_REGS_SIZE (NATSEMI_NREGS * sizeof(u32)) +#define NATSEMI_DEF_EEPROM_SIZE 24 /* 12 16-bit values */ /* Buffer sizes: * The nic writes 32-bit values, even if the upper bytes of @@ -343,6 +344,18 @@ None characterised. +enum pcistuff { + PCI_USES_IO = 0x01, + PCI_USES_MEM = 0x02, + PCI_USES_MASTER = 0x04, + PCI_ADDR0 = 0x08, + PCI_ADDR1 = 0x10, +}; + +/* MMIO operations required */ +#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1) + + /* * Support for fibre connections on Am79C874: * This phy needs a special setup when connected to a fibre cable. @@ -350,25 +363,22 @@ None characterised. */ #define PHYID_AM79C874 0x0022561b -enum { - MII_MCTRL = 0x15, /* mode control register */ - MII_FX_SEL = 0x0001, /* 100BASE-FX (fiber) */ - MII_EN_SCRM = 0x0004, /* enable scrambler (tp) */ -}; +#define MII_MCTRL 0x15 /* mode control register */ +#define MII_FX_SEL 0x0001 /* 100BASE-FX (fiber) */ +#define MII_EN_SCRM 0x0004 /* enable scrambler (tp) */ /* array of board data directly indexed by pci_tbl[x].driver_data */ static const struct { const char *name; unsigned long flags; - unsigned int eeprom_size; } natsemi_pci_info[] __devinitdata = { - { "NatSemi DP8381[56]", 0, 24 }, + { "NatSemi DP8381[56]", PCI_IOTYPE }, }; -static const struct pci_device_id natsemi_pci_tbl[] __devinitdata = { - { PCI_VENDOR_ID_NS, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { } /* terminate list */ +static struct pci_device_id natsemi_pci_tbl[] = { + { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815, PCI_ANY_ID, PCI_ANY_ID, }, + { 0, }, }; MODULE_DEVICE_TABLE(pci, natsemi_pci_tbl); @@ -803,42 +813,6 @@ static void move_int_phy(struct net_device *dev, int addr) udelay(1); } -static void __devinit natsemi_init_media (struct net_device *dev) -{ - struct netdev_private *np = netdev_priv(dev); - u32 tmp; - - netif_carrier_off(dev); - - /* get the initial settings from hardware */ - tmp = mdio_read(dev, MII_BMCR); - np->speed = (tmp & BMCR_SPEED100)? SPEED_100 : SPEED_10; - np->duplex = (tmp & BMCR_FULLDPLX)? DUPLEX_FULL : DUPLEX_HALF; - np->autoneg = (tmp & BMCR_ANENABLE)? AUTONEG_ENABLE: AUTONEG_DISABLE; - np->advertising= mdio_read(dev, MII_ADVERTISE); - - if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL - && netif_msg_probe(np)) { - printk(KERN_INFO "natsemi %s: Transceiver default autonegotiation %s " - "10%s %s duplex.\n", - pci_name(np->pci_dev), - (mdio_read(dev, MII_BMCR) & BMCR_ANENABLE)? - "enabled, advertise" : "disabled, force", - (np->advertising & - (ADVERTISE_100FULL|ADVERTISE_100HALF))? - "0" : "", - (np->advertising & - (ADVERTISE_100FULL|ADVERTISE_10FULL))? - "full" : "half"); - } - if (netif_msg_probe(np)) - printk(KERN_INFO - "natsemi %s: Transceiver status %#04x advertising %#04x.\n", - pci_name(np->pci_dev), mdio_read(dev, MII_BMSR), - np->advertising); - -} - static int __devinit natsemi_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -878,7 +852,8 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, iosize = pci_resource_len(pdev, pcibar); irq = pdev->irq; - pci_set_master(pdev); + if (natsemi_pci_info[chip_idx].flags & PCI_USES_MASTER) + pci_set_master(pdev); dev = alloc_etherdev(sizeof (struct netdev_private)); if (!dev) @@ -917,7 +892,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, np->msg_enable = (debug >= 0) ? (1<hands_off = 0; np->intr_status = 0; - np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size; + np->eeprom_size = NATSEMI_DEF_EEPROM_SIZE; /* Initial port: * - If the nic was configured to use an external phy and if find_mii @@ -982,7 +957,34 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, if (mtu) dev->mtu = mtu; - natsemi_init_media(dev); + netif_carrier_off(dev); + + /* get the initial settings from hardware */ + tmp = mdio_read(dev, MII_BMCR); + np->speed = (tmp & BMCR_SPEED100)? SPEED_100 : SPEED_10; + np->duplex = (tmp & BMCR_FULLDPLX)? DUPLEX_FULL : DUPLEX_HALF; + np->autoneg = (tmp & BMCR_ANENABLE)? AUTONEG_ENABLE: AUTONEG_DISABLE; + np->advertising= mdio_read(dev, MII_ADVERTISE); + + if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL + && netif_msg_probe(np)) { + printk(KERN_INFO "natsemi %s: Transceiver default autonegotiation %s " + "10%s %s duplex.\n", + pci_name(np->pci_dev), + (mdio_read(dev, MII_BMCR) & BMCR_ANENABLE)? + "enabled, advertise" : "disabled, force", + (np->advertising & + (ADVERTISE_100FULL|ADVERTISE_100HALF))? + "0" : "", + (np->advertising & + (ADVERTISE_100FULL|ADVERTISE_10FULL))? + "full" : "half"); + } + if (netif_msg_probe(np)) + printk(KERN_INFO + "natsemi %s: Transceiver status %#04x advertising %#04x.\n", + pci_name(np->pci_dev), mdio_read(dev, MII_BMSR), + np->advertising); /* save the silicon revision for later querying */ np->srr = readl(ioaddr + SiliconRev); diff --git a/trunk/drivers/net/pcnet32.c b/trunk/drivers/net/pcnet32.c index 0e01c75da429..fc08c4af506c 100644 --- a/trunk/drivers/net/pcnet32.c +++ b/trunk/drivers/net/pcnet32.c @@ -309,6 +309,12 @@ static int pcnet32_alloc_ring(struct net_device *dev, char *name); static void pcnet32_free_ring(struct net_device *dev); static void pcnet32_check_media(struct net_device *dev, int verbose); +enum pci_flags_bit { + PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4, + PCI_ADDR0 = 0x10 << 0, PCI_ADDR1 = 0x10 << 1, PCI_ADDR2 = + 0x10 << 2, PCI_ADDR3 = 0x10 << 3, +}; + static u16 pcnet32_wio_read_csr(unsigned long addr, int index) { outw(index, addr + PCNET32_WIO_RAP); diff --git a/trunk/drivers/net/phy/lxt.c b/trunk/drivers/net/phy/lxt.c index 3f702c503afe..bef79e454c33 100644 --- a/trunk/drivers/net/phy/lxt.c +++ b/trunk/drivers/net/phy/lxt.c @@ -123,9 +123,9 @@ static int lxt971_config_intr(struct phy_device *phydev) } static struct phy_driver lxt970_driver = { - .phy_id = 0x78100000, + .phy_id = 0x07810000, .name = "LXT970", - .phy_id_mask = 0xfffffff0, + .phy_id_mask = 0x0fffffff, .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT, .config_init = lxt970_config_init, @@ -137,9 +137,9 @@ static struct phy_driver lxt970_driver = { }; static struct phy_driver lxt971_driver = { - .phy_id = 0x001378e0, + .phy_id = 0x0001378e, .name = "LXT971", - .phy_id_mask = 0xfffffff0, + .phy_id_mask = 0x0fffffff, .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT, .config_aneg = genphy_config_aneg, diff --git a/trunk/drivers/net/tulip/winbond-840.c b/trunk/drivers/net/tulip/winbond-840.c index 602a6e5002a0..8fea2aa455d4 100644 --- a/trunk/drivers/net/tulip/winbond-840.c +++ b/trunk/drivers/net/tulip/winbond-840.c @@ -212,15 +212,26 @@ Test with 'ping -s 10000' on a fast computer. /* PCI probe table. */ -enum chip_capability_flags { - CanHaveMII=1, HasBrokenTx=2, AlwaysFDX=4, FDXOnNoMII=8, +enum pci_id_flags_bits { + /* Set PCI command register bits before calling probe1(). */ + PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, + /* Read and map the single following PCI BAR. */ + PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4, + PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400, }; +enum chip_capability_flags { + CanHaveMII=1, HasBrokenTx=2, AlwaysFDX=4, FDXOnNoMII=8,}; +#ifdef USE_IO_OPS +#define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER) +#else +#define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER) +#endif -static const struct pci_device_id w840_pci_tbl[] = { +static struct pci_device_id w840_pci_tbl[] = { { 0x1050, 0x0840, PCI_ANY_ID, 0x8153, 0, 0, 0 }, { 0x1050, 0x0840, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, { 0x11f6, 0x2011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, - { } + { 0, } }; MODULE_DEVICE_TABLE(pci, w840_pci_tbl); @@ -230,17 +241,18 @@ struct pci_id_info { int pci, pci_mask, subsystem, subsystem_mask; int revision, revision_mask; /* Only 8 bits. */ } id; + enum pci_id_flags_bits pci_flags; int io_size; /* Needed for I/O region check or ioremap(). */ int drv_flags; /* Driver use, intended as capability flags. */ }; static struct pci_id_info pci_id_tbl[] = { {"Winbond W89c840", /* Sometime a Level-One switch card. */ { 0x08401050, 0xffffffff, 0x81530000, 0xffff0000 }, - 128, CanHaveMII | HasBrokenTx | FDXOnNoMII}, + W840_FLAGS, 128, CanHaveMII | HasBrokenTx | FDXOnNoMII}, {"Winbond W89c840", { 0x08401050, 0xffffffff, }, - 128, CanHaveMII | HasBrokenTx}, + W840_FLAGS, 128, CanHaveMII | HasBrokenTx}, {"Compex RL100-ATX", { 0x201111F6, 0xffffffff,}, - 128, CanHaveMII | HasBrokenTx}, + W840_FLAGS, 128, CanHaveMII | HasBrokenTx}, {NULL,}, /* 0 terminated list. */ }; diff --git a/trunk/drivers/net/wan/c101.c b/trunk/drivers/net/wan/c101.c index c92ac9fde083..b60ef02db7b0 100644 --- a/trunk/drivers/net/wan/c101.c +++ b/trunk/drivers/net/wan/c101.c @@ -7,7 +7,7 @@ * under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * - * For information see + * For information see http://hq.pm.waw.pl/hdlc/ * * Sources of information: * Hitachi HD64570 SCA User's Manual diff --git a/trunk/drivers/net/wan/n2.c b/trunk/drivers/net/wan/n2.c index e013b817cab8..b7d88db89a5c 100644 --- a/trunk/drivers/net/wan/n2.c +++ b/trunk/drivers/net/wan/n2.c @@ -7,7 +7,7 @@ * under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * - * For information see + * For information see http://hq.pm.waw.pl/hdlc/ * * Note: integrated CSU/DSU/DDS are not supported by this driver * diff --git a/trunk/drivers/net/wan/pci200syn.c b/trunk/drivers/net/wan/pci200syn.c index 24c3c57c13c9..670e8bd2245c 100644 --- a/trunk/drivers/net/wan/pci200syn.c +++ b/trunk/drivers/net/wan/pci200syn.c @@ -7,7 +7,7 @@ * under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * - * For information see + * For information see http://hq.pm.waw.pl/hdlc/ * * Sources of information: * Hitachi HD64572 SCA-II User's Manual diff --git a/trunk/drivers/net/wireless/ipw2200.c b/trunk/drivers/net/wireless/ipw2200.c index a8a8f975432f..081a8999666e 100644 --- a/trunk/drivers/net/wireless/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2200.c @@ -1229,6 +1229,12 @@ static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv) return error; } +static void ipw_free_error_log(struct ipw_fw_error *error) +{ + if (error) + kfree(error); +} + static ssize_t show_event_log(struct device *d, struct device_attribute *attr, char *buf) { @@ -1290,9 +1296,10 @@ static ssize_t clear_error(struct device *d, const char *buf, size_t count) { struct ipw_priv *priv = dev_get_drvdata(d); - - kfree(priv->error); - priv->error = NULL; + if (priv->error) { + ipw_free_error_log(priv->error); + priv->error = NULL; + } return count; } @@ -1963,7 +1970,8 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) struct ipw_fw_error *error = ipw_alloc_error_log(priv); ipw_dump_error_log(priv, error); - kfree(error); + if (error) + ipw_free_error_log(error); } #endif } else { @@ -11685,8 +11693,10 @@ static void ipw_pci_remove(struct pci_dev *pdev) } } - kfree(priv->error); - priv->error = NULL; + if (priv->error) { + ipw_free_error_log(priv->error); + priv->error = NULL; + } #ifdef CONFIG_IPW2200_PROMISCUOUS ipw_prom_free(priv); diff --git a/trunk/drivers/net/yellowfin.c b/trunk/drivers/net/yellowfin.c index 569305f57561..ecec8e5db786 100644 --- a/trunk/drivers/net/yellowfin.c +++ b/trunk/drivers/net/yellowfin.c @@ -234,6 +234,14 @@ See Packet Engines confidential appendix (prototype chips only). +enum pci_id_flags_bits { + /* Set PCI command register bits before calling probe1(). */ + PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, + /* Read and map the single following PCI BAR. */ + PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4, + PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400, + PCI_UNUSED_IRQ=0x800, +}; enum capability_flags { HasMII=1, FullTxStatus=2, IsGigabit=4, HasMulticastBug=8, FullRxStatus=16, HasMACAddrBug=32, /* Only on early revs. */ @@ -241,6 +249,11 @@ enum capability_flags { }; /* The PCI I/O space extent. */ #define YELLOWFIN_SIZE 0x100 +#ifdef USE_IO_OPS +#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0) +#else +#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1) +#endif struct pci_id_info { const char *name; @@ -248,23 +261,24 @@ struct pci_id_info { int pci, pci_mask, subsystem, subsystem_mask; int revision, revision_mask; /* Only 8 bits. */ } id; + enum pci_id_flags_bits pci_flags; int io_size; /* Needed for I/O region check or ioremap(). */ int drv_flags; /* Driver use, intended as capability flags. */ }; static const struct pci_id_info pci_id_tbl[] = { {"Yellowfin G-NIC Gigabit Ethernet", { 0x07021000, 0xffffffff}, - YELLOWFIN_SIZE, + PCI_IOTYPE, YELLOWFIN_SIZE, FullTxStatus | IsGigabit | HasMulticastBug | HasMACAddrBug | DontUseEeprom}, {"Symbios SYM83C885", { 0x07011000, 0xffffffff}, - YELLOWFIN_SIZE, HasMII | DontUseEeprom }, - { } + PCI_IOTYPE, YELLOWFIN_SIZE, HasMII | DontUseEeprom }, + {NULL,}, }; -static const struct pci_device_id yellowfin_pci_tbl[] = { +static struct pci_device_id yellowfin_pci_tbl[] = { { 0x1000, 0x0702, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, { 0x1000, 0x0701, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, - { } + { 0, } }; MODULE_DEVICE_TABLE (pci, yellowfin_pci_tbl); diff --git a/trunk/drivers/parisc/dino.c b/trunk/drivers/parisc/dino.c index ce0a6ebcff15..6e8ed0c81a6c 100644 --- a/trunk/drivers/parisc/dino.c +++ b/trunk/drivers/parisc/dino.c @@ -299,7 +299,7 @@ struct pci_port_ops dino_port_ops = { static void dino_disable_irq(unsigned int irq) { - struct dino_device *dino_dev = irq_desc[irq].chip_data; + struct dino_device *dino_dev = irq_desc[irq].handler_data; int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); @@ -311,7 +311,7 @@ static void dino_disable_irq(unsigned int irq) static void dino_enable_irq(unsigned int irq) { - struct dino_device *dino_dev = irq_desc[irq].chip_data; + struct dino_device *dino_dev = irq_desc[irq].handler_data; int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); u32 tmp; diff --git a/trunk/drivers/parisc/eisa.c b/trunk/drivers/parisc/eisa.c index 58f0ce8d78e0..9d3bd15bf53b 100644 --- a/trunk/drivers/parisc/eisa.c +++ b/trunk/drivers/parisc/eisa.c @@ -350,7 +350,7 @@ static int __devinit eisa_probe(struct parisc_device *dev) irq_desc[2].action = &irq2_action; for (i = 0; i < 16; i++) { - irq_desc[i].chip = &eisa_interrupt_type; + irq_desc[i].handler = &eisa_interrupt_type; } EISA_bus = 1; diff --git a/trunk/drivers/parisc/gsc.c b/trunk/drivers/parisc/gsc.c index 5476ba7709b3..16d40f95978d 100644 --- a/trunk/drivers/parisc/gsc.c +++ b/trunk/drivers/parisc/gsc.c @@ -109,7 +109,7 @@ int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit) static void gsc_asic_disable_irq(unsigned int irq) { - struct gsc_asic *irq_dev = irq_desc[irq].chip_data; + struct gsc_asic *irq_dev = irq_desc[irq].handler_data; int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); u32 imr; @@ -124,7 +124,7 @@ static void gsc_asic_disable_irq(unsigned int irq) static void gsc_asic_enable_irq(unsigned int irq) { - struct gsc_asic *irq_dev = irq_desc[irq].chip_data; + struct gsc_asic *irq_dev = irq_desc[irq].handler_data; int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); u32 imr; @@ -164,8 +164,8 @@ int gsc_assign_irq(struct hw_interrupt_type *type, void *data) if (irq > GSC_IRQ_MAX) return NO_IRQ; - irq_desc[irq].chip = type; - irq_desc[irq].chip_data = data; + irq_desc[irq].handler = type; + irq_desc[irq].handler_data = data; return irq++; } diff --git a/trunk/drivers/parisc/iosapic.c b/trunk/drivers/parisc/iosapic.c index 1fbda77cefc2..7a458d5bc751 100644 --- a/trunk/drivers/parisc/iosapic.c +++ b/trunk/drivers/parisc/iosapic.c @@ -619,7 +619,7 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1) static struct vector_info *iosapic_get_vector(unsigned int irq) { - return irq_desc[irq].chip_data; + return irq_desc[irq].handler_data; } static void iosapic_disable_irq(unsigned int irq) diff --git a/trunk/drivers/parisc/superio.c b/trunk/drivers/parisc/superio.c index a988dc7a9abd..828eb45062de 100644 --- a/trunk/drivers/parisc/superio.c +++ b/trunk/drivers/parisc/superio.c @@ -360,7 +360,7 @@ int superio_fixup_irq(struct pci_dev *pcidev) #endif for (i = 0; i < 16; i++) { - irq_desc[i].chip = &superio_interrupt_type; + irq_desc[i].handler = &superio_interrupt_type; } /* diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index 76d023d8a33b..7f8429284fab 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -429,12 +429,12 @@ static void irq_handler_init(int cap_id, int pos, int mask) spin_lock_irqsave(&irq_desc[pos].lock, flags); if (cap_id == PCI_CAP_ID_MSIX) - irq_desc[pos].chip = &msix_irq_type; + irq_desc[pos].handler = &msix_irq_type; else { if (!mask) - irq_desc[pos].chip = &msi_irq_wo_maskbit_type; + irq_desc[pos].handler = &msi_irq_wo_maskbit_type; else - irq_desc[pos].chip = &msi_irq_w_maskbit_type; + irq_desc[pos].handler = &msi_irq_w_maskbit_type; } spin_unlock_irqrestore(&irq_desc[pos].lock, flags); } diff --git a/trunk/drivers/pcmcia/hd64465_ss.c b/trunk/drivers/pcmcia/hd64465_ss.c index c662e4f89d46..b39435bbfaeb 100644 --- a/trunk/drivers/pcmcia/hd64465_ss.c +++ b/trunk/drivers/pcmcia/hd64465_ss.c @@ -244,8 +244,8 @@ static void hs_map_irq(hs_socket_t *sp, unsigned int irq) hs_mapped_irq[irq].sock = sp; /* insert ourselves as the irq controller */ - hs_mapped_irq[irq].old_handler = irq_desc[irq].chip; - irq_desc[irq].chip = &hd64465_ss_irq_type; + hs_mapped_irq[irq].old_handler = irq_desc[irq].handler; + irq_desc[irq].handler = &hd64465_ss_irq_type; } @@ -260,7 +260,7 @@ static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq) return; /* restore the original irq controller */ - irq_desc[irq].chip = hs_mapped_irq[irq].old_handler; + irq_desc[irq].handler = hs_mapped_irq[irq].old_handler; } /*============================================================*/ diff --git a/trunk/drivers/pcmcia/m8xx_pcmcia.c b/trunk/drivers/pcmcia/m8xx_pcmcia.c index d0f68ab8f041..0e07d9535116 100644 --- a/trunk/drivers/pcmcia/m8xx_pcmcia.c +++ b/trunk/drivers/pcmcia/m8xx_pcmcia.c @@ -157,7 +157,7 @@ MODULE_LICENSE("Dual MPL/GPL"); static int pcmcia_schlvl = PCMCIA_SCHLVL; -static DEFINE_SPINLOCK(events_lock); +static spinlock_t events_lock = SPIN_LOCK_UNLOCKED; #define PCMCIA_SOCKET_KEY_5V 1 @@ -644,7 +644,7 @@ static struct platform_device m8xx_device = { }; static u32 pending_events[PCMCIA_SOCKETS_NO]; -static DEFINE_SPINLOCK(pending_event_lock); +static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED; static irqreturn_t m8xx_interrupt(int irq, void *dev, struct pt_regs *regs) { diff --git a/trunk/drivers/rapidio/rio-access.c b/trunk/drivers/rapidio/rio-access.c index 8b56bbdd011e..b9fab2ae3a36 100644 --- a/trunk/drivers/rapidio/rio-access.c +++ b/trunk/drivers/rapidio/rio-access.c @@ -17,8 +17,8 @@ * These interrupt-safe spinlocks protect all accesses to RIO * configuration space and doorbell access. */ -static DEFINE_SPINLOCK(rio_config_lock); -static DEFINE_SPINLOCK(rio_doorbell_lock); +static spinlock_t rio_config_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t rio_doorbell_lock = SPIN_LOCK_UNLOCKED; /* * Wrappers for all RIO configuration access functions. They just check diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index f2fc81a9074d..bccff400b198 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -162,16 +162,6 @@ config RTC_DRV_PCF8583 This driver can also be built as a module. If so, the module will be called rtc-pcf8583. -config RTC_DRV_RS5C348 - tristate "Ricoh RS5C348A/B" - depends on RTC_CLASS && SPI - help - If you say yes here you get support for the - Ricoh RS5C348A and RS5C348B RTC chips. - - This driver can also be built as a module. If so, the module - will be called rtc-rs5c348. - config RTC_DRV_RS5C372 tristate "Ricoh RS5C372A/B" depends on RTC_CLASS && I2C diff --git a/trunk/drivers/rtc/Makefile b/trunk/drivers/rtc/Makefile index da5e38774e13..900d210dd1a2 100644 --- a/trunk/drivers/rtc/Makefile +++ b/trunk/drivers/rtc/Makefile @@ -19,7 +19,6 @@ obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o -obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o diff --git a/trunk/drivers/rtc/class.c b/trunk/drivers/rtc/class.c index 1cb61a761cb2..5396beec30d0 100644 --- a/trunk/drivers/rtc/class.c +++ b/trunk/drivers/rtc/class.c @@ -94,9 +94,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, kfree(rtc); exit_idr: - mutex_lock(&idr_lock); idr_remove(&rtc_idr, id); - mutex_unlock(&idr_lock); exit: dev_err(dev, "rtc core: unable to register %s, err = %d\n", diff --git a/trunk/drivers/rtc/rtc-ds1553.c b/trunk/drivers/rtc/rtc-ds1553.c index 762521a1419c..ecafbad41a24 100644 --- a/trunk/drivers/rtc/rtc-ds1553.c +++ b/trunk/drivers/rtc/rtc-ds1553.c @@ -226,7 +226,7 @@ static int ds1553_rtc_ioctl(struct device *dev, unsigned int cmd, struct rtc_plat_data *pdata = platform_get_drvdata(pdev); if (pdata->irq < 0) - return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ + return -ENOIOCTLCMD; switch (cmd) { case RTC_AIE_OFF: pdata->irqen &= ~RTC_AF; diff --git a/trunk/drivers/rtc/rtc-rs5c348.c b/trunk/drivers/rtc/rtc-rs5c348.c deleted file mode 100644 index 0964d1dba925..000000000000 --- a/trunk/drivers/rtc/rtc-rs5c348.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * A SPI driver for the Ricoh RS5C348 RTC - * - * Copyright (C) 2006 Atsushi Nemoto - * - * 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. - * - * The board specific init code should provide characteristics of this - * device: - * Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRV_VERSION "0.1" - -#define RS5C348_REG_SECS 0 -#define RS5C348_REG_MINS 1 -#define RS5C348_REG_HOURS 2 -#define RS5C348_REG_WDAY 3 -#define RS5C348_REG_DAY 4 -#define RS5C348_REG_MONTH 5 -#define RS5C348_REG_YEAR 6 -#define RS5C348_REG_CTL1 14 -#define RS5C348_REG_CTL2 15 - -#define RS5C348_SECS_MASK 0x7f -#define RS5C348_MINS_MASK 0x7f -#define RS5C348_HOURS_MASK 0x3f -#define RS5C348_WDAY_MASK 0x03 -#define RS5C348_DAY_MASK 0x3f -#define RS5C348_MONTH_MASK 0x1f - -#define RS5C348_BIT_PM 0x20 /* REG_HOURS */ -#define RS5C348_BIT_Y2K 0x80 /* REG_MONTH */ -#define RS5C348_BIT_24H 0x20 /* REG_CTL1 */ -#define RS5C348_BIT_XSTP 0x10 /* REG_CTL2 */ -#define RS5C348_BIT_VDET 0x40 /* REG_CTL2 */ - -#define RS5C348_CMD_W(addr) (((addr) << 4) | 0x08) /* single write */ -#define RS5C348_CMD_R(addr) (((addr) << 4) | 0x0c) /* single read */ -#define RS5C348_CMD_MW(addr) (((addr) << 4) | 0x00) /* burst write */ -#define RS5C348_CMD_MR(addr) (((addr) << 4) | 0x04) /* burst read */ - -struct rs5c348_plat_data { - struct rtc_device *rtc; - int rtc_24h; -}; - -static int -rs5c348_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - struct spi_device *spi = to_spi_device(dev); - struct rs5c348_plat_data *pdata = spi->dev.platform_data; - u8 txbuf[5+7], *txp; - int ret; - - /* Transfer 5 bytes before writing SEC. This gives 31us for carry. */ - txp = txbuf; - txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */ - txbuf[1] = 0; /* dummy */ - txbuf[2] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */ - txbuf[3] = 0; /* dummy */ - txbuf[4] = RS5C348_CMD_MW(RS5C348_REG_SECS); /* cmd, sec, ... */ - txp = &txbuf[5]; - txp[RS5C348_REG_SECS] = BIN2BCD(tm->tm_sec); - txp[RS5C348_REG_MINS] = BIN2BCD(tm->tm_min); - if (pdata->rtc_24h) { - txp[RS5C348_REG_HOURS] = BIN2BCD(tm->tm_hour); - } else { - /* hour 0 is AM12, noon is PM12 */ - txp[RS5C348_REG_HOURS] = BIN2BCD((tm->tm_hour + 11) % 12 + 1) | - (tm->tm_hour >= 12 ? RS5C348_BIT_PM : 0); - } - txp[RS5C348_REG_WDAY] = BIN2BCD(tm->tm_wday); - txp[RS5C348_REG_DAY] = BIN2BCD(tm->tm_mday); - txp[RS5C348_REG_MONTH] = BIN2BCD(tm->tm_mon + 1) | - (tm->tm_year >= 100 ? RS5C348_BIT_Y2K : 0); - txp[RS5C348_REG_YEAR] = BIN2BCD(tm->tm_year % 100); - /* write in one transfer to avoid data inconsistency */ - ret = spi_write_then_read(spi, txbuf, sizeof(txbuf), NULL, 0); - udelay(62); /* Tcsr 62us */ - return ret; -} - -static int -rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - struct spi_device *spi = to_spi_device(dev); - struct rs5c348_plat_data *pdata = spi->dev.platform_data; - u8 txbuf[5], rxbuf[7]; - int ret; - - /* Transfer 5 byte befores reading SEC. This gives 31us for carry. */ - txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */ - txbuf[1] = 0; /* dummy */ - txbuf[2] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */ - txbuf[3] = 0; /* dummy */ - txbuf[4] = RS5C348_CMD_MR(RS5C348_REG_SECS); /* cmd, sec, ... */ - - /* read in one transfer to avoid data inconsistency */ - ret = spi_write_then_read(spi, txbuf, sizeof(txbuf), - rxbuf, sizeof(rxbuf)); - udelay(62); /* Tcsr 62us */ - if (ret < 0) - return ret; - - tm->tm_sec = BCD2BIN(rxbuf[RS5C348_REG_SECS] & RS5C348_SECS_MASK); - tm->tm_min = BCD2BIN(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); - tm->tm_hour = BCD2BIN(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); - if (!pdata->rtc_24h) { - tm->tm_hour %= 12; - if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) - tm->tm_hour += 12; - } - tm->tm_wday = BCD2BIN(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); - tm->tm_mday = BCD2BIN(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); - tm->tm_mon = - BCD2BIN(rxbuf[RS5C348_REG_MONTH] & RS5C348_MONTH_MASK) - 1; - /* year is 1900 + tm->tm_year */ - tm->tm_year = BCD2BIN(rxbuf[RS5C348_REG_YEAR]) + - ((rxbuf[RS5C348_REG_MONTH] & RS5C348_BIT_Y2K) ? 100 : 0); - - if (rtc_valid_tm(tm) < 0) { - dev_err(&spi->dev, "retrieved date/time is not valid.\n"); - rtc_time_to_tm(0, tm); - } - - return 0; -} - -static struct rtc_class_ops rs5c348_rtc_ops = { - .read_time = rs5c348_rtc_read_time, - .set_time = rs5c348_rtc_set_time, -}; - -static struct spi_driver rs5c348_driver; - -static int __devinit rs5c348_probe(struct spi_device *spi) -{ - int ret; - struct rtc_device *rtc; - struct rs5c348_plat_data *pdata; - - pdata = kzalloc(sizeof(struct rs5c348_plat_data), GFP_KERNEL); - if (!pdata) - return -ENOMEM; - spi->dev.platform_data = pdata; - - /* Check D7 of SECOND register */ - ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_SECS)); - if (ret < 0 || (ret & 0x80)) { - dev_err(&spi->dev, "not found.\n"); - goto kfree_exit; - } - - dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n"); - dev_info(&spi->dev, "spiclk %u KHz.\n", - (spi->max_speed_hz + 500) / 1000); - - /* turn RTC on if it was not on */ - ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2)); - if (ret < 0) - goto kfree_exit; - if (ret & (RS5C348_BIT_XSTP | RS5C348_BIT_VDET)) { - u8 buf[2]; - if (ret & RS5C348_BIT_VDET) - dev_warn(&spi->dev, "voltage-low detected.\n"); - buf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2); - buf[1] = 0; - ret = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0); - if (ret < 0) - goto kfree_exit; - } - - ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL1)); - if (ret < 0) - goto kfree_exit; - if (ret & RS5C348_BIT_24H) - pdata->rtc_24h = 1; - - rtc = rtc_device_register(rs5c348_driver.driver.name, &spi->dev, - &rs5c348_rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc)) { - ret = PTR_ERR(rtc); - goto kfree_exit; - } - - pdata->rtc = rtc; - - return 0; - kfree_exit: - kfree(pdata); - return ret; -} - -static int __devexit rs5c348_remove(struct spi_device *spi) -{ - struct rs5c348_plat_data *pdata = spi->dev.platform_data; - struct rtc_device *rtc = pdata->rtc; - - if (rtc) - rtc_device_unregister(rtc); - kfree(pdata); - return 0; -} - -static struct spi_driver rs5c348_driver = { - .driver = { - .name = "rs5c348", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = rs5c348_probe, - .remove = __devexit_p(rs5c348_remove), -}; - -static __init int rs5c348_init(void) -{ - return spi_register_driver(&rs5c348_driver); -} - -static __exit void rs5c348_exit(void) -{ - spi_unregister_driver(&rs5c348_driver); -} - -module_init(rs5c348_init); -module_exit(rs5c348_exit); - -MODULE_AUTHOR("Atsushi Nemoto "); -MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); diff --git a/trunk/drivers/rtc/rtc-sa1100.c b/trunk/drivers/rtc/rtc-sa1100.c index 9cd1cb304bb2..ab486fbc828d 100644 --- a/trunk/drivers/rtc/rtc-sa1100.c +++ b/trunk/drivers/rtc/rtc-sa1100.c @@ -45,7 +45,7 @@ static unsigned long rtc_freq = 1024; static struct rtc_time rtc_alarm; -static DEFINE_SPINLOCK(sa1100_rtc_lock); +static spinlock_t sa1100_rtc_lock = SPIN_LOCK_UNLOCKED; static int rtc_update_alarm(struct rtc_time *alrm) { diff --git a/trunk/drivers/rtc/rtc-vr41xx.c b/trunk/drivers/rtc/rtc-vr41xx.c index 4b9291dd4443..33e029207e26 100644 --- a/trunk/drivers/rtc/rtc-vr41xx.c +++ b/trunk/drivers/rtc/rtc-vr41xx.c @@ -93,7 +93,7 @@ static void __iomem *rtc2_base; static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */ -static DEFINE_SPINLOCK(rtc_lock); +static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED; static char rtc_name[] = "RTC"; static unsigned long periodic_frequency; static unsigned long periodic_count; diff --git a/trunk/drivers/s390/block/dasd_eer.c b/trunk/drivers/s390/block/dasd_eer.c index 2d8af709947f..2d946b6ca074 100644 --- a/trunk/drivers/s390/block/dasd_eer.c +++ b/trunk/drivers/s390/block/dasd_eer.c @@ -89,7 +89,7 @@ struct eerbuffer { }; static LIST_HEAD(bufferlist); -static DEFINE_SPINLOCK(bufferlock); +static spinlock_t bufferlock = SPIN_LOCK_UNLOCKED; static DECLARE_WAIT_QUEUE_HEAD(dasd_eer_read_wait_queue); /* diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index 96a81cd17617..c84b02aec1f3 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -501,7 +501,7 @@ config SCSI_ATA_PIIX tristate "Intel PIIX/ICH SATA support" depends on SCSI_SATA && PCI help - This option enables support for ICH5/6/7/8 Serial ATA. + This option enables support for ICH5 Serial ATA. If PATA support was enabled previously, this enables support for select Intel PIIX/ICH PATA host controllers. diff --git a/trunk/drivers/scsi/ahci.c b/trunk/drivers/scsi/ahci.c index f05946777718..4bb77f62b3b9 100644 --- a/trunk/drivers/scsi/ahci.c +++ b/trunk/drivers/scsi/ahci.c @@ -48,7 +48,7 @@ #include #define DRV_NAME "ahci" -#define DRV_VERSION "2.0" +#define DRV_VERSION "1.3" enum { diff --git a/trunk/drivers/scsi/ata_piix.c b/trunk/drivers/scsi/ata_piix.c index 94b1261a259d..521b718763f6 100644 --- a/trunk/drivers/scsi/ata_piix.c +++ b/trunk/drivers/scsi/ata_piix.c @@ -93,7 +93,7 @@ #include #define DRV_NAME "ata_piix" -#define DRV_VERSION "2.00" +#define DRV_VERSION "1.10" enum { PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ diff --git a/trunk/drivers/scsi/libata-core.c b/trunk/drivers/scsi/libata-core.c index d1c1c30d123f..6c66877be2bf 100644 --- a/trunk/drivers/scsi/libata-core.c +++ b/trunk/drivers/scsi/libata-core.c @@ -88,10 +88,6 @@ int libata_fua = 0; module_param_named(fua, libata_fua, int, 0444); MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)"); -static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ; -module_param(ata_probe_timeout, int, 0444); -MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)"); - MODULE_AUTHOR("Jeff Garzik"); MODULE_DESCRIPTION("Library module for ATA devices"); MODULE_LICENSE("GPL"); @@ -781,9 +777,11 @@ void ata_std_dev_select (struct ata_port *ap, unsigned int device) void ata_dev_select(struct ata_port *ap, unsigned int device, unsigned int wait, unsigned int can_sleep) { - if (ata_msg_probe(ap)) + if (ata_msg_probe(ap)) { ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, ata%u: " - "device %u, wait %u\n", ap->id, device, wait); + "device %u, wait %u\n", + ap->id, device, wait); + } if (wait) ata_wait_idle(ap); @@ -952,8 +950,7 @@ void ata_port_flush_task(struct ata_port *ap) */ if (!cancel_delayed_work(&ap->port_task)) { if (ata_msg_ctl(ap)) - ata_port_printk(ap, KERN_DEBUG, "%s: flush #2\n", - __FUNCTION__); + ata_port_printk(ap, KERN_DEBUG, "%s: flush #2\n", __FUNCTION__); flush_workqueue(ata_wq); } @@ -1062,7 +1059,7 @@ unsigned ata_exec_internal(struct ata_device *dev, spin_unlock_irqrestore(ap->lock, flags); - rc = wait_for_completion_timeout(&wait, ata_probe_timeout); + rc = wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL); ata_port_flush_task(ap); @@ -1084,7 +1081,7 @@ unsigned ata_exec_internal(struct ata_device *dev, if (ata_msg_warn(ap)) ata_dev_printk(dev, KERN_WARNING, - "qc timeout (cmd 0x%x)\n", command); + "qc timeout (cmd 0x%x)\n", command); } spin_unlock_irqrestore(ap->lock, flags); @@ -1096,9 +1093,9 @@ unsigned ata_exec_internal(struct ata_device *dev, if (qc->flags & ATA_QCFLAG_FAILED && !qc->err_mask) { if (ata_msg_warn(ap)) - ata_dev_printk(dev, KERN_WARNING, + ata_dev_printk(dev, KERN_WARNING, "zero err_mask for failed " - "internal command, assuming AC_ERR_OTHER\n"); + "internal command, assuming AC_ERR_OTHER\n"); qc->err_mask |= AC_ERR_OTHER; } @@ -1134,33 +1131,6 @@ unsigned ata_exec_internal(struct ata_device *dev, return err_mask; } -/** - * ata_do_simple_cmd - execute simple internal command - * @dev: Device to which the command is sent - * @cmd: Opcode to execute - * - * Execute a 'simple' command, that only consists of the opcode - * 'cmd' itself, without filling any other registers - * - * LOCKING: - * Kernel thread context (may sleep). - * - * RETURNS: - * Zero on success, AC_ERR_* mask on failure - */ -unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd) -{ - struct ata_taskfile tf; - - ata_tf_init(dev, &tf); - - tf.command = cmd; - tf.flags |= ATA_TFLAG_DEVICE; - tf.protocol = ATA_PROT_NODATA; - - return ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); -} - /** * ata_pio_need_iordy - check if iordy needed * @adev: ATA device @@ -1223,8 +1193,8 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, int rc; if (ata_msg_ctl(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", - __FUNCTION__, ap->id, dev->devno); + ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", + __FUNCTION__, ap->id, dev->devno); ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ @@ -1293,9 +1263,9 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, return 0; err_out: - if (ata_msg_warn(ap)) + if (ata_msg_warn(ap)) ata_dev_printk(dev, KERN_WARNING, "failed to IDENTIFY " - "(%s, err_mask=0x%x)\n", reason, err_mask); + "(%s, err_mask=0x%x)\n", reason, err_mask); return rc; } @@ -1348,21 +1318,19 @@ int ata_dev_configure(struct ata_device *dev, int print_info) int i, rc; if (!ata_dev_enabled(dev) && ata_msg_info(ap)) { - ata_dev_printk(dev, KERN_INFO, - "%s: ENTER/EXIT (host %u, dev %u) -- nodev\n", - __FUNCTION__, ap->id, dev->devno); + ata_dev_printk(dev, KERN_INFO, "%s: ENTER/EXIT (host %u, dev %u) -- nodev\n", + __FUNCTION__, ap->id, dev->devno); return 0; } if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", - __FUNCTION__, ap->id, dev->devno); + ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER, host %u, dev %u\n", + __FUNCTION__, ap->id, dev->devno); /* print device capabilities */ if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: cfg 49:%04x 82:%04x 83:%04x 84:%04x " - "85:%04x 86:%04x 87:%04x 88:%04x\n", + ata_dev_printk(dev, KERN_DEBUG, "%s: cfg 49:%04x 82:%04x 83:%04x " + "84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n", __FUNCTION__, id[49], id[82], id[83], id[84], id[85], id[86], id[87], id[88]); @@ -1434,16 +1402,14 @@ int ata_dev_configure(struct ata_device *dev, int print_info) ata_id_major_version(id), ata_mode_string(xfer_mask), (unsigned long long)dev->n_sectors, - dev->cylinders, dev->heads, - dev->sectors); + dev->cylinders, dev->heads, dev->sectors); } if (dev->id[59] & 0x100) { dev->multi_count = dev->id[59] & 0xff; if (ata_msg_info(ap)) - ata_dev_printk(dev, KERN_INFO, - "ata%u: dev %u multi count %u\n", - ap->id, dev->devno, dev->multi_count); + ata_dev_printk(dev, KERN_INFO, "ata%u: dev %u multi count %u\n", + ap->id, dev->devno, dev->multi_count); } dev->cdb_len = 16; @@ -1456,8 +1422,8 @@ int ata_dev_configure(struct ata_device *dev, int print_info) rc = atapi_cdb_len(id); if ((rc < 12) || (rc > ATAPI_CDB_LEN)) { if (ata_msg_warn(ap)) - ata_dev_printk(dev, KERN_WARNING, - "unsupported CDB len\n"); + ata_dev_printk(dev, KERN_WARNING, + "unsupported CDB len\n"); rc = -EINVAL; goto err_out_nosup; } @@ -1500,8 +1466,8 @@ int ata_dev_configure(struct ata_device *dev, int print_info) err_out_nosup: if (ata_msg_probe(ap)) - ata_dev_printk(dev, KERN_DEBUG, - "%s: EXIT, err\n", __FUNCTION__); + ata_dev_printk(dev, KERN_DEBUG, + "%s: EXIT, err\n", __FUNCTION__); return rc; } @@ -3561,7 +3527,7 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) * Inherited from caller. */ -void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, +void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) { struct ata_port *ap = adev->ap; @@ -3607,7 +3573,7 @@ void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, * Inherited from caller. */ -void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf, +void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) { struct ata_port *ap = adev->ap; @@ -3641,7 +3607,7 @@ void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf, * @buflen: buffer length * @write_data: read/write * - * Transfer data from/to the device data register by PIO. Do the + * Transfer data from/to the device data register by PIO. Do the * transfer with interrupts disabled. * * LOCKING: @@ -4980,9 +4946,31 @@ int ata_port_offline(struct ata_port *ap) return 0; } -int ata_flush_cache(struct ata_device *dev) +/* + * Execute a 'simple' command, that only consists of the opcode 'cmd' itself, + * without filling any other registers + */ +static int ata_do_simple_cmd(struct ata_device *dev, u8 cmd) +{ + struct ata_taskfile tf; + int err; + + ata_tf_init(dev, &tf); + + tf.command = cmd; + tf.flags |= ATA_TFLAG_DEVICE; + tf.protocol = ATA_PROT_NODATA; + + err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); + if (err) + ata_dev_printk(dev, KERN_ERR, "%s: ata command failed: %d\n", + __FUNCTION__, err); + + return err; +} + +static int ata_flush_cache(struct ata_device *dev) { - unsigned int err_mask; u8 cmd; if (!ata_try_flush_cache(dev)) @@ -4993,41 +4981,17 @@ int ata_flush_cache(struct ata_device *dev) else cmd = ATA_CMD_FLUSH; - err_mask = ata_do_simple_cmd(dev, cmd); - if (err_mask) { - ata_dev_printk(dev, KERN_ERR, "failed to flush cache\n"); - return -EIO; - } - - return 0; + return ata_do_simple_cmd(dev, cmd); } static int ata_standby_drive(struct ata_device *dev) { - unsigned int err_mask; - - err_mask = ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1); - if (err_mask) { - ata_dev_printk(dev, KERN_ERR, "failed to standby drive " - "(err_mask=0x%x)\n", err_mask); - return -EIO; - } - - return 0; + return ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1); } static int ata_start_drive(struct ata_device *dev) { - unsigned int err_mask; - - err_mask = ata_do_simple_cmd(dev, ATA_CMD_IDLEIMMEDIATE); - if (err_mask) { - ata_dev_printk(dev, KERN_ERR, "failed to start drive " - "(err_mask=0x%x)\n", err_mask); - return -EIO; - } - - return 0; + return ata_do_simple_cmd(dev, ATA_CMD_IDLEIMMEDIATE); } /** @@ -5248,7 +5212,7 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, ap->msg_enable = 0x00FF; #elif defined(ATA_DEBUG) ap->msg_enable = ATA_MSG_DRV | ATA_MSG_INFO | ATA_MSG_CTL | ATA_MSG_WARN | ATA_MSG_ERR; -#else +#else ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN; #endif @@ -5745,7 +5709,6 @@ int ata_pci_device_resume(struct pci_dev *pdev) static int __init ata_init(void) { - ata_probe_timeout *= HZ; ata_wq = create_workqueue("ata"); if (!ata_wq) return -ENOMEM; @@ -5770,7 +5733,7 @@ module_init(ata_init); module_exit(ata_exit); static unsigned long ratelimit_time; -static DEFINE_SPINLOCK(ata_ratelimit_lock); +static spinlock_t ata_ratelimit_lock = SPIN_LOCK_UNLOCKED; int ata_ratelimit(void) { diff --git a/trunk/drivers/scsi/libata-eh.c b/trunk/drivers/scsi/libata-eh.c index bf5a72aca8a4..823385981a7a 100644 --- a/trunk/drivers/scsi/libata-eh.c +++ b/trunk/drivers/scsi/libata-eh.c @@ -93,38 +93,6 @@ static int ata_ering_map(struct ata_ering *ering, return rc; } -static unsigned int ata_eh_dev_action(struct ata_device *dev) -{ - struct ata_eh_context *ehc = &dev->ap->eh_context; - - return ehc->i.action | ehc->i.dev_action[dev->devno]; -} - -static void ata_eh_clear_action(struct ata_device *dev, - struct ata_eh_info *ehi, unsigned int action) -{ - int i; - - if (!dev) { - ehi->action &= ~action; - for (i = 0; i < ATA_MAX_DEVICES; i++) - ehi->dev_action[i] &= ~action; - } else { - /* doesn't make sense for port-wide EH actions */ - WARN_ON(!(action & ATA_EH_PERDEV_MASK)); - - /* break ehi->action into ehi->dev_action */ - if (ehi->action & action) { - for (i = 0; i < ATA_MAX_DEVICES; i++) - ehi->dev_action[i] |= ehi->action & action; - ehi->action &= ~action; - } - - /* turn off the specified per-dev action */ - ehi->dev_action[dev->devno] &= ~action; - } -} - /** * ata_scsi_timed_out - SCSI layer time out callback * @cmd: timed out SCSI command @@ -734,13 +702,34 @@ static void ata_eh_detach_dev(struct ata_device *dev) ap->flags |= ATA_FLAG_SCSI_HOTPLUG; } - /* clear per-dev EH actions */ - ata_eh_clear_action(dev, &ap->eh_info, ATA_EH_PERDEV_MASK); - ata_eh_clear_action(dev, &ap->eh_context.i, ATA_EH_PERDEV_MASK); - spin_unlock_irqrestore(ap->lock, flags); } +static void ata_eh_clear_action(struct ata_device *dev, + struct ata_eh_info *ehi, unsigned int action) +{ + int i; + + if (!dev) { + ehi->action &= ~action; + for (i = 0; i < ATA_MAX_DEVICES; i++) + ehi->dev_action[i] &= ~action; + } else { + /* doesn't make sense for port-wide EH actions */ + WARN_ON(!(action & ATA_EH_PERDEV_MASK)); + + /* break ehi->action into ehi->dev_action */ + if (ehi->action & action) { + for (i = 0; i < ATA_MAX_DEVICES; i++) + ehi->dev_action[i] |= ehi->action & action; + ehi->action &= ~action; + } + + /* turn off the specified per-dev action */ + ehi->dev_action[dev->devno] &= ~action; + } +} + /** * ata_eh_about_to_do - about to perform eh_action * @ap: target ATA port @@ -1603,7 +1592,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, unsigned int action; dev = &ap->device[i]; - action = ata_eh_dev_action(dev); + action = ehc->i.action | ehc->i.dev_action[dev->devno]; if (action & ATA_EH_REVALIDATE && ata_dev_enabled(dev)) { if (ata_port_offline(ap)) { diff --git a/trunk/drivers/scsi/libata-scsi.c b/trunk/drivers/scsi/libata-scsi.c index 2915bca691e8..93d18a74c401 100644 --- a/trunk/drivers/scsi/libata-scsi.c +++ b/trunk/drivers/scsi/libata-scsi.c @@ -222,7 +222,9 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) && copy_to_user(arg + sizeof(args), argbuf, argsize)) rc = -EFAULT; error: - kfree(argbuf); + if (argbuf) + kfree(argbuf); + return rc; } diff --git a/trunk/drivers/scsi/libata.h b/trunk/drivers/scsi/libata.h index c325679d9b54..bdd488897096 100644 --- a/trunk/drivers/scsi/libata.h +++ b/trunk/drivers/scsi/libata.h @@ -29,7 +29,7 @@ #define __LIBATA_H__ #define DRV_NAME "libata" -#define DRV_VERSION "2.00" /* must be exactly four chars */ +#define DRV_VERSION "1.30" /* must be exactly four chars */ struct ata_scsi_args { struct ata_device *dev; @@ -50,7 +50,6 @@ extern void ata_port_flush_task(struct ata_port *ap); extern unsigned ata_exec_internal(struct ata_device *dev, struct ata_taskfile *tf, const u8 *cdb, int dma_dir, void *buf, unsigned int buflen); -extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd); extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, int post_reset, u16 *id); extern int ata_dev_configure(struct ata_device *dev, int print_info); @@ -65,7 +64,6 @@ extern int ata_check_atapi_dma(struct ata_queued_cmd *qc); extern void ata_dev_select(struct ata_port *ap, unsigned int device, unsigned int wait, unsigned int can_sleep); extern void swap_buf_le16(u16 *buf, unsigned int buf_words); -extern int ata_flush_cache(struct ata_device *dev); extern void ata_dev_init(struct ata_device *dev); extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); diff --git a/trunk/drivers/scsi/sata_nv.c b/trunk/drivers/scsi/sata_nv.c index 5cc42c6054eb..d18e7e0932ef 100644 --- a/trunk/drivers/scsi/sata_nv.c +++ b/trunk/drivers/scsi/sata_nv.c @@ -44,7 +44,7 @@ #include #define DRV_NAME "sata_nv" -#define DRV_VERSION "2.0" +#define DRV_VERSION "0.9" enum { NV_PORTS = 2, diff --git a/trunk/drivers/scsi/sata_sil.c b/trunk/drivers/scsi/sata_sil.c index 51d86d750e84..bc9f918a7f28 100644 --- a/trunk/drivers/scsi/sata_sil.c +++ b/trunk/drivers/scsi/sata_sil.c @@ -46,13 +46,12 @@ #include #define DRV_NAME "sata_sil" -#define DRV_VERSION "2.0" +#define DRV_VERSION "1.0" enum { /* * host flags */ - SIL_FLAG_NO_SATA_IRQ = (1 << 28), SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29), SIL_FLAG_MOD15WRITE = (1 << 30), @@ -63,9 +62,8 @@ enum { * Controller IDs */ sil_3112 = 0, - sil_3112_no_sata_irq = 1, - sil_3512 = 2, - sil_3114 = 3, + sil_3512 = 1, + sil_3114 = 2, /* * Register offsets @@ -125,8 +123,8 @@ static const struct pci_device_id sil_pci_tbl[] = { { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3512 }, { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, - { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq }, - { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_no_sata_irq }, + { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, + { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, { } /* terminate list */ }; @@ -219,16 +217,6 @@ static const struct ata_port_info sil_port_info[] = { .udma_mask = 0x3f, /* udma0-5 */ .port_ops = &sil_ops, }, - /* sil_3112_no_sata_irq */ - { - .sht = &sil_sht, - .host_flags = SIL_DFL_HOST_FLAGS | SIL_FLAG_MOD15WRITE | - SIL_FLAG_NO_SATA_IRQ, - .pio_mask = 0x1f, /* pio0-4 */ - .mwdma_mask = 0x07, /* mwdma0-2 */ - .udma_mask = 0x3f, /* udma0-5 */ - .port_ops = &sil_ops, - }, /* sil_3512 */ { .sht = &sil_sht, @@ -449,10 +437,6 @@ static irqreturn_t sil_interrupt(int irq, void *dev_instance, if (unlikely(!ap || ap->flags & ATA_FLAG_DISABLED)) continue; - /* turn off SATA_IRQ if not supported */ - if (ap->flags & SIL_FLAG_NO_SATA_IRQ) - bmdma2 &= ~SIL_DMA_SATA_IRQ; - if (bmdma2 == 0xffffffff || !(bmdma2 & (SIL_DMA_COMPLETE | SIL_DMA_SATA_IRQ))) continue; @@ -490,9 +474,8 @@ static void sil_thaw(struct ata_port *ap) ata_chk_status(ap); ata_bmdma_irq_clear(ap); - /* turn on SATA IRQ if supported */ - if (!(ap->flags & SIL_FLAG_NO_SATA_IRQ)) - writel(SIL_SIEN_N, mmio_base + sil_port[ap->port_no].sien); + /* turn on SATA IRQ */ + writel(SIL_SIEN_N, mmio_base + sil_port[ap->port_no].sien); /* turn on IRQ */ tmp = readl(mmio_base + SIL_SYSCFG); diff --git a/trunk/drivers/scsi/sata_sil24.c b/trunk/drivers/scsi/sata_sil24.c index b5f8fa955679..c8b477c67247 100644 --- a/trunk/drivers/scsi/sata_sil24.c +++ b/trunk/drivers/scsi/sata_sil24.c @@ -31,7 +31,7 @@ #include #define DRV_NAME "sata_sil24" -#define DRV_VERSION "0.3" +#define DRV_VERSION "0.24" /* * Port request block (PRB) 32 bytes diff --git a/trunk/drivers/scsi/sata_svw.c b/trunk/drivers/scsi/sata_svw.c index 7566c2cabaf7..c94b870cf378 100644 --- a/trunk/drivers/scsi/sata_svw.c +++ b/trunk/drivers/scsi/sata_svw.c @@ -54,7 +54,7 @@ #endif /* CONFIG_PPC_OF */ #define DRV_NAME "sata_svw" -#define DRV_VERSION "2.0" +#define DRV_VERSION "1.8" enum { /* Taskfile registers offsets */ diff --git a/trunk/drivers/scsi/sata_uli.c b/trunk/drivers/scsi/sata_uli.c index 64f3c1aeed21..f668c997e9af 100644 --- a/trunk/drivers/scsi/sata_uli.c +++ b/trunk/drivers/scsi/sata_uli.c @@ -37,7 +37,7 @@ #include #define DRV_NAME "sata_uli" -#define DRV_VERSION "1.0" +#define DRV_VERSION "0.6" enum { uli_5289 = 0, diff --git a/trunk/drivers/scsi/sata_via.c b/trunk/drivers/scsi/sata_via.c index 67c3d2999775..322890b400a6 100644 --- a/trunk/drivers/scsi/sata_via.c +++ b/trunk/drivers/scsi/sata_via.c @@ -47,7 +47,7 @@ #include #define DRV_NAME "sata_via" -#define DRV_VERSION "2.0" +#define DRV_VERSION "1.2" enum board_ids_enum { vt6420, diff --git a/trunk/drivers/scsi/sata_vsc.c b/trunk/drivers/scsi/sata_vsc.c index 616fd9634b4b..6d0c4f18e652 100644 --- a/trunk/drivers/scsi/sata_vsc.c +++ b/trunk/drivers/scsi/sata_vsc.c @@ -47,7 +47,7 @@ #include #define DRV_NAME "sata_vsc" -#define DRV_VERSION "2.0" +#define DRV_VERSION "1.2" enum { /* Interrupt register offsets (from chip base address) */ @@ -443,12 +443,16 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d } +/* + * Intel 31244 is supposed to be identical. + * Compatibility is untested as of yet. + */ static const struct pci_device_id vsc_sata_pci_tbl[] = { - { PCI_VENDOR_ID_VITESSE, 0x7174, + { PCI_VENDOR_ID_VITESSE, PCI_DEVICE_ID_VITESSE_VSC7174, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, - { PCI_VENDOR_ID_INTEL, 0x3200, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_GD31244, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, - { } /* terminate list */ + { } }; diff --git a/trunk/drivers/serial/68328serial.c b/trunk/drivers/serial/68328serial.c index bff94541991c..b88a7c1158af 100644 --- a/trunk/drivers/serial/68328serial.c +++ b/trunk/drivers/serial/68328serial.c @@ -131,6 +131,17 @@ static int m68328_console_baud = CONSOLE_BAUD_RATE; static int m68328_console_cbaud = DEFAULT_CBAUD; +/* + * tmp_buf is used as a temporary buffer by serial_write. We need to + * lock it in case the memcpy_fromfs blocks while swapping in a page, + * and some other program tries to do a serial write at the same time. + * Since the lock will only come under contention when the system is + * swapping and available memory is low, it makes sense to share one + * buffer across all the serial ports, since it significantly saves + * memory if large numbers of serial ports are open. + */ +static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */ + static inline int serial_paranoia_check(struct m68k_serial *info, char *name, const char *routine) { @@ -200,16 +211,16 @@ static void rs_stop(struct tty_struct *tty) if (serial_paranoia_check(info, tty->name, "rs_stop")) return; - local_irq_save(flags); + save_flags(flags); cli(); uart->ustcnt &= ~USTCNT_TXEN; - local_irq_restore(flags); + restore_flags(flags); } static void rs_put_char(char ch) { int flags, loops = 0; - local_irq_save(flags); + save_flags(flags); cli(); while (!(UTX & UTX_TX_AVAIL) && (loops < 1000)) { loops++; @@ -218,7 +229,7 @@ static void rs_put_char(char ch) UTX_TXDATA = ch; udelay(5); - local_irq_restore(flags); + restore_flags(flags); } static void rs_start(struct tty_struct *tty) @@ -230,7 +241,7 @@ static void rs_start(struct tty_struct *tty) if (serial_paranoia_check(info, tty->name, "rs_start")) return; - local_irq_save(flags); + save_flags(flags); cli(); if (info->xmit_cnt && info->xmit_buf && !(uart->ustcnt & USTCNT_TXEN)) { #ifdef USE_INTS uart->ustcnt |= USTCNT_TXEN | USTCNT_TX_INTR_MASK; @@ -238,7 +249,7 @@ static void rs_start(struct tty_struct *tty) uart->ustcnt |= USTCNT_TXEN; #endif } - local_irq_restore(flags); + restore_flags(flags); } /* Drop into either the boot monitor or kadb upon receiving a break @@ -316,6 +327,14 @@ static void receive_chars(struct m68k_serial *info, struct pt_regs *regs, if(!tty) goto clear_and_exit; + /* + * Make sure that we do not overflow the buffer + */ + if (tty_request_buffer_room(tty, 1) == 0) { + tty_schedule_flip(tty); + return; + } + flag = TTY_NORMAL; if(rx & URX_PARITY_ERROR) { @@ -454,7 +473,7 @@ static int startup(struct m68k_serial * info) return -ENOMEM; } - local_irq_save(flags); + save_flags(flags); cli(); /* * Clear the FIFO buffers and disable them @@ -487,7 +506,7 @@ static int startup(struct m68k_serial * info) change_speed(info); info->flags |= S_INITIALIZED; - local_irq_restore(flags); + restore_flags(flags); return 0; } @@ -504,7 +523,7 @@ static void shutdown(struct m68k_serial * info) if (!(info->flags & S_INITIALIZED)) return; - local_irq_save(flags); + save_flags(flags); cli(); /* Disable interrupts */ if (info->xmit_buf) { free_page((unsigned long) info->xmit_buf); @@ -515,7 +534,7 @@ static void shutdown(struct m68k_serial * info) set_bit(TTY_IO_ERROR, &info->tty->flags); info->flags &= ~S_INITIALIZED; - local_irq_restore(flags); + restore_flags(flags); } struct { @@ -636,24 +655,24 @@ static void rs_fair_output(void) if (info == 0) return; if (info->xmit_buf == 0) return; - local_irq_save(flags); + save_flags(flags); cli(); left = info->xmit_cnt; while (left != 0) { c = info->xmit_buf[info->xmit_tail]; info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1); info->xmit_cnt--; - local_irq_restore(flags); + restore_flags(flags); rs_put_char(c); - local_irq_save(flags); + save_flags(flags); cli(); left = min(info->xmit_cnt, left-1); } /* Last character is being transmitted now (hopefully). */ udelay(5); - local_irq_restore(flags); + restore_flags(flags); return; } @@ -701,11 +720,11 @@ static void rs_flush_chars(struct tty_struct *tty) #endif /* Enable transmitter */ - local_irq_save(flags); + save_flags(flags); cli(); if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf) { - local_irq_restore(flags); + restore_flags(flags); return; } @@ -730,7 +749,7 @@ static void rs_flush_chars(struct tty_struct *tty) while (!(uart->utx.w & UTX_TX_AVAIL)) udelay(5); } #endif - local_irq_restore(flags); + restore_flags(flags); } extern void console_printn(const char * b, int count); @@ -749,22 +768,18 @@ static int rs_write(struct tty_struct * tty, if (!tty || !info->xmit_buf) return 0; - local_save_flags(flags); + save_flags(flags); while (1) { - local_irq_disable(); + cli(); c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, SERIAL_XMIT_SIZE - info->xmit_head)); - local_irq_restore(flags); - if (c <= 0) break; memcpy(info->xmit_buf + info->xmit_head, buf, c); - - local_irq_disable(); info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); info->xmit_cnt += c; - local_irq_restore(flags); + restore_flags(flags); buf += c; count -= c; total += c; @@ -772,7 +787,7 @@ static int rs_write(struct tty_struct * tty, if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { /* Enable transmitter */ - local_irq_disable(); + cli(); #ifndef USE_INTS while(info->xmit_cnt) { #endif @@ -792,9 +807,9 @@ static int rs_write(struct tty_struct * tty, #ifndef USE_INTS } #endif - local_irq_restore(flags); + restore_flags(flags); } - + restore_flags(flags); return total; } @@ -823,13 +838,12 @@ static int rs_chars_in_buffer(struct tty_struct *tty) static void rs_flush_buffer(struct tty_struct *tty) { struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; - unsigned long flags; if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) return; - local_irq_save(flags); + cli(); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - local_irq_restore(flags); + sti(); tty_wakeup(tty); } @@ -959,15 +973,14 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value) m68328_uart *uart = &uart_addr[info->line]; #endif unsigned char status; - unsigned long flags; - local_irq_save(flags); + cli(); #ifdef CONFIG_SERIAL_68328_RTS_CTS status = (uart->utx.w & UTX_CTS_STAT) ? 1 : 0; #else status = 0; #endif - local_irq_restore(flags); + sti(); put_user(status,value); return 0; } @@ -981,13 +994,14 @@ static void send_break(struct m68k_serial * info, unsigned int duration) unsigned long flags; if (!info->port) return; - local_irq_save(flags); + save_flags(flags); + cli(); #ifdef USE_INTS uart->utx.w |= UTX_SEND_BREAK; msleep_interruptible(duration); uart->utx.w &= ~UTX_SEND_BREAK; #endif - local_irq_restore(flags); + restore_flags(flags); } static int rs_ioctl(struct tty_struct *tty, struct file * file, @@ -1046,7 +1060,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, (struct serial_struct *) arg); case TIOCSERGETLSR: /* Get line status register */ if (access_ok(VERIFY_WRITE, (void *) arg, - sizeof(unsigned int))) + sizeof(unsigned int)); return get_lsr_info(info, (unsigned int *) arg); return -EFAULT; case TIOCSERGSTRUCT: @@ -1099,10 +1113,10 @@ static void rs_close(struct tty_struct *tty, struct file * filp) if (!info || serial_paranoia_check(info, tty->name, "rs_close")) return; - local_irq_save(flags); + save_flags(flags); cli(); if (tty_hung_up_p(filp)) { - local_irq_restore(flags); + restore_flags(flags); return; } @@ -1124,7 +1138,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) info->count = 0; } if (info->count) { - local_irq_restore(flags); + restore_flags(flags); return; } info->flags |= S_CLOSING; @@ -1172,7 +1186,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) } info->flags &= ~(S_NORMAL_ACTIVE|S_CLOSING); wake_up_interruptible(&info->close_wait); - local_irq_restore(flags); + restore_flags(flags); } /* @@ -1248,9 +1262,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, info->count--; info->blocked_open++; while (1) { - local_irq_disable(); + cli(); m68k_rtsdtr(info, 1); - local_irq_enable(); + sti(); current->state = TASK_INTERRUPTIBLE; if (tty_hung_up_p(filp) || !(info->flags & S_INITIALIZED)) { @@ -1430,7 +1444,7 @@ rs68328_init(void) return -ENOMEM; } - local_irq_save(flags); + save_flags(flags); cli(); for(i=0;idata = info; #endif } - local_irq_restore(flags); + restore_flags(flags); return 0; } diff --git a/trunk/drivers/serial/crisv10.c b/trunk/drivers/serial/crisv10.c index 5cacc5e74a92..89700141f87e 100644 --- a/trunk/drivers/serial/crisv10.c +++ b/trunk/drivers/serial/crisv10.c @@ -2573,6 +2573,12 @@ static void flush_to_flip_buffer(struct e100_serial *info) DFLIP( if (1) { + + if (test_bit(TTY_DONT_FLIP, &tty->flags)) { + DEBUG_LOG(info->line, "*** TTY_DONT_FLIP set flip.count %i ***\n", tty->flip.count); + DEBUG_LOG(info->line, "*** recv_cnt %i\n", info->recv_cnt); + } else { + } DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx); DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty)); DEBUG_LOG(info->line, "room %lu\n", tty->ldisc.receive_room(tty)); diff --git a/trunk/drivers/serial/jsm/jsm_tty.c b/trunk/drivers/serial/jsm/jsm_tty.c index f8262e6ad8d3..7d823705193c 100644 --- a/trunk/drivers/serial/jsm/jsm_tty.c +++ b/trunk/drivers/serial/jsm/jsm_tty.c @@ -588,6 +588,13 @@ void jsm_input(struct jsm_channel *ch) len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt); ld = tty_ldisc_ref(tp); + /* + * If the DONT_FLIP flag is on, don't flush our buffer, and act + * like the ld doesn't have any space to put the data right now. + */ + if (test_bit(TTY_DONT_FLIP, &tp->flags)) + len = 0; + /* * If we were unable to get a reference to the ld, * don't flush our buffer, and act like the ld doesn't diff --git a/trunk/drivers/sn/ioc3.c b/trunk/drivers/sn/ioc3.c index ed946311d3a4..501316b198e5 100644 --- a/trunk/drivers/sn/ioc3.c +++ b/trunk/drivers/sn/ioc3.c @@ -26,7 +26,7 @@ static DECLARE_RWSEM(ioc3_devices_rwsem); static struct ioc3_submodule *ioc3_submodules[IOC3_MAX_SUBMODULES]; static struct ioc3_submodule *ioc3_ethernet; -static DEFINE_RWLOCK(ioc3_submodules_lock); +static rwlock_t ioc3_submodules_lock = RW_LOCK_UNLOCKED; /* NIC probing code */ diff --git a/trunk/drivers/sn/ioc4.c b/trunk/drivers/sn/ioc4.c index 8562821e6498..8256a97eb508 100644 --- a/trunk/drivers/sn/ioc4.c +++ b/trunk/drivers/sn/ioc4.c @@ -438,7 +438,7 @@ static struct pci_device_id ioc4_id_table[] = { {0} }; -static struct pci_driver ioc4_driver = { +static struct pci_driver __devinitdata ioc4_driver = { .name = "IOC4", .id_table = ioc4_id_table, .probe = ioc4_probe, diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index ed1cdf6ac8f3..1cea4a6799fe 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -210,7 +210,6 @@ spi_new_device(struct spi_master *master, struct spi_board_info *chip) proxy->master = master; proxy->chip_select = chip->chip_select; proxy->max_speed_hz = chip->max_speed_hz; - proxy->mode = chip->mode; proxy->irq = chip->irq; proxy->modalias = chip->modalias; diff --git a/trunk/drivers/usb/serial/ir-usb.c b/trunk/drivers/usb/serial/ir-usb.c index d7f3f736a692..9432c7302275 100644 --- a/trunk/drivers/usb/serial/ir-usb.c +++ b/trunk/drivers/usb/serial/ir-usb.c @@ -453,7 +453,8 @@ static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs) tty = port->tty; /* - * FIXME: must not do this in IRQ context + * FIXME: must not do this in IRQ context, + * must honour TTY_DONT_FLIP */ tty->ldisc.receive_buf( tty, diff --git a/trunk/drivers/video/aty/radeon_backlight.c b/trunk/drivers/video/aty/radeon_backlight.c index 1755dddf1899..7de66b855d4e 100644 --- a/trunk/drivers/video/aty/radeon_backlight.c +++ b/trunk/drivers/video/aty/radeon_backlight.c @@ -40,14 +40,14 @@ static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata, mutex_unlock(&info->bl_mutex); + if (pdata->negative) + rlevel = MAX_RADEON_LEVEL - rlevel; + if (rlevel < 0) rlevel = 0; else if (rlevel > MAX_RADEON_LEVEL) rlevel = MAX_RADEON_LEVEL; - if (pdata->negative) - rlevel = MAX_RADEON_LEVEL - rlevel; - return rlevel; } diff --git a/trunk/drivers/video/au1100fb.c b/trunk/drivers/video/au1100fb.c index 9ef68cd83bb4..d63c3f485853 100644 --- a/trunk/drivers/video/au1100fb.c +++ b/trunk/drivers/video/au1100fb.c @@ -743,7 +743,8 @@ void __exit au1100fb_cleanup(void) { driver_unregister(&au1100fb_driver); - kfree(drv_info.opt_mode); + if (drv_info.opt_mode) + kfree(drv_info.opt_mode); } module_init(au1100fb_init); diff --git a/trunk/drivers/video/backlight/hp680_bl.c b/trunk/drivers/video/backlight/hp680_bl.c index ffc72ae3ada8..a71e984c93d4 100644 --- a/trunk/drivers/video/backlight/hp680_bl.c +++ b/trunk/drivers/video/backlight/hp680_bl.c @@ -27,7 +27,7 @@ static int hp680bl_suspended; static int current_intensity = 0; -static DEFINE_SPINLOCK(bl_lock); +static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED; static struct backlight_device *hp680_backlight_device; static void hp680bl_send_intensity(struct backlight_device *bd) diff --git a/trunk/drivers/video/console/vgacon.c b/trunk/drivers/video/console/vgacon.c index f32b590730f2..01401cd63ac0 100644 --- a/trunk/drivers/video/console/vgacon.c +++ b/trunk/drivers/video/console/vgacon.c @@ -390,7 +390,7 @@ static const char *vgacon_startup(void) vga_video_port_val = VGA_CRT_DM; if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { static struct resource ega_console_resource = - { "ega", 0x3B0, 0x3BF }; + { .name = "ega", .start = 0x3B0, .end = 0x3BF }; vga_video_type = VIDEO_TYPE_EGAM; vga_vram_size = 0x8000; display_desc = "EGA+"; @@ -398,9 +398,9 @@ static const char *vgacon_startup(void) &ega_console_resource); } else { static struct resource mda1_console_resource = - { "mda", 0x3B0, 0x3BB }; + { .name = "mda", .start = 0x3B0, .end = 0x3BB }; static struct resource mda2_console_resource = - { "mda", 0x3BF, 0x3BF }; + { .name = "mda", .start = 0x3BF, .end = 0x3BF }; vga_video_type = VIDEO_TYPE_MDA; vga_vram_size = 0x2000; display_desc = "*MDA"; @@ -423,14 +423,14 @@ static const char *vgacon_startup(void) if (!ORIG_VIDEO_ISVGA) { static struct resource ega_console_resource - = { "ega", 0x3C0, 0x3DF }; + = { .name = "ega", .start = 0x3C0, .end = 0x3DF }; vga_video_type = VIDEO_TYPE_EGAC; display_desc = "EGA"; request_resource(&ioport_resource, &ega_console_resource); } else { static struct resource vga_console_resource - = { "vga+", 0x3C0, 0x3DF }; + = { .name = "vga+", .start = 0x3C0, .end = 0x3DF }; vga_video_type = VIDEO_TYPE_VGAC; display_desc = "VGA+"; request_resource(&ioport_resource, @@ -474,7 +474,7 @@ static const char *vgacon_startup(void) } } else { static struct resource cga_console_resource = - { "cga", 0x3D4, 0x3D5 }; + { .name = "cga", .start = 0x3D4, .end = 0x3D5 }; vga_video_type = VIDEO_TYPE_CGA; vga_vram_size = 0x2000; display_desc = "*CGA"; diff --git a/trunk/drivers/video/sgivwfb.c b/trunk/drivers/video/sgivwfb.c index c0cc5e3ba7b5..2e6df1fcb2b9 100644 --- a/trunk/drivers/video/sgivwfb.c +++ b/trunk/drivers/video/sgivwfb.c @@ -23,8 +23,6 @@ #include #include -#include - #define INCLUDE_TIMING_TABLE_DATA #define DBE_REG_BASE par->regs #include